@empline/preflight 1.1.11 → 1.1.13
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/checks/consolidated/auth-storage-state.d.ts +3 -0
- package/dist/checks/consolidated/auth-storage-state.d.ts.map +1 -0
- package/dist/checks/consolidated/auth-storage-state.js +146 -0
- package/dist/checks/consolidated/auth-storage-state.js.map +1 -0
- package/dist/checks/consolidated/business.d.ts +50 -0
- package/dist/checks/consolidated/business.d.ts.map +1 -0
- package/dist/checks/consolidated/business.js +252 -0
- package/dist/checks/consolidated/business.js.map +1 -0
- package/dist/checks/consolidated/caching-strategy.d.ts +104 -0
- package/dist/checks/consolidated/caching-strategy.d.ts.map +1 -0
- package/dist/checks/consolidated/caching-strategy.js +725 -0
- package/dist/checks/consolidated/caching-strategy.js.map +1 -0
- package/dist/checks/consolidated/code-quality.d.ts +83 -0
- package/dist/checks/consolidated/code-quality.d.ts.map +1 -0
- package/dist/checks/consolidated/code-quality.js +445 -0
- package/dist/checks/consolidated/code-quality.js.map +1 -0
- package/dist/checks/consolidated/console-statements.d.ts +32 -0
- package/dist/checks/consolidated/console-statements.d.ts.map +1 -0
- package/dist/checks/consolidated/console-statements.js +304 -0
- package/dist/checks/consolidated/console-statements.js.map +1 -0
- package/dist/checks/consolidated/css-advanced-validation.d.ts +24 -0
- package/dist/checks/consolidated/css-advanced-validation.d.ts.map +1 -0
- package/dist/checks/consolidated/css-advanced-validation.js +415 -0
- package/dist/checks/consolidated/css-advanced-validation.js.map +1 -0
- package/dist/checks/consolidated/css-organization.d.ts +14 -0
- package/dist/checks/consolidated/css-organization.d.ts.map +1 -0
- package/dist/checks/consolidated/css-organization.js +432 -0
- package/dist/checks/consolidated/css-organization.js.map +1 -0
- package/dist/checks/consolidated/css-runtime-validation.d.ts +22 -0
- package/dist/checks/consolidated/css-runtime-validation.d.ts.map +1 -0
- package/dist/checks/consolidated/css-runtime-validation.js +330 -0
- package/dist/checks/consolidated/css-runtime-validation.js.map +1 -0
- package/dist/checks/consolidated/css-variable-validation.d.ts +17 -0
- package/dist/checks/consolidated/css-variable-validation.d.ts.map +1 -0
- package/dist/checks/consolidated/css-variable-validation.js +412 -0
- package/dist/checks/consolidated/css-variable-validation.js.map +1 -0
- package/dist/checks/consolidated/dark-mode-consistency.d.ts +23 -0
- package/dist/checks/consolidated/dark-mode-consistency.d.ts.map +1 -0
- package/dist/checks/consolidated/dark-mode-consistency.js +291 -0
- package/dist/checks/consolidated/dark-mode-consistency.js.map +1 -0
- package/dist/checks/consolidated/database.d.ts +95 -0
- package/dist/checks/consolidated/database.d.ts.map +1 -0
- package/dist/checks/consolidated/database.js +427 -0
- package/dist/checks/consolidated/database.js.map +1 -0
- package/dist/checks/consolidated/e2e-checks.d.ts +52 -0
- package/dist/checks/consolidated/e2e-checks.d.ts.map +1 -0
- package/dist/checks/consolidated/e2e-checks.js +157 -0
- package/dist/checks/consolidated/e2e-checks.js.map +1 -0
- package/dist/checks/consolidated/e2e-regression-coverage.d.ts +14 -0
- package/dist/checks/consolidated/e2e-regression-coverage.d.ts.map +1 -0
- package/dist/checks/consolidated/e2e-regression-coverage.js +151 -0
- package/dist/checks/consolidated/e2e-regression-coverage.js.map +1 -0
- package/dist/checks/consolidated/e2e-validation.d.ts +137 -0
- package/dist/checks/consolidated/e2e-validation.d.ts.map +1 -0
- package/dist/checks/consolidated/e2e-validation.js +1001 -0
- package/dist/checks/consolidated/e2e-validation.js.map +1 -0
- package/dist/checks/consolidated/enterprise-baseline.d.ts +9 -0
- package/dist/checks/consolidated/enterprise-baseline.d.ts.map +1 -0
- package/dist/checks/consolidated/enterprise-baseline.js +277 -0
- package/dist/checks/consolidated/enterprise-baseline.js.map +1 -0
- package/dist/checks/consolidated/generate-pageload-config.d.ts +6 -0
- package/dist/checks/consolidated/generate-pageload-config.d.ts.map +1 -0
- package/dist/checks/consolidated/generate-pageload-config.js +161 -0
- package/dist/checks/consolidated/generate-pageload-config.js.map +1 -0
- package/dist/checks/consolidated/hardened-checks.d.ts +276 -0
- package/dist/checks/consolidated/hardened-checks.d.ts.map +1 -0
- package/dist/checks/consolidated/hardened-checks.js +3056 -0
- package/dist/checks/consolidated/hardened-checks.js.map +1 -0
- package/dist/checks/consolidated/homepage-ux.d.ts +12 -0
- package/dist/checks/consolidated/homepage-ux.d.ts.map +1 -0
- package/dist/checks/consolidated/homepage-ux.js +242 -0
- package/dist/checks/consolidated/homepage-ux.js.map +1 -0
- package/dist/checks/consolidated/images.d.ts +76 -0
- package/dist/checks/consolidated/images.d.ts.map +1 -0
- package/dist/checks/consolidated/images.js +311 -0
- package/dist/checks/consolidated/images.js.map +1 -0
- package/dist/checks/consolidated/import-cycles.d.ts +63 -0
- package/dist/checks/consolidated/import-cycles.d.ts.map +1 -0
- package/dist/checks/consolidated/import-cycles.js +291 -0
- package/dist/checks/consolidated/import-cycles.js.map +1 -0
- package/dist/checks/consolidated/imports.d.ts +112 -0
- package/dist/checks/consolidated/imports.d.ts.map +1 -0
- package/dist/checks/consolidated/imports.js +977 -0
- package/dist/checks/consolidated/imports.js.map +1 -0
- package/dist/checks/consolidated/inline-style-conflicts.d.ts +21 -0
- package/dist/checks/consolidated/inline-style-conflicts.d.ts.map +1 -0
- package/dist/checks/consolidated/inline-style-conflicts.js +300 -0
- package/dist/checks/consolidated/inline-style-conflicts.js.map +1 -0
- package/dist/checks/consolidated/lib-organization.d.ts +12 -0
- package/dist/checks/consolidated/lib-organization.d.ts.map +1 -0
- package/dist/checks/consolidated/lib-organization.js +419 -0
- package/dist/checks/consolidated/lib-organization.js.map +1 -0
- package/dist/checks/consolidated/n-plus-one.d.ts +63 -0
- package/dist/checks/consolidated/n-plus-one.d.ts.map +1 -0
- package/dist/checks/consolidated/n-plus-one.js +331 -0
- package/dist/checks/consolidated/n-plus-one.js.map +1 -0
- package/dist/checks/consolidated/nextjs.d.ts +51 -0
- package/dist/checks/consolidated/nextjs.d.ts.map +1 -0
- package/dist/checks/consolidated/nextjs.js +205 -0
- package/dist/checks/consolidated/nextjs.js.map +1 -0
- package/dist/checks/consolidated/organization.d.ts +54 -0
- package/dist/checks/consolidated/organization.d.ts.map +1 -0
- package/dist/checks/consolidated/organization.js +158 -0
- package/dist/checks/consolidated/organization.js.map +1 -0
- package/dist/checks/consolidated/pageload.d.ts +12 -0
- package/dist/checks/consolidated/pageload.d.ts.map +1 -0
- package/dist/checks/consolidated/pageload.js +138 -0
- package/dist/checks/consolidated/pageload.js.map +1 -0
- package/dist/checks/consolidated/performance.d.ts +112 -0
- package/dist/checks/consolidated/performance.d.ts.map +1 -0
- package/dist/checks/consolidated/performance.js +1546 -0
- package/dist/checks/consolidated/performance.js.map +1 -0
- package/dist/checks/consolidated/quality.d.ts +52 -0
- package/dist/checks/consolidated/quality.d.ts.map +1 -0
- package/dist/checks/consolidated/quality.js +253 -0
- package/dist/checks/consolidated/quality.js.map +1 -0
- package/dist/checks/consolidated/react.d.ts +48 -0
- package/dist/checks/consolidated/react.d.ts.map +1 -0
- package/dist/checks/consolidated/react.js +203 -0
- package/dist/checks/consolidated/react.js.map +1 -0
- package/dist/checks/consolidated/regression-hygiene.d.ts +17 -0
- package/dist/checks/consolidated/regression-hygiene.d.ts.map +1 -0
- package/dist/checks/consolidated/regression-hygiene.js +242 -0
- package/dist/checks/consolidated/regression-hygiene.js.map +1 -0
- package/dist/checks/consolidated/regression.d.ts +20 -0
- package/dist/checks/consolidated/regression.d.ts.map +1 -0
- package/dist/checks/consolidated/regression.js +121 -0
- package/dist/checks/consolidated/regression.js.map +1 -0
- package/dist/checks/consolidated/runtime.d.ts +53 -0
- package/dist/checks/consolidated/runtime.d.ts.map +1 -0
- package/dist/checks/consolidated/runtime.js +160 -0
- package/dist/checks/consolidated/runtime.js.map +1 -0
- package/dist/checks/consolidated/script-performance.d.ts +17 -0
- package/dist/checks/consolidated/script-performance.d.ts.map +1 -0
- package/dist/checks/consolidated/script-performance.js +137 -0
- package/dist/checks/consolidated/script-performance.js.map +1 -0
- package/dist/checks/consolidated/security.d.ts +78 -0
- package/dist/checks/consolidated/security.d.ts.map +1 -0
- package/dist/checks/consolidated/security.js +404 -0
- package/dist/checks/consolidated/security.js.map +1 -0
- package/dist/checks/consolidated/seo.d.ts +31 -0
- package/dist/checks/consolidated/seo.d.ts.map +1 -0
- package/dist/checks/consolidated/seo.js +1438 -0
- package/dist/checks/consolidated/seo.js.map +1 -0
- package/dist/checks/consolidated/sx-prop-deprecation.d.ts +22 -0
- package/dist/checks/consolidated/sx-prop-deprecation.d.ts.map +1 -0
- package/dist/checks/consolidated/sx-prop-deprecation.js +280 -0
- package/dist/checks/consolidated/sx-prop-deprecation.js.map +1 -0
- package/dist/checks/consolidated/tailwind-class-validation.d.ts +25 -0
- package/dist/checks/consolidated/tailwind-class-validation.d.ts.map +1 -0
- package/dist/checks/consolidated/tailwind-class-validation.js +533 -0
- package/dist/checks/consolidated/tailwind-class-validation.js.map +1 -0
- package/dist/checks/consolidated/testing.d.ts +54 -0
- package/dist/checks/consolidated/testing.d.ts.map +1 -0
- package/dist/checks/consolidated/testing.js +163 -0
- package/dist/checks/consolidated/testing.js.map +1 -0
- package/dist/checks/consolidated/typescript.d.ts +3 -0
- package/dist/checks/consolidated/typescript.d.ts.map +1 -0
- package/dist/checks/consolidated/typescript.js +31 -0
- package/dist/checks/consolidated/typescript.js.map +1 -0
- package/dist/checks/consolidated/ui-accessibility-advanced.d.ts +104 -0
- package/dist/checks/consolidated/ui-accessibility-advanced.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-accessibility-advanced.js +689 -0
- package/dist/checks/consolidated/ui-accessibility-advanced.js.map +1 -0
- package/dist/checks/consolidated/ui-accessibility.d.ts +121 -0
- package/dist/checks/consolidated/ui-accessibility.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-accessibility.js +776 -0
- package/dist/checks/consolidated/ui-accessibility.js.map +1 -0
- package/dist/checks/consolidated/ui-advanced-spacing.d.ts +142 -0
- package/dist/checks/consolidated/ui-advanced-spacing.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-advanced-spacing.js +1220 -0
- package/dist/checks/consolidated/ui-advanced-spacing.js.map +1 -0
- package/dist/checks/consolidated/ui-animation-duration.d.ts +108 -0
- package/dist/checks/consolidated/ui-animation-duration.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-animation-duration.js +531 -0
- package/dist/checks/consolidated/ui-animation-duration.js.map +1 -0
- package/dist/checks/consolidated/ui-border-radius.d.ts +90 -0
- package/dist/checks/consolidated/ui-border-radius.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-border-radius.js +519 -0
- package/dist/checks/consolidated/ui-border-radius.js.map +1 -0
- package/dist/checks/consolidated/ui-buttons.d.ts +32 -0
- package/dist/checks/consolidated/ui-buttons.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-buttons.js +481 -0
- package/dist/checks/consolidated/ui-buttons.js.map +1 -0
- package/dist/checks/consolidated/ui-cards.d.ts +29 -0
- package/dist/checks/consolidated/ui-cards.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-cards.js +504 -0
- package/dist/checks/consolidated/ui-cards.js.map +1 -0
- package/dist/checks/consolidated/ui-checks.d.ts +48 -0
- package/dist/checks/consolidated/ui-checks.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-checks.js +264 -0
- package/dist/checks/consolidated/ui-checks.js.map +1 -0
- package/dist/checks/consolidated/ui-cleanup.d.ts +81 -0
- package/dist/checks/consolidated/ui-cleanup.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-cleanup.js +650 -0
- package/dist/checks/consolidated/ui-cleanup.js.map +1 -0
- package/dist/checks/consolidated/ui-components.d.ts +255 -0
- package/dist/checks/consolidated/ui-components.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-components.js +2008 -0
- package/dist/checks/consolidated/ui-components.js.map +1 -0
- package/dist/checks/consolidated/ui-consistency-advanced.d.ts +130 -0
- package/dist/checks/consolidated/ui-consistency-advanced.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-consistency-advanced.js +982 -0
- package/dist/checks/consolidated/ui-consistency-advanced.js.map +1 -0
- package/dist/checks/consolidated/ui-consistency-comprehensive.d.ts +30 -0
- package/dist/checks/consolidated/ui-consistency-comprehensive.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-consistency-comprehensive.js +1018 -0
- package/dist/checks/consolidated/ui-consistency-comprehensive.js.map +1 -0
- package/dist/checks/consolidated/ui-consistency-extended.d.ts +26 -0
- package/dist/checks/consolidated/ui-consistency-extended.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-consistency-extended.js +606 -0
- package/dist/checks/consolidated/ui-consistency-extended.js.map +1 -0
- package/dist/checks/consolidated/ui-data-display.d.ts +103 -0
- package/dist/checks/consolidated/ui-data-display.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-data-display.js +740 -0
- package/dist/checks/consolidated/ui-data-display.js.map +1 -0
- package/dist/checks/consolidated/ui-deprecated.d.ts +22 -0
- package/dist/checks/consolidated/ui-deprecated.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-deprecated.js +336 -0
- package/dist/checks/consolidated/ui-deprecated.js.map +1 -0
- package/dist/checks/consolidated/ui-empty-null-states.d.ts +90 -0
- package/dist/checks/consolidated/ui-empty-null-states.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-empty-null-states.js +511 -0
- package/dist/checks/consolidated/ui-empty-null-states.js.map +1 -0
- package/dist/checks/consolidated/ui-error-states.d.ts +99 -0
- package/dist/checks/consolidated/ui-error-states.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-error-states.js +694 -0
- package/dist/checks/consolidated/ui-error-states.js.map +1 -0
- package/dist/checks/consolidated/ui-feedback-confirmations.d.ts +90 -0
- package/dist/checks/consolidated/ui-feedback-confirmations.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-feedback-confirmations.js +596 -0
- package/dist/checks/consolidated/ui-feedback-confirmations.js.map +1 -0
- package/dist/checks/consolidated/ui-forms.d.ts +32 -0
- package/dist/checks/consolidated/ui-forms.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-forms.js +568 -0
- package/dist/checks/consolidated/ui-forms.js.map +1 -0
- package/dist/checks/consolidated/ui-gradient-shadow.d.ts +90 -0
- package/dist/checks/consolidated/ui-gradient-shadow.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-gradient-shadow.js +568 -0
- package/dist/checks/consolidated/ui-gradient-shadow.js.map +1 -0
- package/dist/checks/consolidated/ui-grid-responsive.d.ts +27 -0
- package/dist/checks/consolidated/ui-grid-responsive.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-grid-responsive.js +441 -0
- package/dist/checks/consolidated/ui-grid-responsive.js.map +1 -0
- package/dist/checks/consolidated/ui-icon-size-tokens.d.ts +104 -0
- package/dist/checks/consolidated/ui-icon-size-tokens.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-icon-size-tokens.js +514 -0
- package/dist/checks/consolidated/ui-icon-size-tokens.js.map +1 -0
- package/dist/checks/consolidated/ui-iconography.d.ts +90 -0
- package/dist/checks/consolidated/ui-iconography.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-iconography.js +565 -0
- package/dist/checks/consolidated/ui-iconography.js.map +1 -0
- package/dist/checks/consolidated/ui-interactive-states.d.ts +240 -0
- package/dist/checks/consolidated/ui-interactive-states.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-interactive-states.js +2474 -0
- package/dist/checks/consolidated/ui-interactive-states.js.map +1 -0
- package/dist/checks/consolidated/ui-layout.d.ts +256 -0
- package/dist/checks/consolidated/ui-layout.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-layout.js +1371 -0
- package/dist/checks/consolidated/ui-layout.js.map +1 -0
- package/dist/checks/consolidated/ui-loading-skeletons.d.ts +11 -0
- package/dist/checks/consolidated/ui-loading-skeletons.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-loading-skeletons.js +145 -0
- package/dist/checks/consolidated/ui-loading-skeletons.js.map +1 -0
- package/dist/checks/consolidated/ui-loading-state-skeletons.d.ts +9 -0
- package/dist/checks/consolidated/ui-loading-state-skeletons.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-loading-state-skeletons.js +125 -0
- package/dist/checks/consolidated/ui-loading-state-skeletons.js.map +1 -0
- package/dist/checks/consolidated/ui-media.d.ts +74 -0
- package/dist/checks/consolidated/ui-media.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-media.js +408 -0
- package/dist/checks/consolidated/ui-media.js.map +1 -0
- package/dist/checks/consolidated/ui-micro-interactions.d.ts +107 -0
- package/dist/checks/consolidated/ui-micro-interactions.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-micro-interactions.js +825 -0
- package/dist/checks/consolidated/ui-micro-interactions.js.map +1 -0
- package/dist/checks/consolidated/ui-microcopy-consistency.d.ts +114 -0
- package/dist/checks/consolidated/ui-microcopy-consistency.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-microcopy-consistency.js +566 -0
- package/dist/checks/consolidated/ui-microcopy-consistency.js.map +1 -0
- package/dist/checks/consolidated/ui-mobile-ux.d.ts +251 -0
- package/dist/checks/consolidated/ui-mobile-ux.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-mobile-ux.js +2212 -0
- package/dist/checks/consolidated/ui-mobile-ux.js.map +1 -0
- package/dist/checks/consolidated/ui-motion-accessibility.d.ts +93 -0
- package/dist/checks/consolidated/ui-motion-accessibility.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-motion-accessibility.js +450 -0
- package/dist/checks/consolidated/ui-motion-accessibility.js.map +1 -0
- package/dist/checks/consolidated/ui-navigation.d.ts +85 -0
- package/dist/checks/consolidated/ui-navigation.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-navigation.js +673 -0
- package/dist/checks/consolidated/ui-navigation.js.map +1 -0
- package/dist/checks/consolidated/ui-patterns.d.ts +174 -0
- package/dist/checks/consolidated/ui-patterns.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-patterns.js +1532 -0
- package/dist/checks/consolidated/ui-patterns.js.map +1 -0
- package/dist/checks/consolidated/ui-responsive.d.ts +89 -0
- package/dist/checks/consolidated/ui-responsive.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-responsive.js +588 -0
- package/dist/checks/consolidated/ui-responsive.js.map +1 -0
- package/dist/checks/consolidated/ui-spacing-standards.d.ts +43 -0
- package/dist/checks/consolidated/ui-spacing-standards.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-spacing-standards.js +874 -0
- package/dist/checks/consolidated/ui-spacing-standards.js.map +1 -0
- package/dist/checks/consolidated/ui-spacing.d.ts +751 -0
- package/dist/checks/consolidated/ui-spacing.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-spacing.js +4996 -0
- package/dist/checks/consolidated/ui-spacing.js.map +1 -0
- package/dist/checks/consolidated/ui-standards-auto-fixer.d.ts +70 -0
- package/dist/checks/consolidated/ui-standards-auto-fixer.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-standards-auto-fixer.js +429 -0
- package/dist/checks/consolidated/ui-standards-auto-fixer.js.map +1 -0
- package/dist/checks/consolidated/ui-standards-enforcement.d.ts +100 -0
- package/dist/checks/consolidated/ui-standards-enforcement.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-standards-enforcement.js +935 -0
- package/dist/checks/consolidated/ui-standards-enforcement.js.map +1 -0
- package/dist/checks/consolidated/ui-state-consistency.d.ts +90 -0
- package/dist/checks/consolidated/ui-state-consistency.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-state-consistency.js +659 -0
- package/dist/checks/consolidated/ui-state-consistency.js.map +1 -0
- package/dist/checks/consolidated/ui-style-validation.d.ts +74 -0
- package/dist/checks/consolidated/ui-style-validation.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-style-validation.js +403 -0
- package/dist/checks/consolidated/ui-style-validation.js.map +1 -0
- package/dist/checks/consolidated/ui-tokens.d.ts +110 -0
- package/dist/checks/consolidated/ui-tokens.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-tokens.js +990 -0
- package/dist/checks/consolidated/ui-tokens.js.map +1 -0
- package/dist/checks/consolidated/ui-typography.d.ts +77 -0
- package/dist/checks/consolidated/ui-typography.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-typography.js +416 -0
- package/dist/checks/consolidated/ui-typography.js.map +1 -0
- package/dist/checks/consolidated/ui-visual-hierarchy.d.ts +90 -0
- package/dist/checks/consolidated/ui-visual-hierarchy.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-visual-hierarchy.js +562 -0
- package/dist/checks/consolidated/ui-visual-hierarchy.js.map +1 -0
- package/dist/checks/consolidated/woocommerce.d.ts +50 -0
- package/dist/checks/consolidated/woocommerce.d.ts.map +1 -0
- package/dist/checks/consolidated/woocommerce.js +198 -0
- package/dist/checks/consolidated/woocommerce.js.map +1 -0
- package/dist/checks/core/api-route-protection.d.ts +2 -0
- package/dist/checks/core/api-route-protection.d.ts.map +1 -0
- package/dist/checks/core/api-route-protection.js +101 -0
- package/dist/checks/core/api-route-protection.js.map +1 -0
- package/dist/checks/core/critical.d.ts +8 -0
- package/dist/checks/core/critical.d.ts.map +1 -0
- package/dist/checks/core/critical.js +200 -0
- package/dist/checks/core/critical.js.map +1 -0
- package/dist/checks/core/database.d.ts +8 -0
- package/dist/checks/core/database.d.ts.map +1 -0
- package/dist/checks/core/database.js +699 -0
- package/dist/checks/core/database.js.map +1 -0
- package/dist/checks/core/development.d.ts +8 -0
- package/dist/checks/core/development.d.ts.map +1 -0
- package/dist/checks/core/development.js +417 -0
- package/dist/checks/core/development.js.map +1 -0
- package/dist/checks/core/hydration-mismatch-check.d.ts +38 -0
- package/dist/checks/core/hydration-mismatch-check.d.ts.map +1 -0
- package/dist/checks/core/hydration-mismatch-check.js +411 -0
- package/dist/checks/core/hydration-mismatch-check.js.map +1 -0
- package/dist/checks/core/performance.d.ts +8 -0
- package/dist/checks/core/performance.d.ts.map +1 -0
- package/dist/checks/core/performance.js +474 -0
- package/dist/checks/core/performance.js.map +1 -0
- package/dist/checks/core/security.d.ts +8 -0
- package/dist/checks/core/security.d.ts.map +1 -0
- package/dist/checks/core/security.js +275 -0
- package/dist/checks/core/security.js.map +1 -0
- package/dist/checks/core/standardized-error-handling.d.ts +43 -0
- package/dist/checks/core/standardized-error-handling.d.ts.map +1 -0
- package/dist/checks/core/standardized-error-handling.js +384 -0
- package/dist/checks/core/standardized-error-handling.js.map +1 -0
- package/dist/checks/core/supercatch.d.ts +8 -0
- package/dist/checks/core/supercatch.d.ts.map +1 -0
- package/dist/checks/core/supercatch.js +750 -0
- package/dist/checks/core/supercatch.js.map +1 -0
- package/dist/checks/core/suppression-check.d.ts +2 -0
- package/dist/checks/core/suppression-check.d.ts.map +1 -0
- package/dist/checks/core/suppression-check.js +129 -0
- package/dist/checks/core/suppression-check.js.map +1 -0
- package/dist/checks/core/ui-quality.d.ts +8 -0
- package/dist/checks/core/ui-quality.d.ts.map +1 -0
- package/dist/checks/core/ui-quality.js +1736 -0
- package/dist/checks/core/ui-quality.js.map +1 -0
- package/dist/checks/core/unused-assets-check.d.ts +2 -0
- package/dist/checks/core/unused-assets-check.d.ts.map +1 -0
- package/dist/checks/core/unused-assets-check.js +112 -0
- package/dist/checks/core/unused-assets-check.js.map +1 -0
- package/dist/checks/core/use-status-ssr-safety.d.ts +34 -0
- package/dist/checks/core/use-status-ssr-safety.d.ts.map +1 -0
- package/dist/checks/core/use-status-ssr-safety.js +283 -0
- package/dist/checks/core/use-status-ssr-safety.js.map +1 -0
- package/dist/checks/email/email-flow-validation.d.ts +23 -0
- package/dist/checks/email/email-flow-validation.d.ts.map +1 -0
- package/dist/checks/email/email-flow-validation.js +468 -0
- package/dist/checks/email/email-flow-validation.js.map +1 -0
- package/dist/checks/email/email-template-db-verification.d.ts +20 -0
- package/dist/checks/email/email-template-db-verification.d.ts.map +1 -0
- package/dist/checks/email/email-template-db-verification.js +46 -0
- package/dist/checks/email/email-template-db-verification.js.map +1 -0
- package/dist/checks/email/email-template-validation.d.ts +24 -0
- package/dist/checks/email/email-template-validation.d.ts.map +1 -0
- package/dist/checks/email/email-template-validation.js +688 -0
- package/dist/checks/email/email-template-validation.js.map +1 -0
- package/dist/checks/jsx/comment-placement.d.ts +45 -0
- package/dist/checks/jsx/comment-placement.d.ts.map +1 -0
- package/dist/checks/jsx/comment-placement.js +316 -0
- package/dist/checks/jsx/comment-placement.js.map +1 -0
- package/dist/checks/specialized/admin-layout-check.d.ts +19 -0
- package/dist/checks/specialized/admin-layout-check.d.ts.map +1 -0
- package/dist/checks/specialized/admin-layout-check.js +166 -0
- package/dist/checks/specialized/admin-layout-check.js.map +1 -0
- package/dist/checks/specialized/client-server-separation.d.ts +14 -0
- package/dist/checks/specialized/client-server-separation.d.ts.map +1 -0
- package/dist/checks/specialized/client-server-separation.js +197 -0
- package/dist/checks/specialized/client-server-separation.js.map +1 -0
- package/dist/checks/specialized/cost-optimization.d.ts +18 -0
- package/dist/checks/specialized/cost-optimization.d.ts.map +1 -0
- package/dist/checks/specialized/cost-optimization.js +78 -0
- package/dist/checks/specialized/cost-optimization.js.map +1 -0
- package/dist/checks/specialized/database-migration-sync.d.ts +21 -0
- package/dist/checks/specialized/database-migration-sync.d.ts.map +1 -0
- package/dist/checks/specialized/database-migration-sync.js +150 -0
- package/dist/checks/specialized/database-migration-sync.js.map +1 -0
- package/dist/checks/specialized/database-model-validation.d.ts +15 -0
- package/dist/checks/specialized/database-model-validation.d.ts.map +1 -0
- package/dist/checks/specialized/database-model-validation.js +35 -0
- package/dist/checks/specialized/database-model-validation.js.map +1 -0
- package/dist/checks/specialized/database-schema-migrations-diff.d.ts +27 -0
- package/dist/checks/specialized/database-schema-migrations-diff.d.ts.map +1 -0
- package/dist/checks/specialized/database-schema-migrations-diff.js +177 -0
- package/dist/checks/specialized/database-schema-migrations-diff.js.map +1 -0
- package/dist/checks/specialized/database-schema-sync.d.ts +23 -0
- package/dist/checks/specialized/database-schema-sync.d.ts.map +1 -0
- package/dist/checks/specialized/database-schema-sync.js +77 -0
- package/dist/checks/specialized/database-schema-sync.js.map +1 -0
- package/dist/checks/specialized/decimal-serialization.d.ts +24 -0
- package/dist/checks/specialized/decimal-serialization.d.ts.map +1 -0
- package/dist/checks/specialized/decimal-serialization.js +400 -0
- package/dist/checks/specialized/decimal-serialization.js.map +1 -0
- package/dist/checks/specialized/detect-router-issues.d.ts +14 -0
- package/dist/checks/specialized/detect-router-issues.d.ts.map +1 -0
- package/dist/checks/specialized/detect-router-issues.js +96 -0
- package/dist/checks/specialized/detect-router-issues.js.map +1 -0
- package/dist/checks/specialized/enum-validation.d.ts +15 -0
- package/dist/checks/specialized/enum-validation.d.ts.map +1 -0
- package/dist/checks/specialized/enum-validation.js +35 -0
- package/dist/checks/specialized/enum-validation.js.map +1 -0
- package/dist/checks/specialized/hash-collision.d.ts +18 -0
- package/dist/checks/specialized/hash-collision.d.ts.map +1 -0
- package/dist/checks/specialized/hash-collision.js +78 -0
- package/dist/checks/specialized/hash-collision.js.map +1 -0
- package/dist/checks/specialized/id-generation-enforcement.d.ts +16 -0
- package/dist/checks/specialized/id-generation-enforcement.d.ts.map +1 -0
- package/dist/checks/specialized/id-generation-enforcement.js +307 -0
- package/dist/checks/specialized/id-generation-enforcement.js.map +1 -0
- package/dist/checks/specialized/image-data-integrity.d.ts +15 -0
- package/dist/checks/specialized/image-data-integrity.d.ts.map +1 -0
- package/dist/checks/specialized/image-data-integrity.js +79 -0
- package/dist/checks/specialized/image-data-integrity.js.map +1 -0
- package/dist/checks/specialized/image-health.d.ts +14 -0
- package/dist/checks/specialized/image-health.d.ts.map +1 -0
- package/dist/checks/specialized/image-health.js +122 -0
- package/dist/checks/specialized/image-health.js.map +1 -0
- package/dist/checks/specialized/image-metadata-validation.d.ts +14 -0
- package/dist/checks/specialized/image-metadata-validation.d.ts.map +1 -0
- package/dist/checks/specialized/image-metadata-validation.js +95 -0
- package/dist/checks/specialized/image-metadata-validation.js.map +1 -0
- package/dist/checks/specialized/image-optimization.d.ts +16 -0
- package/dist/checks/specialized/image-optimization.d.ts.map +1 -0
- package/dist/checks/specialized/image-optimization.js +86 -0
- package/dist/checks/specialized/image-optimization.js.map +1 -0
- package/dist/checks/specialized/invalid-module-imports.d.ts +24 -0
- package/dist/checks/specialized/invalid-module-imports.d.ts.map +1 -0
- package/dist/checks/specialized/invalid-module-imports.js +209 -0
- package/dist/checks/specialized/invalid-module-imports.js.map +1 -0
- package/dist/checks/specialized/lint-validation.d.ts +26 -0
- package/dist/checks/specialized/lint-validation.d.ts.map +1 -0
- package/dist/checks/specialized/lint-validation.js +193 -0
- package/dist/checks/specialized/lint-validation.js.map +1 -0
- package/dist/checks/specialized/listing-workflow.d.ts +19 -0
- package/dist/checks/specialized/listing-workflow.d.ts.map +1 -0
- package/dist/checks/specialized/listing-workflow.js +89 -0
- package/dist/checks/specialized/listing-workflow.js.map +1 -0
- package/dist/checks/specialized/mui-imports-validation.d.ts +18 -0
- package/dist/checks/specialized/mui-imports-validation.d.ts.map +1 -0
- package/dist/checks/specialized/mui-imports-validation.js +134 -0
- package/dist/checks/specialized/mui-imports-validation.js.map +1 -0
- package/dist/checks/specialized/nextauth-v5-compliance.d.ts +16 -0
- package/dist/checks/specialized/nextauth-v5-compliance.d.ts.map +1 -0
- package/dist/checks/specialized/nextauth-v5-compliance.js +164 -0
- package/dist/checks/specialized/nextauth-v5-compliance.js.map +1 -0
- package/dist/checks/specialized/nextjs-params-check.d.ts +14 -0
- package/dist/checks/specialized/nextjs-params-check.d.ts.map +1 -0
- package/dist/checks/specialized/nextjs-params-check.js +140 -0
- package/dist/checks/specialized/nextjs-params-check.js.map +1 -0
- package/dist/checks/specialized/no-legacy-catalog-aliases-validation.d.ts +16 -0
- package/dist/checks/specialized/no-legacy-catalog-aliases-validation.d.ts.map +1 -0
- package/dist/checks/specialized/no-legacy-catalog-aliases-validation.js +36 -0
- package/dist/checks/specialized/no-legacy-catalog-aliases-validation.js.map +1 -0
- package/dist/checks/specialized/no-wata-cardgraded-validation.d.ts +22 -0
- package/dist/checks/specialized/no-wata-cardgraded-validation.d.ts.map +1 -0
- package/dist/checks/specialized/no-wata-cardgraded-validation.js +97 -0
- package/dist/checks/specialized/no-wata-cardgraded-validation.js.map +1 -0
- package/dist/checks/specialized/parameter-consistency-check.d.ts +20 -0
- package/dist/checks/specialized/parameter-consistency-check.d.ts.map +1 -0
- package/dist/checks/specialized/parameter-consistency-check.js +115 -0
- package/dist/checks/specialized/parameter-consistency-check.js.map +1 -0
- package/dist/checks/specialized/prisma-field-names-validation.d.ts +15 -0
- package/dist/checks/specialized/prisma-field-names-validation.d.ts.map +1 -0
- package/dist/checks/specialized/prisma-field-names-validation.js +35 -0
- package/dist/checks/specialized/prisma-field-names-validation.js.map +1 -0
- package/dist/checks/specialized/prisma-null-syntax.d.ts +34 -0
- package/dist/checks/specialized/prisma-null-syntax.d.ts.map +1 -0
- package/dist/checks/specialized/prisma-null-syntax.js +330 -0
- package/dist/checks/specialized/prisma-null-syntax.js.map +1 -0
- package/dist/checks/specialized/prisma-query-validation.d.ts +15 -0
- package/dist/checks/specialized/prisma-query-validation.d.ts.map +1 -0
- package/dist/checks/specialized/prisma-query-validation.js +35 -0
- package/dist/checks/specialized/prisma-query-validation.js.map +1 -0
- package/dist/checks/specialized/product-type-validation.d.ts +17 -0
- package/dist/checks/specialized/product-type-validation.d.ts.map +1 -0
- package/dist/checks/specialized/product-type-validation.js +129 -0
- package/dist/checks/specialized/product-type-validation.js.map +1 -0
- package/dist/checks/specialized/responsive-image-validation.d.ts +14 -0
- package/dist/checks/specialized/responsive-image-validation.d.ts.map +1 -0
- package/dist/checks/specialized/responsive-image-validation.js +101 -0
- package/dist/checks/specialized/responsive-image-validation.js.map +1 -0
- package/dist/checks/specialized/root-cleanliness.d.ts +21 -0
- package/dist/checks/specialized/root-cleanliness.d.ts.map +1 -0
- package/dist/checks/specialized/root-cleanliness.js +251 -0
- package/dist/checks/specialized/root-cleanliness.js.map +1 -0
- package/dist/checks/specialized/rotation-detection-validation.d.ts +16 -0
- package/dist/checks/specialized/rotation-detection-validation.d.ts.map +1 -0
- package/dist/checks/specialized/rotation-detection-validation.js +113 -0
- package/dist/checks/specialized/rotation-detection-validation.js.map +1 -0
- package/dist/checks/specialized/script-organization.d.ts +17 -0
- package/dist/checks/specialized/script-organization.d.ts.map +1 -0
- package/dist/checks/specialized/script-organization.js +487 -0
- package/dist/checks/specialized/script-organization.js.map +1 -0
- package/dist/checks/specialized/shared-components-migration.d.ts +137 -0
- package/dist/checks/specialized/shared-components-migration.d.ts.map +1 -0
- package/dist/checks/specialized/shared-components-migration.js +1288 -0
- package/dist/checks/specialized/shared-components-migration.js.map +1 -0
- package/dist/checks/specialized/store-specialties-normalization.d.ts +10 -0
- package/dist/checks/specialized/store-specialties-normalization.d.ts.map +1 -0
- package/dist/checks/specialized/store-specialties-normalization.js +126 -0
- package/dist/checks/specialized/store-specialties-normalization.js.map +1 -0
- package/dist/checks/specialized/two-stage-trim-validation.d.ts +16 -0
- package/dist/checks/specialized/two-stage-trim-validation.d.ts.map +1 -0
- package/dist/checks/specialized/two-stage-trim-validation.js +115 -0
- package/dist/checks/specialized/two-stage-trim-validation.js.map +1 -0
- package/dist/checks/specialized/underscore-variable-audit.d.ts +26 -0
- package/dist/checks/specialized/underscore-variable-audit.d.ts.map +1 -0
- package/dist/checks/specialized/underscore-variable-audit.js +219 -0
- package/dist/checks/specialized/underscore-variable-audit.js.map +1 -0
- package/dist/checks/specialized/unified-badge-consistency.d.ts +16 -0
- package/dist/checks/specialized/unified-badge-consistency.d.ts.map +1 -0
- package/dist/checks/specialized/unified-badge-consistency.js +284 -0
- package/dist/checks/specialized/unified-badge-consistency.js.map +1 -0
- package/dist/checks/specialized/validate-integration-enums.d.ts +15 -0
- package/dist/checks/specialized/validate-integration-enums.d.ts.map +1 -0
- package/dist/checks/specialized/validate-integration-enums.js +131 -0
- package/dist/checks/specialized/validate-integration-enums.js.map +1 -0
- package/dist/checks/testing/action-regression.d.ts +23 -0
- package/dist/checks/testing/action-regression.d.ts.map +1 -0
- package/dist/checks/testing/action-regression.js +192 -0
- package/dist/checks/testing/action-regression.js.map +1 -0
- package/dist/checks/testing/critical-api-coverage.d.ts +21 -0
- package/dist/checks/testing/critical-api-coverage.d.ts.map +1 -0
- package/dist/checks/testing/critical-api-coverage.js +158 -0
- package/dist/checks/testing/critical-api-coverage.js.map +1 -0
- package/dist/checks/testing/data-entry-regression-required.d.ts +24 -0
- package/dist/checks/testing/data-entry-regression-required.d.ts.map +1 -0
- package/dist/checks/testing/data-entry-regression-required.js +378 -0
- package/dist/checks/testing/data-entry-regression-required.js.map +1 -0
- package/dist/checks/testing/e2e-best-practices.d.ts +24 -0
- package/dist/checks/testing/e2e-best-practices.d.ts.map +1 -0
- package/dist/checks/testing/e2e-best-practices.js +791 -0
- package/dist/checks/testing/e2e-best-practices.js.map +1 -0
- package/dist/checks/testing/e2e-flake-patterns.d.ts +26 -0
- package/dist/checks/testing/e2e-flake-patterns.d.ts.map +1 -0
- package/dist/checks/testing/e2e-flake-patterns.js +305 -0
- package/dist/checks/testing/e2e-flake-patterns.js.map +1 -0
- package/dist/checks/testing/e2e-redundant-visibility-checks.d.ts +25 -0
- package/dist/checks/testing/e2e-redundant-visibility-checks.d.ts.map +1 -0
- package/dist/checks/testing/e2e-redundant-visibility-checks.js +613 -0
- package/dist/checks/testing/e2e-redundant-visibility-checks.js.map +1 -0
- package/dist/checks/testing/e2e-slow-tests.d.ts +9 -0
- package/dist/checks/testing/e2e-slow-tests.d.ts.map +1 -0
- package/dist/checks/testing/e2e-slow-tests.js +142 -0
- package/dist/checks/testing/e2e-slow-tests.js.map +1 -0
- package/dist/checks/testing/e2e-timeouts.d.ts +9 -0
- package/dist/checks/testing/e2e-timeouts.d.ts.map +1 -0
- package/dist/checks/testing/e2e-timeouts.js +82 -0
- package/dist/checks/testing/e2e-timeouts.js.map +1 -0
- package/dist/checks/testing/integration-e2e-depth.d.ts +20 -0
- package/dist/checks/testing/integration-e2e-depth.d.ts.map +1 -0
- package/dist/checks/testing/integration-e2e-depth.js +575 -0
- package/dist/checks/testing/integration-e2e-depth.js.map +1 -0
- package/dist/checks/testing/playwright-feature-coverage-gaps.d.ts +31 -0
- package/dist/checks/testing/playwright-feature-coverage-gaps.d.ts.map +1 -0
- package/dist/checks/testing/playwright-feature-coverage-gaps.js +1582 -0
- package/dist/checks/testing/playwright-feature-coverage-gaps.js.map +1 -0
- package/dist/checks/testing/playwright-mock-inventory.d.ts +24 -0
- package/dist/checks/testing/playwright-mock-inventory.d.ts.map +1 -0
- package/dist/checks/testing/playwright-mock-inventory.js +380 -0
- package/dist/checks/testing/playwright-mock-inventory.js.map +1 -0
- package/dist/checks/testing/test-coverage-threshold.d.ts +25 -0
- package/dist/checks/testing/test-coverage-threshold.d.ts.map +1 -0
- package/dist/checks/testing/test-coverage-threshold.js +166 -0
- package/dist/checks/testing/test-coverage-threshold.js.map +1 -0
- package/dist/checks/testing/test-flakiness-score.d.ts +27 -0
- package/dist/checks/testing/test-flakiness-score.d.ts.map +1 -0
- package/dist/checks/testing/test-flakiness-score.js +358 -0
- package/dist/checks/testing/test-flakiness-score.js.map +1 -0
- package/dist/checks/testing/test-patterns.d.ts +16 -0
- package/dist/checks/testing/test-patterns.d.ts.map +1 -0
- package/dist/checks/testing/test-patterns.js +156 -0
- package/dist/checks/testing/test-patterns.js.map +1 -0
- package/dist/checks/workflows/a-plus-rating-validation.d.ts +42 -0
- package/dist/checks/workflows/a-plus-rating-validation.d.ts.map +1 -0
- package/dist/checks/workflows/a-plus-rating-validation.js +527 -0
- package/dist/checks/workflows/a-plus-rating-validation.js.map +1 -0
- package/dist/checks/workflows/affected.d.ts +14 -0
- package/dist/checks/workflows/affected.d.ts.map +1 -0
- package/dist/checks/workflows/affected.js +126 -0
- package/dist/checks/workflows/affected.js.map +1 -0
- package/dist/checks/workflows/ai.d.ts +6 -0
- package/dist/checks/workflows/ai.d.ts.map +1 -0
- package/dist/checks/workflows/ai.js +42 -0
- package/dist/checks/workflows/ai.js.map +1 -0
- package/dist/checks/workflows/all.d.ts +31 -0
- package/dist/checks/workflows/all.d.ts.map +1 -0
- package/dist/checks/workflows/all.js +2688 -0
- package/dist/checks/workflows/all.js.map +1 -0
- package/dist/checks/workflows/commit.d.ts +19 -0
- package/dist/checks/workflows/commit.d.ts.map +1 -0
- package/dist/checks/workflows/commit.js +207 -0
- package/dist/checks/workflows/commit.js.map +1 -0
- package/dist/checks/workflows/critical.d.ts +9 -0
- package/dist/checks/workflows/critical.d.ts.map +1 -0
- package/dist/checks/workflows/critical.js +213 -0
- package/dist/checks/workflows/critical.js.map +1 -0
- package/dist/checks/workflows/database-id-validation.d.ts +9 -0
- package/dist/checks/workflows/database-id-validation.d.ts.map +1 -0
- package/dist/checks/workflows/database-id-validation.js +13 -0
- package/dist/checks/workflows/database-id-validation.js.map +1 -0
- package/dist/checks/workflows/deploy.d.ts +20 -0
- package/dist/checks/workflows/deploy.d.ts.map +1 -0
- package/dist/checks/workflows/deploy.js +107 -0
- package/dist/checks/workflows/deploy.js.map +1 -0
- package/dist/checks/workflows/deployment-readiness.d.ts +12 -0
- package/dist/checks/workflows/deployment-readiness.d.ts.map +1 -0
- package/dist/checks/workflows/deployment-readiness.js +403 -0
- package/dist/checks/workflows/deployment-readiness.js.map +1 -0
- package/dist/checks/workflows/dev.d.ts +19 -0
- package/dist/checks/workflows/dev.d.ts.map +1 -0
- package/dist/checks/workflows/dev.js +88 -0
- package/dist/checks/workflows/dev.js.map +1 -0
- package/dist/checks/workflows/development.d.ts +9 -0
- package/dist/checks/workflows/development.d.ts.map +1 -0
- package/dist/checks/workflows/development.js +65 -0
- package/dist/checks/workflows/development.js.map +1 -0
- package/dist/checks/workflows/enterprise.d.ts +10 -0
- package/dist/checks/workflows/enterprise.d.ts.map +1 -0
- package/dist/checks/workflows/enterprise.js +359 -0
- package/dist/checks/workflows/enterprise.js.map +1 -0
- package/dist/checks/workflows/images.d.ts +6 -0
- package/dist/checks/workflows/images.d.ts.map +1 -0
- package/dist/checks/workflows/images.js +58 -0
- package/dist/checks/workflows/images.js.map +1 -0
- package/dist/checks/workflows/naming.d.ts +19 -0
- package/dist/checks/workflows/naming.d.ts.map +1 -0
- package/dist/checks/workflows/naming.js +42 -0
- package/dist/checks/workflows/naming.js.map +1 -0
- package/dist/checks/workflows/performance.d.ts +8 -0
- package/dist/checks/workflows/performance.d.ts.map +1 -0
- package/dist/checks/workflows/performance.js +77 -0
- package/dist/checks/workflows/performance.js.map +1 -0
- package/dist/checks/workflows/pre-deploy.d.ts +6 -0
- package/dist/checks/workflows/pre-deploy.d.ts.map +1 -0
- package/dist/checks/workflows/pre-deploy.js +41 -0
- package/dist/checks/workflows/pre-deploy.js.map +1 -0
- package/dist/checks/workflows/security.d.ts +8 -0
- package/dist/checks/workflows/security.d.ts.map +1 -0
- package/dist/checks/workflows/security.js +71 -0
- package/dist/checks/workflows/security.js.map +1 -0
- package/dist/checks/workflows/supercatch.d.ts +8 -0
- package/dist/checks/workflows/supercatch.d.ts.map +1 -0
- package/dist/checks/workflows/supercatch.js +127 -0
- package/dist/checks/workflows/supercatch.js.map +1 -0
- package/dist/checks/workflows/ui-quality.d.ts +9 -0
- package/dist/checks/workflows/ui-quality.d.ts.map +1 -0
- package/dist/checks/workflows/ui-quality.js +264 -0
- package/dist/checks/workflows/ui-quality.js.map +1 -0
- package/dist/checks/workflows/ui-uniformity.d.ts +18 -0
- package/dist/checks/workflows/ui-uniformity.d.ts.map +1 -0
- package/dist/checks/workflows/ui-uniformity.js +265 -0
- package/dist/checks/workflows/ui-uniformity.js.map +1 -0
- package/dist/checks/workflows/vercel.d.ts +16 -0
- package/dist/checks/workflows/vercel.d.ts.map +1 -0
- package/dist/checks/workflows/vercel.js +173 -0
- package/dist/checks/workflows/vercel.js.map +1 -0
- package/dist/utils/validation-helpers.d.ts +43 -0
- package/dist/utils/validation-helpers.d.ts.map +1 -0
- package/dist/utils/validation-helpers.js +370 -0
- package/dist/utils/validation-helpers.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,1288 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* Shared Components Migration Check (Enhanced)
|
|
5
|
+
*
|
|
6
|
+
* Prevents reversion to old patterns by detecting:
|
|
7
|
+
*
|
|
8
|
+
* ERRORS (blocking):
|
|
9
|
+
* - MUI imports (@mui/material, @mui/icons-material, @emotion)
|
|
10
|
+
* - Banned libraries (react-icons, heroicons, fortawesome, lodash, moment)
|
|
11
|
+
*
|
|
12
|
+
* WARNINGS (should fix):
|
|
13
|
+
* - Duplicate hook implementations
|
|
14
|
+
* - Duplicate utility functions
|
|
15
|
+
* - TypeScript 'any' type usage (except types/, mocks, configs)
|
|
16
|
+
* - Console statements in components
|
|
17
|
+
* - Empty catch blocks
|
|
18
|
+
* - Accessibility issues (missing alt, click on non-interactive)
|
|
19
|
+
* - Deprecated component usage
|
|
20
|
+
*
|
|
21
|
+
* INFO (suggestions with --info):
|
|
22
|
+
* - Inline patterns that should use shared components
|
|
23
|
+
* - Loading/skeleton patterns
|
|
24
|
+
* - Dialog/modal patterns
|
|
25
|
+
* - Table patterns with sorting/pagination
|
|
26
|
+
* - Form patterns with many fields
|
|
27
|
+
* - Date formatting patterns
|
|
28
|
+
* - Price display patterns
|
|
29
|
+
* - Performance patterns (inline handlers, missing keys)
|
|
30
|
+
* - TODO/FIXME comments
|
|
31
|
+
* - Hardcoded URLs
|
|
32
|
+
* - Magic numbers
|
|
33
|
+
*
|
|
34
|
+
* Run: pnpm preflight:shared-components
|
|
35
|
+
*
|
|
36
|
+
* Options:
|
|
37
|
+
* --verbose, -v Show all warnings (not just errors)
|
|
38
|
+
* --report Output JSON report for CI integration
|
|
39
|
+
* --info Show info-level suggestions
|
|
40
|
+
* --fix Auto-fix issues where possible:
|
|
41
|
+
* - Adds preflight-ignore comments for 'any' type
|
|
42
|
+
* - Removes console.log statements
|
|
43
|
+
* - Adds missing imports
|
|
44
|
+
*
|
|
45
|
+
* Ignore patterns:
|
|
46
|
+
* // preflight-ignore - Ignore next line
|
|
47
|
+
* // preflight-ignore-file - Ignore entire file (must be at top)
|
|
48
|
+
* // preflight-ignore-next-N - Ignore next N lines
|
|
49
|
+
*
|
|
50
|
+
* Auto-fix types:
|
|
51
|
+
* - remove-line: Removes the entire line
|
|
52
|
+
* - replace-line: Replaces the line with new content
|
|
53
|
+
* - replace-import: Replaces an import statement
|
|
54
|
+
* - add-import: Adds a new import statement
|
|
55
|
+
* - remove-console: Removes console.log/debug/info statements
|
|
56
|
+
* - add-preflight-ignore: Adds a preflight-ignore comment
|
|
57
|
+
*/
|
|
58
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
59
|
+
if (k2 === undefined) k2 = k;
|
|
60
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
61
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
62
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
63
|
+
}
|
|
64
|
+
Object.defineProperty(o, k2, desc);
|
|
65
|
+
}) : (function(o, m, k, k2) {
|
|
66
|
+
if (k2 === undefined) k2 = k;
|
|
67
|
+
o[k2] = m[k];
|
|
68
|
+
}));
|
|
69
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
70
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
71
|
+
}) : function(o, v) {
|
|
72
|
+
o["default"] = v;
|
|
73
|
+
});
|
|
74
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
75
|
+
var ownKeys = function(o) {
|
|
76
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
77
|
+
var ar = [];
|
|
78
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
79
|
+
return ar;
|
|
80
|
+
};
|
|
81
|
+
return ownKeys(o);
|
|
82
|
+
};
|
|
83
|
+
return function (mod) {
|
|
84
|
+
if (mod && mod.__esModule) return mod;
|
|
85
|
+
var result = {};
|
|
86
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
87
|
+
__setModuleDefault(result, mod);
|
|
88
|
+
return result;
|
|
89
|
+
};
|
|
90
|
+
})();
|
|
91
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
92
|
+
exports.SharedComponentsChecker = exports.tags = exports.description = exports.blocking = exports.category = exports.name = exports.id = void 0;
|
|
93
|
+
const fs = __importStar(require("fs"));
|
|
94
|
+
const file_cache_1 = require("../../shared/file-cache");
|
|
95
|
+
const path = __importStar(require("path"));
|
|
96
|
+
const console_chars_1 = require("../../utils/console-chars");
|
|
97
|
+
// Check metadata
|
|
98
|
+
exports.id = "specialized/shared-components-migration";
|
|
99
|
+
exports.name = "Shared Components Migration";
|
|
100
|
+
exports.category = "specialized";
|
|
101
|
+
exports.blocking = true;
|
|
102
|
+
exports.description = "Shared Components Migration Check (Enhanced)";
|
|
103
|
+
exports.tags = ["specialized", "database"];
|
|
104
|
+
// CONFIGURATION
|
|
105
|
+
// MUI is BANNED - all imports should use @/components/ui or @/components/shared
|
|
106
|
+
const BANNED_IMPORT_PATTERNS = [
|
|
107
|
+
{ pattern: /@mui\/material/, message: "MUI Material is banned", replacement: "@/components/ui" },
|
|
108
|
+
{ pattern: /@mui\/icons-material/, message: "MUI Icons are banned", replacement: "lucide-react" },
|
|
109
|
+
{ pattern: /@mui\/lab/, message: "MUI Lab is banned", replacement: "@/components/ui" },
|
|
110
|
+
{
|
|
111
|
+
pattern: /@mui\/x-/,
|
|
112
|
+
message: "MUI X components are banned",
|
|
113
|
+
replacement: "@/components/shared",
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
pattern: /@emotion\//,
|
|
117
|
+
message: "Emotion (MUI styling) is banned",
|
|
118
|
+
replacement: "Tailwind CSS",
|
|
119
|
+
},
|
|
120
|
+
// Other banned icon libraries
|
|
121
|
+
{ pattern: /react-icons\//, message: "react-icons is banned", replacement: "lucide-react" },
|
|
122
|
+
{ pattern: /@heroicons\//, message: "Heroicons is banned", replacement: "lucide-react" },
|
|
123
|
+
{ pattern: /@fortawesome\//, message: "Font Awesome is banned", replacement: "lucide-react" },
|
|
124
|
+
// Banned utility libraries (use native JS or shared utils)
|
|
125
|
+
{ pattern: /^lodash$/, message: "lodash is banned", replacement: "native JS or @/lib/utils" },
|
|
126
|
+
{ pattern: /lodash\//, message: "lodash is banned", replacement: "native JS or @/lib/utils" },
|
|
127
|
+
{ pattern: /^moment$/, message: "moment.js is banned", replacement: "date-fns or native Date" },
|
|
128
|
+
];
|
|
129
|
+
// Deprecated components that should not be used (from shared/index.ts comments)
|
|
130
|
+
// Note: Some are re-exported as aliases (e.g., PriceDisplay -> UnifiedPriceDisplay)
|
|
131
|
+
// Only flag if importing from wrong location or using truly deprecated names
|
|
132
|
+
const DEPRECATED_COMPONENTS = [
|
|
133
|
+
{ name: "SkeletonLoader", replacement: "UnifiedSkeleton", checkImportPath: true },
|
|
134
|
+
{
|
|
135
|
+
name: "ToastProvider",
|
|
136
|
+
replacement: "StatusProvider from @/components/shared/status",
|
|
137
|
+
checkImportPath: false,
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
name: "useToast",
|
|
141
|
+
replacement: "useStatus from @/components/shared/status",
|
|
142
|
+
checkImportPath: false,
|
|
143
|
+
},
|
|
144
|
+
// These are aliases in shared/index.ts, so only flag if imported from wrong place
|
|
145
|
+
// { name: "PriceDisplay", replacement: "UnifiedPriceDisplay" }, // Alias exists, skip
|
|
146
|
+
{ name: "Modal", replacement: "UnifiedDialog from @/components/shared", checkImportPath: false },
|
|
147
|
+
{ name: "DataTable", replacement: "EnhancedDataTable", checkImportPath: true },
|
|
148
|
+
{ name: "PageHeader", replacement: "UnifiedPageHeader", checkImportPath: true },
|
|
149
|
+
{ name: "SimilarItems", replacement: "RelatedItems (server-rendered)", checkImportPath: false },
|
|
150
|
+
{ name: "ActionBanner", replacement: "UnifiedStatus position='banner'", checkImportPath: false },
|
|
151
|
+
{ name: "ImageUploadZone", replacement: "UnifiedFileInterface", checkImportPath: false },
|
|
152
|
+
{ name: "FloatingActionButton", replacement: "removed (dead code)", checkImportPath: false },
|
|
153
|
+
];
|
|
154
|
+
// Hooks that should use shared implementations
|
|
155
|
+
const SHARED_HOOKS = [
|
|
156
|
+
"useToggle",
|
|
157
|
+
"useDisclosure",
|
|
158
|
+
"useLocalStorage",
|
|
159
|
+
"useForm",
|
|
160
|
+
"useAsync",
|
|
161
|
+
"useCopyToClipboard",
|
|
162
|
+
"useMediaQuery",
|
|
163
|
+
"useClickOutside",
|
|
164
|
+
"usePagination",
|
|
165
|
+
"useDebounce",
|
|
166
|
+
"useThrottle",
|
|
167
|
+
"useIntersectionObserver",
|
|
168
|
+
"useWindowSize",
|
|
169
|
+
];
|
|
170
|
+
// Utilities that should use shared implementations
|
|
171
|
+
const SHARED_UTILITIES = [
|
|
172
|
+
"unique",
|
|
173
|
+
"groupBy",
|
|
174
|
+
"chunk",
|
|
175
|
+
"sortBy",
|
|
176
|
+
"capitalize",
|
|
177
|
+
"slugify",
|
|
178
|
+
"camelCase",
|
|
179
|
+
"formatCurrency",
|
|
180
|
+
"formatDate",
|
|
181
|
+
"formatFileSize",
|
|
182
|
+
"formatNumber",
|
|
183
|
+
"formatPercent",
|
|
184
|
+
"isValidEmail",
|
|
185
|
+
"validatePassword",
|
|
186
|
+
"isRequired",
|
|
187
|
+
"truncate",
|
|
188
|
+
"debounce",
|
|
189
|
+
"throttle",
|
|
190
|
+
];
|
|
191
|
+
// Inline patterns that indicate code smell
|
|
192
|
+
const INLINE_PATTERNS_TO_CHECK = [
|
|
193
|
+
{
|
|
194
|
+
pattern: /className="[^"]*flex[^"]*items-center[^"]*gap-[^"]*"/,
|
|
195
|
+
context: "StatusChip",
|
|
196
|
+
message: "Flex row with gap pattern (possible status display)",
|
|
197
|
+
suggestion: "Consider StatusIconChip or LabelValuePair from @/components/shared",
|
|
198
|
+
severity: "info",
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
pattern: /\bawait\s+fetch\s*\(/,
|
|
202
|
+
context: "useQuery",
|
|
203
|
+
message: "Direct fetch call in component",
|
|
204
|
+
suggestion: "Consider using React Query or a custom hook for data fetching",
|
|
205
|
+
severity: "info",
|
|
206
|
+
},
|
|
207
|
+
];
|
|
208
|
+
// Files/patterns to always exclude
|
|
209
|
+
const EXCLUDED_PATTERNS = [
|
|
210
|
+
"**/node_modules/**",
|
|
211
|
+
"**/.next/**",
|
|
212
|
+
"**/dist/**",
|
|
213
|
+
"**/build/**",
|
|
214
|
+
"components/shared/**",
|
|
215
|
+
"components/ui/**",
|
|
216
|
+
"hooks/**",
|
|
217
|
+
"lib/utils/**",
|
|
218
|
+
"packages/**",
|
|
219
|
+
"scripts/**",
|
|
220
|
+
"tests/**",
|
|
221
|
+
"**/*.test.{ts,tsx}",
|
|
222
|
+
"**/*.spec.{ts,tsx}",
|
|
223
|
+
"**/*.stories.{ts,tsx}",
|
|
224
|
+
];
|
|
225
|
+
// Files where 'any' type is acceptable (type definitions, mocks, configs)
|
|
226
|
+
const ANY_TYPE_ALLOWED_PATTERNS = [
|
|
227
|
+
/^types[\/\\]/,
|
|
228
|
+
/^__mocks__[\/\\]/,
|
|
229
|
+
/\.config\.(ts|js)$/,
|
|
230
|
+
/\.d\.ts$/,
|
|
231
|
+
/prisma[\/\\].*\.ts$/,
|
|
232
|
+
/docs[\/\\]code-examples[\/\\]/, // Documentation examples
|
|
233
|
+
];
|
|
234
|
+
// CHECKER CLASS
|
|
235
|
+
class SharedComponentsChecker {
|
|
236
|
+
issues = [];
|
|
237
|
+
options;
|
|
238
|
+
stats = {
|
|
239
|
+
filesChecked: 0,
|
|
240
|
+
errors: 0,
|
|
241
|
+
warnings: 0,
|
|
242
|
+
info: 0,
|
|
243
|
+
ignoredFiles: 0,
|
|
244
|
+
ignoredLines: 0,
|
|
245
|
+
fixesApplied: 0,
|
|
246
|
+
fixesFailed: 0,
|
|
247
|
+
};
|
|
248
|
+
fileIgnoreCache = new Map();
|
|
249
|
+
constructor(options = {}) {
|
|
250
|
+
this.options = options;
|
|
251
|
+
}
|
|
252
|
+
async check() {
|
|
253
|
+
console.log(`${console_chars_1.emoji.search} Checking for shared component usage...\n`);
|
|
254
|
+
const files = await file_cache_1.fileCache.getAllTsTsx();
|
|
255
|
+
for (const file of files) {
|
|
256
|
+
await this.checkFile(file);
|
|
257
|
+
}
|
|
258
|
+
this.calculateStats();
|
|
259
|
+
// Apply fixes if --fix flag is set
|
|
260
|
+
if (this.options.fix) {
|
|
261
|
+
await this.applyFixes();
|
|
262
|
+
}
|
|
263
|
+
this.printResults();
|
|
264
|
+
if (this.options.report) {
|
|
265
|
+
this.outputJsonReport();
|
|
266
|
+
}
|
|
267
|
+
return {
|
|
268
|
+
passed: this.stats.errors === 0,
|
|
269
|
+
issues: this.issues,
|
|
270
|
+
stats: this.stats,
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
async checkFile(filePath) {
|
|
274
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
275
|
+
const lines = content.split("\n");
|
|
276
|
+
// Check for file-level ignore
|
|
277
|
+
const firstLines = lines.slice(0, 10).join("\n");
|
|
278
|
+
if (firstLines.includes("preflight-ignore-file")) {
|
|
279
|
+
this.stats.ignoredFiles++;
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
this.stats.filesChecked++;
|
|
283
|
+
// Build ignore line cache for this file
|
|
284
|
+
this.buildIgnoreCache(filePath, lines);
|
|
285
|
+
lines.forEach((line, index) => {
|
|
286
|
+
const lineNumber = index + 1;
|
|
287
|
+
// Skip ignored lines
|
|
288
|
+
if (this.isLineIgnored(filePath, lineNumber)) {
|
|
289
|
+
this.stats.ignoredLines++;
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
// Run all checks
|
|
293
|
+
this.checkMUIImports(line, lineNumber, filePath);
|
|
294
|
+
this.checkDuplicateHooks(line, lineNumber, filePath);
|
|
295
|
+
this.checkDuplicateUtilities(line, lineNumber, filePath);
|
|
296
|
+
this.checkInlinePatterns(line, lineNumber, filePath, lines);
|
|
297
|
+
this.checkLoadingPatterns(line, lineNumber, filePath, lines);
|
|
298
|
+
this.checkDatePatterns(line, lineNumber, filePath);
|
|
299
|
+
this.checkPricePatterns(line, lineNumber, filePath);
|
|
300
|
+
this.checkDialogPatterns(line, lineNumber, filePath, lines);
|
|
301
|
+
this.checkSkeletonPatterns(line, lineNumber, filePath, lines);
|
|
302
|
+
this.checkTablePatterns(line, lineNumber, filePath, lines);
|
|
303
|
+
this.checkFormPatterns(line, lineNumber, filePath, lines);
|
|
304
|
+
this.checkCodeQuality(line, lineNumber, filePath, lines);
|
|
305
|
+
this.checkDeprecatedComponents(line, lineNumber, filePath);
|
|
306
|
+
this.checkDateFnsUsage(line, lineNumber, filePath);
|
|
307
|
+
this.checkAccessibility(line, lineNumber, filePath);
|
|
308
|
+
this.checkPerformancePatterns(line, lineNumber, filePath, lines);
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
// IGNORE HANDLING
|
|
312
|
+
buildIgnoreCache(filePath, lines) {
|
|
313
|
+
const ignoredLines = new Set();
|
|
314
|
+
lines.forEach((line, index) => {
|
|
315
|
+
// Check for inline ignore comment
|
|
316
|
+
if (line.includes("preflight-ignore")) {
|
|
317
|
+
// Ignore current line and next line
|
|
318
|
+
ignoredLines.add(index + 1);
|
|
319
|
+
ignoredLines.add(index + 2);
|
|
320
|
+
// Also check for range ignore (preflight-ignore-next-5)
|
|
321
|
+
const rangeMatch = line.match(/preflight-ignore-next-(\d+)/);
|
|
322
|
+
if (rangeMatch) {
|
|
323
|
+
const count = parseInt(rangeMatch[1], 10);
|
|
324
|
+
for (let i = 1; i <= count; i++) {
|
|
325
|
+
ignoredLines.add(index + 1 + i);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
});
|
|
330
|
+
this.fileIgnoreCache.set(filePath, ignoredLines);
|
|
331
|
+
}
|
|
332
|
+
isLineIgnored(filePath, lineNumber) {
|
|
333
|
+
const ignoredLines = this.fileIgnoreCache.get(filePath);
|
|
334
|
+
if (!ignoredLines)
|
|
335
|
+
return false;
|
|
336
|
+
// Check if this line or any of the previous 3 lines have ignore
|
|
337
|
+
for (let i = 0; i <= 3; i++) {
|
|
338
|
+
if (ignoredLines.has(lineNumber - i)) {
|
|
339
|
+
return true;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
return false;
|
|
343
|
+
}
|
|
344
|
+
// CHECK METHODS
|
|
345
|
+
checkMUIImports(line, lineNumber, filePath) {
|
|
346
|
+
// Check for ANY banned import patterns (MUI, Emotion, etc.)
|
|
347
|
+
for (const banned of BANNED_IMPORT_PATTERNS) {
|
|
348
|
+
if (banned.pattern.test(line)) {
|
|
349
|
+
this.addIssue({
|
|
350
|
+
file: filePath,
|
|
351
|
+
line: lineNumber,
|
|
352
|
+
type: "error", // MUI imports are ERRORS, not warnings
|
|
353
|
+
category: "banned-import",
|
|
354
|
+
message: banned.message,
|
|
355
|
+
suggestion: `Use ${banned.replacement} instead`,
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
checkDuplicateHooks(line, lineNumber, filePath) {
|
|
361
|
+
const hookMatch = line.match(/(?:export\s+)?(?:const|function)\s+(use[A-Z]\w+)/);
|
|
362
|
+
if (hookMatch) {
|
|
363
|
+
const hookName = hookMatch[1];
|
|
364
|
+
if (SHARED_HOOKS.includes(hookName)) {
|
|
365
|
+
this.addIssue({
|
|
366
|
+
file: filePath,
|
|
367
|
+
line: lineNumber,
|
|
368
|
+
type: "warning",
|
|
369
|
+
category: "duplicate-hook",
|
|
370
|
+
message: `Duplicate hook implementation: ${hookName}`,
|
|
371
|
+
suggestion: `Import ${hookName} from @/hooks instead`,
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
checkDuplicateUtilities(line, lineNumber, filePath) {
|
|
377
|
+
const utilMatch = line.match(/(?:export\s+)?(?:const|function)\s+(\w+)\s*[=:]/);
|
|
378
|
+
if (utilMatch) {
|
|
379
|
+
const utilName = utilMatch[1];
|
|
380
|
+
if (SHARED_UTILITIES.includes(utilName)) {
|
|
381
|
+
// Skip false positives
|
|
382
|
+
if (this.isFalsePositiveUtility(line, utilName, filePath)) {
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
this.addIssue({
|
|
386
|
+
file: filePath,
|
|
387
|
+
line: lineNumber,
|
|
388
|
+
type: "warning",
|
|
389
|
+
category: "duplicate-utility",
|
|
390
|
+
message: `Duplicate utility function: ${utilName}`,
|
|
391
|
+
suggestion: `Import ${utilName} from @/lib/utils instead`,
|
|
392
|
+
autoFixable: true,
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
isFalsePositiveUtility(line, utilName, filePath) {
|
|
398
|
+
// Skip variable assignments (not function definitions)
|
|
399
|
+
if (line.includes("=") && !line.includes("=>") && !line.includes("function")) {
|
|
400
|
+
return true;
|
|
401
|
+
}
|
|
402
|
+
// Skip streaming decoder chunks
|
|
403
|
+
if (utilName === "chunk" && line.includes("decoder.decode")) {
|
|
404
|
+
return true;
|
|
405
|
+
}
|
|
406
|
+
// Skip loop variables
|
|
407
|
+
if (line.includes("const chunk = buffer.slice")) {
|
|
408
|
+
return true;
|
|
409
|
+
}
|
|
410
|
+
// Skip object properties
|
|
411
|
+
if (line.includes("{") && !line.includes("function") && !line.includes("=>")) {
|
|
412
|
+
return true;
|
|
413
|
+
}
|
|
414
|
+
// Skip if already importing from shared utils
|
|
415
|
+
const fileContent = fs.readFileSync(filePath, "utf-8");
|
|
416
|
+
if (fileContent.includes(`import { ${utilName}`) && fileContent.includes("@/lib/utils")) {
|
|
417
|
+
return true;
|
|
418
|
+
}
|
|
419
|
+
// Skip component-specific formatters
|
|
420
|
+
if (line.startsWith("const ") && !line.includes("export")) {
|
|
421
|
+
if (line.includes("(value") || line.includes("(dateString") || line.includes("(amount")) {
|
|
422
|
+
return true;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
return false;
|
|
426
|
+
}
|
|
427
|
+
checkInlinePatterns(line, lineNumber, filePath, lines) {
|
|
428
|
+
const getNextLines = (count) => {
|
|
429
|
+
return lines.slice(lineNumber, lineNumber + count).join("\n");
|
|
430
|
+
};
|
|
431
|
+
const getPrevLines = (count) => {
|
|
432
|
+
return lines.slice(Math.max(0, lineNumber - count - 1), lineNumber - 1).join("\n");
|
|
433
|
+
};
|
|
434
|
+
// Balance card pattern (colored icon background + currency value)
|
|
435
|
+
if (line.match(/bg-(green|orange|red|blue)-100/) && !filePath.includes("BalanceStatCard")) {
|
|
436
|
+
const nextLines = getNextLines(10);
|
|
437
|
+
if (nextLines.includes("formatCurrency") || nextLines.includes('variant="h4"')) {
|
|
438
|
+
this.addIssue({
|
|
439
|
+
file: filePath,
|
|
440
|
+
line: lineNumber,
|
|
441
|
+
type: "warning",
|
|
442
|
+
category: "inline-pattern",
|
|
443
|
+
message: "Inline balance card pattern detected (colored icon bg + currency)",
|
|
444
|
+
suggestion: "Use BalanceStatCard from @/components/shared for consistent finance cards",
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
// Status icon + chip combo pattern
|
|
449
|
+
if ((line.includes("getStatusIcon") || line.match(/\{.*Icon.*size=\{16\}/)) &&
|
|
450
|
+
!filePath.includes("StatusIconChip")) {
|
|
451
|
+
const nextLines = getNextLines(3);
|
|
452
|
+
if (nextLines.includes("StatusChip")) {
|
|
453
|
+
this.addIssue({
|
|
454
|
+
file: filePath,
|
|
455
|
+
line: lineNumber,
|
|
456
|
+
type: "warning",
|
|
457
|
+
category: "inline-pattern",
|
|
458
|
+
message: "Status icon + StatusChip combo pattern detected",
|
|
459
|
+
suggestion: "Use StatusIconChip from @/components/shared which auto-detects icons",
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
// Compact stat card pattern (caption label + h5 value)
|
|
464
|
+
if (line.includes('variant="caption"') && line.includes('color="text.secondary"')) {
|
|
465
|
+
const nextLines = getNextLines(3);
|
|
466
|
+
if (nextLines.includes('variant="h5"') && nextLines.includes('fontWeight="bold"')) {
|
|
467
|
+
const prevLines = getPrevLines(5);
|
|
468
|
+
if (prevLines.includes("CardContent") && prevLines.includes("p-4")) {
|
|
469
|
+
this.addIssue({
|
|
470
|
+
file: filePath,
|
|
471
|
+
line: lineNumber,
|
|
472
|
+
type: "warning",
|
|
473
|
+
category: "inline-pattern",
|
|
474
|
+
message: "Compact stat card pattern detected (caption + h5 bold)",
|
|
475
|
+
suggestion: "Use CompactStatCard from @/components/shared for consistent stat display",
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
// Pagination logic
|
|
481
|
+
if (line.includes("useState") && (line.includes("page") || line.includes("Page"))) {
|
|
482
|
+
const nextLines = getNextLines(5);
|
|
483
|
+
if (nextLines.includes("setPage") && nextLines.includes("totalPages")) {
|
|
484
|
+
this.addIssue({
|
|
485
|
+
file: filePath,
|
|
486
|
+
line: lineNumber,
|
|
487
|
+
type: "info",
|
|
488
|
+
category: "inline-pattern",
|
|
489
|
+
message: "Inline pagination state detected",
|
|
490
|
+
suggestion: "Consider using usePagination hook from @/hooks",
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
// Toggle logic
|
|
495
|
+
if (line.match(/const\s+\[is\w+,\s*set\w+\]\s*=\s*useState<boolean>/)) {
|
|
496
|
+
this.addIssue({
|
|
497
|
+
file: filePath,
|
|
498
|
+
line: lineNumber,
|
|
499
|
+
type: "info",
|
|
500
|
+
category: "inline-pattern",
|
|
501
|
+
message: "Boolean state detected",
|
|
502
|
+
suggestion: "Consider using useToggle or useDisclosure hook from @/hooks",
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
// Copy to clipboard
|
|
506
|
+
if (line.includes("navigator.clipboard.writeText")) {
|
|
507
|
+
this.addIssue({
|
|
508
|
+
file: filePath,
|
|
509
|
+
line: lineNumber,
|
|
510
|
+
type: "warning",
|
|
511
|
+
category: "inline-pattern",
|
|
512
|
+
message: "Direct clipboard API usage detected",
|
|
513
|
+
suggestion: "Use useCopyToClipboard hook from @/hooks for better UX",
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
// Currency formatting inline
|
|
517
|
+
if (line.match(/toLocaleString\(['"]en-US['"],\s*{\s*style:\s*['"]currency['"]/)) {
|
|
518
|
+
this.addIssue({
|
|
519
|
+
file: filePath,
|
|
520
|
+
line: lineNumber,
|
|
521
|
+
type: "warning",
|
|
522
|
+
category: "inline-pattern",
|
|
523
|
+
message: "Inline currency formatting detected",
|
|
524
|
+
suggestion: "Use formatCurrency from @/lib/utils/format",
|
|
525
|
+
autoFixable: true,
|
|
526
|
+
});
|
|
527
|
+
}
|
|
528
|
+
// Email validation
|
|
529
|
+
if (line.match(/\/\^[^\/]*@[^\/]*\$\//)) {
|
|
530
|
+
this.addIssue({
|
|
531
|
+
file: filePath,
|
|
532
|
+
line: lineNumber,
|
|
533
|
+
type: "info",
|
|
534
|
+
category: "inline-pattern",
|
|
535
|
+
message: "Inline email regex detected",
|
|
536
|
+
suggestion: "Use isValidEmail from @/lib/utils",
|
|
537
|
+
});
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
checkLoadingPatterns(line, lineNumber, filePath, lines) {
|
|
541
|
+
// Loading spinner with animate-spin
|
|
542
|
+
if (line.includes("animate-spin") &&
|
|
543
|
+
(line.includes("RefreshCw") || line.includes("Loader") || line.includes("Spinner"))) {
|
|
544
|
+
// Check if it's a standalone loading indicator (not part of a button)
|
|
545
|
+
const prevLines = lines.slice(Math.max(0, lineNumber - 3), lineNumber).join("\n");
|
|
546
|
+
if (!prevLines.includes("<Button") && !prevLines.includes("LoadingButton")) {
|
|
547
|
+
this.addIssue({
|
|
548
|
+
file: filePath,
|
|
549
|
+
line: lineNumber,
|
|
550
|
+
type: "info",
|
|
551
|
+
category: "loading-pattern",
|
|
552
|
+
message: "Inline loading spinner detected",
|
|
553
|
+
suggestion: "Consider using LoadingState from @/components/shared for consistent loading UI",
|
|
554
|
+
});
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
// CircularProgress usage
|
|
558
|
+
if (line.includes("<CircularProgress") && !filePath.includes("LoadingState")) {
|
|
559
|
+
this.addIssue({
|
|
560
|
+
file: filePath,
|
|
561
|
+
line: lineNumber,
|
|
562
|
+
type: "info",
|
|
563
|
+
category: "loading-pattern",
|
|
564
|
+
message: "CircularProgress detected",
|
|
565
|
+
suggestion: "Consider using LoadingState from @/components/shared for consistent loading UI",
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
checkDatePatterns(line, lineNumber, filePath) {
|
|
570
|
+
// toLocaleString for dates
|
|
571
|
+
if (line.match(/\.toLocaleString\(\)/) ||
|
|
572
|
+
line.match(/\.toLocaleDateString\(\)/) ||
|
|
573
|
+
line.match(/\.toLocaleTimeString\(\)/)) {
|
|
574
|
+
// Skip if it's in a comment
|
|
575
|
+
if (line.trim().startsWith("//") || line.trim().startsWith("*")) {
|
|
576
|
+
return;
|
|
577
|
+
}
|
|
578
|
+
this.addIssue({
|
|
579
|
+
file: filePath,
|
|
580
|
+
line: lineNumber,
|
|
581
|
+
type: "info",
|
|
582
|
+
category: "date-pattern",
|
|
583
|
+
message: "Inline date formatting detected",
|
|
584
|
+
suggestion: "Consider using formatDate from @/lib/utils/format for consistent date display",
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
// new Date().toISOString() for display
|
|
588
|
+
if (line.includes("new Date(") && line.includes("toISOString()")) {
|
|
589
|
+
this.addIssue({
|
|
590
|
+
file: filePath,
|
|
591
|
+
line: lineNumber,
|
|
592
|
+
type: "info",
|
|
593
|
+
category: "date-pattern",
|
|
594
|
+
message: "ISO date string for display detected",
|
|
595
|
+
suggestion: "Use formatDate from @/lib/utils/format for user-friendly dates",
|
|
596
|
+
});
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
checkPricePatterns(line, lineNumber, filePath) {
|
|
600
|
+
// Inline price display with $ symbol
|
|
601
|
+
if (line.match(/\$\{.*\.toFixed\(2\)\}/) || line.match(/\$\s*\{.*price/i)) {
|
|
602
|
+
this.addIssue({
|
|
603
|
+
file: filePath,
|
|
604
|
+
line: lineNumber,
|
|
605
|
+
type: "info",
|
|
606
|
+
category: "price-pattern",
|
|
607
|
+
message: "Inline price display detected",
|
|
608
|
+
suggestion: "Use UnifiedPriceDisplay from @/components/shared for consistent pricing",
|
|
609
|
+
});
|
|
610
|
+
}
|
|
611
|
+
// Manual price formatting
|
|
612
|
+
if (line.match(/\.toFixed\(2\)/) && (line.includes("price") || line.includes("amount"))) {
|
|
613
|
+
this.addIssue({
|
|
614
|
+
file: filePath,
|
|
615
|
+
line: lineNumber,
|
|
616
|
+
type: "info",
|
|
617
|
+
category: "price-pattern",
|
|
618
|
+
message: "Manual price formatting detected",
|
|
619
|
+
suggestion: "Use formatCurrency from @/lib/utils/format",
|
|
620
|
+
});
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
checkDialogPatterns(line, lineNumber, filePath, lines) {
|
|
624
|
+
// useState for dialog open state + conditional rendering
|
|
625
|
+
if (line.match(/const\s+\[(open|isOpen|showModal|dialogOpen)/)) {
|
|
626
|
+
const nextLines = lines.slice(lineNumber, lineNumber + 30).join("\n");
|
|
627
|
+
// Check if there's a Dialog/Modal being conditionally rendered
|
|
628
|
+
if (nextLines.includes("<Dialog") ||
|
|
629
|
+
nextLines.includes("<Modal") ||
|
|
630
|
+
nextLines.includes("&& (")) {
|
|
631
|
+
// Skip if already using UnifiedDialog
|
|
632
|
+
if (nextLines.includes("UnifiedDialog") || nextLines.includes("useDialog")) {
|
|
633
|
+
return;
|
|
634
|
+
}
|
|
635
|
+
this.addIssue({
|
|
636
|
+
file: filePath,
|
|
637
|
+
line: lineNumber,
|
|
638
|
+
type: "info",
|
|
639
|
+
category: "dialog-pattern",
|
|
640
|
+
message: "Manual dialog state management detected",
|
|
641
|
+
suggestion: "Consider using UnifiedDialog with useDialog hook from @/components/shared for consistent dialogs",
|
|
642
|
+
});
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
checkSkeletonPatterns(line, lineNumber, filePath, lines) {
|
|
647
|
+
// Multiple Skeleton components in sequence
|
|
648
|
+
if (line.includes("<Skeleton") && !filePath.includes("UnifiedSkeleton")) {
|
|
649
|
+
const nextLines = lines.slice(lineNumber, lineNumber + 5).join("\n");
|
|
650
|
+
const skeletonCount = (nextLines.match(/<Skeleton/g) || []).length;
|
|
651
|
+
if (skeletonCount >= 3) {
|
|
652
|
+
this.addIssue({
|
|
653
|
+
file: filePath,
|
|
654
|
+
line: lineNumber,
|
|
655
|
+
type: "info",
|
|
656
|
+
category: "skeleton-pattern",
|
|
657
|
+
message: "Multiple skeleton components detected",
|
|
658
|
+
suggestion: "Use UnifiedSkeleton presets (SkeletonCard, SkeletonList, etc.) from @/components/shared",
|
|
659
|
+
});
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
checkTablePatterns(line, lineNumber, filePath, lines) {
|
|
664
|
+
// Table with sorting/pagination state
|
|
665
|
+
if (line.includes("<Table") && !filePath.includes("EnhancedDataTable")) {
|
|
666
|
+
const fileContent = lines.join("\n");
|
|
667
|
+
// Check for sorting state
|
|
668
|
+
const hasSorting = fileContent.includes("sortBy") ||
|
|
669
|
+
fileContent.includes("sortDirection") ||
|
|
670
|
+
fileContent.includes("orderBy");
|
|
671
|
+
// Check for pagination
|
|
672
|
+
const hasPagination = fileContent.includes("currentPage") ||
|
|
673
|
+
fileContent.includes("pageSize") ||
|
|
674
|
+
fileContent.includes("totalPages");
|
|
675
|
+
// Check for selection
|
|
676
|
+
const hasSelection = fileContent.includes("selectedRows") || fileContent.includes("selectedIds");
|
|
677
|
+
if (hasSorting && hasPagination) {
|
|
678
|
+
this.addIssue({
|
|
679
|
+
file: filePath,
|
|
680
|
+
line: lineNumber,
|
|
681
|
+
type: "info",
|
|
682
|
+
category: "table-pattern",
|
|
683
|
+
message: "Table with sorting and pagination detected",
|
|
684
|
+
suggestion: "Consider using EnhancedDataTable from @/components/shared for built-in sorting, pagination, and selection",
|
|
685
|
+
});
|
|
686
|
+
}
|
|
687
|
+
else if (hasSelection) {
|
|
688
|
+
this.addIssue({
|
|
689
|
+
file: filePath,
|
|
690
|
+
line: lineNumber,
|
|
691
|
+
type: "info",
|
|
692
|
+
category: "table-pattern",
|
|
693
|
+
message: "Table with row selection detected",
|
|
694
|
+
suggestion: "Consider using EnhancedDataTable from @/components/shared for built-in selection",
|
|
695
|
+
});
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
checkFormPatterns(line, lineNumber, filePath, lines) {
|
|
700
|
+
// Multiple TextField/Input components in sequence
|
|
701
|
+
if (line.includes("<TextField") || line.includes("<Input")) {
|
|
702
|
+
const nextLines = lines.slice(lineNumber, lineNumber + 20).join("\n");
|
|
703
|
+
const fieldCount = (nextLines.match(/<TextField/g) || []).length + (nextLines.match(/<Input/g) || []).length;
|
|
704
|
+
if (fieldCount >= 5) {
|
|
705
|
+
// Check if using FormBuilder
|
|
706
|
+
const fileContent = lines.join("\n");
|
|
707
|
+
if (!fileContent.includes("FormBuilder") && !fileContent.includes("useForm")) {
|
|
708
|
+
this.addIssue({
|
|
709
|
+
file: filePath,
|
|
710
|
+
line: lineNumber,
|
|
711
|
+
type: "info",
|
|
712
|
+
category: "form-pattern",
|
|
713
|
+
message: "Multiple form fields detected",
|
|
714
|
+
suggestion: "Consider using FormBuilder from @/components/shared for dynamic form generation",
|
|
715
|
+
});
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
checkCodeQuality(line, lineNumber, filePath, lines) {
|
|
721
|
+
// Skip non-component files for some checks
|
|
722
|
+
const isComponentFile = filePath.endsWith(".tsx");
|
|
723
|
+
const isApiRoute = filePath.includes("/api/");
|
|
724
|
+
// Console.log in production code (warning for components, info for API routes)
|
|
725
|
+
if (line.match(/console\.(log|debug|info)\s*\(/) && !line.includes("// eslint-disable")) {
|
|
726
|
+
// Skip if it's in a catch block or error handler
|
|
727
|
+
const prevLines = lines.slice(Math.max(0, lineNumber - 3), lineNumber).join("\n");
|
|
728
|
+
if (!prevLines.includes("catch") && !prevLines.includes("error")) {
|
|
729
|
+
this.addIssue({
|
|
730
|
+
file: filePath,
|
|
731
|
+
line: lineNumber,
|
|
732
|
+
type: isComponentFile ? "warning" : "info",
|
|
733
|
+
category: "code-quality",
|
|
734
|
+
message: "Console statement detected",
|
|
735
|
+
suggestion: "Use logger from @/lib/debug-logger for structured logging",
|
|
736
|
+
autoFixable: true,
|
|
737
|
+
fixData: { type: "remove-console" },
|
|
738
|
+
});
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
// Empty catch blocks
|
|
742
|
+
if (line.match(/catch\s*\([^)]*\)\s*{\s*}/) || line.match(/catch\s*{\s*}/)) {
|
|
743
|
+
this.addIssue({
|
|
744
|
+
file: filePath,
|
|
745
|
+
line: lineNumber,
|
|
746
|
+
type: "warning",
|
|
747
|
+
category: "code-quality",
|
|
748
|
+
message: "Empty catch block detected",
|
|
749
|
+
suggestion: "Handle errors properly or use logger.error() to log them",
|
|
750
|
+
});
|
|
751
|
+
}
|
|
752
|
+
// Hardcoded API URLs
|
|
753
|
+
if (line.match(/['"]https?:\/\/[^'"]+['"]/) && !filePath.includes("constants")) {
|
|
754
|
+
// Skip common allowed patterns
|
|
755
|
+
if (!line.includes("localhost") &&
|
|
756
|
+
!line.includes("example.com") &&
|
|
757
|
+
!line.includes("placeholder") &&
|
|
758
|
+
!line.includes("schema.org") &&
|
|
759
|
+
!line.includes("w3.org") &&
|
|
760
|
+
!line.includes("googleapis.com") // Common external APIs
|
|
761
|
+
) {
|
|
762
|
+
this.addIssue({
|
|
763
|
+
file: filePath,
|
|
764
|
+
line: lineNumber,
|
|
765
|
+
type: "info",
|
|
766
|
+
category: "code-quality",
|
|
767
|
+
message: "Hardcoded URL detected",
|
|
768
|
+
suggestion: "Consider moving to environment variables or constants file",
|
|
769
|
+
});
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
// Magic numbers (only in component files)
|
|
773
|
+
if (isComponentFile && !isApiRoute) {
|
|
774
|
+
// Look for standalone numbers that aren't common values
|
|
775
|
+
const magicNumberMatch = line.match(/[^a-zA-Z0-9_](\d{3,})[^a-zA-Z0-9_]/);
|
|
776
|
+
if (magicNumberMatch) {
|
|
777
|
+
const num = parseInt(magicNumberMatch[1], 10);
|
|
778
|
+
// Skip common values like 100, 200, 300, 400, 500, 1000, etc.
|
|
779
|
+
const commonValues = [100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1024, 2048];
|
|
780
|
+
if (!commonValues.includes(num) && num > 100) {
|
|
781
|
+
// Skip if it's in a className (Tailwind)
|
|
782
|
+
if (!line.includes("className") && !line.includes("style")) {
|
|
783
|
+
this.addIssue({
|
|
784
|
+
file: filePath,
|
|
785
|
+
line: lineNumber,
|
|
786
|
+
type: "info",
|
|
787
|
+
category: "code-quality",
|
|
788
|
+
message: `Magic number ${num} detected`,
|
|
789
|
+
suggestion: "Consider extracting to a named constant for clarity",
|
|
790
|
+
});
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
// Inline styles (should use Tailwind or CSS modules)
|
|
796
|
+
if (isComponentFile && line.match(/style=\{\{[^}]+\}\}/)) {
|
|
797
|
+
// Skip if it's a dynamic style that can't be done with Tailwind
|
|
798
|
+
if (!line.includes("width:") &&
|
|
799
|
+
!line.includes("height:") &&
|
|
800
|
+
!line.includes("transform") &&
|
|
801
|
+
!line.includes("--") // CSS variables
|
|
802
|
+
) {
|
|
803
|
+
this.addIssue({
|
|
804
|
+
file: filePath,
|
|
805
|
+
line: lineNumber,
|
|
806
|
+
type: "info",
|
|
807
|
+
category: "code-quality",
|
|
808
|
+
message: "Inline style object detected",
|
|
809
|
+
suggestion: "Prefer Tailwind classes or CSS modules for styling",
|
|
810
|
+
});
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
// TODO/FIXME comments (info level)
|
|
814
|
+
if (line.match(/\/\/\s*(TODO|FIXME|HACK|XXX):/i)) {
|
|
815
|
+
this.addIssue({
|
|
816
|
+
file: filePath,
|
|
817
|
+
line: lineNumber,
|
|
818
|
+
type: "info",
|
|
819
|
+
category: "code-quality",
|
|
820
|
+
message: "TODO/FIXME comment detected",
|
|
821
|
+
suggestion: "Consider creating a ticket to track this work",
|
|
822
|
+
});
|
|
823
|
+
}
|
|
824
|
+
// any type usage (skip files where it's acceptable)
|
|
825
|
+
// Match: `: any`, `<any>`, `as any` (with word boundary to avoid "has any")
|
|
826
|
+
if (line.match(/:\s*any\b/) || line.match(/<any>/) || line.match(/\bas\s+any\b/)) {
|
|
827
|
+
// Skip comments
|
|
828
|
+
if (line.trim().startsWith("//") ||
|
|
829
|
+
line.trim().startsWith("*") ||
|
|
830
|
+
line.trim().startsWith("/*")) {
|
|
831
|
+
return;
|
|
832
|
+
}
|
|
833
|
+
// Skip if previous line has eslint-disable comment for any
|
|
834
|
+
const prevLine = lines[lineNumber - 2] || "";
|
|
835
|
+
if (prevLine.includes("eslint-disable") && prevLine.includes("any")) {
|
|
836
|
+
return;
|
|
837
|
+
}
|
|
838
|
+
// Skip if line itself has eslint-disable inline
|
|
839
|
+
if (line.includes("eslint-disable")) {
|
|
840
|
+
return;
|
|
841
|
+
}
|
|
842
|
+
// Check if this file is in the allowed list
|
|
843
|
+
const isAllowed = ANY_TYPE_ALLOWED_PATTERNS.some((pattern) => pattern.test(filePath));
|
|
844
|
+
if (!isAllowed) {
|
|
845
|
+
this.addIssue({
|
|
846
|
+
file: filePath,
|
|
847
|
+
line: lineNumber,
|
|
848
|
+
type: "warning",
|
|
849
|
+
category: "code-quality",
|
|
850
|
+
message: "TypeScript 'any' type detected",
|
|
851
|
+
suggestion: "Use proper typing or 'unknown' with type guards",
|
|
852
|
+
autoFixable: true,
|
|
853
|
+
fixData: { type: "add-preflight-ignore" },
|
|
854
|
+
});
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
// Non-null assertion (!)
|
|
858
|
+
if (line.match(/\w+!\./)) {
|
|
859
|
+
this.addIssue({
|
|
860
|
+
file: filePath,
|
|
861
|
+
line: lineNumber,
|
|
862
|
+
type: "info",
|
|
863
|
+
category: "code-quality",
|
|
864
|
+
message: "Non-null assertion (!) detected",
|
|
865
|
+
suggestion: "Consider using optional chaining (?.) or proper null checks",
|
|
866
|
+
});
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
checkDeprecatedComponents(line, lineNumber, filePath) {
|
|
870
|
+
// Check for imports of deprecated components from @/components/shared
|
|
871
|
+
if (line.includes("@/components/shared") ||
|
|
872
|
+
line.includes("from './") ||
|
|
873
|
+
line.includes('from "../')) {
|
|
874
|
+
for (const deprecated of DEPRECATED_COMPONENTS) {
|
|
875
|
+
// Match import { DeprecatedName } or import { DeprecatedName, ... }
|
|
876
|
+
const importPattern = new RegExp(`\\b${deprecated.name}\\b`);
|
|
877
|
+
if (importPattern.test(line) && line.includes("import")) {
|
|
878
|
+
// Skip if it's the replacement being imported
|
|
879
|
+
if (line.includes(deprecated.replacement.split(" ")[0])) {
|
|
880
|
+
continue;
|
|
881
|
+
}
|
|
882
|
+
this.addIssue({
|
|
883
|
+
file: filePath,
|
|
884
|
+
line: lineNumber,
|
|
885
|
+
type: "warning",
|
|
886
|
+
category: "deprecated-component",
|
|
887
|
+
message: `Deprecated component: ${deprecated.name}`,
|
|
888
|
+
suggestion: `Use ${deprecated.replacement} instead`,
|
|
889
|
+
});
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
checkDateFnsUsage(line, lineNumber, filePath) {
|
|
895
|
+
// Check for direct date-fns imports
|
|
896
|
+
if (line.match(/from\s+['"]date-fns['"]/)) {
|
|
897
|
+
// Skip if it's in a utility file that wraps date-fns
|
|
898
|
+
if (filePath.includes("lib/utils") || filePath.includes("lib/format")) {
|
|
899
|
+
return;
|
|
900
|
+
}
|
|
901
|
+
this.addIssue({
|
|
902
|
+
file: filePath,
|
|
903
|
+
line: lineNumber,
|
|
904
|
+
type: "info",
|
|
905
|
+
category: "date-pattern",
|
|
906
|
+
message: "Direct date-fns import detected",
|
|
907
|
+
suggestion: "Consider using formatDate/formatRelativeTime from @/lib/utils/format for consistency",
|
|
908
|
+
});
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
checkAccessibility(line, lineNumber, filePath) {
|
|
912
|
+
// Only check component files
|
|
913
|
+
if (!filePath.endsWith(".tsx"))
|
|
914
|
+
return;
|
|
915
|
+
// Image without alt
|
|
916
|
+
if (line.match(/<img\s/) && !line.includes("alt=")) {
|
|
917
|
+
this.addIssue({
|
|
918
|
+
file: filePath,
|
|
919
|
+
line: lineNumber,
|
|
920
|
+
type: "warning",
|
|
921
|
+
category: "accessibility",
|
|
922
|
+
message: "Image without alt attribute",
|
|
923
|
+
suggestion: 'Add alt text for accessibility (use alt="" for decorative images)',
|
|
924
|
+
});
|
|
925
|
+
}
|
|
926
|
+
// Button without type
|
|
927
|
+
if (line.match(/<button\s/) && !line.includes("type=")) {
|
|
928
|
+
this.addIssue({
|
|
929
|
+
file: filePath,
|
|
930
|
+
line: lineNumber,
|
|
931
|
+
type: "info",
|
|
932
|
+
category: "accessibility",
|
|
933
|
+
message: "Button without explicit type attribute",
|
|
934
|
+
suggestion: 'Add type="button" or type="submit" to prevent form submission issues',
|
|
935
|
+
});
|
|
936
|
+
}
|
|
937
|
+
// onClick on non-interactive element without role
|
|
938
|
+
if (line.match(/onClick=\{/) && line.match(/<(div|span|p)\s/) && !line.includes("role=")) {
|
|
939
|
+
this.addIssue({
|
|
940
|
+
file: filePath,
|
|
941
|
+
line: lineNumber,
|
|
942
|
+
type: "warning",
|
|
943
|
+
category: "accessibility",
|
|
944
|
+
message: "Click handler on non-interactive element without role",
|
|
945
|
+
suggestion: 'Add role="button" and tabIndex={0} for keyboard accessibility, or use <button>',
|
|
946
|
+
});
|
|
947
|
+
}
|
|
948
|
+
// Form input without label association
|
|
949
|
+
if (line.match(/<(input|select|textarea)\s/) &&
|
|
950
|
+
!line.includes("aria-label") &&
|
|
951
|
+
!line.includes("id=")) {
|
|
952
|
+
this.addIssue({
|
|
953
|
+
file: filePath,
|
|
954
|
+
line: lineNumber,
|
|
955
|
+
type: "info",
|
|
956
|
+
category: "accessibility",
|
|
957
|
+
message: "Form input may lack label association",
|
|
958
|
+
suggestion: "Add aria-label or associate with <label htmlFor>",
|
|
959
|
+
});
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
checkPerformancePatterns(line, lineNumber, filePath, lines) {
|
|
963
|
+
// Only check component files
|
|
964
|
+
if (!filePath.endsWith(".tsx"))
|
|
965
|
+
return;
|
|
966
|
+
// Large array map without key
|
|
967
|
+
if (line.match(/\.map\s*\(\s*\([^)]*\)\s*=>\s*[(<]/) && !line.includes("key=")) {
|
|
968
|
+
// Check next few lines for key
|
|
969
|
+
const nextLines = lines.slice(lineNumber, lineNumber + 3).join("\n");
|
|
970
|
+
if (!nextLines.includes("key=")) {
|
|
971
|
+
this.addIssue({
|
|
972
|
+
file: filePath,
|
|
973
|
+
line: lineNumber,
|
|
974
|
+
type: "info",
|
|
975
|
+
category: "performance",
|
|
976
|
+
message: "Array map may be missing key prop",
|
|
977
|
+
suggestion: "Add key prop to mapped elements for React reconciliation",
|
|
978
|
+
});
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
// Inline object/array in JSX props (causes re-renders)
|
|
982
|
+
if (line.match(/\s(style|sx)=\{\{/) && !line.includes("useMemo")) {
|
|
983
|
+
// Skip simple cases
|
|
984
|
+
if (!line.match(/\{\{[^}]{50,}\}\}/)) {
|
|
985
|
+
return; // Skip short inline styles
|
|
986
|
+
}
|
|
987
|
+
this.addIssue({
|
|
988
|
+
file: filePath,
|
|
989
|
+
line: lineNumber,
|
|
990
|
+
type: "info",
|
|
991
|
+
category: "performance",
|
|
992
|
+
message: "Complex inline style object may cause re-renders",
|
|
993
|
+
suggestion: "Extract to useMemo or move outside component",
|
|
994
|
+
});
|
|
995
|
+
}
|
|
996
|
+
// Anonymous function in JSX event handler (common but worth noting for hot paths)
|
|
997
|
+
if (line.match(/on[A-Z]\w+=\{\s*\(\)\s*=>\s*\{/)) {
|
|
998
|
+
// Only flag if it looks like a complex handler
|
|
999
|
+
const nextLines = lines.slice(lineNumber, lineNumber + 5).join("\n");
|
|
1000
|
+
if (nextLines.includes("await") ||
|
|
1001
|
+
nextLines.includes("fetch") ||
|
|
1002
|
+
nextLines.includes("setState")) {
|
|
1003
|
+
this.addIssue({
|
|
1004
|
+
file: filePath,
|
|
1005
|
+
line: lineNumber,
|
|
1006
|
+
type: "info",
|
|
1007
|
+
category: "performance",
|
|
1008
|
+
message: "Inline async handler in JSX",
|
|
1009
|
+
suggestion: "Consider extracting to useCallback for memoized components",
|
|
1010
|
+
});
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
// AUTO-FIX
|
|
1015
|
+
async applyFixes() {
|
|
1016
|
+
const fixableIssues = this.issues.filter((i) => i.autoFixable && i.fixData);
|
|
1017
|
+
if (fixableIssues.length === 0) {
|
|
1018
|
+
console.log(`\n${console_chars_1.emoji.hint} No auto-fixable issues found.\n`);
|
|
1019
|
+
return;
|
|
1020
|
+
}
|
|
1021
|
+
console.log(`\n${console_chars_1.emoji.warning} Applying ${fixableIssues.length} auto-fixes...\n`);
|
|
1022
|
+
// Group fixes by file to apply them efficiently
|
|
1023
|
+
const fixesByFile = new Map();
|
|
1024
|
+
for (const issue of fixableIssues) {
|
|
1025
|
+
const existing = fixesByFile.get(issue.file) || [];
|
|
1026
|
+
existing.push(issue);
|
|
1027
|
+
fixesByFile.set(issue.file, existing);
|
|
1028
|
+
}
|
|
1029
|
+
let fixesApplied = 0;
|
|
1030
|
+
let fixesFailed = 0;
|
|
1031
|
+
for (const [filePath, issues] of fixesByFile) {
|
|
1032
|
+
try {
|
|
1033
|
+
const result = await this.applyFixesToFile(filePath, issues);
|
|
1034
|
+
fixesApplied += result.applied;
|
|
1035
|
+
fixesFailed += result.failed;
|
|
1036
|
+
}
|
|
1037
|
+
catch (error) {
|
|
1038
|
+
console.log(` ${console_chars_1.emoji.error} Failed to fix ${filePath}: ${error}`);
|
|
1039
|
+
fixesFailed += issues.length;
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
this.stats.fixesApplied = fixesApplied;
|
|
1043
|
+
this.stats.fixesFailed = fixesFailed;
|
|
1044
|
+
console.log(`\n${console_chars_1.emoji.success} Fixes applied: ${fixesApplied}`);
|
|
1045
|
+
if (fixesFailed > 0) {
|
|
1046
|
+
console.log(`${console_chars_1.emoji.error} Fixes failed: ${fixesFailed}`);
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
async applyFixesToFile(filePath, issues) {
|
|
1050
|
+
let content = fs.readFileSync(filePath, "utf-8");
|
|
1051
|
+
const lines = content.split("\n");
|
|
1052
|
+
let applied = 0;
|
|
1053
|
+
let failed = 0;
|
|
1054
|
+
// Sort issues by line number descending so we can modify from bottom to top
|
|
1055
|
+
// This prevents line number shifts from affecting subsequent fixes
|
|
1056
|
+
const sortedIssues = [...issues].sort((a, b) => b.line - a.line);
|
|
1057
|
+
for (const issue of sortedIssues) {
|
|
1058
|
+
if (!issue.fixData) {
|
|
1059
|
+
failed++;
|
|
1060
|
+
continue;
|
|
1061
|
+
}
|
|
1062
|
+
try {
|
|
1063
|
+
const lineIndex = issue.line - 1;
|
|
1064
|
+
switch (issue.fixData.type) {
|
|
1065
|
+
case "remove-line":
|
|
1066
|
+
lines.splice(lineIndex, 1);
|
|
1067
|
+
console.log(` ${console_chars_1.emoji.success} Removed line ${issue.line} in ${filePath}`);
|
|
1068
|
+
applied++;
|
|
1069
|
+
break;
|
|
1070
|
+
case "replace-line":
|
|
1071
|
+
if (issue.fixData.replacement !== undefined) {
|
|
1072
|
+
lines[lineIndex] = issue.fixData.replacement;
|
|
1073
|
+
console.log(` ${console_chars_1.emoji.success} Replaced line ${issue.line} in ${filePath}`);
|
|
1074
|
+
applied++;
|
|
1075
|
+
}
|
|
1076
|
+
else {
|
|
1077
|
+
failed++;
|
|
1078
|
+
}
|
|
1079
|
+
break;
|
|
1080
|
+
case "replace-import":
|
|
1081
|
+
if (issue.fixData.replacement !== undefined) {
|
|
1082
|
+
lines[lineIndex] = issue.fixData.replacement;
|
|
1083
|
+
console.log(` ${console_chars_1.emoji.success} Replaced import at line ${issue.line} in ${filePath}`);
|
|
1084
|
+
applied++;
|
|
1085
|
+
}
|
|
1086
|
+
else {
|
|
1087
|
+
failed++;
|
|
1088
|
+
}
|
|
1089
|
+
break;
|
|
1090
|
+
case "add-import":
|
|
1091
|
+
if (issue.fixData.importName && issue.fixData.importPath) {
|
|
1092
|
+
// Find the last import line
|
|
1093
|
+
let lastImportIndex = -1;
|
|
1094
|
+
for (let i = 0; i < lines.length; i++) {
|
|
1095
|
+
if (lines[i].startsWith("import ") || lines[i].match(/^import\s*{/)) {
|
|
1096
|
+
lastImportIndex = i;
|
|
1097
|
+
}
|
|
1098
|
+
import { createUniversalProgressReporter } from "../system/universal-progress-reporter";
|
|
1099
|
+
}
|
|
1100
|
+
const newImport = `import { ${issue.fixData.importName} } from "${issue.fixData.importPath}";`;
|
|
1101
|
+
if (lastImportIndex >= 0) {
|
|
1102
|
+
lines.splice(lastImportIndex + 1, 0, newImport);
|
|
1103
|
+
}
|
|
1104
|
+
else {
|
|
1105
|
+
// No imports found, add at top after "use client" if present
|
|
1106
|
+
const useClientIndex = lines.findIndex((l) => l.includes('"use client"'));
|
|
1107
|
+
lines.splice(useClientIndex >= 0 ? useClientIndex + 1 : 0, 0, newImport);
|
|
1108
|
+
}
|
|
1109
|
+
console.log(` ${console_chars_1.emoji.success} Added import for ${issue.fixData.importName} in ${filePath}`);
|
|
1110
|
+
applied++;
|
|
1111
|
+
}
|
|
1112
|
+
else {
|
|
1113
|
+
failed++;
|
|
1114
|
+
}
|
|
1115
|
+
break;
|
|
1116
|
+
case "remove-console":
|
|
1117
|
+
// Remove console.log/debug/info statements
|
|
1118
|
+
const consoleLine = lines[lineIndex];
|
|
1119
|
+
if (consoleLine.match(/^\s*console\.(log|debug|info)\s*\(/)) {
|
|
1120
|
+
// Check if it's a single-line console statement
|
|
1121
|
+
if (consoleLine.includes(");")) {
|
|
1122
|
+
lines.splice(lineIndex, 1);
|
|
1123
|
+
console.log(` ${console_chars_1.emoji.success} Removed console statement at line ${issue.line} in ${filePath}`);
|
|
1124
|
+
applied++;
|
|
1125
|
+
}
|
|
1126
|
+
else {
|
|
1127
|
+
// Multi-line console - just comment it out for safety
|
|
1128
|
+
lines[lineIndex] = `// ${consoleLine} // TODO: Remove this console statement`;
|
|
1129
|
+
console.log(` ${console_chars_1.emoji.warning} Commented out console at line ${issue.line} in ${filePath} (multi-line)`);
|
|
1130
|
+
applied++;
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
else {
|
|
1134
|
+
failed++;
|
|
1135
|
+
}
|
|
1136
|
+
break;
|
|
1137
|
+
case "add-preflight-ignore":
|
|
1138
|
+
// Add a preflight-ignore comment above the line
|
|
1139
|
+
const indent = lines[lineIndex].match(/^(\s*)/)?.[1] || "";
|
|
1140
|
+
lines.splice(lineIndex, 0, `${indent}// preflight-ignore - Auto-added`);
|
|
1141
|
+
console.log(` ${console_chars_1.emoji.success} Added preflight-ignore at line ${issue.line} in ${filePath}`);
|
|
1142
|
+
applied++;
|
|
1143
|
+
break;
|
|
1144
|
+
default:
|
|
1145
|
+
console.log(` ${console_chars_1.emoji.warning} Unknown fix type: ${issue.fixData.type}`);
|
|
1146
|
+
failed++;
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
catch (error) {
|
|
1150
|
+
console.log(` ${console_chars_1.emoji.error} Failed to apply fix at line ${issue.line}: ${error}`);
|
|
1151
|
+
failed++;
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
// Write the modified content back
|
|
1155
|
+
if (applied > 0) {
|
|
1156
|
+
fs.writeFileSync(filePath, lines.join("\n"));
|
|
1157
|
+
}
|
|
1158
|
+
return { applied, failed };
|
|
1159
|
+
}
|
|
1160
|
+
// HELPERS
|
|
1161
|
+
addIssue(issue) {
|
|
1162
|
+
// Skip info issues unless --info flag is set
|
|
1163
|
+
if (issue.type === "info" && !this.options.showInfo) {
|
|
1164
|
+
return;
|
|
1165
|
+
}
|
|
1166
|
+
this.issues.push(issue);
|
|
1167
|
+
}
|
|
1168
|
+
calculateStats() {
|
|
1169
|
+
this.stats.errors = this.issues.filter((i) => i.type === "error").length;
|
|
1170
|
+
this.stats.warnings = this.issues.filter((i) => i.type === "warning").length;
|
|
1171
|
+
this.stats.info = this.issues.filter((i) => i.type === "info").length;
|
|
1172
|
+
}
|
|
1173
|
+
// OUTPUT
|
|
1174
|
+
printResults() {
|
|
1175
|
+
if (this.issues.length === 0) {
|
|
1176
|
+
console.log(`${console_chars_1.emoji.success} All files use shared components correctly\n`);
|
|
1177
|
+
console.log(` Files checked: ${this.stats.filesChecked}`);
|
|
1178
|
+
console.log(` Files ignored: ${this.stats.ignoredFiles}`);
|
|
1179
|
+
console.log(` Lines ignored: ${this.stats.ignoredLines}`);
|
|
1180
|
+
return;
|
|
1181
|
+
}
|
|
1182
|
+
const errors = this.issues.filter((i) => i.type === "error");
|
|
1183
|
+
const warnings = this.issues.filter((i) => i.type === "warning");
|
|
1184
|
+
const infos = this.issues.filter((i) => i.type === "info");
|
|
1185
|
+
// Group issues by category
|
|
1186
|
+
const byCategory = new Map();
|
|
1187
|
+
this.issues.forEach((issue) => {
|
|
1188
|
+
const existing = byCategory.get(issue.category) || [];
|
|
1189
|
+
existing.push(issue);
|
|
1190
|
+
byCategory.set(issue.category, existing);
|
|
1191
|
+
});
|
|
1192
|
+
if (errors.length > 0) {
|
|
1193
|
+
console.log(`\n${console_chars_1.emoji.error} ERRORS (must fix):\n`);
|
|
1194
|
+
this.printIssueGroup(errors);
|
|
1195
|
+
}
|
|
1196
|
+
if (warnings.length > 0 && this.options.verbose) {
|
|
1197
|
+
console.log(`\n${console_chars_1.emoji.warning} WARNINGS (should fix):\n`);
|
|
1198
|
+
this.printIssueGroup(warnings);
|
|
1199
|
+
}
|
|
1200
|
+
if (infos.length > 0 && this.options.showInfo) {
|
|
1201
|
+
console.log(`\n${console_chars_1.emoji.hint} INFO (suggestions):\n`);
|
|
1202
|
+
this.printIssueGroup(infos);
|
|
1203
|
+
}
|
|
1204
|
+
console.log((0, console_chars_1.createDivider)(80, "heavy"));
|
|
1205
|
+
console.log(`\nSummary:`);
|
|
1206
|
+
console.log(` Files checked: ${this.stats.filesChecked}`);
|
|
1207
|
+
console.log(` Files ignored: ${this.stats.ignoredFiles}`);
|
|
1208
|
+
console.log(` Lines ignored: ${this.stats.ignoredLines}`);
|
|
1209
|
+
if (this.stats.fixesApplied !== undefined) {
|
|
1210
|
+
console.log(`\nAuto-fix results:`);
|
|
1211
|
+
console.log(` ${console_chars_1.emoji.success} Fixes applied: ${this.stats.fixesApplied}`);
|
|
1212
|
+
if (this.stats.fixesFailed && this.stats.fixesFailed > 0) {
|
|
1213
|
+
console.log(` ${console_chars_1.emoji.error} Fixes failed: ${this.stats.fixesFailed}`);
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
console.log(`\nIssues by severity:`);
|
|
1217
|
+
console.log(` ${console_chars_1.emoji.error} Errors: ${errors.length}`);
|
|
1218
|
+
console.log(` ${console_chars_1.emoji.warning} Warnings: ${warnings.length}`);
|
|
1219
|
+
console.log(` ${console_chars_1.emoji.hint} Info: ${infos.length}`);
|
|
1220
|
+
// Show auto-fixable count if not in fix mode
|
|
1221
|
+
if (!this.options.fix) {
|
|
1222
|
+
const fixableCount = this.issues.filter((i) => i.autoFixable).length;
|
|
1223
|
+
if (fixableCount > 0) {
|
|
1224
|
+
console.log(`\n ${console_chars_1.emoji.hint} ${fixableCount} issues are auto-fixable with --fix`);
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1227
|
+
console.log(`\nIssues by category:`);
|
|
1228
|
+
byCategory.forEach((issues, category) => {
|
|
1229
|
+
console.log(` ${category}: ${issues.length}`);
|
|
1230
|
+
});
|
|
1231
|
+
console.log((0, console_chars_1.createDivider)(80, "heavy"));
|
|
1232
|
+
if (errors.length > 0) {
|
|
1233
|
+
console.log(`\n${console_chars_1.emoji.error} SHARED COMPONENTS CHECK FAILED`);
|
|
1234
|
+
console.log(" Fix errors to maintain consistency\n");
|
|
1235
|
+
}
|
|
1236
|
+
else if (warnings.length > 0) {
|
|
1237
|
+
console.log(`\n${console_chars_1.emoji.success} SHARED COMPONENTS CHECK PASSED (with warnings)`);
|
|
1238
|
+
console.log(" Run with --verbose to see warnings\n");
|
|
1239
|
+
}
|
|
1240
|
+
else {
|
|
1241
|
+
console.log(`\n${console_chars_1.emoji.success} SHARED COMPONENTS CHECK PASSED\n`);
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
printIssueGroup(issues) {
|
|
1245
|
+
issues.forEach((issue) => {
|
|
1246
|
+
console.log(` ${issue.file}:${issue.line}`);
|
|
1247
|
+
console.log(` [${issue.category}] ${issue.message}`);
|
|
1248
|
+
if (issue.suggestion) {
|
|
1249
|
+
console.log(` ${console_chars_1.emoji.hint} ${issue.suggestion}`);
|
|
1250
|
+
}
|
|
1251
|
+
if (issue.autoFixable) {
|
|
1252
|
+
console.log(` ${console_chars_1.emoji.success} Auto-fixable with --fix`);
|
|
1253
|
+
}
|
|
1254
|
+
console.log();
|
|
1255
|
+
});
|
|
1256
|
+
}
|
|
1257
|
+
outputJsonReport() {
|
|
1258
|
+
const report = {
|
|
1259
|
+
timestamp: new Date().toISOString(),
|
|
1260
|
+
passed: this.stats.errors === 0,
|
|
1261
|
+
stats: this.stats,
|
|
1262
|
+
issues: this.issues,
|
|
1263
|
+
categories: [...new Set(this.issues.map((i) => i.category))],
|
|
1264
|
+
};
|
|
1265
|
+
const reportPath = path.join(process.cwd(), "shared-component-report.json");
|
|
1266
|
+
fs.writeFileSync(reportPath, JSON.stringify(report, null, 2));
|
|
1267
|
+
console.log(`\n${console_chars_1.emoji.success} JSON report written to: ${reportPath}`);
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
exports.SharedComponentsChecker = SharedComponentsChecker;
|
|
1271
|
+
// MAIN
|
|
1272
|
+
async function main() {
|
|
1273
|
+
const reporter = createUniversalProgressReporter(exports.name);
|
|
1274
|
+
const args = process.argv.slice(2);
|
|
1275
|
+
const options = {
|
|
1276
|
+
verbose: args.includes("--verbose") || args.includes("-v"),
|
|
1277
|
+
report: args.includes("--report"),
|
|
1278
|
+
fix: args.includes("--fix"),
|
|
1279
|
+
showInfo: args.includes("--info"),
|
|
1280
|
+
};
|
|
1281
|
+
const checker = new SharedComponentsChecker(options);
|
|
1282
|
+
const result = await checker.check();
|
|
1283
|
+
process.exit(result.passed ? 0 : 1);
|
|
1284
|
+
}
|
|
1285
|
+
if (require.main === module) {
|
|
1286
|
+
main();
|
|
1287
|
+
}
|
|
1288
|
+
//# sourceMappingURL=shared-components-migration.js.map
|