@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,277 @@
|
|
|
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
|
+
import { ControlFlowAnalyzer } from '../control-flow-analyzer.js';
|
|
12
|
+
import { TypeInferenceEngine } from '../type-inference-engine.js';
|
|
13
|
+
/**
|
|
14
|
+
* Rule: unsafe-formatting-methods
|
|
15
|
+
*
|
|
16
|
+
* Detects formatting methods (toFixed, toLowerCase, etc.) called on potentially null/undefined
|
|
17
|
+
* values without optional chaining or null checks. Uses control flow analysis and type inference
|
|
18
|
+
* to reduce false positives.
|
|
19
|
+
*
|
|
20
|
+
* Closure dependencies: ControlFlowAnalyzer, TypeInferenceEngine, LinterOptions,
|
|
21
|
+
* EntityInfo, EntityFieldInfo (all instantiated locally within the rule)
|
|
22
|
+
*
|
|
23
|
+
* Severity: medium-high (depends on entity metadata nullability)
|
|
24
|
+
* Applies to: all components
|
|
25
|
+
*/
|
|
26
|
+
let UnsafeFormattingMethodsRule = class UnsafeFormattingMethodsRule extends BaseLintRule {
|
|
27
|
+
get Name() { return 'unsafe-formatting-methods'; }
|
|
28
|
+
get AppliesTo() { return 'all'; }
|
|
29
|
+
Test(ast, componentName, componentSpec, options) {
|
|
30
|
+
const violations = [];
|
|
31
|
+
// Standard props that are always defined (passed by runtime to all components)
|
|
32
|
+
const standardProps = new Set(['utilities', 'styles', 'components', 'callbacks', 'savedUserSettings', 'onSaveUserSettings']);
|
|
33
|
+
// Create control flow analyzer for guard detection
|
|
34
|
+
const cfa = new ControlFlowAnalyzer(ast, componentSpec);
|
|
35
|
+
// Create type inference engine for property safety checking
|
|
36
|
+
const typeInferenceEngine = new TypeInferenceEngine(componentSpec);
|
|
37
|
+
// Run analysis synchronously (the async part is not needed for basic inference)
|
|
38
|
+
typeInferenceEngine.analyze(ast);
|
|
39
|
+
const typeContext = typeInferenceEngine.getTypeContext();
|
|
40
|
+
/**
|
|
41
|
+
* Check if an object property is safe to access based on type inference.
|
|
42
|
+
* Returns true if the object is locally defined with known structure and the property exists.
|
|
43
|
+
*
|
|
44
|
+
* Example: const metrics = { winRate: 75.5 }; metrics.winRate.toFixed() is safe
|
|
45
|
+
*/
|
|
46
|
+
const isKnownObjectProperty = (objectName, propertyName) => {
|
|
47
|
+
const varType = typeContext.getVariableType(objectName);
|
|
48
|
+
if (!varType) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
// Check if it's an object type with known fields
|
|
52
|
+
if (varType.type === 'object' && varType.fields) {
|
|
53
|
+
const fieldInfo = varType.fields.get(propertyName);
|
|
54
|
+
// Property exists in the object definition and is non-null
|
|
55
|
+
return fieldInfo !== undefined && !fieldInfo.nullable;
|
|
56
|
+
}
|
|
57
|
+
return false;
|
|
58
|
+
};
|
|
59
|
+
// Common formatting methods that can fail on null/undefined
|
|
60
|
+
const formattingMethods = new Set([
|
|
61
|
+
// Number methods
|
|
62
|
+
'toFixed',
|
|
63
|
+
'toPrecision',
|
|
64
|
+
'toExponential',
|
|
65
|
+
// Conversion methods
|
|
66
|
+
'toLocaleString',
|
|
67
|
+
'toString',
|
|
68
|
+
// String methods
|
|
69
|
+
'toLowerCase',
|
|
70
|
+
'toUpperCase',
|
|
71
|
+
'trim',
|
|
72
|
+
'split',
|
|
73
|
+
'slice',
|
|
74
|
+
'substring',
|
|
75
|
+
'substr',
|
|
76
|
+
'charAt',
|
|
77
|
+
'charCodeAt',
|
|
78
|
+
'indexOf',
|
|
79
|
+
'lastIndexOf',
|
|
80
|
+
'padStart',
|
|
81
|
+
'padEnd',
|
|
82
|
+
'repeat',
|
|
83
|
+
'replace',
|
|
84
|
+
]);
|
|
85
|
+
const checkFieldNullability = (propertyName) => {
|
|
86
|
+
// Step 1: Check if componentSpec has data requirements and utilities are available
|
|
87
|
+
if (!componentSpec?.dataRequirements?.entities || !options?.utilities?.md?.Entities) {
|
|
88
|
+
return { found: false, nullable: false };
|
|
89
|
+
}
|
|
90
|
+
try {
|
|
91
|
+
// Step 2: Iterate through only the entities defined in dataRequirements
|
|
92
|
+
for (const dataReqEntity of componentSpec.dataRequirements.entities) {
|
|
93
|
+
const entityName = dataReqEntity.name; // e.g., "AI Prompt Runs"
|
|
94
|
+
// Step 3: Find this entity in the full metadata (case insensitive)
|
|
95
|
+
// Use proper typing - we know Entities is an array of EntityInfo objects
|
|
96
|
+
const fullEntity = options.utilities.md?.Entities.find((e) => e.Name && e.Name.toLowerCase() === entityName.toLowerCase());
|
|
97
|
+
if (fullEntity && fullEntity.Fields && Array.isArray(fullEntity.Fields)) {
|
|
98
|
+
// Step 4: Look for the field in this specific entity (case insensitive)
|
|
99
|
+
const field = fullEntity.Fields.find((f) => f.Name && f.Name.trim().toLowerCase() === propertyName.trim().toLowerCase());
|
|
100
|
+
if (field) {
|
|
101
|
+
// Field found - check if it's nullable
|
|
102
|
+
// In MJ, AllowsNull is a boolean property
|
|
103
|
+
return {
|
|
104
|
+
found: true,
|
|
105
|
+
nullable: field.AllowsNull,
|
|
106
|
+
entityName: fullEntity.Name,
|
|
107
|
+
fieldName: field.Name,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
// If there's any error accessing metadata, fail gracefully
|
|
115
|
+
console.warn('Error checking field nullability:', error);
|
|
116
|
+
}
|
|
117
|
+
return { found: false, nullable: false };
|
|
118
|
+
};
|
|
119
|
+
traverse(ast, {
|
|
120
|
+
// Check JSX expressions
|
|
121
|
+
JSXExpressionContainer(path) {
|
|
122
|
+
const expr = path.node.expression;
|
|
123
|
+
// Look for object.property.method() pattern
|
|
124
|
+
if (t.isCallExpression(expr) && t.isMemberExpression(expr.callee) && t.isIdentifier(expr.callee.property)) {
|
|
125
|
+
const methodName = expr.callee.property.name;
|
|
126
|
+
// Check if it's a formatting method
|
|
127
|
+
if (formattingMethods.has(methodName)) {
|
|
128
|
+
const callee = expr.callee;
|
|
129
|
+
// Check if the object being called on is also a member expression (x.y pattern)
|
|
130
|
+
if (t.isMemberExpression(callee.object) && t.isIdentifier(callee.object.property)) {
|
|
131
|
+
const propertyName = callee.object.property.name;
|
|
132
|
+
// Check if optional chaining is already used
|
|
133
|
+
const hasOptionalChaining = callee.object.optional || callee.optional;
|
|
134
|
+
// Check if there's a fallback (looking in parent for || or ??)
|
|
135
|
+
let hasFallback = false;
|
|
136
|
+
const parent = path.parent;
|
|
137
|
+
const grandParent = path.parentPath?.parent;
|
|
138
|
+
// Check if parent is a logical expression with fallback
|
|
139
|
+
if (grandParent && t.isLogicalExpression(grandParent) && (grandParent.operator === '||' || grandParent.operator === '??')) {
|
|
140
|
+
hasFallback = true;
|
|
141
|
+
}
|
|
142
|
+
// Also check conditional expressions
|
|
143
|
+
if (grandParent && t.isConditionalExpression(grandParent)) {
|
|
144
|
+
hasFallback = true;
|
|
145
|
+
}
|
|
146
|
+
// Check if inside a null/undefined check using Control Flow Analyzer
|
|
147
|
+
const hasNullCheck = cfa.isDefinitelyNonNull(callee.object, path);
|
|
148
|
+
// Skip if accessing properties on standard props (guaranteed to be defined)
|
|
149
|
+
// Pattern: styles.borders.radius is ALWAYS safe (styles is always provided)
|
|
150
|
+
let isStandardProp = false;
|
|
151
|
+
if (t.isIdentifier(callee.object.object)) {
|
|
152
|
+
const objectName = callee.object.object.name;
|
|
153
|
+
if (standardProps.has(objectName)) {
|
|
154
|
+
isStandardProp = true;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// Skip if the object property is known to be safe via type inference
|
|
158
|
+
// Pattern: const metrics = { winRate: 75.5 }; metrics.winRate.toFixed() is safe
|
|
159
|
+
// This uses TypeInferenceEngine to track object literal assignments
|
|
160
|
+
let isKnownObjectProperty_flag = false;
|
|
161
|
+
if (t.isIdentifier(callee.object.object)) {
|
|
162
|
+
const objectName = callee.object.object.name;
|
|
163
|
+
isKnownObjectProperty_flag = isKnownObjectProperty(objectName, propertyName);
|
|
164
|
+
}
|
|
165
|
+
if (!hasOptionalChaining && !hasFallback && !hasNullCheck && !isStandardProp && !isKnownObjectProperty_flag) {
|
|
166
|
+
// Check entity metadata for this field
|
|
167
|
+
const fieldInfo = checkFieldNullability(propertyName);
|
|
168
|
+
// Determine severity based on metadata
|
|
169
|
+
let severity = 'medium';
|
|
170
|
+
let message = `Unsafe formatting method '${methodName}()' called on '${propertyName}'. Consider using optional chaining.`;
|
|
171
|
+
if (fieldInfo.found) {
|
|
172
|
+
if (fieldInfo.nullable) {
|
|
173
|
+
severity = 'high';
|
|
174
|
+
message = `Field '${fieldInfo.fieldName}' from entity '${fieldInfo.entityName}' is nullable. Use optional chaining to prevent runtime errors when calling '${methodName}()'.`;
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
// Keep medium severity but note it's non-nullable
|
|
178
|
+
message = `Field '${fieldInfo.fieldName}' from entity '${fieldInfo.entityName}' appears to be non-nullable, but consider using optional chaining for safety when calling '${methodName}()'.`;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
// Get the object name for better error message
|
|
182
|
+
let objectName = '';
|
|
183
|
+
if (t.isIdentifier(callee.object.object)) {
|
|
184
|
+
objectName = callee.object.object.name;
|
|
185
|
+
}
|
|
186
|
+
violations.push({
|
|
187
|
+
rule: 'unsafe-formatting-methods',
|
|
188
|
+
severity: severity,
|
|
189
|
+
line: expr.loc?.start.line || 0,
|
|
190
|
+
column: expr.loc?.start.column || 0,
|
|
191
|
+
message: message,
|
|
192
|
+
code: `${objectName}.${propertyName}.${methodName}() → ${objectName}.${propertyName}?.${methodName}() ?? defaultValue`,
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
// Also check template literals
|
|
200
|
+
TemplateLiteral(path) {
|
|
201
|
+
for (const expr of path.node.expressions) {
|
|
202
|
+
// Look for object.property.method() pattern in template expressions
|
|
203
|
+
if (t.isCallExpression(expr) && t.isMemberExpression(expr.callee) && t.isIdentifier(expr.callee.property)) {
|
|
204
|
+
const methodName = expr.callee.property.name;
|
|
205
|
+
// Check if it's a formatting method
|
|
206
|
+
if (formattingMethods.has(methodName)) {
|
|
207
|
+
const callee = expr.callee;
|
|
208
|
+
// Check if the object being called on is also a member expression (x.y pattern)
|
|
209
|
+
if (t.isMemberExpression(callee.object) && t.isIdentifier(callee.object.property)) {
|
|
210
|
+
const propertyName = callee.object.property.name;
|
|
211
|
+
// Check if optional chaining is already used
|
|
212
|
+
const hasOptionalChaining = callee.object.optional || callee.optional;
|
|
213
|
+
// Check if inside a null/undefined check using Control Flow Analyzer
|
|
214
|
+
// Note: For template literals, we need to check the template itself since
|
|
215
|
+
// the expression doesn't have its own NodePath
|
|
216
|
+
const hasNullCheck = cfa.isDefinitelyNonNull(callee.object, path) ||
|
|
217
|
+
cfa.isProtectedByTernary(callee.object, path);
|
|
218
|
+
// Skip if accessing properties on standard props (guaranteed to be defined)
|
|
219
|
+
let isStandardProp = false;
|
|
220
|
+
if (t.isIdentifier(callee.object.object)) {
|
|
221
|
+
const objectName = callee.object.object.name;
|
|
222
|
+
if (standardProps.has(objectName)) {
|
|
223
|
+
isStandardProp = true;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
// Skip if the object property is known to be safe via type inference
|
|
227
|
+
// Pattern: const metrics = { winRate: 75.5 }; metrics.winRate.toFixed() is safe
|
|
228
|
+
// This uses TypeInferenceEngine to track object literal assignments
|
|
229
|
+
let isKnownObjectProperty_flag = false;
|
|
230
|
+
if (t.isIdentifier(callee.object.object)) {
|
|
231
|
+
const objectName = callee.object.object.name;
|
|
232
|
+
isKnownObjectProperty_flag = isKnownObjectProperty(objectName, propertyName);
|
|
233
|
+
}
|
|
234
|
+
if (!hasOptionalChaining && !hasNullCheck && !isStandardProp && !isKnownObjectProperty_flag) {
|
|
235
|
+
// Check entity metadata for this field
|
|
236
|
+
const fieldInfo = checkFieldNullability(propertyName);
|
|
237
|
+
// Determine severity based on metadata
|
|
238
|
+
let severity = 'medium';
|
|
239
|
+
let message = `Unsafe formatting method '${methodName}()' called on '${propertyName}' in template literal. Consider using optional chaining.`;
|
|
240
|
+
if (fieldInfo.found) {
|
|
241
|
+
if (fieldInfo.nullable) {
|
|
242
|
+
severity = 'high';
|
|
243
|
+
message = `Field '${propertyName}' is nullable in entity metadata. Use optional chaining to prevent runtime errors when calling '${methodName}()' in template literal.`;
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
// Keep medium severity but note it's non-nullable
|
|
247
|
+
message = `Field '${propertyName}' appears to be non-nullable, but consider using optional chaining for safety when calling '${methodName}()' in template literal.`;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
// Get the object name for better error message
|
|
251
|
+
let objectName = '';
|
|
252
|
+
if (t.isIdentifier(callee.object.object)) {
|
|
253
|
+
objectName = callee.object.object.name;
|
|
254
|
+
}
|
|
255
|
+
violations.push({
|
|
256
|
+
rule: 'unsafe-formatting-methods',
|
|
257
|
+
severity: severity,
|
|
258
|
+
line: expr.loc?.start.line || 0,
|
|
259
|
+
column: expr.loc?.start.column || 0,
|
|
260
|
+
message: message,
|
|
261
|
+
code: `\${${objectName}.${propertyName}.${methodName}()} → \${${objectName}.${propertyName}?.${methodName}() ?? defaultValue}`,
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
},
|
|
269
|
+
});
|
|
270
|
+
return violations;
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
UnsafeFormattingMethodsRule = __decorate([
|
|
274
|
+
RegisterClass(BaseLintRule, 'unsafe-formatting-methods')
|
|
275
|
+
], UnsafeFormattingMethodsRule);
|
|
276
|
+
export { UnsafeFormattingMethodsRule };
|
|
277
|
+
//# sourceMappingURL=unsafe-formatting-methods.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unsafe-formatting-methods.js","sourceRoot":"","sources":["../../src/runtime-rules/unsafe-formatting-methods.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: unused-component-dependencies
|
|
7
|
+
*
|
|
8
|
+
* Detects declared embedded component dependencies that are not used in the component code.
|
|
9
|
+
* Checks for various usage patterns including JSX, dot notation, and bracket notation.
|
|
10
|
+
*
|
|
11
|
+
* Severity: low
|
|
12
|
+
* Applies to: all components
|
|
13
|
+
*/
|
|
14
|
+
export declare class UnusedComponentDependenciesRule 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=unused-component-dependencies.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unused-component-dependencies.d.ts","sourceRoot":"","sources":["../../src/runtime-rules/unused-component-dependencies.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,+BAAgC,SAAQ,YAAY;IAC/D,IAAI,IAAI,WAA8C;IACtD,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;CA0ErF"}
|
|
@@ -0,0 +1,90 @@
|
|
|
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 { BaseLintRule } from '../lint-rule.js';
|
|
10
|
+
/**
|
|
11
|
+
* Rule: unused-component-dependencies
|
|
12
|
+
*
|
|
13
|
+
* Detects declared embedded component dependencies that are not used in the component code.
|
|
14
|
+
* Checks for various usage patterns including JSX, dot notation, and bracket notation.
|
|
15
|
+
*
|
|
16
|
+
* Severity: low
|
|
17
|
+
* Applies to: all components
|
|
18
|
+
*/
|
|
19
|
+
let UnusedComponentDependenciesRule = class UnusedComponentDependenciesRule extends BaseLintRule {
|
|
20
|
+
get Name() { return 'unused-component-dependencies'; }
|
|
21
|
+
get AppliesTo() { return 'all'; }
|
|
22
|
+
Test(ast, componentName, componentSpec) {
|
|
23
|
+
const violations = [];
|
|
24
|
+
// Skip if no dependencies declared
|
|
25
|
+
if (!componentSpec?.dependencies || componentSpec.dependencies.length === 0) {
|
|
26
|
+
return violations;
|
|
27
|
+
}
|
|
28
|
+
// Filter to only embedded components
|
|
29
|
+
const embeddedDeps = componentSpec.dependencies.filter((dep) => dep.location === 'embedded' && dep.name);
|
|
30
|
+
if (embeddedDeps.length === 0) {
|
|
31
|
+
return violations;
|
|
32
|
+
}
|
|
33
|
+
// Get the function body to search within
|
|
34
|
+
let functionBody = '';
|
|
35
|
+
traverse(ast, {
|
|
36
|
+
FunctionDeclaration(path) {
|
|
37
|
+
if (path.node.id && path.node.id.name === componentName) {
|
|
38
|
+
functionBody = path.toString();
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
// If we couldn't find the function body, use the whole code
|
|
43
|
+
if (!functionBody) {
|
|
44
|
+
functionBody = ast.toString ? ast.toString() : '';
|
|
45
|
+
}
|
|
46
|
+
// Check each component dependency for usage
|
|
47
|
+
for (const dep of embeddedDeps) {
|
|
48
|
+
const depName = dep.name;
|
|
49
|
+
// Check for various usage patterns
|
|
50
|
+
// Components can be used directly (if destructured) or via components object
|
|
51
|
+
const usagePatterns = [
|
|
52
|
+
// Direct usage (after destructuring)
|
|
53
|
+
'<' + depName + ' ', // JSX: <AccountList />
|
|
54
|
+
'<' + depName + '>', // JSX: <AccountList>
|
|
55
|
+
'<' + depName + '/', // JSX self-closing: <AccountList/>
|
|
56
|
+
depName + '(', // Direct call: AccountList()
|
|
57
|
+
'= ' + depName, // Assignment: const List = AccountList
|
|
58
|
+
depName + ' ||', // Fallback: AccountList || DefaultComponent
|
|
59
|
+
depName + ' &&', // Conditional: AccountList && ...
|
|
60
|
+
depName + ' ?', // Ternary: AccountList ? ... : ...
|
|
61
|
+
', ' + depName, // In parameter/array list
|
|
62
|
+
'(' + depName, // Start of expression
|
|
63
|
+
'{' + depName, // In object literal
|
|
64
|
+
// Via components object
|
|
65
|
+
'components.' + depName, // Dot notation: components.AccountList
|
|
66
|
+
"components['" + depName + "']", // Bracket notation single quotes
|
|
67
|
+
'components["' + depName + '"]', // Bracket notation double quotes
|
|
68
|
+
'components[`' + depName + '`]', // Bracket notation template literal
|
|
69
|
+
'<components.' + depName, // JSX via components: <components.AccountList
|
|
70
|
+
];
|
|
71
|
+
const isUsed = usagePatterns.some((pattern) => functionBody.includes(pattern));
|
|
72
|
+
if (!isUsed) {
|
|
73
|
+
violations.push({
|
|
74
|
+
rule: 'unused-component-dependencies',
|
|
75
|
+
severity: 'low',
|
|
76
|
+
line: 1,
|
|
77
|
+
column: 0,
|
|
78
|
+
message: `Component dependency "${depName}" is declared but never used. Consider removing it if not needed.`,
|
|
79
|
+
code: `Expected usage: <${depName} /> or <components.${depName} />`,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return violations;
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
UnusedComponentDependenciesRule = __decorate([
|
|
87
|
+
RegisterClass(BaseLintRule, 'unused-component-dependencies')
|
|
88
|
+
], UnusedComponentDependenciesRule);
|
|
89
|
+
export { UnusedComponentDependenciesRule };
|
|
90
|
+
//# sourceMappingURL=unused-component-dependencies.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unused-component-dependencies.js","sourceRoot":"","sources":["../../src/runtime-rules/unused-component-dependencies.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: unused-libraries
|
|
7
|
+
*
|
|
8
|
+
* Detects declared libraries that are not used in the component code.
|
|
9
|
+
* Libraries declared in the component spec should be referenced in the code.
|
|
10
|
+
*
|
|
11
|
+
* Severity: critical (none used), high/low (some unused)
|
|
12
|
+
* Applies to: all components
|
|
13
|
+
*/
|
|
14
|
+
export declare class UnusedLibrariesRule 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=unused-libraries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unused-libraries.d.ts","sourceRoot":"","sources":["../../src/runtime-rules/unused-libraries.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,mBAAoB,SAAQ,YAAY;IACnD,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;CA+GrF"}
|
|
@@ -0,0 +1,127 @@
|
|
|
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 { BaseLintRule } from '../lint-rule.js';
|
|
10
|
+
/**
|
|
11
|
+
* Rule: unused-libraries
|
|
12
|
+
*
|
|
13
|
+
* Detects declared libraries that are not used in the component code.
|
|
14
|
+
* Libraries declared in the component spec should be referenced in the code.
|
|
15
|
+
*
|
|
16
|
+
* Severity: critical (none used), high/low (some unused)
|
|
17
|
+
* Applies to: all components
|
|
18
|
+
*/
|
|
19
|
+
let UnusedLibrariesRule = class UnusedLibrariesRule extends BaseLintRule {
|
|
20
|
+
get Name() { return 'unused-libraries'; }
|
|
21
|
+
get AppliesTo() { return 'all'; }
|
|
22
|
+
Test(ast, componentName, componentSpec) {
|
|
23
|
+
const violations = [];
|
|
24
|
+
// Skip if no libraries declared
|
|
25
|
+
if (!componentSpec?.libraries || componentSpec.libraries.length === 0) {
|
|
26
|
+
return violations;
|
|
27
|
+
}
|
|
28
|
+
// Get the function body to search within — include root AND child component code
|
|
29
|
+
let functionBody = '';
|
|
30
|
+
traverse(ast, {
|
|
31
|
+
FunctionDeclaration(path) {
|
|
32
|
+
if (path.node.id && path.node.id.name === componentName) {
|
|
33
|
+
functionBody = path.toString();
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
// If we couldn't find the function body, use the whole code
|
|
38
|
+
if (!functionBody) {
|
|
39
|
+
functionBody = ast.toString ? ast.toString() : '';
|
|
40
|
+
}
|
|
41
|
+
// Also include child component code — libraries declared on the root spec
|
|
42
|
+
// may be used by child components in multi-component trees
|
|
43
|
+
if (componentSpec?.dependencies) {
|
|
44
|
+
for (const dep of componentSpec.dependencies) {
|
|
45
|
+
if (dep.code) {
|
|
46
|
+
functionBody += '\n' + dep.code;
|
|
47
|
+
}
|
|
48
|
+
// Include grandchildren too
|
|
49
|
+
if (dep.dependencies) {
|
|
50
|
+
for (const grandchild of dep.dependencies) {
|
|
51
|
+
if (grandchild.code) {
|
|
52
|
+
functionBody += '\n' + grandchild.code;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// Track which libraries are used and unused
|
|
59
|
+
const unusedLibraries = [];
|
|
60
|
+
const usedLibraries = [];
|
|
61
|
+
// Check each library for usage
|
|
62
|
+
for (const lib of componentSpec.libraries) {
|
|
63
|
+
const globalVar = lib.globalVariable;
|
|
64
|
+
if (!globalVar)
|
|
65
|
+
continue;
|
|
66
|
+
// Check for various usage patterns
|
|
67
|
+
const usagePatterns = [
|
|
68
|
+
globalVar + '.', // Direct property access: Chart.defaults
|
|
69
|
+
globalVar + '(', // Direct call: dayjs()
|
|
70
|
+
'new ' + globalVar + '(', // Constructor: new Chart()
|
|
71
|
+
globalVar + '[', // Array/property access: XLSX['utils']
|
|
72
|
+
'= ' + globalVar, // Assignment: const myChart = Chart
|
|
73
|
+
', ' + globalVar, // In parameter list
|
|
74
|
+
'(' + globalVar, // Start of expression
|
|
75
|
+
'{' + globalVar, // In object literal
|
|
76
|
+
'<' + globalVar, // JSX component
|
|
77
|
+
globalVar + ' ', // Followed by space (various uses)
|
|
78
|
+
'unwrapLibraryComponents(' + globalVar, // unwrapLibraryComponents(antd, ...)
|
|
79
|
+
'unwrapLibraryComponents( ' + globalVar, // unwrapLibraryComponents( antd, ...)
|
|
80
|
+
];
|
|
81
|
+
const isUsed = usagePatterns.some((pattern) => functionBody.includes(pattern));
|
|
82
|
+
if (isUsed) {
|
|
83
|
+
usedLibraries.push({ name: lib.name, globalVariable: globalVar });
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
unusedLibraries.push({ name: lib.name, globalVariable: globalVar });
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// Determine severity based on usage patterns
|
|
90
|
+
const totalLibraries = componentSpec.libraries.length;
|
|
91
|
+
const usedCount = usedLibraries.length;
|
|
92
|
+
if (usedCount === 0 && totalLibraries > 0) {
|
|
93
|
+
// CRITICAL: No libraries used at all
|
|
94
|
+
violations.push({
|
|
95
|
+
rule: 'unused-libraries',
|
|
96
|
+
severity: 'critical',
|
|
97
|
+
line: 1,
|
|
98
|
+
column: 0,
|
|
99
|
+
message: `CRITICAL: None of the ${totalLibraries} declared libraries are used. This indicates missing core functionality.`,
|
|
100
|
+
code: `Unused libraries: ${unusedLibraries.map((l) => l.name).join(', ')}`,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
else if (unusedLibraries.length > 0) {
|
|
104
|
+
// Some libraries unused, severity depends on ratio
|
|
105
|
+
for (const lib of unusedLibraries) {
|
|
106
|
+
const severity = totalLibraries === 1 ? 'high' : 'low';
|
|
107
|
+
const contextMessage = totalLibraries === 1
|
|
108
|
+
? "This is the only declared library and it's not being used."
|
|
109
|
+
: `${usedCount} of ${totalLibraries} libraries are being used. This might be an alternative/optional library.`;
|
|
110
|
+
violations.push({
|
|
111
|
+
rule: 'unused-libraries',
|
|
112
|
+
severity: severity,
|
|
113
|
+
line: 1,
|
|
114
|
+
column: 0,
|
|
115
|
+
message: `Library "${lib.name}" (${lib.globalVariable}) is declared but not used. ${contextMessage}`,
|
|
116
|
+
code: `Consider removing if not needed: { name: "${lib.name}", globalVariable: "${lib.globalVariable}" }`,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return violations;
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
UnusedLibrariesRule = __decorate([
|
|
124
|
+
RegisterClass(BaseLintRule, 'unused-libraries')
|
|
125
|
+
], UnusedLibrariesRule);
|
|
126
|
+
export { UnusedLibrariesRule };
|
|
127
|
+
//# sourceMappingURL=unused-libraries.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unused-libraries.js","sourceRoot":"","sources":["../../src/runtime-rules/unused-libraries.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,QAAQ,EAAY,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAI5C;;;;;;;;GAQG;AAEI,IAAM,mBAAmB,GAAzB,MAAM,mBAAoB,SAAQ,YAAY;IACnD,IAAI,IAAI,KAAK,OAAO,kBAAkB,CAAC,CAAC,CAAC;IACzC,IAAI,SAAS,KAA+B,OAAO,KAAK,CAAC,CAAC,CAAC;IAE3D,IAAI,CAAC,GAAW,EAAE,aAAqB,EAAE,aAA6B;QACpE,MAAM,UAAU,GAAgB,EAAE,CAAC;QAEnC,gCAAgC;QAChC,IAAI,CAAC,aAAa,EAAE,SAAS,IAAI,aAAa,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtE,OAAO,UAAU,CAAC;QACpB,CAAC;QAED,iFAAiF;QACjF,IAAI,YAAY,GAAW,EAAE,CAAC;QAC9B,QAAQ,CAAC,GAAG,EAAE;YACZ,mBAAmB,CAAC,IAAqC;gBACvD,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;oBACxD,YAAY,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACjC,CAAC;YACH,CAAC;SACF,CAAC,CAAC;QAEH,4DAA4D;QAC5D,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,YAAY,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACpD,CAAC;QAED,0EAA0E;QAC1E,2DAA2D;QAC3D,IAAI,aAAa,EAAE,YAAY,EAAE,CAAC;YAChC,KAAK,MAAM,GAAG,IAAI,aAAa,CAAC,YAAY,EAAE,CAAC;gBAC7C,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;oBACb,YAAY,IAAI,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;gBAClC,CAAC;gBACD,4BAA4B;gBAC5B,IAAI,GAAG,CAAC,YAAY,EAAE,CAAC;oBACrB,KAAK,MAAM,UAAU,IAAI,GAAG,CAAC,YAAY,EAAE,CAAC;wBAC1C,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC;4BACpB,YAAY,IAAI,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC;wBACzC,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,4CAA4C;QAC5C,MAAM,eAAe,GAAoD,EAAE,CAAC;QAC5E,MAAM,aAAa,GAAoD,EAAE,CAAC;QAE1E,+BAA+B;QAC/B,KAAK,MAAM,GAAG,IAAI,aAAa,CAAC,SAAS,EAAE,CAAC;YAC1C,MAAM,SAAS,GAAG,GAAG,CAAC,cAAc,CAAC;YACrC,IAAI,CAAC,SAAS;gBAAE,SAAS;YAEzB,mCAAmC;YACnC,MAAM,aAAa,GAAG;gBACpB,SAAS,GAAG,GAAG,EAAE,yCAAyC;gBAC1D,SAAS,GAAG,GAAG,EAAE,uBAAuB;gBACxC,MAAM,GAAG,SAAS,GAAG,GAAG,EAAE,2BAA2B;gBACrD,SAAS,GAAG,GAAG,EAAE,uCAAuC;gBACxD,IAAI,GAAG,SAAS,EAAE,oCAAoC;gBACtD,IAAI,GAAG,SAAS,EAAE,oBAAoB;gBACtC,GAAG,GAAG,SAAS,EAAE,sBAAsB;gBACvC,GAAG,GAAG,SAAS,EAAE,oBAAoB;gBACrC,GAAG,GAAG,SAAS,EAAE,gBAAgB;gBACjC,SAAS,GAAG,GAAG,EAAE,mCAAmC;gBACpD,0BAA0B,GAAG,SAAS,EAAE,qCAAqC;gBAC7E,2BAA2B,GAAG,SAAS,EAAE,sCAAsC;aAChF,CAAC;YAEF,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;YAE/E,IAAI,MAAM,EAAE,CAAC;gBACX,aAAa,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,cAAc,EAAE,SAAS,EAAE,CAAC,CAAC;YACpE,CAAC;iBAAM,CAAC;gBACN,eAAe,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,cAAc,EAAE,SAAS,EAAE,CAAC,CAAC;YACtE,CAAC;QACH,CAAC;QAED,6CAA6C;QAC7C,MAAM,cAAc,GAAG,aAAa,CAAC,SAAS,CAAC,MAAM,CAAC;QACtD,MAAM,SAAS,GAAG,aAAa,CAAC,MAAM,CAAC;QAEvC,IAAI,SAAS,KAAK,CAAC,IAAI,cAAc,GAAG,CAAC,EAAE,CAAC;YAC1C,qCAAqC;YACrC,UAAU,CAAC,IAAI,CAAC;gBACd,IAAI,EAAE,kBAAkB;gBACxB,QAAQ,EAAE,UAAU;gBACpB,IAAI,EAAE,CAAC;gBACP,MAAM,EAAE,CAAC;gBACT,OAAO,EAAE,yBAAyB,cAAc,0EAA0E;gBAC1H,IAAI,EAAE,qBAAqB,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;aAC3E,CAAC,CAAC;QACL,CAAC;aAAM,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtC,mDAAmD;YACnD,KAAK,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;gBAClC,MAAM,QAAQ,GAAG,cAAc,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;gBACvD,MAAM,cAAc,GAClB,cAAc,KAAK,CAAC;oBAClB,CAAC,CAAC,4DAA4D;oBAC9D,CAAC,CAAC,GAAG,SAAS,OAAO,cAAc,2EAA2E,CAAC;gBAEnH,UAAU,CAAC,IAAI,CAAC;oBACd,IAAI,EAAE,kBAAkB;oBACxB,QAAQ,EAAE,QAAQ;oBAClB,IAAI,EAAE,CAAC;oBACP,MAAM,EAAE,CAAC;oBACT,OAAO,EAAE,YAAY,GAAG,CAAC,IAAI,MAAM,GAAG,CAAC,cAAc,+BAA+B,cAAc,EAAE;oBACpG,IAAI,EAAE,6CAA6C,GAAG,CAAC,IAAI,uBAAuB,GAAG,CAAC,cAAc,KAAK;iBAC1G,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,UAAU,CAAC;IACpB,CAAC;CACF,CAAA;AAnHY,mBAAmB;IAD/B,aAAa,CAAC,YAAY,EAAE,kBAAkB,CAAC;GACnC,mBAAmB,CAmH/B"}
|
|
@@ -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: use-function-declaration
|
|
6
|
+
*
|
|
7
|
+
* Ensures that components use function declaration syntax instead of
|
|
8
|
+
* arrow functions or function expressions.
|
|
9
|
+
*
|
|
10
|
+
* Severity: critical
|
|
11
|
+
* Applies to: all components
|
|
12
|
+
*/
|
|
13
|
+
export declare class UseFunctionDeclarationRule extends BaseLintRule {
|
|
14
|
+
get Name(): string;
|
|
15
|
+
get AppliesTo(): 'all' | 'child' | 'root';
|
|
16
|
+
Test(ast: t.File, componentName: string): Violation[];
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=use-function-declaration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-function-declaration.d.ts","sourceRoot":"","sources":["../../src/runtime-rules/use-function-declaration.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAGhD;;;;;;;;GAQG;AACH,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,aAAa,EAAE,MAAM,GAAG,SAAS,EAAE;CA2HtD"}
|