@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,1736 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* UI Quality Preflight Checks
|
|
5
|
+
* Comprehensive UI consistency, design tokens, and accessibility validation
|
|
6
|
+
*/
|
|
7
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
+
if (k2 === undefined) k2 = k;
|
|
9
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
+
}
|
|
13
|
+
Object.defineProperty(o, k2, desc);
|
|
14
|
+
}) : (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
o[k2] = m[k];
|
|
17
|
+
}));
|
|
18
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
19
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
20
|
+
}) : function(o, v) {
|
|
21
|
+
o["default"] = v;
|
|
22
|
+
});
|
|
23
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
24
|
+
var ownKeys = function(o) {
|
|
25
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
26
|
+
var ar = [];
|
|
27
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
28
|
+
return ar;
|
|
29
|
+
};
|
|
30
|
+
return ownKeys(o);
|
|
31
|
+
};
|
|
32
|
+
return function (mod) {
|
|
33
|
+
if (mod && mod.__esModule) return mod;
|
|
34
|
+
var result = {};
|
|
35
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
36
|
+
__setModuleDefault(result, mod);
|
|
37
|
+
return result;
|
|
38
|
+
};
|
|
39
|
+
})();
|
|
40
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
|
+
// import { validateHeaderSpacing } from '../specialized/header-spacing-validation'; // Module not yet implemented
|
|
42
|
+
const console_chars_1 = require("../../utils/console-chars");
|
|
43
|
+
const unified_badge_consistency_1 = require("../specialized/unified-badge-consistency");
|
|
44
|
+
const file_scanner_1 = require("../../utils/file-scanner");
|
|
45
|
+
const preflight_runner_1 = require("../../utils/preflight-runner");
|
|
46
|
+
const validation_helpers_1 = require("../../utils/validation-helpers");
|
|
47
|
+
async function runUIQualityPreflights() {
|
|
48
|
+
const runner = new preflight_runner_1.PreflightRunner(true);
|
|
49
|
+
const scanner = new file_scanner_1.FileScanner();
|
|
50
|
+
// File Naming Conventions
|
|
51
|
+
runner.addCheck((0, preflight_runner_1.createCheck)("File Naming Conventions", "Validate kebab-case and PascalCase naming patterns", async () => {
|
|
52
|
+
return await (0, validation_helpers_1.validateFileNaming)();
|
|
53
|
+
}));
|
|
54
|
+
// Design Tokens Usage
|
|
55
|
+
runner.addCheck((0, preflight_runner_1.createCheck)("Design Tokens Usage", "Validate consistent use of design tokens instead of hardcoded values", async () => {
|
|
56
|
+
const errors = [];
|
|
57
|
+
const warnings = [];
|
|
58
|
+
const info = [];
|
|
59
|
+
const componentFiles = await scanner.findComponentFiles();
|
|
60
|
+
const hardcodedPatterns = [
|
|
61
|
+
// Pixel values (non-responsive)
|
|
62
|
+
/padding:\s*['"]?\d+px['"]?/g,
|
|
63
|
+
/margin:\s*['"]?\d+px['"]?/g,
|
|
64
|
+
/fontSize:\s*['"]?\d+px['"]?/g,
|
|
65
|
+
/width:\s*['"]?\d+px['"]?/g,
|
|
66
|
+
/height:\s*['"]?\d+px['"]?/g,
|
|
67
|
+
/top:\s*['"]?\d+px['"]?/g,
|
|
68
|
+
/bottom:\s*['"]?\d+px['"]?/g,
|
|
69
|
+
/left:\s*['"]?\d+px['"]?/g,
|
|
70
|
+
/right:\s*['"]?\d+px['"]?/g,
|
|
71
|
+
/gap:\s*['"]?\d+px['"]?/g,
|
|
72
|
+
/borderRadius:\s*['"]?\d+px['"]?/g,
|
|
73
|
+
/lineHeight:\s*['"]?\d+px['"]?/g,
|
|
74
|
+
/letterSpacing:\s*['"]?\d+px['"]?/g,
|
|
75
|
+
/textIndent:\s*['"]?\d+px['"]?/g,
|
|
76
|
+
/boxShadow:\s*['"][^"]*\d+px[^"]*['"]?/g,
|
|
77
|
+
/border:\s*['"][^"]*\d+px[^"]*['"]?/g,
|
|
78
|
+
/outline:\s*['"][^"]*\d+px[^"]*['"]?/g,
|
|
79
|
+
// Material-UI sx prop pixel values
|
|
80
|
+
/(?:mt|mb|ml|mr|mx|my|pt|pb|pl|pr|px|py):\s*['"]?\d+px['"]?/g,
|
|
81
|
+
// Hardcoded hex colors
|
|
82
|
+
/color:\s*['"]?#[0-9a-fA-F]{6}['"]?/g,
|
|
83
|
+
/backgroundColor:\s*['"]?#[0-9a-fA-F]{6}['"]?/g,
|
|
84
|
+
/borderColor:\s*['"]?#[0-9a-fA-F]{6}['"]?/g,
|
|
85
|
+
];
|
|
86
|
+
let totalHardcoded = 0;
|
|
87
|
+
for (const file of componentFiles) {
|
|
88
|
+
const content = await scanner.readFileContent(file.path);
|
|
89
|
+
if (!content)
|
|
90
|
+
continue;
|
|
91
|
+
let fileHardcoded = 0;
|
|
92
|
+
const fileViolations = [];
|
|
93
|
+
for (const pattern of hardcodedPatterns) {
|
|
94
|
+
const matches = content.match(pattern);
|
|
95
|
+
if (matches) {
|
|
96
|
+
fileHardcoded += matches.length;
|
|
97
|
+
fileViolations.push(...matches);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (fileHardcoded > 0) {
|
|
101
|
+
warnings.push(`${file.relativePath} has ${fileHardcoded} hardcoded style values (including non-responsive px units)`);
|
|
102
|
+
fileViolations.slice(0, 3).forEach((violation) => {
|
|
103
|
+
warnings.push(` - VIOLATION: ${violation}`);
|
|
104
|
+
});
|
|
105
|
+
if (fileViolations.length > 3) {
|
|
106
|
+
warnings.push(` - ... and ${fileViolations.length - 3} more violations`);
|
|
107
|
+
}
|
|
108
|
+
totalHardcoded += fileHardcoded;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
if (totalHardcoded === 0) {
|
|
112
|
+
info.push("${chars.check} No hardcoded style values or non-responsive px units detected");
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
info.push(`Found ${totalHardcoded} hardcoded style values (including non-responsive px units) across ${componentFiles.length} files`);
|
|
116
|
+
info.push("REQUIRED: Replace px values with responsive units (rem, em, %, vw, vh) or design tokens");
|
|
117
|
+
info.push('EXAMPLES: "16px" ${chars.arrow} "1rem", "24px" → "var(--spacing-6)", "320px" → "20rem"');
|
|
118
|
+
}
|
|
119
|
+
return { passed: errors.length === 0, errors, warnings, info };
|
|
120
|
+
}));
|
|
121
|
+
// Component Consistency
|
|
122
|
+
runner.addCheck((0, preflight_runner_1.createCheck)("Component Consistency", "Validate consistent component patterns and structure", async () => {
|
|
123
|
+
const errors = [];
|
|
124
|
+
const warnings = [];
|
|
125
|
+
const info = [];
|
|
126
|
+
const componentFiles = await scanner.findComponentFiles();
|
|
127
|
+
for (const file of componentFiles) {
|
|
128
|
+
const content = await scanner.readFileContent(file.path);
|
|
129
|
+
if (!content)
|
|
130
|
+
continue;
|
|
131
|
+
// Check for proper TypeScript interfaces
|
|
132
|
+
if (content.includes("interface ") && content.includes("Props")) {
|
|
133
|
+
info.push(`${console_chars_1.chars.check} ${file.name} has TypeScript interface`);
|
|
134
|
+
}
|
|
135
|
+
else if (file.extension === ".tsx") {
|
|
136
|
+
warnings.push(`${file.relativePath} may lack TypeScript interface for props`);
|
|
137
|
+
}
|
|
138
|
+
// Check for proper export patterns
|
|
139
|
+
if (content.includes("export default function") ||
|
|
140
|
+
content.includes("export default const")) {
|
|
141
|
+
info.push(`${console_chars_1.chars.check} ${file.name} uses proper export pattern`);
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
warnings.push(`${file.relativePath} may not use standard export pattern`);
|
|
145
|
+
}
|
|
146
|
+
// Check component size (should be under 400 lines)
|
|
147
|
+
const lineCount = content.split("\n").length;
|
|
148
|
+
if (lineCount > 400) {
|
|
149
|
+
warnings.push(`${file.relativePath} is ${lineCount} lines - consider breaking into smaller components`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return { passed: errors.length === 0, errors, warnings, info };
|
|
153
|
+
}));
|
|
154
|
+
// Accessibility Validation
|
|
155
|
+
runner.addCheck((0, preflight_runner_1.createCheck)("Accessibility Validation", "Check for accessibility best practices", async () => {
|
|
156
|
+
const errors = [];
|
|
157
|
+
const warnings = [];
|
|
158
|
+
const info = [];
|
|
159
|
+
const componentFiles = await scanner.findComponentFiles();
|
|
160
|
+
for (const file of componentFiles) {
|
|
161
|
+
const content = await scanner.readFileContent(file.path);
|
|
162
|
+
if (!content)
|
|
163
|
+
continue;
|
|
164
|
+
// Check for alt attributes on images
|
|
165
|
+
const imgTags = content.match(/<img[^>]*>/g);
|
|
166
|
+
if (imgTags) {
|
|
167
|
+
for (const img of imgTags) {
|
|
168
|
+
if (!img.includes("alt=")) {
|
|
169
|
+
warnings.push(`${file.relativePath} has img tag without alt attribute`);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
// Check for aria-label or aria-labelledby on interactive elements
|
|
174
|
+
const interactiveElements = ["button", "input", "select", "textarea"];
|
|
175
|
+
for (const element of interactiveElements) {
|
|
176
|
+
const elementRegex = new RegExp(`<${element}[^>]*>`, "g");
|
|
177
|
+
const elements = content.match(elementRegex);
|
|
178
|
+
if (elements) {
|
|
179
|
+
for (const el of elements) {
|
|
180
|
+
if (!el.includes("aria-label") &&
|
|
181
|
+
!el.includes("aria-labelledby") &&
|
|
182
|
+
!el.includes("aria-describedby") &&
|
|
183
|
+
element !== "input") {
|
|
184
|
+
warnings.push(`${file.relativePath} has ${element} without aria attributes`);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
// Check for semantic HTML usage
|
|
190
|
+
const semanticElements = ["header", "nav", "main", "section", "article", "aside", "footer"];
|
|
191
|
+
const hasSemanticHTML = semanticElements.some((element) => content.includes(`<${element}`));
|
|
192
|
+
if (hasSemanticHTML) {
|
|
193
|
+
info.push(`${console_chars_1.chars.check} ${file.name} uses semantic HTML`);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return { passed: errors.length === 0, errors, warnings, info };
|
|
197
|
+
}));
|
|
198
|
+
// Color Contrast Validation
|
|
199
|
+
runner.addCheck((0, preflight_runner_1.createCheck)("Color Contrast", "Validate color contrast ratios for accessibility", async () => {
|
|
200
|
+
const errors = [];
|
|
201
|
+
const warnings = [];
|
|
202
|
+
const info = [];
|
|
203
|
+
// Check for CSS files with color definitions
|
|
204
|
+
const styleFiles = await scanner.findFiles(/\.(css|scss|sass)$/);
|
|
205
|
+
for (const file of styleFiles) {
|
|
206
|
+
const content = await scanner.readFileContent(file.path);
|
|
207
|
+
if (!content)
|
|
208
|
+
continue;
|
|
209
|
+
// Look for color definitions
|
|
210
|
+
const colorPattern = /color:\s*#[0-9a-fA-F]{6}/g;
|
|
211
|
+
const backgroundPattern = /background-color:\s*#[0-9a-fA-F]{6}/g;
|
|
212
|
+
const colors = content.match(colorPattern);
|
|
213
|
+
const backgrounds = content.match(backgroundPattern);
|
|
214
|
+
if (colors || backgrounds) {
|
|
215
|
+
info.push(`${file.name} contains color definitions - manual contrast check recommended`);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
// Check for common low-contrast combinations
|
|
219
|
+
const lowContrastPatterns = [
|
|
220
|
+
/#ffffff.*#f0f0f0/g, // White on light gray
|
|
221
|
+
/#000000.*#333333/g, // Black on dark gray
|
|
222
|
+
/#cccccc.*#ffffff/g, // Light gray on white
|
|
223
|
+
];
|
|
224
|
+
for (const file of styleFiles) {
|
|
225
|
+
const content = await scanner.readFileContent(file.path);
|
|
226
|
+
if (!content)
|
|
227
|
+
continue;
|
|
228
|
+
for (const pattern of lowContrastPatterns) {
|
|
229
|
+
if (pattern.test(content)) {
|
|
230
|
+
warnings.push(`${file.relativePath} may have low contrast color combinations`);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return { passed: errors.length === 0, errors, warnings, info };
|
|
235
|
+
}));
|
|
236
|
+
// Mobile Responsiveness
|
|
237
|
+
runner.addCheck((0, preflight_runner_1.createCheck)("Mobile Responsiveness", "Check for mobile-responsive design patterns", async () => {
|
|
238
|
+
const errors = [];
|
|
239
|
+
const warnings = [];
|
|
240
|
+
const info = [];
|
|
241
|
+
const styleFiles = await scanner.findFiles(/\.(css|scss|sass)$/);
|
|
242
|
+
const componentFiles = await scanner.findComponentFiles();
|
|
243
|
+
let hasMediaQueries = false;
|
|
244
|
+
let hasFlexbox = false;
|
|
245
|
+
let hasGrid = false;
|
|
246
|
+
// Check CSS files for responsive patterns
|
|
247
|
+
for (const file of styleFiles) {
|
|
248
|
+
const content = await scanner.readFileContent(file.path);
|
|
249
|
+
if (!content)
|
|
250
|
+
continue;
|
|
251
|
+
if (content.includes("@media")) {
|
|
252
|
+
hasMediaQueries = true;
|
|
253
|
+
info.push(`${console_chars_1.chars.check} ${file.name} contains media queries`);
|
|
254
|
+
}
|
|
255
|
+
if (content.includes("display: flex") || content.includes("display:flex")) {
|
|
256
|
+
hasFlexbox = true;
|
|
257
|
+
}
|
|
258
|
+
if (content.includes("display: grid") || content.includes("display:grid")) {
|
|
259
|
+
hasGrid = true;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
// Check component files for responsive patterns
|
|
263
|
+
for (const file of componentFiles) {
|
|
264
|
+
const content = await scanner.readFileContent(file.path);
|
|
265
|
+
if (!content)
|
|
266
|
+
continue;
|
|
267
|
+
// Check for Material-UI responsive props
|
|
268
|
+
if (content.includes("xs=") ||
|
|
269
|
+
content.includes("sm=") ||
|
|
270
|
+
content.includes("md=") ||
|
|
271
|
+
content.includes("lg=")) {
|
|
272
|
+
info.push(`${console_chars_1.chars.check} ${file.name} uses responsive grid props`);
|
|
273
|
+
}
|
|
274
|
+
// Check for responsive breakpoint usage
|
|
275
|
+
if (content.includes("useMediaQuery") || content.includes("breakpoints")) {
|
|
276
|
+
info.push(`${console_chars_1.chars.check} ${file.name} uses responsive breakpoints`);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
if (!hasMediaQueries) {
|
|
280
|
+
warnings.push("No media queries found - ensure mobile responsiveness");
|
|
281
|
+
}
|
|
282
|
+
if (hasFlexbox) {
|
|
283
|
+
info.push("${chars.check} Flexbox layout detected");
|
|
284
|
+
}
|
|
285
|
+
if (hasGrid) {
|
|
286
|
+
info.push("✓ CSS Grid layout detected");
|
|
287
|
+
}
|
|
288
|
+
return { passed: errors.length === 0, errors, warnings, info };
|
|
289
|
+
}));
|
|
290
|
+
// Typography Consistency
|
|
291
|
+
runner.addCheck((0, preflight_runner_1.createCheck)("Typography Consistency", "Validate consistent typography usage", async () => {
|
|
292
|
+
const errors = [];
|
|
293
|
+
const warnings = [];
|
|
294
|
+
const info = [];
|
|
295
|
+
const componentFiles = await scanner.findComponentFiles();
|
|
296
|
+
for (const file of componentFiles) {
|
|
297
|
+
const content = await scanner.readFileContent(file.path);
|
|
298
|
+
if (!content)
|
|
299
|
+
continue;
|
|
300
|
+
// Check for Material-UI Typography component usage
|
|
301
|
+
if (content.includes("<Typography")) {
|
|
302
|
+
info.push(`${console_chars_1.chars.check} ${file.name} uses Typography component`);
|
|
303
|
+
}
|
|
304
|
+
// Check for hardcoded font sizes
|
|
305
|
+
const fontSizePattern = /fontSize:\s*['"]?\d+px['"]?/g;
|
|
306
|
+
const hardcodedSizes = content.match(fontSizePattern);
|
|
307
|
+
if (hardcodedSizes) {
|
|
308
|
+
warnings.push(`${file.relativePath} has ${hardcodedSizes.length} hardcoded font sizes`);
|
|
309
|
+
}
|
|
310
|
+
// Check for proper heading hierarchy
|
|
311
|
+
const headingPattern = /<h[1-6]/g;
|
|
312
|
+
const headings = content.match(headingPattern);
|
|
313
|
+
if (headings && headings.length > 0) {
|
|
314
|
+
info.push(`${console_chars_1.chars.check} ${file.name} uses semantic headings`);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
return { passed: errors.length === 0, errors, warnings, info };
|
|
318
|
+
}));
|
|
319
|
+
// SEO Validation (from seo.ts)
|
|
320
|
+
runner.addCheck((0, preflight_runner_1.createCheck)("SEO Validation", "Validate meta tags, OpenGraph, and structured data", async () => {
|
|
321
|
+
const errors = [];
|
|
322
|
+
const warnings = [];
|
|
323
|
+
const info = [];
|
|
324
|
+
// Check for robots.txt
|
|
325
|
+
const robotsExists = await scanner.fileExists("public/robots.txt");
|
|
326
|
+
if (!robotsExists) {
|
|
327
|
+
errors.push("Missing robots.txt file in public folder");
|
|
328
|
+
}
|
|
329
|
+
else {
|
|
330
|
+
info.push("${chars.check} robots.txt found");
|
|
331
|
+
}
|
|
332
|
+
// Check for ai.txt
|
|
333
|
+
const aiTxtExists = await scanner.fileExists("public/ai.txt");
|
|
334
|
+
if (!aiTxtExists) {
|
|
335
|
+
warnings.push("Missing ai.txt file in public folder (recommended for AI crawlers)");
|
|
336
|
+
}
|
|
337
|
+
else {
|
|
338
|
+
info.push("✓ ai.txt found");
|
|
339
|
+
}
|
|
340
|
+
// Check for sitemap
|
|
341
|
+
const sitemapTsExists = await scanner.fileExists("app/sitemap.ts");
|
|
342
|
+
const sitemapXmlExists = await scanner.fileExists("public/sitemap.xml");
|
|
343
|
+
if (!sitemapTsExists && !sitemapXmlExists) {
|
|
344
|
+
warnings.push("No sitemap found (app/sitemap.ts or public/sitemap.xml)");
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
info.push("✓ Sitemap found");
|
|
348
|
+
}
|
|
349
|
+
// Check pages for metadata
|
|
350
|
+
const pageFiles = await scanner.findFiles(/app\/.*\/page\.(ts|tsx)$/);
|
|
351
|
+
let pagesWithMetadata = 0;
|
|
352
|
+
let pagesWithoutMetadata = 0;
|
|
353
|
+
for (const file of pageFiles) {
|
|
354
|
+
// Skip API routes
|
|
355
|
+
if (file.relativePath.includes("/api/"))
|
|
356
|
+
continue;
|
|
357
|
+
const content = await scanner.readFileContent(file.path);
|
|
358
|
+
if (!content)
|
|
359
|
+
continue;
|
|
360
|
+
// Check for metadata export or Metadata type in page
|
|
361
|
+
const hasMetadata = content.includes("export const metadata") || content.includes("generateMetadata");
|
|
362
|
+
if (hasMetadata) {
|
|
363
|
+
pagesWithMetadata++;
|
|
364
|
+
info.push(`${console_chars_1.chars.check} ${file.relativePath} has metadata`);
|
|
365
|
+
}
|
|
366
|
+
else {
|
|
367
|
+
pagesWithoutMetadata++;
|
|
368
|
+
warnings.push(`${file.relativePath} missing metadata export`);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
info.push(`Pages with metadata: ${pagesWithMetadata}`);
|
|
372
|
+
if (pagesWithoutMetadata > 0) {
|
|
373
|
+
warnings.push(`Pages without metadata: ${pagesWithoutMetadata}`);
|
|
374
|
+
}
|
|
375
|
+
return { passed: errors.length === 0, errors, warnings, info };
|
|
376
|
+
}));
|
|
377
|
+
// Error Boundaries Validation (new)
|
|
378
|
+
runner.addCheck((0, preflight_runner_1.createCheck)("Error Boundaries", "Validate error.tsx files exist for route segments", async () => {
|
|
379
|
+
const errors = [];
|
|
380
|
+
const warnings = [];
|
|
381
|
+
const info = [];
|
|
382
|
+
// Find all route segments (directories with page.tsx)
|
|
383
|
+
const pageFiles = await scanner.findFiles(/app\/.*\/page\.(ts|tsx)$/);
|
|
384
|
+
const routeSegments = pageFiles.map((file) => {
|
|
385
|
+
const dir = file.relativePath.replace(/\/page\.(ts|tsx)$/, "");
|
|
386
|
+
return dir;
|
|
387
|
+
});
|
|
388
|
+
let errorBoundariesFound = 0;
|
|
389
|
+
let missingErrorBoundaries = 0;
|
|
390
|
+
for (const segment of routeSegments) {
|
|
391
|
+
// Skip root app directory
|
|
392
|
+
if (segment === "app")
|
|
393
|
+
continue;
|
|
394
|
+
const errorTsxPath = `${segment}/error.tsx`;
|
|
395
|
+
const errorTsPath = `${segment}/error.ts`;
|
|
396
|
+
const errorTsxExists = await scanner.fileExists(errorTsxPath);
|
|
397
|
+
const errorTsExists = await scanner.fileExists(errorTsPath);
|
|
398
|
+
if (errorTsxExists || errorTsExists) {
|
|
399
|
+
errorBoundariesFound++;
|
|
400
|
+
info.push(`${console_chars_1.chars.check} ${segment} has error boundary`);
|
|
401
|
+
}
|
|
402
|
+
else {
|
|
403
|
+
missingErrorBoundaries++;
|
|
404
|
+
warnings.push(`${segment} missing error.tsx boundary`);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
info.push(`Route segments with error boundaries: ${errorBoundariesFound}`);
|
|
408
|
+
if (missingErrorBoundaries > 0) {
|
|
409
|
+
warnings.push(`Route segments without error boundaries: ${missingErrorBoundaries}`);
|
|
410
|
+
warnings.push("Consider adding error.tsx files for better error handling");
|
|
411
|
+
}
|
|
412
|
+
return { passed: errors.length === 0, errors, warnings, info };
|
|
413
|
+
}));
|
|
414
|
+
// Duplicate Components Detection (new)
|
|
415
|
+
runner.addCheck((0, preflight_runner_1.createCheck)("Duplicate Components", "Detect potentially duplicate component implementations", async () => {
|
|
416
|
+
const errors = [];
|
|
417
|
+
const warnings = [];
|
|
418
|
+
const info = [];
|
|
419
|
+
const componentFiles = await scanner.findComponentFiles();
|
|
420
|
+
const componentsByName = {};
|
|
421
|
+
// Group components by name
|
|
422
|
+
for (const file of componentFiles) {
|
|
423
|
+
const componentName = file.name.replace(/\.(tsx|jsx)$/, "");
|
|
424
|
+
if (!componentsByName[componentName]) {
|
|
425
|
+
componentsByName[componentName] = [];
|
|
426
|
+
}
|
|
427
|
+
componentsByName[componentName].push(file.relativePath);
|
|
428
|
+
}
|
|
429
|
+
// Find duplicates
|
|
430
|
+
const duplicates = Object.entries(componentsByName).filter(([name, files]) => files.length > 1);
|
|
431
|
+
if (duplicates.length > 0) {
|
|
432
|
+
warnings.push("Potential duplicate components detected:");
|
|
433
|
+
for (const [name, files] of duplicates) {
|
|
434
|
+
warnings.push(` ${name}:`);
|
|
435
|
+
files.forEach((file) => warnings.push(` - ${file}`));
|
|
436
|
+
}
|
|
437
|
+
warnings.push("Consider consolidating duplicate components or renaming for clarity");
|
|
438
|
+
}
|
|
439
|
+
else {
|
|
440
|
+
info.push("${chars.check} No duplicate component names detected");
|
|
441
|
+
}
|
|
442
|
+
info.push(`Total components analyzed: ${componentFiles.length}`);
|
|
443
|
+
info.push(`Unique component names: ${Object.keys(componentsByName).length}`);
|
|
444
|
+
return { passed: errors.length === 0, errors, warnings, info };
|
|
445
|
+
}));
|
|
446
|
+
// Page Header Structure Validation (CRITICAL)
|
|
447
|
+
runner.addCheck((0, preflight_runner_1.createCheck)("Page Header Structure", "CRITICAL: Validate all pages have proper UnifiedHeader structure", async () => {
|
|
448
|
+
console.log(`${console_chars_1.emoji.search} Running Page Header Structure check...`);
|
|
449
|
+
const errors = [];
|
|
450
|
+
const warnings = [];
|
|
451
|
+
const info = [];
|
|
452
|
+
// Find all page files and client components
|
|
453
|
+
const pageFiles = await scanner.findFiles(/app\/.*\/(page\.(tsx|ts)|.*Client\.(tsx|ts))$/);
|
|
454
|
+
// Debug: Log total files found
|
|
455
|
+
console.log(`Found ${pageFiles.length} page files to check`);
|
|
456
|
+
let pagesWithPageHeader = 0;
|
|
457
|
+
let pagesWithNavigationOnly = 0;
|
|
458
|
+
let pagesMissingHeaders = 0;
|
|
459
|
+
let totalPagesChecked = 0;
|
|
460
|
+
for (const file of pageFiles) {
|
|
461
|
+
// Skip API routes and non-page files
|
|
462
|
+
if (file.relativePath.includes("/api/") ||
|
|
463
|
+
file.relativePath.includes("/layout.") ||
|
|
464
|
+
file.relativePath.includes("/loading.") ||
|
|
465
|
+
file.relativePath.includes("/error.") ||
|
|
466
|
+
file.relativePath.includes("/not-found.")) {
|
|
467
|
+
continue;
|
|
468
|
+
}
|
|
469
|
+
const content = await scanner.readFileContent(file.path);
|
|
470
|
+
if (!content)
|
|
471
|
+
continue;
|
|
472
|
+
totalPagesChecked++;
|
|
473
|
+
const hasUnifiedHeaderNavigation = content.includes("UnifiedHeader") && content.includes('variant="navigation"');
|
|
474
|
+
const hasUnifiedHeaderPage = content.includes("UnifiedHeader") && content.includes('variant="page"');
|
|
475
|
+
const hasUnifiedHeaderAdmin = content.includes("UnifiedHeader") && content.includes('variant="admin"');
|
|
476
|
+
// Check for proper page header structure
|
|
477
|
+
if (hasUnifiedHeaderPage) {
|
|
478
|
+
pagesWithPageHeader++;
|
|
479
|
+
info.push(`${console_chars_1.chars.check} ${file.relativePath} has proper page header`);
|
|
480
|
+
// Validate page header has required props
|
|
481
|
+
const pageHeaderMatch = content.match(/<UnifiedHeader[^>]*variant="page"[^>]*>/);
|
|
482
|
+
if (pageHeaderMatch) {
|
|
483
|
+
const headerTag = pageHeaderMatch[0];
|
|
484
|
+
if (!headerTag.includes("title=")) {
|
|
485
|
+
warnings.push(`${file.relativePath} page header missing title prop`);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
else if (hasUnifiedHeaderNavigation && !hasUnifiedHeaderAdmin) {
|
|
490
|
+
pagesWithNavigationOnly++;
|
|
491
|
+
// Check if this is a content page that should have a page header
|
|
492
|
+
const isContentPage = !file.relativePath.includes("/login") &&
|
|
493
|
+
!file.relativePath.includes("/register") &&
|
|
494
|
+
!file.relativePath.includes("/not-found") &&
|
|
495
|
+
!file.relativePath.includes("/loading") &&
|
|
496
|
+
!file.relativePath.includes("/error");
|
|
497
|
+
if (isContentPage) {
|
|
498
|
+
errors.push(`CRITICAL: ${file.relativePath} missing page header`);
|
|
499
|
+
errors.push(` - Has navigation header but missing UnifiedHeader variant="page"`);
|
|
500
|
+
errors.push(` - REQUIRED: Add page header for consistent structure`);
|
|
501
|
+
errors.push(` - Standard pattern: Navigation ${console_chars_1.chars.arrow} Breadcrumbs → Page Header → Content`);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
else if (!hasUnifiedHeaderNavigation &&
|
|
505
|
+
!hasUnifiedHeaderPage &&
|
|
506
|
+
!hasUnifiedHeaderAdmin) {
|
|
507
|
+
pagesMissingHeaders++;
|
|
508
|
+
warnings.push(`${file.relativePath} missing any header component`);
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
// Summary
|
|
512
|
+
info.push(`Total pages checked: ${totalPagesChecked}`);
|
|
513
|
+
info.push(`Pages with page headers: ${pagesWithPageHeader}`);
|
|
514
|
+
info.push(`Pages with navigation only: ${pagesWithNavigationOnly}`);
|
|
515
|
+
info.push(`Pages missing headers: ${pagesMissingHeaders}`);
|
|
516
|
+
// Critical validation
|
|
517
|
+
const criticalFailures = errors.length > 0;
|
|
518
|
+
if (criticalFailures) {
|
|
519
|
+
errors.push("");
|
|
520
|
+
errors.push(`${console_chars_1.emoji.bell} PAGE HEADER STRUCTURE IS CRITICAL FOR CONSISTENCY`);
|
|
521
|
+
errors.push("All content pages must follow the universal structure:");
|
|
522
|
+
errors.push(' 1. UnifiedHeader variant="navigation" (app navigation)');
|
|
523
|
+
errors.push(" 2. Breadcrumbs component (py: 1)");
|
|
524
|
+
errors.push(' 3. UnifiedHeader variant="page" (page title/description)');
|
|
525
|
+
errors.push(" 4. Page content (no extra margin-top)");
|
|
526
|
+
errors.push("");
|
|
527
|
+
errors.push("NO EXCEPTIONS - Every content page must have a page header!");
|
|
528
|
+
}
|
|
529
|
+
if (!criticalFailures && pagesWithPageHeader > 0) {
|
|
530
|
+
info.push(`${console_chars_1.emoji.party} ALL CONTENT PAGES HAVE PROPER HEADER STRUCTURE`);
|
|
531
|
+
info.push("${chars.check} Navigation headers present");
|
|
532
|
+
info.push("✓ Page headers present with titles");
|
|
533
|
+
info.push("✓ Consistent page structure maintained");
|
|
534
|
+
}
|
|
535
|
+
return { passed: !criticalFailures, errors, warnings, info };
|
|
536
|
+
}));
|
|
537
|
+
// Card Grid Spacing Consistency (CRITICAL)
|
|
538
|
+
runner.addCheck((0, preflight_runner_1.createCheck)("Card Grid Spacing Consistency", 'CRITICAL: Validate all card grids use consistent gap: "var(--spacing-4)" spacing', async () => {
|
|
539
|
+
const errors = [];
|
|
540
|
+
const warnings = [];
|
|
541
|
+
const info = [];
|
|
542
|
+
// Find all TSX files
|
|
543
|
+
const allTsxFiles = await scanner.findFiles(/\.tsx$/);
|
|
544
|
+
let filesWithCorrectSpacing = 0;
|
|
545
|
+
let filesWithIncorrectSpacing = 0;
|
|
546
|
+
const incorrectFiles = [];
|
|
547
|
+
const correctFiles = [];
|
|
548
|
+
// Patterns for card grid spacing
|
|
549
|
+
const incorrectSpacingPattern = /gap:\s*["']var\(--spacing-6\)["']/g;
|
|
550
|
+
const correctSpacingPattern = /gap:\s*["']var\(--spacing-4\)["']/g;
|
|
551
|
+
for (const file of allTsxFiles) {
|
|
552
|
+
// Skip node_modules and build files
|
|
553
|
+
if (file.relativePath.includes("node_modules") ||
|
|
554
|
+
file.relativePath.includes(".next") ||
|
|
555
|
+
file.relativePath.includes("dist")) {
|
|
556
|
+
continue;
|
|
557
|
+
}
|
|
558
|
+
const content = await scanner.readFileContent(file.path);
|
|
559
|
+
if (!content)
|
|
560
|
+
continue;
|
|
561
|
+
const incorrectMatches = content.match(incorrectSpacingPattern);
|
|
562
|
+
const correctMatches = content.match(correctSpacingPattern);
|
|
563
|
+
if (incorrectMatches) {
|
|
564
|
+
filesWithIncorrectSpacing++;
|
|
565
|
+
incorrectFiles.push(`${file.relativePath} (${incorrectMatches.length} occurrences)`);
|
|
566
|
+
errors.push(`CRITICAL: ${file.relativePath} uses gap: "var(--spacing-6)" instead of "var(--spacing-4)"`);
|
|
567
|
+
}
|
|
568
|
+
if (correctMatches) {
|
|
569
|
+
filesWithCorrectSpacing++;
|
|
570
|
+
correctFiles.push(`${file.relativePath} (${correctMatches.length} occurrences)`);
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
// Summary
|
|
574
|
+
info.push(`Files with correct card spacing (var(--spacing-4)): ${filesWithCorrectSpacing}`);
|
|
575
|
+
info.push(`Files with incorrect card spacing (var(--spacing-6)): ${filesWithIncorrectSpacing}`);
|
|
576
|
+
if (filesWithIncorrectSpacing > 0) {
|
|
577
|
+
errors.push("");
|
|
578
|
+
errors.push(`${console_chars_1.emoji.bell} INCONSISTENT CARD SPACING DETECTED!`);
|
|
579
|
+
errors.push('All card grids must use gap: "var(--spacing-4)" for consistency.');
|
|
580
|
+
errors.push("Reference standard: app/seller/analytics/AnalyticsPageClient.tsx");
|
|
581
|
+
errors.push("");
|
|
582
|
+
errors.push("Files that need fixing:");
|
|
583
|
+
incorrectFiles.forEach((file) => errors.push(` - ${file}`));
|
|
584
|
+
errors.push("");
|
|
585
|
+
errors.push('REQUIRED ACTION: Replace gap: "var(--spacing-6)" with gap: "var(--spacing-4)"');
|
|
586
|
+
}
|
|
587
|
+
else {
|
|
588
|
+
info.push(`${console_chars_1.emoji.party} All card grids use consistent spacing!`);
|
|
589
|
+
}
|
|
590
|
+
return { passed: filesWithIncorrectSpacing === 0, errors, warnings, info };
|
|
591
|
+
}));
|
|
592
|
+
// UI Spacing Consistency - COMPREHENSIVE (ALL PAGES)
|
|
593
|
+
runner.addCheck((0, preflight_runner_1.createCheck)("UI Spacing Consistency", "CRITICAL: Validate consistent spacing patterns across ALL pages and components", async () => {
|
|
594
|
+
const errors = [];
|
|
595
|
+
const warnings = [];
|
|
596
|
+
const info = [];
|
|
597
|
+
// 1. CRITICAL: Check Breadcrumbs component for correct tokenized spacing
|
|
598
|
+
const breadcrumbsFile = await scanner.findFiles(/components\/Breadcrumbs\.(tsx|ts)$/);
|
|
599
|
+
if (breadcrumbsFile.length > 0) {
|
|
600
|
+
const content = await scanner.readFileContent(breadcrumbsFile[0].path);
|
|
601
|
+
if (content) {
|
|
602
|
+
// Check for incorrect breadcrumbs spacing (should be py: 1, not py: 1.5 or higher)
|
|
603
|
+
const incorrectSpacingPatterns = [
|
|
604
|
+
{ pattern: /py:\s*1\.5/g, issue: "py: 1.5 (should be py: 1)" },
|
|
605
|
+
{ pattern: /py:\s*2/g, issue: "py: 2 (should be py: 1)" },
|
|
606
|
+
{ pattern: /py:\s*['"]?\d+px['"]?/g, issue: "hardcoded pixels (should be py: 1)" },
|
|
607
|
+
{
|
|
608
|
+
pattern: /padding:\s*['"]?\d+px\s+\d+px['"]?/g,
|
|
609
|
+
issue: "hardcoded padding (should use design tokens)",
|
|
610
|
+
},
|
|
611
|
+
];
|
|
612
|
+
let breadcrumbsHasErrors = false;
|
|
613
|
+
for (const { pattern, issue } of incorrectSpacingPatterns) {
|
|
614
|
+
if (pattern.test(content)) {
|
|
615
|
+
errors.push(`CRITICAL: Breadcrumbs component has incorrect spacing: ${issue}`);
|
|
616
|
+
errors.push("REQUIRED: Use py: 1 for consistent spacing hierarchy");
|
|
617
|
+
breadcrumbsHasErrors = true;
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
if (!breadcrumbsHasErrors && content.includes("py: 1")) {
|
|
621
|
+
info.push("${chars.check} Breadcrumbs component uses correct tokenized spacing (py: 1)");
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
else {
|
|
626
|
+
warnings.push("Breadcrumbs component not found - ensure it exists and uses py: 1");
|
|
627
|
+
}
|
|
628
|
+
// 2. COMPREHENSIVE: Check ALL pages for spacing consistency (not just seller pages)
|
|
629
|
+
const allPageFiles = await scanner.findFiles(/app\/.*\/page\.(tsx|ts)$/);
|
|
630
|
+
const allClientFiles = await scanner.findFiles(/app\/.*Client\.(tsx|ts)$/);
|
|
631
|
+
const allLayoutFiles = await scanner.findFiles(/app\/.*\/layout\.(tsx|ts)$/);
|
|
632
|
+
// Combine all page-related files
|
|
633
|
+
const allPageRelatedFiles = [...allPageFiles, ...allClientFiles, ...allLayoutFiles];
|
|
634
|
+
let totalPagesChecked = 0;
|
|
635
|
+
let pagesWithCorrectSpacing = 0;
|
|
636
|
+
let pagesWithIncorrectSpacing = 0;
|
|
637
|
+
// Enhanced patterns for detecting spacing violations
|
|
638
|
+
const spacingViolationPatterns = {
|
|
639
|
+
// Excessive margins after headers
|
|
640
|
+
excessiveMarginTop: [
|
|
641
|
+
/<(?:Stack|Box|Container|Grid)[^>]*sx=\{[^}]*mt:\s*["']var\(--spacing-[6-9]\)["'][^}]*\}/g,
|
|
642
|
+
/<(?:Stack|Box|Container|Grid)[^>]*sx=\{[^}]*marginTop:\s*["']var\(--spacing-[6-9]\)["'][^}]*\}/g,
|
|
643
|
+
],
|
|
644
|
+
// Hardcoded pixel spacing
|
|
645
|
+
hardcodedPixels: [
|
|
646
|
+
/(?:margin|padding|gap):\s*['"]?\d+px['"]?/g,
|
|
647
|
+
/(?:mt|mb|ml|mr|pt|pb|pl|pr|px|py):\s*['"]?\d+px['"]?/g,
|
|
648
|
+
/(?:marginTop|marginBottom|paddingTop|paddingBottom):\s*['"]?\d+px['"]?/g,
|
|
649
|
+
],
|
|
650
|
+
// Non-tokenized numeric spacing (except Material-UI standard values like py: 1, 2, 3, 4)
|
|
651
|
+
nonTokenizedSpacing: [
|
|
652
|
+
/(?:mt|mb|ml|mr|pt|pb|pl|pr):\s*['"]?\d{2}['"]?/g, // Numbers >= 10 should use tokens
|
|
653
|
+
/(?:margin|padding):\s*['"]?\d{2}['"]?/g,
|
|
654
|
+
],
|
|
655
|
+
// Inconsistent decimal spacing (like py: 1.5, 2.5, etc.)
|
|
656
|
+
inconsistentDecimalSpacing: [/(?:py|px|pt|pb|pl|pr):\s*\d+\.\d+/g],
|
|
657
|
+
// NEW: Inconsistent gap spacing between cards/components
|
|
658
|
+
inconsistentGapSpacing: [
|
|
659
|
+
/gap:\s*['"]?\d+px['"]?/g, // Hardcoded pixel gaps
|
|
660
|
+
/gap:\s*['"]?(?:10|12|14|15|18|20|22|25|28|30)['"]?/g, // Non-standard gap values
|
|
661
|
+
/gridGap:\s*['"]?\d+px['"]?/g, // Hardcoded grid gaps
|
|
662
|
+
],
|
|
663
|
+
// NEW: Card grid spacing inconsistency (should use var(--spacing-4) standard)
|
|
664
|
+
inconsistentCardGridSpacing: [
|
|
665
|
+
/gap:\s*["']var\(--spacing-6\)["']/g, // Should be var(--spacing-4) for consistency
|
|
666
|
+
/gap:\s*["']var\(--spacing-[5789]\)["']/g, // Non-standard spacing values
|
|
667
|
+
],
|
|
668
|
+
// NEW: Mixed spacing units within same component
|
|
669
|
+
mixedSpacingUnits: [
|
|
670
|
+
/sx=\{[^}]*(?:gap:\s*["']var\(--spacing-\d+\)["'][^}]*(?:mt|mb|ml|mr|pt|pb|pl|pr):\s*\d+[^}]*|(?:mt|mb|ml|mr|pt|pb|pl|pr):\s*\d+[^}]*gap:\s*["']var\(--spacing-\d+\)["'])/g,
|
|
671
|
+
],
|
|
672
|
+
// NEW: Inconsistent card grid spacing
|
|
673
|
+
inconsistentCardGrids: [
|
|
674
|
+
/gridTemplateColumns:[^}]*gap:\s*['"]?(?!var\(--spacing-[346]\))['"]?[^}]*\}/g, // Non-standard grid gaps
|
|
675
|
+
/display:\s*["']grid["'][^}]*gap:\s*['"]?\d+px['"]?/g, // Hardcoded grid gaps
|
|
676
|
+
],
|
|
677
|
+
// NEW: Header-to-card spacing inconsistency
|
|
678
|
+
headerCardSpacingInconsistency: [
|
|
679
|
+
/UnifiedHeader[^>]*\/>[^{]*\{[^}]*display:\s*["']grid["'][^}]*gap:\s*["']var\(--spacing-6\)["'][^}]*(?!mt:\s*["']var\(--spacing-3\)["'])/g,
|
|
680
|
+
],
|
|
681
|
+
// NEW: Inconsistent page-wide spacing (breadcrumbs to header to content)
|
|
682
|
+
inconsistentPageSpacing: [
|
|
683
|
+
// Page with UnifiedHeader page variant that doesn't have consistent mt: var(--spacing-6)
|
|
684
|
+
/UnifiedHeader[^>]*variant=["']page["'][^>]*(?!.*sx=\{[^}]*mt:\s*["']var\(--spacing-6\)["'])/g,
|
|
685
|
+
// Container with py padding that breaks consistent spacing
|
|
686
|
+
/Box[^>]*sx=\{[^}]*py:\s*["']var\(--spacing-[4-9]\)["'][^}]*\}[^>]*>[^<]*<UnifiedHeader[^>]*variant=["']page["']/g,
|
|
687
|
+
// Missing consistent spacing between major page sections
|
|
688
|
+
/\{\/\*[^}]*Cards?\*\/\}[^<]*<(?:Box|Card)[^>]*(?!.*mt:\s*["']var\(--spacing-6\)["'])/g,
|
|
689
|
+
// Horizontal spacing inconsistent with vertical spacing (should match)
|
|
690
|
+
/px:\s*["']var\(--spacing-4\)["'][^}]*\}[^>]*>[^<]*<UnifiedHeader[^>]*variant=["']page["'][^>]*sx=\{[^}]*mt:\s*["']var\(--spacing-6\)["']/g,
|
|
691
|
+
],
|
|
692
|
+
};
|
|
693
|
+
for (const file of allPageRelatedFiles) {
|
|
694
|
+
// Skip API routes
|
|
695
|
+
if (file.relativePath.includes("/api/"))
|
|
696
|
+
continue;
|
|
697
|
+
const content = await scanner.readFileContent(file.path);
|
|
698
|
+
if (!content)
|
|
699
|
+
continue;
|
|
700
|
+
totalPagesChecked++;
|
|
701
|
+
let pageHasSpacingIssues = false;
|
|
702
|
+
// Check for excessive margin-top after headers
|
|
703
|
+
for (const pattern of spacingViolationPatterns.excessiveMarginTop) {
|
|
704
|
+
const matches = content.match(pattern);
|
|
705
|
+
if (matches) {
|
|
706
|
+
pageHasSpacingIssues = true;
|
|
707
|
+
pagesWithIncorrectSpacing++;
|
|
708
|
+
errors.push(`${file.relativePath} has excessive margin-top after header components`);
|
|
709
|
+
matches.forEach((match) => {
|
|
710
|
+
errors.push(` - VIOLATION: ${match.substring(0, 80)}...`);
|
|
711
|
+
});
|
|
712
|
+
errors.push(" - REQUIRED: Remove excessive margin-top, headers provide their own spacing");
|
|
713
|
+
break;
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
// Check for hardcoded pixel values
|
|
717
|
+
for (const pattern of spacingViolationPatterns.hardcodedPixels) {
|
|
718
|
+
const matches = content.match(pattern);
|
|
719
|
+
if (matches) {
|
|
720
|
+
pageHasSpacingIssues = true;
|
|
721
|
+
warnings.push(`${file.relativePath} uses hardcoded pixel spacing`);
|
|
722
|
+
matches.slice(0, 3).forEach((match) => {
|
|
723
|
+
// Limit to first 3 matches
|
|
724
|
+
warnings.push(` - HARDCODED: ${match}`);
|
|
725
|
+
});
|
|
726
|
+
warnings.push(" - REQUIRED: Use design tokens like var(--spacing-4)");
|
|
727
|
+
break;
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
// Check for non-tokenized large numeric spacing
|
|
731
|
+
for (const pattern of spacingViolationPatterns.nonTokenizedSpacing) {
|
|
732
|
+
const matches = content.match(pattern);
|
|
733
|
+
if (matches) {
|
|
734
|
+
pageHasSpacingIssues = true;
|
|
735
|
+
warnings.push(`${file.relativePath} uses non-tokenized large spacing values`);
|
|
736
|
+
matches.slice(0, 3).forEach((match) => {
|
|
737
|
+
warnings.push(` - NON-TOKENIZED: ${match}`);
|
|
738
|
+
});
|
|
739
|
+
warnings.push(" - REQUIRED: Use design tokens for values >= 10");
|
|
740
|
+
break;
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
// Check for inconsistent decimal spacing
|
|
744
|
+
for (const pattern of spacingViolationPatterns.inconsistentDecimalSpacing) {
|
|
745
|
+
const matches = content.match(pattern);
|
|
746
|
+
if (matches) {
|
|
747
|
+
pageHasSpacingIssues = true;
|
|
748
|
+
// Special case for py: 1.5 in breadcrumbs (already caught above)
|
|
749
|
+
if (!file.relativePath.includes("Breadcrumbs")) {
|
|
750
|
+
warnings.push(`${file.relativePath} uses inconsistent decimal spacing`);
|
|
751
|
+
matches.slice(0, 3).forEach((match) => {
|
|
752
|
+
warnings.push(` - INCONSISTENT: ${match} (use whole numbers: py: 1, py: 2, etc.)`);
|
|
753
|
+
});
|
|
754
|
+
}
|
|
755
|
+
break;
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
// NEW: Check for inconsistent gap spacing between cards/components
|
|
759
|
+
for (const pattern of spacingViolationPatterns.inconsistentGapSpacing) {
|
|
760
|
+
const matches = content.match(pattern);
|
|
761
|
+
if (matches) {
|
|
762
|
+
pageHasSpacingIssues = true;
|
|
763
|
+
warnings.push(`${file.relativePath} uses inconsistent gap spacing between components`);
|
|
764
|
+
matches.slice(0, 3).forEach((match) => {
|
|
765
|
+
warnings.push(` - INCONSISTENT GAP: ${match}`);
|
|
766
|
+
});
|
|
767
|
+
warnings.push(" - REQUIRED: Use standard gaps: var(--spacing-3), var(--spacing-4), var(--spacing-6)");
|
|
768
|
+
break;
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
// NEW: Check for card grid spacing inconsistency (should be var(--spacing-4))
|
|
772
|
+
for (const pattern of spacingViolationPatterns.inconsistentCardGridSpacing) {
|
|
773
|
+
const matches = content.match(pattern);
|
|
774
|
+
if (matches) {
|
|
775
|
+
pageHasSpacingIssues = true;
|
|
776
|
+
errors.push(`CRITICAL: ${file.relativePath} uses inconsistent card grid spacing`);
|
|
777
|
+
matches.slice(0, 3).forEach((match) => {
|
|
778
|
+
errors.push(` - INCONSISTENT CARD SPACING: ${match}`);
|
|
779
|
+
});
|
|
780
|
+
errors.push(' - REQUIRED: Use gap: "var(--spacing-4)" for consistent card grid spacing');
|
|
781
|
+
errors.push(" - STANDARD: All card grids should use 16px gaps like /seller/analytics");
|
|
782
|
+
break;
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
// NEW: Check for mixed spacing units within same component
|
|
786
|
+
for (const pattern of spacingViolationPatterns.mixedSpacingUnits) {
|
|
787
|
+
const matches = content.match(pattern);
|
|
788
|
+
if (matches) {
|
|
789
|
+
pageHasSpacingIssues = true;
|
|
790
|
+
warnings.push(`${file.relativePath} mixes different spacing unit types in same component`);
|
|
791
|
+
matches.slice(0, 2).forEach((match) => {
|
|
792
|
+
warnings.push(` - MIXED UNITS: ${match.substring(0, 60)}...`);
|
|
793
|
+
});
|
|
794
|
+
warnings.push(" - REQUIRED: Use consistent spacing units (all design tokens or all Material-UI units)");
|
|
795
|
+
break;
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
// NEW: Check for inconsistent card grid spacing
|
|
799
|
+
for (const pattern of spacingViolationPatterns.inconsistentCardGrids) {
|
|
800
|
+
const matches = content.match(pattern);
|
|
801
|
+
if (matches) {
|
|
802
|
+
pageHasSpacingIssues = true;
|
|
803
|
+
warnings.push(`${file.relativePath} uses inconsistent spacing in card grids`);
|
|
804
|
+
matches.slice(0, 2).forEach((match) => {
|
|
805
|
+
warnings.push(` - INCONSISTENT GRID: ${match.substring(0, 60)}...`);
|
|
806
|
+
});
|
|
807
|
+
warnings.push(" - REQUIRED: Use standard grid gaps: var(--spacing-4) (standard), var(--spacing-3) (compact)");
|
|
808
|
+
break;
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
// NEW: Check for header-to-card spacing inconsistency
|
|
812
|
+
for (const pattern of spacingViolationPatterns.headerCardSpacingInconsistency) {
|
|
813
|
+
const matches = content.match(pattern);
|
|
814
|
+
if (matches) {
|
|
815
|
+
pageHasSpacingIssues = true;
|
|
816
|
+
warnings.push(`${file.relativePath} has inconsistent spacing between header and card grid`);
|
|
817
|
+
matches.slice(0, 2).forEach((match) => {
|
|
818
|
+
warnings.push(` - HEADER-CARD GAP: ${match.substring(0, 60)}...`);
|
|
819
|
+
});
|
|
820
|
+
warnings.push(' - REQUIRED: Use consistent mt: "var(--spacing-4)" for standard spacing throughout page');
|
|
821
|
+
break;
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
// NEW: Check for inconsistent page-wide spacing
|
|
825
|
+
for (const pattern of spacingViolationPatterns.inconsistentPageSpacing) {
|
|
826
|
+
const matches = content.match(pattern);
|
|
827
|
+
if (matches) {
|
|
828
|
+
pageHasSpacingIssues = true;
|
|
829
|
+
warnings.push(`${file.relativePath} has inconsistent page-wide spacing`);
|
|
830
|
+
matches.slice(0, 2).forEach((match) => {
|
|
831
|
+
warnings.push(` - SPACING INCONSISTENCY: ${match.substring(0, 60)}...`);
|
|
832
|
+
});
|
|
833
|
+
warnings.push(" - REQUIRED: Use consistent var(--spacing-4) spacing throughout entire page");
|
|
834
|
+
warnings.push(" - PATTERN: Breadcrumbs ${chars.arrow} Header (16px) → Content (16px) → Sections (16px)");
|
|
835
|
+
warnings.push(" - HORIZONTAL: Use px: var(--spacing-4) to match vertical spacing rhythm");
|
|
836
|
+
break;
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
if (!pageHasSpacingIssues) {
|
|
840
|
+
pagesWithCorrectSpacing++;
|
|
841
|
+
info.push(`${console_chars_1.chars.check} ${file.relativePath} follows spacing standards`);
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
// 3. COMPREHENSIVE: Check ALL components for design token usage
|
|
845
|
+
const allComponentFiles = await scanner.findFiles(/\.(tsx|ts)$/);
|
|
846
|
+
let totalFilesChecked = 0;
|
|
847
|
+
let filesWithHardcodedSpacing = 0;
|
|
848
|
+
let filesWithCorrectTokens = 0;
|
|
849
|
+
for (const file of allComponentFiles) {
|
|
850
|
+
// Skip node_modules, build files, and test files
|
|
851
|
+
if (file.relativePath.includes("node_modules") ||
|
|
852
|
+
file.relativePath.includes(".next") ||
|
|
853
|
+
file.relativePath.includes("dist") ||
|
|
854
|
+
file.relativePath.includes(".test.") ||
|
|
855
|
+
file.relativePath.includes(".spec.")) {
|
|
856
|
+
continue;
|
|
857
|
+
}
|
|
858
|
+
const content = await scanner.readFileContent(file.path);
|
|
859
|
+
if (!content)
|
|
860
|
+
continue;
|
|
861
|
+
totalFilesChecked++;
|
|
862
|
+
// Check for hardcoded spacing values
|
|
863
|
+
const hasHardcodedSpacing = spacingViolationPatterns.hardcodedPixels.some((pattern) => pattern.test(content));
|
|
864
|
+
// Check for proper design token usage
|
|
865
|
+
const hasDesignTokens = /var\(--spacing-\d+\)/.test(content);
|
|
866
|
+
if (hasHardcodedSpacing) {
|
|
867
|
+
filesWithHardcodedSpacing++;
|
|
868
|
+
}
|
|
869
|
+
else if (hasDesignTokens) {
|
|
870
|
+
filesWithCorrectTokens++;
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
// 4. SPECIFIC: Check critical layout components
|
|
874
|
+
const criticalComponents = [
|
|
875
|
+
"components/UnifiedHeader.tsx",
|
|
876
|
+
"components/Breadcrumbs.tsx",
|
|
877
|
+
"components/PageLayout.tsx",
|
|
878
|
+
"components/LayoutSystem.tsx",
|
|
879
|
+
];
|
|
880
|
+
for (const componentPath of criticalComponents) {
|
|
881
|
+
const componentExists = await scanner.fileExists(componentPath);
|
|
882
|
+
if (componentExists) {
|
|
883
|
+
const content = await scanner.readFileContent(componentPath);
|
|
884
|
+
if (content) {
|
|
885
|
+
// Check for proper spacing patterns in critical components
|
|
886
|
+
const hasProperSpacing = /var\(--spacing-\d+\)|py:\s*[1-4](?!\.\d)|px:\s*[1-4](?!\.\d)/.test(content);
|
|
887
|
+
if (hasProperSpacing) {
|
|
888
|
+
info.push(`${console_chars_1.chars.check} ${componentPath} uses proper spacing patterns`);
|
|
889
|
+
}
|
|
890
|
+
else {
|
|
891
|
+
warnings.push(`${componentPath} may need spacing pattern review`);
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
// 5. SUMMARY AND REQUIREMENTS
|
|
897
|
+
info.push(`Total pages/components checked: ${totalPagesChecked}`);
|
|
898
|
+
info.push(`Pages with correct spacing: ${pagesWithCorrectSpacing}`);
|
|
899
|
+
info.push(`Total files scanned for tokens: ${totalFilesChecked}`);
|
|
900
|
+
info.push(`Files using design tokens: ${filesWithCorrectTokens}`);
|
|
901
|
+
if (pagesWithIncorrectSpacing > 0) {
|
|
902
|
+
errors.push(`CRITICAL: ${pagesWithIncorrectSpacing} pages have spacing violations`);
|
|
903
|
+
errors.push("REQUIRED STANDARDS:");
|
|
904
|
+
errors.push(" - Breadcrumbs: py: 1 (not py: 1.5)");
|
|
905
|
+
errors.push(" - Page-wide consistency: Breadcrumbs ${chars.arrow} Header → Content (all 16px gaps)");
|
|
906
|
+
errors.push(" - Headers: Use mt: var(--spacing-4) for consistent spacing");
|
|
907
|
+
errors.push(" - Content: No excessive margin-top after headers");
|
|
908
|
+
errors.push(" - Card Grids: Use consistent gaps (var(--spacing-4) standard, var(--spacing-3) compact)");
|
|
909
|
+
errors.push(" - All spacing: Use design tokens var(--spacing-X)");
|
|
910
|
+
errors.push(' - CRITICAL: All card grids must use gap: "var(--spacing-4)" for consistency');
|
|
911
|
+
}
|
|
912
|
+
if (filesWithHardcodedSpacing > 0) {
|
|
913
|
+
warnings.push(`${filesWithHardcodedSpacing} files use hardcoded spacing values`);
|
|
914
|
+
warnings.push("TOKENIZATION REQUIRED:");
|
|
915
|
+
warnings.push(' - Replace "24px" with "var(--spacing-6)"');
|
|
916
|
+
warnings.push(' - Replace "16px" with "var(--spacing-4)"');
|
|
917
|
+
warnings.push(' - Replace "8px" with "var(--spacing-2)"');
|
|
918
|
+
warnings.push(" - Card gaps: Use var(--spacing-4) for card grids");
|
|
919
|
+
warnings.push(" - Page consistency: All major sections should have 16px gaps");
|
|
920
|
+
warnings.push(' - STANDARD: Follow /seller/analytics pattern with gap: "var(--spacing-4)"');
|
|
921
|
+
warnings.push(" - Use Material-UI units (py: 1, 2, 3, 4) for small values");
|
|
922
|
+
warnings.push(" - Avoid mixed spacing units in same component");
|
|
923
|
+
}
|
|
924
|
+
// CRITICAL: This check must pass for consistent UX
|
|
925
|
+
const criticalFailures = errors.length > 0;
|
|
926
|
+
if (criticalFailures) {
|
|
927
|
+
errors.push("");
|
|
928
|
+
errors.push(`${console_chars_1.emoji.bell} SPACING CONSISTENCY IS CRITICAL FOR USER EXPERIENCE`);
|
|
929
|
+
errors.push("All pages must follow the same spacing hierarchy:");
|
|
930
|
+
errors.push("Navigation ${chars.arrow} Breadcrumbs (py: 1) → Page Header → Content");
|
|
931
|
+
errors.push("No exceptions. No page-specific spacing rules.");
|
|
932
|
+
}
|
|
933
|
+
if (!criticalFailures && warnings.length === 0) {
|
|
934
|
+
info.push(`${console_chars_1.emoji.party} ALL PAGES FOLLOW CONSISTENT SPACING STANDARDS`);
|
|
935
|
+
info.push("${chars.check} Breadcrumbs use correct tokenized spacing");
|
|
936
|
+
info.push("✓ Headers have consistent spacing hierarchy");
|
|
937
|
+
info.push("✓ Design tokens used throughout");
|
|
938
|
+
}
|
|
939
|
+
return { passed: !criticalFailures, errors, warnings, info };
|
|
940
|
+
}));
|
|
941
|
+
// Sidebar Width Consistency (CRITICAL)
|
|
942
|
+
runner.addCheck((0, preflight_runner_1.createCheck)("Sidebar Width Consistency", "CRITICAL: Ensure all sidebars use consistent width for header alignment", async () => {
|
|
943
|
+
const errors = [];
|
|
944
|
+
const warnings = [];
|
|
945
|
+
const info = [];
|
|
946
|
+
// Check for hardcoded sidebar widths that don't match the standard
|
|
947
|
+
const sidebarFiles = [
|
|
948
|
+
"components/SellerSidebar.tsx",
|
|
949
|
+
"components/DashboardSidebar.tsx",
|
|
950
|
+
"components/filters/SportsCardsFilter.tsx",
|
|
951
|
+
"components/filters/TradingCardGamesFilter.tsx",
|
|
952
|
+
"components/filters/VideoGamesFilter.tsx",
|
|
953
|
+
"components/filters/FilterContainer.tsx",
|
|
954
|
+
"components/SearchFiltersEnhanced.tsx",
|
|
955
|
+
];
|
|
956
|
+
const hardcodedWidthPattern = /width:\s*(?:config\.width\s*\|\|\s*)?(\d+)/g;
|
|
957
|
+
const constantWidthPattern = /const\s+SIDEBAR_WIDTH\s*=\s*(\d+)/g;
|
|
958
|
+
for (const filePath of sidebarFiles) {
|
|
959
|
+
try {
|
|
960
|
+
const content = await scanner.readFileContent(filePath);
|
|
961
|
+
if (!content)
|
|
962
|
+
continue;
|
|
963
|
+
// Check for hardcoded widths
|
|
964
|
+
let match;
|
|
965
|
+
while ((match = hardcodedWidthPattern.exec(content)) !== null) {
|
|
966
|
+
const width = parseInt(match[1] || "");
|
|
967
|
+
if (width !== 260 && width !== 64) {
|
|
968
|
+
// 64 is collapsed width
|
|
969
|
+
errors.push(`${filePath}: Hardcoded width ${width}px should use SIDEBAR_WIDTH constant (260px)`);
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
// Check for local constants that don't match
|
|
973
|
+
while ((match = constantWidthPattern.exec(content)) !== null) {
|
|
974
|
+
const width = parseInt(match[1] || "");
|
|
975
|
+
if (width !== 260) {
|
|
976
|
+
errors.push(`${filePath}: Local SIDEBAR_WIDTH constant ${width}px should be 260px`);
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
// Check if file imports the shared constant
|
|
980
|
+
if (content.includes("SIDEBAR_WIDTH") &&
|
|
981
|
+
!content.includes('from "@/lib/sidebar-constants"')) {
|
|
982
|
+
warnings.push(`${filePath}: Should import SIDEBAR_WIDTH from @/lib/sidebar-constants`);
|
|
983
|
+
}
|
|
984
|
+
if (content.includes('from "@/lib/sidebar-constants"')) {
|
|
985
|
+
info.push(`${console_chars_1.chars.check} ${filePath} uses shared sidebar constants`);
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
catch (error) {
|
|
989
|
+
// File might not exist, skip silently
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
// Check category page clients for consistent usage
|
|
993
|
+
const categoryPageFiles = await scanner.findFiles(/CategoryPageClient\.tsx$/);
|
|
994
|
+
for (const file of categoryPageFiles) {
|
|
995
|
+
const content = await scanner.readFileContent(file.path);
|
|
996
|
+
if (!content)
|
|
997
|
+
continue;
|
|
998
|
+
if (content.includes("SIDEBAR_WIDTH") &&
|
|
999
|
+
!content.includes('from "@/lib/sidebar-constants"')) {
|
|
1000
|
+
warnings.push(`${file.relativePath}: Should import SIDEBAR_WIDTH from @/lib/sidebar-constants`);
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
return { passed: errors.length === 0, errors, warnings, info };
|
|
1004
|
+
}));
|
|
1005
|
+
// Sidebar-to-Content Spacing Consistency (CRITICAL)
|
|
1006
|
+
runner.addCheck((0, preflight_runner_1.createCheck)("Sidebar-to-Content Spacing Consistency", "CRITICAL: Ensure consistent spacing between sidebars and main content across all pages", async () => {
|
|
1007
|
+
const errors = [];
|
|
1008
|
+
const warnings = [];
|
|
1009
|
+
const info = [];
|
|
1010
|
+
// 1. Check FilterContainer for margin-right violations
|
|
1011
|
+
const filterContainerFile = await scanner.findFiles(/components\/filters\/FilterContainer\.tsx$/);
|
|
1012
|
+
if (filterContainerFile.length > 0) {
|
|
1013
|
+
const content = await scanner.readFileContent(filterContainerFile[0].path);
|
|
1014
|
+
if (content) {
|
|
1015
|
+
// Check for margin-right that creates extra spacing
|
|
1016
|
+
const marginRightPattern = /mr:\s*[1-9]/g;
|
|
1017
|
+
const marginRightMatches = content.match(marginRightPattern);
|
|
1018
|
+
if (marginRightMatches) {
|
|
1019
|
+
errors.push("CRITICAL: FilterContainer has margin-right that creates inconsistent spacing");
|
|
1020
|
+
marginRightMatches.forEach((match) => {
|
|
1021
|
+
errors.push(` - VIOLATION: ${match} creates extra gap between sidebar and content`);
|
|
1022
|
+
});
|
|
1023
|
+
errors.push(" - REQUIRED: Remove margin-right from FilterContainercomponent");
|
|
1024
|
+
errors.push(' - STANDARD: Sidebars should have no margin-right, content should have px: "var(--spacing-4)"');
|
|
1025
|
+
}
|
|
1026
|
+
else {
|
|
1027
|
+
info.push("${chars.check} FilterContainer has no margin-right violations");
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
// 2. Check DashboardSidebar for correct spacing pattern (reference standard)
|
|
1032
|
+
const dashboardSidebarFile = await scanner.findFiles(/components\/DashboardSidebar\.tsx$/);
|
|
1033
|
+
if (dashboardSidebarFile.length > 0) {
|
|
1034
|
+
const content = await scanner.readFileContent(dashboardSidebarFile[0].path);
|
|
1035
|
+
if (content) {
|
|
1036
|
+
// Verify DashboardSidebar doesn't have margin-right
|
|
1037
|
+
const hasMarginRight = /mr:\s*[1-9]/.test(content);
|
|
1038
|
+
if (hasMarginRight) {
|
|
1039
|
+
errors.push("CRITICAL: DashboardSidebar should not have margin-right");
|
|
1040
|
+
}
|
|
1041
|
+
else {
|
|
1042
|
+
info.push("✓ DashboardSidebar follows correct spacing pattern (no margin-right)");
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
// 3. Check category pages for consistent main content padding
|
|
1047
|
+
const categoryPageFiles = await scanner.findFiles(/CategoryPageClient\.tsx$/);
|
|
1048
|
+
let categoryPagesWithCorrectSpacing = 0;
|
|
1049
|
+
let categoryPagesWithIncorrectSpacing = 0;
|
|
1050
|
+
for (const file of categoryPageFiles) {
|
|
1051
|
+
const content = await scanner.readFileContent(file.path);
|
|
1052
|
+
if (!content)
|
|
1053
|
+
continue;
|
|
1054
|
+
// Check for consistent px: "var(--spacing-4)" in main content area
|
|
1055
|
+
const hasCorrectContentPadding = /px:\s*["']var\(--spacing-4\)["']/.test(content);
|
|
1056
|
+
// Check for nested padding that might create inconsistency
|
|
1057
|
+
const hasNestedPadding = /px:\s*["']var\(--spacing-4\)["'][^}]*\}[^>]*>[^<]*<[^>]*sx=\{[^}]*px:\s*["']var\(--spacing-4\)["']/.test(content);
|
|
1058
|
+
if (hasCorrectContentPadding && !hasNestedPadding) {
|
|
1059
|
+
categoryPagesWithCorrectSpacing++;
|
|
1060
|
+
info.push(`✓ ${file.relativePath} has consistent content padding`);
|
|
1061
|
+
}
|
|
1062
|
+
else if (!hasCorrectContentPadding) {
|
|
1063
|
+
categoryPagesWithIncorrectSpacing++;
|
|
1064
|
+
errors.push(`CRITICAL: ${file.relativePath} missing consistent content padding`);
|
|
1065
|
+
errors.push(' - REQUIRED: Main content area must have px: "var(--spacing-4)"');
|
|
1066
|
+
errors.push(" - PATTERN: Same as account dashboard - sidebar (no margin) + content (px: var(--spacing-4))");
|
|
1067
|
+
}
|
|
1068
|
+
else if (hasNestedPadding) {
|
|
1069
|
+
categoryPagesWithIncorrectSpacing++;
|
|
1070
|
+
warnings.push(`${file.relativePath} has nested padding that may create inconsistency`);
|
|
1071
|
+
warnings.push(" - Review: Ensure padding is applied to outer container, not nested elements");
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
// 4. Check account dashboard for reference pattern
|
|
1075
|
+
const accountDashboardFiles = await scanner.findFiles(/app\/account\/dashboard\/.*Client\.tsx$/);
|
|
1076
|
+
if (accountDashboardFiles.length > 0) {
|
|
1077
|
+
const content = await scanner.readFileContent(accountDashboardFiles[0].path);
|
|
1078
|
+
if (content) {
|
|
1079
|
+
const hasCorrectPattern = /px:\s*["']var\(--spacing-4\)["']/.test(content);
|
|
1080
|
+
if (hasCorrectPattern) {
|
|
1081
|
+
info.push("${chars.check} Account dashboard uses correct spacing pattern (reference standard)");
|
|
1082
|
+
}
|
|
1083
|
+
else {
|
|
1084
|
+
warnings.push("Account dashboard spacing pattern may have changed - verify consistency");
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
// 5. Summary and requirements
|
|
1089
|
+
info.push(`Category pages with correct spacing: ${categoryPagesWithCorrectSpacing}`);
|
|
1090
|
+
if (categoryPagesWithIncorrectSpacing > 0) {
|
|
1091
|
+
errors.push(`CRITICAL: ${categoryPagesWithIncorrectSpacing} category pages have spacing inconsistencies`);
|
|
1092
|
+
errors.push("");
|
|
1093
|
+
errors.push("REQUIRED SPACING PATTERN:");
|
|
1094
|
+
errors.push(" 1. Sidebar components: NO margin-right");
|
|
1095
|
+
errors.push(' 2. Main content container: px: "var(--spacing-4)"');
|
|
1096
|
+
errors.push(" 3. Consistent with account dashboard pattern");
|
|
1097
|
+
errors.push(" 4. No nested padding in main content area");
|
|
1098
|
+
errors.push("");
|
|
1099
|
+
errors.push("REFERENCE: /account/dashboard has correct sidebar-to-content spacing");
|
|
1100
|
+
}
|
|
1101
|
+
const criticalFailures = errors.length > 0;
|
|
1102
|
+
if (criticalFailures) {
|
|
1103
|
+
errors.push("");
|
|
1104
|
+
errors.push(`${console_chars_1.emoji.bell} SIDEBAR-TO-CONTENT SPACING MUST BE CONSISTENT`);
|
|
1105
|
+
errors.push("Users expect the same spacing between sidebar and cards on all pages");
|
|
1106
|
+
errors.push("Account dashboard (/account/dashboard) is the reference standard");
|
|
1107
|
+
errors.push("Category pages (/trading-card-games/*, /sports-cards/*) must match exactly");
|
|
1108
|
+
}
|
|
1109
|
+
if (!criticalFailures) {
|
|
1110
|
+
info.push(`${console_chars_1.emoji.party} ALL PAGES HAVE CONSISTENT SIDEBAR-TO-CONTENT SPACING`);
|
|
1111
|
+
info.push("${chars.check} FilterContainer has no margin-right violations");
|
|
1112
|
+
info.push("✓ Category pages match account dashboard spacing");
|
|
1113
|
+
info.push('✓ Main content areas use consistent px: "var(--spacing-4)"');
|
|
1114
|
+
}
|
|
1115
|
+
return { passed: !criticalFailures, errors, warnings, info };
|
|
1116
|
+
}));
|
|
1117
|
+
// Header Spacing Consistency (CRITICAL) - Module not yet implemented
|
|
1118
|
+
// runner.addCheck(createCheck(
|
|
1119
|
+
// 'Header Spacing Consistency',
|
|
1120
|
+
// 'CRITICAL: Validate consistent spacing between navigation, breadcrumbs, and page headers',
|
|
1121
|
+
// async () => {
|
|
1122
|
+
// return validateHeaderSpacing() as Promise<PreflightResult>;
|
|
1123
|
+
// }
|
|
1124
|
+
// ));
|
|
1125
|
+
// KPI Box Width Consistency (CRITICAL)
|
|
1126
|
+
runner.addCheck((0, preflight_runner_1.createCheck)("KPI Box Width Consistency", "CRITICAL: Ensure all KPI/statistics boxes have consistent widths for professional appearance", async () => {
|
|
1127
|
+
const errors = [];
|
|
1128
|
+
const warnings = [];
|
|
1129
|
+
const info = [];
|
|
1130
|
+
// Find files that contain KPI/statistics boxes
|
|
1131
|
+
const kpiFiles = await scanner.findFiles(/\.(tsx|ts)$/);
|
|
1132
|
+
let filesWithInconsistentKPIs = 0;
|
|
1133
|
+
let filesWithConsistentKPIs = 0;
|
|
1134
|
+
const inconsistentFiles = [];
|
|
1135
|
+
for (const file of kpiFiles) {
|
|
1136
|
+
// Skip non-relevant files
|
|
1137
|
+
if (file.relativePath.includes("node_modules") ||
|
|
1138
|
+
file.relativePath.includes(".next") ||
|
|
1139
|
+
file.relativePath.includes("dist")) {
|
|
1140
|
+
continue;
|
|
1141
|
+
}
|
|
1142
|
+
const content = await scanner.readFileContent(file.path);
|
|
1143
|
+
if (!content)
|
|
1144
|
+
continue;
|
|
1145
|
+
// Look for KPI/statistics card patterns
|
|
1146
|
+
const hasKPICards = content.includes("Statistics Cards") ||
|
|
1147
|
+
content.includes("KPI") ||
|
|
1148
|
+
content.includes("Total Listings") ||
|
|
1149
|
+
content.includes("Active") ||
|
|
1150
|
+
content.includes("Pending") ||
|
|
1151
|
+
content.includes("Draft") ||
|
|
1152
|
+
content.includes("Sold") ||
|
|
1153
|
+
(content.includes("<Grid") &&
|
|
1154
|
+
content.includes("CardContent") &&
|
|
1155
|
+
content.includes("Typography") &&
|
|
1156
|
+
content.includes('variant="h4"'));
|
|
1157
|
+
// SPECIFIC CHECK: Admin Analytics page card consistency
|
|
1158
|
+
const isAdminAnalytics = file.relativePath.includes("admin/analytics/AdminAnalyticsClient");
|
|
1159
|
+
if (isAdminAnalytics) {
|
|
1160
|
+
// Check for consistent card width properties
|
|
1161
|
+
const hasConsistentCardWidths = content.includes("width: '100%'") &&
|
|
1162
|
+
content.includes("maxWidth: '100%'") &&
|
|
1163
|
+
content.includes("boxSizing: 'border-box'");
|
|
1164
|
+
// Check for MetricCard component with proper width styling
|
|
1165
|
+
const metricCardHasWidth = content.includes("function MetricCard") && content.includes("width: '100%'");
|
|
1166
|
+
const hasProperMetricCard = metricCardHasWidth;
|
|
1167
|
+
if (!hasConsistentCardWidths || !hasProperMetricCard) {
|
|
1168
|
+
filesWithInconsistentKPIs++;
|
|
1169
|
+
inconsistentFiles.push(file.relativePath);
|
|
1170
|
+
errors.push(`CRITICAL: ${file.relativePath} (Admin Analytics) has inconsistent card widths`);
|
|
1171
|
+
errors.push(" - ISSUE: Cards may have different visual widths due to content differences");
|
|
1172
|
+
errors.push(' - REQUIRED: All cards must have width: "100%", maxWidth: "100%", boxSizing: "border-box"');
|
|
1173
|
+
errors.push(" - REQUIRED: MetricCard component must enforce consistent dimensions");
|
|
1174
|
+
errors.push(" - IMPACT: Professional dashboard appearance requires uniform card sizes");
|
|
1175
|
+
}
|
|
1176
|
+
else {
|
|
1177
|
+
filesWithConsistentKPIs++;
|
|
1178
|
+
info.push(`${console_chars_1.chars.check} ${file.relativePath} (Admin Analytics) has consistent card widths`);
|
|
1179
|
+
}
|
|
1180
|
+
continue; // Skip general checks for this specific file
|
|
1181
|
+
}
|
|
1182
|
+
// Check for proper KPI layout patterns
|
|
1183
|
+
const hasProperGridLayout = content.includes("gridTemplateColumns: 'repeat(") ||
|
|
1184
|
+
content.includes('gridTemplateColumns: "repeat(');
|
|
1185
|
+
const hasConsistentMaterialUIGrid = content.includes("md={2.4}") &&
|
|
1186
|
+
!content.includes("md={3}") &&
|
|
1187
|
+
!content.includes("md={2}") &&
|
|
1188
|
+
!content.includes("md={4}");
|
|
1189
|
+
// Check for problematic patterns that cause width inconsistencies
|
|
1190
|
+
const hasProblematicPattern = hasKPICards &&
|
|
1191
|
+
content.includes("<Grid") &&
|
|
1192
|
+
content.includes("CardContent") &&
|
|
1193
|
+
!hasProperGridLayout &&
|
|
1194
|
+
!content.includes("height: '100%'") &&
|
|
1195
|
+
!content.includes("display: 'flex'");
|
|
1196
|
+
const hasProperKPILayout = hasProperGridLayout || hasConsistentMaterialUIGrid;
|
|
1197
|
+
if (!hasKPICards)
|
|
1198
|
+
continue;
|
|
1199
|
+
// Check for inconsistent Grid item widths in KPI sections
|
|
1200
|
+
const gridItemPattern = /<Grid\s+item[^>]*(?:xs|sm|md|lg|xl)=\{?([^}>\s]+)\}?[^>]*>/g;
|
|
1201
|
+
const gridItems = [];
|
|
1202
|
+
let match;
|
|
1203
|
+
while ((match = gridItemPattern.exec(content)) !== null) {
|
|
1204
|
+
// Look for the full Grid item tag to get all breakpoint props
|
|
1205
|
+
const fullMatch = match[0] || "";
|
|
1206
|
+
gridItems.push(fullMatch);
|
|
1207
|
+
}
|
|
1208
|
+
if (gridItems.length >= 4) {
|
|
1209
|
+
// Likely KPI boxes if 4+ grid items
|
|
1210
|
+
// Check if all grid items have consistent breakpoint values
|
|
1211
|
+
const breakpointValues = {};
|
|
1212
|
+
let hasInconsistentWidths = false;
|
|
1213
|
+
for (const item of gridItems) {
|
|
1214
|
+
// Extract breakpoint values (xs, sm, md, lg, xl)
|
|
1215
|
+
const breakpoints = ["xs", "sm", "md", "lg", "xl"];
|
|
1216
|
+
for (const bp of breakpoints) {
|
|
1217
|
+
const bpPattern = new RegExp(`${bp}=\\{?([^}\\s>]+)\\}?`);
|
|
1218
|
+
const bpMatch = item.match(bpPattern);
|
|
1219
|
+
if (bpMatch && bpMatch[1]) {
|
|
1220
|
+
if (!breakpointValues[bp]) {
|
|
1221
|
+
breakpointValues[bp] = new Set();
|
|
1222
|
+
}
|
|
1223
|
+
breakpointValues[bp].add(bpMatch[1]);
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1227
|
+
// Check for inconsistencies
|
|
1228
|
+
for (const [breakpoint, values] of Object.entries(breakpointValues)) {
|
|
1229
|
+
if (values.size > 1) {
|
|
1230
|
+
hasInconsistentWidths = true;
|
|
1231
|
+
errors.push(`CRITICAL: ${file.relativePath} has inconsistent KPI box widths at ${breakpoint} breakpoint`);
|
|
1232
|
+
errors.push(` - VALUES FOUND: ${Array.from(values).join(", ")}`);
|
|
1233
|
+
errors.push(` - REQUIRED: All KPI boxes must have identical width values`);
|
|
1234
|
+
errors.push(` - EXAMPLE: All should use md={2.4} or md={3} consistently`);
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
if (hasInconsistentWidths) {
|
|
1238
|
+
filesWithInconsistentKPIs++;
|
|
1239
|
+
inconsistentFiles.push(file.relativePath);
|
|
1240
|
+
// Show the problematic grid items
|
|
1241
|
+
errors.push(` - PROBLEMATIC GRID ITEMS:`);
|
|
1242
|
+
gridItems.slice(0, 5).forEach((item, index) => {
|
|
1243
|
+
errors.push(` ${index + 1}. ${item.substring(0, 80)}...`);
|
|
1244
|
+
});
|
|
1245
|
+
}
|
|
1246
|
+
else if (hasProblematicPattern) {
|
|
1247
|
+
// Check for problematic patterns that cause visual inconsistencies
|
|
1248
|
+
filesWithInconsistentKPIs++;
|
|
1249
|
+
inconsistentFiles.push(file.relativePath);
|
|
1250
|
+
errors.push(`CRITICAL: ${file.relativePath} has KPI boxes with problematic layout causing width inconsistencies`);
|
|
1251
|
+
errors.push(` - ISSUE: Basic Material-UI Grid without flex properties causes text-based width differences`);
|
|
1252
|
+
errors.push(` - PROBLEM: "Total Listings" text is longer than "Active", causing visual width differences`);
|
|
1253
|
+
errors.push(` - SOLUTION 1 (PREFERRED): Use CSS Grid with gridTemplateColumns: 'repeat(5, 1fr)'`);
|
|
1254
|
+
errors.push(` - SOLUTION 2: Add proper flex properties to force equal widths`);
|
|
1255
|
+
errors.push(` - EXAMPLE: <Box sx={{ display: 'grid', gridTemplateColumns: 'repeat(5, 1fr)', gap: 3 }}>`);
|
|
1256
|
+
errors.push(` - REQUIRED: All KPI boxes must appear visually identical in width`);
|
|
1257
|
+
}
|
|
1258
|
+
else if (hasKPICards && !hasProperKPILayout) {
|
|
1259
|
+
// Check for missing proper layout that ensures visual consistency
|
|
1260
|
+
filesWithInconsistentKPIs++;
|
|
1261
|
+
inconsistentFiles.push(file.relativePath);
|
|
1262
|
+
errors.push(`CRITICAL: ${file.relativePath} has KPI boxes without proper layout for equal widths`);
|
|
1263
|
+
errors.push(` - ISSUE: KPI boxes may have inconsistent visual widths due to text content differences`);
|
|
1264
|
+
errors.push(` - SOLUTION 1: Use CSS Grid with gridTemplateColumns: 'repeat(5, 1fr)' for 5 equal boxes`);
|
|
1265
|
+
errors.push(` - SOLUTION 2: Use Material-UI Grid with consistent md={2.4} for all 5 boxes`);
|
|
1266
|
+
errors.push(` - EXAMPLE: <Box sx={{ display: 'grid', gridTemplateColumns: 'repeat(5, 1fr)', gap: 3 }}>`);
|
|
1267
|
+
errors.push(` - REQUIRED: All KPI boxes must appear visually identical in width`);
|
|
1268
|
+
}
|
|
1269
|
+
else {
|
|
1270
|
+
filesWithConsistentKPIs++;
|
|
1271
|
+
info.push(`${console_chars_1.chars.check} ${file.relativePath} has consistent KPI box widths`);
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1275
|
+
// Summary
|
|
1276
|
+
info.push(`Files with consistent KPI boxes: ${filesWithConsistentKPIs}`);
|
|
1277
|
+
if (filesWithInconsistentKPIs > 0) {
|
|
1278
|
+
errors.push(`CRITICAL: ${filesWithInconsistentKPIs} files have inconsistent KPI box widths`);
|
|
1279
|
+
errors.push("");
|
|
1280
|
+
errors.push("FILES WITH INCONSISTENT KPI BOXES:");
|
|
1281
|
+
inconsistentFiles.forEach((file) => errors.push(` - ${file}`));
|
|
1282
|
+
errors.push("");
|
|
1283
|
+
errors.push("REQUIRED STANDARDS:");
|
|
1284
|
+
errors.push(" - All KPI/statistics boxes must have identical visual widths");
|
|
1285
|
+
errors.push(' - ADMIN ANALYTICS: Cards must have width: "100%", maxWidth: "100%", boxSizing: "border-box"');
|
|
1286
|
+
errors.push(' - PREFERRED: Use CSS Grid with gridTemplateColumns: "repeat(N, 1fr)"');
|
|
1287
|
+
errors.push(" - ALTERNATIVE: Use Material-UI Grid with consistent md values");
|
|
1288
|
+
errors.push(' - Example: 5 boxes = gridTemplateColumns: "repeat(5, 1fr)" OR md={2.4}');
|
|
1289
|
+
errors.push(' - Example: 4 boxes = gridTemplateColumns: "repeat(4, 1fr)" OR md={3}');
|
|
1290
|
+
errors.push(' - Example: 3 boxes = gridTemplateColumns: "repeat(3, 1fr)" OR md={4}');
|
|
1291
|
+
errors.push("");
|
|
1292
|
+
errors.push("VISUAL IMPACT: Inconsistent widths look unprofessional and break layout harmony");
|
|
1293
|
+
errors.push('TEXT CONTENT ISSUE: Longer labels like "Total Listings" vs "Active" cause width differences');
|
|
1294
|
+
}
|
|
1295
|
+
const criticalFailures = errors.length > 0;
|
|
1296
|
+
if (criticalFailures) {
|
|
1297
|
+
errors.push("");
|
|
1298
|
+
errors.push(`${console_chars_1.emoji.bell} KPI BOX WIDTH CONSISTENCY IS CRITICAL FOR PROFESSIONAL APPEARANCE`);
|
|
1299
|
+
errors.push("Users notice when dashboard elements have different widths");
|
|
1300
|
+
errors.push("All statistics/KPI boxes must be perfectly aligned and sized");
|
|
1301
|
+
errors.push("ADMIN ANALYTICS: Uniform card widths are essential for professional dashboard");
|
|
1302
|
+
}
|
|
1303
|
+
if (!criticalFailures && filesWithConsistentKPIs > 0) {
|
|
1304
|
+
info.push(`${console_chars_1.emoji.party} ALL KPI BOXES HAVE CONSISTENT WIDTHS`);
|
|
1305
|
+
info.push("${chars.check} Professional dashboard appearance maintained");
|
|
1306
|
+
info.push("✓ Grid layouts are perfectly aligned");
|
|
1307
|
+
info.push("✓ Admin Analytics cards have uniform dimensions");
|
|
1308
|
+
}
|
|
1309
|
+
return { passed: !criticalFailures, errors, warnings, info };
|
|
1310
|
+
}));
|
|
1311
|
+
// Footer Component Validation (CRITICAL)
|
|
1312
|
+
runner.addCheck((0, preflight_runner_1.createCheck)("Footer Component Validation", "CRITICAL: Ensure all admin and page components include Footer component", async () => {
|
|
1313
|
+
const errors = [];
|
|
1314
|
+
const warnings = [];
|
|
1315
|
+
const info = [];
|
|
1316
|
+
// Find all admin client components and page files
|
|
1317
|
+
const adminFiles = await scanner.findFiles(/app\/admin\/.*Client\.(tsx|ts)$/);
|
|
1318
|
+
const sellerFiles = await scanner.findFiles(/app\/seller\/.*Client\.(tsx|ts)$/);
|
|
1319
|
+
const accountFiles = await scanner.findFiles(/app\/account\/.*Client\.(tsx|ts)$/);
|
|
1320
|
+
const pageFiles = await scanner.findFiles(/app\/.*\/page\.(tsx|ts)$/);
|
|
1321
|
+
// Combine all files that should have Footer
|
|
1322
|
+
const allFilesToCheck = [...adminFiles, ...sellerFiles, ...accountFiles, ...pageFiles];
|
|
1323
|
+
let filesWithFooter = 0;
|
|
1324
|
+
let filesWithoutFooter = 0;
|
|
1325
|
+
const missingFooterFiles = [];
|
|
1326
|
+
const correctFooterFiles = [];
|
|
1327
|
+
for (const file of allFilesToCheck) {
|
|
1328
|
+
// Skip API routes and certain system files
|
|
1329
|
+
if (file.relativePath.includes("/api/") ||
|
|
1330
|
+
file.relativePath.includes("/login") ||
|
|
1331
|
+
file.relativePath.includes("/register") ||
|
|
1332
|
+
file.relativePath.includes("/not-found") ||
|
|
1333
|
+
file.relativePath.includes("/loading") ||
|
|
1334
|
+
file.relativePath.includes("/error")) {
|
|
1335
|
+
continue;
|
|
1336
|
+
}
|
|
1337
|
+
const content = await scanner.readFileContent(file.path);
|
|
1338
|
+
if (!content)
|
|
1339
|
+
continue;
|
|
1340
|
+
// Check if file imports Footer
|
|
1341
|
+
const importsFooter = content.includes("import { Footer }") ||
|
|
1342
|
+
(content.includes("import {") && content.includes("Footer"));
|
|
1343
|
+
// Check if file renders Footer component
|
|
1344
|
+
const rendersFooter = content.includes("<Footer />") || content.includes("<Footer>");
|
|
1345
|
+
if (importsFooter && rendersFooter) {
|
|
1346
|
+
filesWithFooter++;
|
|
1347
|
+
correctFooterFiles.push(file.relativePath);
|
|
1348
|
+
info.push(`✓ ${file.relativePath} includes Footer component`);
|
|
1349
|
+
}
|
|
1350
|
+
else if (importsFooter && !rendersFooter) {
|
|
1351
|
+
filesWithoutFooter++;
|
|
1352
|
+
missingFooterFiles.push(file.relativePath);
|
|
1353
|
+
errors.push(`CRITICAL: ${file.relativePath} imports Footer but doesn't render it`);
|
|
1354
|
+
errors.push(" - ISSUE: Footer is imported but not included in JSX");
|
|
1355
|
+
errors.push(" - REQUIRED: Add <Footer /> before closing </PageLayout>");
|
|
1356
|
+
}
|
|
1357
|
+
else if (!importsFooter && !rendersFooter) {
|
|
1358
|
+
// Check if this is a page that should have Footer
|
|
1359
|
+
const isPageThatNeedsFooter = file.relativePath.includes("/admin/") ||
|
|
1360
|
+
file.relativePath.includes("/store/") ||
|
|
1361
|
+
file.relativePath.includes("/account/") ||
|
|
1362
|
+
(file.relativePath.includes("/page.") &&
|
|
1363
|
+
!file.relativePath.includes("/(auth)/") &&
|
|
1364
|
+
!file.relativePath.includes("/api/"));
|
|
1365
|
+
if (isPageThatNeedsFooter) {
|
|
1366
|
+
filesWithoutFooter++;
|
|
1367
|
+
missingFooterFiles.push(file.relativePath);
|
|
1368
|
+
errors.push(`CRITICAL: ${file.relativePath} missing Footer component`);
|
|
1369
|
+
errors.push(' - REQUIRED: Import Footer from "@/components/Footer"');
|
|
1370
|
+
errors.push(" - REQUIRED: Add <Footer /> before closing </PageLayout>");
|
|
1371
|
+
}
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
// Summary
|
|
1375
|
+
info.push(`Files with Footer component: ${filesWithFooter}`);
|
|
1376
|
+
if (filesWithoutFooter > 0) {
|
|
1377
|
+
errors.push(`CRITICAL: ${filesWithoutFooter} files are missing Footer component`);
|
|
1378
|
+
errors.push("");
|
|
1379
|
+
errors.push("FILES MISSING FOOTER:");
|
|
1380
|
+
missingFooterFiles.forEach((file) => errors.push(` - ${file}`));
|
|
1381
|
+
errors.push("");
|
|
1382
|
+
errors.push("REQUIRED PATTERN:");
|
|
1383
|
+
errors.push(' 1. Import: import { Footer } from "@/components/Footer";');
|
|
1384
|
+
errors.push(" 2. Render: <Footer /> before closing </PageLayout>");
|
|
1385
|
+
errors.push(" 3. ALL admin, seller, and account pages must have Footer");
|
|
1386
|
+
errors.push("");
|
|
1387
|
+
errors.push("REFERENCE: Other admin pages like /admin/users show correct pattern");
|
|
1388
|
+
}
|
|
1389
|
+
const criticalFailures = errors.length > 0;
|
|
1390
|
+
if (criticalFailures) {
|
|
1391
|
+
errors.push("");
|
|
1392
|
+
errors.push(`${console_chars_1.emoji.bell} FOOTER COMPONENT IS MANDATORY FOR ALL PAGES`);
|
|
1393
|
+
errors.push("Footer provides consistent navigation and branding");
|
|
1394
|
+
errors.push("Users expect Footer on every page for complete user experience");
|
|
1395
|
+
errors.push("NO EXCEPTIONS - Every page must include Footer component");
|
|
1396
|
+
}
|
|
1397
|
+
if (!criticalFailures && filesWithFooter > 0) {
|
|
1398
|
+
info.push(`${console_chars_1.emoji.party} ALL PAGES INCLUDE FOOTER COMPONENT`);
|
|
1399
|
+
info.push("${chars.check} Consistent page structure maintained");
|
|
1400
|
+
info.push("✓ Complete user experience provided");
|
|
1401
|
+
}
|
|
1402
|
+
return { passed: !criticalFailures, errors, warnings, info };
|
|
1403
|
+
}));
|
|
1404
|
+
// Footer Spacing Consistency (CRITICAL)
|
|
1405
|
+
runner.addCheck((0, preflight_runner_1.createCheck)("Footer Spacing Consistency", "CRITICAL: Ensure consistent spacing between last content element and Footer component", async () => {
|
|
1406
|
+
const errors = [];
|
|
1407
|
+
const warnings = [];
|
|
1408
|
+
const info = [];
|
|
1409
|
+
const pageFiles = await scanner.findFiles(/app[\\/].+[\\/]page\.tsx$/);
|
|
1410
|
+
let filesChecked = 0;
|
|
1411
|
+
let filesWithFooter = 0;
|
|
1412
|
+
let filesWithProperSpacing = 0;
|
|
1413
|
+
let criticalFailures = false;
|
|
1414
|
+
for (const file of pageFiles) {
|
|
1415
|
+
const content = await scanner.readFileContent(file.path);
|
|
1416
|
+
if (!content)
|
|
1417
|
+
continue;
|
|
1418
|
+
filesChecked++;
|
|
1419
|
+
// Skip if file doesn't use Footer component
|
|
1420
|
+
if (!content.includes("<Footer")) {
|
|
1421
|
+
continue;
|
|
1422
|
+
}
|
|
1423
|
+
filesWithFooter++;
|
|
1424
|
+
// Check for proper bottom padding before Footer
|
|
1425
|
+
// Pattern 1: Main content Box with pb: "var(--spacing-8)"
|
|
1426
|
+
const hasProperBoxSpacing = /sx=\{\{[^}]*pb:\s*"var\(--spacing-8\)"[^}]*\}\}/.test(content);
|
|
1427
|
+
// Pattern 2: PageLayout with pb: "var(--spacing-8)"
|
|
1428
|
+
const hasProperLayoutSpacing = /<PageLayout[^>]*sx=\{\{[^}]*pb:\s*"var\(--spacing-8\)"[^}]*\}\}/.test(content);
|
|
1429
|
+
if (hasProperBoxSpacing || hasProperLayoutSpacing) {
|
|
1430
|
+
filesWithProperSpacing++;
|
|
1431
|
+
}
|
|
1432
|
+
else {
|
|
1433
|
+
// Check if there's any bottom padding at all
|
|
1434
|
+
const hasAnyBottomPadding = /pb:\s*"var\(--spacing-\d+\)"|pb:\s*\d+/.test(content);
|
|
1435
|
+
if (!hasAnyBottomPadding) {
|
|
1436
|
+
errors.push(`${console_chars_1.emoji.error} CRITICAL: ${file.relativePath}`);
|
|
1437
|
+
errors.push(` No bottom padding found before Footer component`);
|
|
1438
|
+
errors.push(` ${console_chars_1.emoji.hint} Add pb: "var(--spacing-8)" to the main content Box`);
|
|
1439
|
+
criticalFailures = true;
|
|
1440
|
+
}
|
|
1441
|
+
else {
|
|
1442
|
+
warnings.push(`${console_chars_1.emoji.warning} ${file.relativePath}`);
|
|
1443
|
+
warnings.push(` Bottom padding found but not using standard var(--spacing-8)`);
|
|
1444
|
+
warnings.push(` ${console_chars_1.emoji.hint} Use pb: "var(--spacing-8)" for consistency`);
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
}
|
|
1448
|
+
info.push(`${console_chars_1.emoji.chart} Footer Spacing Statistics:`);
|
|
1449
|
+
info.push(` Files checked: ${filesChecked}`);
|
|
1450
|
+
info.push(` Files with Footer: ${filesWithFooter}`);
|
|
1451
|
+
info.push(` Files with proper spacing: ${filesWithProperSpacing}`);
|
|
1452
|
+
if (criticalFailures) {
|
|
1453
|
+
errors.push("");
|
|
1454
|
+
errors.push(`${console_chars_1.emoji.bell} CRITICAL: Footer spacing violations detected`);
|
|
1455
|
+
errors.push("");
|
|
1456
|
+
errors.push(`${console_chars_1.emoji.clipboard} Required Pattern:`);
|
|
1457
|
+
errors.push(' <Box sx={{ px: "var(--spacing-4)", pb: "var(--spacing-8)" }}>');
|
|
1458
|
+
errors.push(" {/* Page content */}");
|
|
1459
|
+
errors.push(" </Box>");
|
|
1460
|
+
errors.push(" <Footer />");
|
|
1461
|
+
}
|
|
1462
|
+
if (!criticalFailures && filesWithFooter > 0) {
|
|
1463
|
+
info.push("");
|
|
1464
|
+
info.push(`${console_chars_1.emoji.success} ALL PAGES HAVE PROPER FOOTER SPACING`);
|
|
1465
|
+
info.push("${chars.check} Consistent spacing maintained across all pages");
|
|
1466
|
+
info.push("✓ Professional appearance with proper gaps");
|
|
1467
|
+
}
|
|
1468
|
+
return { passed: !criticalFailures, errors, warnings, info };
|
|
1469
|
+
}));
|
|
1470
|
+
// Header-to-Breadcrumbs Spacing Consistency (CRITICAL)
|
|
1471
|
+
runner.addCheck((0, preflight_runner_1.createCheck)("Header-to-Breadcrumbs Spacing Consistency", "CRITICAL: Ensure consistent spacing between UnifiedHeader navigation and Breadcrumbs across all pages", async () => {
|
|
1472
|
+
const errors = [];
|
|
1473
|
+
const warnings = [];
|
|
1474
|
+
const info = [];
|
|
1475
|
+
// Find all client components that have both UnifiedHeader and Breadcrumbs
|
|
1476
|
+
const clientFiles = await scanner.findFiles(/Client\.(tsx|ts)$/);
|
|
1477
|
+
let pagesWithCorrectSpacing = 0;
|
|
1478
|
+
let pagesWithIncorrectSpacing = 0;
|
|
1479
|
+
const incorrectPages = [];
|
|
1480
|
+
const correctPages = [];
|
|
1481
|
+
for (const file of clientFiles) {
|
|
1482
|
+
// Skip non-page client files
|
|
1483
|
+
if (file.relativePath.includes("/components/") || file.relativePath.includes("/lib/")) {
|
|
1484
|
+
continue;
|
|
1485
|
+
}
|
|
1486
|
+
const content = await scanner.readFileContent(file.path);
|
|
1487
|
+
if (!content)
|
|
1488
|
+
continue;
|
|
1489
|
+
// Check if file has both UnifiedHeader navigation and Breadcrumbs
|
|
1490
|
+
const hasNavigationHeader = content.includes("UnifiedHeader") && content.includes('variant="navigation"');
|
|
1491
|
+
const hasBreadcrumbs = content.includes("<Breadcrumbs");
|
|
1492
|
+
if (!hasNavigationHeader || !hasBreadcrumbs) {
|
|
1493
|
+
continue; // Skip files that don't have both components
|
|
1494
|
+
}
|
|
1495
|
+
// Check for problematic patterns that create extra spacing
|
|
1496
|
+
const problematicPatterns = [
|
|
1497
|
+
// Main content container with py padding after breadcrumbs
|
|
1498
|
+
/px:\s*["']var\(--spacing-4\)["'][^}]*,\s*py:\s*["']var\(--spacing-4\)["']/g,
|
|
1499
|
+
// Explicit vertical padding in main content after breadcrumbs
|
|
1500
|
+
/Breadcrumbs[^}]*\}[^<]*<[^>]*sx=\{[^}]*py:\s*["']var\(--spacing-[1-9]\)["']/g,
|
|
1501
|
+
// Padding top in main content container
|
|
1502
|
+
/px:\s*["']var\(--spacing-4\)["'][^}]*,\s*pt:\s*["']var\(--spacing-[1-9]\)["']/g,
|
|
1503
|
+
];
|
|
1504
|
+
let hasSpacingIssue = false;
|
|
1505
|
+
for (const pattern of problematicPatterns) {
|
|
1506
|
+
const matches = content.match(pattern);
|
|
1507
|
+
if (matches) {
|
|
1508
|
+
hasSpacingIssue = true;
|
|
1509
|
+
pagesWithIncorrectSpacing++;
|
|
1510
|
+
incorrectPages.push(file.relativePath);
|
|
1511
|
+
errors.push(`CRITICAL: ${file.relativePath} has extra vertical padding creating inconsistent header-to-breadcrumbs spacing`);
|
|
1512
|
+
matches.forEach((match) => {
|
|
1513
|
+
errors.push(` - VIOLATION: ${match.substring(0, 80)}...`);
|
|
1514
|
+
});
|
|
1515
|
+
errors.push(" - REQUIRED: Remove py/pt padding from main content container");
|
|
1516
|
+
errors.push(' - STANDARD: Only use px: "var(--spacing-4)" for horizontal padding');
|
|
1517
|
+
break;
|
|
1518
|
+
}
|
|
1519
|
+
}
|
|
1520
|
+
if (!hasSpacingIssue) {
|
|
1521
|
+
pagesWithCorrectSpacing++;
|
|
1522
|
+
correctPages.push(file.relativePath);
|
|
1523
|
+
info.push(`${console_chars_1.chars.check} ${file.relativePath} has correct header-to-breadcrumbs spacing`);
|
|
1524
|
+
}
|
|
1525
|
+
}
|
|
1526
|
+
// Summary
|
|
1527
|
+
info.push(`Pages with correct header-breadcrumbs spacing: ${pagesWithCorrectSpacing}`);
|
|
1528
|
+
if (pagesWithIncorrectSpacing > 0) {
|
|
1529
|
+
errors.push(`CRITICAL: ${pagesWithIncorrectSpacing} pages have inconsistent header-to-breadcrumbs spacing`);
|
|
1530
|
+
errors.push("");
|
|
1531
|
+
errors.push("PAGES WITH INCORRECT SPACING:");
|
|
1532
|
+
incorrectPages.forEach((page) => errors.push(` - ${page}`));
|
|
1533
|
+
errors.push("");
|
|
1534
|
+
errors.push("REQUIRED PATTERN:");
|
|
1535
|
+
errors.push(' 1. UnifiedHeader variant="navigation" (no extra spacing)');
|
|
1536
|
+
errors.push(" 2. Breadcrumbs component (py: 1 only)");
|
|
1537
|
+
errors.push(' 3. Main content: px: "var(--spacing-4)" ONLY (no py/pt)');
|
|
1538
|
+
errors.push(' 4. UnifiedHeader variant="page" provides its own top spacing');
|
|
1539
|
+
errors.push("");
|
|
1540
|
+
errors.push("REFERENCE: /seller/listings has correct spacing pattern");
|
|
1541
|
+
}
|
|
1542
|
+
const criticalFailures = errors.length > 0;
|
|
1543
|
+
if (criticalFailures) {
|
|
1544
|
+
errors.push("");
|
|
1545
|
+
errors.push(`${console_chars_1.emoji.bell} HEADER-TO-BREADCRUMBS SPACING MUST BE CONSISTENT`);
|
|
1546
|
+
errors.push("Extra vertical padding in main content creates visual inconsistency");
|
|
1547
|
+
errors.push("Users expect the same gap between header and breadcrumbs on all pages");
|
|
1548
|
+
errors.push("Only horizontal padding (px) should be used in main content containers");
|
|
1549
|
+
}
|
|
1550
|
+
if (!criticalFailures && pagesWithCorrectSpacing > 0) {
|
|
1551
|
+
info.push(`${console_chars_1.emoji.party} ALL PAGES HAVE CONSISTENT HEADER-TO-BREADCRUMBS SPACING`);
|
|
1552
|
+
info.push("${chars.check} No extra vertical padding in main content containers");
|
|
1553
|
+
info.push("✓ Consistent gap between navigation header and breadcrumbs");
|
|
1554
|
+
info.push("✓ UnifiedHeader page variants provide proper top spacing");
|
|
1555
|
+
}
|
|
1556
|
+
return { passed: !criticalFailures, errors, warnings, info };
|
|
1557
|
+
}));
|
|
1558
|
+
// Unified Badge System Consistency (CRITICAL)
|
|
1559
|
+
runner.addCheck((0, preflight_runner_1.createCheck)("Unified Badge System", "CRITICAL: Validate all badge components use the unified system", async () => {
|
|
1560
|
+
console.log(`${console_chars_1.emoji.search} Running Unified Badge System check...`);
|
|
1561
|
+
// Run the specialized badge consistency check
|
|
1562
|
+
const badgeCheckResult = await (0, unified_badge_consistency_1.runUnifiedBadgeConsistencyCheck)();
|
|
1563
|
+
// Extract results from the badge check
|
|
1564
|
+
const errors = [];
|
|
1565
|
+
const warnings = [];
|
|
1566
|
+
const info = [];
|
|
1567
|
+
if (!badgeCheckResult.passed) {
|
|
1568
|
+
errors.push(`${console_chars_1.emoji.bell} UNIFIED BADGE SYSTEM VALIDATION FAILED`);
|
|
1569
|
+
errors.push("All badge components must use UnifiedHeaderBadge system");
|
|
1570
|
+
errors.push("Legacy HeaderBadge and EnhancedHeaderBadge components must be removed");
|
|
1571
|
+
errors.push("Run: pnpm preflight:unified-badge-consistency for details");
|
|
1572
|
+
}
|
|
1573
|
+
else {
|
|
1574
|
+
info.push(`${console_chars_1.emoji.success} UNIFIED BADGE SYSTEM VALIDATION PASSED`);
|
|
1575
|
+
info.push("${chars.check} All badge components use the unified system");
|
|
1576
|
+
info.push("✓ Legacy components properly removed");
|
|
1577
|
+
info.push("✓ Consistent styling across all pages");
|
|
1578
|
+
}
|
|
1579
|
+
return { passed: badgeCheckResult.passed, errors, warnings, info };
|
|
1580
|
+
}));
|
|
1581
|
+
// StatusChip Icon Sizing Consistency
|
|
1582
|
+
runner.addCheck((0, preflight_runner_1.createCheck)("StatusChip Icon Sizing", "Validate icons passed to StatusChip use consistent sizing", async () => {
|
|
1583
|
+
console.log(`${console_chars_1.emoji.search} Running StatusChip Icon Sizing check...`);
|
|
1584
|
+
const errors = [];
|
|
1585
|
+
const warnings = [];
|
|
1586
|
+
const info = [];
|
|
1587
|
+
const componentFiles = await scanner.findComponentFiles();
|
|
1588
|
+
let totalStatusChipWithIcons = 0;
|
|
1589
|
+
let unsizedIcons = 0;
|
|
1590
|
+
const filesWithUnsizedIcons = [];
|
|
1591
|
+
// Pattern to find StatusChip with icon prop
|
|
1592
|
+
const statusChipIconPattern = /<StatusChip[^>]*icon=\{<(\w+)([^}]*)\}/g;
|
|
1593
|
+
// Pattern to check if icon has size prop
|
|
1594
|
+
const iconWithSizePattern = /size=\{?\d+\}?/;
|
|
1595
|
+
for (const file of componentFiles) {
|
|
1596
|
+
const content = await scanner.readFileContent(file.path);
|
|
1597
|
+
if (!content)
|
|
1598
|
+
continue;
|
|
1599
|
+
// Find all StatusChip usages with icons
|
|
1600
|
+
const matches = [...content.matchAll(statusChipIconPattern)];
|
|
1601
|
+
for (const match of matches) {
|
|
1602
|
+
totalStatusChipWithIcons++;
|
|
1603
|
+
const iconProps = match[2] || "";
|
|
1604
|
+
// Check if icon has explicit size
|
|
1605
|
+
if (!iconWithSizePattern.test(iconProps)) {
|
|
1606
|
+
unsizedIcons++;
|
|
1607
|
+
if (!filesWithUnsizedIcons.includes(file.relativePath)) {
|
|
1608
|
+
filesWithUnsizedIcons.push(file.relativePath);
|
|
1609
|
+
}
|
|
1610
|
+
warnings.push(`${file.relativePath}: StatusChip icon without explicit size (auto-sized by component)`);
|
|
1611
|
+
}
|
|
1612
|
+
}
|
|
1613
|
+
}
|
|
1614
|
+
// Summary
|
|
1615
|
+
info.push(`StatusChip usages with icons: ${totalStatusChipWithIcons}`);
|
|
1616
|
+
if (unsizedIcons > 0) {
|
|
1617
|
+
info.push(`Icons without explicit size: ${unsizedIcons} (auto-sized by StatusChip)`);
|
|
1618
|
+
info.push("Note: StatusChip now auto-sizes icons, but explicit sizing is recommended for clarity");
|
|
1619
|
+
info.push("Recommended pattern: icon={<IconName size={14} />} for sm chips");
|
|
1620
|
+
}
|
|
1621
|
+
else if (totalStatusChipWithIcons > 0) {
|
|
1622
|
+
info.push(`${console_chars_1.emoji.success} All StatusChip icons have explicit sizing`);
|
|
1623
|
+
}
|
|
1624
|
+
// This is a warning-only check, not blocking
|
|
1625
|
+
return { passed: true, errors, warnings, info };
|
|
1626
|
+
}));
|
|
1627
|
+
// Hydration Mismatch Prevention (CRITICAL)
|
|
1628
|
+
runner.addCheck((0, preflight_runner_1.createCheck)("Hydration Mismatch Prevention", "CRITICAL: Detect potential hydration mismatches before they cause runtime errors", async () => {
|
|
1629
|
+
console.log(`${console_chars_1.emoji.search} Running Hydration Mismatch Prevention check...`);
|
|
1630
|
+
try {
|
|
1631
|
+
const { HydrationMismatchChecker } = await Promise.resolve().then(() => __importStar(require("./hydration-mismatch-check.js")));
|
|
1632
|
+
const checker = new HydrationMismatchChecker();
|
|
1633
|
+
// Run the hydration check and capture results
|
|
1634
|
+
let checkPassed = true;
|
|
1635
|
+
let capturedOutput = [];
|
|
1636
|
+
// Override console methods to capture output
|
|
1637
|
+
const originalLog = console.log;
|
|
1638
|
+
const originalError = console.error;
|
|
1639
|
+
const originalExit = process.exit;
|
|
1640
|
+
// Prevent actual process exit during preflight
|
|
1641
|
+
process.exit = ((code) => {
|
|
1642
|
+
checkPassed = code === 0;
|
|
1643
|
+
throw new Error(`HydrationCheckExit:${code}`);
|
|
1644
|
+
});
|
|
1645
|
+
// Capture console output
|
|
1646
|
+
console.log = (...args) => {
|
|
1647
|
+
capturedOutput.push(args.join(" "));
|
|
1648
|
+
};
|
|
1649
|
+
console.error = (...args) => {
|
|
1650
|
+
capturedOutput.push(`ERROR: ${args.join(" ")}`);
|
|
1651
|
+
};
|
|
1652
|
+
try {
|
|
1653
|
+
await checker.run();
|
|
1654
|
+
}
|
|
1655
|
+
catch (error) {
|
|
1656
|
+
// Check if this is our controlled exit
|
|
1657
|
+
if (error.message.includes("HydrationCheckExit:")) {
|
|
1658
|
+
const exitCode = parseInt(error.message.split(":")[1]);
|
|
1659
|
+
checkPassed = exitCode === 0;
|
|
1660
|
+
}
|
|
1661
|
+
else {
|
|
1662
|
+
throw error;
|
|
1663
|
+
}
|
|
1664
|
+
}
|
|
1665
|
+
finally {
|
|
1666
|
+
// Restore original methods
|
|
1667
|
+
console.log = originalLog;
|
|
1668
|
+
console.error = originalError;
|
|
1669
|
+
process.exit = originalExit;
|
|
1670
|
+
}
|
|
1671
|
+
// Process captured output
|
|
1672
|
+
const errors = [];
|
|
1673
|
+
const warnings = [];
|
|
1674
|
+
const info = [];
|
|
1675
|
+
for (const line of capturedOutput) {
|
|
1676
|
+
if (line.includes(`${console_chars_1.emoji.bell}`) ||
|
|
1677
|
+
line.includes("CRITICAL") ||
|
|
1678
|
+
line.includes("ERROR:")) {
|
|
1679
|
+
errors.push(line.replace("ERROR: ", ""));
|
|
1680
|
+
}
|
|
1681
|
+
else if (line.includes(`${console_chars_1.emoji.warning}`) || line.includes("WARNING")) {
|
|
1682
|
+
warnings.push(line);
|
|
1683
|
+
}
|
|
1684
|
+
else if (line.includes(`${console_chars_1.emoji.success}`) ||
|
|
1685
|
+
line.includes("${chars.check}") ||
|
|
1686
|
+
line.includes("INFO")) {
|
|
1687
|
+
info.push(line);
|
|
1688
|
+
}
|
|
1689
|
+
}
|
|
1690
|
+
// Add summary information
|
|
1691
|
+
if (checkPassed && errors.length === 0) {
|
|
1692
|
+
info.push(`${console_chars_1.emoji.success} HYDRATION MISMATCH PREVENTION PASSED`);
|
|
1693
|
+
info.push("${chars.check} No critical hydration mismatch patterns detected");
|
|
1694
|
+
info.push("✓ Client-side APIs are properly guarded");
|
|
1695
|
+
info.push("✓ Date/time operations are consistent");
|
|
1696
|
+
info.push("✓ No non-deterministic functions in render");
|
|
1697
|
+
}
|
|
1698
|
+
else {
|
|
1699
|
+
errors.push(`${console_chars_1.emoji.bell} HYDRATION MISMATCH PREVENTION FAILED`);
|
|
1700
|
+
errors.push("Critical hydration issues detected that WILL cause runtime errors");
|
|
1701
|
+
errors.push("These patterns MUST be fixed before deployment:");
|
|
1702
|
+
errors.push(' ${chars.bullet} Wrap client-side APIs in typeof window !== "undefined" checks');
|
|
1703
|
+
errors.push(" • Move dynamic operations to useEffect hooks");
|
|
1704
|
+
errors.push(" • Use consistent date/number formatting");
|
|
1705
|
+
errors.push(" • Ensure initial state matches between server and client");
|
|
1706
|
+
}
|
|
1707
|
+
return {
|
|
1708
|
+
passed: checkPassed && errors.length === 0,
|
|
1709
|
+
errors,
|
|
1710
|
+
warnings,
|
|
1711
|
+
info,
|
|
1712
|
+
};
|
|
1713
|
+
}
|
|
1714
|
+
catch (error) {
|
|
1715
|
+
return {
|
|
1716
|
+
passed: false,
|
|
1717
|
+
errors: [`Failed to run hydration mismatch check: ${error}`],
|
|
1718
|
+
warnings: [],
|
|
1719
|
+
info: [],
|
|
1720
|
+
};
|
|
1721
|
+
}
|
|
1722
|
+
}));
|
|
1723
|
+
const result = await runner.runAll();
|
|
1724
|
+
if (!result.passed) {
|
|
1725
|
+
console.log(`\n${console_chars_1.emoji.bell} UI Quality preflight checks failed!`);
|
|
1726
|
+
process.exit(1);
|
|
1727
|
+
}
|
|
1728
|
+
console.log(`\n${console_chars_1.emoji.palette} All UI Quality preflight checks passed!`);
|
|
1729
|
+
return result;
|
|
1730
|
+
}
|
|
1731
|
+
// Run if called directly
|
|
1732
|
+
if (require.main === module) {
|
|
1733
|
+
runUIQualityPreflights().catch(console.error);
|
|
1734
|
+
}
|
|
1735
|
+
exports.default = runUIQualityPreflights;
|
|
1736
|
+
//# sourceMappingURL=ui-quality.js.map
|