@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,72 @@
|
|
|
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 * as t from '@babel/types';
|
|
9
|
+
import { BaseLintRule } from '../lint-rule.js';
|
|
10
|
+
import { traverse, createViolation } from '../lint-utils.js';
|
|
11
|
+
/**
|
|
12
|
+
* Rule: react-component-naming
|
|
13
|
+
*
|
|
14
|
+
* Ensures that React components follow naming conventions:
|
|
15
|
+
* - Component names must start with an uppercase letter
|
|
16
|
+
* - JSX treats lowercase as HTML elements
|
|
17
|
+
*
|
|
18
|
+
* Severity: critical
|
|
19
|
+
* Applies to: all components
|
|
20
|
+
*/
|
|
21
|
+
let ReactComponentNamingRule = class ReactComponentNamingRule extends BaseLintRule {
|
|
22
|
+
get Name() { return 'react-component-naming'; }
|
|
23
|
+
get AppliesTo() { return 'all'; }
|
|
24
|
+
Test(ast, componentName) {
|
|
25
|
+
const violations = [];
|
|
26
|
+
traverse(ast, {
|
|
27
|
+
FunctionDeclaration(path) {
|
|
28
|
+
if (path.node.id && path.node.id.name === componentName) {
|
|
29
|
+
// Check if it's the main component function
|
|
30
|
+
const funcName = path.node.id.name;
|
|
31
|
+
// Check if function has component-like parameters (props structure)
|
|
32
|
+
const firstParam = path.node.params[0];
|
|
33
|
+
const hasComponentProps = firstParam && (t.isObjectPattern(firstParam) || t.isIdentifier(firstParam));
|
|
34
|
+
if (hasComponentProps && funcName[0] !== funcName[0].toUpperCase()) {
|
|
35
|
+
violations.push(createViolation('react-component-naming', 'critical', path.node.id, `React component "${funcName}" must start with uppercase. JSX treats lowercase as HTML elements.`, `function ${funcName[0].toUpperCase()}${funcName.slice(1)}`));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// Also check for any other component-like functions
|
|
39
|
+
if (path.node.id && path.node.params[0]) {
|
|
40
|
+
const funcName = path.node.id.name;
|
|
41
|
+
const firstParam = path.node.params[0];
|
|
42
|
+
// Check if it looks like a component (has props parameter and returns JSX)
|
|
43
|
+
let returnsJSX = false;
|
|
44
|
+
path.traverse({
|
|
45
|
+
ReturnStatement(returnPath) {
|
|
46
|
+
if (returnPath.node.argument && t.isJSXElement(returnPath.node.argument)) {
|
|
47
|
+
returnsJSX = true;
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
if (returnsJSX && t.isObjectPattern(firstParam)) {
|
|
52
|
+
// Check if any props match component prop pattern
|
|
53
|
+
const propNames = firstParam.properties
|
|
54
|
+
.filter((p) => t.isObjectProperty(p))
|
|
55
|
+
.filter((p) => t.isIdentifier(p.key))
|
|
56
|
+
.map((p) => p.key.name);
|
|
57
|
+
const hasComponentLikeProps = propNames.some((name) => ['utilities', 'styles', 'components', 'callbacks', 'savedUserSettings', 'onSaveUserSettings'].includes(name));
|
|
58
|
+
if (hasComponentLikeProps && funcName[0] !== funcName[0].toUpperCase()) {
|
|
59
|
+
violations.push(createViolation('react-component-naming', 'critical', path.node.id, `Function "${funcName}" appears to be a React component and must start with uppercase.`, `function ${funcName[0].toUpperCase()}${funcName.slice(1)}`));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
return violations;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
ReactComponentNamingRule = __decorate([
|
|
69
|
+
RegisterClass(BaseLintRule, 'react-component-naming')
|
|
70
|
+
], ReactComponentNamingRule);
|
|
71
|
+
export { ReactComponentNamingRule };
|
|
72
|
+
//# sourceMappingURL=react-component-naming.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react-component-naming.js","sourceRoot":"","sources":["../../src/runtime-rules/react-component-naming.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import * as t from '@babel/types';
|
|
2
|
+
import { BaseLintRule } from '../lint-rule.js';
|
|
3
|
+
import { Violation } from '../component-linter.js';
|
|
4
|
+
/**
|
|
5
|
+
* Rule: react-hooks-rules
|
|
6
|
+
*
|
|
7
|
+
* Enforces the Rules of Hooks:
|
|
8
|
+
* 1. Only call hooks at the top level (not inside loops, conditions, or nested functions)
|
|
9
|
+
* 2. Only call hooks from React functions (components or custom hooks)
|
|
10
|
+
* 3. Hooks must be called in the same order on every render
|
|
11
|
+
*
|
|
12
|
+
* Detects:
|
|
13
|
+
* - Hooks called inside non-component/non-hook functions
|
|
14
|
+
* - Hooks called conditionally (if statements, ternary, logical expressions)
|
|
15
|
+
* - Hooks called inside loops
|
|
16
|
+
* - Hooks called inside try/catch blocks (high severity warning)
|
|
17
|
+
* - Hooks called after conditional early returns
|
|
18
|
+
*
|
|
19
|
+
* Severity: critical (most violations), high (try/catch blocks)
|
|
20
|
+
* Applies to: all components
|
|
21
|
+
*/
|
|
22
|
+
export declare class ReactHooksRulesRule extends BaseLintRule {
|
|
23
|
+
get Name(): string;
|
|
24
|
+
get AppliesTo(): 'all' | 'child' | 'root';
|
|
25
|
+
Test(ast: t.File, componentName: string): Violation[];
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=react-hooks-rules.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react-hooks-rules.d.ts","sourceRoot":"","sources":["../../src/runtime-rules/react-hooks-rules.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAgChD;;;;;;;;;;;;;;;;;GAiBG;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,aAAa,EAAE,MAAM,GAAG,SAAS,EAAE;CAqLtD"}
|
|
@@ -0,0 +1,223 @@
|
|
|
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 { RegisterClass } from '@memberjunction/global';
|
|
9
|
+
import * as t from '@babel/types';
|
|
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: react-hooks-rules
|
|
38
|
+
*
|
|
39
|
+
* Enforces the Rules of Hooks:
|
|
40
|
+
* 1. Only call hooks at the top level (not inside loops, conditions, or nested functions)
|
|
41
|
+
* 2. Only call hooks from React functions (components or custom hooks)
|
|
42
|
+
* 3. Hooks must be called in the same order on every render
|
|
43
|
+
*
|
|
44
|
+
* Detects:
|
|
45
|
+
* - Hooks called inside non-component/non-hook functions
|
|
46
|
+
* - Hooks called conditionally (if statements, ternary, logical expressions)
|
|
47
|
+
* - Hooks called inside loops
|
|
48
|
+
* - Hooks called inside try/catch blocks (high severity warning)
|
|
49
|
+
* - Hooks called after conditional early returns
|
|
50
|
+
*
|
|
51
|
+
* Severity: critical (most violations), high (try/catch blocks)
|
|
52
|
+
* Applies to: all components
|
|
53
|
+
*/
|
|
54
|
+
let ReactHooksRulesRule = class ReactHooksRulesRule extends BaseLintRule {
|
|
55
|
+
get Name() { return 'react-hooks-rules'; }
|
|
56
|
+
get AppliesTo() { return 'all'; }
|
|
57
|
+
Test(ast, componentName) {
|
|
58
|
+
const violations = [];
|
|
59
|
+
const hooks = ['useState', 'useEffect', 'useMemo', 'useCallback', 'useRef', 'useContext', 'useReducer', 'useLayoutEffect'];
|
|
60
|
+
traverse(ast, {
|
|
61
|
+
CallExpression(path) {
|
|
62
|
+
if (t.isIdentifier(path.node.callee) && hooks.includes(path.node.callee.name)) {
|
|
63
|
+
const hookName = path.node.callee.name;
|
|
64
|
+
// Rule 1: Check if hook is inside the main component function or custom hook
|
|
65
|
+
let funcParent = path.getFunctionParent();
|
|
66
|
+
if (funcParent) {
|
|
67
|
+
const funcName = getFunctionName(funcParent);
|
|
68
|
+
// Violation: Hook not in component or custom hook
|
|
69
|
+
if (funcName && funcName !== componentName && !funcName.startsWith('use')) {
|
|
70
|
+
violations.push({
|
|
71
|
+
rule: 'react-hooks-rules',
|
|
72
|
+
severity: 'critical',
|
|
73
|
+
line: path.node.loc?.start.line || 0,
|
|
74
|
+
column: path.node.loc?.start.column || 0,
|
|
75
|
+
message: `React Hook "${hookName}" cannot be called inside function "${funcName}". Hooks can only be called at the top level of React components or custom hooks.`,
|
|
76
|
+
code: path.toString().substring(0, 100),
|
|
77
|
+
});
|
|
78
|
+
return; // Skip further checks for this hook
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// Rule 2: Check if hook is inside a conditional (if statement)
|
|
82
|
+
let parent = path.parentPath;
|
|
83
|
+
while (parent) {
|
|
84
|
+
// Check if we've reached the component function - stop looking
|
|
85
|
+
if (t.isFunctionDeclaration(parent.node) || t.isFunctionExpression(parent.node) || t.isArrowFunctionExpression(parent.node)) {
|
|
86
|
+
const parentFuncName = getFunctionName(parent);
|
|
87
|
+
if (parentFuncName === componentName || parentFuncName?.startsWith('use')) {
|
|
88
|
+
break; // We've reached the component/hook boundary
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// Check for conditional statements
|
|
92
|
+
if (t.isIfStatement(parent.node)) {
|
|
93
|
+
violations.push({
|
|
94
|
+
rule: 'react-hooks-rules',
|
|
95
|
+
severity: 'critical',
|
|
96
|
+
line: path.node.loc?.start.line || 0,
|
|
97
|
+
column: path.node.loc?.start.column || 0,
|
|
98
|
+
message: `React Hook "${hookName}" is called conditionally. Hooks must be called in the exact same order in every component render.`,
|
|
99
|
+
code: path.toString().substring(0, 100),
|
|
100
|
+
});
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
// Check for ternary expressions
|
|
104
|
+
if (t.isConditionalExpression(parent.node)) {
|
|
105
|
+
violations.push({
|
|
106
|
+
rule: 'react-hooks-rules',
|
|
107
|
+
severity: 'critical',
|
|
108
|
+
line: path.node.loc?.start.line || 0,
|
|
109
|
+
column: path.node.loc?.start.column || 0,
|
|
110
|
+
message: `React Hook "${hookName}" is called conditionally in a ternary expression. Hooks must be called unconditionally.`,
|
|
111
|
+
code: path.toString().substring(0, 100),
|
|
112
|
+
});
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
// Check for logical expressions (&&, ||)
|
|
116
|
+
if (t.isLogicalExpression(parent.node)) {
|
|
117
|
+
violations.push({
|
|
118
|
+
rule: 'react-hooks-rules',
|
|
119
|
+
severity: 'critical',
|
|
120
|
+
line: path.node.loc?.start.line || 0,
|
|
121
|
+
column: path.node.loc?.start.column || 0,
|
|
122
|
+
message: `React Hook "${hookName}" is called conditionally in a logical expression. Hooks must be called unconditionally.`,
|
|
123
|
+
code: path.toString().substring(0, 100),
|
|
124
|
+
});
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
// Check for switch statements
|
|
128
|
+
if (t.isSwitchStatement(parent.node) || t.isSwitchCase(parent.node)) {
|
|
129
|
+
violations.push({
|
|
130
|
+
rule: 'react-hooks-rules',
|
|
131
|
+
severity: 'critical',
|
|
132
|
+
line: path.node.loc?.start.line || 0,
|
|
133
|
+
column: path.node.loc?.start.column || 0,
|
|
134
|
+
message: `React Hook "${hookName}" is called inside a switch statement. Hooks must be called at the top level.`,
|
|
135
|
+
code: path.toString().substring(0, 100),
|
|
136
|
+
});
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
// Rule 3: Check for loops
|
|
140
|
+
if (t.isForStatement(parent.node) ||
|
|
141
|
+
t.isForInStatement(parent.node) ||
|
|
142
|
+
t.isForOfStatement(parent.node) ||
|
|
143
|
+
t.isWhileStatement(parent.node) ||
|
|
144
|
+
t.isDoWhileStatement(parent.node)) {
|
|
145
|
+
violations.push({
|
|
146
|
+
rule: 'react-hooks-rules',
|
|
147
|
+
severity: 'critical',
|
|
148
|
+
line: path.node.loc?.start.line || 0,
|
|
149
|
+
column: path.node.loc?.start.column || 0,
|
|
150
|
+
message: `React Hook "${hookName}" may not be called inside a loop. This can lead to hooks being called in different order between renders.`,
|
|
151
|
+
code: path.toString().substring(0, 100),
|
|
152
|
+
});
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
// Rule 4: Check for try/catch blocks
|
|
156
|
+
if (t.isTryStatement(parent.node) || t.isCatchClause(parent.node)) {
|
|
157
|
+
violations.push({
|
|
158
|
+
rule: 'react-hooks-rules',
|
|
159
|
+
severity: 'high', // Less severe as it might be intentional
|
|
160
|
+
line: path.node.loc?.start.line || 0,
|
|
161
|
+
column: path.node.loc?.start.column || 0,
|
|
162
|
+
message: `React Hook "${hookName}" is called inside a try/catch block. While not strictly forbidden, this can lead to issues if the hook throws.`,
|
|
163
|
+
code: path.toString().substring(0, 100),
|
|
164
|
+
});
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
// Rule 5: Check for early returns before this hook
|
|
168
|
+
// This is complex and would need to track control flow, so we'll do a simpler check
|
|
169
|
+
if (t.isBlockStatement(parent.node)) {
|
|
170
|
+
const statements = parent.node.body;
|
|
171
|
+
// Find the statement that contains this hook by walking up the path
|
|
172
|
+
let statementNode = path.parentPath;
|
|
173
|
+
while (statementNode && !statements.includes(statementNode.node)) {
|
|
174
|
+
statementNode = statementNode.parentPath;
|
|
175
|
+
}
|
|
176
|
+
if (statementNode) {
|
|
177
|
+
const hookIndex = statements.indexOf(statementNode.node);
|
|
178
|
+
// Check if there's a return statement before this hook
|
|
179
|
+
for (let i = 0; i < hookIndex; i++) {
|
|
180
|
+
const stmt = statements[i];
|
|
181
|
+
if (t.isReturnStatement(stmt)) {
|
|
182
|
+
violations.push({
|
|
183
|
+
rule: 'react-hooks-rules',
|
|
184
|
+
severity: 'critical',
|
|
185
|
+
line: path.node.loc?.start.line || 0,
|
|
186
|
+
column: path.node.loc?.start.column || 0,
|
|
187
|
+
message: `React Hook "${hookName}" is called after a conditional early return. All hooks must be called before any conditional returns.`,
|
|
188
|
+
code: path.toString().substring(0, 100),
|
|
189
|
+
});
|
|
190
|
+
break;
|
|
191
|
+
}
|
|
192
|
+
// Check for conditional returns
|
|
193
|
+
// NOTE: This check is too aggressive and produces false positives
|
|
194
|
+
// It triggers when ANY if statement exists before hooks, even if the early return
|
|
195
|
+
// is in the render section (after hooks) or in nested callbacks
|
|
196
|
+
// TODO: Improve this to only catch actual violations where hooks come after conditional returns
|
|
197
|
+
// if (t.isIfStatement(stmt) && ComponentLinter.containsReturn(stmt)) {
|
|
198
|
+
// violations.push({
|
|
199
|
+
// rule: 'react-hooks-rules',
|
|
200
|
+
// severity: 'critical',
|
|
201
|
+
// line: path.node.loc?.start.line || 0,
|
|
202
|
+
// column: path.node.loc?.start.column || 0,
|
|
203
|
+
// message: `React Hook "${hookName}" is called after a possible early return. Move this hook before any conditional logic.`,
|
|
204
|
+
// code: path.toString().substring(0, 100),
|
|
205
|
+
// });
|
|
206
|
+
// break;
|
|
207
|
+
// }
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
parent = parent.parentPath;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
},
|
|
215
|
+
});
|
|
216
|
+
return violations;
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
ReactHooksRulesRule = __decorate([
|
|
220
|
+
RegisterClass(BaseLintRule, 'react-hooks-rules')
|
|
221
|
+
], ReactHooksRulesRule);
|
|
222
|
+
export { ReactHooksRulesRule };
|
|
223
|
+
//# sourceMappingURL=react-hooks-rules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react-hooks-rules.js","sourceRoot":"","sources":["../../src/runtime-rules/react-hooks-rules.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: required-queries-not-called
|
|
7
|
+
*
|
|
8
|
+
* Ensures that components with dataRequirements in 'queries' or 'hybrid' mode
|
|
9
|
+
* actually call RunQuery for queries that are not delegated to child components.
|
|
10
|
+
*
|
|
11
|
+
* Severity: critical
|
|
12
|
+
* Applies to: root components only
|
|
13
|
+
*/
|
|
14
|
+
export declare class RequiredQueriesNotCalledRule 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=required-queries-not-called.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"required-queries-not-called.d.ts","sourceRoot":"","sources":["../../src/runtime-rules/required-queries-not-called.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAE5E;;;;;;;;GAQG;AACH,qBACa,4BAA6B,SAAQ,YAAY;IAC5D,IAAI,IAAI,WAA4C;IACpD,IAAI,SAAS,IAAI,KAAK,GAAG,OAAO,GAAG,MAAM,CAAmB;IAE5D,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,aAAa,GAAG,SAAS,EAAE;CAuIrF"}
|
|
@@ -0,0 +1,146 @@
|
|
|
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, extractRunQueryNamesFromCode } from '../lint-utils.js';
|
|
8
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
9
|
+
import * as t from '@babel/types';
|
|
10
|
+
import { BaseLintRule } from '../lint-rule.js';
|
|
11
|
+
/**
|
|
12
|
+
* Rule: required-queries-not-called
|
|
13
|
+
*
|
|
14
|
+
* Ensures that components with dataRequirements in 'queries' or 'hybrid' mode
|
|
15
|
+
* actually call RunQuery for queries that are not delegated to child components.
|
|
16
|
+
*
|
|
17
|
+
* Severity: critical
|
|
18
|
+
* Applies to: root components only
|
|
19
|
+
*/
|
|
20
|
+
let RequiredQueriesNotCalledRule = class RequiredQueriesNotCalledRule extends BaseLintRule {
|
|
21
|
+
get Name() { return 'required-queries-not-called'; }
|
|
22
|
+
get AppliesTo() { return 'root'; }
|
|
23
|
+
Test(ast, componentName, componentSpec) {
|
|
24
|
+
const violations = [];
|
|
25
|
+
// Check the mode - only enforce for 'queries' or 'hybrid' mode
|
|
26
|
+
const mode = componentSpec?.dataRequirements?.mode;
|
|
27
|
+
if (mode !== 'queries' && mode !== 'hybrid') {
|
|
28
|
+
// Mode is not 'queries' or 'hybrid', so this rule doesn't apply
|
|
29
|
+
return violations;
|
|
30
|
+
}
|
|
31
|
+
// Check if there are any queries defined in dataRequirements
|
|
32
|
+
const hasQueries = componentSpec?.dataRequirements?.queries && componentSpec.dataRequirements.queries.length > 0;
|
|
33
|
+
if (!hasQueries) {
|
|
34
|
+
// No queries defined, so no violation
|
|
35
|
+
return violations;
|
|
36
|
+
}
|
|
37
|
+
const allQueryNames = componentSpec.dataRequirements.queries.map((q) => q.name).filter(Boolean);
|
|
38
|
+
// In hierarchical components, the root's dataRequirements contains the complete
|
|
39
|
+
// set of queries for the entire tree, but child components can own subsets and
|
|
40
|
+
// call RunQuery themselves. Collect query names claimed by child dependencies
|
|
41
|
+
// via two methods:
|
|
42
|
+
// 1. Child spec has dataRequirements.queries (explicit delegation)
|
|
43
|
+
// 2. Child spec has code that contains RunQuery + the query name (implicit delegation)
|
|
44
|
+
const childClaimedQueries = new Set();
|
|
45
|
+
if (componentSpec.dependencies) {
|
|
46
|
+
for (const dep of componentSpec.dependencies) {
|
|
47
|
+
// Method 1: Explicit dataRequirements on child
|
|
48
|
+
if (dep.dataRequirements?.queries) {
|
|
49
|
+
for (const q of dep.dataRequirements.queries) {
|
|
50
|
+
if (q.name) {
|
|
51
|
+
childClaimedQueries.add(q.name);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// Method 2: Parse child code AST and extract actual RunQuery QueryName values
|
|
56
|
+
if (dep.code) {
|
|
57
|
+
for (const name of extractRunQueryNamesFromCode(dep.code)) {
|
|
58
|
+
childClaimedQueries.add(name);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// Recurse into nested dependencies (grandchildren)
|
|
62
|
+
if (dep.dependencies) {
|
|
63
|
+
for (const grandchild of dep.dependencies) {
|
|
64
|
+
if (grandchild.dataRequirements?.queries) {
|
|
65
|
+
for (const q of grandchild.dataRequirements.queries) {
|
|
66
|
+
if (q.name)
|
|
67
|
+
childClaimedQueries.add(q.name);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (grandchild.code) {
|
|
71
|
+
for (const name of extractRunQueryNamesFromCode(grandchild.code)) {
|
|
72
|
+
childClaimedQueries.add(name);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
const unclaimedQueryNames = allQueryNames.filter((name) => !childClaimedQueries.has(name));
|
|
80
|
+
// If all queries are delegated to child components, no violation for the root
|
|
81
|
+
if (unclaimedQueryNames.length === 0) {
|
|
82
|
+
return violations;
|
|
83
|
+
}
|
|
84
|
+
// Track whether RunQuery is called anywhere in the root component's code
|
|
85
|
+
let hasRunQueryCall = false;
|
|
86
|
+
traverse(ast, {
|
|
87
|
+
CallExpression(path) {
|
|
88
|
+
// Check for utilities.rq.RunQuery pattern
|
|
89
|
+
if (t.isMemberExpression(path.node.callee) &&
|
|
90
|
+
t.isMemberExpression(path.node.callee.object) &&
|
|
91
|
+
t.isIdentifier(path.node.callee.object.object) &&
|
|
92
|
+
path.node.callee.object.object.name === 'utilities' &&
|
|
93
|
+
t.isIdentifier(path.node.callee.object.property) &&
|
|
94
|
+
path.node.callee.object.property.name === 'rq' &&
|
|
95
|
+
t.isIdentifier(path.node.callee.property) &&
|
|
96
|
+
path.node.callee.property.name === 'RunQuery') {
|
|
97
|
+
hasRunQueryCall = true;
|
|
98
|
+
}
|
|
99
|
+
// Also check for destructured pattern: rq.RunQuery
|
|
100
|
+
if (t.isMemberExpression(path.node.callee) &&
|
|
101
|
+
t.isIdentifier(path.node.callee.object) &&
|
|
102
|
+
path.node.callee.object.name === 'rq' &&
|
|
103
|
+
t.isIdentifier(path.node.callee.property) &&
|
|
104
|
+
path.node.callee.property.name === 'RunQuery') {
|
|
105
|
+
hasRunQueryCall = true;
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
// If unclaimed queries exist but RunQuery is never called, that's a critical violation
|
|
110
|
+
if (!hasRunQueryCall) {
|
|
111
|
+
violations.push({
|
|
112
|
+
rule: 'required-queries-not-called',
|
|
113
|
+
severity: 'critical',
|
|
114
|
+
line: 1,
|
|
115
|
+
column: 0,
|
|
116
|
+
message: `Component has ${unclaimedQueryNames.length} defined ${unclaimedQueryNames.length === 1 ? 'query' : 'queries'} in dataRequirements (mode: '${mode}') but never calls RunQuery. Queries defined: ${unclaimedQueryNames.join(', ')}`,
|
|
117
|
+
suggestion: {
|
|
118
|
+
text: `When dataRequirements.mode is '${mode}' and includes queries, you must use utilities.rq.RunQuery to execute them, not RunView.`,
|
|
119
|
+
example: `// Your dataRequirements defines these queries: ${unclaimedQueryNames.join(', ')}
|
|
120
|
+
// Mode is set to: '${mode}'
|
|
121
|
+
|
|
122
|
+
// ❌ WRONG - Using RunView for a query:
|
|
123
|
+
const result = await utilities.rv.RunView({
|
|
124
|
+
EntityName: '${unclaimedQueryNames[0] || 'QueryName'}'
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
// ✅ CORRECT - Using RunQuery for queries:
|
|
128
|
+
const result = await utilities.rq.RunQuery({
|
|
129
|
+
QueryName: '${unclaimedQueryNames[0] || 'QueryName'}'
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
// Key differences:
|
|
133
|
+
// - RunView: For entity-based data access (uses EntityName)
|
|
134
|
+
// - RunQuery: For pre-defined queries (uses QueryName)
|
|
135
|
+
// - dataRequirements.mode: '${mode}' requires RunQuery for queries`,
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
return violations;
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
RequiredQueriesNotCalledRule = __decorate([
|
|
143
|
+
RegisterClass(BaseLintRule, 'required-queries-not-called')
|
|
144
|
+
], RequiredQueriesNotCalledRule);
|
|
145
|
+
export { RequiredQueriesNotCalledRule };
|
|
146
|
+
//# sourceMappingURL=required-queries-not-called.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"required-queries-not-called.js","sourceRoot":"","sources":["../../src/runtime-rules/required-queries-not-called.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
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
|
+
import { TypeContext } from '../type-context.js';
|
|
6
|
+
export declare class RunQueryCallValidationRule extends BaseLintRule {
|
|
7
|
+
get Name(): string;
|
|
8
|
+
get AppliesTo(): 'all' | 'child' | 'root';
|
|
9
|
+
Test(ast: t.File, _componentName: string, componentSpec?: ComponentSpec, _options?: unknown, typeContext?: TypeContext): Violation[];
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=runquery-call-validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runquery-call-validation.d.ts","sourceRoot":"","sources":["../../src/runtime-rules/runquery-call-validation.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,aAAa,EAA+D,MAAM,6CAA6C,CAAC;AACzI,OAAO,EAAsB,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAwvBlE,qBACa,0BAA2B,SAAQ,YAAY;IAC1D,IAAI,IAAI,WAAyC;IACjD,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,EAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,WAAW,CAAC,EAAE,WAAW,GAAG,SAAS,EAAE;CA6MrI"}
|