@opensip-cli/checks-universal 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 +17 -0
- package/dist/__tests__/all-checks-execute.test.d.ts.map +1 -0
- package/dist/__tests__/all-checks-execute.test.js +452 -0
- package/dist/__tests__/all-checks-execute.test.js.map +1 -0
- package/dist/__tests__/behavior-fixtures-10.test.d.ts +8 -0
- package/dist/__tests__/behavior-fixtures-10.test.d.ts.map +1 -0
- package/dist/__tests__/behavior-fixtures-10.test.js +200 -0
- package/dist/__tests__/behavior-fixtures-10.test.js.map +1 -0
- package/dist/__tests__/behavior-fixtures-11.test.d.ts +8 -0
- package/dist/__tests__/behavior-fixtures-11.test.d.ts.map +1 -0
- package/dist/__tests__/behavior-fixtures-11.test.js +120 -0
- package/dist/__tests__/behavior-fixtures-11.test.js.map +1 -0
- package/dist/__tests__/behavior-fixtures-12.test.d.ts +8 -0
- package/dist/__tests__/behavior-fixtures-12.test.d.ts.map +1 -0
- package/dist/__tests__/behavior-fixtures-12.test.js +157 -0
- package/dist/__tests__/behavior-fixtures-12.test.js.map +1 -0
- package/dist/__tests__/behavior-fixtures-2.test.d.ts +8 -0
- package/dist/__tests__/behavior-fixtures-2.test.d.ts.map +1 -0
- package/dist/__tests__/behavior-fixtures-2.test.js +785 -0
- package/dist/__tests__/behavior-fixtures-2.test.js.map +1 -0
- package/dist/__tests__/behavior-fixtures-3.test.d.ts +6 -0
- package/dist/__tests__/behavior-fixtures-3.test.d.ts.map +1 -0
- package/dist/__tests__/behavior-fixtures-3.test.js +663 -0
- package/dist/__tests__/behavior-fixtures-3.test.js.map +1 -0
- package/dist/__tests__/behavior-fixtures-4.test.d.ts +5 -0
- package/dist/__tests__/behavior-fixtures-4.test.d.ts.map +1 -0
- package/dist/__tests__/behavior-fixtures-4.test.js +612 -0
- package/dist/__tests__/behavior-fixtures-4.test.js.map +1 -0
- package/dist/__tests__/behavior-fixtures-5.test.d.ts +5 -0
- package/dist/__tests__/behavior-fixtures-5.test.d.ts.map +1 -0
- package/dist/__tests__/behavior-fixtures-5.test.js +469 -0
- package/dist/__tests__/behavior-fixtures-5.test.js.map +1 -0
- package/dist/__tests__/behavior-fixtures-6.test.d.ts +8 -0
- package/dist/__tests__/behavior-fixtures-6.test.d.ts.map +1 -0
- package/dist/__tests__/behavior-fixtures-6.test.js +591 -0
- package/dist/__tests__/behavior-fixtures-6.test.js.map +1 -0
- package/dist/__tests__/behavior-fixtures-7.test.d.ts +5 -0
- package/dist/__tests__/behavior-fixtures-7.test.d.ts.map +1 -0
- package/dist/__tests__/behavior-fixtures-7.test.js +662 -0
- package/dist/__tests__/behavior-fixtures-7.test.js.map +1 -0
- package/dist/__tests__/behavior-fixtures-8.test.d.ts +11 -0
- package/dist/__tests__/behavior-fixtures-8.test.d.ts.map +1 -0
- package/dist/__tests__/behavior-fixtures-8.test.js +634 -0
- package/dist/__tests__/behavior-fixtures-8.test.js.map +1 -0
- package/dist/__tests__/behavior-fixtures-9.test.d.ts +11 -0
- package/dist/__tests__/behavior-fixtures-9.test.d.ts.map +1 -0
- package/dist/__tests__/behavior-fixtures-9.test.js +271 -0
- package/dist/__tests__/behavior-fixtures-9.test.js.map +1 -0
- package/dist/__tests__/behavior-fixtures.test.d.ts +14 -0
- package/dist/__tests__/behavior-fixtures.test.d.ts.map +1 -0
- package/dist/__tests__/behavior-fixtures.test.js +1423 -0
- package/dist/__tests__/behavior-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 +61 -0
- package/dist/__tests__/checks.test.js.map +1 -0
- package/dist/__tests__/env-var-validation.test.d.ts +14 -0
- package/dist/__tests__/env-var-validation.test.d.ts.map +1 -0
- package/dist/__tests__/env-var-validation.test.js +53 -0
- package/dist/__tests__/env-var-validation.test.js.map +1 -0
- package/dist/__tests__/file-length-limit.test.d.ts +2 -0
- package/dist/__tests__/file-length-limit.test.d.ts.map +1 -0
- package/dist/__tests__/file-length-limit.test.js +29 -0
- package/dist/__tests__/file-length-limit.test.js.map +1 -0
- package/dist/__tests__/fixture-coverage.allowlist.d.ts +18 -0
- package/dist/__tests__/fixture-coverage.allowlist.d.ts.map +1 -0
- package/dist/__tests__/fixture-coverage.allowlist.js +35 -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__/iic.test.d.ts +15 -0
- package/dist/__tests__/iic.test.d.ts.map +1 -0
- package/dist/__tests__/iic.test.js +316 -0
- package/dist/__tests__/iic.test.js.map +1 -0
- package/dist/__tests__/no-skipped-tests.test.d.ts +14 -0
- package/dist/__tests__/no-skipped-tests.test.d.ts.map +1 -0
- package/dist/__tests__/no-skipped-tests.test.js +144 -0
- package/dist/__tests__/no-skipped-tests.test.js.map +1 -0
- package/dist/__tests__/no-todo-comments.test.d.ts +2 -0
- package/dist/__tests__/no-todo-comments.test.d.ts.map +1 -0
- package/dist/__tests__/no-todo-comments.test.js +31 -0
- package/dist/__tests__/no-todo-comments.test.js.map +1 -0
- package/dist/__tests__/no-unimplemented-markers.test.d.ts +2 -0
- package/dist/__tests__/no-unimplemented-markers.test.d.ts.map +1 -0
- package/dist/__tests__/no-unimplemented-markers.test.js +140 -0
- package/dist/__tests__/no-unimplemented-markers.test.js.map +1 -0
- package/dist/__tests__/public-api-jsdoc-scope.test.d.ts +10 -0
- package/dist/__tests__/public-api-jsdoc-scope.test.d.ts.map +1 -0
- package/dist/__tests__/public-api-jsdoc-scope.test.js +176 -0
- package/dist/__tests__/public-api-jsdoc-scope.test.js.map +1 -0
- package/dist/__tests__/resilience-fp.test.d.ts +14 -0
- package/dist/__tests__/resilience-fp.test.d.ts.map +1 -0
- package/dist/__tests__/resilience-fp.test.js +110 -0
- package/dist/__tests__/resilience-fp.test.js.map +1 -0
- package/dist/checks/architecture/__tests__/no-kebab-option-indexing.test.d.ts +2 -0
- package/dist/checks/architecture/__tests__/no-kebab-option-indexing.test.d.ts.map +1 -0
- package/dist/checks/architecture/__tests__/no-kebab-option-indexing.test.js +32 -0
- package/dist/checks/architecture/__tests__/no-kebab-option-indexing.test.js.map +1 -0
- package/dist/checks/architecture/__tests__/tool-has-manifest.test.d.ts +2 -0
- package/dist/checks/architecture/__tests__/tool-has-manifest.test.d.ts.map +1 -0
- package/dist/checks/architecture/__tests__/tool-has-manifest.test.js +152 -0
- package/dist/checks/architecture/__tests__/tool-has-manifest.test.js.map +1 -0
- package/dist/checks/architecture/__tests__/vitest-config-required-with-tests.test.d.ts +2 -0
- package/dist/checks/architecture/__tests__/vitest-config-required-with-tests.test.d.ts.map +1 -0
- package/dist/checks/architecture/__tests__/vitest-config-required-with-tests.test.js +129 -0
- package/dist/checks/architecture/__tests__/vitest-config-required-with-tests.test.js.map +1 -0
- package/dist/checks/architecture/_yaml-doc-bindings.d.ts +23 -0
- package/dist/checks/architecture/_yaml-doc-bindings.d.ts.map +1 -0
- package/dist/checks/architecture/_yaml-doc-bindings.js +29 -0
- package/dist/checks/architecture/_yaml-doc-bindings.js.map +1 -0
- package/dist/checks/architecture/dependencies/index.d.ts +2 -0
- package/dist/checks/architecture/dependencies/index.d.ts.map +1 -0
- package/dist/checks/architecture/dependencies/index.js +2 -0
- package/dist/checks/architecture/dependencies/index.js.map +1 -0
- package/dist/checks/architecture/dependencies/no-duplicate-packages.d.ts +11 -0
- package/dist/checks/architecture/dependencies/no-duplicate-packages.d.ts.map +1 -0
- package/dist/checks/architecture/dependencies/no-duplicate-packages.js +171 -0
- package/dist/checks/architecture/dependencies/no-duplicate-packages.js.map +1 -0
- package/dist/checks/architecture/docker-best-practices.d.ts +23 -0
- package/dist/checks/architecture/docker-best-practices.d.ts.map +1 -0
- package/dist/checks/architecture/docker-best-practices.js +427 -0
- package/dist/checks/architecture/docker-best-practices.js.map +1 -0
- package/dist/checks/architecture/docker-ignore-validation.d.ts +18 -0
- package/dist/checks/architecture/docker-ignore-validation.d.ts.map +1 -0
- package/dist/checks/architecture/docker-ignore-validation.js +117 -0
- package/dist/checks/architecture/docker-ignore-validation.js.map +1 -0
- package/dist/checks/architecture/docker-version-sync.d.ts +16 -0
- package/dist/checks/architecture/docker-version-sync.d.ts.map +1 -0
- package/dist/checks/architecture/docker-version-sync.js +193 -0
- package/dist/checks/architecture/docker-version-sync.js.map +1 -0
- package/dist/checks/architecture/env-var-validation.d.ts +14 -0
- package/dist/checks/architecture/env-var-validation.d.ts.map +1 -0
- package/dist/checks/architecture/env-var-validation.js +289 -0
- package/dist/checks/architecture/env-var-validation.js.map +1 -0
- package/dist/checks/architecture/heavy-import-detection.d.ts +11 -0
- package/dist/checks/architecture/heavy-import-detection.d.ts.map +1 -0
- package/dist/checks/architecture/heavy-import-detection.js +91 -0
- package/dist/checks/architecture/heavy-import-detection.js.map +1 -0
- package/dist/checks/architecture/index.d.ts +16 -0
- package/dist/checks/architecture/index.d.ts.map +1 -0
- package/dist/checks/architecture/index.js +16 -0
- package/dist/checks/architecture/index.js.map +1 -0
- package/dist/checks/architecture/modules/empty-package-detection.d.ts +11 -0
- package/dist/checks/architecture/modules/empty-package-detection.d.ts.map +1 -0
- package/dist/checks/architecture/modules/empty-package-detection.js +277 -0
- package/dist/checks/architecture/modules/empty-package-detection.js.map +1 -0
- package/dist/checks/architecture/modules/index.d.ts +3 -0
- package/dist/checks/architecture/modules/index.d.ts.map +1 -0
- package/dist/checks/architecture/modules/index.js +3 -0
- package/dist/checks/architecture/modules/index.js.map +1 -0
- package/dist/checks/architecture/modules/interface-implementation-consistency.d.ts +12 -0
- package/dist/checks/architecture/modules/interface-implementation-consistency.d.ts.map +1 -0
- package/dist/checks/architecture/modules/interface-implementation-consistency.js +555 -0
- package/dist/checks/architecture/modules/interface-implementation-consistency.js.map +1 -0
- package/dist/checks/architecture/no-custom-event-emitter.d.ts +11 -0
- package/dist/checks/architecture/no-custom-event-emitter.d.ts.map +1 -0
- package/dist/checks/architecture/no-custom-event-emitter.js +123 -0
- package/dist/checks/architecture/no-custom-event-emitter.js.map +1 -0
- package/dist/checks/architecture/no-kebab-option-indexing.d.ts +33 -0
- package/dist/checks/architecture/no-kebab-option-indexing.d.ts.map +1 -0
- package/dist/checks/architecture/no-kebab-option-indexing.js +81 -0
- package/dist/checks/architecture/no-kebab-option-indexing.js.map +1 -0
- package/dist/checks/architecture/node-version-consistency.d.ts +22 -0
- package/dist/checks/architecture/node-version-consistency.d.ts.map +1 -0
- package/dist/checks/architecture/node-version-consistency.js +225 -0
- package/dist/checks/architecture/node-version-consistency.js.map +1 -0
- package/dist/checks/architecture/project-readme-existence.d.ts +13 -0
- package/dist/checks/architecture/project-readme-existence.d.ts.map +1 -0
- package/dist/checks/architecture/project-readme-existence.js +55 -0
- package/dist/checks/architecture/project-readme-existence.js.map +1 -0
- package/dist/checks/architecture/stale-build-artifacts.d.ts +10 -0
- package/dist/checks/architecture/stale-build-artifacts.d.ts.map +1 -0
- package/dist/checks/architecture/stale-build-artifacts.js +55 -0
- package/dist/checks/architecture/stale-build-artifacts.js.map +1 -0
- package/dist/checks/architecture/tool-has-manifest.d.ts +27 -0
- package/dist/checks/architecture/tool-has-manifest.d.ts.map +1 -0
- package/dist/checks/architecture/tool-has-manifest.js +135 -0
- package/dist/checks/architecture/tool-has-manifest.js.map +1 -0
- package/dist/checks/architecture/vitest-config-extends-base.d.ts +15 -0
- package/dist/checks/architecture/vitest-config-extends-base.d.ts.map +1 -0
- package/dist/checks/architecture/vitest-config-extends-base.js +104 -0
- package/dist/checks/architecture/vitest-config-extends-base.js.map +1 -0
- package/dist/checks/architecture/vitest-config-required-with-tests.d.ts +49 -0
- package/dist/checks/architecture/vitest-config-required-with-tests.d.ts.map +1 -0
- package/dist/checks/architecture/vitest-config-required-with-tests.js +199 -0
- package/dist/checks/architecture/vitest-config-required-with-tests.js.map +1 -0
- package/dist/checks/documentation/_directives/eslint.d.ts +9 -0
- package/dist/checks/documentation/_directives/eslint.d.ts.map +1 -0
- package/dist/checks/documentation/_directives/eslint.js +168 -0
- package/dist/checks/documentation/_directives/eslint.js.map +1 -0
- package/dist/checks/documentation/_directives/fitness.d.ts +9 -0
- package/dist/checks/documentation/_directives/fitness.d.ts.map +1 -0
- package/dist/checks/documentation/_directives/fitness.js +64 -0
- package/dist/checks/documentation/_directives/fitness.js.map +1 -0
- package/dist/checks/documentation/_directives/graph.d.ts +10 -0
- package/dist/checks/documentation/_directives/graph.d.ts.map +1 -0
- package/dist/checks/documentation/_directives/graph.js +65 -0
- package/dist/checks/documentation/_directives/graph.js.map +1 -0
- package/dist/checks/documentation/_directives/graph.test.d.ts +2 -0
- package/dist/checks/documentation/_directives/graph.test.d.ts.map +1 -0
- package/dist/checks/documentation/_directives/graph.test.js +54 -0
- package/dist/checks/documentation/_directives/graph.test.js.map +1 -0
- package/dist/checks/documentation/_directives/semgrep.d.ts +8 -0
- package/dist/checks/documentation/_directives/semgrep.d.ts.map +1 -0
- package/dist/checks/documentation/_directives/semgrep.js +72 -0
- package/dist/checks/documentation/_directives/semgrep.js.map +1 -0
- package/dist/checks/documentation/_directives/types.d.ts +21 -0
- package/dist/checks/documentation/_directives/types.d.ts.map +1 -0
- package/dist/checks/documentation/_directives/types.js +9 -0
- package/dist/checks/documentation/_directives/types.js.map +1 -0
- package/dist/checks/documentation/_directives/typescript.d.ts +10 -0
- package/dist/checks/documentation/_directives/typescript.d.ts.map +1 -0
- package/dist/checks/documentation/_directives/typescript.js +54 -0
- package/dist/checks/documentation/_directives/typescript.js.map +1 -0
- package/dist/checks/documentation/_public-api-graph.d.ts +30 -0
- package/dist/checks/documentation/_public-api-graph.d.ts.map +1 -0
- package/dist/checks/documentation/_public-api-graph.js +304 -0
- package/dist/checks/documentation/_public-api-graph.js.map +1 -0
- package/dist/checks/documentation/directive-audit.d.ts +26 -0
- package/dist/checks/documentation/directive-audit.d.ts.map +1 -0
- package/dist/checks/documentation/directive-audit.js +144 -0
- package/dist/checks/documentation/directive-audit.js.map +1 -0
- package/dist/checks/documentation/index.d.ts +3 -0
- package/dist/checks/documentation/index.d.ts.map +1 -0
- package/dist/checks/documentation/index.js +3 -0
- package/dist/checks/documentation/index.js.map +1 -0
- package/dist/checks/documentation/public-api-jsdoc.d.ts +10 -0
- package/dist/checks/documentation/public-api-jsdoc.d.ts.map +1 -0
- package/dist/checks/documentation/public-api-jsdoc.js +131 -0
- package/dist/checks/documentation/public-api-jsdoc.js.map +1 -0
- package/dist/checks/file-length-limit.d.ts +16 -0
- package/dist/checks/file-length-limit.d.ts.map +1 -0
- package/dist/checks/file-length-limit.js +47 -0
- package/dist/checks/file-length-limit.js.map +1 -0
- package/dist/checks/index.d.ts +16 -0
- package/dist/checks/index.d.ts.map +1 -0
- package/dist/checks/index.js +16 -0
- package/dist/checks/index.js.map +1 -0
- package/dist/checks/no-todo-comments.d.ts +18 -0
- package/dist/checks/no-todo-comments.d.ts.map +1 -0
- package/dist/checks/no-todo-comments.js +79 -0
- package/dist/checks/no-todo-comments.js.map +1 -0
- package/dist/checks/no-unimplemented-markers.d.ts +24 -0
- package/dist/checks/no-unimplemented-markers.d.ts.map +1 -0
- package/dist/checks/no-unimplemented-markers.js +198 -0
- package/dist/checks/no-unimplemented-markers.js.map +1 -0
- package/dist/checks/quality/api/graphql-offset-pagination.d.ts +9 -0
- package/dist/checks/quality/api/graphql-offset-pagination.d.ts.map +1 -0
- package/dist/checks/quality/api/graphql-offset-pagination.js +63 -0
- package/dist/checks/quality/api/graphql-offset-pagination.js.map +1 -0
- package/dist/checks/quality/api/index.d.ts +3 -0
- package/dist/checks/quality/api/index.d.ts.map +1 -0
- package/dist/checks/quality/api/index.js +3 -0
- package/dist/checks/quality/api/index.js.map +1 -0
- package/dist/checks/quality/api/zod-openapi-sync.d.ts +13 -0
- package/dist/checks/quality/api/zod-openapi-sync.d.ts.map +1 -0
- package/dist/checks/quality/api/zod-openapi-sync.js +88 -0
- package/dist/checks/quality/api/zod-openapi-sync.js.map +1 -0
- package/dist/checks/quality/code-structure/dead-code.d.ts +12 -0
- package/dist/checks/quality/code-structure/dead-code.d.ts.map +1 -0
- package/dist/checks/quality/code-structure/dead-code.js +238 -0
- package/dist/checks/quality/code-structure/dead-code.js.map +1 -0
- package/dist/checks/quality/code-structure/index.d.ts +5 -0
- package/dist/checks/quality/code-structure/index.d.ts.map +1 -0
- package/dist/checks/quality/code-structure/index.js +5 -0
- package/dist/checks/quality/code-structure/index.js.map +1 -0
- package/dist/checks/quality/code-structure/no-ai-attribution.d.ts +25 -0
- package/dist/checks/quality/code-structure/no-ai-attribution.d.ts.map +1 -0
- package/dist/checks/quality/code-structure/no-ai-attribution.js +76 -0
- package/dist/checks/quality/code-structure/no-ai-attribution.js.map +1 -0
- package/dist/checks/quality/code-structure/no-console-log.d.ts +17 -0
- package/dist/checks/quality/code-structure/no-console-log.d.ts.map +1 -0
- package/dist/checks/quality/code-structure/no-console-log.js +106 -0
- package/dist/checks/quality/code-structure/no-console-log.js.map +1 -0
- package/dist/checks/quality/code-structure/no-process-artifacts.d.ts +25 -0
- package/dist/checks/quality/code-structure/no-process-artifacts.d.ts.map +1 -0
- package/dist/checks/quality/code-structure/no-process-artifacts.js +104 -0
- package/dist/checks/quality/code-structure/no-process-artifacts.js.map +1 -0
- package/dist/checks/quality/dependency-version-consistency.d.ts +20 -0
- package/dist/checks/quality/dependency-version-consistency.d.ts.map +1 -0
- package/dist/checks/quality/dependency-version-consistency.js +266 -0
- package/dist/checks/quality/dependency-version-consistency.js.map +1 -0
- package/dist/checks/quality/fitness-ignore-hygiene.d.ts +10 -0
- package/dist/checks/quality/fitness-ignore-hygiene.d.ts.map +1 -0
- package/dist/checks/quality/fitness-ignore-hygiene.js +93 -0
- package/dist/checks/quality/fitness-ignore-hygiene.js.map +1 -0
- package/dist/checks/quality/frontend/expo-vector-icons.d.ts +13 -0
- package/dist/checks/quality/frontend/expo-vector-icons.d.ts.map +1 -0
- package/dist/checks/quality/frontend/expo-vector-icons.js +80 -0
- package/dist/checks/quality/frontend/expo-vector-icons.js.map +1 -0
- package/dist/checks/quality/frontend/image-optimization.d.ts +13 -0
- package/dist/checks/quality/frontend/image-optimization.d.ts.map +1 -0
- package/dist/checks/quality/frontend/image-optimization.js +166 -0
- package/dist/checks/quality/frontend/image-optimization.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/navigation-typing.d.ts +12 -0
- package/dist/checks/quality/frontend/navigation-typing.d.ts.map +1 -0
- package/dist/checks/quality/frontend/navigation-typing.js +77 -0
- package/dist/checks/quality/frontend/navigation-typing.js.map +1 -0
- package/dist/checks/quality/graph-ignore-hygiene.d.ts +10 -0
- package/dist/checks/quality/graph-ignore-hygiene.d.ts.map +1 -0
- package/dist/checks/quality/graph-ignore-hygiene.js +95 -0
- package/dist/checks/quality/graph-ignore-hygiene.js.map +1 -0
- package/dist/checks/quality/graph-ignore-hygiene.test.d.ts +14 -0
- package/dist/checks/quality/graph-ignore-hygiene.test.d.ts.map +1 -0
- package/dist/checks/quality/graph-ignore-hygiene.test.js +58 -0
- package/dist/checks/quality/graph-ignore-hygiene.test.js.map +1 -0
- package/dist/checks/quality/index.d.ts +16 -0
- package/dist/checks/quality/index.d.ts.map +1 -0
- package/dist/checks/quality/index.js +16 -0
- package/dist/checks/quality/index.js.map +1 -0
- package/dist/checks/quality/linting/eslint-justifications.d.ts +12 -0
- package/dist/checks/quality/linting/eslint-justifications.d.ts.map +1 -0
- package/dist/checks/quality/linting/eslint-justifications.js +328 -0
- package/dist/checks/quality/linting/eslint-justifications.js.map +1 -0
- package/dist/checks/quality/linting/index.d.ts +4 -0
- package/dist/checks/quality/linting/index.d.ts.map +1 -0
- package/dist/checks/quality/linting/index.js +4 -0
- package/dist/checks/quality/linting/index.js.map +1 -0
- package/dist/checks/quality/linting/semgrep-justifications.d.ts +16 -0
- package/dist/checks/quality/linting/semgrep-justifications.d.ts.map +1 -0
- package/dist/checks/quality/linting/semgrep-justifications.js +229 -0
- package/dist/checks/quality/linting/semgrep-justifications.js.map +1 -0
- package/dist/checks/quality/linting/typescript-directive-hygiene.d.ts +12 -0
- package/dist/checks/quality/linting/typescript-directive-hygiene.d.ts.map +1 -0
- package/dist/checks/quality/linting/typescript-directive-hygiene.js +142 -0
- package/dist/checks/quality/linting/typescript-directive-hygiene.js.map +1 -0
- package/dist/checks/quality/no-compatibility-layer-names.d.ts +13 -0
- package/dist/checks/quality/no-compatibility-layer-names.d.ts.map +1 -0
- package/dist/checks/quality/no-compatibility-layer-names.js +100 -0
- package/dist/checks/quality/no-compatibility-layer-names.js.map +1 -0
- package/dist/checks/quality/no-deprecated-tags.d.ts +11 -0
- package/dist/checks/quality/no-deprecated-tags.d.ts.map +1 -0
- package/dist/checks/quality/no-deprecated-tags.js +76 -0
- package/dist/checks/quality/no-deprecated-tags.js.map +1 -0
- package/dist/checks/quality/no-markdown-references.d.ts +16 -0
- package/dist/checks/quality/no-markdown-references.d.ts.map +1 -0
- package/dist/checks/quality/no-markdown-references.js +145 -0
- package/dist/checks/quality/no-markdown-references.js.map +1 -0
- package/dist/checks/quality/no-raw-regex-on-code.d.ts +9 -0
- package/dist/checks/quality/no-raw-regex-on-code.d.ts.map +1 -0
- package/dist/checks/quality/no-raw-regex-on-code.js +61 -0
- package/dist/checks/quality/no-raw-regex-on-code.js.map +1 -0
- package/dist/checks/quality/no-temporary-workarounds.d.ts +11 -0
- package/dist/checks/quality/no-temporary-workarounds.d.ts.map +1 -0
- package/dist/checks/quality/no-temporary-workarounds.js +69 -0
- package/dist/checks/quality/no-temporary-workarounds.js.map +1 -0
- package/dist/checks/quality/no-window-alert.d.ts +19 -0
- package/dist/checks/quality/no-window-alert.d.ts.map +1 -0
- package/dist/checks/quality/no-window-alert.js +74 -0
- package/dist/checks/quality/no-window-alert.js.map +1 -0
- package/dist/checks/quality/observability/index.d.ts +2 -0
- package/dist/checks/quality/observability/index.d.ts.map +1 -0
- package/dist/checks/quality/observability/index.js +2 -0
- package/dist/checks/quality/observability/index.js.map +1 -0
- package/dist/checks/quality/observability/pino-serializer-coverage.d.ts +15 -0
- package/dist/checks/quality/observability/pino-serializer-coverage.d.ts.map +1 -0
- package/dist/checks/quality/observability/pino-serializer-coverage.js +209 -0
- package/dist/checks/quality/observability/pino-serializer-coverage.js.map +1 -0
- package/dist/checks/quality/patterns/async-state-pattern.d.ts +14 -0
- package/dist/checks/quality/patterns/async-state-pattern.d.ts.map +1 -0
- package/dist/checks/quality/patterns/async-state-pattern.js +80 -0
- package/dist/checks/quality/patterns/async-state-pattern.js.map +1 -0
- package/dist/checks/quality/patterns/index.d.ts +4 -0
- package/dist/checks/quality/patterns/index.d.ts.map +1 -0
- package/dist/checks/quality/patterns/index.js +4 -0
- package/dist/checks/quality/patterns/index.js.map +1 -0
- package/dist/checks/quality/patterns/no-non-null-assertions.d.ts +10 -0
- package/dist/checks/quality/patterns/no-non-null-assertions.d.ts.map +1 -0
- package/dist/checks/quality/patterns/no-non-null-assertions.js +97 -0
- package/dist/checks/quality/patterns/no-non-null-assertions.js.map +1 -0
- package/dist/checks/quality/patterns/performance-anti-patterns.d.ts +16 -0
- package/dist/checks/quality/patterns/performance-anti-patterns.d.ts.map +1 -0
- package/dist/checks/quality/patterns/performance-anti-patterns.js +239 -0
- package/dist/checks/quality/patterns/performance-anti-patterns.js.map +1 -0
- package/dist/checks/resilience/_helpers/config-validation.d.ts +27 -0
- package/dist/checks/resilience/_helpers/config-validation.d.ts.map +1 -0
- package/dist/checks/resilience/_helpers/config-validation.js +61 -0
- package/dist/checks/resilience/_helpers/config-validation.js.map +1 -0
- package/dist/checks/resilience/batch-operations.d.ts +22 -0
- package/dist/checks/resilience/batch-operations.d.ts.map +1 -0
- package/dist/checks/resilience/batch-operations.js +422 -0
- package/dist/checks/resilience/batch-operations.js.map +1 -0
- package/dist/checks/resilience/cache-ttl-validation.d.ts +13 -0
- package/dist/checks/resilience/cache-ttl-validation.d.ts.map +1 -0
- package/dist/checks/resilience/cache-ttl-validation.js +222 -0
- package/dist/checks/resilience/cache-ttl-validation.js.map +1 -0
- package/dist/checks/resilience/catch-clause-safety.d.ts +12 -0
- package/dist/checks/resilience/catch-clause-safety.d.ts.map +1 -0
- package/dist/checks/resilience/catch-clause-safety.js +110 -0
- package/dist/checks/resilience/catch-clause-safety.js.map +1 -0
- package/dist/checks/resilience/dangerous-config-defaults.d.ts +11 -0
- package/dist/checks/resilience/dangerous-config-defaults.d.ts.map +1 -0
- package/dist/checks/resilience/dangerous-config-defaults.js +304 -0
- package/dist/checks/resilience/dangerous-config-defaults.js.map +1 -0
- package/dist/checks/resilience/error-code-registration.d.ts +11 -0
- package/dist/checks/resilience/error-code-registration.d.ts.map +1 -0
- package/dist/checks/resilience/error-code-registration.js +88 -0
- package/dist/checks/resilience/error-code-registration.js.map +1 -0
- package/dist/checks/resilience/event-patterns.d.ts +21 -0
- package/dist/checks/resilience/event-patterns.d.ts.map +1 -0
- package/dist/checks/resilience/event-patterns.js +232 -0
- package/dist/checks/resilience/event-patterns.js.map +1 -0
- package/dist/checks/resilience/exit-code-correctness.d.ts +12 -0
- package/dist/checks/resilience/exit-code-correctness.d.ts.map +1 -0
- package/dist/checks/resilience/exit-code-correctness.js +107 -0
- package/dist/checks/resilience/exit-code-correctness.js.map +1 -0
- package/dist/checks/resilience/index.d.ts +18 -0
- package/dist/checks/resilience/index.d.ts.map +1 -0
- package/dist/checks/resilience/index.js +18 -0
- package/dist/checks/resilience/index.js.map +1 -0
- package/dist/checks/resilience/no-hardcoded-timeouts.d.ts +10 -0
- package/dist/checks/resilience/no-hardcoded-timeouts.d.ts.map +1 -0
- package/dist/checks/resilience/no-hardcoded-timeouts.js +291 -0
- package/dist/checks/resilience/no-hardcoded-timeouts.js.map +1 -0
- package/dist/checks/resilience/no-process-exit-in-finally.d.ts +11 -0
- package/dist/checks/resilience/no-process-exit-in-finally.d.ts.map +1 -0
- package/dist/checks/resilience/no-process-exit-in-finally.js +89 -0
- package/dist/checks/resilience/no-process-exit-in-finally.js.map +1 -0
- package/dist/checks/resilience/readline-cleanup.d.ts +11 -0
- package/dist/checks/resilience/readline-cleanup.d.ts.map +1 -0
- package/dist/checks/resilience/readline-cleanup.js +107 -0
- package/dist/checks/resilience/readline-cleanup.js.map +1 -0
- package/dist/checks/resilience/recovery-patterns.d.ts +25 -0
- package/dist/checks/resilience/recovery-patterns.d.ts.map +1 -0
- package/dist/checks/resilience/recovery-patterns.js +273 -0
- package/dist/checks/resilience/recovery-patterns.js.map +1 -0
- package/dist/checks/resilience/reentrancy-guard.d.ts +12 -0
- package/dist/checks/resilience/reentrancy-guard.d.ts.map +1 -0
- package/dist/checks/resilience/reentrancy-guard.js +86 -0
- package/dist/checks/resilience/reentrancy-guard.js.map +1 -0
- package/dist/checks/resilience/retry-config-validation.d.ts +13 -0
- package/dist/checks/resilience/retry-config-validation.d.ts.map +1 -0
- package/dist/checks/resilience/retry-config-validation.js +159 -0
- package/dist/checks/resilience/retry-config-validation.js.map +1 -0
- package/dist/checks/resilience/sentry/_helpers/sentry.d.ts +25 -0
- package/dist/checks/resilience/sentry/_helpers/sentry.d.ts.map +1 -0
- package/dist/checks/resilience/sentry/_helpers/sentry.js +68 -0
- package/dist/checks/resilience/sentry/_helpers/sentry.js.map +1 -0
- package/dist/checks/resilience/sentry/index.d.ts +8 -0
- package/dist/checks/resilience/sentry/index.d.ts.map +1 -0
- package/dist/checks/resilience/sentry/index.js +8 -0
- package/dist/checks/resilience/sentry/index.js.map +1 -0
- package/dist/checks/resilience/sentry/sentry-dsn-configured.d.ts +12 -0
- package/dist/checks/resilience/sentry/sentry-dsn-configured.d.ts.map +1 -0
- package/dist/checks/resilience/sentry/sentry-dsn-configured.js +55 -0
- package/dist/checks/resilience/sentry/sentry-dsn-configured.js.map +1 -0
- package/dist/checks/resilience/sentry/sentry-environment-set.d.ts +12 -0
- package/dist/checks/resilience/sentry/sentry-environment-set.d.ts.map +1 -0
- package/dist/checks/resilience/sentry/sentry-environment-set.js +51 -0
- package/dist/checks/resilience/sentry/sentry-environment-set.js.map +1 -0
- package/dist/checks/resilience/sentry/sentry-error-boundary.d.ts +12 -0
- package/dist/checks/resilience/sentry/sentry-error-boundary.d.ts.map +1 -0
- package/dist/checks/resilience/sentry/sentry-error-boundary.js +75 -0
- package/dist/checks/resilience/sentry/sentry-error-boundary.js.map +1 -0
- package/dist/checks/resilience/sentry/sentry-pii-scrubbing.d.ts +13 -0
- package/dist/checks/resilience/sentry/sentry-pii-scrubbing.d.ts.map +1 -0
- package/dist/checks/resilience/sentry/sentry-pii-scrubbing.js +125 -0
- package/dist/checks/resilience/sentry/sentry-pii-scrubbing.js.map +1 -0
- package/dist/checks/resilience/sentry/sentry-release-set.d.ts +12 -0
- package/dist/checks/resilience/sentry/sentry-release-set.d.ts.map +1 -0
- package/dist/checks/resilience/sentry/sentry-release-set.js +51 -0
- package/dist/checks/resilience/sentry/sentry-release-set.js.map +1 -0
- package/dist/checks/resilience/sentry/sentry-sample-rate.d.ts +12 -0
- package/dist/checks/resilience/sentry/sentry-sample-rate.d.ts.map +1 -0
- package/dist/checks/resilience/sentry/sentry-sample-rate.js +78 -0
- package/dist/checks/resilience/sentry/sentry-sample-rate.js.map +1 -0
- package/dist/checks/resilience/sentry/sentry-source-maps.d.ts +12 -0
- package/dist/checks/resilience/sentry/sentry-source-maps.d.ts.map +1 -0
- package/dist/checks/resilience/sentry/sentry-source-maps.js +83 -0
- package/dist/checks/resilience/sentry/sentry-source-maps.js.map +1 -0
- package/dist/checks/resilience/service-patterns.d.ts +18 -0
- package/dist/checks/resilience/service-patterns.d.ts.map +1 -0
- package/dist/checks/resilience/service-patterns.js +230 -0
- package/dist/checks/resilience/service-patterns.js.map +1 -0
- package/dist/checks/resilience/timer-lifecycle.d.ts +10 -0
- package/dist/checks/resilience/timer-lifecycle.d.ts.map +1 -0
- package/dist/checks/resilience/timer-lifecycle.js +78 -0
- package/dist/checks/resilience/timer-lifecycle.js.map +1 -0
- package/dist/checks/resilience/transaction-patterns.d.ts +21 -0
- package/dist/checks/resilience/transaction-patterns.d.ts.map +1 -0
- package/dist/checks/resilience/transaction-patterns.js +258 -0
- package/dist/checks/resilience/transaction-patterns.js.map +1 -0
- package/dist/checks/security/__tests__/no-hardcoded-secrets.test.d.ts +9 -0
- package/dist/checks/security/__tests__/no-hardcoded-secrets.test.d.ts.map +1 -0
- package/dist/checks/security/__tests__/no-hardcoded-secrets.test.js +37 -0
- package/dist/checks/security/__tests__/no-hardcoded-secrets.test.js.map +1 -0
- package/dist/checks/security/__tests__/package-supply-chain-policy.test.d.ts +2 -0
- package/dist/checks/security/__tests__/package-supply-chain-policy.test.d.ts.map +1 -0
- package/dist/checks/security/__tests__/package-supply-chain-policy.test.js +128 -0
- package/dist/checks/security/__tests__/package-supply-chain-policy.test.js.map +1 -0
- package/dist/checks/security/api-key-rotation.d.ts +10 -0
- package/dist/checks/security/api-key-rotation.d.ts.map +1 -0
- package/dist/checks/security/api-key-rotation.js +186 -0
- package/dist/checks/security/api-key-rotation.js.map +1 -0
- package/dist/checks/security/auth-middleware-coverage.d.ts +11 -0
- package/dist/checks/security/auth-middleware-coverage.d.ts.map +1 -0
- package/dist/checks/security/auth-middleware-coverage.js +210 -0
- package/dist/checks/security/auth-middleware-coverage.js.map +1 -0
- package/dist/checks/security/auth-route-guard.d.ts +12 -0
- package/dist/checks/security/auth-route-guard.d.ts.map +1 -0
- package/dist/checks/security/auth-route-guard.js +70 -0
- package/dist/checks/security/auth-route-guard.js.map +1 -0
- package/dist/checks/security/cors-configuration.d.ts +11 -0
- package/dist/checks/security/cors-configuration.d.ts.map +1 -0
- package/dist/checks/security/cors-configuration.js +126 -0
- package/dist/checks/security/cors-configuration.js.map +1 -0
- package/dist/checks/security/csp-headers.d.ts +11 -0
- package/dist/checks/security/csp-headers.d.ts.map +1 -0
- package/dist/checks/security/csp-headers.js +192 -0
- package/dist/checks/security/csp-headers.js.map +1 -0
- package/dist/checks/security/dependency-vulnerability-audit.d.ts +15 -0
- package/dist/checks/security/dependency-vulnerability-audit.d.ts.map +1 -0
- package/dist/checks/security/dependency-vulnerability-audit.js +184 -0
- package/dist/checks/security/dependency-vulnerability-audit.js.map +1 -0
- package/dist/checks/security/env-secret-exposure.d.ts +11 -0
- package/dist/checks/security/env-secret-exposure.d.ts.map +1 -0
- package/dist/checks/security/env-secret-exposure.js +127 -0
- package/dist/checks/security/env-secret-exposure.js.map +1 -0
- package/dist/checks/security/hasura-production-config.d.ts +11 -0
- package/dist/checks/security/hasura-production-config.d.ts.map +1 -0
- package/dist/checks/security/hasura-production-config.js +122 -0
- package/dist/checks/security/hasura-production-config.js.map +1 -0
- package/dist/checks/security/index.d.ts +17 -0
- package/dist/checks/security/index.d.ts.map +1 -0
- package/dist/checks/security/index.js +17 -0
- package/dist/checks/security/index.js.map +1 -0
- package/dist/checks/security/jwt-validation.d.ts +11 -0
- package/dist/checks/security/jwt-validation.d.ts.map +1 -0
- package/dist/checks/security/jwt-validation.js +294 -0
- package/dist/checks/security/jwt-validation.js.map +1 -0
- package/dist/checks/security/no-eval.d.ts +16 -0
- package/dist/checks/security/no-eval.d.ts.map +1 -0
- package/dist/checks/security/no-eval.js +83 -0
- package/dist/checks/security/no-eval.js.map +1 -0
- package/dist/checks/security/no-hardcoded-secrets.d.ts +28 -0
- package/dist/checks/security/no-hardcoded-secrets.d.ts.map +1 -0
- package/dist/checks/security/no-hardcoded-secrets.js +209 -0
- package/dist/checks/security/no-hardcoded-secrets.js.map +1 -0
- package/dist/checks/security/package-supply-chain-policy.d.ts +12 -0
- package/dist/checks/security/package-supply-chain-policy.d.ts.map +1 -0
- package/dist/checks/security/package-supply-chain-policy.js +534 -0
- package/dist/checks/security/package-supply-chain-policy.js.map +1 -0
- package/dist/checks/security/rate-limit-coverage.d.ts +10 -0
- package/dist/checks/security/rate-limit-coverage.d.ts.map +1 -0
- package/dist/checks/security/rate-limit-coverage.js +143 -0
- package/dist/checks/security/rate-limit-coverage.js.map +1 -0
- package/dist/checks/security/semgrep-scan.d.ts +13 -0
- package/dist/checks/security/semgrep-scan.d.ts.map +1 -0
- package/dist/checks/security/semgrep-scan.js +86 -0
- package/dist/checks/security/semgrep-scan.js.map +1 -0
- package/dist/checks/security/use-centralized-crypto.d.ts +11 -0
- package/dist/checks/security/use-centralized-crypto.d.ts.map +1 -0
- package/dist/checks/security/use-centralized-crypto.js +129 -0
- package/dist/checks/security/use-centralized-crypto.js.map +1 -0
- package/dist/checks/security/webhook-signature-verification.d.ts +10 -0
- package/dist/checks/security/webhook-signature-verification.d.ts.map +1 -0
- package/dist/checks/security/webhook-signature-verification.js +183 -0
- package/dist/checks/security/webhook-signature-verification.js.map +1 -0
- package/dist/checks/testing/index.d.ts +6 -0
- package/dist/checks/testing/index.d.ts.map +1 -0
- package/dist/checks/testing/index.js +6 -0
- package/dist/checks/testing/index.js.map +1 -0
- package/dist/checks/testing/no-skipped-tests.d.ts +40 -0
- package/dist/checks/testing/no-skipped-tests.d.ts.map +1 -0
- package/dist/checks/testing/no-skipped-tests.js +174 -0
- package/dist/checks/testing/no-skipped-tests.js.map +1 -0
- package/dist/checks/testing/no-stub-tests.d.ts +11 -0
- package/dist/checks/testing/no-stub-tests.d.ts.map +1 -0
- package/dist/checks/testing/no-stub-tests.js +103 -0
- package/dist/checks/testing/no-stub-tests.js.map +1 -0
- package/dist/checks/testing/test-convention-consistency.d.ts +14 -0
- package/dist/checks/testing/test-convention-consistency.d.ts.map +1 -0
- package/dist/checks/testing/test-convention-consistency.js +93 -0
- package/dist/checks/testing/test-convention-consistency.js.map +1 -0
- package/dist/checks/testing/test-file-naming.d.ts +13 -0
- package/dist/checks/testing/test-file-naming.d.ts.map +1 -0
- package/dist/checks/testing/test-file-naming.js +218 -0
- package/dist/checks/testing/test-file-naming.js.map +1 -0
- package/dist/checks/testing/test-file-pairing.d.ts +13 -0
- package/dist/checks/testing/test-file-pairing.d.ts.map +1 -0
- package/dist/checks/testing/test-file-pairing.js +274 -0
- package/dist/checks/testing/test-file-pairing.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 +29 -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 +34 -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 +36 -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 +31 -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 +52 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview No Custom Event Emitter check
|
|
3
|
+
*/
|
|
4
|
+
import { defineCheck } from '@opensip-cli/fitness';
|
|
5
|
+
/**
|
|
6
|
+
* Creates a pre-compiled RegExp for pattern matching.
|
|
7
|
+
* These patterns operate on trusted source code files, not user input.
|
|
8
|
+
* @param pattern - The regex pattern string
|
|
9
|
+
* @param flags - Optional regex flags
|
|
10
|
+
* @returns Compiled RegExp object
|
|
11
|
+
*/
|
|
12
|
+
function createPattern(pattern, flags) {
|
|
13
|
+
// @fitness-ignore-next-line semgrep-scan -- non-literal RegExp is intentional; patterns are hardcoded string constants for code analysis, not user input
|
|
14
|
+
return new RegExp(pattern, flags);
|
|
15
|
+
}
|
|
16
|
+
// Note: These regex patterns operate on trusted source code files, not user input.
|
|
17
|
+
// The patterns use bounded character classes ([^}]*) instead of .* to prevent ReDoS.
|
|
18
|
+
const EVENT_EMITTER_PATTERNS = [
|
|
19
|
+
{
|
|
20
|
+
// Fixed pattern - no backtracking issues
|
|
21
|
+
pattern: createPattern(String.raw `new\s+EventEmitter\s*\(`, 'g'),
|
|
22
|
+
type: 'new-event-emitter',
|
|
23
|
+
suggestion: 'Use a centralized event bus instead of direct EventEmitter instantiation',
|
|
24
|
+
severity: 'error',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
// Fixed pattern - word boundary prevents issues
|
|
28
|
+
pattern: createPattern(String.raw `extends\s+EventEmitter\b`, 'g'),
|
|
29
|
+
type: 'extends-event-emitter',
|
|
30
|
+
suggestion: 'Implement event handling via a centralized event bus instead of extending EventEmitter',
|
|
31
|
+
severity: 'error',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
// Use [^}]* (bounded by curly brace) instead of .* to prevent catastrophic backtracking
|
|
35
|
+
pattern: createPattern(String.raw `import\s+[^}]*\bEventEmitter\b[^}]*from\s+['"]events['"]`, 'g'),
|
|
36
|
+
type: 'import-event-emitter',
|
|
37
|
+
suggestion: 'Use a centralized event bus instead of importing EventEmitter directly',
|
|
38
|
+
severity: 'error',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
// Use [^}]* (bounded by curly brace) instead of .* to prevent catastrophic backtracking
|
|
42
|
+
pattern: createPattern(String.raw `import\s+[^}]*\bEventEmitter\b[^}]*from\s+['"]node:events['"]`, 'g'),
|
|
43
|
+
type: 'import-event-emitter',
|
|
44
|
+
suggestion: 'Use a centralized event bus instead of importing EventEmitter directly',
|
|
45
|
+
severity: 'error',
|
|
46
|
+
},
|
|
47
|
+
];
|
|
48
|
+
const EVENT_INFRA_PATTERNS = [
|
|
49
|
+
/infrastructure\/events\//,
|
|
50
|
+
/foundation\//,
|
|
51
|
+
/\/adapters\//,
|
|
52
|
+
/interfaces\//,
|
|
53
|
+
];
|
|
54
|
+
function analyzeFile(filePath, content) {
|
|
55
|
+
const issues = [];
|
|
56
|
+
if (EVENT_INFRA_PATTERNS.some((p) => p.test(filePath))) {
|
|
57
|
+
return [];
|
|
58
|
+
}
|
|
59
|
+
const lines = content.split('\n');
|
|
60
|
+
for (const [i, line] of lines.entries()) {
|
|
61
|
+
if (!line)
|
|
62
|
+
continue;
|
|
63
|
+
for (const { pattern, type, suggestion, severity } of EVENT_EMITTER_PATTERNS) {
|
|
64
|
+
pattern.lastIndex = 0;
|
|
65
|
+
const match = pattern.exec(line);
|
|
66
|
+
if (match) {
|
|
67
|
+
issues.push({
|
|
68
|
+
file: filePath,
|
|
69
|
+
line: i + 1,
|
|
70
|
+
type,
|
|
71
|
+
match: match[0],
|
|
72
|
+
suggestion,
|
|
73
|
+
severity,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return issues;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Check: architecture/no-custom-event-emitter
|
|
82
|
+
*
|
|
83
|
+
* Detects direct EventEmitter usage that should use infrastructure/events module.
|
|
84
|
+
* Ensures consistent event handling patterns across the codebase.
|
|
85
|
+
*/
|
|
86
|
+
export const noCustomEventEmitter = defineCheck({
|
|
87
|
+
id: '7a36c3b8-fb23-42fc-8f25-336e012aab57',
|
|
88
|
+
slug: 'no-custom-event-emitter',
|
|
89
|
+
disabled: true,
|
|
90
|
+
scope: { languages: ['typescript'], concerns: ['backend', 'server'] },
|
|
91
|
+
contentFilter: 'strip-strings',
|
|
92
|
+
confidence: 'medium',
|
|
93
|
+
description: 'Detects direct EventEmitter usage that should use infrastructure/events',
|
|
94
|
+
longDescription: `**Purpose:** Prevents direct usage of Node.js \`EventEmitter\` in favor of a centralized event bus.
|
|
95
|
+
|
|
96
|
+
**Detects:**
|
|
97
|
+
- Direct instantiation of Node.js event emitter
|
|
98
|
+
- Class inheritance from Node.js event emitter
|
|
99
|
+
- Imports of Node.js event emitter from 'events' or 'node:events'
|
|
100
|
+
- Excludes \`infrastructure/events/\`, \`foundation/\`, \`/adapters/\`, and \`interfaces/\` directories
|
|
101
|
+
|
|
102
|
+
**Why it matters:** Custom event emitters bypass centralized event bus patterns, making event flows untraceable and inconsistent across the platform.
|
|
103
|
+
|
|
104
|
+
**Scope:** Codebase-specific convention. Analyzes each file individually.`,
|
|
105
|
+
tags: ['architecture', 'best-practices'],
|
|
106
|
+
fileTypes: ['ts'],
|
|
107
|
+
analyze(content, filePath) {
|
|
108
|
+
// Skip if no EventEmitter usage
|
|
109
|
+
if (!content.includes('EventEmitter')) {
|
|
110
|
+
return [];
|
|
111
|
+
}
|
|
112
|
+
const issues = analyzeFile(filePath, content);
|
|
113
|
+
return issues.map((issue) => ({
|
|
114
|
+
line: issue.line,
|
|
115
|
+
message: `Custom event emitter: ${issue.type}. ${issue.suggestion}`,
|
|
116
|
+
severity: issue.severity,
|
|
117
|
+
suggestion: issue.suggestion,
|
|
118
|
+
match: issue.match,
|
|
119
|
+
type: issue.type,
|
|
120
|
+
}));
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
//# sourceMappingURL=no-custom-event-emitter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-custom-event-emitter.js","sourceRoot":"","sources":["../../../src/checks/architecture/no-custom-event-emitter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview A command handler must not index its parsed-options object by a
|
|
3
|
+
* KEBAB-CASE string literal — Commander camelCases long flags, so the kebab key
|
|
4
|
+
* is always `undefined`.
|
|
5
|
+
*
|
|
6
|
+
* WHY (the drift this freezes out):
|
|
7
|
+
* Commander stores `--summary-only` under `opts.summaryOnly`, `--report-to`
|
|
8
|
+
* under `opts.reportTo`, etc. — it camelCases the long flag when it builds the
|
|
9
|
+
* parsed-options object. A handler that reads `opts['summary-only']` therefore
|
|
10
|
+
* reads a key Commander NEVER sets: the value is silently `undefined`, the flag
|
|
11
|
+
* becomes a permanent no-op, and the bug is invisible (no crash, no warning).
|
|
12
|
+
* This is a recurring CLI footgun whenever a multi-word flag is wired by hand.
|
|
13
|
+
*
|
|
14
|
+
* DETECTION — regex on RAW content (the kebab string literal IS the signal, so it
|
|
15
|
+
* must NOT be stripped; comment lines are skipped manually). Flags an index
|
|
16
|
+
* access on a Commander-convention options identifier (`opts` / `rawOpts` /
|
|
17
|
+
* `cmdOpts` / `parsedOpts` / `cmdOptions`) whose key is a kebab-case string
|
|
18
|
+
* literal (`['a-b']`). camelCase keys, numeric keys, and non-options objects
|
|
19
|
+
* (`headers['content-type']`, `style['font-size']`) do not match.
|
|
20
|
+
*
|
|
21
|
+
* SCOPE — TypeScript backend/CLI sources. This is a generic Commander
|
|
22
|
+
* best-practice (a kebab-indexed parsed-options read is wrong in any
|
|
23
|
+
* Commander-based CLI), so there is no repo-specific path guard. Test files are
|
|
24
|
+
* skipped.
|
|
25
|
+
*/
|
|
26
|
+
import { type CheckViolation } from '@opensip-cli/fitness';
|
|
27
|
+
/**
|
|
28
|
+
* Pure analysis over one source file. Returns a finding for each kebab-indexed
|
|
29
|
+
* parsed-options read. Exported for unit tests.
|
|
30
|
+
*/
|
|
31
|
+
export declare function analyzeNoKebabOptionIndexing(content: string, filePath: string): CheckViolation[];
|
|
32
|
+
export declare const noKebabOptionIndexing: import("@opensip-cli/fitness").Check;
|
|
33
|
+
//# sourceMappingURL=no-kebab-option-indexing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-kebab-option-indexing.d.ts","sourceRoot":"","sources":["../../../src/checks/architecture/no-kebab-option-indexing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EAAe,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAcxE;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,cAAc,EAAE,CA4BhG;AAED,eAAO,MAAM,qBAAqB,sCAYhC,CAAC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview A command handler must not index its parsed-options object by a
|
|
3
|
+
* KEBAB-CASE string literal — Commander camelCases long flags, so the kebab key
|
|
4
|
+
* is always `undefined`.
|
|
5
|
+
*
|
|
6
|
+
* WHY (the drift this freezes out):
|
|
7
|
+
* Commander stores `--summary-only` under `opts.summaryOnly`, `--report-to`
|
|
8
|
+
* under `opts.reportTo`, etc. — it camelCases the long flag when it builds the
|
|
9
|
+
* parsed-options object. A handler that reads `opts['summary-only']` therefore
|
|
10
|
+
* reads a key Commander NEVER sets: the value is silently `undefined`, the flag
|
|
11
|
+
* becomes a permanent no-op, and the bug is invisible (no crash, no warning).
|
|
12
|
+
* This is a recurring CLI footgun whenever a multi-word flag is wired by hand.
|
|
13
|
+
*
|
|
14
|
+
* DETECTION — regex on RAW content (the kebab string literal IS the signal, so it
|
|
15
|
+
* must NOT be stripped; comment lines are skipped manually). Flags an index
|
|
16
|
+
* access on a Commander-convention options identifier (`opts` / `rawOpts` /
|
|
17
|
+
* `cmdOpts` / `parsedOpts` / `cmdOptions`) whose key is a kebab-case string
|
|
18
|
+
* literal (`['a-b']`). camelCase keys, numeric keys, and non-options objects
|
|
19
|
+
* (`headers['content-type']`, `style['font-size']`) do not match.
|
|
20
|
+
*
|
|
21
|
+
* SCOPE — TypeScript backend/CLI sources. This is a generic Commander
|
|
22
|
+
* best-practice (a kebab-indexed parsed-options read is wrong in any
|
|
23
|
+
* Commander-based CLI), so there is no repo-specific path guard. Test files are
|
|
24
|
+
* skipped.
|
|
25
|
+
*/
|
|
26
|
+
import { defineCheck } from '@opensip-cli/fitness';
|
|
27
|
+
/** Test-file fragments — skipped. */
|
|
28
|
+
const TEST_PATH = /(?:\.test\.tsx?$|\/__tests__\/)/;
|
|
29
|
+
/**
|
|
30
|
+
* `<optsVar>['<kebab-case>']` — a parsed-options index by a kebab string literal.
|
|
31
|
+
* The identifier set is the Commander parsed-options naming convention; the key
|
|
32
|
+
* must contain at least one `-` (kebab), which a camelCased Commander key never
|
|
33
|
+
* does.
|
|
34
|
+
*/
|
|
35
|
+
const KEBAB_OPTION_INDEX_RE = /\b(?:opts|rawOpts|cmdOpts|parsedOpts|cmdOptions)\s*\[\s*(['"])([a-z][a-z0-9]*(?:-[a-z0-9]+)+)\1\s*\]/g;
|
|
36
|
+
/**
|
|
37
|
+
* Pure analysis over one source file. Returns a finding for each kebab-indexed
|
|
38
|
+
* parsed-options read. Exported for unit tests.
|
|
39
|
+
*/
|
|
40
|
+
export function analyzeNoKebabOptionIndexing(content, filePath) {
|
|
41
|
+
if (TEST_PATH.test(filePath.replaceAll('\\', '/')))
|
|
42
|
+
return [];
|
|
43
|
+
const violations = [];
|
|
44
|
+
const lines = content.split('\n');
|
|
45
|
+
for (const [i, rawLine] of lines.entries()) {
|
|
46
|
+
// Skip comment lines so prose/examples mentioning the pattern don't fire
|
|
47
|
+
// (content is raw, so the kebab literal survives — we must comment-skip here).
|
|
48
|
+
const trimmed = rawLine.trimStart();
|
|
49
|
+
if (trimmed.startsWith('*') || trimmed.startsWith('//'))
|
|
50
|
+
continue;
|
|
51
|
+
KEBAB_OPTION_INDEX_RE.lastIndex = 0;
|
|
52
|
+
let m;
|
|
53
|
+
while ((m = KEBAB_OPTION_INDEX_RE.exec(rawLine)) !== null) {
|
|
54
|
+
const kebabKey = m[2];
|
|
55
|
+
const camel = kebabKey.replaceAll(/-([a-z0-9])/g, (_, c) => c.toUpperCase());
|
|
56
|
+
violations.push({
|
|
57
|
+
line: i + 1,
|
|
58
|
+
message: `Parsed options indexed by the kebab-case key '${kebabKey}'. Commander ` +
|
|
59
|
+
`camelCases long flags, so it stores this under '${camel}' — the kebab key is ` +
|
|
60
|
+
`always undefined and the flag is a silent no-op.`,
|
|
61
|
+
severity: 'error',
|
|
62
|
+
suggestion: `Read the camelCased key Commander actually sets: 'opts.${camel}'.`,
|
|
63
|
+
type: 'no-kebab-option-indexing',
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return violations;
|
|
68
|
+
}
|
|
69
|
+
export const noKebabOptionIndexing = defineCheck({
|
|
70
|
+
id: '64bb7fa7-3e0d-4f4d-a1e6-d7b189df053c',
|
|
71
|
+
slug: 'no-kebab-option-indexing',
|
|
72
|
+
description: 'Command handlers must not index parsed options by a kebab-case key — Commander camelCases long flags, so the kebab key is always undefined (silent no-op flag)',
|
|
73
|
+
scope: { languages: ['typescript'], concerns: ['backend'] },
|
|
74
|
+
tags: ['architecture'],
|
|
75
|
+
fileTypes: ['ts'],
|
|
76
|
+
// raw: the kebab-case string literal IS the signal — strip-strings would blank
|
|
77
|
+
// it. Comment lines are skipped in the analyzer so prose does not false-fire.
|
|
78
|
+
contentFilter: 'raw',
|
|
79
|
+
analyze: (content, filePath) => analyzeNoKebabOptionIndexing(content, filePath),
|
|
80
|
+
});
|
|
81
|
+
//# sourceMappingURL=no-kebab-option-indexing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-kebab-option-indexing.js","sourceRoot":"","sources":["../../../src/checks/architecture/no-kebab-option-indexing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EAAE,WAAW,EAAuB,MAAM,sBAAsB,CAAC;AAExE,qCAAqC;AACrC,MAAM,SAAS,GAAG,iCAAiC,CAAC;AAEpD;;;;;GAKG;AACH,MAAM,qBAAqB,GACzB,uGAAuG,CAAC;AAE1G;;;GAGG;AACH,MAAM,UAAU,4BAA4B,CAAC,OAAe,EAAE,QAAgB;IAC5E,IAAI,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAAE,OAAO,EAAE,CAAC;IAE9D,MAAM,UAAU,GAAqB,EAAE,CAAC;IACxC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,KAAK,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;QAC3C,yEAAyE;QACzE,+EAA+E;QAC/E,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;QACpC,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,SAAS;QAClE,qBAAqB,CAAC,SAAS,GAAG,CAAC,CAAC;QACpC,IAAI,CAAyB,CAAC;QAC9B,OAAO,CAAC,CAAC,GAAG,qBAAqB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YAC1D,MAAM,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACtB,MAAM,KAAK,GAAG,QAAQ,CAAC,UAAU,CAAC,cAAc,EAAE,CAAC,CAAC,EAAE,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;YACrF,UAAU,CAAC,IAAI,CAAC;gBACd,IAAI,EAAE,CAAC,GAAG,CAAC;gBACX,OAAO,EACL,iDAAiD,QAAQ,eAAe;oBACxE,mDAAmD,KAAK,uBAAuB;oBAC/E,kDAAkD;gBACpD,QAAQ,EAAE,OAAO;gBACjB,UAAU,EAAE,0DAA0D,KAAK,IAAI;gBAC/E,IAAI,EAAE,0BAA0B;aACjC,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,gKAAgK;IAClK,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,CAAC;IACjB,+EAA+E;IAC/E,8EAA8E;IAC9E,aAAa,EAAE,KAAK;IACpB,OAAO,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,CAAC,4BAA4B,CAAC,OAAO,EAAE,QAAQ,CAAC;CAChF,CAAC,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Node version consistency fitness check
|
|
3
|
+
* @invariants
|
|
4
|
+
* - All engines.node fields must match root package.json
|
|
5
|
+
* - .nvmrc major version must match engines.node
|
|
6
|
+
* - @types/node major version must match engines.node
|
|
7
|
+
* - CI workflow node-version must match engines.node
|
|
8
|
+
* - Dockerfiles are NOT checked (covered by docker-version-sync)
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Check: architecture/node-version-consistency
|
|
12
|
+
*
|
|
13
|
+
* Validates that Node.js version references are consistent across the codebase:
|
|
14
|
+
* 1. .nvmrc matches root package.json engines.node
|
|
15
|
+
* 2. All workspace package.json engines.node fields match root
|
|
16
|
+
* 3. @types/node major version matches engines.node major
|
|
17
|
+
* 4. CI workflow node-version matches engines.node
|
|
18
|
+
*
|
|
19
|
+
* Note: Dockerfile FROM node:XX checks are handled by docker-version-sync.
|
|
20
|
+
*/
|
|
21
|
+
export declare const nodeVersionConsistency: import("@opensip-cli/fitness").Check;
|
|
22
|
+
//# sourceMappingURL=node-version-consistency.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-version-consistency.d.ts","sourceRoot":"","sources":["../../../src/checks/architecture/node-version-consistency.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAkMH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,sBAAsB,sCAqEjC,CAAC"}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
// @fitness-ignore-file fitness-check-standards -- Uses fs for package.json reading, not source file content
|
|
2
|
+
// @fitness-ignore-file detached-promises -- helpers (checkNvmrc, checkWorkspaceEngines, checkTypesNode, checkCiWorkflow) are synchronous violation-collectors; heuristic flags them despite returning void
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview Node version consistency fitness check
|
|
5
|
+
* @invariants
|
|
6
|
+
* - All engines.node fields must match root package.json
|
|
7
|
+
* - .nvmrc major version must match engines.node
|
|
8
|
+
* - @types/node major version must match engines.node
|
|
9
|
+
* - CI workflow node-version must match engines.node
|
|
10
|
+
* - Dockerfiles are NOT checked (covered by docker-version-sync)
|
|
11
|
+
*/
|
|
12
|
+
import * as path from 'node:path';
|
|
13
|
+
import { defineCheck } from '@opensip-cli/fitness';
|
|
14
|
+
// =============================================================================
|
|
15
|
+
// REGEX PATTERNS
|
|
16
|
+
// =============================================================================
|
|
17
|
+
/** Extract major version from engines.node constraint like ">=24.0.0" -> 24 */
|
|
18
|
+
const ENGINES_NODE_MAJOR = /(\d+)/;
|
|
19
|
+
/** Match @types/node version like "^24.0.0" -> 24 */
|
|
20
|
+
const TYPES_NODE_MAJOR = /\^(\d+)/;
|
|
21
|
+
/** Match node-version in CI workflow YAML */
|
|
22
|
+
const CI_NODE_VERSION = /node-version:\s*['"]?(\d+)['"]?/;
|
|
23
|
+
// =============================================================================
|
|
24
|
+
// HELPERS
|
|
25
|
+
// =============================================================================
|
|
26
|
+
/**
|
|
27
|
+
* Extract major Node version from engines.node constraint.
|
|
28
|
+
* e.g. ">=24.0.0" -> 24
|
|
29
|
+
*/
|
|
30
|
+
function extractNodeMajor(constraint) {
|
|
31
|
+
const match = ENGINES_NODE_MAJOR.exec(constraint);
|
|
32
|
+
/* v8 ignore next 3 -- defensive: regex (\d+) ensures group [1] is set when match succeeds */
|
|
33
|
+
const digit = match?.[1];
|
|
34
|
+
// @fitness-ignore-next-line numeric-validation -- regex guarantees digit-only string; null guard above
|
|
35
|
+
return digit ? Number.parseInt(digit, 10) : null;
|
|
36
|
+
}
|
|
37
|
+
// =============================================================================
|
|
38
|
+
// PER-FILE ANALYSIS HELPERS
|
|
39
|
+
// =============================================================================
|
|
40
|
+
function checkNvmrc(content, filePath, expectedMajor, violations) {
|
|
41
|
+
const trimmed = content.trim();
|
|
42
|
+
const nvmrcMajor = Number.parseInt(trimmed, 10);
|
|
43
|
+
/* v8 ignore next -- defensive: malformed .nvmrc not exercised in fixtures */
|
|
44
|
+
if (Number.isNaN(nvmrcMajor))
|
|
45
|
+
return;
|
|
46
|
+
if (nvmrcMajor !== expectedMajor) {
|
|
47
|
+
violations.push({
|
|
48
|
+
line: 1,
|
|
49
|
+
filePath,
|
|
50
|
+
message: `.nvmrc specifies Node ${nvmrcMajor} but root package.json engines.node requires ${expectedMajor}`,
|
|
51
|
+
severity: 'error',
|
|
52
|
+
suggestion: `Change .nvmrc from "${trimmed}" to "${expectedMajor}"`,
|
|
53
|
+
type: 'nvmrc-version-mismatch',
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function checkWorkspaceEngines(content, filePath, expectedMajor, rootConstraint, violations) {
|
|
58
|
+
let pkg;
|
|
59
|
+
try {
|
|
60
|
+
pkg = JSON.parse(content);
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
/* v8 ignore next -- defensive: malformed workspace package.json not exercised in fixtures */
|
|
64
|
+
// @swallow-ok expected for non-JSON files or malformed package.json
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const enginesNode = pkg.engines?.node;
|
|
68
|
+
if (!enginesNode)
|
|
69
|
+
return;
|
|
70
|
+
const workspaceMajor = extractNodeMajor(enginesNode);
|
|
71
|
+
/* v8 ignore next -- defensive: enginesNode already checked, regex match guaranteed */
|
|
72
|
+
if (workspaceMajor === null)
|
|
73
|
+
return;
|
|
74
|
+
if (workspaceMajor !== expectedMajor) {
|
|
75
|
+
const relPath = path.relative(process.cwd(), filePath);
|
|
76
|
+
violations.push({
|
|
77
|
+
line: 1,
|
|
78
|
+
filePath,
|
|
79
|
+
message: `${relPath} engines.node is "${enginesNode}" but root package.json has "${rootConstraint}"`,
|
|
80
|
+
severity: 'error',
|
|
81
|
+
suggestion: `Change engines.node from "${enginesNode}" to "${rootConstraint}"`,
|
|
82
|
+
type: 'workspace-engines-mismatch',
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function checkTypesNode(content, filePath, expectedMajor, violations) {
|
|
87
|
+
let pkg;
|
|
88
|
+
try {
|
|
89
|
+
pkg = JSON.parse(content);
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
/* v8 ignore next -- defensive: malformed workspace package.json not exercised in fixtures */
|
|
93
|
+
// @swallow-ok expected for non-JSON files or malformed package.json
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
/* v8 ignore next -- defensive: pkg.dependencies fallback when devDependencies missing */
|
|
97
|
+
const typesNodeVersion = pkg.devDependencies?.['@types/node'] ?? pkg.dependencies?.['@types/node'];
|
|
98
|
+
if (!typesNodeVersion)
|
|
99
|
+
return;
|
|
100
|
+
const match = TYPES_NODE_MAJOR.exec(typesNodeVersion);
|
|
101
|
+
/* v8 ignore next 2 -- defensive: regex ^\d+ ensures group [1] is set when match succeeds */
|
|
102
|
+
const typesMajor = match?.[1];
|
|
103
|
+
if (!typesMajor)
|
|
104
|
+
return;
|
|
105
|
+
// @fitness-ignore-next-line numeric-validation -- regex ^\d+ guarantees digit-only string
|
|
106
|
+
const typesMajorNum = Number.parseInt(typesMajor, 10);
|
|
107
|
+
if (typesMajorNum !== expectedMajor) {
|
|
108
|
+
const relPath = path.relative(process.cwd(), filePath);
|
|
109
|
+
violations.push({
|
|
110
|
+
line: 1,
|
|
111
|
+
filePath,
|
|
112
|
+
message: `${relPath} has @types/node "${typesNodeVersion}" but engines.node major is ${expectedMajor}`,
|
|
113
|
+
severity: 'error',
|
|
114
|
+
suggestion: `Change @types/node from "${typesNodeVersion}" to "^${expectedMajor}.0.0"`,
|
|
115
|
+
type: 'types-node-mismatch',
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function checkCiWorkflow(content, filePath, expectedMajor, violations) {
|
|
120
|
+
const lines = content.split('\n');
|
|
121
|
+
for (const [i, rawLine] of lines.entries()) {
|
|
122
|
+
/* v8 ignore next -- defensive: lines.entries() never yields undefined */
|
|
123
|
+
if (!rawLine)
|
|
124
|
+
continue;
|
|
125
|
+
const line = rawLine.trim();
|
|
126
|
+
const match = CI_NODE_VERSION.exec(line);
|
|
127
|
+
/* v8 ignore next 2 -- defensive: regex (\d+) ensures group [1] is set when match succeeds */
|
|
128
|
+
const ciVersion = match?.[1];
|
|
129
|
+
if (!ciVersion)
|
|
130
|
+
continue;
|
|
131
|
+
// @fitness-ignore-next-line numeric-validation -- regex (\d+) guarantees digit-only string
|
|
132
|
+
const ciMajor = Number.parseInt(ciVersion, 10);
|
|
133
|
+
if (ciMajor !== expectedMajor) {
|
|
134
|
+
violations.push({
|
|
135
|
+
line: i + 1,
|
|
136
|
+
filePath,
|
|
137
|
+
message: `CI workflow uses node-version: '${ciVersion}' but root package.json engines.node requires ${expectedMajor}`,
|
|
138
|
+
severity: 'error',
|
|
139
|
+
suggestion: `Change node-version from '${ciVersion}' to '${expectedMajor}'`,
|
|
140
|
+
type: 'ci-node-version-mismatch',
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// =============================================================================
|
|
146
|
+
// CHECK DEFINITION
|
|
147
|
+
// =============================================================================
|
|
148
|
+
/**
|
|
149
|
+
* Check: architecture/node-version-consistency
|
|
150
|
+
*
|
|
151
|
+
* Validates that Node.js version references are consistent across the codebase:
|
|
152
|
+
* 1. .nvmrc matches root package.json engines.node
|
|
153
|
+
* 2. All workspace package.json engines.node fields match root
|
|
154
|
+
* 3. @types/node major version matches engines.node major
|
|
155
|
+
* 4. CI workflow node-version matches engines.node
|
|
156
|
+
*
|
|
157
|
+
* Note: Dockerfile FROM node:XX checks are handled by docker-version-sync.
|
|
158
|
+
*/
|
|
159
|
+
export const nodeVersionConsistency = defineCheck({
|
|
160
|
+
id: 'e32068df-b100-4406-a8ba-caec5d53fa92',
|
|
161
|
+
slug: 'node-version-consistency',
|
|
162
|
+
scope: { languages: ['json', 'typescript', 'yaml'], concerns: ['config'] },
|
|
163
|
+
contentFilter: 'raw',
|
|
164
|
+
confidence: 'medium',
|
|
165
|
+
description: 'Validate Node.js version consistency across configs',
|
|
166
|
+
longDescription: `**Purpose:** Ensures all Node.js version references across the codebase stay in sync with the root \`package.json\` \`engines.node\` field.
|
|
167
|
+
|
|
168
|
+
**Detects:**
|
|
169
|
+
- \`.nvmrc\` major version mismatches against \`engines.node\`
|
|
170
|
+
- Workspace \`package.json\` \`engines.node\` fields that differ from root
|
|
171
|
+
- \`@types/node\` major version mismatches in any \`package.json\`
|
|
172
|
+
- CI workflow \`node-version:\` lines that don't match
|
|
173
|
+
|
|
174
|
+
**Why it matters:** Version drift between .nvmrc, CI, and package.json leads to "works on my machine" issues and inconsistent runtime behavior.
|
|
175
|
+
|
|
176
|
+
**Scope:** Codebase-specific convention. Cross-file analysis via \`analyzeAll\`. Dockerfiles are intentionally excluded (covered by \`docker-version-sync\`).`,
|
|
177
|
+
tags: ['node', 'version-sync', 'architecture'],
|
|
178
|
+
async analyzeAll(files) {
|
|
179
|
+
const violations = [];
|
|
180
|
+
// Find the root package.json from the scanned file set.
|
|
181
|
+
// The root is the shortest path (shallowest) package.json in the set.
|
|
182
|
+
const packageJsonPaths = files.paths.filter((p) => path.basename(p) === 'package.json');
|
|
183
|
+
if (packageJsonPaths.length === 0)
|
|
184
|
+
return violations;
|
|
185
|
+
const rootPkgPath = packageJsonPaths.reduce((shortest, p) => (p.length < shortest.length ? p : shortest),
|
|
186
|
+
/* v8 ignore next -- defensive: packageJsonPaths.length checked above */
|
|
187
|
+
packageJsonPaths[0]);
|
|
188
|
+
// Read root package.json for version truth
|
|
189
|
+
const rootContent = await files.read(rootPkgPath);
|
|
190
|
+
let rootPkg;
|
|
191
|
+
try {
|
|
192
|
+
rootPkg = JSON.parse(rootContent);
|
|
193
|
+
}
|
|
194
|
+
catch {
|
|
195
|
+
return violations;
|
|
196
|
+
}
|
|
197
|
+
const rootConstraint = rootPkg.engines?.node;
|
|
198
|
+
if (!rootConstraint)
|
|
199
|
+
return violations;
|
|
200
|
+
const expectedMajor = extractNodeMajor(rootConstraint);
|
|
201
|
+
/* v8 ignore next -- defensive: rootConstraint already checked, regex (\d+) ensures match */
|
|
202
|
+
if (expectedMajor === null)
|
|
203
|
+
return violations;
|
|
204
|
+
for (const filePath of files.paths) {
|
|
205
|
+
// @fitness-ignore-next-line performance-anti-patterns -- sequential file reading to control memory; FileAccessor is lazy
|
|
206
|
+
const content = await files.read(filePath);
|
|
207
|
+
const basename = path.basename(filePath);
|
|
208
|
+
if (basename === '.nvmrc') {
|
|
209
|
+
checkNvmrc(content, filePath, expectedMajor, violations);
|
|
210
|
+
}
|
|
211
|
+
else if (basename === 'package.json') {
|
|
212
|
+
// Skip root package.json (it's the source of truth)
|
|
213
|
+
if (filePath === rootPkgPath)
|
|
214
|
+
continue;
|
|
215
|
+
checkWorkspaceEngines(content, filePath, expectedMajor, rootConstraint, violations);
|
|
216
|
+
checkTypesNode(content, filePath, expectedMajor, violations);
|
|
217
|
+
}
|
|
218
|
+
else if (filePath.includes('.github/workflows/') && basename.endsWith('.yml')) {
|
|
219
|
+
checkCiWorkflow(content, filePath, expectedMajor, violations);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
return violations;
|
|
223
|
+
},
|
|
224
|
+
});
|
|
225
|
+
//# sourceMappingURL=node-version-consistency.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-version-consistency.js","sourceRoot":"","sources":["../../../src/checks/architecture/node-version-consistency.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Project README existence check
|
|
3
|
+
*
|
|
4
|
+
* Ensures every package, app, CLI, and service has a README.md file.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Check: architecture/project-readme-existence
|
|
8
|
+
*
|
|
9
|
+
* Ensures every package, app, CLI tool, and service has a README.md file
|
|
10
|
+
* for documentation and discoverability.
|
|
11
|
+
*/
|
|
12
|
+
export declare const projectReadmeExistence: import("@opensip-cli/fitness").Check;
|
|
13
|
+
//# sourceMappingURL=project-readme-existence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-readme-existence.d.ts","sourceRoot":"","sources":["../../../src/checks/architecture/project-readme-existence.ts"],"names":[],"mappings":"AACA;;;;GAIG;AAOH;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,sCA6CjC,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// @fitness-ignore-file fitness-check-standards -- Uses fs for README existence checking, not source file content
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview Project README existence check
|
|
4
|
+
*
|
|
5
|
+
* Ensures every package, app, CLI, and service has a README.md file.
|
|
6
|
+
*/
|
|
7
|
+
import * as fs from 'node:fs';
|
|
8
|
+
import * as path from 'node:path';
|
|
9
|
+
import { defineCheck } from '@opensip-cli/fitness';
|
|
10
|
+
/**
|
|
11
|
+
* Check: architecture/project-readme-existence
|
|
12
|
+
*
|
|
13
|
+
* Ensures every package, app, CLI tool, and service has a README.md file
|
|
14
|
+
* for documentation and discoverability.
|
|
15
|
+
*/
|
|
16
|
+
export const projectReadmeExistence = defineCheck({
|
|
17
|
+
id: 'b7c3a2c2-0448-405f-86e3-8b5fca987bc7',
|
|
18
|
+
slug: 'project-readme-existence',
|
|
19
|
+
scope: { languages: ['typescript'], concerns: ['backend', 'frontend', 'cli'] },
|
|
20
|
+
confidence: 'medium',
|
|
21
|
+
description: 'Ensures every package has a README.md file',
|
|
22
|
+
longDescription: `**Purpose:** Ensures every package, app, CLI tool, and service has a README.md file for documentation and discoverability.
|
|
23
|
+
|
|
24
|
+
**Detects:**
|
|
25
|
+
- Missing \`README.md\` files in package directories
|
|
26
|
+
- Checks sibling directory of each \`package.json\`
|
|
27
|
+
- Skips the monorepo root \`package.json\` (via target patterns)
|
|
28
|
+
|
|
29
|
+
**Why it matters:** README files are essential for onboarding, discoverability, and maintaining documentation standards across the monorepo. Without them, developers must read source code to understand package purpose and usage.
|
|
30
|
+
|
|
31
|
+
**Scope:** Cross-file analysis via \`analyzeAll\`. Codebase-specific convention.`,
|
|
32
|
+
tags: ['architecture', 'documentation'],
|
|
33
|
+
// @fitness-ignore-next-line concurrency-safety -- async keyword required by analyzeAll interface contract; synchronous analysis implementation
|
|
34
|
+
// eslint-disable-next-line @typescript-eslint/require-await -- AnalyzeAllCheckConfig requires Promise<CheckViolation[]>; this implementation is synchronous
|
|
35
|
+
async analyzeAll(files) {
|
|
36
|
+
const violations = [];
|
|
37
|
+
// Only check directories that contain a package.json (actual packages)
|
|
38
|
+
const packageJsonPaths = files.paths.filter((fp) => path.basename(fp) === 'package.json');
|
|
39
|
+
for (const packageJsonPath of packageJsonPaths) {
|
|
40
|
+
const dirPath = path.dirname(packageJsonPath);
|
|
41
|
+
const readmePath = path.join(dirPath, 'README.md');
|
|
42
|
+
if (!fs.existsSync(readmePath)) {
|
|
43
|
+
violations.push({
|
|
44
|
+
filePath: packageJsonPath,
|
|
45
|
+
line: 1,
|
|
46
|
+
message: `Missing README.md in ${path.basename(dirPath)}`,
|
|
47
|
+
severity: 'warning',
|
|
48
|
+
suggestion: 'Create a README.md file with package description, usage, and API documentation',
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return violations;
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
//# sourceMappingURL=project-readme-existence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-readme-existence.js","sourceRoot":"","sources":["../../../src/checks/architecture/project-readme-existence.ts"],"names":[],"mappings":"AAAA,iHAAiH;AACjH;;;;GAIG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,WAAW,EAA0C,MAAM,sBAAsB,CAAC;AAE3F;;;;;GAKG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,WAAW,CAAC;IAChD,EAAE,EAAE,sCAAsC;IAC1C,IAAI,EAAE,0BAA0B;IAChC,KAAK,EAAE,EAAE,SAAS,EAAE,CAAC,YAAY,CAAC,EAAE,QAAQ,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,KAAK,CAAC,EAAE;IAE9E,UAAU,EAAE,QAAQ;IACpB,WAAW,EAAE,4CAA4C;IACzD,eAAe,EAAE;;;;;;;;;iFAS8D;IAC/E,IAAI,EAAE,CAAC,cAAc,EAAE,eAAe,CAAC;IAEvC,+IAA+I;IAC/I,4JAA4J;IAC5J,KAAK,CAAC,UAAU,CAAC,KAAmB;QAClC,MAAM,UAAU,GAAqB,EAAE,CAAC;QAExC,uEAAuE;QACvE,MAAM,gBAAgB,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,cAAc,CAAC,CAAC;QAE1F,KAAK,MAAM,eAAe,IAAI,gBAAgB,EAAE,CAAC;YAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;YAC9C,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;YAEnD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC/B,UAAU,CAAC,IAAI,CAAC;oBACd,QAAQ,EAAE,eAAe;oBACzB,IAAI,EAAE,CAAC;oBACP,OAAO,EAAE,wBAAwB,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE;oBACzD,QAAQ,EAAE,SAAS;oBACnB,UAAU,EACR,gFAAgF;iBACnF,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,UAAU,CAAC;IACpB,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Stale build artifact detection
|
|
3
|
+
* @module checks-builtin/checks/architecture/stale-build-artifacts
|
|
4
|
+
*
|
|
5
|
+
* Detects .js, .d.ts, and .js.map files in source directories that should
|
|
6
|
+
* only exist in dist/. These cause confusing import resolution bugs where
|
|
7
|
+
* the compiled artifact shadows the source file.
|
|
8
|
+
*/
|
|
9
|
+
export declare const staleBuildArtifacts: import("@opensip-cli/fitness").Check;
|
|
10
|
+
//# sourceMappingURL=stale-build-artifacts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stale-build-artifacts.d.ts","sourceRoot":"","sources":["../../../src/checks/architecture/stale-build-artifacts.ts"],"names":[],"mappings":"AACA;;;;;;;GAOG;AA0BH,eAAO,MAAM,mBAAmB,sCA6B9B,CAAC"}
|