@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,381 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQL WHERE Clause Validator
|
|
3
|
+
*
|
|
4
|
+
* Validates SQL WHERE clauses for syntax and field references.
|
|
5
|
+
* Uses SQLParser for accurate AST-based validation with regex fallback.
|
|
6
|
+
*
|
|
7
|
+
* This validator is essential for catching errors like:
|
|
8
|
+
* ```jsx
|
|
9
|
+
* // ❌ BROKEN - LastModified doesn't exist on Products
|
|
10
|
+
* <EntityDataGrid
|
|
11
|
+
* entityName="Products"
|
|
12
|
+
* extraFilter="Status='Active' AND LastModified > '2024-01-01'"
|
|
13
|
+
* />
|
|
14
|
+
*
|
|
15
|
+
* // ✅ FIXED - CreatedAt exists on Products
|
|
16
|
+
* <EntityDataGrid
|
|
17
|
+
* entityName="Products"
|
|
18
|
+
* extraFilter="Status='Active' AND CreatedAt > '2024-01-01'"
|
|
19
|
+
* />
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* Validation Levels:
|
|
23
|
+
* - **Level 1**: Field existence (IMPLEMENTED)
|
|
24
|
+
* - **Level 2**: Type compatibility (FUTURE)
|
|
25
|
+
* - **Level 3**: SQL function validation (FUTURE)
|
|
26
|
+
*
|
|
27
|
+
* Constraint Definition:
|
|
28
|
+
* ```json
|
|
29
|
+
* {
|
|
30
|
+
* "type": "sql-where-clause",
|
|
31
|
+
* "dependsOn": "entityName",
|
|
32
|
+
* "config": {
|
|
33
|
+
* "caseSensitive": false
|
|
34
|
+
* }
|
|
35
|
+
* }
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
39
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
40
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
41
|
+
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;
|
|
42
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
43
|
+
};
|
|
44
|
+
var SqlWhereClauseValidator_1;
|
|
45
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
46
|
+
import { SemanticValidator } from './semantic-validator.js';
|
|
47
|
+
import { SQLParser } from '@memberjunction/sql-parser';
|
|
48
|
+
import { GetDialect } from '@memberjunction/sql-dialect';
|
|
49
|
+
/** Default SQL dialect when none is provided via ValidationContext */
|
|
50
|
+
const DEFAULT_DIALECT = GetDialect('sqlserver');
|
|
51
|
+
/**
|
|
52
|
+
* Validates SQL WHERE clauses for syntax and field references
|
|
53
|
+
*
|
|
54
|
+
* **Depends On**: Entity name (from entityName prop)
|
|
55
|
+
* **Validates**: SQL WHERE clause string
|
|
56
|
+
* **Common Use Cases**:
|
|
57
|
+
* - EntityDataGrid extraFilter prop
|
|
58
|
+
* - RunView ExtraFilter parameter
|
|
59
|
+
* - Custom components with SQL filtering
|
|
60
|
+
*
|
|
61
|
+
* **Implementation**: Uses SQLParser for accurate AST-based validation
|
|
62
|
+
* with regex fallback for edge cases.
|
|
63
|
+
*/
|
|
64
|
+
let SqlWhereClauseValidator = class SqlWhereClauseValidator extends SemanticValidator {
|
|
65
|
+
static { SqlWhereClauseValidator_1 = this; }
|
|
66
|
+
/**
|
|
67
|
+
* SQL keywords that are not field references
|
|
68
|
+
* Used in regex fallback when AST parsing fails
|
|
69
|
+
*/
|
|
70
|
+
static { this.SQL_KEYWORDS = new Set([
|
|
71
|
+
'AND', 'OR', 'NOT', 'IN', 'LIKE', 'BETWEEN', 'IS', 'NULL',
|
|
72
|
+
'TRUE', 'FALSE', 'ASC', 'DESC', 'CASE', 'WHEN', 'THEN', 'ELSE', 'END',
|
|
73
|
+
'EXISTS', 'ALL', 'ANY', 'SOME',
|
|
74
|
+
// SQL Server functions - not field references
|
|
75
|
+
'DATEADD', 'DATEDIFF', 'GETDATE', 'GETUTCDATE', 'SYSDATETIME',
|
|
76
|
+
'CAST', 'CONVERT', 'ISNULL', 'COALESCE', 'NULLIF',
|
|
77
|
+
'YEAR', 'MONTH', 'DAY', 'DATEPART', 'DATENAME',
|
|
78
|
+
'LEN', 'SUBSTRING', 'CHARINDEX', 'PATINDEX', 'REPLACE',
|
|
79
|
+
'UPPER', 'LOWER', 'TRIM', 'LTRIM', 'RTRIM',
|
|
80
|
+
'LEFT', 'RIGHT', 'REVERSE', 'CONCAT', 'STRING_AGG',
|
|
81
|
+
'COUNT', 'SUM', 'AVG', 'MIN', 'MAX',
|
|
82
|
+
'ROW_NUMBER', 'RANK', 'DENSE_RANK',
|
|
83
|
+
]); }
|
|
84
|
+
/**
|
|
85
|
+
* Validate SQL WHERE clause
|
|
86
|
+
*
|
|
87
|
+
* @param context - Validation context
|
|
88
|
+
* @param constraint - Constraint definition
|
|
89
|
+
* @returns Array of violations (empty if valid)
|
|
90
|
+
*/
|
|
91
|
+
validate(context, constraint) {
|
|
92
|
+
const violations = [];
|
|
93
|
+
// Check if value is dynamic (can't validate statically)
|
|
94
|
+
if (this.isDynamicValue(context.propertyValue)) {
|
|
95
|
+
return violations; // Skip validation
|
|
96
|
+
}
|
|
97
|
+
// WHERE clause must be a string
|
|
98
|
+
if (typeof context.propertyValue !== 'string') {
|
|
99
|
+
return violations; // Not a string - not this validator's responsibility
|
|
100
|
+
}
|
|
101
|
+
const whereClause = context.propertyValue.trim();
|
|
102
|
+
// Empty WHERE clause is valid
|
|
103
|
+
if (whereClause.length === 0) {
|
|
104
|
+
return violations;
|
|
105
|
+
}
|
|
106
|
+
// Get the entity name from dependent prop
|
|
107
|
+
const entityName = this.getDependentPropValue(context, constraint);
|
|
108
|
+
if (!entityName || typeof entityName !== 'string') {
|
|
109
|
+
// Can't validate without entity name
|
|
110
|
+
return violations;
|
|
111
|
+
}
|
|
112
|
+
// Check if entity exists
|
|
113
|
+
if (!context.hasEntity(entityName)) {
|
|
114
|
+
// Entity doesn't exist - not this validator's responsibility
|
|
115
|
+
return violations;
|
|
116
|
+
}
|
|
117
|
+
// Get entity fields
|
|
118
|
+
const entityFields = context.getEntityFields(entityName);
|
|
119
|
+
const fieldNames = entityFields.map((f) => f.name);
|
|
120
|
+
const fieldNamesLower = fieldNames.map((f) => f.toLowerCase());
|
|
121
|
+
// Extract config
|
|
122
|
+
const config = constraint.config || {};
|
|
123
|
+
const caseSensitive = config.caseSensitive === true;
|
|
124
|
+
// Try AST-based validation first (more accurate)
|
|
125
|
+
try {
|
|
126
|
+
const astViolations = this.validateWithAST(whereClause, entityName, fieldNames, fieldNamesLower, caseSensitive, context, constraint);
|
|
127
|
+
violations.push(...astViolations);
|
|
128
|
+
}
|
|
129
|
+
catch (parseError) {
|
|
130
|
+
// Fall back to regex if SQL parsing fails
|
|
131
|
+
console.warn(`SQL parsing failed for WHERE clause, using regex fallback: ${parseError.message}`);
|
|
132
|
+
const regexViolations = this.validateWithRegex(whereClause, entityName, fieldNames, fieldNamesLower, caseSensitive, context, constraint);
|
|
133
|
+
violations.push(...regexViolations);
|
|
134
|
+
}
|
|
135
|
+
return violations;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Validate WHERE clause using AST parsing (Level 1: Field existence)
|
|
139
|
+
*
|
|
140
|
+
* Uses SQLParser to accurately extract column references.
|
|
141
|
+
*
|
|
142
|
+
* @param whereClause - SQL WHERE clause
|
|
143
|
+
* @param entityName - Entity name for context
|
|
144
|
+
* @param fieldNames - Valid field names
|
|
145
|
+
* @param fieldNamesLower - Lowercase field names for case-insensitive matching
|
|
146
|
+
* @param caseSensitive - Whether to check case sensitivity
|
|
147
|
+
* @param context - Validation context
|
|
148
|
+
* @param constraint - Constraint definition
|
|
149
|
+
* @returns Array of violations
|
|
150
|
+
*/
|
|
151
|
+
validateWithAST(whereClause, entityName, fieldNames, fieldNamesLower, caseSensitive, context, constraint) {
|
|
152
|
+
const violations = [];
|
|
153
|
+
// Parse WHERE clause using SQLParser (wraps node-sql-parser with FOR XML workaround)
|
|
154
|
+
const dialect = context.dialect ?? DEFAULT_DIALECT;
|
|
155
|
+
const ast = SQLParser.ParseSQL(`SELECT * FROM t WHERE ${whereClause}`, dialect);
|
|
156
|
+
if (!ast) {
|
|
157
|
+
throw new Error('Failed to parse WHERE clause');
|
|
158
|
+
}
|
|
159
|
+
// Extract column references from AST
|
|
160
|
+
const columnRefs = new Set();
|
|
161
|
+
const statements = Array.isArray(ast) ? ast : [ast];
|
|
162
|
+
for (const statement of statements) {
|
|
163
|
+
// Type guard: check if statement has a where clause
|
|
164
|
+
if (statement && typeof statement === 'object' && 'where' in statement && statement.where) {
|
|
165
|
+
this.extractColumnReferences(statement.where, columnRefs);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
// Validate each column reference
|
|
169
|
+
for (const col of columnRefs) {
|
|
170
|
+
// Handle qualified names (table.column) - extract just column name
|
|
171
|
+
const colName = col.includes('.') ? col.split('.').pop() : col;
|
|
172
|
+
// Check if field exists
|
|
173
|
+
let fieldExists = false;
|
|
174
|
+
let correctCaseName = null;
|
|
175
|
+
if (caseSensitive) {
|
|
176
|
+
fieldExists = fieldNames.includes(colName);
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
// Case-insensitive check
|
|
180
|
+
const index = fieldNamesLower.indexOf(colName.toLowerCase());
|
|
181
|
+
fieldExists = index !== -1;
|
|
182
|
+
if (fieldExists) {
|
|
183
|
+
correctCaseName = fieldNames[index];
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
if (!fieldExists) {
|
|
187
|
+
// Field doesn't exist - find similar fields for suggestion
|
|
188
|
+
const similarFields = this.findSimilar(colName, fieldNames, 3, 3);
|
|
189
|
+
let suggestion = '';
|
|
190
|
+
if (similarFields.length > 0) {
|
|
191
|
+
suggestion = `Did you mean: ${this.formatValueList(similarFields, 3)}?`;
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
suggestion = `Available fields: ${this.formatValueList(fieldNames, 10)}`;
|
|
195
|
+
}
|
|
196
|
+
violations.push(this.createViolation('invalid-field-reference', this.applyErrorTemplate(constraint, context, `SQL WHERE clause references invalid field '${colName}' on entity '${entityName}'`, {
|
|
197
|
+
field: colName,
|
|
198
|
+
entityName,
|
|
199
|
+
availableFields: fieldNames.slice(0, 10).join(', '),
|
|
200
|
+
}), 'critical', suggestion, {
|
|
201
|
+
field: colName,
|
|
202
|
+
entityName,
|
|
203
|
+
availableFields: fieldNames,
|
|
204
|
+
similarFields,
|
|
205
|
+
}));
|
|
206
|
+
}
|
|
207
|
+
else if (!caseSensitive && correctCaseName && correctCaseName !== colName) {
|
|
208
|
+
// Field exists but case doesn't match
|
|
209
|
+
violations.push(this.createViolation('case-mismatch', this.applyErrorTemplate(constraint, context, `Field '${colName}' case doesn't match schema in WHERE clause. Expected '${correctCaseName}' on entity '${entityName}'`, {
|
|
210
|
+
field: colName,
|
|
211
|
+
correctCase: correctCaseName,
|
|
212
|
+
entityName,
|
|
213
|
+
}), 'medium', `Use '${correctCaseName}' instead of '${colName}'`, {
|
|
214
|
+
field: colName,
|
|
215
|
+
correctCase: correctCaseName,
|
|
216
|
+
entityName,
|
|
217
|
+
}));
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return violations;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Extract column references from SQL AST
|
|
224
|
+
*
|
|
225
|
+
* Pattern based on MJQueryEntity.extractColumnReferences (lines 563-590)
|
|
226
|
+
* Recursively traverses the AST to find all column_ref nodes.
|
|
227
|
+
*
|
|
228
|
+
* @param expr - Expression node from AST
|
|
229
|
+
* @param referencedColumns - Set to collect column names
|
|
230
|
+
*/
|
|
231
|
+
extractColumnReferences(expr, referencedColumns) {
|
|
232
|
+
if (!expr || typeof expr !== 'object')
|
|
233
|
+
return;
|
|
234
|
+
// Column reference found
|
|
235
|
+
if (expr.type === 'column_ref') {
|
|
236
|
+
// Handle qualified names (table.column)
|
|
237
|
+
const colName = expr.table ? `${expr.table}.${expr.column}` : expr.column;
|
|
238
|
+
if (typeof colName === 'string') {
|
|
239
|
+
referencedColumns.add(colName);
|
|
240
|
+
}
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
// Skip SQL functions - these are not field references
|
|
244
|
+
// But still check function arguments for column references
|
|
245
|
+
if (expr.type === 'function') {
|
|
246
|
+
if (expr.args) {
|
|
247
|
+
const args = expr.args.value || expr.args;
|
|
248
|
+
const argsArray = Array.isArray(args) ? args : [args];
|
|
249
|
+
for (const arg of argsArray) {
|
|
250
|
+
if (arg)
|
|
251
|
+
this.extractColumnReferences(arg, referencedColumns);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
// Recursively traverse binary expressions (AND, OR, comparisons)
|
|
257
|
+
if (expr.left)
|
|
258
|
+
this.extractColumnReferences(expr.left, referencedColumns);
|
|
259
|
+
if (expr.right)
|
|
260
|
+
this.extractColumnReferences(expr.right, referencedColumns);
|
|
261
|
+
// Handle IN clauses and arrays
|
|
262
|
+
if (expr.value && Array.isArray(expr.value)) {
|
|
263
|
+
for (const item of expr.value) {
|
|
264
|
+
this.extractColumnReferences(item, referencedColumns);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
// Handle CASE expressions
|
|
268
|
+
if (expr.result)
|
|
269
|
+
this.extractColumnReferences(expr.result, referencedColumns);
|
|
270
|
+
if (expr.expr)
|
|
271
|
+
this.extractColumnReferences(expr.expr, referencedColumns);
|
|
272
|
+
// Handle function args (different structure than type:'function')
|
|
273
|
+
if (expr.args) {
|
|
274
|
+
const args = Array.isArray(expr.args) ? expr.args : [expr.args];
|
|
275
|
+
for (const arg of args) {
|
|
276
|
+
if (arg && typeof arg === 'object') {
|
|
277
|
+
if (arg.value) {
|
|
278
|
+
this.extractColumnReferences(arg.value, referencedColumns);
|
|
279
|
+
}
|
|
280
|
+
else {
|
|
281
|
+
this.extractColumnReferences(arg, referencedColumns);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Fallback regex-based validation for when SQL parsing fails
|
|
289
|
+
*
|
|
290
|
+
* Less accurate than AST parsing but handles edge cases.
|
|
291
|
+
* Violations from regex fallback have 'high' severity instead of 'critical'
|
|
292
|
+
* to indicate less certainty.
|
|
293
|
+
*
|
|
294
|
+
* @param whereClause - SQL WHERE clause
|
|
295
|
+
* @param entityName - Entity name for context
|
|
296
|
+
* @param fieldNames - Valid field names
|
|
297
|
+
* @param fieldNamesLower - Lowercase field names
|
|
298
|
+
* @param caseSensitive - Whether to check case sensitivity
|
|
299
|
+
* @param context - Validation context
|
|
300
|
+
* @param constraint - Constraint definition
|
|
301
|
+
* @returns Array of violations
|
|
302
|
+
*/
|
|
303
|
+
validateWithRegex(whereClause, entityName, fieldNames, fieldNamesLower, caseSensitive, context, constraint) {
|
|
304
|
+
const violations = [];
|
|
305
|
+
// Simple regex to extract potential field names
|
|
306
|
+
// Matches word characters that could be identifiers
|
|
307
|
+
const fieldPattern = /\b([A-Za-z_][A-Za-z0-9_]*)\b/g;
|
|
308
|
+
let match;
|
|
309
|
+
const checkedFields = new Set();
|
|
310
|
+
while ((match = fieldPattern.exec(whereClause)) !== null) {
|
|
311
|
+
const identifier = match[1];
|
|
312
|
+
// Skip SQL keywords
|
|
313
|
+
if (SqlWhereClauseValidator_1.SQL_KEYWORDS.has(identifier.toUpperCase())) {
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
// Skip duplicates
|
|
317
|
+
if (checkedFields.has(identifier.toLowerCase())) {
|
|
318
|
+
continue;
|
|
319
|
+
}
|
|
320
|
+
checkedFields.add(identifier.toLowerCase());
|
|
321
|
+
// Check if field exists
|
|
322
|
+
let fieldExists = false;
|
|
323
|
+
let correctCaseName = null;
|
|
324
|
+
if (caseSensitive) {
|
|
325
|
+
fieldExists = fieldNames.includes(identifier);
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
const index = fieldNamesLower.indexOf(identifier.toLowerCase());
|
|
329
|
+
fieldExists = index !== -1;
|
|
330
|
+
if (fieldExists) {
|
|
331
|
+
correctCaseName = fieldNames[index];
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
if (!fieldExists) {
|
|
335
|
+
const similarFields = this.findSimilar(identifier, fieldNames, 3, 3);
|
|
336
|
+
let suggestion = '';
|
|
337
|
+
if (similarFields.length > 0) {
|
|
338
|
+
suggestion = `Did you mean: ${this.formatValueList(similarFields, 3)}?`;
|
|
339
|
+
}
|
|
340
|
+
else {
|
|
341
|
+
suggestion = `Available fields: ${this.formatValueList(fieldNames, 10)}`;
|
|
342
|
+
}
|
|
343
|
+
violations.push(this.createViolation('invalid-field-reference', this.applyErrorTemplate(constraint, context, `Possible invalid field '${identifier}' in WHERE clause (entity: '${entityName}')`, {
|
|
344
|
+
field: identifier,
|
|
345
|
+
entityName,
|
|
346
|
+
}), 'high', // Lower severity for regex fallback (less certain)
|
|
347
|
+
suggestion, {
|
|
348
|
+
field: identifier,
|
|
349
|
+
entityName,
|
|
350
|
+
availableFields: fieldNames,
|
|
351
|
+
similarFields,
|
|
352
|
+
validationMethod: 'regex-fallback',
|
|
353
|
+
}));
|
|
354
|
+
}
|
|
355
|
+
else if (!caseSensitive && correctCaseName && correctCaseName !== identifier) {
|
|
356
|
+
violations.push(this.createViolation('case-mismatch', this.applyErrorTemplate(constraint, context, `Field '${identifier}' case doesn't match schema in WHERE clause. Expected '${correctCaseName}'`, {
|
|
357
|
+
field: identifier,
|
|
358
|
+
correctCase: correctCaseName,
|
|
359
|
+
entityName,
|
|
360
|
+
}), 'medium', `Use '${correctCaseName}' instead of '${identifier}'`, {
|
|
361
|
+
field: identifier,
|
|
362
|
+
correctCase: correctCaseName,
|
|
363
|
+
entityName,
|
|
364
|
+
validationMethod: 'regex-fallback',
|
|
365
|
+
}));
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
return violations;
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Get validator description
|
|
372
|
+
*/
|
|
373
|
+
getDescription() {
|
|
374
|
+
return 'Validates SQL WHERE clauses for syntax and field references using AST parsing';
|
|
375
|
+
}
|
|
376
|
+
};
|
|
377
|
+
SqlWhereClauseValidator = SqlWhereClauseValidator_1 = __decorate([
|
|
378
|
+
RegisterClass(SemanticValidator, 'sql-where-clause')
|
|
379
|
+
], SqlWhereClauseValidator);
|
|
380
|
+
export { SqlWhereClauseValidator };
|
|
381
|
+
//# sourceMappingURL=sql-where-clause-validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql-where-clause-validator.js","sourceRoot":"","sources":["../../../src/schema-validation/semantic-validators/sql-where-clause-validator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subset Of Entity Fields Validator
|
|
3
|
+
*
|
|
4
|
+
* Validates that array elements are valid field names for a specified entity.
|
|
5
|
+
*
|
|
6
|
+
* This validator is essential for catching errors like:
|
|
7
|
+
* ```jsx
|
|
8
|
+
* // ❌ BROKEN - FullName, Status, StartDate don't exist on Members
|
|
9
|
+
* <EntityDataGrid
|
|
10
|
+
* entityName="Members"
|
|
11
|
+
* fields={['FullName', 'Status', 'StartDate']}
|
|
12
|
+
* />
|
|
13
|
+
*
|
|
14
|
+
* // ✅ FIXED - FirstName, LastName, Email exist on Members
|
|
15
|
+
* <EntityDataGrid
|
|
16
|
+
* entityName="Members"
|
|
17
|
+
* fields={['FirstName', 'LastName', 'Email']}
|
|
18
|
+
* />
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* Constraint Definition:
|
|
22
|
+
* ```json
|
|
23
|
+
* {
|
|
24
|
+
* "type": "subset-of-entity-fields",
|
|
25
|
+
* "dependsOn": "entityName",
|
|
26
|
+
* "config": {
|
|
27
|
+
* "allowWildcard": false,
|
|
28
|
+
* "caseSensitive": false
|
|
29
|
+
* }
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
import { PropertyConstraint, ConstraintViolation } from '@memberjunction/interactive-component-types';
|
|
34
|
+
import { SemanticValidator } from './semantic-validator.js';
|
|
35
|
+
import { ValidationContext } from './validation-context.js';
|
|
36
|
+
/**
|
|
37
|
+
* Validates that array elements are valid field names for an entity
|
|
38
|
+
*
|
|
39
|
+
* **Depends On**: Entity name (from entityName prop)
|
|
40
|
+
* **Validates**: Array of field name strings
|
|
41
|
+
* **Common Use Cases**:
|
|
42
|
+
* - EntityDataGrid fields prop
|
|
43
|
+
* - DataGrid columns (when using entity binding)
|
|
44
|
+
* - Custom components with entity field arrays
|
|
45
|
+
*/
|
|
46
|
+
export declare class SubsetOfEntityFieldsValidator extends SemanticValidator {
|
|
47
|
+
/**
|
|
48
|
+
* Validate that array elements are valid entity field names
|
|
49
|
+
*
|
|
50
|
+
* @param context - Validation context
|
|
51
|
+
* @param constraint - Constraint definition
|
|
52
|
+
* @returns Array of violations (empty if valid)
|
|
53
|
+
*/
|
|
54
|
+
validate(context: ValidationContext, constraint: PropertyConstraint): ConstraintViolation[];
|
|
55
|
+
/**
|
|
56
|
+
* Get validator description
|
|
57
|
+
*/
|
|
58
|
+
getDescription(): string;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=subset-of-entity-fields-validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subset-of-entity-fields-validator.d.ts","sourceRoot":"","sources":["../../../src/schema-validation/semantic-validators/subset-of-entity-fields-validator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,6CAA6C,CAAC;AAErD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAGzD;;;;;;;;;GASG;AACH,qBACa,6BAA8B,SAAQ,iBAAiB;IAClE;;;;;;OAMG;IACH,QAAQ,CACN,OAAO,EAAE,iBAAiB,EAC1B,UAAU,EAAE,kBAAkB,GAC7B,mBAAmB,EAAE;IAwMxB;;OAEG;IACH,cAAc,IAAI,MAAM;CAGzB"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subset Of Entity Fields Validator
|
|
3
|
+
*
|
|
4
|
+
* Validates that array elements are valid field names for a specified entity.
|
|
5
|
+
*
|
|
6
|
+
* This validator is essential for catching errors like:
|
|
7
|
+
* ```jsx
|
|
8
|
+
* // ❌ BROKEN - FullName, Status, StartDate don't exist on Members
|
|
9
|
+
* <EntityDataGrid
|
|
10
|
+
* entityName="Members"
|
|
11
|
+
* fields={['FullName', 'Status', 'StartDate']}
|
|
12
|
+
* />
|
|
13
|
+
*
|
|
14
|
+
* // ✅ FIXED - FirstName, LastName, Email exist on Members
|
|
15
|
+
* <EntityDataGrid
|
|
16
|
+
* entityName="Members"
|
|
17
|
+
* fields={['FirstName', 'LastName', 'Email']}
|
|
18
|
+
* />
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* Constraint Definition:
|
|
22
|
+
* ```json
|
|
23
|
+
* {
|
|
24
|
+
* "type": "subset-of-entity-fields",
|
|
25
|
+
* "dependsOn": "entityName",
|
|
26
|
+
* "config": {
|
|
27
|
+
* "allowWildcard": false,
|
|
28
|
+
* "caseSensitive": false
|
|
29
|
+
* }
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
34
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
35
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
36
|
+
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;
|
|
37
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
38
|
+
};
|
|
39
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
40
|
+
import { SemanticValidator } from './semantic-validator.js';
|
|
41
|
+
/**
|
|
42
|
+
* Validates that array elements are valid field names for an entity
|
|
43
|
+
*
|
|
44
|
+
* **Depends On**: Entity name (from entityName prop)
|
|
45
|
+
* **Validates**: Array of field name strings
|
|
46
|
+
* **Common Use Cases**:
|
|
47
|
+
* - EntityDataGrid fields prop
|
|
48
|
+
* - DataGrid columns (when using entity binding)
|
|
49
|
+
* - Custom components with entity field arrays
|
|
50
|
+
*/
|
|
51
|
+
let SubsetOfEntityFieldsValidator = class SubsetOfEntityFieldsValidator extends SemanticValidator {
|
|
52
|
+
/**
|
|
53
|
+
* Validate that array elements are valid entity field names
|
|
54
|
+
*
|
|
55
|
+
* @param context - Validation context
|
|
56
|
+
* @param constraint - Constraint definition
|
|
57
|
+
* @returns Array of violations (empty if valid)
|
|
58
|
+
*/
|
|
59
|
+
validate(context, constraint) {
|
|
60
|
+
const violations = [];
|
|
61
|
+
// Check if value is dynamic (can't validate statically)
|
|
62
|
+
if (this.isDynamicValue(context.propertyValue)) {
|
|
63
|
+
return violations; // Skip validation
|
|
64
|
+
}
|
|
65
|
+
// Get the entity name from dependent prop
|
|
66
|
+
const entityName = this.getDependentPropValue(context, constraint);
|
|
67
|
+
if (!entityName || typeof entityName !== 'string') {
|
|
68
|
+
// Can't validate without entity name
|
|
69
|
+
return violations;
|
|
70
|
+
}
|
|
71
|
+
// Check if entity exists
|
|
72
|
+
if (!context.hasEntity(entityName)) {
|
|
73
|
+
// Entity doesn't exist - not this validator's responsibility to report
|
|
74
|
+
// (should be caught by valid-entity-reference validator)
|
|
75
|
+
return violations;
|
|
76
|
+
}
|
|
77
|
+
// Get entity fields
|
|
78
|
+
const entityFields = context.getEntityFields(entityName);
|
|
79
|
+
const fieldNames = entityFields.map((f) => f.name);
|
|
80
|
+
const fieldNamesLower = fieldNames.map((f) => f.toLowerCase());
|
|
81
|
+
// Extract config
|
|
82
|
+
const config = constraint.config || {};
|
|
83
|
+
const allowWildcard = config.allowWildcard === true;
|
|
84
|
+
const caseSensitive = config.caseSensitive === true;
|
|
85
|
+
// Validate the property value is an array
|
|
86
|
+
if (!Array.isArray(context.propertyValue)) {
|
|
87
|
+
violations.push(this.createViolation('invalid-type', this.applyErrorTemplate(constraint, context, `Property '${context.propertyName}' must be an array of field names`, { entityName }), 'critical', `Use an array: ${context.propertyName}={['${fieldNames.slice(0, 3).join("', '")}']}`));
|
|
88
|
+
return violations;
|
|
89
|
+
}
|
|
90
|
+
// Validate each element is a string or object with 'field' property
|
|
91
|
+
for (let i = 0; i < context.propertyValue.length; i++) {
|
|
92
|
+
const element = context.propertyValue[i];
|
|
93
|
+
// Skip dynamic values (identifiers, expressions)
|
|
94
|
+
if (this.isDynamicValue(element)) {
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
// Extract field name from element
|
|
98
|
+
let fieldName = null;
|
|
99
|
+
if (typeof element === 'string') {
|
|
100
|
+
// Simple string field name
|
|
101
|
+
fieldName = element;
|
|
102
|
+
}
|
|
103
|
+
else if (typeof element === 'object' && element !== null) {
|
|
104
|
+
// Object with 'field' property (e.g., ColumnDef, FieldDefinition)
|
|
105
|
+
const fieldProp = element.field;
|
|
106
|
+
if (typeof fieldProp === 'string') {
|
|
107
|
+
fieldName = fieldProp;
|
|
108
|
+
}
|
|
109
|
+
else if (this.isDynamicValue(fieldProp)) {
|
|
110
|
+
// Dynamic field property - skip validation
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
// Object without valid 'field' property
|
|
115
|
+
violations.push(this.createViolation('invalid-element-type', this.applyErrorTemplate(constraint, context, `Element at index ${i} in '${context.propertyName}' must be a string or object with 'field' property`, { entityName, index: i, elementType: typeof element }), 'high', `Use string field names or objects with 'field' property from entity '${entityName}'`));
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
// Invalid type (not string or object)
|
|
121
|
+
violations.push(this.createViolation('invalid-element-type', this.applyErrorTemplate(constraint, context, `Element at index ${i} in '${context.propertyName}' must be a string or object, got ${typeof element}`, { entityName, index: i, elementType: typeof element }), 'high', `Use string field names from entity '${entityName}'`));
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
// At this point, fieldName should be a string
|
|
125
|
+
if (!fieldName) {
|
|
126
|
+
continue; // Should not reach here, but safety check
|
|
127
|
+
}
|
|
128
|
+
// Check for wildcard
|
|
129
|
+
if (allowWildcard && fieldName === '*') {
|
|
130
|
+
continue; // Wildcard is allowed
|
|
131
|
+
}
|
|
132
|
+
// Check if field exists
|
|
133
|
+
let fieldExists = false;
|
|
134
|
+
let correctCaseName = null;
|
|
135
|
+
if (caseSensitive) {
|
|
136
|
+
fieldExists = fieldNames.includes(fieldName);
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
// Case-insensitive check
|
|
140
|
+
const index = fieldNamesLower.indexOf(fieldName.toLowerCase());
|
|
141
|
+
fieldExists = index !== -1;
|
|
142
|
+
if (fieldExists) {
|
|
143
|
+
correctCaseName = fieldNames[index];
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
if (!fieldExists) {
|
|
147
|
+
// Field doesn't exist - find similar fields for suggestion
|
|
148
|
+
const similarFields = this.findSimilar(fieldName, fieldNames, 3, 3);
|
|
149
|
+
let suggestion = '';
|
|
150
|
+
if (similarFields.length > 0) {
|
|
151
|
+
suggestion = `Did you mean: ${this.formatValueList(similarFields, 3)}?`;
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
suggestion = `Available fields: ${this.formatValueList(fieldNames, 10)}`;
|
|
155
|
+
}
|
|
156
|
+
violations.push(this.createViolation('invalid-field', this.applyErrorTemplate(constraint, context, `Field '${fieldName}' does not exist on entity '${entityName}'`, {
|
|
157
|
+
field: fieldName,
|
|
158
|
+
entityName,
|
|
159
|
+
availableFields: fieldNames.slice(0, 10).join(', '),
|
|
160
|
+
}), 'critical', suggestion, {
|
|
161
|
+
field: fieldName,
|
|
162
|
+
entityName,
|
|
163
|
+
index: i,
|
|
164
|
+
availableFields: fieldNames,
|
|
165
|
+
similarFields,
|
|
166
|
+
}));
|
|
167
|
+
}
|
|
168
|
+
else if (!caseSensitive && correctCaseName && correctCaseName !== fieldName) {
|
|
169
|
+
// Field exists but case doesn't match
|
|
170
|
+
violations.push(this.createViolation('case-mismatch', this.applyErrorTemplate(constraint, context, `Field '${fieldName}' case doesn't match schema. Expected '${correctCaseName}' on entity '${entityName}'`, {
|
|
171
|
+
field: fieldName,
|
|
172
|
+
correctCase: correctCaseName,
|
|
173
|
+
entityName,
|
|
174
|
+
}), 'medium', `Use '${correctCaseName}' instead of '${fieldName}'`, {
|
|
175
|
+
field: fieldName,
|
|
176
|
+
correctCase: correctCaseName,
|
|
177
|
+
entityName,
|
|
178
|
+
index: i,
|
|
179
|
+
}));
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return violations;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Get validator description
|
|
186
|
+
*/
|
|
187
|
+
getDescription() {
|
|
188
|
+
return 'Validates that array elements are valid field names for the specified entity';
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
SubsetOfEntityFieldsValidator = __decorate([
|
|
192
|
+
RegisterClass(SemanticValidator, 'subset-of-entity-fields')
|
|
193
|
+
], SubsetOfEntityFieldsValidator);
|
|
194
|
+
export { SubsetOfEntityFieldsValidator };
|
|
195
|
+
//# sourceMappingURL=subset-of-entity-fields-validator.js.map
|