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,699 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AST Detector - AST-based detection base class
|
|
3
|
+
*
|
|
4
|
+
* Provides Tree-sitter query helpers and utilities for AST-based pattern detection.
|
|
5
|
+
* Extends BaseDetector with specialized methods for traversing and querying ASTs.
|
|
6
|
+
*
|
|
7
|
+
* @requirements 6.4 - THE Detector_System SHALL support detection methods: ast, regex, semantic, structural, and custom
|
|
8
|
+
*/
|
|
9
|
+
import { BaseDetector } from './base-detector.js';
|
|
10
|
+
// ============================================================================
|
|
11
|
+
// AST Detector Abstract Class
|
|
12
|
+
// ============================================================================
|
|
13
|
+
/**
|
|
14
|
+
* Abstract base class for AST-based detectors
|
|
15
|
+
*
|
|
16
|
+
* Provides Tree-sitter query helpers and utilities for pattern detection
|
|
17
|
+
* that operates on parsed AST structures.
|
|
18
|
+
*
|
|
19
|
+
* @requirements 6.4 - THE Detector_System SHALL support detection methods: ast
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* class FunctionNamingDetector extends ASTDetector {
|
|
24
|
+
* readonly id = 'structural/function-naming';
|
|
25
|
+
* readonly category = 'structural';
|
|
26
|
+
* readonly subcategory = 'naming-conventions';
|
|
27
|
+
* readonly name = 'Function Naming Detector';
|
|
28
|
+
* readonly description = 'Detects function naming patterns';
|
|
29
|
+
* readonly supportedLanguages = ['typescript', 'javascript'];
|
|
30
|
+
*
|
|
31
|
+
* async detect(context: DetectionContext): Promise<DetectionResult> {
|
|
32
|
+
* if (!context.ast) {
|
|
33
|
+
* return this.createEmptyResult();
|
|
34
|
+
* }
|
|
35
|
+
*
|
|
36
|
+
* const functions = this.findNodes(context.ast, 'function_declaration');
|
|
37
|
+
* // Analyze function naming patterns...
|
|
38
|
+
* }
|
|
39
|
+
*
|
|
40
|
+
* generateQuickFix(violation: Violation): QuickFix | null {
|
|
41
|
+
* return null;
|
|
42
|
+
* }
|
|
43
|
+
* }
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export class ASTDetector extends BaseDetector {
|
|
47
|
+
/**
|
|
48
|
+
* Detection method is always 'ast' for AST-based detectors
|
|
49
|
+
*
|
|
50
|
+
* @requirements 6.4 - Detector declares detection method as 'ast'
|
|
51
|
+
*/
|
|
52
|
+
detectionMethod = 'ast';
|
|
53
|
+
// ============================================================================
|
|
54
|
+
// Node Finding Methods
|
|
55
|
+
// ============================================================================
|
|
56
|
+
/**
|
|
57
|
+
* Find all nodes of a specific type in the AST
|
|
58
|
+
*
|
|
59
|
+
* Traverses the entire AST and returns all nodes matching the specified type.
|
|
60
|
+
*
|
|
61
|
+
* @param ast - The AST to search
|
|
62
|
+
* @param nodeType - The type of node to find (e.g., 'function_declaration', 'class_declaration')
|
|
63
|
+
* @returns Array of matching nodes
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```typescript
|
|
67
|
+
* const functions = this.findNodes(ast, 'function_declaration');
|
|
68
|
+
* const classes = this.findNodes(ast, 'class_declaration');
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
findNodes(ast, nodeType) {
|
|
72
|
+
const results = [];
|
|
73
|
+
this.traverse(ast, (node) => {
|
|
74
|
+
if (node.type === nodeType) {
|
|
75
|
+
results.push(node);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
return results;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Find all nodes matching multiple types
|
|
82
|
+
*
|
|
83
|
+
* @param ast - The AST to search
|
|
84
|
+
* @param nodeTypes - Array of node types to find
|
|
85
|
+
* @returns Array of matching nodes
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```typescript
|
|
89
|
+
* const declarations = this.findNodesByTypes(ast, ['function_declaration', 'arrow_function']);
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
findNodesByTypes(ast, nodeTypes) {
|
|
93
|
+
const typeSet = new Set(nodeTypes);
|
|
94
|
+
const results = [];
|
|
95
|
+
this.traverse(ast, (node) => {
|
|
96
|
+
if (typeSet.has(node.type)) {
|
|
97
|
+
results.push(node);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
return results;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Find the first node of a specific type
|
|
104
|
+
*
|
|
105
|
+
* @param ast - The AST to search
|
|
106
|
+
* @param nodeType - The type of node to find
|
|
107
|
+
* @returns The first matching node, or null if not found
|
|
108
|
+
*/
|
|
109
|
+
findFirstNode(ast, nodeType) {
|
|
110
|
+
let result = null;
|
|
111
|
+
this.traverse(ast, (node) => {
|
|
112
|
+
if (node.type === nodeType) {
|
|
113
|
+
result = node;
|
|
114
|
+
return false; // Stop traversal
|
|
115
|
+
}
|
|
116
|
+
return undefined;
|
|
117
|
+
});
|
|
118
|
+
return result;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Find nodes matching a predicate function
|
|
122
|
+
*
|
|
123
|
+
* @param ast - The AST to search
|
|
124
|
+
* @param predicate - Function that returns true for matching nodes
|
|
125
|
+
* @returns Array of matching nodes
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ```typescript
|
|
129
|
+
* const asyncFunctions = this.findNodesWhere(ast, (node) =>
|
|
130
|
+
* node.type === 'function_declaration' && node.text.includes('async')
|
|
131
|
+
* );
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
134
|
+
findNodesWhere(ast, predicate) {
|
|
135
|
+
const results = [];
|
|
136
|
+
this.traverse(ast, (node) => {
|
|
137
|
+
if (predicate(node)) {
|
|
138
|
+
results.push(node);
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
return results;
|
|
142
|
+
}
|
|
143
|
+
// ============================================================================
|
|
144
|
+
// Ancestor/Descendant Methods
|
|
145
|
+
// ============================================================================
|
|
146
|
+
/**
|
|
147
|
+
* Find the nearest ancestor of a specific type
|
|
148
|
+
*
|
|
149
|
+
* Traverses up the tree from the given node to find the first ancestor
|
|
150
|
+
* matching the specified type.
|
|
151
|
+
*
|
|
152
|
+
* @param node - The starting node
|
|
153
|
+
* @param nodeType - The type of ancestor to find
|
|
154
|
+
* @param ast - The AST containing the node (needed for parent lookup)
|
|
155
|
+
* @returns The ancestor node, or null if not found
|
|
156
|
+
*
|
|
157
|
+
* @example
|
|
158
|
+
* ```typescript
|
|
159
|
+
* const parentClass = this.findAncestor(methodNode, 'class_declaration', ast);
|
|
160
|
+
* ```
|
|
161
|
+
*/
|
|
162
|
+
findAncestor(node, nodeType, ast) {
|
|
163
|
+
const parentChain = this.getParentChain(ast, node);
|
|
164
|
+
// Search from immediate parent up to root
|
|
165
|
+
for (let i = parentChain.length - 1; i >= 0; i--) {
|
|
166
|
+
const parent = parentChain[i];
|
|
167
|
+
if (parent && parent.type === nodeType) {
|
|
168
|
+
return parent;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Find all ancestors of a node
|
|
175
|
+
*
|
|
176
|
+
* @param node - The starting node
|
|
177
|
+
* @param ast - The AST containing the node
|
|
178
|
+
* @returns Array of ancestor nodes from immediate parent to root
|
|
179
|
+
*/
|
|
180
|
+
findAllAncestors(node, ast) {
|
|
181
|
+
const parentChain = this.getParentChain(ast, node);
|
|
182
|
+
return parentChain.reverse();
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Find all descendants of a node
|
|
186
|
+
*
|
|
187
|
+
* @param node - The starting node
|
|
188
|
+
* @returns Array of all descendant nodes
|
|
189
|
+
*/
|
|
190
|
+
findDescendants(node) {
|
|
191
|
+
const descendants = [];
|
|
192
|
+
const collect = (n) => {
|
|
193
|
+
for (const child of n.children) {
|
|
194
|
+
descendants.push(child);
|
|
195
|
+
collect(child);
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
collect(node);
|
|
199
|
+
return descendants;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Find descendants of a specific type
|
|
203
|
+
*
|
|
204
|
+
* @param node - The starting node
|
|
205
|
+
* @param nodeType - The type of descendants to find
|
|
206
|
+
* @returns Array of matching descendant nodes
|
|
207
|
+
*/
|
|
208
|
+
findDescendantsByType(node, nodeType) {
|
|
209
|
+
const results = [];
|
|
210
|
+
const search = (n) => {
|
|
211
|
+
for (const child of n.children) {
|
|
212
|
+
if (child.type === nodeType) {
|
|
213
|
+
results.push(child);
|
|
214
|
+
}
|
|
215
|
+
search(child);
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
search(node);
|
|
219
|
+
return results;
|
|
220
|
+
}
|
|
221
|
+
// ============================================================================
|
|
222
|
+
// Node Text Methods
|
|
223
|
+
// ============================================================================
|
|
224
|
+
/**
|
|
225
|
+
* Get the text content of a node
|
|
226
|
+
*
|
|
227
|
+
* Returns the source text corresponding to the node's position.
|
|
228
|
+
* If content is provided, extracts from content; otherwise uses node.text.
|
|
229
|
+
*
|
|
230
|
+
* @param node - The node to get text for
|
|
231
|
+
* @param content - Optional source content to extract from
|
|
232
|
+
* @returns The text content of the node
|
|
233
|
+
*
|
|
234
|
+
* @example
|
|
235
|
+
* ```typescript
|
|
236
|
+
* const functionName = this.getNodeText(identifierNode, context.content);
|
|
237
|
+
* ```
|
|
238
|
+
*/
|
|
239
|
+
getNodeText(node, content) {
|
|
240
|
+
if (content) {
|
|
241
|
+
const lines = content.split('\n');
|
|
242
|
+
const startLine = node.startPosition.row;
|
|
243
|
+
const endLine = node.endPosition.row;
|
|
244
|
+
const startCol = node.startPosition.column;
|
|
245
|
+
const endCol = node.endPosition.column;
|
|
246
|
+
if (startLine === endLine) {
|
|
247
|
+
// Single line
|
|
248
|
+
const line = lines[startLine];
|
|
249
|
+
return line ? line.slice(startCol, endCol) : node.text;
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
// Multi-line
|
|
253
|
+
const result = [];
|
|
254
|
+
for (let i = startLine; i <= endLine; i++) {
|
|
255
|
+
const line = lines[i];
|
|
256
|
+
if (!line)
|
|
257
|
+
continue;
|
|
258
|
+
if (i === startLine) {
|
|
259
|
+
result.push(line.slice(startCol));
|
|
260
|
+
}
|
|
261
|
+
else if (i === endLine) {
|
|
262
|
+
result.push(line.slice(0, endCol));
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
result.push(line);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
return result.join('\n');
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
return node.text;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Get the trimmed text content of a node
|
|
275
|
+
*
|
|
276
|
+
* @param node - The node to get text for
|
|
277
|
+
* @param content - Optional source content to extract from
|
|
278
|
+
* @returns The trimmed text content
|
|
279
|
+
*/
|
|
280
|
+
getNodeTextTrimmed(node, content) {
|
|
281
|
+
return this.getNodeText(node, content).trim();
|
|
282
|
+
}
|
|
283
|
+
// ============================================================================
|
|
284
|
+
// Pattern Matching Methods
|
|
285
|
+
// ============================================================================
|
|
286
|
+
/**
|
|
287
|
+
* Match an AST against a pattern
|
|
288
|
+
*
|
|
289
|
+
* Searches the AST for nodes matching the specified pattern and returns
|
|
290
|
+
* all matches with their confidence scores.
|
|
291
|
+
*
|
|
292
|
+
* @param ast - The AST to search
|
|
293
|
+
* @param pattern - The pattern to match
|
|
294
|
+
* @returns Array of match results
|
|
295
|
+
*
|
|
296
|
+
* @example
|
|
297
|
+
* ```typescript
|
|
298
|
+
* const matches = this.matchPattern(ast, {
|
|
299
|
+
* type: 'function_declaration',
|
|
300
|
+
* children: [{ type: 'identifier', capture: 'name' }]
|
|
301
|
+
* });
|
|
302
|
+
* ```
|
|
303
|
+
*/
|
|
304
|
+
matchPattern(ast, pattern) {
|
|
305
|
+
const results = [];
|
|
306
|
+
this.traverse(ast, (node) => {
|
|
307
|
+
const captures = new Map();
|
|
308
|
+
const confidence = this.matchNode(node, pattern, captures);
|
|
309
|
+
if (confidence > 0) {
|
|
310
|
+
results.push({
|
|
311
|
+
node,
|
|
312
|
+
confidence,
|
|
313
|
+
captures,
|
|
314
|
+
startPosition: node.startPosition,
|
|
315
|
+
endPosition: node.endPosition,
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
return results;
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Match a single node against a pattern
|
|
323
|
+
*
|
|
324
|
+
* @param node - The node to match
|
|
325
|
+
* @param pattern - The pattern to match against
|
|
326
|
+
* @param captures - Map to store captured nodes
|
|
327
|
+
* @returns Confidence score (0-1), 0 if no match
|
|
328
|
+
*/
|
|
329
|
+
matchNode(node, pattern, captures) {
|
|
330
|
+
let score = 1.0;
|
|
331
|
+
// Check type
|
|
332
|
+
if (pattern.type !== undefined && node.type !== pattern.type) {
|
|
333
|
+
return 0;
|
|
334
|
+
}
|
|
335
|
+
// Check text
|
|
336
|
+
if (pattern.text !== undefined) {
|
|
337
|
+
const textMatches = this.matchText(node.text, pattern.text, pattern.exactText);
|
|
338
|
+
if (!textMatches) {
|
|
339
|
+
return 0;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
// Check children count constraints
|
|
343
|
+
if (pattern.minChildren !== undefined && node.children.length < pattern.minChildren) {
|
|
344
|
+
return 0;
|
|
345
|
+
}
|
|
346
|
+
if (pattern.maxChildren !== undefined && node.children.length > pattern.maxChildren) {
|
|
347
|
+
return 0;
|
|
348
|
+
}
|
|
349
|
+
// Check custom predicate
|
|
350
|
+
if (pattern.predicate !== undefined && !pattern.predicate(node)) {
|
|
351
|
+
return 0;
|
|
352
|
+
}
|
|
353
|
+
// Check child patterns
|
|
354
|
+
if (pattern.children !== undefined && pattern.children.length > 0) {
|
|
355
|
+
const childScore = this.matchChildPatterns(node, pattern.children, pattern.matchDescendants, captures);
|
|
356
|
+
if (childScore === 0) {
|
|
357
|
+
return 0;
|
|
358
|
+
}
|
|
359
|
+
score *= childScore;
|
|
360
|
+
}
|
|
361
|
+
// Capture the node if requested
|
|
362
|
+
if (pattern.capture !== undefined) {
|
|
363
|
+
captures.set(pattern.capture, node);
|
|
364
|
+
}
|
|
365
|
+
return score;
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Match text against a pattern (string or regex)
|
|
369
|
+
*/
|
|
370
|
+
matchText(text, pattern, exact) {
|
|
371
|
+
if (pattern instanceof RegExp) {
|
|
372
|
+
return pattern.test(text);
|
|
373
|
+
}
|
|
374
|
+
if (exact) {
|
|
375
|
+
return text === pattern;
|
|
376
|
+
}
|
|
377
|
+
return text.includes(pattern);
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Match child patterns against node children
|
|
381
|
+
*/
|
|
382
|
+
matchChildPatterns(node, childPatterns, matchDescendants, captures) {
|
|
383
|
+
const nodesToSearch = matchDescendants
|
|
384
|
+
? this.findDescendants(node)
|
|
385
|
+
: node.children;
|
|
386
|
+
let matchedCount = 0;
|
|
387
|
+
for (const childPattern of childPatterns) {
|
|
388
|
+
let found = false;
|
|
389
|
+
for (const child of nodesToSearch) {
|
|
390
|
+
const childCaptures = captures || new Map();
|
|
391
|
+
const confidence = this.matchNode(child, childPattern, childCaptures);
|
|
392
|
+
if (confidence > 0) {
|
|
393
|
+
found = true;
|
|
394
|
+
matchedCount++;
|
|
395
|
+
// Merge captures
|
|
396
|
+
if (captures) {
|
|
397
|
+
for (const [key, value] of childCaptures) {
|
|
398
|
+
captures.set(key, value);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
break;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
if (!found) {
|
|
405
|
+
return 0; // Required child pattern not found
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
return matchedCount / childPatterns.length;
|
|
409
|
+
}
|
|
410
|
+
// ============================================================================
|
|
411
|
+
// Traversal Methods
|
|
412
|
+
// ============================================================================
|
|
413
|
+
/**
|
|
414
|
+
* Traverse the AST depth-first
|
|
415
|
+
*
|
|
416
|
+
* Visits each node in the AST, calling the visitor function.
|
|
417
|
+
* The visitor can return false to stop traversal of a subtree.
|
|
418
|
+
*
|
|
419
|
+
* @param ast - The AST to traverse
|
|
420
|
+
* @param visitor - Function called for each node
|
|
421
|
+
* @param options - Traversal options
|
|
422
|
+
*
|
|
423
|
+
* @example
|
|
424
|
+
* ```typescript
|
|
425
|
+
* this.traverse(ast, (node, parent, depth) => {
|
|
426
|
+
* console.log(`${node.type} at depth ${depth}`);
|
|
427
|
+
* if (depth > 5) return false; // Stop going deeper
|
|
428
|
+
* });
|
|
429
|
+
* ```
|
|
430
|
+
*/
|
|
431
|
+
traverse(ast, visitor, options = {}) {
|
|
432
|
+
const { maxDepth, skipTypes, includeRoot = true } = options;
|
|
433
|
+
const skipSet = skipTypes ? new Set(skipTypes) : null;
|
|
434
|
+
const visit = (node, parent, depth) => {
|
|
435
|
+
// Check max depth
|
|
436
|
+
if (maxDepth !== undefined && depth > maxDepth) {
|
|
437
|
+
return true;
|
|
438
|
+
}
|
|
439
|
+
// Check if type should be skipped
|
|
440
|
+
if (skipSet && skipSet.has(node.type)) {
|
|
441
|
+
return true;
|
|
442
|
+
}
|
|
443
|
+
// Call visitor
|
|
444
|
+
const result = visitor(node, parent, depth);
|
|
445
|
+
// If visitor returns false, stop traversal of this subtree
|
|
446
|
+
if (result === false) {
|
|
447
|
+
return true;
|
|
448
|
+
}
|
|
449
|
+
// Traverse children
|
|
450
|
+
for (const child of node.children) {
|
|
451
|
+
visit(child, node, depth + 1);
|
|
452
|
+
}
|
|
453
|
+
return true;
|
|
454
|
+
};
|
|
455
|
+
if (includeRoot) {
|
|
456
|
+
visit(ast.rootNode, null, 0);
|
|
457
|
+
}
|
|
458
|
+
else {
|
|
459
|
+
for (const child of ast.rootNode.children) {
|
|
460
|
+
visit(child, ast.rootNode, 1);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Traverse a specific node and its descendants
|
|
466
|
+
*
|
|
467
|
+
* @param node - The node to start traversal from
|
|
468
|
+
* @param visitor - Function called for each node
|
|
469
|
+
* @param options - Traversal options
|
|
470
|
+
*/
|
|
471
|
+
traverseNode(node, visitor, options = {}) {
|
|
472
|
+
const { maxDepth, skipTypes } = options;
|
|
473
|
+
const skipSet = skipTypes ? new Set(skipTypes) : null;
|
|
474
|
+
const visit = (n, parent, depth) => {
|
|
475
|
+
if (maxDepth !== undefined && depth > maxDepth) {
|
|
476
|
+
return true;
|
|
477
|
+
}
|
|
478
|
+
if (skipSet && skipSet.has(n.type)) {
|
|
479
|
+
return true;
|
|
480
|
+
}
|
|
481
|
+
const result = visitor(n, parent, depth);
|
|
482
|
+
if (result === false) {
|
|
483
|
+
return true;
|
|
484
|
+
}
|
|
485
|
+
for (const child of n.children) {
|
|
486
|
+
visit(child, n, depth + 1);
|
|
487
|
+
}
|
|
488
|
+
return true;
|
|
489
|
+
};
|
|
490
|
+
visit(node, null, 0);
|
|
491
|
+
}
|
|
492
|
+
// ============================================================================
|
|
493
|
+
// Utility Methods
|
|
494
|
+
// ============================================================================
|
|
495
|
+
/**
|
|
496
|
+
* Get the parent chain from root to a specific node
|
|
497
|
+
*
|
|
498
|
+
* @param ast - The AST to search
|
|
499
|
+
* @param targetNode - The node to find parents for
|
|
500
|
+
* @returns Array of parent nodes from root to immediate parent
|
|
501
|
+
*/
|
|
502
|
+
getParentChain(ast, targetNode) {
|
|
503
|
+
const parents = [];
|
|
504
|
+
const findParents = (node, chain) => {
|
|
505
|
+
if (node === targetNode) {
|
|
506
|
+
parents.push(...chain);
|
|
507
|
+
return true;
|
|
508
|
+
}
|
|
509
|
+
for (const child of node.children) {
|
|
510
|
+
if (findParents(child, [...chain, node])) {
|
|
511
|
+
return true;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
return false;
|
|
515
|
+
};
|
|
516
|
+
findParents(ast.rootNode, []);
|
|
517
|
+
return parents;
|
|
518
|
+
}
|
|
519
|
+
/**
|
|
520
|
+
* Get the immediate parent of a node
|
|
521
|
+
*
|
|
522
|
+
* @param ast - The AST containing the node
|
|
523
|
+
* @param node - The node to find the parent of
|
|
524
|
+
* @returns The parent node, or null if node is root
|
|
525
|
+
*/
|
|
526
|
+
getParent(ast, node) {
|
|
527
|
+
const chain = this.getParentChain(ast, node);
|
|
528
|
+
return chain.length > 0 ? chain[chain.length - 1] ?? null : null;
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* Get the depth of a node in the AST
|
|
532
|
+
*
|
|
533
|
+
* @param ast - The AST containing the node
|
|
534
|
+
* @param targetNode - The node to get depth for
|
|
535
|
+
* @returns The depth (0 for root), or -1 if not found
|
|
536
|
+
*/
|
|
537
|
+
getNodeDepth(ast, targetNode) {
|
|
538
|
+
let foundDepth = -1;
|
|
539
|
+
this.traverse(ast, (node, _parent, depth) => {
|
|
540
|
+
if (node === targetNode) {
|
|
541
|
+
foundDepth = depth;
|
|
542
|
+
return false;
|
|
543
|
+
}
|
|
544
|
+
return undefined;
|
|
545
|
+
});
|
|
546
|
+
return foundDepth;
|
|
547
|
+
}
|
|
548
|
+
/**
|
|
549
|
+
* Check if a node is a leaf node (has no children)
|
|
550
|
+
*
|
|
551
|
+
* @param node - The node to check
|
|
552
|
+
* @returns true if the node has no children
|
|
553
|
+
*/
|
|
554
|
+
isLeafNode(node) {
|
|
555
|
+
return node.children.length === 0;
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* Get direct children of a specific type
|
|
559
|
+
*
|
|
560
|
+
* @param node - The parent node
|
|
561
|
+
* @param nodeType - The type of children to find
|
|
562
|
+
* @returns Array of matching child nodes
|
|
563
|
+
*/
|
|
564
|
+
getChildrenByType(node, nodeType) {
|
|
565
|
+
return node.children.filter((child) => child.type === nodeType);
|
|
566
|
+
}
|
|
567
|
+
/**
|
|
568
|
+
* Get the first direct child of a specific type
|
|
569
|
+
*
|
|
570
|
+
* @param node - The parent node
|
|
571
|
+
* @param nodeType - The type of child to find
|
|
572
|
+
* @returns The first matching child, or null if not found
|
|
573
|
+
*/
|
|
574
|
+
getFirstChildByType(node, nodeType) {
|
|
575
|
+
return node.children.find((child) => child.type === nodeType) ?? null;
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* Check if a node has a child of a specific type
|
|
579
|
+
*
|
|
580
|
+
* @param node - The parent node
|
|
581
|
+
* @param nodeType - The type to check for
|
|
582
|
+
* @returns true if a child of the specified type exists
|
|
583
|
+
*/
|
|
584
|
+
hasChildOfType(node, nodeType) {
|
|
585
|
+
return node.children.some((child) => child.type === nodeType);
|
|
586
|
+
}
|
|
587
|
+
/**
|
|
588
|
+
* Check if a node has a descendant of a specific type
|
|
589
|
+
*
|
|
590
|
+
* @param node - The starting node
|
|
591
|
+
* @param nodeType - The type to check for
|
|
592
|
+
* @returns true if a descendant of the specified type exists
|
|
593
|
+
*/
|
|
594
|
+
hasDescendantOfType(node, nodeType) {
|
|
595
|
+
const descendants = this.findDescendantsByType(node, nodeType);
|
|
596
|
+
return descendants.length > 0;
|
|
597
|
+
}
|
|
598
|
+
/**
|
|
599
|
+
* Get siblings of a node (other children of the same parent)
|
|
600
|
+
*
|
|
601
|
+
* @param ast - The AST containing the node
|
|
602
|
+
* @param node - The node to find siblings for
|
|
603
|
+
* @returns Array of sibling nodes (excluding the node itself)
|
|
604
|
+
*/
|
|
605
|
+
getSiblings(ast, node) {
|
|
606
|
+
const parent = this.getParent(ast, node);
|
|
607
|
+
if (!parent) {
|
|
608
|
+
return [];
|
|
609
|
+
}
|
|
610
|
+
return parent.children.filter((child) => child !== node);
|
|
611
|
+
}
|
|
612
|
+
/**
|
|
613
|
+
* Get the next sibling of a node
|
|
614
|
+
*
|
|
615
|
+
* @param ast - The AST containing the node
|
|
616
|
+
* @param node - The node to find the next sibling for
|
|
617
|
+
* @returns The next sibling, or null if none exists
|
|
618
|
+
*/
|
|
619
|
+
getNextSibling(ast, node) {
|
|
620
|
+
const parent = this.getParent(ast, node);
|
|
621
|
+
if (!parent) {
|
|
622
|
+
return null;
|
|
623
|
+
}
|
|
624
|
+
const index = parent.children.indexOf(node);
|
|
625
|
+
if (index === -1 || index === parent.children.length - 1) {
|
|
626
|
+
return null;
|
|
627
|
+
}
|
|
628
|
+
return parent.children[index + 1] ?? null;
|
|
629
|
+
}
|
|
630
|
+
/**
|
|
631
|
+
* Get the previous sibling of a node
|
|
632
|
+
*
|
|
633
|
+
* @param ast - The AST containing the node
|
|
634
|
+
* @param node - The node to find the previous sibling for
|
|
635
|
+
* @returns The previous sibling, or null if none exists
|
|
636
|
+
*/
|
|
637
|
+
getPreviousSibling(ast, node) {
|
|
638
|
+
const parent = this.getParent(ast, node);
|
|
639
|
+
if (!parent) {
|
|
640
|
+
return null;
|
|
641
|
+
}
|
|
642
|
+
const index = parent.children.indexOf(node);
|
|
643
|
+
if (index <= 0) {
|
|
644
|
+
return null;
|
|
645
|
+
}
|
|
646
|
+
return parent.children[index - 1] ?? null;
|
|
647
|
+
}
|
|
648
|
+
/**
|
|
649
|
+
* Count nodes of a specific type in the AST
|
|
650
|
+
*
|
|
651
|
+
* @param ast - The AST to search
|
|
652
|
+
* @param nodeType - The type of nodes to count
|
|
653
|
+
* @returns The count of matching nodes
|
|
654
|
+
*/
|
|
655
|
+
countNodes(ast, nodeType) {
|
|
656
|
+
return this.findNodes(ast, nodeType).length;
|
|
657
|
+
}
|
|
658
|
+
/**
|
|
659
|
+
* Check if the AST contains a node of a specific type
|
|
660
|
+
*
|
|
661
|
+
* @param ast - The AST to search
|
|
662
|
+
* @param nodeType - The type to check for
|
|
663
|
+
* @returns true if a node of the specified type exists
|
|
664
|
+
*/
|
|
665
|
+
hasNodeOfType(ast, nodeType) {
|
|
666
|
+
return this.findFirstNode(ast, nodeType) !== null;
|
|
667
|
+
}
|
|
668
|
+
/**
|
|
669
|
+
* Get the line number of a node (1-indexed)
|
|
670
|
+
*
|
|
671
|
+
* @param node - The node to get the line number for
|
|
672
|
+
* @returns The line number (1-indexed)
|
|
673
|
+
*/
|
|
674
|
+
getLineNumber(node) {
|
|
675
|
+
return node.startPosition.row + 1;
|
|
676
|
+
}
|
|
677
|
+
/**
|
|
678
|
+
* Get the column number of a node (1-indexed)
|
|
679
|
+
*
|
|
680
|
+
* @param node - The node to get the column number for
|
|
681
|
+
* @returns The column number (1-indexed)
|
|
682
|
+
*/
|
|
683
|
+
getColumnNumber(node) {
|
|
684
|
+
return node.startPosition.column + 1;
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
// ============================================================================
|
|
688
|
+
// Type Guards
|
|
689
|
+
// ============================================================================
|
|
690
|
+
/**
|
|
691
|
+
* Type guard to check if a detector is an AST detector
|
|
692
|
+
*
|
|
693
|
+
* @param detector - The detector to check
|
|
694
|
+
* @returns true if the detector is an ASTDetector
|
|
695
|
+
*/
|
|
696
|
+
export function isASTDetector(detector) {
|
|
697
|
+
return detector.detectionMethod === 'ast';
|
|
698
|
+
}
|
|
699
|
+
//# sourceMappingURL=ast-detector.js.map
|