@memberjunction/react-linter 0.0.1 → 5.38.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/component-linter.d.ts +77 -0
- package/dist/component-linter.d.ts.map +1 -0
- package/dist/component-linter.js +1206 -0
- package/dist/component-linter.js.map +1 -0
- package/dist/control-flow-analyzer.d.ts +184 -0
- package/dist/control-flow-analyzer.d.ts.map +1 -0
- package/dist/control-flow-analyzer.js +798 -0
- package/dist/control-flow-analyzer.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/library-lint-cache.d.ts +50 -0
- package/dist/library-lint-cache.d.ts.map +1 -0
- package/dist/library-lint-cache.js +173 -0
- package/dist/library-lint-cache.js.map +1 -0
- package/dist/lint-rule.d.ts +70 -0
- package/dist/lint-rule.d.ts.map +1 -0
- package/dist/lint-rule.js +30 -0
- package/dist/lint-rule.js.map +1 -0
- package/dist/lint-utils.d.ts +131 -0
- package/dist/lint-utils.d.ts.map +1 -0
- package/dist/lint-utils.js +358 -0
- package/dist/lint-utils.js.map +1 -0
- package/dist/linter-options.d.ts +51 -0
- package/dist/linter-options.d.ts.map +1 -0
- package/dist/linter-options.js +2 -0
- package/dist/linter-options.js.map +1 -0
- package/dist/prop-value-extractor.d.ts +147 -0
- package/dist/prop-value-extractor.d.ts.map +1 -0
- package/dist/prop-value-extractor.js +472 -0
- package/dist/prop-value-extractor.js.map +1 -0
- package/dist/runtime-rules/ai-tools-availability-check.d.ts +9 -0
- package/dist/runtime-rules/ai-tools-availability-check.d.ts.map +1 -0
- package/dist/runtime-rules/ai-tools-availability-check.js +223 -0
- package/dist/runtime-rules/ai-tools-availability-check.js.map +1 -0
- package/dist/runtime-rules/callback-event-validation.d.ts +22 -0
- package/dist/runtime-rules/callback-event-validation.d.ts.map +1 -0
- package/dist/runtime-rules/callback-event-validation.js +561 -0
- package/dist/runtime-rules/callback-event-validation.js.map +1 -0
- package/dist/runtime-rules/chart-field-validation.d.ts +10 -0
- package/dist/runtime-rules/chart-field-validation.d.ts.map +1 -0
- package/dist/runtime-rules/chart-field-validation.js +270 -0
- package/dist/runtime-rules/chart-field-validation.js.map +1 -0
- package/dist/runtime-rules/child-component-prop-validation.d.ts +11 -0
- package/dist/runtime-rules/child-component-prop-validation.d.ts.map +1 -0
- package/dist/runtime-rules/child-component-prop-validation.js +443 -0
- package/dist/runtime-rules/child-component-prop-validation.js.map +1 -0
- package/dist/runtime-rules/component-name-mismatch.d.ts +19 -0
- package/dist/runtime-rules/component-name-mismatch.d.ts.map +1 -0
- package/dist/runtime-rules/component-name-mismatch.js +82 -0
- package/dist/runtime-rules/component-name-mismatch.js.map +1 -0
- package/dist/runtime-rules/component-not-in-dependencies.d.ts +20 -0
- package/dist/runtime-rules/component-not-in-dependencies.d.ts.map +1 -0
- package/dist/runtime-rules/component-not-in-dependencies.js +92 -0
- package/dist/runtime-rules/component-not-in-dependencies.js.map +1 -0
- package/dist/runtime-rules/component-props-validation.d.ts +25 -0
- package/dist/runtime-rules/component-props-validation.d.ts.map +1 -0
- package/dist/runtime-rules/component-props-validation.js +228 -0
- package/dist/runtime-rules/component-props-validation.js.map +1 -0
- package/dist/runtime-rules/component-usage-without-destructuring.d.ts +20 -0
- package/dist/runtime-rules/component-usage-without-destructuring.d.ts.map +1 -0
- package/dist/runtime-rules/component-usage-without-destructuring.js +124 -0
- package/dist/runtime-rules/component-usage-without-destructuring.js.map +1 -0
- package/dist/runtime-rules/data-result-validation.d.ts +9 -0
- package/dist/runtime-rules/data-result-validation.d.ts.map +1 -0
- package/dist/runtime-rules/data-result-validation.js +763 -0
- package/dist/runtime-rules/data-result-validation.js.map +1 -0
- package/dist/runtime-rules/datagrid-field-validation.d.ts +10 -0
- package/dist/runtime-rules/datagrid-field-validation.d.ts.map +1 -0
- package/dist/runtime-rules/datagrid-field-validation.js +249 -0
- package/dist/runtime-rules/datagrid-field-validation.js.map +1 -0
- package/dist/runtime-rules/dependency-shadowing.d.ts +20 -0
- package/dist/runtime-rules/dependency-shadowing.d.ts.map +1 -0
- package/dist/runtime-rules/dependency-shadowing.js +147 -0
- package/dist/runtime-rules/dependency-shadowing.js.map +1 -0
- package/dist/runtime-rules/entity-field-access-validation.d.ts +12 -0
- package/dist/runtime-rules/entity-field-access-validation.d.ts.map +1 -0
- package/dist/runtime-rules/entity-field-access-validation.js +304 -0
- package/dist/runtime-rules/entity-field-access-validation.js.map +1 -0
- package/dist/runtime-rules/event-parameter-validation.d.ts +22 -0
- package/dist/runtime-rules/event-parameter-validation.d.ts.map +1 -0
- package/dist/runtime-rules/event-parameter-validation.js +406 -0
- package/dist/runtime-rules/event-parameter-validation.js.map +1 -0
- package/dist/runtime-rules/index.d.ts +61 -0
- package/dist/runtime-rules/index.d.ts.map +1 -0
- package/dist/runtime-rules/index.js +62 -0
- package/dist/runtime-rules/index.js.map +1 -0
- package/dist/runtime-rules/library-variable-names.d.ts +24 -0
- package/dist/runtime-rules/library-variable-names.d.ts.map +1 -0
- package/dist/runtime-rules/library-variable-names.js +88 -0
- package/dist/runtime-rules/library-variable-names.js.map +1 -0
- package/dist/runtime-rules/no-child-implementation.d.ts +18 -0
- package/dist/runtime-rules/no-child-implementation.d.ts.map +1 -0
- package/dist/runtime-rules/no-child-implementation.js +57 -0
- package/dist/runtime-rules/no-child-implementation.js.map +1 -0
- package/dist/runtime-rules/no-data-prop.d.ts +22 -0
- package/dist/runtime-rules/no-data-prop.d.ts.map +1 -0
- package/dist/runtime-rules/no-data-prop.js +111 -0
- package/dist/runtime-rules/no-data-prop.js.map +1 -0
- package/dist/runtime-rules/no-export-statements.d.ts +18 -0
- package/dist/runtime-rules/no-export-statements.d.ts.map +1 -0
- package/dist/runtime-rules/no-export-statements.js +143 -0
- package/dist/runtime-rules/no-export-statements.js.map +1 -0
- package/dist/runtime-rules/no-iife-wrapper.d.ts +18 -0
- package/dist/runtime-rules/no-iife-wrapper.d.ts.map +1 -0
- package/dist/runtime-rules/no-iife-wrapper.js +217 -0
- package/dist/runtime-rules/no-iife-wrapper.js.map +1 -0
- package/dist/runtime-rules/no-import-statements.d.ts +18 -0
- package/dist/runtime-rules/no-import-statements.d.ts.map +1 -0
- package/dist/runtime-rules/no-import-statements.js +65 -0
- package/dist/runtime-rules/no-import-statements.js.map +1 -0
- package/dist/runtime-rules/no-react-destructuring.d.ts +18 -0
- package/dist/runtime-rules/no-react-destructuring.d.ts.map +1 -0
- package/dist/runtime-rules/no-react-destructuring.js +60 -0
- package/dist/runtime-rules/no-react-destructuring.js.map +1 -0
- package/dist/runtime-rules/no-require-statements.d.ts +18 -0
- package/dist/runtime-rules/no-require-statements.d.ts.map +1 -0
- package/dist/runtime-rules/no-require-statements.js +109 -0
- package/dist/runtime-rules/no-require-statements.js.map +1 -0
- package/dist/runtime-rules/no-return-component.d.ts +18 -0
- package/dist/runtime-rules/no-return-component.d.ts.map +1 -0
- package/dist/runtime-rules/no-return-component.js +106 -0
- package/dist/runtime-rules/no-return-component.js.map +1 -0
- package/dist/runtime-rules/no-unwrap-utility-libs.d.ts +20 -0
- package/dist/runtime-rules/no-unwrap-utility-libs.d.ts.map +1 -0
- package/dist/runtime-rules/no-unwrap-utility-libs.js +75 -0
- package/dist/runtime-rules/no-unwrap-utility-libs.js.map +1 -0
- package/dist/runtime-rules/no-use-reducer.d.ts +19 -0
- package/dist/runtime-rules/no-use-reducer.d.ts.map +1 -0
- package/dist/runtime-rules/no-use-reducer.js +78 -0
- package/dist/runtime-rules/no-use-reducer.js.map +1 -0
- package/dist/runtime-rules/no-window-access.d.ts +23 -0
- package/dist/runtime-rules/no-window-access.d.ts.map +1 -0
- package/dist/runtime-rules/no-window-access.js +136 -0
- package/dist/runtime-rules/no-window-access.js.map +1 -0
- package/dist/runtime-rules/noisy-settings-updates.d.ts +18 -0
- package/dist/runtime-rules/noisy-settings-updates.d.ts.map +1 -0
- package/dist/runtime-rules/noisy-settings-updates.js +110 -0
- package/dist/runtime-rules/noisy-settings-updates.js.map +1 -0
- package/dist/runtime-rules/overflow-hidden-on-layout-container.d.ts +30 -0
- package/dist/runtime-rules/overflow-hidden-on-layout-container.d.ts.map +1 -0
- package/dist/runtime-rules/overflow-hidden-on-layout-container.js +220 -0
- package/dist/runtime-rules/overflow-hidden-on-layout-container.js.map +1 -0
- package/dist/runtime-rules/pass-standard-props.d.ts +19 -0
- package/dist/runtime-rules/pass-standard-props.d.ts.map +1 -0
- package/dist/runtime-rules/pass-standard-props.js +82 -0
- package/dist/runtime-rules/pass-standard-props.js.map +1 -0
- package/dist/runtime-rules/prefer-async-await.d.ts +17 -0
- package/dist/runtime-rules/prefer-async-await.d.ts.map +1 -0
- package/dist/runtime-rules/prefer-async-await.js +52 -0
- package/dist/runtime-rules/prefer-async-await.js.map +1 -0
- package/dist/runtime-rules/prefer-jsx-syntax.d.ts +17 -0
- package/dist/runtime-rules/prefer-jsx-syntax.d.ts.map +1 -0
- package/dist/runtime-rules/prefer-jsx-syntax.js +51 -0
- package/dist/runtime-rules/prefer-jsx-syntax.js.map +1 -0
- package/dist/runtime-rules/prop-state-sync.d.ts +19 -0
- package/dist/runtime-rules/prop-state-sync.d.ts.map +1 -0
- package/dist/runtime-rules/prop-state-sync.js +76 -0
- package/dist/runtime-rules/prop-state-sync.js.map +1 -0
- package/dist/runtime-rules/property-name-consistency.d.ts +20 -0
- package/dist/runtime-rules/property-name-consistency.d.ts.map +1 -0
- package/dist/runtime-rules/property-name-consistency.js +172 -0
- package/dist/runtime-rules/property-name-consistency.js.map +1 -0
- package/dist/runtime-rules/query-result-field-access-validation.d.ts +10 -0
- package/dist/runtime-rules/query-result-field-access-validation.d.ts.map +1 -0
- package/dist/runtime-rules/query-result-field-access-validation.js +304 -0
- package/dist/runtime-rules/query-result-field-access-validation.js.map +1 -0
- package/dist/runtime-rules/react-component-naming.d.ts +19 -0
- package/dist/runtime-rules/react-component-naming.d.ts.map +1 -0
- package/dist/runtime-rules/react-component-naming.js +72 -0
- package/dist/runtime-rules/react-component-naming.js.map +1 -0
- package/dist/runtime-rules/react-hooks-rules.d.ts +27 -0
- package/dist/runtime-rules/react-hooks-rules.d.ts.map +1 -0
- package/dist/runtime-rules/react-hooks-rules.js +223 -0
- package/dist/runtime-rules/react-hooks-rules.js.map +1 -0
- package/dist/runtime-rules/required-queries-not-called.d.ts +19 -0
- package/dist/runtime-rules/required-queries-not-called.d.ts.map +1 -0
- package/dist/runtime-rules/required-queries-not-called.js +146 -0
- package/dist/runtime-rules/required-queries-not-called.js.map +1 -0
- package/dist/runtime-rules/runquery-call-validation.d.ts +11 -0
- package/dist/runtime-rules/runquery-call-validation.d.ts.map +1 -0
- package/dist/runtime-rules/runquery-call-validation.js +886 -0
- package/dist/runtime-rules/runquery-call-validation.js.map +1 -0
- package/dist/runtime-rules/runview-call-validation.d.ts +10 -0
- package/dist/runtime-rules/runview-call-validation.d.ts.map +1 -0
- package/dist/runtime-rules/runview-call-validation.js +336 -0
- package/dist/runtime-rules/runview-call-validation.js.map +1 -0
- package/dist/runtime-rules/saved-user-settings-pattern.d.ts +19 -0
- package/dist/runtime-rules/saved-user-settings-pattern.d.ts.map +1 -0
- package/dist/runtime-rules/saved-user-settings-pattern.js +90 -0
- package/dist/runtime-rules/saved-user-settings-pattern.js.map +1 -0
- package/dist/runtime-rules/search-availability-check.d.ts +9 -0
- package/dist/runtime-rules/search-availability-check.d.ts.map +1 -0
- package/dist/runtime-rules/search-availability-check.js +220 -0
- package/dist/runtime-rules/search-availability-check.js.map +1 -0
- package/dist/runtime-rules/search-call-validation.d.ts +9 -0
- package/dist/runtime-rules/search-call-validation.d.ts.map +1 -0
- package/dist/runtime-rules/search-call-validation.js +336 -0
- package/dist/runtime-rules/search-call-validation.js.map +1 -0
- package/dist/runtime-rules/server-reload-on-client-operation.d.ts +18 -0
- package/dist/runtime-rules/server-reload-on-client-operation.d.ts.map +1 -0
- package/dist/runtime-rules/server-reload-on-client-operation.js +107 -0
- package/dist/runtime-rules/server-reload-on-client-operation.js.map +1 -0
- package/dist/runtime-rules/single-function-only.d.ts +18 -0
- package/dist/runtime-rules/single-function-only.d.ts.map +1 -0
- package/dist/runtime-rules/single-function-only.js +103 -0
- package/dist/runtime-rules/single-function-only.js.map +1 -0
- package/dist/runtime-rules/string-replace-all-occurrences.d.ts +19 -0
- package/dist/runtime-rules/string-replace-all-occurrences.d.ts.map +1 -0
- package/dist/runtime-rules/string-replace-all-occurrences.js +109 -0
- package/dist/runtime-rules/string-replace-all-occurrences.js.map +1 -0
- package/dist/runtime-rules/string-template-validation.d.ts +22 -0
- package/dist/runtime-rules/string-template-validation.d.ts.map +1 -0
- package/dist/runtime-rules/string-template-validation.js +163 -0
- package/dist/runtime-rules/string-template-validation.js.map +1 -0
- package/dist/runtime-rules/styles-validation.d.ts +10 -0
- package/dist/runtime-rules/styles-validation.d.ts.map +1 -0
- package/dist/runtime-rules/styles-validation.js +153 -0
- package/dist/runtime-rules/styles-validation.js.map +1 -0
- package/dist/runtime-rules/type-inference-errors.d.ts +23 -0
- package/dist/runtime-rules/type-inference-errors.d.ts.map +1 -0
- package/dist/runtime-rules/type-inference-errors.js +53 -0
- package/dist/runtime-rules/type-inference-errors.js.map +1 -0
- package/dist/runtime-rules/type-mismatch-operation.d.ts +23 -0
- package/dist/runtime-rules/type-mismatch-operation.d.ts.map +1 -0
- package/dist/runtime-rules/type-mismatch-operation.js +145 -0
- package/dist/runtime-rules/type-mismatch-operation.js.map +1 -0
- package/dist/runtime-rules/undefined-component-usage.d.ts +20 -0
- package/dist/runtime-rules/undefined-component-usage.d.ts.map +1 -0
- package/dist/runtime-rules/undefined-component-usage.js +138 -0
- package/dist/runtime-rules/undefined-component-usage.js.map +1 -0
- package/dist/runtime-rules/undefined-jsx-component.d.ts +25 -0
- package/dist/runtime-rules/undefined-jsx-component.d.ts.map +1 -0
- package/dist/runtime-rules/undefined-jsx-component.js +269 -0
- package/dist/runtime-rules/undefined-jsx-component.js.map +1 -0
- package/dist/runtime-rules/unsafe-array-operations.d.ts +25 -0
- package/dist/runtime-rules/unsafe-array-operations.d.ts.map +1 -0
- package/dist/runtime-rules/unsafe-array-operations.js +347 -0
- package/dist/runtime-rules/unsafe-array-operations.js.map +1 -0
- package/dist/runtime-rules/unsafe-formatting-methods.d.ts +24 -0
- package/dist/runtime-rules/unsafe-formatting-methods.d.ts.map +1 -0
- package/dist/runtime-rules/unsafe-formatting-methods.js +277 -0
- package/dist/runtime-rules/unsafe-formatting-methods.js.map +1 -0
- package/dist/runtime-rules/unused-component-dependencies.d.ts +19 -0
- package/dist/runtime-rules/unused-component-dependencies.d.ts.map +1 -0
- package/dist/runtime-rules/unused-component-dependencies.js +90 -0
- package/dist/runtime-rules/unused-component-dependencies.js.map +1 -0
- package/dist/runtime-rules/unused-libraries.d.ts +19 -0
- package/dist/runtime-rules/unused-libraries.d.ts.map +1 -0
- package/dist/runtime-rules/unused-libraries.js +127 -0
- package/dist/runtime-rules/unused-libraries.js.map +1 -0
- package/dist/runtime-rules/use-function-declaration.d.ts +18 -0
- package/dist/runtime-rules/use-function-declaration.d.ts.map +1 -0
- package/dist/runtime-rules/use-function-declaration.js +127 -0
- package/dist/runtime-rules/use-function-declaration.js.map +1 -0
- package/dist/runtime-rules/use-unwrap-components.d.ts +19 -0
- package/dist/runtime-rules/use-unwrap-components.d.ts.map +1 -0
- package/dist/runtime-rules/use-unwrap-components.js +84 -0
- package/dist/runtime-rules/use-unwrap-components.js.map +1 -0
- package/dist/runtime-rules/useeffect-unstable-dependencies.d.ts +23 -0
- package/dist/runtime-rules/useeffect-unstable-dependencies.d.ts.map +1 -0
- package/dist/runtime-rules/useeffect-unstable-dependencies.js +215 -0
- package/dist/runtime-rules/useeffect-unstable-dependencies.js.map +1 -0
- package/dist/runtime-rules/utilities-api-validation.d.ts +24 -0
- package/dist/runtime-rules/utilities-api-validation.d.ts.map +1 -0
- package/dist/runtime-rules/utilities-api-validation.js +121 -0
- package/dist/runtime-rules/utilities-api-validation.js.map +1 -0
- package/dist/runtime-rules/utilities-no-direct-instantiation.d.ts +20 -0
- package/dist/runtime-rules/utilities-no-direct-instantiation.d.ts.map +1 -0
- package/dist/runtime-rules/utilities-no-direct-instantiation.js +58 -0
- package/dist/runtime-rules/utilities-no-direct-instantiation.js.map +1 -0
- package/dist/runtime-rules/validate-component-references.d.ts +19 -0
- package/dist/runtime-rules/validate-component-references.d.ts.map +1 -0
- package/dist/runtime-rules/validate-component-references.js +255 -0
- package/dist/runtime-rules/validate-component-references.js.map +1 -0
- package/dist/schema-validation/component-prop-rule.d.ts +131 -0
- package/dist/schema-validation/component-prop-rule.d.ts.map +1 -0
- package/dist/schema-validation/component-prop-rule.js +625 -0
- package/dist/schema-validation/component-prop-rule.js.map +1 -0
- package/dist/schema-validation/index.d.ts +26 -0
- package/dist/schema-validation/index.d.ts.map +1 -0
- package/dist/schema-validation/index.js +26 -0
- package/dist/schema-validation/index.js.map +1 -0
- package/dist/schema-validation/semantic-validators/index.d.ts +23 -0
- package/dist/schema-validation/semantic-validators/index.d.ts.map +1 -0
- package/dist/schema-validation/semantic-validators/index.js +23 -0
- package/dist/schema-validation/semantic-validators/index.js.map +1 -0
- package/dist/schema-validation/semantic-validators/required-when-validator.d.ts +43 -0
- package/dist/schema-validation/semantic-validators/required-when-validator.d.ts.map +1 -0
- package/dist/schema-validation/semantic-validators/required-when-validator.js +94 -0
- package/dist/schema-validation/semantic-validators/required-when-validator.js.map +1 -0
- package/dist/schema-validation/semantic-validators/semantic-validator-registry.d.ts +122 -0
- package/dist/schema-validation/semantic-validators/semantic-validator-registry.d.ts.map +1 -0
- package/dist/schema-validation/semantic-validators/semantic-validator-registry.js +166 -0
- package/dist/schema-validation/semantic-validators/semantic-validator-registry.js.map +1 -0
- package/dist/schema-validation/semantic-validators/semantic-validator.d.ts +260 -0
- package/dist/schema-validation/semantic-validators/semantic-validator.d.ts.map +1 -0
- package/dist/schema-validation/semantic-validators/semantic-validator.js +301 -0
- package/dist/schema-validation/semantic-validators/semantic-validator.js.map +1 -0
- package/dist/schema-validation/semantic-validators/sql-where-clause-validator.d.ts +115 -0
- package/dist/schema-validation/semantic-validators/sql-where-clause-validator.d.ts.map +1 -0
- package/dist/schema-validation/semantic-validators/sql-where-clause-validator.js +381 -0
- package/dist/schema-validation/semantic-validators/sql-where-clause-validator.js.map +1 -0
- package/dist/schema-validation/semantic-validators/subset-of-entity-fields-validator.d.ts +60 -0
- package/dist/schema-validation/semantic-validators/subset-of-entity-fields-validator.d.ts.map +1 -0
- package/dist/schema-validation/semantic-validators/subset-of-entity-fields-validator.js +195 -0
- package/dist/schema-validation/semantic-validators/subset-of-entity-fields-validator.js.map +1 -0
- package/dist/schema-validation/semantic-validators/validation-context.d.ts +335 -0
- package/dist/schema-validation/semantic-validators/validation-context.d.ts.map +1 -0
- package/dist/schema-validation/semantic-validators/validation-context.js +13 -0
- package/dist/schema-validation/semantic-validators/validation-context.js.map +1 -0
- package/dist/styles-type-analyzer.d.ts +64 -0
- package/dist/styles-type-analyzer.d.ts.map +1 -0
- package/dist/styles-type-analyzer.js +242 -0
- package/dist/styles-type-analyzer.js.map +1 -0
- package/dist/type-context.d.ts +184 -0
- package/dist/type-context.d.ts.map +1 -0
- package/dist/type-context.js +415 -0
- package/dist/type-context.js.map +1 -0
- package/dist/type-inference-engine.d.ts +181 -0
- package/dist/type-inference-engine.d.ts.map +1 -0
- package/dist/type-inference-engine.js +1151 -0
- package/dist/type-inference-engine.js.map +1 -0
- package/dist/type-rules/type-compatibility-rule.d.ts +85 -0
- package/dist/type-rules/type-compatibility-rule.d.ts.map +1 -0
- package/dist/type-rules/type-compatibility-rule.js +211 -0
- package/dist/type-rules/type-compatibility-rule.js.map +1 -0
- package/package.json +35 -7
- package/README.md +0 -45
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import * as t from '@babel/types';
|
|
2
|
+
import { BaseLintRule } from '../lint-rule.js';
|
|
3
|
+
import { Violation } from '../component-linter.js';
|
|
4
|
+
/**
|
|
5
|
+
* Rule: overflow-hidden-on-layout-container
|
|
6
|
+
*
|
|
7
|
+
* Detects `overflow: 'hidden'` on flex content containers that also have
|
|
8
|
+
* `flex: 1`. This combination creates an invisible clipping boundary that
|
|
9
|
+
* blocks scrolling for child content (DataGrid, tables, lists, etc.).
|
|
10
|
+
*
|
|
11
|
+
* The Angular host (`mj-react-component`) already delegates scrolling to its
|
|
12
|
+
* parent container which uses `overflow: auto`. Adding `overflow: hidden` on
|
|
13
|
+
* a flex content wrapper silently clips all descendant scrollbars.
|
|
14
|
+
*
|
|
15
|
+
* Does NOT flag:
|
|
16
|
+
* - Root viewport containers (`height: '100vh'` + overflow hidden) — these
|
|
17
|
+
* intentionally prevent page-level scrollbars
|
|
18
|
+
* - Small/fixed-size containers (e.g., `width: '200px'` with overflow hidden)
|
|
19
|
+
* - Text truncation (overflow hidden + textOverflow ellipsis)
|
|
20
|
+
* - Containers without flex: 1
|
|
21
|
+
*
|
|
22
|
+
* Severity: medium — the component renders but scrollable content is unreachable.
|
|
23
|
+
* Applies to: all components
|
|
24
|
+
*/
|
|
25
|
+
export declare class OverflowHiddenOnLayoutContainerRule extends BaseLintRule {
|
|
26
|
+
get Name(): string;
|
|
27
|
+
get AppliesTo(): 'all' | 'child' | 'root';
|
|
28
|
+
Test(ast: t.File, componentName: string): Violation[];
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=overflow-hidden-on-layout-container.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overflow-hidden-on-layout-container.d.ts","sourceRoot":"","sources":["../../src/runtime-rules/overflow-hidden-on-layout-container.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAElC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEhD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBACa,mCAAoC,SAAQ,YAAY;IACnE,IAAI,IAAI,WAAoD;IAC5D,IAAI,SAAS,IAAI,KAAK,GAAG,OAAO,GAAG,MAAM,CAAkB;IAE3D,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,aAAa,EAAE,MAAM,GAAG,SAAS,EAAE;CAqDtD"}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { traverse, createViolation, truncateCode } from '../lint-utils.js';
|
|
8
|
+
import * as t from '@babel/types';
|
|
9
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
10
|
+
import { BaseLintRule } from '../lint-rule.js';
|
|
11
|
+
/**
|
|
12
|
+
* Rule: overflow-hidden-on-layout-container
|
|
13
|
+
*
|
|
14
|
+
* Detects `overflow: 'hidden'` on flex content containers that also have
|
|
15
|
+
* `flex: 1`. This combination creates an invisible clipping boundary that
|
|
16
|
+
* blocks scrolling for child content (DataGrid, tables, lists, etc.).
|
|
17
|
+
*
|
|
18
|
+
* The Angular host (`mj-react-component`) already delegates scrolling to its
|
|
19
|
+
* parent container which uses `overflow: auto`. Adding `overflow: hidden` on
|
|
20
|
+
* a flex content wrapper silently clips all descendant scrollbars.
|
|
21
|
+
*
|
|
22
|
+
* Does NOT flag:
|
|
23
|
+
* - Root viewport containers (`height: '100vh'` + overflow hidden) — these
|
|
24
|
+
* intentionally prevent page-level scrollbars
|
|
25
|
+
* - Small/fixed-size containers (e.g., `width: '200px'` with overflow hidden)
|
|
26
|
+
* - Text truncation (overflow hidden + textOverflow ellipsis)
|
|
27
|
+
* - Containers without flex: 1
|
|
28
|
+
*
|
|
29
|
+
* Severity: medium — the component renders but scrollable content is unreachable.
|
|
30
|
+
* Applies to: all components
|
|
31
|
+
*/
|
|
32
|
+
let OverflowHiddenOnLayoutContainerRule = class OverflowHiddenOnLayoutContainerRule extends BaseLintRule {
|
|
33
|
+
get Name() { return 'overflow-hidden-on-layout-container'; }
|
|
34
|
+
get AppliesTo() { return 'all'; }
|
|
35
|
+
Test(ast, componentName) {
|
|
36
|
+
const violations = [];
|
|
37
|
+
traverse(ast, {
|
|
38
|
+
ObjectExpression(path) {
|
|
39
|
+
if (!isInlineStyleObject(path)) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const props = extractStyleProperties(path.node);
|
|
43
|
+
if (!props) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (!hasOverflowHidden(props)) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
// Text truncation pattern — intentional, not a layout bug
|
|
50
|
+
if (hasTextTruncation(props)) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
// Only flag if this looks like a layout container
|
|
54
|
+
if (!isLayoutContainer(props)) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
violations.push(createViolation('overflow-hidden-on-layout-container', 'medium', path.node, `Component "${componentName}" uses overflow: 'hidden' on a layout container ` +
|
|
58
|
+
`(with ${describeLayoutIndicator(props)}). This creates an invisible clipping ` +
|
|
59
|
+
`boundary that blocks scrolling for child content like DataGrid, tables, and ` +
|
|
60
|
+
`lists. The Angular host already manages scrolling via overflow: auto.`, truncateCode(formatStyleSnippet(props), 100), {
|
|
61
|
+
text: `Use overflow: 'auto' to allow child scrolling, or remove the overflow property entirely.`,
|
|
62
|
+
example: `// Before (blocks scrolling):\n` +
|
|
63
|
+
`style={{ flex: 1, overflow: 'hidden' }}\n\n` +
|
|
64
|
+
`// After (allows child scrolling):\n` +
|
|
65
|
+
`style={{ flex: 1, overflow: 'auto' }}\n` +
|
|
66
|
+
`// or simply:\n` +
|
|
67
|
+
`style={{ flex: 1 }}`,
|
|
68
|
+
}));
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
return violations;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
OverflowHiddenOnLayoutContainerRule = __decorate([
|
|
75
|
+
RegisterClass(BaseLintRule, 'overflow-hidden-on-layout-container')
|
|
76
|
+
], OverflowHiddenOnLayoutContainerRule);
|
|
77
|
+
export { OverflowHiddenOnLayoutContainerRule };
|
|
78
|
+
/**
|
|
79
|
+
* Determines if this ObjectExpression is a JSX inline style object.
|
|
80
|
+
* Matches both `style={{ ... }}` and `style={someVar}` where someVar
|
|
81
|
+
* is assigned an object literal.
|
|
82
|
+
*/
|
|
83
|
+
function isInlineStyleObject(path) {
|
|
84
|
+
const parent = path.parent;
|
|
85
|
+
// Direct: style={{ ... }}
|
|
86
|
+
if (t.isJSXExpressionContainer(parent)) {
|
|
87
|
+
const grandparent = path.parentPath?.parent;
|
|
88
|
+
if (t.isJSXAttribute(grandparent) &&
|
|
89
|
+
t.isJSXIdentifier(grandparent.name) &&
|
|
90
|
+
grandparent.name.name === 'style') {
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// Variable: const styles = { ... } used as style={styles}
|
|
95
|
+
// We also catch nested objects within style objects (e.g., containerStyle)
|
|
96
|
+
if (t.isVariableDeclarator(parent)) {
|
|
97
|
+
const id = parent.id;
|
|
98
|
+
if (t.isIdentifier(id) && isStyleVariableName(id.name)) {
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// Property in a styles object: { container: { overflow: 'hidden', flex: 1 } }
|
|
103
|
+
if (t.isObjectProperty(parent) && t.isIdentifier(parent.key)) {
|
|
104
|
+
const propName = parent.key.name.toLowerCase();
|
|
105
|
+
if (propName.includes('style') || propName.includes('container') ||
|
|
106
|
+
propName.includes('wrapper') || propName.includes('root') ||
|
|
107
|
+
propName.includes('layout') || propName.includes('content')) {
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
function isStyleVariableName(name) {
|
|
114
|
+
const lower = name.toLowerCase();
|
|
115
|
+
return lower.includes('style') || lower.includes('container') ||
|
|
116
|
+
lower.includes('wrapper') || lower.includes('root') ||
|
|
117
|
+
lower.includes('layout');
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Extracts known style properties from an ObjectExpression as simple values.
|
|
121
|
+
*/
|
|
122
|
+
function extractStyleProperties(node) {
|
|
123
|
+
const result = {
|
|
124
|
+
overflow: null,
|
|
125
|
+
overflowX: null,
|
|
126
|
+
overflowY: null,
|
|
127
|
+
textOverflow: null,
|
|
128
|
+
flex: null,
|
|
129
|
+
height: null,
|
|
130
|
+
node,
|
|
131
|
+
};
|
|
132
|
+
for (const prop of node.properties) {
|
|
133
|
+
if (!t.isObjectProperty(prop) || !t.isIdentifier(prop.key)) {
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
const key = prop.key.name;
|
|
137
|
+
const val = prop.value;
|
|
138
|
+
switch (key) {
|
|
139
|
+
case 'overflow':
|
|
140
|
+
result.overflow = extractStringOrNumberValue(val);
|
|
141
|
+
break;
|
|
142
|
+
case 'overflowX':
|
|
143
|
+
result.overflowX = extractStringValue(val);
|
|
144
|
+
break;
|
|
145
|
+
case 'overflowY':
|
|
146
|
+
result.overflowY = extractStringValue(val);
|
|
147
|
+
break;
|
|
148
|
+
case 'textOverflow':
|
|
149
|
+
result.textOverflow = extractStringValue(val);
|
|
150
|
+
break;
|
|
151
|
+
case 'flex':
|
|
152
|
+
result.flex = extractFlexValue(val);
|
|
153
|
+
break;
|
|
154
|
+
case 'height':
|
|
155
|
+
result.height = extractStringOrNumberValue(val);
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return result;
|
|
160
|
+
}
|
|
161
|
+
function extractStringValue(node) {
|
|
162
|
+
if (t.isStringLiteral(node))
|
|
163
|
+
return node.value;
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
function extractStringOrNumberValue(node) {
|
|
167
|
+
if (t.isStringLiteral(node))
|
|
168
|
+
return node.value;
|
|
169
|
+
if (t.isNumericLiteral(node))
|
|
170
|
+
return String(node.value);
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
function extractFlexValue(node) {
|
|
174
|
+
if (t.isNumericLiteral(node))
|
|
175
|
+
return node.value;
|
|
176
|
+
if (t.isStringLiteral(node))
|
|
177
|
+
return node.value;
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
function hasOverflowHidden(props) {
|
|
181
|
+
return props.overflow === 'hidden' ||
|
|
182
|
+
(props.overflowX === 'hidden' && props.overflowY === 'hidden');
|
|
183
|
+
}
|
|
184
|
+
function hasTextTruncation(props) {
|
|
185
|
+
return props.textOverflow === 'ellipsis';
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* A flex content container is identified by having flex: 1 (or similar).
|
|
189
|
+
* These are inner content wrappers where overflow: hidden blocks child scrolling.
|
|
190
|
+
*
|
|
191
|
+
* Root viewport containers (height: '100vh') intentionally use overflow: hidden
|
|
192
|
+
* to prevent page-level scrollbars — that pattern is NOT flagged.
|
|
193
|
+
*/
|
|
194
|
+
function isLayoutContainer(props) {
|
|
195
|
+
// flex: 1 or flex: '1' or flex: '1 1 0%' etc.
|
|
196
|
+
if (props.flex !== null) {
|
|
197
|
+
const flexStr = String(props.flex);
|
|
198
|
+
if (flexStr === '1' || flexStr.startsWith('1 ')) {
|
|
199
|
+
return true;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
function describeLayoutIndicator(props) {
|
|
205
|
+
if (props.flex !== null) {
|
|
206
|
+
return `flex: ${typeof props.flex === 'string' ? `'${props.flex}'` : props.flex}`;
|
|
207
|
+
}
|
|
208
|
+
return 'flex layout';
|
|
209
|
+
}
|
|
210
|
+
function formatStyleSnippet(props) {
|
|
211
|
+
const parts = [];
|
|
212
|
+
if (props.overflow)
|
|
213
|
+
parts.push(`overflow: '${props.overflow}'`);
|
|
214
|
+
if (props.flex !== null)
|
|
215
|
+
parts.push(`flex: ${typeof props.flex === 'string' ? `'${props.flex}'` : props.flex}`);
|
|
216
|
+
if (props.height)
|
|
217
|
+
parts.push(`height: '${props.height}'`);
|
|
218
|
+
return `{ ${parts.join(', ')} }`;
|
|
219
|
+
}
|
|
220
|
+
//# sourceMappingURL=overflow-hidden-on-layout-container.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overflow-hidden-on-layout-container.js","sourceRoot":"","sources":["../../src/runtime-rules/overflow-hidden-on-layout-container.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as t from '@babel/types';
|
|
2
|
+
import { BaseLintRule } from '../lint-rule.js';
|
|
3
|
+
import { Violation } from '../component-linter.js';
|
|
4
|
+
import { ComponentSpec } from '@memberjunction/interactive-component-types';
|
|
5
|
+
/**
|
|
6
|
+
* Rule: pass-standard-props
|
|
7
|
+
*
|
|
8
|
+
* Ensures that all dependency components receive the standard props:
|
|
9
|
+
* styles, utilities, and components.
|
|
10
|
+
*
|
|
11
|
+
* Severity: critical
|
|
12
|
+
* Applies to: all components
|
|
13
|
+
*/
|
|
14
|
+
export declare class PassStandardPropsRule extends BaseLintRule {
|
|
15
|
+
get Name(): string;
|
|
16
|
+
get AppliesTo(): 'all' | 'child' | 'root';
|
|
17
|
+
Test(ast: t.File, _componentName: string, componentSpec?: ComponentSpec): Violation[];
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=pass-standard-props.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pass-standard-props.d.ts","sourceRoot":"","sources":["../../src/runtime-rules/pass-standard-props.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAElC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAG5E;;;;;;;;GAQG;AACH,qBACa,qBAAsB,SAAQ,YAAY;IACrD,IAAI,IAAI,WAAoC;IAC5C,IAAI,SAAS,IAAI,KAAK,GAAG,OAAO,GAAG,MAAM,CAAkB;IAE3D,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,aAAa,GAAG,SAAS,EAAE;CAwEtF"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
8
|
+
import { BaseLintRule } from '../lint-rule.js';
|
|
9
|
+
import { traverse, createViolation, getJSXElementName, hasJSXAttribute } from '../lint-utils.js';
|
|
10
|
+
/**
|
|
11
|
+
* Rule: pass-standard-props
|
|
12
|
+
*
|
|
13
|
+
* Ensures that all dependency components receive the standard props:
|
|
14
|
+
* styles, utilities, and components.
|
|
15
|
+
*
|
|
16
|
+
* Severity: critical
|
|
17
|
+
* Applies to: all components
|
|
18
|
+
*/
|
|
19
|
+
let PassStandardPropsRule = class PassStandardPropsRule extends BaseLintRule {
|
|
20
|
+
get Name() { return 'pass-standard-props'; }
|
|
21
|
+
get AppliesTo() { return 'all'; }
|
|
22
|
+
Test(ast, _componentName, componentSpec) {
|
|
23
|
+
const violations = [];
|
|
24
|
+
const requiredProps = ['styles', 'utilities', 'components'];
|
|
25
|
+
// ONLY check components that are explicitly in our dependencies
|
|
26
|
+
// Do NOT check library components, HTML elements, or anything else
|
|
27
|
+
const ourComponentNames = new Set();
|
|
28
|
+
// Only add components from the componentSpec.dependencies array
|
|
29
|
+
if (componentSpec?.dependencies && Array.isArray(componentSpec.dependencies)) {
|
|
30
|
+
for (const dep of componentSpec.dependencies) {
|
|
31
|
+
if (dep && dep.name) {
|
|
32
|
+
ourComponentNames.add(dep.name);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// If there are no dependencies, skip this rule entirely
|
|
37
|
+
if (ourComponentNames.size === 0) {
|
|
38
|
+
return violations;
|
|
39
|
+
}
|
|
40
|
+
traverse(ast, {
|
|
41
|
+
JSXElement(path) {
|
|
42
|
+
const openingElement = path.node.openingElement;
|
|
43
|
+
const elementName = getJSXElementName(openingElement);
|
|
44
|
+
// Only check if this is one of our dependency components
|
|
45
|
+
if (elementName && ourComponentNames.has(elementName)) {
|
|
46
|
+
// Check for required props
|
|
47
|
+
const missingProps = [];
|
|
48
|
+
for (const propName of requiredProps) {
|
|
49
|
+
if (!hasJSXAttribute(openingElement, propName)) {
|
|
50
|
+
missingProps.push(propName);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (missingProps.length > 0) {
|
|
54
|
+
violations.push(createViolation('pass-standard-props', 'critical', openingElement, `Dependency component "${elementName}" is missing required props: ${missingProps.join(', ')}. Components from dependencies must receive styles, utilities, and components props.`, `<${elementName} ... />`, {
|
|
55
|
+
text: 'Always pass standard props to all components',
|
|
56
|
+
example: `// Always include these props when calling components:
|
|
57
|
+
<ChildComponent
|
|
58
|
+
items={items} // Data props
|
|
59
|
+
|
|
60
|
+
// Settings persistence
|
|
61
|
+
savedUserSettings={savedUserSettings?.childComponent}
|
|
62
|
+
onSaveUserSettings={handleChildSettings}
|
|
63
|
+
|
|
64
|
+
// Standard props
|
|
65
|
+
styles={styles}
|
|
66
|
+
utilities={utilities}
|
|
67
|
+
components={components}
|
|
68
|
+
callbacks={callbacks}
|
|
69
|
+
/>`,
|
|
70
|
+
}));
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
return violations;
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
PassStandardPropsRule = __decorate([
|
|
79
|
+
RegisterClass(BaseLintRule, 'pass-standard-props')
|
|
80
|
+
], PassStandardPropsRule);
|
|
81
|
+
export { PassStandardPropsRule };
|
|
82
|
+
//# sourceMappingURL=pass-standard-props.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pass-standard-props.js","sourceRoot":"","sources":["../../src/runtime-rules/pass-standard-props.ts"],"names":[],"mappings":";;;;;;AACA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAG5C,OAAO,EAAE,QAAQ,EAAY,eAAe,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAExG;;;;;;;;GAQG;AAEI,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,YAAY;IACrD,IAAI,IAAI,KAAK,OAAO,qBAAqB,CAAC,CAAC,CAAC;IAC5C,IAAI,SAAS,KAA+B,OAAO,KAAK,CAAC,CAAC,CAAC;IAE3D,IAAI,CAAC,GAAW,EAAE,cAAsB,EAAE,aAA6B;QACrE,MAAM,UAAU,GAAgB,EAAE,CAAC;QACnC,MAAM,aAAa,GAAG,CAAC,QAAQ,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC;QAE5D,gEAAgE;QAChE,mEAAmE;QACnE,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAU,CAAC;QAE5C,gEAAgE;QAChE,IAAI,aAAa,EAAE,YAAY,IAAI,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,YAAY,CAAC,EAAE,CAAC;YAC7E,KAAK,MAAM,GAAG,IAAI,aAAa,CAAC,YAAY,EAAE,CAAC;gBAC7C,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;oBACpB,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBAClC,CAAC;YACH,CAAC;QACH,CAAC;QAED,wDAAwD;QACxD,IAAI,iBAAiB,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACjC,OAAO,UAAU,CAAC;QACpB,CAAC;QAED,QAAQ,CAAC,GAAG,EAAE;YACZ,UAAU,CAAC,IAA4B;gBACrC,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC;gBAChD,MAAM,WAAW,GAAG,iBAAiB,CAAC,cAAc,CAAC,CAAC;gBAEtD,yDAAyD;gBACzD,IAAI,WAAW,IAAI,iBAAiB,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;oBACtD,2BAA2B;oBAC3B,MAAM,YAAY,GAAa,EAAE,CAAC;oBAElC,KAAK,MAAM,QAAQ,IAAI,aAAa,EAAE,CAAC;wBACrC,IAAI,CAAC,eAAe,CAAC,cAAc,EAAE,QAAQ,CAAC,EAAE,CAAC;4BAC/C,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;wBAC9B,CAAC;oBACH,CAAC;oBAED,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBAC5B,UAAU,CAAC,IAAI,CACb,eAAe,CACb,qBAAqB,EACrB,UAAU,EACV,cAAc,EACd,yBAAyB,WAAW,gCAAgC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,sFAAsF,EACjL,IAAI,WAAW,SAAS,EACxB;4BACE,IAAI,EAAE,8CAA8C;4BACpD,OAAO,EAAE;;;;;;;;;;;;;GAaxB;yBACc,CACF,CACF,CAAC;oBACJ,CAAC;gBACH,CAAC;YACH,CAAC;SACF,CAAC,CAAC;QAEH,OAAO,UAAU,CAAC;IACpB,CAAC;CACF,CAAA;AA5EY,qBAAqB;IADjC,aAAa,CAAC,YAAY,EAAE,qBAAqB,CAAC;GACtC,qBAAqB,CA4EjC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as t from '@babel/types';
|
|
2
|
+
import { BaseLintRule } from '../lint-rule.js';
|
|
3
|
+
import { Violation } from '../component-linter.js';
|
|
4
|
+
/**
|
|
5
|
+
* Rule: prefer-async-await
|
|
6
|
+
*
|
|
7
|
+
* Encourages the use of async/await over .then() chains for better readability.
|
|
8
|
+
*
|
|
9
|
+
* Severity: low
|
|
10
|
+
* Applies to: all components
|
|
11
|
+
*/
|
|
12
|
+
export declare class PreferAsyncAwaitRule extends BaseLintRule {
|
|
13
|
+
get Name(): string;
|
|
14
|
+
get AppliesTo(): 'all' | 'child' | 'root';
|
|
15
|
+
Test(ast: t.File, _componentName: string): Violation[];
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=prefer-async-await.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prefer-async-await.d.ts","sourceRoot":"","sources":["../../src/runtime-rules/prefer-async-await.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAElC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEhD;;;;;;;GAOG;AACH,qBACa,oBAAqB,SAAQ,YAAY;IACpD,IAAI,IAAI,WAAmC;IAC3C,IAAI,SAAS,IAAI,KAAK,GAAG,OAAO,GAAG,MAAM,CAAkB;IAE3D,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,GAAG,SAAS,EAAE;CA6BvD"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { traverse } from '../lint-utils.js';
|
|
8
|
+
import * as t from '@babel/types';
|
|
9
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
10
|
+
import { BaseLintRule } from '../lint-rule.js';
|
|
11
|
+
/**
|
|
12
|
+
* Rule: prefer-async-await
|
|
13
|
+
*
|
|
14
|
+
* Encourages the use of async/await over .then() chains for better readability.
|
|
15
|
+
*
|
|
16
|
+
* Severity: low
|
|
17
|
+
* Applies to: all components
|
|
18
|
+
*/
|
|
19
|
+
let PreferAsyncAwaitRule = class PreferAsyncAwaitRule extends BaseLintRule {
|
|
20
|
+
get Name() { return 'prefer-async-await'; }
|
|
21
|
+
get AppliesTo() { return 'all'; }
|
|
22
|
+
Test(ast, _componentName) {
|
|
23
|
+
const violations = [];
|
|
24
|
+
traverse(ast, {
|
|
25
|
+
CallExpression(path) {
|
|
26
|
+
const callee = path.node.callee;
|
|
27
|
+
// Check for .then() chains
|
|
28
|
+
if (t.isMemberExpression(callee) && t.isIdentifier(callee.property) && callee.property.name === 'then') {
|
|
29
|
+
// Try to get the context of what's being chained
|
|
30
|
+
let context = '';
|
|
31
|
+
if (t.isMemberExpression(callee.object)) {
|
|
32
|
+
context = ' Consider using async/await for cleaner code.';
|
|
33
|
+
}
|
|
34
|
+
violations.push({
|
|
35
|
+
rule: 'prefer-async-await',
|
|
36
|
+
severity: 'low',
|
|
37
|
+
line: callee.property.loc?.start.line || 0,
|
|
38
|
+
column: callee.property.loc?.start.column || 0,
|
|
39
|
+
message: `Prefer async/await over .then() chains for better readability.${context}`,
|
|
40
|
+
code: '.then(result => ...) → const result = await ...',
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
return violations;
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
PreferAsyncAwaitRule = __decorate([
|
|
49
|
+
RegisterClass(BaseLintRule, 'prefer-async-await')
|
|
50
|
+
], PreferAsyncAwaitRule);
|
|
51
|
+
export { PreferAsyncAwaitRule };
|
|
52
|
+
//# sourceMappingURL=prefer-async-await.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prefer-async-await.js","sourceRoot":"","sources":["../../src/runtime-rules/prefer-async-await.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,QAAQ,EAAY,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAG5C;;;;;;;GAOG;AAEI,IAAM,oBAAoB,GAA1B,MAAM,oBAAqB,SAAQ,YAAY;IACpD,IAAI,IAAI,KAAK,OAAO,oBAAoB,CAAC,CAAC,CAAC;IAC3C,IAAI,SAAS,KAA+B,OAAO,KAAK,CAAC,CAAC,CAAC;IAE3D,IAAI,CAAC,GAAW,EAAE,cAAsB;QACtC,MAAM,UAAU,GAAgB,EAAE,CAAC;QAEnC,QAAQ,CAAC,GAAG,EAAE;YACZ,cAAc,CAAC,IAAgC;gBAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;gBAEhC,2BAA2B;gBAC3B,IAAI,CAAC,CAAC,kBAAkB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;oBACvG,iDAAiD;oBACjD,IAAI,OAAO,GAAG,EAAE,CAAC;oBACjB,IAAI,CAAC,CAAC,kBAAkB,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;wBACxC,OAAO,GAAG,+CAA+C,CAAC;oBAC5D,CAAC;oBAED,UAAU,CAAC,IAAI,CAAC;wBACd,IAAI,EAAE,oBAAoB;wBAC1B,QAAQ,EAAE,KAAK;wBACf,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC;wBAC1C,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC;wBAC9C,OAAO,EAAE,iEAAiE,OAAO,EAAE;wBACnF,IAAI,EAAE,iDAAiD;qBACxD,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;SACF,CAAC,CAAC;QAEH,OAAO,UAAU,CAAC;IACpB,CAAC;CACF,CAAA;AAjCY,oBAAoB;IADhC,aAAa,CAAC,YAAY,EAAE,oBAAoB,CAAC;GACrC,oBAAoB,CAiChC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as t from '@babel/types';
|
|
2
|
+
import { BaseLintRule } from '../lint-rule.js';
|
|
3
|
+
import { Violation } from '../component-linter.js';
|
|
4
|
+
/**
|
|
5
|
+
* Rule: prefer-jsx-syntax
|
|
6
|
+
*
|
|
7
|
+
* Encourages the use of JSX syntax over React.createElement for better readability.
|
|
8
|
+
*
|
|
9
|
+
* Severity: low
|
|
10
|
+
* Applies to: all components
|
|
11
|
+
*/
|
|
12
|
+
export declare class PreferJsxSyntaxRule extends BaseLintRule {
|
|
13
|
+
get Name(): string;
|
|
14
|
+
get AppliesTo(): 'all' | 'child' | 'root';
|
|
15
|
+
Test(ast: t.File, _componentName: string): Violation[];
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=prefer-jsx-syntax.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prefer-jsx-syntax.d.ts","sourceRoot":"","sources":["../../src/runtime-rules/prefer-jsx-syntax.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAElC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEhD;;;;;;;GAOG;AACH,qBACa,mBAAoB,SAAQ,YAAY;IACnD,IAAI,IAAI,WAAkC;IAC1C,IAAI,SAAS,IAAI,KAAK,GAAG,OAAO,GAAG,MAAM,CAAkB;IAE3D,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,GAAG,SAAS,EAAE;CA6BvD"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { traverse } from '../lint-utils.js';
|
|
8
|
+
import * as t from '@babel/types';
|
|
9
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
10
|
+
import { BaseLintRule } from '../lint-rule.js';
|
|
11
|
+
/**
|
|
12
|
+
* Rule: prefer-jsx-syntax
|
|
13
|
+
*
|
|
14
|
+
* Encourages the use of JSX syntax over React.createElement for better readability.
|
|
15
|
+
*
|
|
16
|
+
* Severity: low
|
|
17
|
+
* Applies to: all components
|
|
18
|
+
*/
|
|
19
|
+
let PreferJsxSyntaxRule = class PreferJsxSyntaxRule extends BaseLintRule {
|
|
20
|
+
get Name() { return 'prefer-jsx-syntax'; }
|
|
21
|
+
get AppliesTo() { return 'all'; }
|
|
22
|
+
Test(ast, _componentName) {
|
|
23
|
+
const violations = [];
|
|
24
|
+
traverse(ast, {
|
|
25
|
+
CallExpression(path) {
|
|
26
|
+
const callee = path.node.callee;
|
|
27
|
+
// Check for React.createElement
|
|
28
|
+
if (t.isMemberExpression(callee) &&
|
|
29
|
+
t.isIdentifier(callee.object) &&
|
|
30
|
+
callee.object.name === 'React' &&
|
|
31
|
+
t.isIdentifier(callee.property) &&
|
|
32
|
+
callee.property.name === 'createElement') {
|
|
33
|
+
violations.push({
|
|
34
|
+
rule: 'prefer-jsx-syntax',
|
|
35
|
+
severity: 'low',
|
|
36
|
+
line: callee.loc?.start.line || 0,
|
|
37
|
+
column: callee.loc?.start.column || 0,
|
|
38
|
+
message: 'Prefer JSX syntax over React.createElement for better readability',
|
|
39
|
+
code: 'React.createElement(...) → <ComponentName ... />',
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
return violations;
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
PreferJsxSyntaxRule = __decorate([
|
|
48
|
+
RegisterClass(BaseLintRule, 'prefer-jsx-syntax')
|
|
49
|
+
], PreferJsxSyntaxRule);
|
|
50
|
+
export { PreferJsxSyntaxRule };
|
|
51
|
+
//# sourceMappingURL=prefer-jsx-syntax.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prefer-jsx-syntax.js","sourceRoot":"","sources":["../../src/runtime-rules/prefer-jsx-syntax.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,QAAQ,EAAY,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAG5C;;;;;;;GAOG;AAEI,IAAM,mBAAmB,GAAzB,MAAM,mBAAoB,SAAQ,YAAY;IACnD,IAAI,IAAI,KAAK,OAAO,mBAAmB,CAAC,CAAC,CAAC;IAC1C,IAAI,SAAS,KAA+B,OAAO,KAAK,CAAC,CAAC,CAAC;IAE3D,IAAI,CAAC,GAAW,EAAE,cAAsB;QACtC,MAAM,UAAU,GAAgB,EAAE,CAAC;QAEnC,QAAQ,CAAC,GAAG,EAAE;YACZ,cAAc,CAAC,IAAgC;gBAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;gBAEhC,gCAAgC;gBAChC,IACE,CAAC,CAAC,kBAAkB,CAAC,MAAM,CAAC;oBAC5B,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC;oBAC7B,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,OAAO;oBAC9B,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC;oBAC/B,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,eAAe,EACxC,CAAC;oBACD,UAAU,CAAC,IAAI,CAAC;wBACd,IAAI,EAAE,mBAAmB;wBACzB,QAAQ,EAAE,KAAK;wBACf,IAAI,EAAE,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC;wBACjC,MAAM,EAAE,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC;wBACrC,OAAO,EAAE,mEAAmE;wBAC5E,IAAI,EAAE,kDAAkD;qBACzD,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;SACF,CAAC,CAAC;QAEH,OAAO,UAAU,CAAC;IACpB,CAAC;CACF,CAAA;AAjCY,mBAAmB;IAD/B,aAAa,CAAC,YAAY,EAAE,mBAAmB,CAAC;GACpC,mBAAmB,CAiC/B"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as t from '@babel/types';
|
|
2
|
+
import { BaseLintRule } from '../lint-rule.js';
|
|
3
|
+
import { Violation } from '../component-linter.js';
|
|
4
|
+
/**
|
|
5
|
+
* Rule: prop-state-sync
|
|
6
|
+
*
|
|
7
|
+
* Detects useEffect hooks that sync props to internal state, which creates
|
|
8
|
+
* dual state management and can lead to bugs and stale state issues.
|
|
9
|
+
* Components should use props directly or manage state independently.
|
|
10
|
+
*
|
|
11
|
+
* Severity: critical
|
|
12
|
+
* Applies to: all components
|
|
13
|
+
*/
|
|
14
|
+
export declare class PropStateSyncRule extends BaseLintRule {
|
|
15
|
+
get Name(): string;
|
|
16
|
+
get AppliesTo(): 'all' | 'child' | 'root';
|
|
17
|
+
Test(ast: t.File, _componentName: string): Violation[];
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=prop-state-sync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prop-state-sync.d.ts","sourceRoot":"","sources":["../../src/runtime-rules/prop-state-sync.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAElC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEhD;;;;;;;;;GASG;AACH,qBACa,iBAAkB,SAAQ,YAAY;IACjD,IAAI,IAAI,WAAgC;IACxC,IAAI,SAAS,IAAI,KAAK,GAAG,OAAO,GAAG,MAAM,CAAkB;IAE3D,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,GAAG,SAAS,EAAE;CAqDvD"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { traverse } from '../lint-utils.js';
|
|
8
|
+
import * as t from '@babel/types';
|
|
9
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
10
|
+
import { BaseLintRule } from '../lint-rule.js';
|
|
11
|
+
/**
|
|
12
|
+
* Rule: prop-state-sync
|
|
13
|
+
*
|
|
14
|
+
* Detects useEffect hooks that sync props to internal state, which creates
|
|
15
|
+
* dual state management and can lead to bugs and stale state issues.
|
|
16
|
+
* Components should use props directly or manage state independently.
|
|
17
|
+
*
|
|
18
|
+
* Severity: critical
|
|
19
|
+
* Applies to: all components
|
|
20
|
+
*/
|
|
21
|
+
let PropStateSyncRule = class PropStateSyncRule extends BaseLintRule {
|
|
22
|
+
get Name() { return 'prop-state-sync'; }
|
|
23
|
+
get AppliesTo() { return 'all'; }
|
|
24
|
+
Test(ast, _componentName) {
|
|
25
|
+
const violations = [];
|
|
26
|
+
traverse(ast, {
|
|
27
|
+
CallExpression(path) {
|
|
28
|
+
if (t.isIdentifier(path.node.callee) && path.node.callee.name === 'useEffect') {
|
|
29
|
+
const effectBody = path.node.arguments[0];
|
|
30
|
+
const deps = path.node.arguments[1];
|
|
31
|
+
if (effectBody && (t.isArrowFunctionExpression(effectBody) || t.isFunctionExpression(effectBody))) {
|
|
32
|
+
const bodyString = effectBody.body.toString();
|
|
33
|
+
// Check if it's setting state based on props
|
|
34
|
+
const hasSetState = /set[A-Z]\w*\s*\(/.test(bodyString);
|
|
35
|
+
const depsString = deps ? deps.toString() : '';
|
|
36
|
+
// Check if deps include prop-like names
|
|
37
|
+
const propPatterns = ['Prop', 'value', 'data', 'items'];
|
|
38
|
+
const hasPropDeps = propPatterns.some((p) => depsString.includes(p));
|
|
39
|
+
if (hasSetState && hasPropDeps && !bodyString.includes('async')) {
|
|
40
|
+
violations.push({
|
|
41
|
+
rule: 'prop-state-sync',
|
|
42
|
+
severity: 'critical',
|
|
43
|
+
line: path.node.loc?.start.line || 0,
|
|
44
|
+
column: path.node.loc?.start.column || 0,
|
|
45
|
+
message: 'Syncing props to internal state with useEffect creates dual state management',
|
|
46
|
+
code: path.toString().substring(0, 100),
|
|
47
|
+
suggestion: {
|
|
48
|
+
text: "Initialize state once, don't sync from props",
|
|
49
|
+
example: `// ❌ WRONG - Syncing prop to state:
|
|
50
|
+
const [value, setValue] = useState(propValue);
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
setValue(propValue); // Creates dual state management!
|
|
53
|
+
}, [propValue]);
|
|
54
|
+
|
|
55
|
+
// ✅ CORRECT - Initialize once:
|
|
56
|
+
const [value, setValue] = useState(
|
|
57
|
+
savedUserSettings?.value || defaultValue
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
// ✅ CORRECT - If you need prop changes, use derived state:
|
|
61
|
+
const displayValue = propOverride || value;`,
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
return violations;
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
PropStateSyncRule = __decorate([
|
|
73
|
+
RegisterClass(BaseLintRule, 'prop-state-sync')
|
|
74
|
+
], PropStateSyncRule);
|
|
75
|
+
export { PropStateSyncRule };
|
|
76
|
+
//# sourceMappingURL=prop-state-sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prop-state-sync.js","sourceRoot":"","sources":["../../src/runtime-rules/prop-state-sync.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,QAAQ,EAAY,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAG5C;;;;;;;;;GASG;AAEI,IAAM,iBAAiB,GAAvB,MAAM,iBAAkB,SAAQ,YAAY;IACjD,IAAI,IAAI,KAAK,OAAO,iBAAiB,CAAC,CAAC,CAAC;IACxC,IAAI,SAAS,KAA+B,OAAO,KAAK,CAAC,CAAC,CAAC;IAE3D,IAAI,CAAC,GAAW,EAAE,cAAsB;QACtC,MAAM,UAAU,GAAgB,EAAE,CAAC;QAEnC,QAAQ,CAAC,GAAG,EAAE;YACZ,cAAc,CAAC,IAAgC;gBAC7C,IAAI,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;oBAC9E,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;oBAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;oBAEpC,IAAI,UAAU,IAAI,CAAC,CAAC,CAAC,yBAAyB,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;wBAClG,MAAM,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;wBAE9C,6CAA6C;wBAC7C,MAAM,WAAW,GAAG,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;wBACxD,MAAM,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBAE/C,wCAAwC;wBACxC,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;wBACxD,MAAM,WAAW,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;wBAErE,IAAI,WAAW,IAAI,WAAW,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;4BAChE,UAAU,CAAC,IAAI,CAAC;gCACd,IAAI,EAAE,iBAAiB;gCACvB,QAAQ,EAAE,UAAU;gCACpB,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC;gCACpC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC;gCACxC,OAAO,EAAE,8EAA8E;gCACvF,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC;gCACvC,UAAU,EAAE;oCACV,IAAI,EAAE,8CAA8C;oCACpD,OAAO,EAAE;;;;;;;;;;;;4CAYiB;iCAC3B;6BACF,CAAC,CAAC;wBACL,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;SACF,CAAC,CAAC;QAEH,OAAO,UAAU,CAAC;IACpB,CAAC;CACF,CAAA;AAzDY,iBAAiB;IAD7B,aAAa,CAAC,YAAY,EAAE,iBAAiB,CAAC;GAClC,iBAAiB,CAyD7B"}
|