driftdetect-detectors 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/dist/accessibility/alt-text.d.ts +63 -0
- package/dist/accessibility/alt-text.d.ts.map +1 -0
- package/dist/accessibility/alt-text.js +100 -0
- package/dist/accessibility/alt-text.js.map +1 -0
- package/dist/accessibility/aria-roles.d.ts +65 -0
- package/dist/accessibility/aria-roles.d.ts.map +1 -0
- package/dist/accessibility/aria-roles.js +87 -0
- package/dist/accessibility/aria-roles.js.map +1 -0
- package/dist/accessibility/focus-management.d.ts +62 -0
- package/dist/accessibility/focus-management.d.ts.map +1 -0
- package/dist/accessibility/focus-management.js +88 -0
- package/dist/accessibility/focus-management.js.map +1 -0
- package/dist/accessibility/heading-hierarchy.d.ts +66 -0
- package/dist/accessibility/heading-hierarchy.d.ts.map +1 -0
- package/dist/accessibility/heading-hierarchy.js +94 -0
- package/dist/accessibility/heading-hierarchy.js.map +1 -0
- package/dist/accessibility/index.d.ts +25 -0
- package/dist/accessibility/index.d.ts.map +1 -0
- package/dist/accessibility/index.js +21 -0
- package/dist/accessibility/index.js.map +1 -0
- package/dist/accessibility/keyboard-nav.d.ts +63 -0
- package/dist/accessibility/keyboard-nav.d.ts.map +1 -0
- package/dist/accessibility/keyboard-nav.js +86 -0
- package/dist/accessibility/keyboard-nav.js.map +1 -0
- package/dist/accessibility/semantic-html.d.ts +76 -0
- package/dist/accessibility/semantic-html.d.ts.map +1 -0
- package/dist/accessibility/semantic-html.js +204 -0
- package/dist/accessibility/semantic-html.js.map +1 -0
- package/dist/api/client-patterns.d.ts +121 -0
- package/dist/api/client-patterns.d.ts.map +1 -0
- package/dist/api/client-patterns.js +478 -0
- package/dist/api/client-patterns.js.map +1 -0
- package/dist/api/error-format.d.ts +140 -0
- package/dist/api/error-format.d.ts.map +1 -0
- package/dist/api/error-format.js +614 -0
- package/dist/api/error-format.js.map +1 -0
- package/dist/api/http-methods.d.ts +255 -0
- package/dist/api/http-methods.d.ts.map +1 -0
- package/dist/api/http-methods.js +890 -0
- package/dist/api/http-methods.js.map +1 -0
- package/dist/api/index.d.ts +16 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +37 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/pagination.d.ts +133 -0
- package/dist/api/pagination.d.ts.map +1 -0
- package/dist/api/pagination.js +521 -0
- package/dist/api/pagination.js.map +1 -0
- package/dist/api/response-envelope.d.ts +261 -0
- package/dist/api/response-envelope.d.ts.map +1 -0
- package/dist/api/response-envelope.js +1050 -0
- package/dist/api/response-envelope.js.map +1 -0
- package/dist/api/retry-patterns.d.ts +117 -0
- package/dist/api/retry-patterns.d.ts.map +1 -0
- package/dist/api/retry-patterns.js +480 -0
- package/dist/api/retry-patterns.js.map +1 -0
- package/dist/api/route-structure.d.ts +128 -0
- package/dist/api/route-structure.d.ts.map +1 -0
- package/dist/api/route-structure.js +738 -0
- package/dist/api/route-structure.js.map +1 -0
- package/dist/auth/audit-logging.d.ts +80 -0
- package/dist/auth/audit-logging.d.ts.map +1 -0
- package/dist/auth/audit-logging.js +370 -0
- package/dist/auth/audit-logging.js.map +1 -0
- package/dist/auth/index.d.ts +33 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +49 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/middleware-usage.d.ts +65 -0
- package/dist/auth/middleware-usage.d.ts.map +1 -0
- package/dist/auth/middleware-usage.js +192 -0
- package/dist/auth/middleware-usage.js.map +1 -0
- package/dist/auth/permission-checks.d.ts +60 -0
- package/dist/auth/permission-checks.d.ts.map +1 -0
- package/dist/auth/permission-checks.js +159 -0
- package/dist/auth/permission-checks.js.map +1 -0
- package/dist/auth/rbac-patterns.d.ts +68 -0
- package/dist/auth/rbac-patterns.d.ts.map +1 -0
- package/dist/auth/rbac-patterns.js +143 -0
- package/dist/auth/rbac-patterns.js.map +1 -0
- package/dist/auth/resource-ownership.d.ts +77 -0
- package/dist/auth/resource-ownership.d.ts.map +1 -0
- package/dist/auth/resource-ownership.js +324 -0
- package/dist/auth/resource-ownership.js.map +1 -0
- package/dist/auth/token-handling.d.ts +64 -0
- package/dist/auth/token-handling.d.ts.map +1 -0
- package/dist/auth/token-handling.js +151 -0
- package/dist/auth/token-handling.js.map +1 -0
- package/dist/base/ast-detector.d.ts +421 -0
- package/dist/base/ast-detector.d.ts.map +1 -0
- package/dist/base/ast-detector.js +699 -0
- package/dist/base/ast-detector.js.map +1 -0
- package/dist/base/base-detector.d.ts +366 -0
- package/dist/base/base-detector.d.ts.map +1 -0
- package/dist/base/base-detector.js +170 -0
- package/dist/base/base-detector.js.map +1 -0
- package/dist/base/index.d.ts +12 -0
- package/dist/base/index.d.ts.map +1 -0
- package/dist/base/index.js +17 -0
- package/dist/base/index.js.map +1 -0
- package/dist/base/regex-detector.d.ts +421 -0
- package/dist/base/regex-detector.d.ts.map +1 -0
- package/dist/base/regex-detector.js +537 -0
- package/dist/base/regex-detector.js.map +1 -0
- package/dist/base/structural-detector.d.ts +424 -0
- package/dist/base/structural-detector.d.ts.map +1 -0
- package/dist/base/structural-detector.js +731 -0
- package/dist/base/structural-detector.js.map +1 -0
- package/dist/base/types.d.ts +53 -0
- package/dist/base/types.d.ts.map +1 -0
- package/dist/base/types.js +5 -0
- package/dist/base/types.js.map +1 -0
- package/dist/components/component-structure.d.ts +163 -0
- package/dist/components/component-structure.d.ts.map +1 -0
- package/dist/components/component-structure.js +500 -0
- package/dist/components/component-structure.js.map +1 -0
- package/dist/components/composition.d.ts +287 -0
- package/dist/components/composition.d.ts.map +1 -0
- package/dist/components/composition.js +1123 -0
- package/dist/components/composition.js.map +1 -0
- package/dist/components/duplicate-detection.d.ts +251 -0
- package/dist/components/duplicate-detection.d.ts.map +1 -0
- package/dist/components/duplicate-detection.js +804 -0
- package/dist/components/duplicate-detection.js.map +1 -0
- package/dist/components/index.d.ts +16 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +51 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/near-duplicate.d.ts +402 -0
- package/dist/components/near-duplicate.d.ts.map +1 -0
- package/dist/components/near-duplicate.js +1090 -0
- package/dist/components/near-duplicate.js.map +1 -0
- package/dist/components/props-patterns.d.ts +194 -0
- package/dist/components/props-patterns.d.ts.map +1 -0
- package/dist/components/props-patterns.js +795 -0
- package/dist/components/props-patterns.js.map +1 -0
- package/dist/components/ref-forwarding.d.ts +250 -0
- package/dist/components/ref-forwarding.d.ts.map +1 -0
- package/dist/components/ref-forwarding.js +832 -0
- package/dist/components/ref-forwarding.js.map +1 -0
- package/dist/components/state-patterns.d.ts +291 -0
- package/dist/components/state-patterns.d.ts.map +1 -0
- package/dist/components/state-patterns.js +970 -0
- package/dist/components/state-patterns.js.map +1 -0
- package/dist/config/config-validation.d.ts +74 -0
- package/dist/config/config-validation.d.ts.map +1 -0
- package/dist/config/config-validation.js +446 -0
- package/dist/config/config-validation.js.map +1 -0
- package/dist/config/default-values.d.ts +72 -0
- package/dist/config/default-values.d.ts.map +1 -0
- package/dist/config/default-values.js +386 -0
- package/dist/config/default-values.js.map +1 -0
- package/dist/config/env-naming.d.ts +73 -0
- package/dist/config/env-naming.d.ts.map +1 -0
- package/dist/config/env-naming.js +429 -0
- package/dist/config/env-naming.js.map +1 -0
- package/dist/config/environment-detection.d.ts +72 -0
- package/dist/config/environment-detection.d.ts.map +1 -0
- package/dist/config/environment-detection.js +400 -0
- package/dist/config/environment-detection.js.map +1 -0
- package/dist/config/feature-flags.d.ts +72 -0
- package/dist/config/feature-flags.d.ts.map +1 -0
- package/dist/config/feature-flags.js +384 -0
- package/dist/config/feature-flags.js.map +1 -0
- package/dist/config/index.d.ts +27 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +43 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/required-optional.d.ts +71 -0
- package/dist/config/required-optional.d.ts.map +1 -0
- package/dist/config/required-optional.js +344 -0
- package/dist/config/required-optional.js.map +1 -0
- package/dist/data-access/connection-pooling.d.ts +63 -0
- package/dist/data-access/connection-pooling.d.ts.map +1 -0
- package/dist/data-access/connection-pooling.js +297 -0
- package/dist/data-access/connection-pooling.js.map +1 -0
- package/dist/data-access/dto-patterns.d.ts +64 -0
- package/dist/data-access/dto-patterns.d.ts.map +1 -0
- package/dist/data-access/dto-patterns.js +291 -0
- package/dist/data-access/dto-patterns.js.map +1 -0
- package/dist/data-access/index.d.ts +31 -0
- package/dist/data-access/index.d.ts.map +1 -0
- package/dist/data-access/index.js +49 -0
- package/dist/data-access/index.js.map +1 -0
- package/dist/data-access/n-plus-one.d.ts +60 -0
- package/dist/data-access/n-plus-one.d.ts.map +1 -0
- package/dist/data-access/n-plus-one.js +264 -0
- package/dist/data-access/n-plus-one.js.map +1 -0
- package/dist/data-access/query-patterns.d.ts +64 -0
- package/dist/data-access/query-patterns.d.ts.map +1 -0
- package/dist/data-access/query-patterns.js +314 -0
- package/dist/data-access/query-patterns.js.map +1 -0
- package/dist/data-access/repository-pattern.d.ts +62 -0
- package/dist/data-access/repository-pattern.d.ts.map +1 -0
- package/dist/data-access/repository-pattern.js +257 -0
- package/dist/data-access/repository-pattern.js.map +1 -0
- package/dist/data-access/transaction-patterns.d.ts +61 -0
- package/dist/data-access/transaction-patterns.d.ts.map +1 -0
- package/dist/data-access/transaction-patterns.js +277 -0
- package/dist/data-access/transaction-patterns.js.map +1 -0
- package/dist/data-access/validation-patterns.d.ts +62 -0
- package/dist/data-access/validation-patterns.d.ts.map +1 -0
- package/dist/data-access/validation-patterns.js +301 -0
- package/dist/data-access/validation-patterns.js.map +1 -0
- package/dist/documentation/deprecation.d.ts +62 -0
- package/dist/documentation/deprecation.d.ts.map +1 -0
- package/dist/documentation/deprecation.js +83 -0
- package/dist/documentation/deprecation.js.map +1 -0
- package/dist/documentation/example-code.d.ts +64 -0
- package/dist/documentation/example-code.d.ts.map +1 -0
- package/dist/documentation/example-code.js +79 -0
- package/dist/documentation/example-code.js.map +1 -0
- package/dist/documentation/index.d.ts +22 -0
- package/dist/documentation/index.d.ts.map +1 -0
- package/dist/documentation/index.js +19 -0
- package/dist/documentation/index.js.map +1 -0
- package/dist/documentation/jsdoc-patterns.d.ts +72 -0
- package/dist/documentation/jsdoc-patterns.d.ts.map +1 -0
- package/dist/documentation/jsdoc-patterns.js +92 -0
- package/dist/documentation/jsdoc-patterns.js.map +1 -0
- package/dist/documentation/readme-structure.d.ts +67 -0
- package/dist/documentation/readme-structure.d.ts.map +1 -0
- package/dist/documentation/readme-structure.js +76 -0
- package/dist/documentation/readme-structure.js.map +1 -0
- package/dist/documentation/todo-patterns.d.ts +67 -0
- package/dist/documentation/todo-patterns.d.ts.map +1 -0
- package/dist/documentation/todo-patterns.js +73 -0
- package/dist/documentation/todo-patterns.js.map +1 -0
- package/dist/errors/async-errors.d.ts +72 -0
- package/dist/errors/async-errors.d.ts.map +1 -0
- package/dist/errors/async-errors.js +214 -0
- package/dist/errors/async-errors.js.map +1 -0
- package/dist/errors/circuit-breaker.d.ts +53 -0
- package/dist/errors/circuit-breaker.d.ts.map +1 -0
- package/dist/errors/circuit-breaker.js +241 -0
- package/dist/errors/circuit-breaker.js.map +1 -0
- package/dist/errors/error-codes.d.ts +73 -0
- package/dist/errors/error-codes.d.ts.map +1 -0
- package/dist/errors/error-codes.js +211 -0
- package/dist/errors/error-codes.js.map +1 -0
- package/dist/errors/error-logging.d.ts +73 -0
- package/dist/errors/error-logging.d.ts.map +1 -0
- package/dist/errors/error-logging.js +256 -0
- package/dist/errors/error-logging.js.map +1 -0
- package/dist/errors/error-propagation.d.ts +73 -0
- package/dist/errors/error-propagation.d.ts.map +1 -0
- package/dist/errors/error-propagation.js +244 -0
- package/dist/errors/error-propagation.js.map +1 -0
- package/dist/errors/exception-hierarchy.d.ts +75 -0
- package/dist/errors/exception-hierarchy.d.ts.map +1 -0
- package/dist/errors/exception-hierarchy.js +259 -0
- package/dist/errors/exception-hierarchy.js.map +1 -0
- package/dist/errors/index.d.ts +31 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +49 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/errors/try-catch-placement.d.ts +73 -0
- package/dist/errors/try-catch-placement.d.ts.map +1 -0
- package/dist/errors/try-catch-placement.js +214 -0
- package/dist/errors/try-catch-placement.js.map +1 -0
- package/dist/index.d.ts +221 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +245 -0
- package/dist/index.js.map +1 -0
- package/dist/logging/context-fields.d.ts +48 -0
- package/dist/logging/context-fields.d.ts.map +1 -0
- package/dist/logging/context-fields.js +160 -0
- package/dist/logging/context-fields.js.map +1 -0
- package/dist/logging/correlation-ids.d.ts +44 -0
- package/dist/logging/correlation-ids.d.ts.map +1 -0
- package/dist/logging/correlation-ids.js +144 -0
- package/dist/logging/correlation-ids.js.map +1 -0
- package/dist/logging/health-checks.d.ts +45 -0
- package/dist/logging/health-checks.d.ts.map +1 -0
- package/dist/logging/health-checks.js +165 -0
- package/dist/logging/health-checks.js.map +1 -0
- package/dist/logging/index.d.ts +31 -0
- package/dist/logging/index.d.ts.map +1 -0
- package/dist/logging/index.js +49 -0
- package/dist/logging/index.js.map +1 -0
- package/dist/logging/log-levels.d.ts +46 -0
- package/dist/logging/log-levels.d.ts.map +1 -0
- package/dist/logging/log-levels.js +178 -0
- package/dist/logging/log-levels.js.map +1 -0
- package/dist/logging/metric-naming.d.ts +46 -0
- package/dist/logging/metric-naming.d.ts.map +1 -0
- package/dist/logging/metric-naming.js +157 -0
- package/dist/logging/metric-naming.js.map +1 -0
- package/dist/logging/pii-redaction.d.ts +44 -0
- package/dist/logging/pii-redaction.d.ts.map +1 -0
- package/dist/logging/pii-redaction.js +166 -0
- package/dist/logging/pii-redaction.js.map +1 -0
- package/dist/logging/structured-format.d.ts +53 -0
- package/dist/logging/structured-format.d.ts.map +1 -0
- package/dist/logging/structured-format.js +235 -0
- package/dist/logging/structured-format.js.map +1 -0
- package/dist/performance/bundle-size.d.ts +79 -0
- package/dist/performance/bundle-size.d.ts.map +1 -0
- package/dist/performance/bundle-size.js +276 -0
- package/dist/performance/bundle-size.js.map +1 -0
- package/dist/performance/caching-patterns.d.ts +78 -0
- package/dist/performance/caching-patterns.d.ts.map +1 -0
- package/dist/performance/caching-patterns.js +257 -0
- package/dist/performance/caching-patterns.js.map +1 -0
- package/dist/performance/code-splitting.d.ts +86 -0
- package/dist/performance/code-splitting.d.ts.map +1 -0
- package/dist/performance/code-splitting.js +447 -0
- package/dist/performance/code-splitting.js.map +1 -0
- package/dist/performance/debounce-throttle.d.ts +75 -0
- package/dist/performance/debounce-throttle.d.ts.map +1 -0
- package/dist/performance/debounce-throttle.js +232 -0
- package/dist/performance/debounce-throttle.js.map +1 -0
- package/dist/performance/index.d.ts +28 -0
- package/dist/performance/index.d.ts.map +1 -0
- package/dist/performance/index.js +39 -0
- package/dist/performance/index.js.map +1 -0
- package/dist/performance/lazy-loading.d.ts +75 -0
- package/dist/performance/lazy-loading.d.ts.map +1 -0
- package/dist/performance/lazy-loading.js +233 -0
- package/dist/performance/lazy-loading.js.map +1 -0
- package/dist/performance/memoization.d.ts +75 -0
- package/dist/performance/memoization.d.ts.map +1 -0
- package/dist/performance/memoization.js +251 -0
- package/dist/performance/memoization.js.map +1 -0
- package/dist/registry/detector-registry.d.ts +266 -0
- package/dist/registry/detector-registry.d.ts.map +1 -0
- package/dist/registry/detector-registry.js +526 -0
- package/dist/registry/detector-registry.js.map +1 -0
- package/dist/registry/index.d.ts +10 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +10 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/registry/loader.d.ts +232 -0
- package/dist/registry/loader.d.ts.map +1 -0
- package/dist/registry/loader.js +419 -0
- package/dist/registry/loader.js.map +1 -0
- package/dist/registry/types.d.ts +111 -0
- package/dist/registry/types.d.ts.map +1 -0
- package/dist/registry/types.js +19 -0
- package/dist/registry/types.js.map +1 -0
- package/dist/security/csp-headers.d.ts +78 -0
- package/dist/security/csp-headers.d.ts.map +1 -0
- package/dist/security/csp-headers.js +401 -0
- package/dist/security/csp-headers.js.map +1 -0
- package/dist/security/csrf-protection.d.ts +72 -0
- package/dist/security/csrf-protection.d.ts.map +1 -0
- package/dist/security/csrf-protection.js +344 -0
- package/dist/security/csrf-protection.js.map +1 -0
- package/dist/security/index.d.ts +30 -0
- package/dist/security/index.d.ts.map +1 -0
- package/dist/security/index.js +48 -0
- package/dist/security/index.js.map +1 -0
- package/dist/security/input-sanitization.d.ts +74 -0
- package/dist/security/input-sanitization.d.ts.map +1 -0
- package/dist/security/input-sanitization.js +373 -0
- package/dist/security/input-sanitization.js.map +1 -0
- package/dist/security/rate-limiting.d.ts +81 -0
- package/dist/security/rate-limiting.d.ts.map +1 -0
- package/dist/security/rate-limiting.js +535 -0
- package/dist/security/rate-limiting.js.map +1 -0
- package/dist/security/secret-management.d.ts +83 -0
- package/dist/security/secret-management.d.ts.map +1 -0
- package/dist/security/secret-management.js +547 -0
- package/dist/security/secret-management.js.map +1 -0
- package/dist/security/sql-injection.d.ts +76 -0
- package/dist/security/sql-injection.d.ts.map +1 -0
- package/dist/security/sql-injection.js +383 -0
- package/dist/security/sql-injection.js.map +1 -0
- package/dist/security/xss-prevention.d.ts +80 -0
- package/dist/security/xss-prevention.d.ts.map +1 -0
- package/dist/security/xss-prevention.js +416 -0
- package/dist/security/xss-prevention.js.map +1 -0
- package/dist/structural/barrel-exports.d.ts +178 -0
- package/dist/structural/barrel-exports.d.ts.map +1 -0
- package/dist/structural/barrel-exports.js +553 -0
- package/dist/structural/barrel-exports.js.map +1 -0
- package/dist/structural/circular-deps.d.ts +140 -0
- package/dist/structural/circular-deps.d.ts.map +1 -0
- package/dist/structural/circular-deps.js +422 -0
- package/dist/structural/circular-deps.js.map +1 -0
- package/dist/structural/co-location.d.ts +202 -0
- package/dist/structural/co-location.d.ts.map +1 -0
- package/dist/structural/co-location.js +640 -0
- package/dist/structural/co-location.js.map +1 -0
- package/dist/structural/directory-structure.d.ts +151 -0
- package/dist/structural/directory-structure.d.ts.map +1 -0
- package/dist/structural/directory-structure.js +457 -0
- package/dist/structural/directory-structure.js.map +1 -0
- package/dist/structural/file-naming.d.ts +61 -0
- package/dist/structural/file-naming.d.ts.map +1 -0
- package/dist/structural/file-naming.js +231 -0
- package/dist/structural/file-naming.js.map +1 -0
- package/dist/structural/import-ordering.d.ts +212 -0
- package/dist/structural/import-ordering.d.ts.map +1 -0
- package/dist/structural/import-ordering.js +821 -0
- package/dist/structural/import-ordering.js.map +1 -0
- package/dist/structural/index.d.ts +23 -0
- package/dist/structural/index.d.ts.map +1 -0
- package/dist/structural/index.js +26 -0
- package/dist/structural/index.js.map +1 -0
- package/dist/structural/module-boundaries.d.ts +164 -0
- package/dist/structural/module-boundaries.d.ts.map +1 -0
- package/dist/structural/module-boundaries.js +616 -0
- package/dist/structural/module-boundaries.js.map +1 -0
- package/dist/structural/package-boundaries.d.ts +182 -0
- package/dist/structural/package-boundaries.d.ts.map +1 -0
- package/dist/structural/package-boundaries.js +602 -0
- package/dist/structural/package-boundaries.js.map +1 -0
- package/dist/styling/class-naming.d.ts +263 -0
- package/dist/styling/class-naming.d.ts.map +1 -0
- package/dist/styling/class-naming.js +892 -0
- package/dist/styling/class-naming.js.map +1 -0
- package/dist/styling/color-usage.d.ts +213 -0
- package/dist/styling/color-usage.d.ts.map +1 -0
- package/dist/styling/color-usage.js +732 -0
- package/dist/styling/color-usage.js.map +1 -0
- package/dist/styling/design-tokens.d.ts +212 -0
- package/dist/styling/design-tokens.d.ts.map +1 -0
- package/dist/styling/design-tokens.js +748 -0
- package/dist/styling/design-tokens.js.map +1 -0
- package/dist/styling/index.d.ts +16 -0
- package/dist/styling/index.d.ts.map +1 -0
- package/dist/styling/index.js +56 -0
- package/dist/styling/index.js.map +1 -0
- package/dist/styling/responsive.d.ts +304 -0
- package/dist/styling/responsive.d.ts.map +1 -0
- package/dist/styling/responsive.js +888 -0
- package/dist/styling/responsive.js.map +1 -0
- package/dist/styling/spacing-scale.d.ts +248 -0
- package/dist/styling/spacing-scale.d.ts.map +1 -0
- package/dist/styling/spacing-scale.js +865 -0
- package/dist/styling/spacing-scale.js.map +1 -0
- package/dist/styling/tailwind-patterns.d.ts +305 -0
- package/dist/styling/tailwind-patterns.d.ts.map +1 -0
- package/dist/styling/tailwind-patterns.js +1181 -0
- package/dist/styling/tailwind-patterns.js.map +1 -0
- package/dist/styling/typography.d.ts +281 -0
- package/dist/styling/typography.d.ts.map +1 -0
- package/dist/styling/typography.js +1004 -0
- package/dist/styling/typography.js.map +1 -0
- package/dist/styling/z-index-scale.d.ts +270 -0
- package/dist/styling/z-index-scale.d.ts.map +1 -0
- package/dist/styling/z-index-scale.js +714 -0
- package/dist/styling/z-index-scale.js.map +1 -0
- package/dist/testing/co-location.d.ts +42 -0
- package/dist/testing/co-location.d.ts.map +1 -0
- package/dist/testing/co-location.js +134 -0
- package/dist/testing/co-location.js.map +1 -0
- package/dist/testing/describe-naming.d.ts +47 -0
- package/dist/testing/describe-naming.d.ts.map +1 -0
- package/dist/testing/describe-naming.js +150 -0
- package/dist/testing/describe-naming.js.map +1 -0
- package/dist/testing/file-naming.d.ts +44 -0
- package/dist/testing/file-naming.d.ts.map +1 -0
- package/dist/testing/file-naming.js +131 -0
- package/dist/testing/file-naming.js.map +1 -0
- package/dist/testing/fixture-patterns.d.ts +52 -0
- package/dist/testing/fixture-patterns.d.ts.map +1 -0
- package/dist/testing/fixture-patterns.js +228 -0
- package/dist/testing/fixture-patterns.js.map +1 -0
- package/dist/testing/index.d.ts +31 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +49 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/mock-patterns.d.ts +53 -0
- package/dist/testing/mock-patterns.d.ts.map +1 -0
- package/dist/testing/mock-patterns.js +264 -0
- package/dist/testing/mock-patterns.js.map +1 -0
- package/dist/testing/setup-teardown.d.ts +55 -0
- package/dist/testing/setup-teardown.d.ts.map +1 -0
- package/dist/testing/setup-teardown.js +262 -0
- package/dist/testing/setup-teardown.js.map +1 -0
- package/dist/testing/test-structure.d.ts +51 -0
- package/dist/testing/test-structure.d.ts.map +1 -0
- package/dist/testing/test-structure.js +225 -0
- package/dist/testing/test-structure.js.map +1 -0
- package/dist/types/any-usage.d.ts +99 -0
- package/dist/types/any-usage.d.ts.map +1 -0
- package/dist/types/any-usage.js +641 -0
- package/dist/types/any-usage.js.map +1 -0
- package/dist/types/file-location.d.ts +76 -0
- package/dist/types/file-location.d.ts.map +1 -0
- package/dist/types/file-location.js +395 -0
- package/dist/types/file-location.js.map +1 -0
- package/dist/types/generic-patterns.d.ts +97 -0
- package/dist/types/generic-patterns.d.ts.map +1 -0
- package/dist/types/generic-patterns.js +615 -0
- package/dist/types/generic-patterns.js.map +1 -0
- package/dist/types/index.d.ts +31 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +43 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/interface-vs-type.d.ts +81 -0
- package/dist/types/interface-vs-type.d.ts.map +1 -0
- package/dist/types/interface-vs-type.js +440 -0
- package/dist/types/interface-vs-type.js.map +1 -0
- package/dist/types/naming-conventions.d.ts +84 -0
- package/dist/types/naming-conventions.d.ts.map +1 -0
- package/dist/types/naming-conventions.js +455 -0
- package/dist/types/naming-conventions.js.map +1 -0
- package/dist/types/type-assertions.d.ts +98 -0
- package/dist/types/type-assertions.d.ts.map +1 -0
- package/dist/types/type-assertions.js +639 -0
- package/dist/types/type-assertions.js.map +1 -0
- package/dist/types/utility-types.d.ts +110 -0
- package/dist/types/utility-types.d.ts.map +1 -0
- package/dist/types/utility-types.js +547 -0
- package/dist/types/utility-types.js.map +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Heading Hierarchy Detector - Heading hierarchy pattern detection
|
|
3
|
+
* @requirements 20.5 - Heading hierarchy patterns
|
|
4
|
+
*/
|
|
5
|
+
import { RegexDetector } from '../base/regex-detector.js';
|
|
6
|
+
export const H1_PATTERNS = [/<h1[\s>]/gi, /<H1[\s>]/g];
|
|
7
|
+
export const H2_PATTERNS = [/<h2[\s>]/gi, /<H2[\s>]/g];
|
|
8
|
+
export const H3_PATTERNS = [/<h3[\s>]/gi, /<H3[\s>]/g];
|
|
9
|
+
export const H4_PATTERNS = [/<h4[\s>]/gi, /<H4[\s>]/g];
|
|
10
|
+
export const H5_PATTERNS = [/<h5[\s>]/gi, /<H5[\s>]/g];
|
|
11
|
+
export const H6_PATTERNS = [/<h6[\s>]/gi, /<H6[\s>]/g];
|
|
12
|
+
export const HEADING_COMPONENT_PATTERNS = [/<Heading[\s>]/g, /<Typography[^>]*variant\s*=\s*['"`]h\d['"`]/gi];
|
|
13
|
+
export const EMPTY_HEADING_PATTERNS = [/<h[1-6][^>]*>\s*<\/h[1-6]>/gi];
|
|
14
|
+
export function shouldExcludeFile(filePath) {
|
|
15
|
+
return [/\.test\.[jt]sx?$/, /\.spec\.[jt]sx?$/, /__tests__\//, /node_modules\//, /\.min\.[jt]s$/].some((p) => p.test(filePath));
|
|
16
|
+
}
|
|
17
|
+
function detectPatterns(content, filePath, patterns, type, level) {
|
|
18
|
+
const results = [];
|
|
19
|
+
const lines = content.split('\n');
|
|
20
|
+
for (let i = 0; i < lines.length; i++) {
|
|
21
|
+
const line = lines[i];
|
|
22
|
+
for (const pattern of patterns) {
|
|
23
|
+
const regex = new RegExp(pattern.source, pattern.flags);
|
|
24
|
+
let match;
|
|
25
|
+
while ((match = regex.exec(line)) !== null) {
|
|
26
|
+
results.push({ type, file: filePath, line: i + 1, column: match.index + 1, matchedText: match[0], level, context: line.trim() });
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return results;
|
|
31
|
+
}
|
|
32
|
+
export function detectH1(content, filePath) { return detectPatterns(content, filePath, H1_PATTERNS, 'h1', 1); }
|
|
33
|
+
export function detectH2(content, filePath) { return detectPatterns(content, filePath, H2_PATTERNS, 'h2', 2); }
|
|
34
|
+
export function detectH3(content, filePath) { return detectPatterns(content, filePath, H3_PATTERNS, 'h3', 3); }
|
|
35
|
+
export function detectH4(content, filePath) { return detectPatterns(content, filePath, H4_PATTERNS, 'h4', 4); }
|
|
36
|
+
export function detectH5(content, filePath) { return detectPatterns(content, filePath, H5_PATTERNS, 'h5', 5); }
|
|
37
|
+
export function detectH6(content, filePath) { return detectPatterns(content, filePath, H6_PATTERNS, 'h6', 6); }
|
|
38
|
+
export function detectHeadingComponent(content, filePath) { return detectPatterns(content, filePath, HEADING_COMPONENT_PATTERNS, 'heading-component'); }
|
|
39
|
+
export function detectMultipleH1Violations(content, filePath) {
|
|
40
|
+
const h1Count = (content.match(/<h1[\s>]/gi) || []).length;
|
|
41
|
+
if (h1Count > 1) {
|
|
42
|
+
return [{ type: 'multiple-h1', file: filePath, line: 1, column: 1, matchedText: `${h1Count} h1 elements`, issue: 'Multiple h1 elements found', suggestedFix: 'Use only one h1 per page', severity: 'medium' }];
|
|
43
|
+
}
|
|
44
|
+
return [];
|
|
45
|
+
}
|
|
46
|
+
export function detectEmptyHeadingViolations(content, filePath) {
|
|
47
|
+
const results = [];
|
|
48
|
+
const lines = content.split('\n');
|
|
49
|
+
for (let i = 0; i < lines.length; i++) {
|
|
50
|
+
const line = lines[i];
|
|
51
|
+
for (const pattern of EMPTY_HEADING_PATTERNS) {
|
|
52
|
+
const regex = new RegExp(pattern.source, pattern.flags);
|
|
53
|
+
let match;
|
|
54
|
+
while ((match = regex.exec(line)) !== null) {
|
|
55
|
+
results.push({ type: 'empty-heading', file: filePath, line: i + 1, column: match.index + 1, matchedText: match[0], issue: 'Empty heading element', suggestedFix: 'Add content to heading or remove it', severity: 'high' });
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return results;
|
|
60
|
+
}
|
|
61
|
+
export function analyzeHeadingHierarchy(content, filePath) {
|
|
62
|
+
if (shouldExcludeFile(filePath))
|
|
63
|
+
return { patterns: [], violations: [], headingCount: 0, hasH1: false, confidence: 1.0 };
|
|
64
|
+
const patterns = [...detectH1(content, filePath), ...detectH2(content, filePath), ...detectH3(content, filePath), ...detectH4(content, filePath), ...detectH5(content, filePath), ...detectH6(content, filePath), ...detectHeadingComponent(content, filePath)];
|
|
65
|
+
const violations = [...detectMultipleH1Violations(content, filePath), ...detectEmptyHeadingViolations(content, filePath)];
|
|
66
|
+
const headingCount = patterns.length;
|
|
67
|
+
const hasH1 = patterns.some((p) => p.type === 'h1');
|
|
68
|
+
let confidence = 0.7;
|
|
69
|
+
if (patterns.length > 0)
|
|
70
|
+
confidence += 0.15;
|
|
71
|
+
if (violations.length === 0)
|
|
72
|
+
confidence += 0.1;
|
|
73
|
+
confidence = Math.min(confidence, 0.95);
|
|
74
|
+
return { patterns, violations, headingCount, hasH1, confidence };
|
|
75
|
+
}
|
|
76
|
+
export class HeadingHierarchyDetector extends RegexDetector {
|
|
77
|
+
id = 'accessibility/heading-hierarchy';
|
|
78
|
+
name = 'Heading Hierarchy Detector';
|
|
79
|
+
description = 'Detects heading hierarchy patterns';
|
|
80
|
+
category = 'accessibility';
|
|
81
|
+
subcategory = 'heading-hierarchy';
|
|
82
|
+
supportedLanguages = ['typescript', 'javascript'];
|
|
83
|
+
async detect(context) {
|
|
84
|
+
if (!this.supportsLanguage(context.language))
|
|
85
|
+
return this.createEmptyResult();
|
|
86
|
+
const analysis = analyzeHeadingHierarchy(context.content, context.file);
|
|
87
|
+
if (analysis.patterns.length === 0 && analysis.violations.length === 0)
|
|
88
|
+
return this.createEmptyResult();
|
|
89
|
+
return this.createResult([], [], analysis.confidence, { custom: { patterns: analysis.patterns, violations: analysis.violations, headingCount: analysis.headingCount, hasH1: analysis.hasH1 } });
|
|
90
|
+
}
|
|
91
|
+
generateQuickFix(_violation) { return null; }
|
|
92
|
+
}
|
|
93
|
+
export function createHeadingHierarchyDetector() { return new HeadingHierarchyDetector(); }
|
|
94
|
+
//# sourceMappingURL=heading-hierarchy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heading-hierarchy.js","sourceRoot":"","sources":["../../src/accessibility/heading-hierarchy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Accessibility Detectors - Accessibility pattern detection
|
|
3
|
+
* @requirements 20.1-20.6 - Accessibility pattern detection
|
|
4
|
+
*/
|
|
5
|
+
export { SemanticHtmlDetector, createSemanticHtmlDetector, analyzeSemanticHtml, shouldExcludeFile as shouldExcludeSemanticHtml, detectHeaderElement, detectNavElement, detectMainElement, detectFooterElement, detectArticleElement, detectSectionElement, detectAsideElement, detectFigureElement, detectLandmarkRole, detectDivSoupViolations, HEADER_ELEMENT_PATTERNS, NAV_ELEMENT_PATTERNS, MAIN_ELEMENT_PATTERNS, FOOTER_ELEMENT_PATTERNS } from './semantic-html.js';
|
|
6
|
+
export type { SemanticHtmlPatternType, SemanticHtmlViolationType, SemanticHtmlPatternInfo, SemanticHtmlViolationInfo, SemanticHtmlAnalysis } from './semantic-html.js';
|
|
7
|
+
export { AriaRolesDetector, createAriaRolesDetector, analyzeAriaRoles, shouldExcludeFile as shouldExcludeAriaRoles, detectAriaRole, detectAriaLabel, detectAriaDescribedby, detectAriaHidden, detectAriaLive, detectAriaExpanded, detectAriaControls, detectRedundantRoleViolations, ARIA_ROLE_PATTERNS, ARIA_LABEL_PATTERNS, ARIA_LIVE_PATTERNS } from './aria-roles.js';
|
|
8
|
+
export type { AriaRolesPatternType, AriaRolesViolationType, AriaRolesPatternInfo, AriaRolesViolationInfo, AriaRolesAnalysis } from './aria-roles.js';
|
|
9
|
+
export { KeyboardNavDetector, createKeyboardNavDetector, analyzeKeyboardNav, shouldExcludeFile as shouldExcludeKeyboardNav, detectTabindex, detectOnKeyDown, detectOnKeyUp, detectOnKeyPress, detectFocusTrap, detectSkipLink, detectPositiveTabindexViolations, TABINDEX_PATTERNS, ONKEYDOWN_PATTERNS, FOCUS_TRAP_PATTERNS, SKIP_LINK_PATTERNS } from './keyboard-nav.js';
|
|
10
|
+
export type { KeyboardNavPatternType, KeyboardNavViolationType, KeyboardNavPatternInfo, KeyboardNavViolationInfo, KeyboardNavAnalysis } from './keyboard-nav.js';
|
|
11
|
+
export { FocusManagementDetector, createFocusManagementDetector, analyzeFocusManagement, shouldExcludeFile as shouldExcludeFocusManagement, detectFocusVisible, detectFocusWithin, detectUseFocus, detectAutoFocus, detectFocusRef, detectFocusRing, detectOutlineNoneViolations, FOCUS_VISIBLE_PATTERNS, FOCUS_RING_PATTERNS, OUTLINE_NONE_PATTERNS } from './focus-management.js';
|
|
12
|
+
export type { FocusManagementPatternType, FocusManagementViolationType, FocusManagementPatternInfo, FocusManagementViolationInfo, FocusManagementAnalysis } from './focus-management.js';
|
|
13
|
+
export { HeadingHierarchyDetector, createHeadingHierarchyDetector, analyzeHeadingHierarchy, shouldExcludeFile as shouldExcludeHeadingHierarchy, detectH1, detectH2, detectH3, detectH4, detectH5, detectH6, detectHeadingComponent, detectMultipleH1Violations, detectEmptyHeadingViolations, H1_PATTERNS, H2_PATTERNS, H3_PATTERNS } from './heading-hierarchy.js';
|
|
14
|
+
export type { HeadingHierarchyPatternType, HeadingHierarchyViolationType, HeadingHierarchyPatternInfo, HeadingHierarchyViolationInfo, HeadingHierarchyAnalysis } from './heading-hierarchy.js';
|
|
15
|
+
export { AltTextDetector, createAltTextDetector, analyzeAltText, shouldExcludeFile as shouldExcludeAltText, detectImgAlt, detectDecorativeAlt, detectSvgTitle, detectIconLabel, detectFigureCaption, detectMissingAltViolations, detectRedundantAltViolations, IMG_ALT_PATTERNS, DECORATIVE_ALT_PATTERNS, MISSING_ALT_PATTERNS } from './alt-text.js';
|
|
16
|
+
export type { AltTextPatternType, AltTextViolationType, AltTextPatternInfo, AltTextViolationInfo, AltTextAnalysis } from './alt-text.js';
|
|
17
|
+
import { SemanticHtmlDetector } from './semantic-html.js';
|
|
18
|
+
import { AriaRolesDetector } from './aria-roles.js';
|
|
19
|
+
import { KeyboardNavDetector } from './keyboard-nav.js';
|
|
20
|
+
import { FocusManagementDetector } from './focus-management.js';
|
|
21
|
+
import { HeadingHierarchyDetector } from './heading-hierarchy.js';
|
|
22
|
+
import { AltTextDetector } from './alt-text.js';
|
|
23
|
+
export type AccessibilityDetector = SemanticHtmlDetector | AriaRolesDetector | KeyboardNavDetector | FocusManagementDetector | HeadingHierarchyDetector | AltTextDetector;
|
|
24
|
+
export declare function createAccessibilityDetectors(): AccessibilityDetector[];
|
|
25
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/accessibility/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Accessibility Detectors - Accessibility pattern detection
|
|
3
|
+
* @requirements 20.1-20.6 - Accessibility pattern detection
|
|
4
|
+
*/
|
|
5
|
+
export { SemanticHtmlDetector, createSemanticHtmlDetector, analyzeSemanticHtml, shouldExcludeFile as shouldExcludeSemanticHtml, detectHeaderElement, detectNavElement, detectMainElement, detectFooterElement, detectArticleElement, detectSectionElement, detectAsideElement, detectFigureElement, detectLandmarkRole, detectDivSoupViolations, HEADER_ELEMENT_PATTERNS, NAV_ELEMENT_PATTERNS, MAIN_ELEMENT_PATTERNS, FOOTER_ELEMENT_PATTERNS } from './semantic-html.js';
|
|
6
|
+
export { AriaRolesDetector, createAriaRolesDetector, analyzeAriaRoles, shouldExcludeFile as shouldExcludeAriaRoles, detectAriaRole, detectAriaLabel, detectAriaDescribedby, detectAriaHidden, detectAriaLive, detectAriaExpanded, detectAriaControls, detectRedundantRoleViolations, ARIA_ROLE_PATTERNS, ARIA_LABEL_PATTERNS, ARIA_LIVE_PATTERNS } from './aria-roles.js';
|
|
7
|
+
export { KeyboardNavDetector, createKeyboardNavDetector, analyzeKeyboardNav, shouldExcludeFile as shouldExcludeKeyboardNav, detectTabindex, detectOnKeyDown, detectOnKeyUp, detectOnKeyPress, detectFocusTrap, detectSkipLink, detectPositiveTabindexViolations, TABINDEX_PATTERNS, ONKEYDOWN_PATTERNS, FOCUS_TRAP_PATTERNS, SKIP_LINK_PATTERNS } from './keyboard-nav.js';
|
|
8
|
+
export { FocusManagementDetector, createFocusManagementDetector, analyzeFocusManagement, shouldExcludeFile as shouldExcludeFocusManagement, detectFocusVisible, detectFocusWithin, detectUseFocus, detectAutoFocus, detectFocusRef, detectFocusRing, detectOutlineNoneViolations, FOCUS_VISIBLE_PATTERNS, FOCUS_RING_PATTERNS, OUTLINE_NONE_PATTERNS } from './focus-management.js';
|
|
9
|
+
export { HeadingHierarchyDetector, createHeadingHierarchyDetector, analyzeHeadingHierarchy, shouldExcludeFile as shouldExcludeHeadingHierarchy, detectH1, detectH2, detectH3, detectH4, detectH5, detectH6, detectHeadingComponent, detectMultipleH1Violations, detectEmptyHeadingViolations, H1_PATTERNS, H2_PATTERNS, H3_PATTERNS } from './heading-hierarchy.js';
|
|
10
|
+
export { AltTextDetector, createAltTextDetector, analyzeAltText, shouldExcludeFile as shouldExcludeAltText, detectImgAlt, detectDecorativeAlt, detectSvgTitle, detectIconLabel, detectFigureCaption, detectMissingAltViolations, detectRedundantAltViolations, IMG_ALT_PATTERNS, DECORATIVE_ALT_PATTERNS, MISSING_ALT_PATTERNS } from './alt-text.js';
|
|
11
|
+
// Factory Function
|
|
12
|
+
import { SemanticHtmlDetector } from './semantic-html.js';
|
|
13
|
+
import { AriaRolesDetector } from './aria-roles.js';
|
|
14
|
+
import { KeyboardNavDetector } from './keyboard-nav.js';
|
|
15
|
+
import { FocusManagementDetector } from './focus-management.js';
|
|
16
|
+
import { HeadingHierarchyDetector } from './heading-hierarchy.js';
|
|
17
|
+
import { AltTextDetector } from './alt-text.js';
|
|
18
|
+
export function createAccessibilityDetectors() {
|
|
19
|
+
return [new SemanticHtmlDetector(), new AriaRolesDetector(), new KeyboardNavDetector(), new FocusManagementDetector(), new HeadingHierarchyDetector(), new AltTextDetector()];
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/accessibility/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,oBAAoB,EAAE,0BAA0B,EAAE,mBAAmB,EAAE,iBAAiB,IAAI,yBAAyB,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAG3c,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,iBAAiB,IAAI,sBAAsB,EAAE,cAAc,EAAE,eAAe,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,cAAc,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,6BAA6B,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAG1W,OAAO,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,iBAAiB,IAAI,wBAAwB,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,gBAAgB,EAAE,eAAe,EAAE,cAAc,EAAE,gCAAgC,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAG3W,OAAO,EAAE,uBAAuB,EAAE,6BAA6B,EAAE,sBAAsB,EAAE,iBAAiB,IAAI,4BAA4B,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,cAAc,EAAE,eAAe,EAAE,cAAc,EAAE,eAAe,EAAE,2BAA2B,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAGpX,OAAO,EAAE,wBAAwB,EAAE,8BAA8B,EAAE,uBAAuB,EAAE,iBAAiB,IAAI,6BAA6B,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,sBAAsB,EAAE,0BAA0B,EAAE,4BAA4B,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAGpW,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,cAAc,EAAE,iBAAiB,IAAI,oBAAoB,EAAE,YAAY,EAAE,mBAAmB,EAAE,cAAc,EAAE,eAAe,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,4BAA4B,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAGtV,mBAAmB;AACnB,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAIhD,MAAM,UAAU,4BAA4B;IAC1C,OAAO,CAAC,IAAI,oBAAoB,EAAE,EAAE,IAAI,iBAAiB,EAAE,EAAE,IAAI,mBAAmB,EAAE,EAAE,IAAI,uBAAuB,EAAE,EAAE,IAAI,wBAAwB,EAAE,EAAE,IAAI,eAAe,EAAE,CAAC,CAAC;AAChL,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keyboard Navigation Detector - Keyboard navigation pattern detection
|
|
3
|
+
* @requirements 20.3 - Keyboard navigation patterns
|
|
4
|
+
*/
|
|
5
|
+
import type { Violation, QuickFix, PatternCategory, Language } from 'driftdetect-core';
|
|
6
|
+
import { RegexDetector } from '../base/regex-detector.js';
|
|
7
|
+
import type { DetectionContext, DetectionResult } from '../base/base-detector.js';
|
|
8
|
+
export type KeyboardNavPatternType = 'tabindex' | 'onkeydown' | 'onkeyup' | 'onkeypress' | 'focus-trap' | 'skip-link';
|
|
9
|
+
export type KeyboardNavViolationType = 'positive-tabindex' | 'missing-keyboard-handler' | 'mouse-only-handler';
|
|
10
|
+
export interface KeyboardNavPatternInfo {
|
|
11
|
+
type: KeyboardNavPatternType;
|
|
12
|
+
file: string;
|
|
13
|
+
line: number;
|
|
14
|
+
column: number;
|
|
15
|
+
matchedText: string;
|
|
16
|
+
context?: string | undefined;
|
|
17
|
+
}
|
|
18
|
+
export interface KeyboardNavViolationInfo {
|
|
19
|
+
type: KeyboardNavViolationType;
|
|
20
|
+
file: string;
|
|
21
|
+
line: number;
|
|
22
|
+
column: number;
|
|
23
|
+
matchedText: string;
|
|
24
|
+
issue: string;
|
|
25
|
+
suggestedFix?: string | undefined;
|
|
26
|
+
severity: 'high' | 'medium' | 'low';
|
|
27
|
+
}
|
|
28
|
+
export interface KeyboardNavAnalysis {
|
|
29
|
+
patterns: KeyboardNavPatternInfo[];
|
|
30
|
+
violations: KeyboardNavViolationInfo[];
|
|
31
|
+
tabindexCount: number;
|
|
32
|
+
keyboardHandlerCount: number;
|
|
33
|
+
confidence: number;
|
|
34
|
+
}
|
|
35
|
+
export declare const TABINDEX_PATTERNS: readonly [RegExp, RegExp];
|
|
36
|
+
export declare const ONKEYDOWN_PATTERNS: readonly [RegExp, RegExp];
|
|
37
|
+
export declare const ONKEYUP_PATTERNS: readonly [RegExp, RegExp];
|
|
38
|
+
export declare const ONKEYPRESS_PATTERNS: readonly [RegExp, RegExp];
|
|
39
|
+
export declare const FOCUS_TRAP_PATTERNS: readonly [RegExp, RegExp, RegExp];
|
|
40
|
+
export declare const SKIP_LINK_PATTERNS: readonly [RegExp, RegExp, RegExp, RegExp];
|
|
41
|
+
export declare const POSITIVE_TABINDEX_PATTERNS: readonly [RegExp, RegExp];
|
|
42
|
+
export declare const MOUSE_ONLY_HANDLER_PATTERNS: readonly [RegExp];
|
|
43
|
+
export declare function shouldExcludeFile(filePath: string): boolean;
|
|
44
|
+
export declare function detectTabindex(content: string, filePath: string): KeyboardNavPatternInfo[];
|
|
45
|
+
export declare function detectOnKeyDown(content: string, filePath: string): KeyboardNavPatternInfo[];
|
|
46
|
+
export declare function detectOnKeyUp(content: string, filePath: string): KeyboardNavPatternInfo[];
|
|
47
|
+
export declare function detectOnKeyPress(content: string, filePath: string): KeyboardNavPatternInfo[];
|
|
48
|
+
export declare function detectFocusTrap(content: string, filePath: string): KeyboardNavPatternInfo[];
|
|
49
|
+
export declare function detectSkipLink(content: string, filePath: string): KeyboardNavPatternInfo[];
|
|
50
|
+
export declare function detectPositiveTabindexViolations(content: string, filePath: string): KeyboardNavViolationInfo[];
|
|
51
|
+
export declare function analyzeKeyboardNav(content: string, filePath: string): KeyboardNavAnalysis;
|
|
52
|
+
export declare class KeyboardNavDetector extends RegexDetector {
|
|
53
|
+
readonly id = "accessibility/keyboard-nav";
|
|
54
|
+
readonly name = "Keyboard Navigation Detector";
|
|
55
|
+
readonly description = "Detects keyboard navigation patterns";
|
|
56
|
+
readonly category: PatternCategory;
|
|
57
|
+
readonly subcategory = "keyboard-nav";
|
|
58
|
+
readonly supportedLanguages: Language[];
|
|
59
|
+
detect(context: DetectionContext): Promise<DetectionResult>;
|
|
60
|
+
generateQuickFix(_violation: Violation): QuickFix | null;
|
|
61
|
+
}
|
|
62
|
+
export declare function createKeyboardNavDetector(): KeyboardNavDetector;
|
|
63
|
+
//# sourceMappingURL=keyboard-nav.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyboard-nav.d.ts","sourceRoot":"","sources":["../../src/accessibility/keyboard-nav.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keyboard Navigation Detector - Keyboard navigation pattern detection
|
|
3
|
+
* @requirements 20.3 - Keyboard navigation patterns
|
|
4
|
+
*/
|
|
5
|
+
import { RegexDetector } from '../base/regex-detector.js';
|
|
6
|
+
export const TABINDEX_PATTERNS = [/tabIndex\s*=\s*['"`]?-?\d+['"`]?/gi, /tabindex\s*=\s*['"`]?-?\d+['"`]?/gi];
|
|
7
|
+
export const ONKEYDOWN_PATTERNS = [/onKeyDown\s*=\s*\{/gi, /onkeydown\s*=/gi];
|
|
8
|
+
export const ONKEYUP_PATTERNS = [/onKeyUp\s*=\s*\{/gi, /onkeyup\s*=/gi];
|
|
9
|
+
export const ONKEYPRESS_PATTERNS = [/onKeyPress\s*=\s*\{/gi, /onkeypress\s*=/gi];
|
|
10
|
+
export const FOCUS_TRAP_PATTERNS = [/focus-trap/gi, /FocusTrap/g, /useFocusTrap/g];
|
|
11
|
+
export const SKIP_LINK_PATTERNS = [/skip-link/gi, /skipLink/g, /#main-content/g, /#content/g];
|
|
12
|
+
export const POSITIVE_TABINDEX_PATTERNS = [/tabIndex\s*=\s*['"`]?[1-9]\d*['"`]?/gi, /tabindex\s*=\s*['"`]?[1-9]\d*['"`]?/gi];
|
|
13
|
+
export const MOUSE_ONLY_HANDLER_PATTERNS = [/onClick\s*=\s*\{[^}]+\}(?![^<]*onKey)/gi];
|
|
14
|
+
export function shouldExcludeFile(filePath) {
|
|
15
|
+
return [/\.test\.[jt]sx?$/, /\.spec\.[jt]sx?$/, /__tests__\//, /node_modules\//, /\.min\.[jt]s$/].some((p) => p.test(filePath));
|
|
16
|
+
}
|
|
17
|
+
function detectPatterns(content, filePath, patterns, type) {
|
|
18
|
+
const results = [];
|
|
19
|
+
const lines = content.split('\n');
|
|
20
|
+
for (let i = 0; i < lines.length; i++) {
|
|
21
|
+
const line = lines[i];
|
|
22
|
+
for (const pattern of patterns) {
|
|
23
|
+
const regex = new RegExp(pattern.source, pattern.flags);
|
|
24
|
+
let match;
|
|
25
|
+
while ((match = regex.exec(line)) !== null) {
|
|
26
|
+
results.push({ type, file: filePath, line: i + 1, column: match.index + 1, matchedText: match[0], context: line.trim() });
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return results;
|
|
31
|
+
}
|
|
32
|
+
export function detectTabindex(content, filePath) { return detectPatterns(content, filePath, TABINDEX_PATTERNS, 'tabindex'); }
|
|
33
|
+
export function detectOnKeyDown(content, filePath) { return detectPatterns(content, filePath, ONKEYDOWN_PATTERNS, 'onkeydown'); }
|
|
34
|
+
export function detectOnKeyUp(content, filePath) { return detectPatterns(content, filePath, ONKEYUP_PATTERNS, 'onkeyup'); }
|
|
35
|
+
export function detectOnKeyPress(content, filePath) { return detectPatterns(content, filePath, ONKEYPRESS_PATTERNS, 'onkeypress'); }
|
|
36
|
+
export function detectFocusTrap(content, filePath) { return detectPatterns(content, filePath, FOCUS_TRAP_PATTERNS, 'focus-trap'); }
|
|
37
|
+
export function detectSkipLink(content, filePath) { return detectPatterns(content, filePath, SKIP_LINK_PATTERNS, 'skip-link'); }
|
|
38
|
+
export function detectPositiveTabindexViolations(content, filePath) {
|
|
39
|
+
const results = [];
|
|
40
|
+
const lines = content.split('\n');
|
|
41
|
+
for (let i = 0; i < lines.length; i++) {
|
|
42
|
+
const line = lines[i];
|
|
43
|
+
for (const pattern of POSITIVE_TABINDEX_PATTERNS) {
|
|
44
|
+
const regex = new RegExp(pattern.source, pattern.flags);
|
|
45
|
+
let match;
|
|
46
|
+
while ((match = regex.exec(line)) !== null) {
|
|
47
|
+
results.push({ type: 'positive-tabindex', file: filePath, line: i + 1, column: match.index + 1, matchedText: match[0], issue: 'Positive tabindex disrupts natural tab order', suggestedFix: 'Use tabIndex={0} or tabIndex={-1} instead', severity: 'high' });
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return results;
|
|
52
|
+
}
|
|
53
|
+
export function analyzeKeyboardNav(content, filePath) {
|
|
54
|
+
if (shouldExcludeFile(filePath))
|
|
55
|
+
return { patterns: [], violations: [], tabindexCount: 0, keyboardHandlerCount: 0, confidence: 1.0 };
|
|
56
|
+
const patterns = [...detectTabindex(content, filePath), ...detectOnKeyDown(content, filePath), ...detectOnKeyUp(content, filePath), ...detectOnKeyPress(content, filePath), ...detectFocusTrap(content, filePath), ...detectSkipLink(content, filePath)];
|
|
57
|
+
const violations = [...detectPositiveTabindexViolations(content, filePath)];
|
|
58
|
+
const tabindexCount = patterns.filter((p) => p.type === 'tabindex').length;
|
|
59
|
+
const keyboardHandlerCount = patterns.filter((p) => p.type.startsWith('onkey')).length;
|
|
60
|
+
let confidence = 0.7;
|
|
61
|
+
if (patterns.length > 0)
|
|
62
|
+
confidence += 0.15;
|
|
63
|
+
if (violations.length === 0)
|
|
64
|
+
confidence += 0.1;
|
|
65
|
+
confidence = Math.min(confidence, 0.95);
|
|
66
|
+
return { patterns, violations, tabindexCount, keyboardHandlerCount, confidence };
|
|
67
|
+
}
|
|
68
|
+
export class KeyboardNavDetector extends RegexDetector {
|
|
69
|
+
id = 'accessibility/keyboard-nav';
|
|
70
|
+
name = 'Keyboard Navigation Detector';
|
|
71
|
+
description = 'Detects keyboard navigation patterns';
|
|
72
|
+
category = 'accessibility';
|
|
73
|
+
subcategory = 'keyboard-nav';
|
|
74
|
+
supportedLanguages = ['typescript', 'javascript'];
|
|
75
|
+
async detect(context) {
|
|
76
|
+
if (!this.supportsLanguage(context.language))
|
|
77
|
+
return this.createEmptyResult();
|
|
78
|
+
const analysis = analyzeKeyboardNav(context.content, context.file);
|
|
79
|
+
if (analysis.patterns.length === 0 && analysis.violations.length === 0)
|
|
80
|
+
return this.createEmptyResult();
|
|
81
|
+
return this.createResult([], [], analysis.confidence, { custom: { patterns: analysis.patterns, violations: analysis.violations, tabindexCount: analysis.tabindexCount, keyboardHandlerCount: analysis.keyboardHandlerCount } });
|
|
82
|
+
}
|
|
83
|
+
generateQuickFix(_violation) { return null; }
|
|
84
|
+
}
|
|
85
|
+
export function createKeyboardNavDetector() { return new KeyboardNavDetector(); }
|
|
86
|
+
//# sourceMappingURL=keyboard-nav.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyboard-nav.js","sourceRoot":"","sources":["../../src/accessibility/keyboard-nav.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAU1D,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,oCAAoC,EAAE,oCAAoC,CAAU,CAAC;AACvH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,sBAAsB,EAAE,iBAAiB,CAAU,CAAC;AACvF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,oBAAoB,EAAE,eAAe,CAAU,CAAC;AACjF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,uBAAuB,EAAE,kBAAkB,CAAU,CAAC;AAC1F,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,cAAc,EAAE,YAAY,EAAE,eAAe,CAAU,CAAC;AAC5F,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,aAAa,EAAE,WAAW,EAAE,gBAAgB,EAAE,WAAW,CAAU,CAAC;AACvG,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,uCAAuC,EAAE,uCAAuC,CAAU,CAAC;AACtI,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,yCAAyC,CAAU,CAAC;AAEhG,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAChD,OAAO,CAAC,kBAAkB,EAAE,kBAAkB,EAAE,aAAa,EAAE,gBAAgB,EAAE,eAAe,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;AAClI,CAAC;AAED,SAAS,cAAc,CAAC,OAAe,EAAE,QAAgB,EAAE,QAA2B,EAAE,IAA4B;IAClH,MAAM,OAAO,GAA6B,EAAE,CAAC;IAC7C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;QACvB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;YACxD,IAAI,KAAK,CAAC;YACV,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;gBAC3C,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,KAAK,GAAG,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAC5H,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,OAAe,EAAE,QAAgB,IAA8B,OAAO,cAAc,CAAC,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;AACxK,MAAM,UAAU,eAAe,CAAC,OAAe,EAAE,QAAgB,IAA8B,OAAO,cAAc,CAAC,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;AAC3K,MAAM,UAAU,aAAa,CAAC,OAAe,EAAE,QAAgB,IAA8B,OAAO,cAAc,CAAC,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;AACrK,MAAM,UAAU,gBAAgB,CAAC,OAAe,EAAE,QAAgB,IAA8B,OAAO,cAAc,CAAC,OAAO,EAAE,QAAQ,EAAE,mBAAmB,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;AAC9K,MAAM,UAAU,eAAe,CAAC,OAAe,EAAE,QAAgB,IAA8B,OAAO,cAAc,CAAC,OAAO,EAAE,QAAQ,EAAE,mBAAmB,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;AAC7K,MAAM,UAAU,cAAc,CAAC,OAAe,EAAE,QAAgB,IAA8B,OAAO,cAAc,CAAC,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;AAE1K,MAAM,UAAU,gCAAgC,CAAC,OAAe,EAAE,QAAgB;IAChF,MAAM,OAAO,GAA+B,EAAE,CAAC;IAC/C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;QACvB,KAAK,MAAM,OAAO,IAAI,0BAA0B,EAAE,CAAC;YACjD,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;YACxD,IAAI,KAAK,CAAC;YACV,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;gBAC3C,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,KAAK,GAAG,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,8CAA8C,EAAE,YAAY,EAAE,2CAA2C,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;YAC/P,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAAe,EAAE,QAAgB;IAClE,IAAI,iBAAiB,CAAC,QAAQ,CAAC;QAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,aAAa,EAAE,CAAC,EAAE,oBAAoB,EAAE,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC;IACrI,MAAM,QAAQ,GAA6B,CAAC,GAAG,cAAc,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,GAAG,eAAe,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,GAAG,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,GAAG,gBAAgB,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,GAAG,eAAe,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,GAAG,cAAc,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;IACnR,MAAM,UAAU,GAA+B,CAAC,GAAG,gCAAgC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;IACxG,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,MAAM,CAAC;IAC3E,MAAM,oBAAoB,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;IACvF,IAAI,UAAU,GAAG,GAAG,CAAC;IAAC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;QAAE,UAAU,IAAI,IAAI,CAAC;IAAC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,UAAU,IAAI,GAAG,CAAC;IAAC,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IAC3J,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,aAAa,EAAE,oBAAoB,EAAE,UAAU,EAAE,CAAC;AACnF,CAAC;AAED,MAAM,OAAO,mBAAoB,SAAQ,aAAa;IAC3C,EAAE,GAAG,4BAA4B,CAAC;IAClC,IAAI,GAAG,8BAA8B,CAAC;IACtC,WAAW,GAAG,sCAAsC,CAAC;IACrD,QAAQ,GAAoB,eAAe,CAAC;IAC5C,WAAW,GAAG,cAAc,CAAC;IAC7B,kBAAkB,GAAe,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;IAEvE,KAAK,CAAC,MAAM,CAAC,OAAyB;QACpC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,QAAQ,CAAC;YAAE,OAAO,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC9E,MAAM,QAAQ,GAAG,kBAAkB,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QACnE,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,QAAQ,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACxG,OAAO,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,EAAE,EAAE,QAAQ,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,UAAU,EAAE,QAAQ,CAAC,UAAU,EAAE,aAAa,EAAE,QAAQ,CAAC,aAAa,EAAE,oBAAoB,EAAE,QAAQ,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC;IAClO,CAAC;IAED,gBAAgB,CAAC,UAAqB,IAAqB,OAAO,IAAI,CAAC,CAAC,CAAC;CAC1E;AAED,MAAM,UAAU,yBAAyB,KAA0B,OAAO,IAAI,mBAAmB,EAAE,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Semantic HTML Detector - Semantic HTML pattern detection
|
|
3
|
+
*
|
|
4
|
+
* Detects semantic HTML patterns including:
|
|
5
|
+
* - Semantic elements (header, nav, main, footer, article, section)
|
|
6
|
+
* - Landmark roles
|
|
7
|
+
* - Non-semantic div/span usage
|
|
8
|
+
*
|
|
9
|
+
* @requirements 20.1 - Semantic HTML patterns
|
|
10
|
+
*/
|
|
11
|
+
import type { Violation, QuickFix, PatternCategory, Language } from 'driftdetect-core';
|
|
12
|
+
import { RegexDetector } from '../base/regex-detector.js';
|
|
13
|
+
import type { DetectionContext, DetectionResult } from '../base/base-detector.js';
|
|
14
|
+
export type SemanticHtmlPatternType = 'header-element' | 'nav-element' | 'main-element' | 'footer-element' | 'article-element' | 'section-element' | 'aside-element' | 'figure-element' | 'landmark-role';
|
|
15
|
+
export type SemanticHtmlViolationType = 'div-soup' | 'missing-main' | 'missing-nav' | 'non-semantic-button';
|
|
16
|
+
export interface SemanticHtmlPatternInfo {
|
|
17
|
+
type: SemanticHtmlPatternType;
|
|
18
|
+
file: string;
|
|
19
|
+
line: number;
|
|
20
|
+
column: number;
|
|
21
|
+
matchedText: string;
|
|
22
|
+
context?: string | undefined;
|
|
23
|
+
}
|
|
24
|
+
export interface SemanticHtmlViolationInfo {
|
|
25
|
+
type: SemanticHtmlViolationType;
|
|
26
|
+
file: string;
|
|
27
|
+
line: number;
|
|
28
|
+
column: number;
|
|
29
|
+
matchedText: string;
|
|
30
|
+
issue: string;
|
|
31
|
+
suggestedFix?: string | undefined;
|
|
32
|
+
severity: 'high' | 'medium' | 'low';
|
|
33
|
+
}
|
|
34
|
+
export interface SemanticHtmlAnalysis {
|
|
35
|
+
patterns: SemanticHtmlPatternInfo[];
|
|
36
|
+
violations: SemanticHtmlViolationInfo[];
|
|
37
|
+
semanticElementCount: number;
|
|
38
|
+
hasMain: boolean;
|
|
39
|
+
hasNav: boolean;
|
|
40
|
+
confidence: number;
|
|
41
|
+
}
|
|
42
|
+
export declare const HEADER_ELEMENT_PATTERNS: readonly [RegExp, RegExp];
|
|
43
|
+
export declare const NAV_ELEMENT_PATTERNS: readonly [RegExp, RegExp];
|
|
44
|
+
export declare const MAIN_ELEMENT_PATTERNS: readonly [RegExp, RegExp];
|
|
45
|
+
export declare const FOOTER_ELEMENT_PATTERNS: readonly [RegExp, RegExp];
|
|
46
|
+
export declare const ARTICLE_ELEMENT_PATTERNS: readonly [RegExp, RegExp];
|
|
47
|
+
export declare const SECTION_ELEMENT_PATTERNS: readonly [RegExp, RegExp];
|
|
48
|
+
export declare const ASIDE_ELEMENT_PATTERNS: readonly [RegExp, RegExp];
|
|
49
|
+
export declare const FIGURE_ELEMENT_PATTERNS: readonly [RegExp, RegExp];
|
|
50
|
+
export declare const LANDMARK_ROLE_PATTERNS: readonly [RegExp, RegExp, RegExp, RegExp, RegExp, RegExp];
|
|
51
|
+
export declare const DIV_SOUP_PATTERNS: readonly [RegExp, RegExp, RegExp];
|
|
52
|
+
export declare const NON_SEMANTIC_BUTTON_PATTERNS: readonly [RegExp, RegExp];
|
|
53
|
+
export declare function shouldExcludeFile(filePath: string): boolean;
|
|
54
|
+
export declare function detectHeaderElement(content: string, filePath: string): SemanticHtmlPatternInfo[];
|
|
55
|
+
export declare function detectNavElement(content: string, filePath: string): SemanticHtmlPatternInfo[];
|
|
56
|
+
export declare function detectMainElement(content: string, filePath: string): SemanticHtmlPatternInfo[];
|
|
57
|
+
export declare function detectFooterElement(content: string, filePath: string): SemanticHtmlPatternInfo[];
|
|
58
|
+
export declare function detectArticleElement(content: string, filePath: string): SemanticHtmlPatternInfo[];
|
|
59
|
+
export declare function detectSectionElement(content: string, filePath: string): SemanticHtmlPatternInfo[];
|
|
60
|
+
export declare function detectAsideElement(content: string, filePath: string): SemanticHtmlPatternInfo[];
|
|
61
|
+
export declare function detectFigureElement(content: string, filePath: string): SemanticHtmlPatternInfo[];
|
|
62
|
+
export declare function detectLandmarkRole(content: string, filePath: string): SemanticHtmlPatternInfo[];
|
|
63
|
+
export declare function detectDivSoupViolations(content: string, filePath: string): SemanticHtmlViolationInfo[];
|
|
64
|
+
export declare function analyzeSemanticHtml(content: string, filePath: string): SemanticHtmlAnalysis;
|
|
65
|
+
export declare class SemanticHtmlDetector extends RegexDetector {
|
|
66
|
+
readonly id = "accessibility/semantic-html";
|
|
67
|
+
readonly name = "Semantic HTML Detector";
|
|
68
|
+
readonly description = "Detects semantic HTML element usage patterns";
|
|
69
|
+
readonly category: PatternCategory;
|
|
70
|
+
readonly subcategory = "semantic-html";
|
|
71
|
+
readonly supportedLanguages: Language[];
|
|
72
|
+
detect(context: DetectionContext): Promise<DetectionResult>;
|
|
73
|
+
generateQuickFix(_violation: Violation): QuickFix | null;
|
|
74
|
+
}
|
|
75
|
+
export declare function createSemanticHtmlDetector(): SemanticHtmlDetector;
|
|
76
|
+
//# sourceMappingURL=semantic-html.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semantic-html.d.ts","sourceRoot":"","sources":["../../src/accessibility/semantic-html.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Semantic HTML Detector - Semantic HTML pattern detection
|
|
3
|
+
*
|
|
4
|
+
* Detects semantic HTML patterns including:
|
|
5
|
+
* - Semantic elements (header, nav, main, footer, article, section)
|
|
6
|
+
* - Landmark roles
|
|
7
|
+
* - Non-semantic div/span usage
|
|
8
|
+
*
|
|
9
|
+
* @requirements 20.1 - Semantic HTML patterns
|
|
10
|
+
*/
|
|
11
|
+
import { RegexDetector } from '../base/regex-detector.js';
|
|
12
|
+
// ============================================================================
|
|
13
|
+
// Constants
|
|
14
|
+
// ============================================================================
|
|
15
|
+
export const HEADER_ELEMENT_PATTERNS = [/<header[\s>]/gi, /<Header[\s>]/g];
|
|
16
|
+
export const NAV_ELEMENT_PATTERNS = [/<nav[\s>]/gi, /<Nav[\s>]/g];
|
|
17
|
+
export const MAIN_ELEMENT_PATTERNS = [/<main[\s>]/gi, /<Main[\s>]/g];
|
|
18
|
+
export const FOOTER_ELEMENT_PATTERNS = [/<footer[\s>]/gi, /<Footer[\s>]/g];
|
|
19
|
+
export const ARTICLE_ELEMENT_PATTERNS = [/<article[\s>]/gi, /<Article[\s>]/g];
|
|
20
|
+
export const SECTION_ELEMENT_PATTERNS = [/<section[\s>]/gi, /<Section[\s>]/g];
|
|
21
|
+
export const ASIDE_ELEMENT_PATTERNS = [/<aside[\s>]/gi, /<Aside[\s>]/g];
|
|
22
|
+
export const FIGURE_ELEMENT_PATTERNS = [/<figure[\s>]/gi, /<Figure[\s>]/g];
|
|
23
|
+
export const LANDMARK_ROLE_PATTERNS = [
|
|
24
|
+
/role\s*=\s*['"`]banner['"`]/gi,
|
|
25
|
+
/role\s*=\s*['"`]navigation['"`]/gi,
|
|
26
|
+
/role\s*=\s*['"`]main['"`]/gi,
|
|
27
|
+
/role\s*=\s*['"`]contentinfo['"`]/gi,
|
|
28
|
+
/role\s*=\s*['"`]complementary['"`]/gi,
|
|
29
|
+
/role\s*=\s*['"`]region['"`]/gi,
|
|
30
|
+
];
|
|
31
|
+
export const DIV_SOUP_PATTERNS = [
|
|
32
|
+
/<div[^>]*onClick/gi,
|
|
33
|
+
/<div[^>]*role\s*=\s*['"`]button['"`]/gi,
|
|
34
|
+
/<span[^>]*onClick/gi,
|
|
35
|
+
];
|
|
36
|
+
export const NON_SEMANTIC_BUTTON_PATTERNS = [
|
|
37
|
+
/<div[^>]*onClick[^>]*>[^<]*(?:click|submit|button)/gi,
|
|
38
|
+
/<span[^>]*onClick[^>]*>[^<]*(?:click|submit|button)/gi,
|
|
39
|
+
];
|
|
40
|
+
// ============================================================================
|
|
41
|
+
// Analysis Functions
|
|
42
|
+
// ============================================================================
|
|
43
|
+
export function shouldExcludeFile(filePath) {
|
|
44
|
+
const excludePatterns = [
|
|
45
|
+
/\.test\.[jt]sx?$/,
|
|
46
|
+
/\.spec\.[jt]sx?$/,
|
|
47
|
+
/__tests__\//,
|
|
48
|
+
/node_modules\//,
|
|
49
|
+
/\.min\.[jt]s$/,
|
|
50
|
+
];
|
|
51
|
+
return excludePatterns.some((p) => p.test(filePath));
|
|
52
|
+
}
|
|
53
|
+
function detectPatterns(content, filePath, patterns, type) {
|
|
54
|
+
const results = [];
|
|
55
|
+
const lines = content.split('\n');
|
|
56
|
+
for (let i = 0; i < lines.length; i++) {
|
|
57
|
+
const line = lines[i];
|
|
58
|
+
for (const pattern of patterns) {
|
|
59
|
+
const regex = new RegExp(pattern.source, pattern.flags);
|
|
60
|
+
let match;
|
|
61
|
+
while ((match = regex.exec(line)) !== null) {
|
|
62
|
+
results.push({
|
|
63
|
+
type,
|
|
64
|
+
file: filePath,
|
|
65
|
+
line: i + 1,
|
|
66
|
+
column: match.index + 1,
|
|
67
|
+
matchedText: match[0],
|
|
68
|
+
context: line.trim(),
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return results;
|
|
74
|
+
}
|
|
75
|
+
export function detectHeaderElement(content, filePath) {
|
|
76
|
+
return detectPatterns(content, filePath, HEADER_ELEMENT_PATTERNS, 'header-element');
|
|
77
|
+
}
|
|
78
|
+
export function detectNavElement(content, filePath) {
|
|
79
|
+
return detectPatterns(content, filePath, NAV_ELEMENT_PATTERNS, 'nav-element');
|
|
80
|
+
}
|
|
81
|
+
export function detectMainElement(content, filePath) {
|
|
82
|
+
return detectPatterns(content, filePath, MAIN_ELEMENT_PATTERNS, 'main-element');
|
|
83
|
+
}
|
|
84
|
+
export function detectFooterElement(content, filePath) {
|
|
85
|
+
return detectPatterns(content, filePath, FOOTER_ELEMENT_PATTERNS, 'footer-element');
|
|
86
|
+
}
|
|
87
|
+
export function detectArticleElement(content, filePath) {
|
|
88
|
+
return detectPatterns(content, filePath, ARTICLE_ELEMENT_PATTERNS, 'article-element');
|
|
89
|
+
}
|
|
90
|
+
export function detectSectionElement(content, filePath) {
|
|
91
|
+
return detectPatterns(content, filePath, SECTION_ELEMENT_PATTERNS, 'section-element');
|
|
92
|
+
}
|
|
93
|
+
export function detectAsideElement(content, filePath) {
|
|
94
|
+
return detectPatterns(content, filePath, ASIDE_ELEMENT_PATTERNS, 'aside-element');
|
|
95
|
+
}
|
|
96
|
+
export function detectFigureElement(content, filePath) {
|
|
97
|
+
return detectPatterns(content, filePath, FIGURE_ELEMENT_PATTERNS, 'figure-element');
|
|
98
|
+
}
|
|
99
|
+
export function detectLandmarkRole(content, filePath) {
|
|
100
|
+
return detectPatterns(content, filePath, LANDMARK_ROLE_PATTERNS, 'landmark-role');
|
|
101
|
+
}
|
|
102
|
+
export function detectDivSoupViolations(content, filePath) {
|
|
103
|
+
const results = [];
|
|
104
|
+
const lines = content.split('\n');
|
|
105
|
+
for (let i = 0; i < lines.length; i++) {
|
|
106
|
+
const line = lines[i];
|
|
107
|
+
for (const pattern of DIV_SOUP_PATTERNS) {
|
|
108
|
+
const regex = new RegExp(pattern.source, pattern.flags);
|
|
109
|
+
let match;
|
|
110
|
+
while ((match = regex.exec(line)) !== null) {
|
|
111
|
+
results.push({
|
|
112
|
+
type: 'div-soup',
|
|
113
|
+
file: filePath,
|
|
114
|
+
line: i + 1,
|
|
115
|
+
column: match.index + 1,
|
|
116
|
+
matchedText: match[0],
|
|
117
|
+
issue: 'Interactive div/span should use semantic elements',
|
|
118
|
+
suggestedFix: 'Use <button> for clickable elements',
|
|
119
|
+
severity: 'medium',
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return results;
|
|
125
|
+
}
|
|
126
|
+
export function analyzeSemanticHtml(content, filePath) {
|
|
127
|
+
if (shouldExcludeFile(filePath)) {
|
|
128
|
+
return {
|
|
129
|
+
patterns: [],
|
|
130
|
+
violations: [],
|
|
131
|
+
semanticElementCount: 0,
|
|
132
|
+
hasMain: false,
|
|
133
|
+
hasNav: false,
|
|
134
|
+
confidence: 1.0,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
const patterns = [
|
|
138
|
+
...detectHeaderElement(content, filePath),
|
|
139
|
+
...detectNavElement(content, filePath),
|
|
140
|
+
...detectMainElement(content, filePath),
|
|
141
|
+
...detectFooterElement(content, filePath),
|
|
142
|
+
...detectArticleElement(content, filePath),
|
|
143
|
+
...detectSectionElement(content, filePath),
|
|
144
|
+
...detectAsideElement(content, filePath),
|
|
145
|
+
...detectFigureElement(content, filePath),
|
|
146
|
+
...detectLandmarkRole(content, filePath),
|
|
147
|
+
];
|
|
148
|
+
const violations = [
|
|
149
|
+
...detectDivSoupViolations(content, filePath),
|
|
150
|
+
];
|
|
151
|
+
const semanticElementCount = patterns.length;
|
|
152
|
+
const hasMain = patterns.some((p) => p.type === 'main-element');
|
|
153
|
+
const hasNav = patterns.some((p) => p.type === 'nav-element');
|
|
154
|
+
let confidence = 0.7;
|
|
155
|
+
if (patterns.length > 0)
|
|
156
|
+
confidence += 0.15;
|
|
157
|
+
if (violations.length === 0)
|
|
158
|
+
confidence += 0.1;
|
|
159
|
+
confidence = Math.min(confidence, 0.95);
|
|
160
|
+
return {
|
|
161
|
+
patterns,
|
|
162
|
+
violations,
|
|
163
|
+
semanticElementCount,
|
|
164
|
+
hasMain,
|
|
165
|
+
hasNav,
|
|
166
|
+
confidence,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
// ============================================================================
|
|
170
|
+
// Detector Class
|
|
171
|
+
// ============================================================================
|
|
172
|
+
export class SemanticHtmlDetector extends RegexDetector {
|
|
173
|
+
id = 'accessibility/semantic-html';
|
|
174
|
+
name = 'Semantic HTML Detector';
|
|
175
|
+
description = 'Detects semantic HTML element usage patterns';
|
|
176
|
+
category = 'accessibility';
|
|
177
|
+
subcategory = 'semantic-html';
|
|
178
|
+
supportedLanguages = ['typescript', 'javascript'];
|
|
179
|
+
async detect(context) {
|
|
180
|
+
if (!this.supportsLanguage(context.language)) {
|
|
181
|
+
return this.createEmptyResult();
|
|
182
|
+
}
|
|
183
|
+
const analysis = analyzeSemanticHtml(context.content, context.file);
|
|
184
|
+
if (analysis.patterns.length === 0 && analysis.violations.length === 0) {
|
|
185
|
+
return this.createEmptyResult();
|
|
186
|
+
}
|
|
187
|
+
return this.createResult([], [], analysis.confidence, {
|
|
188
|
+
custom: {
|
|
189
|
+
patterns: analysis.patterns,
|
|
190
|
+
violations: analysis.violations,
|
|
191
|
+
semanticElementCount: analysis.semanticElementCount,
|
|
192
|
+
hasMain: analysis.hasMain,
|
|
193
|
+
hasNav: analysis.hasNav,
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
generateQuickFix(_violation) {
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
export function createSemanticHtmlDetector() {
|
|
202
|
+
return new SemanticHtmlDetector();
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=semantic-html.js.map
|