@memberjunction/react-test-harness 2.124.0 → 2.125.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/lib/component-linter.d.ts.map +1 -1
- package/dist/lib/component-linter.js +433 -2
- package/dist/lib/component-linter.js.map +1 -1
- package/dist/lib/constraint-validators/base-constraint-validator.d.ts +259 -0
- package/dist/lib/constraint-validators/base-constraint-validator.d.ts.map +1 -0
- package/dist/lib/constraint-validators/base-constraint-validator.js +304 -0
- package/dist/lib/constraint-validators/base-constraint-validator.js.map +1 -0
- package/dist/lib/constraint-validators/index.d.ts +21 -0
- package/dist/lib/constraint-validators/index.d.ts.map +1 -0
- package/dist/lib/constraint-validators/index.js +37 -0
- package/dist/lib/constraint-validators/index.js.map +1 -0
- package/dist/lib/constraint-validators/required-when-validator.d.ts +43 -0
- package/dist/lib/constraint-validators/required-when-validator.d.ts.map +1 -0
- package/dist/lib/constraint-validators/required-when-validator.js +97 -0
- package/dist/lib/constraint-validators/required-when-validator.js.map +1 -0
- package/dist/lib/constraint-validators/sql-where-clause-validator.d.ts +116 -0
- package/dist/lib/constraint-validators/sql-where-clause-validator.d.ts.map +1 -0
- package/dist/lib/constraint-validators/sql-where-clause-validator.js +381 -0
- package/dist/lib/constraint-validators/sql-where-clause-validator.js.map +1 -0
- package/dist/lib/constraint-validators/subset-of-entity-fields-validator.d.ts +60 -0
- package/dist/lib/constraint-validators/subset-of-entity-fields-validator.d.ts.map +1 -0
- package/dist/lib/constraint-validators/subset-of-entity-fields-validator.js +198 -0
- package/dist/lib/constraint-validators/subset-of-entity-fields-validator.js.map +1 -0
- package/dist/lib/constraint-validators/validation-context.d.ts +326 -0
- package/dist/lib/constraint-validators/validation-context.d.ts.map +1 -0
- package/dist/lib/constraint-validators/validation-context.js +14 -0
- package/dist/lib/constraint-validators/validation-context.js.map +1 -0
- package/dist/lib/prop-value-extractor.d.ts +147 -0
- package/dist/lib/prop-value-extractor.d.ts.map +1 -0
- package/dist/lib/prop-value-extractor.js +499 -0
- package/dist/lib/prop-value-extractor.js.map +1 -0
- package/dist/lib/type-context.d.ts +2 -0
- package/dist/lib/type-context.d.ts.map +1 -1
- package/dist/lib/type-context.js +22 -9
- package/dist/lib/type-context.js.map +1 -1
- package/dist/lib/type-inference-engine.d.ts +20 -0
- package/dist/lib/type-inference-engine.d.ts.map +1 -1
- package/dist/lib/type-inference-engine.js +253 -20
- package/dist/lib/type-inference-engine.js.map +1 -1
- package/package.json +13 -9
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"required-when-validator.d.ts","sourceRoot":"","sources":["../../../src/lib/constraint-validators/required-when-validator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,6CAA6C,CAAC;AAEtG,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAEzD,qBACa,qBAAsB,SAAQ,uBAAuB;IAChE;;OAEG;IACH,cAAc,IAAI,MAAM;IAIxB;;;;;;;;;OASG;IACH,QAAQ,CAAC,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,kBAAkB,GAAG,mBAAmB,EAAE;CAmD5F"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Required-When Constraint Validator
|
|
4
|
+
*
|
|
5
|
+
* Validates that a property is present when a specified condition is met.
|
|
6
|
+
* Used for conditional requirements like "valueField is required when aggregateMethod is 'sum'".
|
|
7
|
+
*
|
|
8
|
+
* Config:
|
|
9
|
+
* - condition: JavaScript expression evaluated with siblingProp as the dependent property value
|
|
10
|
+
* Example: "siblingProp === 'sum' || siblingProp === 'average'"
|
|
11
|
+
*
|
|
12
|
+
* Example usage in spec JSON:
|
|
13
|
+
* ```json
|
|
14
|
+
* {
|
|
15
|
+
* "type": "required-when",
|
|
16
|
+
* "dependsOn": "aggregateMethod",
|
|
17
|
+
* "config": {
|
|
18
|
+
* "condition": "siblingProp === 'sum' || siblingProp === 'average' || siblingProp === 'min' || siblingProp === 'max'"
|
|
19
|
+
* },
|
|
20
|
+
* "errorTemplate": "valueField is required when aggregateMethod is '{aggregateMethod}'"
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
25
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
26
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
27
|
+
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;
|
|
28
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
29
|
+
};
|
|
30
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
31
|
+
exports.RequiredWhenValidator = void 0;
|
|
32
|
+
const global_1 = require("@memberjunction/global");
|
|
33
|
+
const base_constraint_validator_1 = require("./base-constraint-validator");
|
|
34
|
+
let RequiredWhenValidator = class RequiredWhenValidator extends base_constraint_validator_1.BaseConstraintValidator {
|
|
35
|
+
/**
|
|
36
|
+
* Get description of this validator
|
|
37
|
+
*/
|
|
38
|
+
getDescription() {
|
|
39
|
+
return 'Validates that a property is present when a specified condition is met based on another property value';
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Validate that a property is present when a condition is met
|
|
43
|
+
*
|
|
44
|
+
* Evaluates a JavaScript condition expression with the dependent property value,
|
|
45
|
+
* and checks if the current property has a value when the condition is true.
|
|
46
|
+
*
|
|
47
|
+
* @param context - Validation context containing property info and sibling props
|
|
48
|
+
* @param constraint - The constraint definition from the spec
|
|
49
|
+
* @returns Array of violations (empty if valid)
|
|
50
|
+
*/
|
|
51
|
+
validate(context, constraint) {
|
|
52
|
+
const violations = [];
|
|
53
|
+
if (!constraint.dependsOn) {
|
|
54
|
+
return violations; // Can't validate without a dependency
|
|
55
|
+
}
|
|
56
|
+
const dependentPropValue = context.siblingProps.get(constraint.dependsOn);
|
|
57
|
+
// If dependent prop doesn't exist, condition doesn't apply
|
|
58
|
+
if (dependentPropValue === undefined || dependentPropValue === null) {
|
|
59
|
+
return violations;
|
|
60
|
+
}
|
|
61
|
+
const condition = constraint.config?.condition;
|
|
62
|
+
if (!condition || typeof condition !== 'string') {
|
|
63
|
+
console.warn(`required-when validator missing condition config for ${context.propertyName}`);
|
|
64
|
+
return violations;
|
|
65
|
+
}
|
|
66
|
+
// Evaluate the condition
|
|
67
|
+
let conditionMet = false;
|
|
68
|
+
try {
|
|
69
|
+
// Create a safe evaluation context
|
|
70
|
+
const siblingProp = dependentPropValue;
|
|
71
|
+
// eslint-disable-next-line no-eval
|
|
72
|
+
conditionMet = eval(condition);
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
console.error(`Error evaluating required-when condition "${condition}":`, error);
|
|
76
|
+
return violations;
|
|
77
|
+
}
|
|
78
|
+
// If condition is met, check if the property has a value
|
|
79
|
+
if (conditionMet) {
|
|
80
|
+
const hasValue = context.propertyValue !== undefined &&
|
|
81
|
+
context.propertyValue !== null &&
|
|
82
|
+
context.propertyValue !== '';
|
|
83
|
+
if (!hasValue) {
|
|
84
|
+
const message = constraint.errorTemplate
|
|
85
|
+
? constraint.errorTemplate.replace(`{${constraint.dependsOn}}`, String(dependentPropValue))
|
|
86
|
+
: `${context.propertyName} is required when ${constraint.dependsOn} is ${dependentPropValue}`;
|
|
87
|
+
violations.push(this.createViolation('missing-required-prop', message, 'high'));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return violations;
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
exports.RequiredWhenValidator = RequiredWhenValidator;
|
|
94
|
+
exports.RequiredWhenValidator = RequiredWhenValidator = __decorate([
|
|
95
|
+
(0, global_1.RegisterClass)(base_constraint_validator_1.BaseConstraintValidator, 'required-when')
|
|
96
|
+
], RequiredWhenValidator);
|
|
97
|
+
//# sourceMappingURL=required-when-validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"required-when-validator.js","sourceRoot":"","sources":["../../../src/lib/constraint-validators/required-when-validator.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;;;;;;;;;AAGH,mDAAuD;AACvD,2EAAsE;AAI/D,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,mDAAuB;IAChE;;OAEG;IACH,cAAc;QACZ,OAAO,wGAAwG,CAAC;IAClH,CAAC;IAED;;;;;;;;;OASG;IACH,QAAQ,CAAC,OAA0B,EAAE,UAA8B;QACjE,MAAM,UAAU,GAA0B,EAAE,CAAC;QAE7C,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC;YAC1B,OAAO,UAAU,CAAC,CAAC,sCAAsC;QAC3D,CAAC;QAED,MAAM,kBAAkB,GAAG,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QAE1E,2DAA2D;QAC3D,IAAI,kBAAkB,KAAK,SAAS,IAAI,kBAAkB,KAAK,IAAI,EAAE,CAAC;YACpE,OAAO,UAAU,CAAC;QACpB,CAAC;QAED,MAAM,SAAS,GAAG,UAAU,CAAC,MAAM,EAAE,SAAS,CAAC;QAC/C,IAAI,CAAC,SAAS,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;YAChD,OAAO,CAAC,IAAI,CAAC,wDAAwD,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;YAC7F,OAAO,UAAU,CAAC;QACpB,CAAC;QAED,yBAAyB;QACzB,IAAI,YAAY,GAAG,KAAK,CAAC;QACzB,IAAI,CAAC;YACH,mCAAmC;YACnC,MAAM,WAAW,GAAG,kBAAkB,CAAC;YACvC,mCAAmC;YACnC,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;QACjC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,6CAA6C,SAAS,IAAI,EAAE,KAAK,CAAC,CAAC;YACjF,OAAO,UAAU,CAAC;QACpB,CAAC;QAED,yDAAyD;QACzD,IAAI,YAAY,EAAE,CAAC;YACjB,MAAM,QAAQ,GAAG,OAAO,CAAC,aAAa,KAAK,SAAS;gBACpC,OAAO,CAAC,aAAa,KAAK,IAAI;gBAC9B,OAAO,CAAC,aAAa,KAAK,EAAE,CAAC;YAE7C,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,MAAM,OAAO,GAAG,UAAU,CAAC,aAAa;oBACtC,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,UAAU,CAAC,SAAS,GAAG,EAAE,MAAM,CAAC,kBAAkB,CAAC,CAAC;oBAC3F,CAAC,CAAC,GAAG,OAAO,CAAC,YAAY,qBAAqB,UAAU,CAAC,SAAS,OAAO,kBAAkB,EAAE,CAAC;gBAEhG,UAAU,CAAC,IAAI,CACb,IAAI,CAAC,eAAe,CAAC,uBAAuB,EAAE,OAAO,EAAE,MAAM,CAAC,CAC/D,CAAC;YACJ,CAAC;QACH,CAAC;QAED,OAAO,UAAU,CAAC;IACpB,CAAC;CACF,CAAA;AArEY,sDAAqB;gCAArB,qBAAqB;IADjC,IAAA,sBAAa,EAAC,mDAAuB,EAAE,eAAe,CAAC;GAC3C,qBAAqB,CAqEjC"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQL WHERE Clause Validator
|
|
3
|
+
*
|
|
4
|
+
* Validates SQL WHERE clauses for syntax and field references.
|
|
5
|
+
* Uses node-sql-parser 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
|
+
import { PropertyConstraint, ConstraintViolation } from '@memberjunction/interactive-component-types';
|
|
39
|
+
import { BaseConstraintValidator } from './base-constraint-validator';
|
|
40
|
+
import { ValidationContext } from './validation-context';
|
|
41
|
+
/**
|
|
42
|
+
* Validates SQL WHERE clauses for syntax and field references
|
|
43
|
+
*
|
|
44
|
+
* **Depends On**: Entity name (from entityName prop)
|
|
45
|
+
* **Validates**: SQL WHERE clause string
|
|
46
|
+
* **Common Use Cases**:
|
|
47
|
+
* - EntityDataGrid extraFilter prop
|
|
48
|
+
* - RunView ExtraFilter parameter
|
|
49
|
+
* - Custom components with SQL filtering
|
|
50
|
+
*
|
|
51
|
+
* **Implementation**: Uses node-sql-parser (same as QueryEntity.server.ts)
|
|
52
|
+
* for accurate AST-based validation with regex fallback for edge cases.
|
|
53
|
+
*/
|
|
54
|
+
export declare class SqlWhereClauseValidator extends BaseConstraintValidator {
|
|
55
|
+
/**
|
|
56
|
+
* SQL keywords that are not field references
|
|
57
|
+
* Used in regex fallback when AST parsing fails
|
|
58
|
+
*/
|
|
59
|
+
private static readonly SQL_KEYWORDS;
|
|
60
|
+
/**
|
|
61
|
+
* Validate SQL WHERE clause
|
|
62
|
+
*
|
|
63
|
+
* @param context - Validation context
|
|
64
|
+
* @param constraint - Constraint definition
|
|
65
|
+
* @returns Array of violations (empty if valid)
|
|
66
|
+
*/
|
|
67
|
+
validate(context: ValidationContext, constraint: PropertyConstraint): ConstraintViolation[];
|
|
68
|
+
/**
|
|
69
|
+
* Validate WHERE clause using AST parsing (Level 1: Field existence)
|
|
70
|
+
*
|
|
71
|
+
* Uses node-sql-parser to accurately extract column references.
|
|
72
|
+
* Pattern based on QueryEntity.server.ts (lines 305-324, 560-590)
|
|
73
|
+
*
|
|
74
|
+
* @param whereClause - SQL WHERE clause
|
|
75
|
+
* @param entityName - Entity name for context
|
|
76
|
+
* @param fieldNames - Valid field names
|
|
77
|
+
* @param fieldNamesLower - Lowercase field names for case-insensitive matching
|
|
78
|
+
* @param caseSensitive - Whether to check case sensitivity
|
|
79
|
+
* @param context - Validation context
|
|
80
|
+
* @param constraint - Constraint definition
|
|
81
|
+
* @returns Array of violations
|
|
82
|
+
*/
|
|
83
|
+
private validateWithAST;
|
|
84
|
+
/**
|
|
85
|
+
* Extract column references from SQL AST
|
|
86
|
+
*
|
|
87
|
+
* Pattern based on QueryEntity.extractColumnReferences (lines 563-590)
|
|
88
|
+
* Recursively traverses the AST to find all column_ref nodes.
|
|
89
|
+
*
|
|
90
|
+
* @param expr - Expression node from AST
|
|
91
|
+
* @param referencedColumns - Set to collect column names
|
|
92
|
+
*/
|
|
93
|
+
private extractColumnReferences;
|
|
94
|
+
/**
|
|
95
|
+
* Fallback regex-based validation for when SQL parsing fails
|
|
96
|
+
*
|
|
97
|
+
* Less accurate than AST parsing but handles edge cases.
|
|
98
|
+
* Violations from regex fallback have 'high' severity instead of 'critical'
|
|
99
|
+
* to indicate less certainty.
|
|
100
|
+
*
|
|
101
|
+
* @param whereClause - SQL WHERE clause
|
|
102
|
+
* @param entityName - Entity name for context
|
|
103
|
+
* @param fieldNames - Valid field names
|
|
104
|
+
* @param fieldNamesLower - Lowercase field names
|
|
105
|
+
* @param caseSensitive - Whether to check case sensitivity
|
|
106
|
+
* @param context - Validation context
|
|
107
|
+
* @param constraint - Constraint definition
|
|
108
|
+
* @returns Array of violations
|
|
109
|
+
*/
|
|
110
|
+
private validateWithRegex;
|
|
111
|
+
/**
|
|
112
|
+
* Get validator description
|
|
113
|
+
*/
|
|
114
|
+
getDescription(): string;
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=sql-where-clause-validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql-where-clause-validator.d.ts","sourceRoot":"","sources":["../../../src/lib/constraint-validators/sql-where-clause-validator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,6CAA6C,CAAC;AAErD,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAIzD;;;;;;;;;;;;GAYG;AACH,qBACa,uBAAwB,SAAQ,uBAAuB;IAClE;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAajC;IAEH;;;;;;OAMG;IACH,QAAQ,CACN,OAAO,EAAE,iBAAiB,EAC1B,UAAU,EAAE,kBAAkB,GAC7B,mBAAmB,EAAE;IA0ExB;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,eAAe;IAiHvB;;;;;;;;OAQG;IACH,OAAO,CAAC,uBAAuB;IAwD/B;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,iBAAiB;IA6GzB;;OAEG;IACH,cAAc,IAAI,MAAM;CAGzB"}
|
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SQL WHERE Clause Validator
|
|
4
|
+
*
|
|
5
|
+
* Validates SQL WHERE clauses for syntax and field references.
|
|
6
|
+
* Uses node-sql-parser for accurate AST-based validation with regex fallback.
|
|
7
|
+
*
|
|
8
|
+
* This validator is essential for catching errors like:
|
|
9
|
+
* ```jsx
|
|
10
|
+
* // ❌ BROKEN - LastModified doesn't exist on Products
|
|
11
|
+
* <EntityDataGrid
|
|
12
|
+
* entityName="Products"
|
|
13
|
+
* extraFilter="Status='Active' AND LastModified > '2024-01-01'"
|
|
14
|
+
* />
|
|
15
|
+
*
|
|
16
|
+
* // ✅ FIXED - CreatedAt exists on Products
|
|
17
|
+
* <EntityDataGrid
|
|
18
|
+
* entityName="Products"
|
|
19
|
+
* extraFilter="Status='Active' AND CreatedAt > '2024-01-01'"
|
|
20
|
+
* />
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* Validation Levels:
|
|
24
|
+
* - **Level 1**: Field existence (IMPLEMENTED)
|
|
25
|
+
* - **Level 2**: Type compatibility (FUTURE)
|
|
26
|
+
* - **Level 3**: SQL function validation (FUTURE)
|
|
27
|
+
*
|
|
28
|
+
* Constraint Definition:
|
|
29
|
+
* ```json
|
|
30
|
+
* {
|
|
31
|
+
* "type": "sql-where-clause",
|
|
32
|
+
* "dependsOn": "entityName",
|
|
33
|
+
* "config": {
|
|
34
|
+
* "caseSensitive": false
|
|
35
|
+
* }
|
|
36
|
+
* }
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
40
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
41
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
42
|
+
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;
|
|
43
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
44
|
+
};
|
|
45
|
+
var SqlWhereClauseValidator_1;
|
|
46
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
47
|
+
exports.SqlWhereClauseValidator = void 0;
|
|
48
|
+
const global_1 = require("@memberjunction/global");
|
|
49
|
+
const base_constraint_validator_1 = require("./base-constraint-validator");
|
|
50
|
+
const node_sql_parser_1 = require("node-sql-parser");
|
|
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 node-sql-parser (same as QueryEntity.server.ts)
|
|
62
|
+
* for accurate AST-based validation with regex fallback for edge cases.
|
|
63
|
+
*/
|
|
64
|
+
let SqlWhereClauseValidator = SqlWhereClauseValidator_1 = class SqlWhereClauseValidator extends base_constraint_validator_1.BaseConstraintValidator {
|
|
65
|
+
/**
|
|
66
|
+
* Validate SQL WHERE clause
|
|
67
|
+
*
|
|
68
|
+
* @param context - Validation context
|
|
69
|
+
* @param constraint - Constraint definition
|
|
70
|
+
* @returns Array of violations (empty if valid)
|
|
71
|
+
*/
|
|
72
|
+
validate(context, constraint) {
|
|
73
|
+
const violations = [];
|
|
74
|
+
// Check if value is dynamic (can't validate statically)
|
|
75
|
+
if (this.isDynamicValue(context.propertyValue)) {
|
|
76
|
+
return violations; // Skip validation
|
|
77
|
+
}
|
|
78
|
+
// WHERE clause must be a string
|
|
79
|
+
if (typeof context.propertyValue !== 'string') {
|
|
80
|
+
return violations; // Not a string - not this validator's responsibility
|
|
81
|
+
}
|
|
82
|
+
const whereClause = context.propertyValue.trim();
|
|
83
|
+
// Empty WHERE clause is valid
|
|
84
|
+
if (whereClause.length === 0) {
|
|
85
|
+
return violations;
|
|
86
|
+
}
|
|
87
|
+
// Get the entity name from dependent prop
|
|
88
|
+
const entityName = this.getDependentPropValue(context, constraint);
|
|
89
|
+
if (!entityName || typeof entityName !== 'string') {
|
|
90
|
+
// Can't validate without entity name
|
|
91
|
+
return violations;
|
|
92
|
+
}
|
|
93
|
+
// Check if entity exists
|
|
94
|
+
if (!context.hasEntity(entityName)) {
|
|
95
|
+
// Entity doesn't exist - not this validator's responsibility
|
|
96
|
+
return violations;
|
|
97
|
+
}
|
|
98
|
+
// Get entity fields
|
|
99
|
+
const entityFields = context.getEntityFields(entityName);
|
|
100
|
+
const fieldNames = entityFields.map((f) => f.name);
|
|
101
|
+
const fieldNamesLower = fieldNames.map((f) => f.toLowerCase());
|
|
102
|
+
// Extract config
|
|
103
|
+
const config = constraint.config || {};
|
|
104
|
+
const caseSensitive = config.caseSensitive === true;
|
|
105
|
+
// Try AST-based validation first (more accurate)
|
|
106
|
+
try {
|
|
107
|
+
const astViolations = this.validateWithAST(whereClause, entityName, fieldNames, fieldNamesLower, caseSensitive, context, constraint);
|
|
108
|
+
violations.push(...astViolations);
|
|
109
|
+
}
|
|
110
|
+
catch (parseError) {
|
|
111
|
+
// Fall back to regex if SQL parsing fails
|
|
112
|
+
console.warn(`SQL parsing failed for WHERE clause, using regex fallback: ${parseError.message}`);
|
|
113
|
+
const regexViolations = this.validateWithRegex(whereClause, entityName, fieldNames, fieldNamesLower, caseSensitive, context, constraint);
|
|
114
|
+
violations.push(...regexViolations);
|
|
115
|
+
}
|
|
116
|
+
return violations;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Validate WHERE clause using AST parsing (Level 1: Field existence)
|
|
120
|
+
*
|
|
121
|
+
* Uses node-sql-parser to accurately extract column references.
|
|
122
|
+
* Pattern based on QueryEntity.server.ts (lines 305-324, 560-590)
|
|
123
|
+
*
|
|
124
|
+
* @param whereClause - SQL WHERE clause
|
|
125
|
+
* @param entityName - Entity name for context
|
|
126
|
+
* @param fieldNames - Valid field names
|
|
127
|
+
* @param fieldNamesLower - Lowercase field names for case-insensitive matching
|
|
128
|
+
* @param caseSensitive - Whether to check case sensitivity
|
|
129
|
+
* @param context - Validation context
|
|
130
|
+
* @param constraint - Constraint definition
|
|
131
|
+
* @returns Array of violations
|
|
132
|
+
*/
|
|
133
|
+
validateWithAST(whereClause, entityName, fieldNames, fieldNamesLower, caseSensitive, context, constraint) {
|
|
134
|
+
const violations = [];
|
|
135
|
+
// Parse WHERE clause using node-sql-parser
|
|
136
|
+
// Same pattern as QueryEntity.server.ts line 309
|
|
137
|
+
const parser = new node_sql_parser_1.Parser();
|
|
138
|
+
const ast = parser.astify(`SELECT * FROM t WHERE ${whereClause}`, {
|
|
139
|
+
database: 'TransactSQL',
|
|
140
|
+
});
|
|
141
|
+
// Extract column references from AST
|
|
142
|
+
const columnRefs = new Set();
|
|
143
|
+
const statements = Array.isArray(ast) ? ast : [ast];
|
|
144
|
+
for (const statement of statements) {
|
|
145
|
+
// Type guard: check if statement has a where clause
|
|
146
|
+
if (statement && typeof statement === 'object' && 'where' in statement && statement.where) {
|
|
147
|
+
this.extractColumnReferences(statement.where, columnRefs);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// Validate each column reference
|
|
151
|
+
for (const col of columnRefs) {
|
|
152
|
+
// Handle qualified names (table.column) - extract just column name
|
|
153
|
+
const colName = col.includes('.') ? col.split('.').pop() : col;
|
|
154
|
+
// Check if field exists
|
|
155
|
+
let fieldExists = false;
|
|
156
|
+
let correctCaseName = null;
|
|
157
|
+
if (caseSensitive) {
|
|
158
|
+
fieldExists = fieldNames.includes(colName);
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
// Case-insensitive check
|
|
162
|
+
const index = fieldNamesLower.indexOf(colName.toLowerCase());
|
|
163
|
+
fieldExists = index !== -1;
|
|
164
|
+
if (fieldExists) {
|
|
165
|
+
correctCaseName = fieldNames[index];
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
if (!fieldExists) {
|
|
169
|
+
// Field doesn't exist - find similar fields for suggestion
|
|
170
|
+
const similarFields = this.findSimilar(colName, fieldNames, 3, 3);
|
|
171
|
+
let suggestion = '';
|
|
172
|
+
if (similarFields.length > 0) {
|
|
173
|
+
suggestion = `Did you mean: ${this.formatValueList(similarFields, 3)}?`;
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
suggestion = `Available fields: ${this.formatValueList(fieldNames, 10)}`;
|
|
177
|
+
}
|
|
178
|
+
violations.push(this.createViolation('invalid-field-reference', this.applyErrorTemplate(constraint, context, `SQL WHERE clause references invalid field '${colName}' on entity '${entityName}'`, {
|
|
179
|
+
field: colName,
|
|
180
|
+
entityName,
|
|
181
|
+
availableFields: fieldNames.slice(0, 10).join(', '),
|
|
182
|
+
}), 'critical', suggestion, {
|
|
183
|
+
field: colName,
|
|
184
|
+
entityName,
|
|
185
|
+
availableFields: fieldNames,
|
|
186
|
+
similarFields,
|
|
187
|
+
}));
|
|
188
|
+
}
|
|
189
|
+
else if (!caseSensitive && correctCaseName && correctCaseName !== colName) {
|
|
190
|
+
// Field exists but case doesn't match
|
|
191
|
+
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}'`, {
|
|
192
|
+
field: colName,
|
|
193
|
+
correctCase: correctCaseName,
|
|
194
|
+
entityName,
|
|
195
|
+
}), 'medium', `Use '${correctCaseName}' instead of '${colName}'`, {
|
|
196
|
+
field: colName,
|
|
197
|
+
correctCase: correctCaseName,
|
|
198
|
+
entityName,
|
|
199
|
+
}));
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return violations;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Extract column references from SQL AST
|
|
206
|
+
*
|
|
207
|
+
* Pattern based on QueryEntity.extractColumnReferences (lines 563-590)
|
|
208
|
+
* Recursively traverses the AST to find all column_ref nodes.
|
|
209
|
+
*
|
|
210
|
+
* @param expr - Expression node from AST
|
|
211
|
+
* @param referencedColumns - Set to collect column names
|
|
212
|
+
*/
|
|
213
|
+
extractColumnReferences(expr, referencedColumns) {
|
|
214
|
+
if (!expr || typeof expr !== 'object')
|
|
215
|
+
return;
|
|
216
|
+
// Column reference found
|
|
217
|
+
if (expr.type === 'column_ref') {
|
|
218
|
+
// Handle qualified names (table.column)
|
|
219
|
+
const colName = expr.table ? `${expr.table}.${expr.column}` : expr.column;
|
|
220
|
+
if (typeof colName === 'string') {
|
|
221
|
+
referencedColumns.add(colName);
|
|
222
|
+
}
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
// Skip SQL functions - these are not field references
|
|
226
|
+
// But still check function arguments for column references
|
|
227
|
+
if (expr.type === 'function') {
|
|
228
|
+
if (expr.args) {
|
|
229
|
+
const args = expr.args.value || expr.args;
|
|
230
|
+
const argsArray = Array.isArray(args) ? args : [args];
|
|
231
|
+
for (const arg of argsArray) {
|
|
232
|
+
if (arg)
|
|
233
|
+
this.extractColumnReferences(arg, referencedColumns);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
// Recursively traverse binary expressions (AND, OR, comparisons)
|
|
239
|
+
if (expr.left)
|
|
240
|
+
this.extractColumnReferences(expr.left, referencedColumns);
|
|
241
|
+
if (expr.right)
|
|
242
|
+
this.extractColumnReferences(expr.right, referencedColumns);
|
|
243
|
+
// Handle IN clauses and arrays
|
|
244
|
+
if (expr.value && Array.isArray(expr.value)) {
|
|
245
|
+
for (const item of expr.value) {
|
|
246
|
+
this.extractColumnReferences(item, referencedColumns);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
// Handle CASE expressions
|
|
250
|
+
if (expr.result)
|
|
251
|
+
this.extractColumnReferences(expr.result, referencedColumns);
|
|
252
|
+
if (expr.expr)
|
|
253
|
+
this.extractColumnReferences(expr.expr, referencedColumns);
|
|
254
|
+
// Handle function args (different structure than type:'function')
|
|
255
|
+
if (expr.args) {
|
|
256
|
+
const args = Array.isArray(expr.args) ? expr.args : [expr.args];
|
|
257
|
+
for (const arg of args) {
|
|
258
|
+
if (arg && typeof arg === 'object') {
|
|
259
|
+
if (arg.value) {
|
|
260
|
+
this.extractColumnReferences(arg.value, referencedColumns);
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
this.extractColumnReferences(arg, referencedColumns);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Fallback regex-based validation for when SQL parsing fails
|
|
271
|
+
*
|
|
272
|
+
* Less accurate than AST parsing but handles edge cases.
|
|
273
|
+
* Violations from regex fallback have 'high' severity instead of 'critical'
|
|
274
|
+
* to indicate less certainty.
|
|
275
|
+
*
|
|
276
|
+
* @param whereClause - SQL WHERE clause
|
|
277
|
+
* @param entityName - Entity name for context
|
|
278
|
+
* @param fieldNames - Valid field names
|
|
279
|
+
* @param fieldNamesLower - Lowercase field names
|
|
280
|
+
* @param caseSensitive - Whether to check case sensitivity
|
|
281
|
+
* @param context - Validation context
|
|
282
|
+
* @param constraint - Constraint definition
|
|
283
|
+
* @returns Array of violations
|
|
284
|
+
*/
|
|
285
|
+
validateWithRegex(whereClause, entityName, fieldNames, fieldNamesLower, caseSensitive, context, constraint) {
|
|
286
|
+
const violations = [];
|
|
287
|
+
// Simple regex to extract potential field names
|
|
288
|
+
// Matches word characters that could be identifiers
|
|
289
|
+
const fieldPattern = /\b([A-Za-z_][A-Za-z0-9_]*)\b/g;
|
|
290
|
+
let match;
|
|
291
|
+
const checkedFields = new Set();
|
|
292
|
+
while ((match = fieldPattern.exec(whereClause)) !== null) {
|
|
293
|
+
const identifier = match[1];
|
|
294
|
+
// Skip SQL keywords
|
|
295
|
+
if (SqlWhereClauseValidator_1.SQL_KEYWORDS.has(identifier.toUpperCase())) {
|
|
296
|
+
continue;
|
|
297
|
+
}
|
|
298
|
+
// Skip duplicates
|
|
299
|
+
if (checkedFields.has(identifier.toLowerCase())) {
|
|
300
|
+
continue;
|
|
301
|
+
}
|
|
302
|
+
checkedFields.add(identifier.toLowerCase());
|
|
303
|
+
// Check if field exists
|
|
304
|
+
let fieldExists = false;
|
|
305
|
+
let correctCaseName = null;
|
|
306
|
+
if (caseSensitive) {
|
|
307
|
+
fieldExists = fieldNames.includes(identifier);
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
const index = fieldNamesLower.indexOf(identifier.toLowerCase());
|
|
311
|
+
fieldExists = index !== -1;
|
|
312
|
+
if (fieldExists) {
|
|
313
|
+
correctCaseName = fieldNames[index];
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
if (!fieldExists) {
|
|
317
|
+
const similarFields = this.findSimilar(identifier, fieldNames, 3, 3);
|
|
318
|
+
let suggestion = '';
|
|
319
|
+
if (similarFields.length > 0) {
|
|
320
|
+
suggestion = `Did you mean: ${this.formatValueList(similarFields, 3)}?`;
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
suggestion = `Available fields: ${this.formatValueList(fieldNames, 10)}`;
|
|
324
|
+
}
|
|
325
|
+
violations.push(this.createViolation('invalid-field-reference', this.applyErrorTemplate(constraint, context, `Possible invalid field '${identifier}' in WHERE clause (entity: '${entityName}')`, {
|
|
326
|
+
field: identifier,
|
|
327
|
+
entityName,
|
|
328
|
+
}), 'high', // Lower severity for regex fallback (less certain)
|
|
329
|
+
suggestion, {
|
|
330
|
+
field: identifier,
|
|
331
|
+
entityName,
|
|
332
|
+
availableFields: fieldNames,
|
|
333
|
+
similarFields,
|
|
334
|
+
validationMethod: 'regex-fallback',
|
|
335
|
+
}));
|
|
336
|
+
}
|
|
337
|
+
else if (!caseSensitive && correctCaseName && correctCaseName !== identifier) {
|
|
338
|
+
violations.push(this.createViolation('case-mismatch', this.applyErrorTemplate(constraint, context, `Field '${identifier}' case doesn't match schema in WHERE clause. Expected '${correctCaseName}'`, {
|
|
339
|
+
field: identifier,
|
|
340
|
+
correctCase: correctCaseName,
|
|
341
|
+
entityName,
|
|
342
|
+
}), 'medium', `Use '${correctCaseName}' instead of '${identifier}'`, {
|
|
343
|
+
field: identifier,
|
|
344
|
+
correctCase: correctCaseName,
|
|
345
|
+
entityName,
|
|
346
|
+
validationMethod: 'regex-fallback',
|
|
347
|
+
}));
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
return violations;
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Get validator description
|
|
354
|
+
*/
|
|
355
|
+
getDescription() {
|
|
356
|
+
return 'Validates SQL WHERE clauses for syntax and field references using AST parsing';
|
|
357
|
+
}
|
|
358
|
+
};
|
|
359
|
+
exports.SqlWhereClauseValidator = SqlWhereClauseValidator;
|
|
360
|
+
/**
|
|
361
|
+
* SQL keywords that are not field references
|
|
362
|
+
* Used in regex fallback when AST parsing fails
|
|
363
|
+
*/
|
|
364
|
+
SqlWhereClauseValidator.SQL_KEYWORDS = new Set([
|
|
365
|
+
'AND', 'OR', 'NOT', 'IN', 'LIKE', 'BETWEEN', 'IS', 'NULL',
|
|
366
|
+
'TRUE', 'FALSE', 'ASC', 'DESC', 'CASE', 'WHEN', 'THEN', 'ELSE', 'END',
|
|
367
|
+
'EXISTS', 'ALL', 'ANY', 'SOME',
|
|
368
|
+
// SQL Server functions - not field references
|
|
369
|
+
'DATEADD', 'DATEDIFF', 'GETDATE', 'GETUTCDATE', 'SYSDATETIME',
|
|
370
|
+
'CAST', 'CONVERT', 'ISNULL', 'COALESCE', 'NULLIF',
|
|
371
|
+
'YEAR', 'MONTH', 'DAY', 'DATEPART', 'DATENAME',
|
|
372
|
+
'LEN', 'SUBSTRING', 'CHARINDEX', 'PATINDEX', 'REPLACE',
|
|
373
|
+
'UPPER', 'LOWER', 'TRIM', 'LTRIM', 'RTRIM',
|
|
374
|
+
'LEFT', 'RIGHT', 'REVERSE', 'CONCAT', 'STRING_AGG',
|
|
375
|
+
'COUNT', 'SUM', 'AVG', 'MIN', 'MAX',
|
|
376
|
+
'ROW_NUMBER', 'RANK', 'DENSE_RANK',
|
|
377
|
+
]);
|
|
378
|
+
exports.SqlWhereClauseValidator = SqlWhereClauseValidator = SqlWhereClauseValidator_1 = __decorate([
|
|
379
|
+
(0, global_1.RegisterClass)(base_constraint_validator_1.BaseConstraintValidator, 'sql-where-clause')
|
|
380
|
+
], SqlWhereClauseValidator);
|
|
381
|
+
//# sourceMappingURL=sql-where-clause-validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql-where-clause-validator.js","sourceRoot":"","sources":["../../../src/lib/constraint-validators/sql-where-clause-validator.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;;;;;;;;;;AAMH,mDAAuD;AACvD,2EAAsE;AAGtE,qDAAyC;AAEzC;;;;;;;;;;;;GAYG;AAEI,IAAM,uBAAuB,+BAA7B,MAAM,uBAAwB,SAAQ,mDAAuB;IAoBlE;;;;;;OAMG;IACH,QAAQ,CACN,OAA0B,EAC1B,UAA8B;QAE9B,MAAM,UAAU,GAA0B,EAAE,CAAC;QAE7C,wDAAwD;QACxD,IAAI,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;YAC/C,OAAO,UAAU,CAAC,CAAC,kBAAkB;QACvC,CAAC;QAED,gCAAgC;QAChC,IAAI,OAAO,OAAO,CAAC,aAAa,KAAK,QAAQ,EAAE,CAAC;YAC9C,OAAO,UAAU,CAAC,CAAC,qDAAqD;QAC1E,CAAC;QAED,MAAM,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;QAEjD,8BAA8B;QAC9B,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7B,OAAO,UAAU,CAAC;QACpB,CAAC;QAED,0CAA0C;QAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,qBAAqB,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QAEnE,IAAI,CAAC,UAAU,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;YAClD,qCAAqC;YACrC,OAAO,UAAU,CAAC;QACpB,CAAC;QAED,yBAAyB;QACzB,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC;YACnC,6DAA6D;YAC7D,OAAO,UAAU,CAAC;QACpB,CAAC;QAED,oBAAoB;QACpB,MAAM,YAAY,GAAG,OAAO,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;QACzD,MAAM,UAAU,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACnD,MAAM,eAAe,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;QAE/D,iBAAiB;QACjB,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,IAAI,EAAE,CAAC;QACvC,MAAM,aAAa,GAAG,MAAM,CAAC,aAAa,KAAK,IAAI,CAAC;QAEpD,iDAAiD;QACjD,IAAI,CAAC;YACH,MAAM,aAAa,GAAG,IAAI,CAAC,eAAe,CACxC,WAAW,EACX,UAAU,EACV,UAAU,EACV,eAAe,EACf,aAAa,EACb,OAAO,EACP,UAAU,CACX,CAAC;YACF,UAAU,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,CAAC;QACpC,CAAC;QAAC,OAAO,UAAe,EAAE,CAAC;YACzB,0CAA0C;YAC1C,OAAO,CAAC,IAAI,CAAC,8DAA8D,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;YAEjG,MAAM,eAAe,GAAG,IAAI,CAAC,iBAAiB,CAC5C,WAAW,EACX,UAAU,EACV,UAAU,EACV,eAAe,EACf,aAAa,EACb,OAAO,EACP,UAAU,CACX,CAAC;YACF,UAAU,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,CAAC;QACtC,CAAC;QAED,OAAO,UAAU,CAAC;IACpB,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACK,eAAe,CACrB,WAAmB,EACnB,UAAkB,EAClB,UAAoB,EACpB,eAAyB,EACzB,aAAsB,EACtB,OAA0B,EAC1B,UAA8B;QAE9B,MAAM,UAAU,GAA0B,EAAE,CAAC;QAE7C,2CAA2C;QAC3C,iDAAiD;QACjD,MAAM,MAAM,GAAG,IAAI,wBAAM,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,yBAAyB,WAAW,EAAE,EAAE;YAChE,QAAQ,EAAE,aAAa;SACxB,CAAC,CAAC;QAEH,qCAAqC;QACrC,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;QACrC,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAEpD,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,oDAAoD;YACpD,IAAI,SAAS,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,OAAO,IAAI,SAAS,IAAI,SAAS,CAAC,KAAK,EAAE,CAAC;gBAC1F,IAAI,CAAC,uBAAuB,CAAC,SAAS,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;YAC5D,CAAC;QACH,CAAC;QAED,iCAAiC;QACjC,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;YAC7B,mEAAmE;YACnE,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAG,CAAC,CAAC,CAAC,GAAG,CAAC;YAEhE,wBAAwB;YACxB,IAAI,WAAW,GAAG,KAAK,CAAC;YACxB,IAAI,eAAe,GAAkB,IAAI,CAAC;YAE1C,IAAI,aAAa,EAAE,CAAC;gBAClB,WAAW,GAAG,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAC7C,CAAC;iBAAM,CAAC;gBACN,yBAAyB;gBACzB,MAAM,KAAK,GAAG,eAAe,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;gBAC7D,WAAW,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC;gBAC3B,IAAI,WAAW,EAAE,CAAC;oBAChB,eAAe,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;gBACtC,CAAC;YACH,CAAC;YAED,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,2DAA2D;gBAC3D,MAAM,aAAa,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;gBAClE,IAAI,UAAU,GAAG,EAAE,CAAC;gBAEpB,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC7B,UAAU,GAAG,iBAAiB,IAAI,CAAC,eAAe,CAAC,aAAa,EAAE,CAAC,CAAC,GAAG,CAAC;gBAC1E,CAAC;qBAAM,CAAC;oBACN,UAAU,GAAG,qBAAqB,IAAI,CAAC,eAAe,CAAC,UAAU,EAAE,EAAE,CAAC,EAAE,CAAC;gBAC3E,CAAC;gBAED,UAAU,CAAC,IAAI,CACb,IAAI,CAAC,eAAe,CAClB,yBAAyB,EACzB,IAAI,CAAC,kBAAkB,CACrB,UAAU,EACV,OAAO,EACP,8CAA8C,OAAO,gBAAgB,UAAU,GAAG,EAClF;oBACE,KAAK,EAAE,OAAO;oBACd,UAAU;oBACV,eAAe,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;iBACpD,CACF,EACD,UAAU,EACV,UAAU,EACV;oBACE,KAAK,EAAE,OAAO;oBACd,UAAU;oBACV,eAAe,EAAE,UAAU;oBAC3B,aAAa;iBACd,CACF,CACF,CAAC;YACJ,CAAC;iBAAM,IAAI,CAAC,aAAa,IAAI,eAAe,IAAI,eAAe,KAAK,OAAO,EAAE,CAAC;gBAC5E,sCAAsC;gBACtC,UAAU,CAAC,IAAI,CACb,IAAI,CAAC,eAAe,CAClB,eAAe,EACf,IAAI,CAAC,kBAAkB,CACrB,UAAU,EACV,OAAO,EACP,UAAU,OAAO,0DAA0D,eAAe,gBAAgB,UAAU,GAAG,EACvH;oBACE,KAAK,EAAE,OAAO;oBACd,WAAW,EAAE,eAAe;oBAC5B,UAAU;iBACX,CACF,EACD,QAAQ,EACR,QAAQ,eAAe,iBAAiB,OAAO,GAAG,EAClD;oBACE,KAAK,EAAE,OAAO;oBACd,WAAW,EAAE,eAAe;oBAC5B,UAAU;iBACX,CACF,CACF,CAAC;YACJ,CAAC;QACH,CAAC;QAED,OAAO,UAAU,CAAC;IACpB,CAAC;IAED;;;;;;;;OAQG;IACK,uBAAuB,CAAC,IAAS,EAAE,iBAA8B;QACvE,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;YAAE,OAAO;QAE9C,yBAAyB;QACzB,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YAC/B,wCAAwC;YACxC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;YAC1E,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;gBAChC,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACjC,CAAC;YACD,OAAO;QACT,CAAC;QAED,sDAAsD;QACtD,2DAA2D;QAC3D,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YAC7B,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACd,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC;gBAC1C,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;gBACtD,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;oBAC5B,IAAI,GAAG;wBAAE,IAAI,CAAC,uBAAuB,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;gBAChE,CAAC;YACH,CAAC;YACD,OAAO;QACT,CAAC;QAED,iEAAiE;QACjE,IAAI,IAAI,CAAC,IAAI;YAAE,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;QAC1E,IAAI,IAAI,CAAC,KAAK;YAAE,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC;QAE5E,+BAA+B;QAC/B,IAAI,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5C,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBAC9B,IAAI,CAAC,uBAAuB,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;YACxD,CAAC;QACH,CAAC;QAED,0BAA0B;QAC1B,IAAI,IAAI,CAAC,MAAM;YAAE,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;QAC9E,IAAI,IAAI,CAAC,IAAI;YAAE,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;QAE1E,kEAAkE;QAClE,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAChE,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;gBACvB,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;oBACnC,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;wBACd,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC;oBAC7D,CAAC;yBAAM,CAAC;wBACN,IAAI,CAAC,uBAAuB,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;oBACvD,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACK,iBAAiB,CACvB,WAAmB,EACnB,UAAkB,EAClB,UAAoB,EACpB,eAAyB,EACzB,aAAsB,EACtB,OAA0B,EAC1B,UAA8B;QAE9B,MAAM,UAAU,GAA0B,EAAE,CAAC;QAE7C,gDAAgD;QAChD,oDAAoD;QACpD,MAAM,YAAY,GAAG,+BAA+B,CAAC;QAErD,IAAI,KAAK,CAAC;QACV,MAAM,aAAa,GAAG,IAAI,GAAG,EAAU,CAAC;QAExC,OAAO,CAAC,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YACzD,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAE5B,oBAAoB;YACpB,IAAI,yBAAuB,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;gBACvE,SAAS;YACX,CAAC;YAED,kBAAkB;YAClB,IAAI,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;gBAChD,SAAS;YACX,CAAC;YACD,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC;YAE5C,wBAAwB;YACxB,IAAI,WAAW,GAAG,KAAK,CAAC;YACxB,IAAI,eAAe,GAAkB,IAAI,CAAC;YAE1C,IAAI,aAAa,EAAE,CAAC;gBAClB,WAAW,GAAG,UAAU,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;YAChD,CAAC;iBAAM,CAAC;gBACN,MAAM,KAAK,GAAG,eAAe,CAAC,OAAO,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC;gBAChE,WAAW,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC;gBAC3B,IAAI,WAAW,EAAE,CAAC;oBAChB,eAAe,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;gBACtC,CAAC;YACH,CAAC;YAED,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,MAAM,aAAa,GAAG,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;gBACrE,IAAI,UAAU,GAAG,EAAE,CAAC;gBAEpB,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC7B,UAAU,GAAG,iBAAiB,IAAI,CAAC,eAAe,CAAC,aAAa,EAAE,CAAC,CAAC,GAAG,CAAC;gBAC1E,CAAC;qBAAM,CAAC;oBACN,UAAU,GAAG,qBAAqB,IAAI,CAAC,eAAe,CAAC,UAAU,EAAE,EAAE,CAAC,EAAE,CAAC;gBAC3E,CAAC;gBAED,UAAU,CAAC,IAAI,CACb,IAAI,CAAC,eAAe,CAClB,yBAAyB,EACzB,IAAI,CAAC,kBAAkB,CACrB,UAAU,EACV,OAAO,EACP,2BAA2B,UAAU,+BAA+B,UAAU,IAAI,EAClF;oBACE,KAAK,EAAE,UAAU;oBACjB,UAAU;iBACX,CACF,EACD,MAAM,EAAE,mDAAmD;gBAC3D,UAAU,EACV;oBACE,KAAK,EAAE,UAAU;oBACjB,UAAU;oBACV,eAAe,EAAE,UAAU;oBAC3B,aAAa;oBACb,gBAAgB,EAAE,gBAAgB;iBACnC,CACF,CACF,CAAC;YACJ,CAAC;iBAAM,IAAI,CAAC,aAAa,IAAI,eAAe,IAAI,eAAe,KAAK,UAAU,EAAE,CAAC;gBAC/E,UAAU,CAAC,IAAI,CACb,IAAI,CAAC,eAAe,CAClB,eAAe,EACf,IAAI,CAAC,kBAAkB,CACrB,UAAU,EACV,OAAO,EACP,UAAU,UAAU,0DAA0D,eAAe,GAAG,EAChG;oBACE,KAAK,EAAE,UAAU;oBACjB,WAAW,EAAE,eAAe;oBAC5B,UAAU;iBACX,CACF,EACD,QAAQ,EACR,QAAQ,eAAe,iBAAiB,UAAU,GAAG,EACrD;oBACE,KAAK,EAAE,UAAU;oBACjB,WAAW,EAAE,eAAe;oBAC5B,UAAU;oBACV,gBAAgB,EAAE,gBAAgB;iBACnC,CACF,CACF,CAAC;YACJ,CAAC;QACH,CAAC;QAED,OAAO,UAAU,CAAC;IACpB,CAAC;IAED;;OAEG;IACH,cAAc;QACZ,OAAO,+EAA+E,CAAC;IACzF,CAAC;;AA3aU,0DAAuB;AAClC;;;GAGG;AACqB,oCAAY,GAAG,IAAI,GAAG,CAAC;IAC7C,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM;IACzD,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK;IACrE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM;IAC9B,8CAA8C;IAC9C,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa;IAC7D,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ;IACjD,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU;IAC9C,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS;IACtD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;IAC1C,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY;IAClD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK;IACnC,YAAY,EAAE,MAAM,EAAE,YAAY;CACnC,CAAC,AAbkC,CAajC;kCAlBQ,uBAAuB;IADnC,IAAA,sBAAa,EAAC,mDAAuB,EAAE,kBAAkB,CAAC;GAC9C,uBAAuB,CA4anC"}
|