@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,106 @@
|
|
|
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 * as t from '@babel/types';
|
|
8
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
9
|
+
import { BaseLintRule } from '../lint-rule.js';
|
|
10
|
+
import { createViolation } from '../lint-utils.js';
|
|
11
|
+
/**
|
|
12
|
+
* Rule: no-return-component
|
|
13
|
+
*
|
|
14
|
+
* Ensures that components don't have return statements or component references
|
|
15
|
+
* at the end of the file. The component function should stand alone.
|
|
16
|
+
*
|
|
17
|
+
* Severity: critical
|
|
18
|
+
* Applies to: all components
|
|
19
|
+
*/
|
|
20
|
+
let NoReturnComponentRule = class NoReturnComponentRule extends BaseLintRule {
|
|
21
|
+
get Name() { return 'no-return-component'; }
|
|
22
|
+
get AppliesTo() { return 'all'; }
|
|
23
|
+
Test(ast, componentName) {
|
|
24
|
+
const violations = [];
|
|
25
|
+
// Check for return statements at the program/top level
|
|
26
|
+
if (ast.program && ast.program.body) {
|
|
27
|
+
for (const statement of ast.program.body) {
|
|
28
|
+
// Check for return statement returning the component
|
|
29
|
+
if (t.isReturnStatement(statement)) {
|
|
30
|
+
const argument = statement.argument;
|
|
31
|
+
// Check if it's returning the component identifier or any identifier
|
|
32
|
+
if (argument && t.isIdentifier(argument)) {
|
|
33
|
+
// If it's returning the component name or any identifier at top level
|
|
34
|
+
violations.push(createViolation('no-return-component', 'critical', statement, `Do not return the component at the end of the file. The component function should stand alone.`, `return ${argument.name};`, {
|
|
35
|
+
text: 'Remove the return statement at the end of the file. The component function should stand alone.',
|
|
36
|
+
example: `// ❌ WRONG - Returning the component:
|
|
37
|
+
function MyComponent({ utilities, styles, components }) {
|
|
38
|
+
const [state, setState] = useState('');
|
|
39
|
+
|
|
40
|
+
return <div>{state}</div>;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return MyComponent; // <-- Remove this!
|
|
44
|
+
|
|
45
|
+
// ❌ ALSO WRONG - Component reference at end:
|
|
46
|
+
function MyComponent({ utilities, styles, components }) {
|
|
47
|
+
return <div>Hello</div>;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
MyComponent; // <-- Remove this!
|
|
51
|
+
|
|
52
|
+
// ✅ CORRECT - Just the function declaration:
|
|
53
|
+
function MyComponent({ utilities, styles, components }) {
|
|
54
|
+
const [state, setState] = useState('');
|
|
55
|
+
|
|
56
|
+
return <div>{state}</div>;
|
|
57
|
+
}
|
|
58
|
+
// Nothing after the function - file ends here
|
|
59
|
+
|
|
60
|
+
// The runtime will find and execute your component
|
|
61
|
+
// by its function name. No need to return or reference it!`,
|
|
62
|
+
}));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// Also check for expression statements that might be standalone identifiers
|
|
66
|
+
if (t.isExpressionStatement(statement) && t.isIdentifier(statement.expression) && statement.expression.name === componentName) {
|
|
67
|
+
violations.push(createViolation('no-return-component', 'critical', statement, `Do not reference the component "${componentName}" at the end of the file. The component function should stand alone.`, statement.expression.name, {
|
|
68
|
+
text: 'Remove the return statement at the end of the file. The component function should stand alone.',
|
|
69
|
+
example: `// ❌ WRONG - Returning the component:
|
|
70
|
+
function MyComponent({ utilities, styles, components }) {
|
|
71
|
+
const [state, setState] = useState('');
|
|
72
|
+
|
|
73
|
+
return <div>{state}</div>;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return MyComponent; // <-- Remove this!
|
|
77
|
+
|
|
78
|
+
// ❌ ALSO WRONG - Component reference at end:
|
|
79
|
+
function MyComponent({ utilities, styles, components }) {
|
|
80
|
+
return <div>Hello</div>;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
MyComponent; // <-- Remove this!
|
|
84
|
+
|
|
85
|
+
// ✅ CORRECT - Just the function declaration:
|
|
86
|
+
function MyComponent({ utilities, styles, components }) {
|
|
87
|
+
const [state, setState] = useState('');
|
|
88
|
+
|
|
89
|
+
return <div>{state}</div>;
|
|
90
|
+
}
|
|
91
|
+
// Nothing after the function - file ends here
|
|
92
|
+
|
|
93
|
+
// The runtime will find and execute your component
|
|
94
|
+
// by its function name. No need to return or reference it!`,
|
|
95
|
+
}));
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return violations;
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
NoReturnComponentRule = __decorate([
|
|
103
|
+
RegisterClass(BaseLintRule, 'no-return-component')
|
|
104
|
+
], NoReturnComponentRule);
|
|
105
|
+
export { NoReturnComponentRule };
|
|
106
|
+
//# sourceMappingURL=no-return-component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-return-component.js","sourceRoot":"","sources":["../../src/runtime-rules/no-return-component.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD;;;;;;;;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,aAAqB;QACrC,MAAM,UAAU,GAAgB,EAAE,CAAC;QAEnC,uDAAuD;QACvD,IAAI,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YACpC,KAAK,MAAM,SAAS,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;gBACzC,qDAAqD;gBACrD,IAAI,CAAC,CAAC,iBAAiB,CAAC,SAAS,CAAC,EAAE,CAAC;oBACnC,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAC;oBAEpC,qEAAqE;oBACrE,IAAI,QAAQ,IAAI,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC;wBACzC,sEAAsE;wBACtE,UAAU,CAAC,IAAI,CACb,eAAe,CACb,qBAAqB,EACrB,UAAU,EACV,SAAS,EACT,gGAAgG,EAChG,UAAU,QAAQ,CAAC,IAAI,GAAG,EAC1B;4BACE,IAAI,EAAE,gGAAgG;4BACtG,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;4DAyBiC;yBAC3C,CACF,CACF,CAAC;oBACJ,CAAC;gBACH,CAAC;gBAED,4EAA4E;gBAC5E,IAAI,CAAC,CAAC,qBAAqB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,SAAS,CAAC,UAAU,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;oBAC9H,UAAU,CAAC,IAAI,CACb,eAAe,CACb,qBAAqB,EACrB,UAAU,EACV,SAAS,EACT,mCAAmC,aAAa,sEAAsE,EACtH,SAAS,CAAC,UAAU,CAAC,IAAI,EACzB;wBACE,IAAI,EAAE,gGAAgG;wBACtG,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;4DAyBmC;qBAC7C,CACF,CACF,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,UAAU,CAAC;IACpB,CAAC;CACF,CAAA;AAxGY,qBAAqB;IADjC,aAAa,CAAC,YAAY,EAAE,qBAAqB,CAAC;GACtC,qBAAqB,CAwGjC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as t from '@babel/types';
|
|
2
|
+
import { BaseLintRule } from '../lint-rule.js';
|
|
3
|
+
import { Violation } from '../component-linter.js';
|
|
4
|
+
/**
|
|
5
|
+
* Rule: no-unwrap-utility-libs
|
|
6
|
+
*
|
|
7
|
+
* Flags unwrapLibraryComponents() calls where the first argument is a known utility
|
|
8
|
+
* library global (`_`, `dayjs`, `d3`, `moment`). These libraries expose their API as
|
|
9
|
+
* methods on the global variable — wrapping them with unwrapLibraryComponents() makes
|
|
10
|
+
* the extracted functions non-callable, causing runtime crashes.
|
|
11
|
+
*
|
|
12
|
+
* Severity: critical
|
|
13
|
+
* Applies to: all components
|
|
14
|
+
*/
|
|
15
|
+
export declare class NoUnwrapUtilityLibsRule extends BaseLintRule {
|
|
16
|
+
get Name(): string;
|
|
17
|
+
get AppliesTo(): 'all' | 'child' | 'root';
|
|
18
|
+
Test(ast: t.File, componentName: string): Violation[];
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=no-unwrap-utility-libs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-unwrap-utility-libs.d.ts","sourceRoot":"","sources":["../../src/runtime-rules/no-unwrap-utility-libs.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;AAkBhD;;;;;;;;;;GAUG;AACH,qBACa,uBAAwB,SAAQ,YAAY;IACvD,IAAI,IAAI,WAAuC;IAC/C,IAAI,SAAS,IAAI,KAAK,GAAG,OAAO,GAAG,MAAM,CAAkB;IAE3D,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,aAAa,EAAE,MAAM,GAAG,SAAS,EAAE;CA+CtD"}
|
|
@@ -0,0 +1,75 @@
|
|
|
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
|
+
* Known utility libraries whose globals must NOT be passed to unwrapLibraryComponents().
|
|
13
|
+
* These libraries expose their API as methods on the global variable and should be
|
|
14
|
+
* called directly (e.g., `_.debounce(fn, 500)`, `dayjs(date).format('YYYY-MM-DD')`).
|
|
15
|
+
*
|
|
16
|
+
* unwrapLibraryComponents() wraps the value in a way that makes utility functions
|
|
17
|
+
* non-callable, causing runtime crashes like:
|
|
18
|
+
* Uncaught TypeError: D is not a function
|
|
19
|
+
*/
|
|
20
|
+
const UTILITY_LIBS = new Map([
|
|
21
|
+
['_', { library: 'lodash', example: '_.debounce(myFunction, 500)' }],
|
|
22
|
+
['dayjs', { library: 'Day.js', example: "dayjs(date).format('YYYY-MM-DD')" }],
|
|
23
|
+
['d3', { library: 'D3.js', example: "d3.select('#chart')" }],
|
|
24
|
+
['moment', { library: 'Moment.js', example: "moment().format('YYYY-MM-DD')" }],
|
|
25
|
+
]);
|
|
26
|
+
/**
|
|
27
|
+
* Rule: no-unwrap-utility-libs
|
|
28
|
+
*
|
|
29
|
+
* Flags unwrapLibraryComponents() calls where the first argument is a known utility
|
|
30
|
+
* library global (`_`, `dayjs`, `d3`, `moment`). These libraries expose their API as
|
|
31
|
+
* methods on the global variable — wrapping them with unwrapLibraryComponents() makes
|
|
32
|
+
* the extracted functions non-callable, causing runtime crashes.
|
|
33
|
+
*
|
|
34
|
+
* Severity: critical
|
|
35
|
+
* Applies to: all components
|
|
36
|
+
*/
|
|
37
|
+
let NoUnwrapUtilityLibsRule = class NoUnwrapUtilityLibsRule extends BaseLintRule {
|
|
38
|
+
get Name() { return 'no-unwrap-utility-libs'; }
|
|
39
|
+
get AppliesTo() { return 'all'; }
|
|
40
|
+
Test(ast, componentName) {
|
|
41
|
+
const violations = [];
|
|
42
|
+
traverse(ast, {
|
|
43
|
+
CallExpression(path) {
|
|
44
|
+
if (!t.isIdentifier(path.node.callee) || path.node.callee.name !== 'unwrapLibraryComponents') {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const firstArg = path.node.arguments[0];
|
|
48
|
+
if (!firstArg || !t.isIdentifier(firstArg)) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const globalName = firstArg.name;
|
|
52
|
+
const libInfo = UTILITY_LIBS.get(globalName);
|
|
53
|
+
if (!libInfo) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const message = `Do not use unwrapLibraryComponents() with utility library "${globalName}" (${libInfo.library}). ` +
|
|
57
|
+
`Utility libraries expose their API as methods on the global variable — call them directly ` +
|
|
58
|
+
`(e.g., ${libInfo.example}). unwrapLibraryComponents() is only for UI component libraries like antd.`;
|
|
59
|
+
violations.push(createViolation('no-unwrap-utility-libs', 'critical', path.node, message, truncateCode(path.toString()), {
|
|
60
|
+
text: 'Remove the unwrapLibraryComponents() call and use the library global directly.',
|
|
61
|
+
example: '// Instead of:\n' +
|
|
62
|
+
`const { debounce } = unwrapLibraryComponents(${globalName}, 'debounce');\n` +
|
|
63
|
+
'// Use:\n' +
|
|
64
|
+
`const debouncedFn = ${libInfo.example};`,
|
|
65
|
+
}));
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
return violations;
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
NoUnwrapUtilityLibsRule = __decorate([
|
|
72
|
+
RegisterClass(BaseLintRule, 'no-unwrap-utility-libs')
|
|
73
|
+
], NoUnwrapUtilityLibsRule);
|
|
74
|
+
export { NoUnwrapUtilityLibsRule };
|
|
75
|
+
//# sourceMappingURL=no-unwrap-utility-libs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-unwrap-utility-libs.js","sourceRoot":"","sources":["../../src/runtime-rules/no-unwrap-utility-libs.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,QAAQ,EAAY,eAAe,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClF,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAG5C;;;;;;;;GAQG;AACH,MAAM,YAAY,GAA8D,IAAI,GAAG,CAAC;IACtF,CAAC,GAAG,EAAO,EAAE,OAAO,EAAE,QAAQ,EAAK,OAAO,EAAE,6BAA6B,EAAE,CAAC;IAC5E,CAAC,OAAO,EAAG,EAAE,OAAO,EAAE,QAAQ,EAAK,OAAO,EAAE,kCAAkC,EAAE,CAAC;IACjF,CAAC,IAAI,EAAM,EAAE,OAAO,EAAE,OAAO,EAAM,OAAO,EAAE,qBAAqB,EAAE,CAAC;IACpE,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,+BAA+B,EAAE,CAAC;CAC/E,CAAC,CAAC;AAEH;;;;;;;;;;GAUG;AAEI,IAAM,uBAAuB,GAA7B,MAAM,uBAAwB,SAAQ,YAAY;IACvD,IAAI,IAAI,KAAK,OAAO,wBAAwB,CAAC,CAAC,CAAC;IAC/C,IAAI,SAAS,KAA+B,OAAO,KAAK,CAAC,CAAC,CAAC;IAE3D,IAAI,CAAC,GAAW,EAAE,aAAqB;QACrC,MAAM,UAAU,GAAgB,EAAE,CAAC;QAEnC,QAAQ,CAAC,GAAG,EAAE;YACZ,cAAc,CAAC,IAAgC;gBAC7C,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,yBAAyB,EAAE,CAAC;oBAC7F,OAAO;gBACT,CAAC;gBAED,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;gBACxC,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAC3C,OAAO;gBACT,CAAC;gBAED,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC;gBACjC,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;gBAC7C,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,OAAO;gBACT,CAAC;gBAED,MAAM,OAAO,GACX,8DAA8D,UAAU,MAAM,OAAO,CAAC,OAAO,KAAK;oBAClG,4FAA4F;oBAC5F,UAAU,OAAO,CAAC,OAAO,4EAA4E,CAAC;gBAExG,UAAU,CAAC,IAAI,CACb,eAAe,CACb,wBAAwB,EACxB,UAAU,EACV,IAAI,CAAC,IAAI,EACT,OAAO,EACP,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,EAC7B;oBACE,IAAI,EAAE,gFAAgF;oBACtF,OAAO,EACL,kBAAkB;wBAClB,gDAAgD,UAAU,kBAAkB;wBAC5E,WAAW;wBACX,uBAAuB,OAAO,CAAC,OAAO,GAAG;iBAC5C,CACF,CACF,CAAC;YACJ,CAAC;SACF,CAAC,CAAC;QAEH,OAAO,UAAU,CAAC;IACpB,CAAC;CACF,CAAA;AAnDY,uBAAuB;IADnC,aAAa,CAAC,YAAY,EAAE,wBAAwB,CAAC;GACzC,uBAAuB,CAmDnC"}
|
|
@@ -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: no-use-reducer
|
|
6
|
+
*
|
|
7
|
+
* Prevents usage of useReducer hook in interactive components.
|
|
8
|
+
* Components should manage state with useState and persist important
|
|
9
|
+
* settings with onSaveUserSettings instead.
|
|
10
|
+
*
|
|
11
|
+
* Severity: high (pattern violation, not a functional issue)
|
|
12
|
+
* Applies to: all components
|
|
13
|
+
*/
|
|
14
|
+
export declare class NoUseReducerRule extends BaseLintRule {
|
|
15
|
+
get Name(): string;
|
|
16
|
+
get AppliesTo(): 'all' | 'child' | 'root';
|
|
17
|
+
Test(ast: t.File, componentName: string): Violation[];
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=no-use-reducer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-use-reducer.d.ts","sourceRoot":"","sources":["../../src/runtime-rules/no-use-reducer.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,gBAAiB,SAAQ,YAAY;IAChD,IAAI,IAAI,WAA+B;IACvC,IAAI,SAAS,IAAI,KAAK,GAAG,OAAO,GAAG,MAAM,CAAkB;IAE3D,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,aAAa,EAAE,MAAM,GAAG,SAAS,EAAE;CAsDtD"}
|
|
@@ -0,0 +1,78 @@
|
|
|
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: no-use-reducer
|
|
13
|
+
*
|
|
14
|
+
* Prevents usage of useReducer hook in interactive components.
|
|
15
|
+
* Components should manage state with useState and persist important
|
|
16
|
+
* settings with onSaveUserSettings instead.
|
|
17
|
+
*
|
|
18
|
+
* Severity: high (pattern violation, not a functional issue)
|
|
19
|
+
* Applies to: all components
|
|
20
|
+
*/
|
|
21
|
+
let NoUseReducerRule = class NoUseReducerRule extends BaseLintRule {
|
|
22
|
+
get Name() { return 'no-use-reducer'; }
|
|
23
|
+
get AppliesTo() { return 'all'; }
|
|
24
|
+
Test(ast, componentName) {
|
|
25
|
+
const violations = [];
|
|
26
|
+
traverse(ast, {
|
|
27
|
+
CallExpression(path) {
|
|
28
|
+
const callee = path.node.callee;
|
|
29
|
+
if ((t.isIdentifier(callee) && callee.name === 'useReducer') ||
|
|
30
|
+
(t.isMemberExpression(callee) &&
|
|
31
|
+
t.isIdentifier(callee.object) &&
|
|
32
|
+
callee.object.name === 'React' &&
|
|
33
|
+
t.isIdentifier(callee.property) &&
|
|
34
|
+
callee.property.name === 'useReducer')) {
|
|
35
|
+
violations.push({
|
|
36
|
+
rule: 'no-use-reducer',
|
|
37
|
+
severity: 'high', // High but not critical - it's a pattern violation
|
|
38
|
+
line: path.node.loc?.start.line || 0,
|
|
39
|
+
column: path.node.loc?.start.column || 0,
|
|
40
|
+
message: `Component "${componentName}" uses useReducer at line ${path.node.loc?.start.line}. Components should manage state with useState and persist important settings with onSaveUserSettings.`,
|
|
41
|
+
code: path.toString(),
|
|
42
|
+
suggestion: {
|
|
43
|
+
text: 'Use useState for state management, not useReducer',
|
|
44
|
+
example: `// Instead of:
|
|
45
|
+
const [state, dispatch] = useReducer(reducer, initialState);
|
|
46
|
+
|
|
47
|
+
// Use useState:
|
|
48
|
+
function Component({ savedUserSettings, onSaveUserSettings }) {
|
|
49
|
+
const [selectedId, setSelectedId] = useState(
|
|
50
|
+
savedUserSettings?.selectedId
|
|
51
|
+
);
|
|
52
|
+
const [filters, setFilters] = useState(
|
|
53
|
+
savedUserSettings?.filters || {}
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
// Handle actions directly
|
|
57
|
+
const handleAction = (action) => {
|
|
58
|
+
switch(action.type) {
|
|
59
|
+
case 'SELECT':
|
|
60
|
+
setSelectedId(action.payload);
|
|
61
|
+
onSaveUserSettings?.({ ...savedUserSettings, selectedId: action.payload });
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
}`,
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
return violations;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
NoUseReducerRule = __decorate([
|
|
75
|
+
RegisterClass(BaseLintRule, 'no-use-reducer')
|
|
76
|
+
], NoUseReducerRule);
|
|
77
|
+
export { NoUseReducerRule };
|
|
78
|
+
//# sourceMappingURL=no-use-reducer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-use-reducer.js","sourceRoot":"","sources":["../../src/runtime-rules/no-use-reducer.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,gBAAgB,GAAtB,MAAM,gBAAiB,SAAQ,YAAY;IAChD,IAAI,IAAI,KAAK,OAAO,gBAAgB,CAAC,CAAC,CAAC;IACvC,IAAI,SAAS,KAA+B,OAAO,KAAK,CAAC,CAAC,CAAC;IAE3D,IAAI,CAAC,GAAW,EAAE,aAAqB;QACrC,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,IACE,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,KAAK,YAAY,CAAC;oBACxD,CAAC,CAAC,CAAC,kBAAkB,CAAC,MAAM,CAAC;wBAC3B,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC;wBAC7B,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,OAAO;wBAC9B,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC;wBAC/B,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY,CAAC,EACxC,CAAC;oBACD,UAAU,CAAC,IAAI,CAAC;wBACd,IAAI,EAAE,gBAAgB;wBACtB,QAAQ,EAAE,MAAM,EAAE,mDAAmD;wBACrE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC;wBACpC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC;wBACxC,OAAO,EAAE,cAAc,aAAa,6BAA6B,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,wGAAwG;wBAClM,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE;wBACrB,UAAU,EAAE;4BACV,IAAI,EAAE,mDAAmD;4BACzD,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;EAqBrB;yBACW;qBACF,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;SACF,CAAC,CAAC;QAEH,OAAO,UAAU,CAAC;IACpB,CAAC;CACF,CAAA;AA1DY,gBAAgB;IAD5B,aAAa,CAAC,YAAY,EAAE,gBAAgB,CAAC;GACjC,gBAAgB,CA0D5B"}
|
|
@@ -0,0 +1,23 @@
|
|
|
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: no-window-access
|
|
7
|
+
*
|
|
8
|
+
* Prevents components from accessing the window object. Libraries should be accessed
|
|
9
|
+
* through unwrapComponents, not through window. Interactive components must be
|
|
10
|
+
* self-contained and not rely on global state.
|
|
11
|
+
*
|
|
12
|
+
* Allows export handler patterns (window.ComponentNameExport) for intentional
|
|
13
|
+
* component export functionality with proper cleanup.
|
|
14
|
+
*
|
|
15
|
+
* Severity: critical
|
|
16
|
+
* Applies to: all components
|
|
17
|
+
*/
|
|
18
|
+
export declare class NoWindowAccessRule extends BaseLintRule {
|
|
19
|
+
get Name(): string;
|
|
20
|
+
get AppliesTo(): 'all' | 'child' | 'root';
|
|
21
|
+
Test(ast: t.File, componentName: string, componentSpec?: ComponentSpec): Violation[];
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=no-window-access.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-window-access.d.ts","sourceRoot":"","sources":["../../src/runtime-rules/no-window-access.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;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAE5E;;;;;;;;;;;;GAYG;AACH,qBACa,kBAAmB,SAAQ,YAAY;IAClD,IAAI,IAAI,WAAiC;IACzC,IAAI,SAAS,IAAI,KAAK,GAAG,OAAO,GAAG,MAAM,CAAkB;IAE3D,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,aAAa,GAAG,SAAS,EAAE;CA8GrF"}
|
|
@@ -0,0 +1,136 @@
|
|
|
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: no-window-access
|
|
13
|
+
*
|
|
14
|
+
* Prevents components from accessing the window object. Libraries should be accessed
|
|
15
|
+
* through unwrapComponents, not through window. Interactive components must be
|
|
16
|
+
* self-contained and not rely on global state.
|
|
17
|
+
*
|
|
18
|
+
* Allows export handler patterns (window.ComponentNameExport) for intentional
|
|
19
|
+
* component export functionality with proper cleanup.
|
|
20
|
+
*
|
|
21
|
+
* Severity: critical
|
|
22
|
+
* Applies to: all components
|
|
23
|
+
*/
|
|
24
|
+
let NoWindowAccessRule = class NoWindowAccessRule extends BaseLintRule {
|
|
25
|
+
get Name() { return 'no-window-access'; }
|
|
26
|
+
get AppliesTo() { return 'all'; }
|
|
27
|
+
Test(ast, componentName, componentSpec) {
|
|
28
|
+
const violations = [];
|
|
29
|
+
// Build a map of library names to their global variables from the component spec
|
|
30
|
+
const libraryMap = new Map();
|
|
31
|
+
if (componentSpec?.libraries) {
|
|
32
|
+
for (const lib of componentSpec.libraries) {
|
|
33
|
+
// Skip empty library objects or those without required fields
|
|
34
|
+
if (lib.globalVariable && lib.name) {
|
|
35
|
+
// Store both the library name and globalVariable for lookup
|
|
36
|
+
libraryMap.set(lib.name.toLowerCase(), lib.globalVariable);
|
|
37
|
+
libraryMap.set(lib.globalVariable.toLowerCase(), lib.globalVariable);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
traverse(ast, {
|
|
42
|
+
MemberExpression(path) {
|
|
43
|
+
// Check if accessing window object
|
|
44
|
+
if (t.isIdentifier(path.node.object) && path.node.object.name === 'window') {
|
|
45
|
+
// Check what property is being accessed from window
|
|
46
|
+
let propertyName = '';
|
|
47
|
+
let isDestructuring = false;
|
|
48
|
+
if (t.isIdentifier(path.node.property)) {
|
|
49
|
+
propertyName = path.node.property.name;
|
|
50
|
+
}
|
|
51
|
+
else if (t.isMemberExpression(path.node.property)) {
|
|
52
|
+
// Handle chained access like window.Recharts.ResponsiveContainer
|
|
53
|
+
const firstProp = path.node.property;
|
|
54
|
+
if (t.isIdentifier(firstProp.object)) {
|
|
55
|
+
propertyName = firstProp.object.name;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// Check if this is part of a destructuring assignment
|
|
59
|
+
let currentPath = path.parentPath;
|
|
60
|
+
while (currentPath) {
|
|
61
|
+
if (t.isVariableDeclarator(currentPath.node) && t.isObjectPattern(currentPath.node.id)) {
|
|
62
|
+
isDestructuring = true;
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
currentPath = currentPath.parentPath;
|
|
66
|
+
}
|
|
67
|
+
// Check if the property matches a known library
|
|
68
|
+
const matchedLibrary = libraryMap.get(propertyName.toLowerCase());
|
|
69
|
+
// Allow export handler patterns: window.ComponentNameExport
|
|
70
|
+
// These are intentional patterns for export functionality with proper cleanup
|
|
71
|
+
const isExportPattern = propertyName.endsWith('Export') || propertyName.endsWith('Handler') || propertyName.endsWith('Callback');
|
|
72
|
+
if (isExportPattern) {
|
|
73
|
+
// Skip - this is an intentional pattern for component export functionality
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (matchedLibrary) {
|
|
77
|
+
// Specific guidance for library access
|
|
78
|
+
violations.push({
|
|
79
|
+
rule: 'no-window-access',
|
|
80
|
+
severity: 'critical',
|
|
81
|
+
line: path.node.loc?.start.line || 0,
|
|
82
|
+
column: path.node.loc?.start.column || 0,
|
|
83
|
+
message: `Component "${componentName}" should not access window.${propertyName}. Use "${matchedLibrary}" directly - it's already available in the component's closure scope. Change "window.${propertyName}" to just "${matchedLibrary}".`,
|
|
84
|
+
code: path.toString().substring(0, 100),
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
else if (isDestructuring) {
|
|
88
|
+
// Likely trying to destructure from an unknown library
|
|
89
|
+
violations.push({
|
|
90
|
+
rule: 'no-window-access',
|
|
91
|
+
severity: 'critical',
|
|
92
|
+
line: path.node.loc?.start.line || 0,
|
|
93
|
+
column: path.node.loc?.start.column || 0,
|
|
94
|
+
message: `Component "${componentName}" is trying to access window.${propertyName}. Libraries must be accessed using unwrapComponents, not through the window object. If this library is in your spec, use: const { ... } = unwrapComponents(${propertyName}, [...]); If it's not in your spec, you cannot use it.`,
|
|
95
|
+
code: path.toString().substring(0, 100),
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
// General window access
|
|
100
|
+
violations.push({
|
|
101
|
+
rule: 'no-window-access',
|
|
102
|
+
severity: 'critical',
|
|
103
|
+
line: path.node.loc?.start.line || 0,
|
|
104
|
+
column: path.node.loc?.start.column || 0,
|
|
105
|
+
message: `Component "${componentName}" must not access the window object. Interactive components should be self-contained and not rely on global state.`,
|
|
106
|
+
code: path.toString().substring(0, 100),
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
Identifier(path) {
|
|
112
|
+
// Also check for direct window references (less common but possible)
|
|
113
|
+
if (path.node.name === 'window' && path.isReferencedIdentifier()) {
|
|
114
|
+
// Make sure it's not part of a member expression we already caught
|
|
115
|
+
const parent = path.parent;
|
|
116
|
+
if (!t.isMemberExpression(parent) || parent.object !== path.node) {
|
|
117
|
+
violations.push({
|
|
118
|
+
rule: 'no-window-access',
|
|
119
|
+
severity: 'critical',
|
|
120
|
+
line: path.node.loc?.start.line || 0,
|
|
121
|
+
column: path.node.loc?.start.column || 0,
|
|
122
|
+
message: `Component "${componentName}" must not reference the window object directly. Interactive components should be self-contained.`,
|
|
123
|
+
code: path.toString().substring(0, 100),
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
return violations;
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
NoWindowAccessRule = __decorate([
|
|
133
|
+
RegisterClass(BaseLintRule, 'no-window-access')
|
|
134
|
+
], NoWindowAccessRule);
|
|
135
|
+
export { NoWindowAccessRule };
|
|
136
|
+
//# sourceMappingURL=no-window-access.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-window-access.js","sourceRoot":"","sources":["../../src/runtime-rules/no-window-access.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as t from '@babel/types';
|
|
2
|
+
import { BaseLintRule } from '../lint-rule.js';
|
|
3
|
+
import { Violation } from '../component-linter.js';
|
|
4
|
+
/**
|
|
5
|
+
* Rule: noisy-settings-updates
|
|
6
|
+
*
|
|
7
|
+
* Prevents saving settings on every change/keystroke. Settings should only be
|
|
8
|
+
* saved on blur, submit, or after debouncing to avoid excessive updates.
|
|
9
|
+
*
|
|
10
|
+
* Severity: critical
|
|
11
|
+
* Applies to: all components
|
|
12
|
+
*/
|
|
13
|
+
export declare class NoisySettingsUpdatesRule extends BaseLintRule {
|
|
14
|
+
get Name(): string;
|
|
15
|
+
get AppliesTo(): 'all' | 'child' | 'root';
|
|
16
|
+
Test(ast: t.File, _componentName: string): Violation[];
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=noisy-settings-updates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"noisy-settings-updates.d.ts","sourceRoot":"","sources":["../../src/runtime-rules/noisy-settings-updates.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;AAgChD;;;;;;;;GAQG;AACH,qBACa,wBAAyB,SAAQ,YAAY;IACxD,IAAI,IAAI,WAAuC;IAC/C,IAAI,SAAS,IAAI,KAAK,GAAG,OAAO,GAAG,MAAM,CAAkB;IAE3D,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,GAAG,SAAS,EAAE;CA4DvD"}
|
|
@@ -0,0 +1,110 @@
|
|
|
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
|
+
* Helper function to extract function name from a NodePath
|
|
13
|
+
*/
|
|
14
|
+
function getFunctionName(path) {
|
|
15
|
+
const node = path.node;
|
|
16
|
+
// Check for named function
|
|
17
|
+
if (t.isFunctionDeclaration(node) && node.id) {
|
|
18
|
+
return node.id.name;
|
|
19
|
+
}
|
|
20
|
+
// Check for arrow function assigned to variable
|
|
21
|
+
if (t.isArrowFunctionExpression(node) || t.isFunctionExpression(node)) {
|
|
22
|
+
const parent = path.parent;
|
|
23
|
+
if (t.isVariableDeclarator(parent) && t.isIdentifier(parent.id)) {
|
|
24
|
+
return parent.id.name;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
// Check for function assigned as property
|
|
28
|
+
if (t.isArrowFunctionExpression(node) || t.isFunctionExpression(node)) {
|
|
29
|
+
const parent = path.parent;
|
|
30
|
+
if (t.isObjectProperty(parent) && t.isIdentifier(parent.key)) {
|
|
31
|
+
return parent.key.name;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Rule: noisy-settings-updates
|
|
38
|
+
*
|
|
39
|
+
* Prevents saving settings on every change/keystroke. Settings should only be
|
|
40
|
+
* saved on blur, submit, or after debouncing to avoid excessive updates.
|
|
41
|
+
*
|
|
42
|
+
* Severity: critical
|
|
43
|
+
* Applies to: all components
|
|
44
|
+
*/
|
|
45
|
+
let NoisySettingsUpdatesRule = class NoisySettingsUpdatesRule extends BaseLintRule {
|
|
46
|
+
get Name() { return 'noisy-settings-updates'; }
|
|
47
|
+
get AppliesTo() { return 'all'; }
|
|
48
|
+
Test(ast, _componentName) {
|
|
49
|
+
const violations = [];
|
|
50
|
+
traverse(ast, {
|
|
51
|
+
CallExpression(path) {
|
|
52
|
+
// Check for onSaveUserSettings calls
|
|
53
|
+
if (t.isOptionalCallExpression(path.node) || t.isCallExpression(path.node)) {
|
|
54
|
+
const callee = path.node.callee;
|
|
55
|
+
if (t.isIdentifier(callee) && callee.name === 'onSaveUserSettings') {
|
|
56
|
+
// Check if this is inside an onChange/onInput handler
|
|
57
|
+
let parent = path.getFunctionParent();
|
|
58
|
+
if (parent) {
|
|
59
|
+
const funcName = getFunctionName(parent);
|
|
60
|
+
if (funcName && (funcName.includes('Change') || funcName.includes('Input'))) {
|
|
61
|
+
// Check if it's not debounced or on blur
|
|
62
|
+
const parentBody = parent.node.body;
|
|
63
|
+
const hasDebounce = parentBody && parentBody.toString().includes('debounce');
|
|
64
|
+
const hasTimeout = parentBody && parentBody.toString().includes('setTimeout');
|
|
65
|
+
if (!hasDebounce && !hasTimeout) {
|
|
66
|
+
violations.push({
|
|
67
|
+
rule: 'noisy-settings-updates',
|
|
68
|
+
severity: 'critical',
|
|
69
|
+
line: path.node.loc?.start.line || 0,
|
|
70
|
+
column: path.node.loc?.start.column || 0,
|
|
71
|
+
message: `Saving settings on every change/keystroke. Save on blur, submit, or after debouncing.`,
|
|
72
|
+
suggestion: {
|
|
73
|
+
text: 'Save settings sparingly - only on meaningful user actions',
|
|
74
|
+
example: `// ❌ WRONG - Saving on every keystroke:
|
|
75
|
+
const handleSearchChange = (e) => {
|
|
76
|
+
setSearchTerm(e.target.value);
|
|
77
|
+
onSaveUserSettings?.({ searchTerm: e.target.value }); // TOO NOISY!
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
// ✅ CORRECT - Save on blur or debounced:
|
|
81
|
+
const handleSearchBlur = () => {
|
|
82
|
+
if (searchTerm !== savedUserSettings?.searchTerm) {
|
|
83
|
+
onSaveUserSettings?.({ ...savedUserSettings, searchTerm });
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
// ✅ CORRECT - Debounced save:
|
|
88
|
+
const saveSearchTerm = useMemo(() =>
|
|
89
|
+
debounce((term) => {
|
|
90
|
+
onSaveUserSettings?.({ ...savedUserSettings, searchTerm: term });
|
|
91
|
+
}, 500),
|
|
92
|
+
[savedUserSettings]
|
|
93
|
+
);`,
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
return violations;
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
NoisySettingsUpdatesRule = __decorate([
|
|
107
|
+
RegisterClass(BaseLintRule, 'noisy-settings-updates')
|
|
108
|
+
], NoisySettingsUpdatesRule);
|
|
109
|
+
export { NoisySettingsUpdatesRule };
|
|
110
|
+
//# sourceMappingURL=noisy-settings-updates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"noisy-settings-updates.js","sourceRoot":"","sources":["../../src/runtime-rules/noisy-settings-updates.ts"],"names":[],"mappings":"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"}
|