@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,107 @@
|
|
|
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: server-reload-on-client-operation
|
|
38
|
+
*
|
|
39
|
+
* Detects when components reload data from the server during sort/filter operations.
|
|
40
|
+
* These operations should be performed client-side using useMemo for better performance.
|
|
41
|
+
*
|
|
42
|
+
* Severity: critical
|
|
43
|
+
* Applies to: all components
|
|
44
|
+
*/
|
|
45
|
+
let ServerReloadOnClientOperationRule = class ServerReloadOnClientOperationRule extends BaseLintRule {
|
|
46
|
+
get Name() { return 'server-reload-on-client-operation'; }
|
|
47
|
+
get AppliesTo() { return 'all'; }
|
|
48
|
+
Test(ast, componentName) {
|
|
49
|
+
const violations = [];
|
|
50
|
+
traverse(ast, {
|
|
51
|
+
CallExpression(path) {
|
|
52
|
+
const callee = path.node.callee;
|
|
53
|
+
// Look for data loading functions
|
|
54
|
+
if (t.isIdentifier(callee) && (callee.name.includes('load') || callee.name.includes('fetch'))) {
|
|
55
|
+
// Check if it's called in sort/filter handlers
|
|
56
|
+
let funcParent = path.getFunctionParent();
|
|
57
|
+
if (funcParent) {
|
|
58
|
+
const funcName = getFunctionName(funcParent);
|
|
59
|
+
if (funcName &&
|
|
60
|
+
(funcName.includes('Sort') || funcName.includes('Filter') || funcName.includes('handleSort') || funcName.includes('handleFilter'))) {
|
|
61
|
+
violations.push({
|
|
62
|
+
rule: 'server-reload-on-client-operation',
|
|
63
|
+
severity: 'critical',
|
|
64
|
+
line: path.node.loc?.start.line || 0,
|
|
65
|
+
column: path.node.loc?.start.column || 0,
|
|
66
|
+
message: 'Reloading data from server on sort/filter. Use useMemo for client-side operations.',
|
|
67
|
+
code: `${funcName} calls ${callee.name}`,
|
|
68
|
+
suggestion: {
|
|
69
|
+
text: 'Use client-side operations for sorting and filtering',
|
|
70
|
+
example: `// ❌ WRONG - Reload from server:
|
|
71
|
+
const handleSort = (field) => {
|
|
72
|
+
setSortBy(field);
|
|
73
|
+
loadData(); // Unnecessary server call!
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// ✅ CORRECT - Client-side sort:
|
|
77
|
+
const handleSort = (field) => {
|
|
78
|
+
setSortBy(field);
|
|
79
|
+
setSortDirection(prev => prev === 'asc' ? 'desc' : 'asc');
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
// Use memoized sorted data:
|
|
83
|
+
const sortedData = useMemo(() => {
|
|
84
|
+
const sorted = [...data];
|
|
85
|
+
sorted.sort((a, b) => {
|
|
86
|
+
const aVal = a[sortBy];
|
|
87
|
+
const bVal = b[sortBy];
|
|
88
|
+
const result = aVal < bVal ? -1 : aVal > bVal ? 1 : 0;
|
|
89
|
+
return sortDirection === 'asc' ? result : -result;
|
|
90
|
+
});
|
|
91
|
+
return sorted;
|
|
92
|
+
}, [data, sortBy, sortDirection]);`,
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
return violations;
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
ServerReloadOnClientOperationRule = __decorate([
|
|
104
|
+
RegisterClass(BaseLintRule, 'server-reload-on-client-operation')
|
|
105
|
+
], ServerReloadOnClientOperationRule);
|
|
106
|
+
export { ServerReloadOnClientOperationRule };
|
|
107
|
+
//# sourceMappingURL=server-reload-on-client-operation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-reload-on-client-operation.js","sourceRoot":"","sources":["../../src/runtime-rules/server-reload-on-client-operation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as t from '@babel/types';
|
|
2
|
+
import { BaseLintRule } from '../lint-rule.js';
|
|
3
|
+
import { Violation } from '../component-linter.js';
|
|
4
|
+
/**
|
|
5
|
+
* Rule: single-function-only
|
|
6
|
+
*
|
|
7
|
+
* Ensures that the component code contains exactly one function declaration
|
|
8
|
+
* and no other code at the top level.
|
|
9
|
+
*
|
|
10
|
+
* Severity: critical
|
|
11
|
+
* Applies to: all components
|
|
12
|
+
*/
|
|
13
|
+
export declare class SingleFunctionOnlyRule extends BaseLintRule {
|
|
14
|
+
get Name(): string;
|
|
15
|
+
get AppliesTo(): 'all' | 'child' | 'root';
|
|
16
|
+
Test(ast: t.File, componentName: string): Violation[];
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=single-function-only.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"single-function-only.d.ts","sourceRoot":"","sources":["../../src/runtime-rules/single-function-only.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,sBAAuB,SAAQ,YAAY;IACtD,IAAI,IAAI,WAAqC;IAC7C,IAAI,SAAS,IAAI,KAAK,GAAG,OAAO,GAAG,MAAM,CAAkB;IAE3D,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,aAAa,EAAE,MAAM,GAAG,SAAS,EAAE;CAoItD"}
|
|
@@ -0,0 +1,103 @@
|
|
|
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: single-function-only
|
|
13
|
+
*
|
|
14
|
+
* Ensures that the component code contains exactly one function declaration
|
|
15
|
+
* and no other code at the top level.
|
|
16
|
+
*
|
|
17
|
+
* Severity: critical
|
|
18
|
+
* Applies to: all components
|
|
19
|
+
*/
|
|
20
|
+
let SingleFunctionOnlyRule = class SingleFunctionOnlyRule extends BaseLintRule {
|
|
21
|
+
get Name() { return 'single-function-only'; }
|
|
22
|
+
get AppliesTo() { return 'all'; }
|
|
23
|
+
Test(ast, componentName) {
|
|
24
|
+
const violations = [];
|
|
25
|
+
// Check that the AST body contains exactly one statement and it's a function declaration
|
|
26
|
+
const programBody = ast.program.body;
|
|
27
|
+
// First, check if there's anything other than a single function declaration
|
|
28
|
+
if (programBody.length === 0) {
|
|
29
|
+
violations.push(createViolation('single-function-only', 'critical', null, `Component code must contain exactly one function declaration named "${componentName}". No code found.`, `Add: function ${componentName}({ utilities, styles, components, callbacks, savedUserSettings, onSaveUserSettings }) { ... }`));
|
|
30
|
+
return violations;
|
|
31
|
+
}
|
|
32
|
+
if (programBody.length > 1) {
|
|
33
|
+
// Multiple top-level statements - not allowed
|
|
34
|
+
violations.push(createViolation('single-function-only', 'critical', programBody[1], `Component code must contain ONLY a single function declaration. Found ${programBody.length} top-level statements. No code should exist before or after the function.`, `Remove all code except: function ${componentName}(...) { ... }`));
|
|
35
|
+
// Report each extra statement
|
|
36
|
+
for (let i = 1; i < programBody.length; i++) {
|
|
37
|
+
const stmt = programBody[i];
|
|
38
|
+
let stmtType = 'statement';
|
|
39
|
+
if (t.isVariableDeclaration(stmt)) {
|
|
40
|
+
stmtType = 'variable declaration';
|
|
41
|
+
}
|
|
42
|
+
else if (t.isFunctionDeclaration(stmt)) {
|
|
43
|
+
stmtType = 'function declaration';
|
|
44
|
+
}
|
|
45
|
+
else if (t.isExpressionStatement(stmt)) {
|
|
46
|
+
stmtType = 'expression';
|
|
47
|
+
}
|
|
48
|
+
violations.push(createViolation('single-function-only', 'critical', stmt, `Extra ${stmtType} not allowed. Only the component function should exist.`, ''));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// Check that the single statement is a function declaration (not arrow function or other)
|
|
52
|
+
const firstStatement = programBody[0];
|
|
53
|
+
if (!t.isFunctionDeclaration(firstStatement)) {
|
|
54
|
+
let actualType = 'unknown statement';
|
|
55
|
+
let suggestion = '';
|
|
56
|
+
if (t.isVariableDeclaration(firstStatement)) {
|
|
57
|
+
// Check if it's an arrow function or other variable
|
|
58
|
+
const declarator = firstStatement.declarations[0];
|
|
59
|
+
if (t.isVariableDeclarator(declarator)) {
|
|
60
|
+
if (t.isArrowFunctionExpression(declarator.init) || t.isFunctionExpression(declarator.init)) {
|
|
61
|
+
actualType = 'arrow function or function expression';
|
|
62
|
+
suggestion = `Use function declaration syntax: function ${componentName}(...) { ... }`;
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
actualType = 'variable declaration';
|
|
66
|
+
suggestion = 'Remove this variable and ensure only the component function exists';
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
else if (t.isExpressionStatement(firstStatement)) {
|
|
71
|
+
actualType = 'expression statement';
|
|
72
|
+
suggestion = 'Remove this expression and add the component function';
|
|
73
|
+
}
|
|
74
|
+
violations.push(createViolation('single-function-only', 'critical', firstStatement, `Component must be a function declaration, not ${actualType}. ${suggestion}`, ''));
|
|
75
|
+
// Don't check name if it's not a function declaration
|
|
76
|
+
return violations;
|
|
77
|
+
}
|
|
78
|
+
// Check that the function name matches the component name
|
|
79
|
+
const functionName = firstStatement.id?.name;
|
|
80
|
+
if (functionName !== componentName) {
|
|
81
|
+
violations.push(createViolation('single-function-only', 'critical', firstStatement, `Component function name "${functionName}" does not match component name "${componentName}". The function must be named exactly as specified.`, `Rename to: function ${componentName}(...)`));
|
|
82
|
+
}
|
|
83
|
+
// Additional check: look for any code before the function that might have been missed
|
|
84
|
+
// (e.g., leading variable declarations that destructure from React)
|
|
85
|
+
if (programBody.length === 1 && t.isFunctionDeclaration(firstStatement)) {
|
|
86
|
+
// Use traverse to find any problematic patterns inside
|
|
87
|
+
traverse(ast, {
|
|
88
|
+
Program(path) {
|
|
89
|
+
// Check if there are any directives or other non-obvious code
|
|
90
|
+
if (path.node.directives && path.node.directives.length > 0) {
|
|
91
|
+
violations.push(createViolation('single-function-only', 'high', null, 'Component should not have directives like "use strict". These are added automatically.', ''));
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
return violations;
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
SingleFunctionOnlyRule = __decorate([
|
|
100
|
+
RegisterClass(BaseLintRule, 'single-function-only')
|
|
101
|
+
], SingleFunctionOnlyRule);
|
|
102
|
+
export { SingleFunctionOnlyRule };
|
|
103
|
+
//# sourceMappingURL=single-function-only.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"single-function-only.js","sourceRoot":"","sources":["../../src/runtime-rules/single-function-only.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
|
+
/**
|
|
5
|
+
* Rule: string-replace-all-occurrences
|
|
6
|
+
*
|
|
7
|
+
* Detects usage of .replace() that may only replace the first occurrence.
|
|
8
|
+
* Flags template patterns (high severity) and general string patterns (low severity).
|
|
9
|
+
* Also checks for regex patterns without the 'g' flag.
|
|
10
|
+
*
|
|
11
|
+
* Severity: high (template patterns) / low (general)
|
|
12
|
+
* Applies to: all components
|
|
13
|
+
*/
|
|
14
|
+
export declare class StringReplaceAllOccurrencesRule extends BaseLintRule {
|
|
15
|
+
get Name(): string;
|
|
16
|
+
get AppliesTo(): 'all' | 'child' | 'root';
|
|
17
|
+
Test(ast: t.File): Violation[];
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=string-replace-all-occurrences.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"string-replace-all-occurrences.d.ts","sourceRoot":"","sources":["../../src/runtime-rules/string-replace-all-occurrences.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;AAEhD;;;;;;;;;GASG;AACH,qBACa,+BAAgC,SAAQ,YAAY;IAC/D,IAAI,IAAI,WAA+C;IACvD,IAAI,SAAS,IAAI,KAAK,GAAG,OAAO,GAAG,MAAM,CAAkB;IAE3D,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,GAAG,SAAS,EAAE;CAsF/B"}
|
|
@@ -0,0 +1,109 @@
|
|
|
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
|
+
* Rule: string-replace-all-occurrences
|
|
13
|
+
*
|
|
14
|
+
* Detects usage of .replace() that may only replace the first occurrence.
|
|
15
|
+
* Flags template patterns (high severity) and general string patterns (low severity).
|
|
16
|
+
* Also checks for regex patterns without the 'g' flag.
|
|
17
|
+
*
|
|
18
|
+
* Severity: high (template patterns) / low (general)
|
|
19
|
+
* Applies to: all components
|
|
20
|
+
*/
|
|
21
|
+
let StringReplaceAllOccurrencesRule = class StringReplaceAllOccurrencesRule extends BaseLintRule {
|
|
22
|
+
get Name() { return 'string-replace-all-occurrences'; }
|
|
23
|
+
get AppliesTo() { return 'all'; }
|
|
24
|
+
Test(ast) {
|
|
25
|
+
const violations = [];
|
|
26
|
+
// Template patterns that are HIGH severity (likely to have multiple occurrences)
|
|
27
|
+
const templatePatterns = [
|
|
28
|
+
{ pattern: /\{\{[^}]+\}\}/, example: '{{field}}', desc: 'double curly braces' },
|
|
29
|
+
{ pattern: /\{[^}]+\}/, example: '{field}', desc: 'single curly braces' },
|
|
30
|
+
{ pattern: /<<[^>]+>>/, example: '<<field>>', desc: 'double angle brackets' },
|
|
31
|
+
{ pattern: /<[^>]+>/, example: '<field>', desc: 'single angle brackets' },
|
|
32
|
+
];
|
|
33
|
+
traverse(ast, {
|
|
34
|
+
CallExpression(path) {
|
|
35
|
+
const callee = path.node.callee;
|
|
36
|
+
// Check if it's a .replace() method call
|
|
37
|
+
if (t.isMemberExpression(callee) && t.isIdentifier(callee.property) && callee.property.name === 'replace') {
|
|
38
|
+
const args = path.node.arguments;
|
|
39
|
+
if (args.length >= 2) {
|
|
40
|
+
const [searchArg] = args;
|
|
41
|
+
// Handle string literal search patterns
|
|
42
|
+
if (t.isStringLiteral(searchArg)) {
|
|
43
|
+
const searchValue = searchArg.value;
|
|
44
|
+
// Check if it matches any template pattern
|
|
45
|
+
let matchedPattern = null;
|
|
46
|
+
for (const tp of templatePatterns) {
|
|
47
|
+
if (tp.pattern.test(searchValue)) {
|
|
48
|
+
matchedPattern = tp;
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (matchedPattern) {
|
|
53
|
+
// HIGH severity for template patterns
|
|
54
|
+
violations.push({
|
|
55
|
+
rule: 'string-replace-all-occurrences',
|
|
56
|
+
severity: 'high',
|
|
57
|
+
line: path.node.loc?.start.line || 0,
|
|
58
|
+
column: path.node.loc?.start.column || 0,
|
|
59
|
+
message: `Using replace() with ${matchedPattern.desc} template '${searchValue}' only replaces the first occurrence. This will cause bugs if the template appears multiple times.`,
|
|
60
|
+
suggestion: {
|
|
61
|
+
text: `Use .replaceAll('${searchValue}', ...) to replace all occurrences`,
|
|
62
|
+
example: `str.replaceAll('${searchValue}', value)`,
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
// LOW severity for general replace() usage
|
|
68
|
+
violations.push({
|
|
69
|
+
rule: 'string-replace-all-occurrences',
|
|
70
|
+
severity: 'low',
|
|
71
|
+
line: path.node.loc?.start.line || 0,
|
|
72
|
+
column: path.node.loc?.start.column || 0,
|
|
73
|
+
message: `Note: replace() only replaces the first occurrence of '${searchValue}'. If you need to replace all occurrences, use replaceAll() or a global regex.`,
|
|
74
|
+
suggestion: {
|
|
75
|
+
text: `Consider if you need replaceAll() instead`,
|
|
76
|
+
example: `str.replaceAll('${searchValue}', value) or str.replace(/${searchValue.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}/g, value)`,
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// Handle regex patterns - only warn if not global
|
|
82
|
+
else if (t.isRegExpLiteral(searchArg)) {
|
|
83
|
+
const flags = searchArg.flags || '';
|
|
84
|
+
if (!flags.includes('g')) {
|
|
85
|
+
violations.push({
|
|
86
|
+
rule: 'string-replace-all-occurrences',
|
|
87
|
+
severity: 'low',
|
|
88
|
+
line: path.node.loc?.start.line || 0,
|
|
89
|
+
column: path.node.loc?.start.column || 0,
|
|
90
|
+
message: `Regex pattern without 'g' flag only replaces first match. Add 'g' flag for global replacement.`,
|
|
91
|
+
suggestion: {
|
|
92
|
+
text: `Add 'g' flag to replace all matches`,
|
|
93
|
+
example: `str.replace(/${searchArg.pattern}/${flags}g, value)`,
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
return violations;
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
StringReplaceAllOccurrencesRule = __decorate([
|
|
106
|
+
RegisterClass(BaseLintRule, 'string-replace-all-occurrences')
|
|
107
|
+
], StringReplaceAllOccurrencesRule);
|
|
108
|
+
export { StringReplaceAllOccurrencesRule };
|
|
109
|
+
//# sourceMappingURL=string-replace-all-occurrences.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"string-replace-all-occurrences.js","sourceRoot":"","sources":["../../src/runtime-rules/string-replace-all-occurrences.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import * as t from '@babel/types';
|
|
2
|
+
import { BaseLintRule } from '../lint-rule.js';
|
|
3
|
+
import { Violation } from '../component-linter.js';
|
|
4
|
+
/**
|
|
5
|
+
* Rule: string-template-validation
|
|
6
|
+
*
|
|
7
|
+
* Validates string templates and concatenation patterns for common issues:
|
|
8
|
+
* - Template literals with undefined expressions
|
|
9
|
+
* - String concatenation with undefined
|
|
10
|
+
* - Malformed string return statements
|
|
11
|
+
* - Strings containing template syntax but not using template literals
|
|
12
|
+
* - Unclosed template literals
|
|
13
|
+
*
|
|
14
|
+
* Severity: critical/high
|
|
15
|
+
* Applies to: all components
|
|
16
|
+
*/
|
|
17
|
+
export declare class StringTemplateValidationRule extends BaseLintRule {
|
|
18
|
+
get Name(): string;
|
|
19
|
+
get AppliesTo(): 'all' | 'child' | 'root';
|
|
20
|
+
Test(ast: t.File, _componentName: string): Violation[];
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=string-template-validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"string-template-validation.d.ts","sourceRoot":"","sources":["../../src/runtime-rules/string-template-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;AAEhD;;;;;;;;;;;;GAYG;AACH,qBACa,4BAA6B,SAAQ,YAAY;IAC5D,IAAI,IAAI,WAA2C;IACnD,IAAI,SAAS,IAAI,KAAK,GAAG,OAAO,GAAG,MAAM,CAAkB;IAE3D,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,GAAG,SAAS,EAAE;CAiJvD"}
|
|
@@ -0,0 +1,163 @@
|
|
|
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
|
+
* Rule: string-template-validation
|
|
13
|
+
*
|
|
14
|
+
* Validates string templates and concatenation patterns for common issues:
|
|
15
|
+
* - Template literals with undefined expressions
|
|
16
|
+
* - String concatenation with undefined
|
|
17
|
+
* - Malformed string return statements
|
|
18
|
+
* - Strings containing template syntax but not using template literals
|
|
19
|
+
* - Unclosed template literals
|
|
20
|
+
*
|
|
21
|
+
* Severity: critical/high
|
|
22
|
+
* Applies to: all components
|
|
23
|
+
*/
|
|
24
|
+
let StringTemplateValidationRule = class StringTemplateValidationRule extends BaseLintRule {
|
|
25
|
+
get Name() { return 'string-template-validation'; }
|
|
26
|
+
get AppliesTo() { return 'all'; }
|
|
27
|
+
Test(ast, _componentName) {
|
|
28
|
+
const violations = [];
|
|
29
|
+
traverse(ast, {
|
|
30
|
+
// Check for malformed template literals
|
|
31
|
+
TemplateLiteral(path) {
|
|
32
|
+
// Template literals are parsed correctly by Babel, so if we're here it's valid
|
|
33
|
+
// But we can check for common issues like empty expressions
|
|
34
|
+
path.node.expressions.forEach((expr) => {
|
|
35
|
+
if (t.isIdentifier(expr) && expr.name === 'undefined') {
|
|
36
|
+
violations.push({
|
|
37
|
+
rule: 'string-template-validation',
|
|
38
|
+
severity: 'high',
|
|
39
|
+
line: expr.loc?.start.line || 0,
|
|
40
|
+
column: expr.loc?.start.column || 0,
|
|
41
|
+
message: 'Template literal contains undefined expression',
|
|
42
|
+
code: '${/* value */}',
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
},
|
|
47
|
+
// Check for string concatenation issues
|
|
48
|
+
BinaryExpression(path) {
|
|
49
|
+
if (path.node.operator === '+') {
|
|
50
|
+
const left = path.node.left;
|
|
51
|
+
const right = path.node.right;
|
|
52
|
+
// Check for incomplete string concatenation patterns
|
|
53
|
+
if (t.isStringLiteral(left) && t.isIdentifier(right) && right.name === 'undefined') {
|
|
54
|
+
violations.push({
|
|
55
|
+
rule: 'string-template-validation',
|
|
56
|
+
severity: 'critical',
|
|
57
|
+
line: path.node.loc?.start.line || 0,
|
|
58
|
+
column: path.node.loc?.start.column || 0,
|
|
59
|
+
message: 'String concatenation with undefined',
|
|
60
|
+
code: `'${left.value}'`,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
// Check for malformed return statements with strings
|
|
66
|
+
ReturnStatement(path) {
|
|
67
|
+
const arg = path.node.argument;
|
|
68
|
+
// Look for patterns like: return ' + value (missing opening quote)
|
|
69
|
+
if (t.isBinaryExpression(arg) && arg.operator === '+') {
|
|
70
|
+
const left = arg.left;
|
|
71
|
+
// Check if it starts with just a quote (malformed)
|
|
72
|
+
if (t.isStringLiteral(left) && left.value === '') {
|
|
73
|
+
const code = path.toString();
|
|
74
|
+
// Check for patterns that suggest missing quotes
|
|
75
|
+
if (code.includes("' +") || code.includes('" +')) {
|
|
76
|
+
violations.push({
|
|
77
|
+
rule: 'string-template-validation',
|
|
78
|
+
severity: 'critical',
|
|
79
|
+
line: path.node.loc?.start.line || 0,
|
|
80
|
+
column: path.node.loc?.start.column || 0,
|
|
81
|
+
message: 'Malformed string concatenation - possible missing quote',
|
|
82
|
+
code: 'Check string quotes and concatenation',
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// Detect pattern like: return ' + y.toFixed(4)
|
|
88
|
+
if (t.isCallExpression(arg)) {
|
|
89
|
+
const code = path.toString();
|
|
90
|
+
if (code.match(/return\s+['"`]\s*\+/)) {
|
|
91
|
+
violations.push({
|
|
92
|
+
rule: 'string-template-validation',
|
|
93
|
+
severity: 'critical',
|
|
94
|
+
line: path.node.loc?.start.line || 0,
|
|
95
|
+
column: path.node.loc?.start.column || 0,
|
|
96
|
+
message: 'Malformed string template - missing opening quote or backtick',
|
|
97
|
+
code: `return \`$\{value}\``,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
// Check inside function bodies for malformed strings
|
|
103
|
+
StringLiteral(path) {
|
|
104
|
+
const value = path.node.value;
|
|
105
|
+
// Check for strings that look like incomplete templates
|
|
106
|
+
let isInTemplate = false;
|
|
107
|
+
let currentPath = path.parentPath;
|
|
108
|
+
while (currentPath) {
|
|
109
|
+
if (t.isTemplateLiteral(currentPath.node)) {
|
|
110
|
+
isInTemplate = true;
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
currentPath = currentPath.parentPath;
|
|
114
|
+
}
|
|
115
|
+
if (value.includes('${') && !isInTemplate) {
|
|
116
|
+
violations.push({
|
|
117
|
+
rule: 'string-template-validation',
|
|
118
|
+
severity: 'high',
|
|
119
|
+
line: path.node.loc?.start.line || 0,
|
|
120
|
+
column: path.node.loc?.start.column || 0,
|
|
121
|
+
message: 'String contains template syntax but is not a template literal',
|
|
122
|
+
code: `\`${value}\``,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
// Additional check for specific malformed patterns in raw code
|
|
128
|
+
const code = ast.toString ? ast.toString() : '';
|
|
129
|
+
const lines = code.split('\n');
|
|
130
|
+
lines.forEach((line, index) => {
|
|
131
|
+
// Pattern: return ' + something or return " + something
|
|
132
|
+
const malformedReturn = line.match(/return\s+['"`]\s*\+\s*[\w.()]/);
|
|
133
|
+
if (malformedReturn) {
|
|
134
|
+
violations.push({
|
|
135
|
+
rule: 'string-template-validation',
|
|
136
|
+
severity: 'critical',
|
|
137
|
+
line: index + 1,
|
|
138
|
+
column: malformedReturn.index || 0,
|
|
139
|
+
message: 'Malformed string return - missing opening quote',
|
|
140
|
+
code: 'return `${value}`',
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
// Pattern: unclosed template literal
|
|
144
|
+
const templateStart = line.match(/`[^`]*\$\{[^}]*$/);
|
|
145
|
+
if (templateStart && !line.includes('`', templateStart.index + 1)) {
|
|
146
|
+
violations.push({
|
|
147
|
+
rule: 'string-template-validation',
|
|
148
|
+
severity: 'critical',
|
|
149
|
+
line: index + 1,
|
|
150
|
+
column: templateStart.index || 0,
|
|
151
|
+
message: 'Unclosed template literal',
|
|
152
|
+
code: 'Close template with backtick',
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
return violations;
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
StringTemplateValidationRule = __decorate([
|
|
160
|
+
RegisterClass(BaseLintRule, 'string-template-validation')
|
|
161
|
+
], StringTemplateValidationRule);
|
|
162
|
+
export { StringTemplateValidationRule };
|
|
163
|
+
//# sourceMappingURL=string-template-validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"string-template-validation.js","sourceRoot":"","sources":["../../src/runtime-rules/string-template-validation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
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
|
+
export declare class StylesValidationRule extends BaseLintRule {
|
|
6
|
+
get Name(): string;
|
|
7
|
+
get AppliesTo(): 'all' | 'child' | 'root';
|
|
8
|
+
Test(ast: t.File, componentName: string, componentSpec?: ComponentSpec): Violation[];
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=styles-validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles-validation.d.ts","sourceRoot":"","sources":["../../src/runtime-rules/styles-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,EAAE,MAAM,6CAA6C,CAAC;AAgC5E,qBACa,oBAAqB,SAAQ,YAAY;IACpD,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,EAAE,aAAa,CAAC,EAAE,aAAa,GAAG,SAAS,EAAE;CAkDrF"}
|