@memberjunction/metadata-sync 2.129.0 → 2.130.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.
|
@@ -53,6 +53,12 @@ class RecordDependencyAnalyzer {
|
|
|
53
53
|
const record = records[i];
|
|
54
54
|
const recordId = `${entityName}_${this.recordCounter++}`;
|
|
55
55
|
const path = pathPrefix ? `${pathPrefix}/${entityName}[${i}]` : `${entityName}[${i}]`;
|
|
56
|
+
// Validate that the record has a 'fields' property (required)
|
|
57
|
+
if (!record.fields) {
|
|
58
|
+
const hint = 'field' in record ? ' Did you mean "fields" instead of "field"?' : '';
|
|
59
|
+
throw new Error(`Record at ${path} is missing required "fields" property.${hint} ` +
|
|
60
|
+
`Each record must have a "fields" object containing the entity field values.`);
|
|
61
|
+
}
|
|
56
62
|
const flattenedRecord = {
|
|
57
63
|
record,
|
|
58
64
|
entityName,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"record-dependency-analyzer.js","sourceRoot":"","sources":["../../src/lib/record-dependency-analyzer.ts"],"names":[],"mappings":"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","sourcesContent":["import { Metadata, EntityInfo } from '@memberjunction/core';\nimport { RecordData } from './sync-engine';\nimport { METADATA_KEYWORDS, isNonKeywordAtSymbol } from '../constants/metadata-keywords';\n\n/**\n * Represents a flattened record with its context and dependencies\n */\nexport interface FlattenedRecord {\n record: RecordData;\n entityName: string;\n parentContext?: {\n entityName: string;\n record: RecordData;\n recordIndex: number;\n };\n depth: number;\n path: string; // Path to this record for debugging\n dependencies: Set<string>; // Set of record IDs this record depends on\n id: string; // Unique identifier for this record in the flattened list\n originalIndex: number; // Original index in the source array\n}\n\n/**\n * Represents a reverse dependency relationship\n * (which records depend on a given record)\n */\nexport interface ReverseDependency {\n recordId: string; // The record being referenced\n dependentId: string; // The record that depends on it\n entityName: string; // Entity of the dependent\n fieldName: string | null; // Foreign key field name (if known)\n filePath: string; // Location of dependent record\n}\n\n/**\n * Result of dependency analysis\n */\nexport interface DependencyAnalysisResult {\n sortedRecords: FlattenedRecord[];\n circularDependencies: string[][];\n dependencyGraph: Map<string, Set<string>>;\n dependencyLevels?: FlattenedRecord[][]; // Records grouped by dependency level for parallel processing\n}\n\n/**\n * Analyzes and sorts records based on their dependencies\n */\nexport class RecordDependencyAnalyzer {\n private metadata: Metadata;\n private flattenedRecords: FlattenedRecord[] = [];\n private recordIdMap: Map<string, FlattenedRecord> = new Map();\n private entityInfoCache: Map<string, EntityInfo> = new Map();\n private recordCounter: number = 0;\n\n constructor() {\n this.metadata = new Metadata();\n }\n\n /**\n * Main entry point: analyzes all records in a file and returns them in dependency order\n */\n public async analyzeFileRecords(\n records: RecordData[],\n entityName: string\n ): Promise<DependencyAnalysisResult> {\n // Reset state\n this.flattenedRecords = [];\n this.recordIdMap.clear();\n this.recordCounter = 0;\n\n // Step 1: Flatten all records (including nested relatedEntities)\n this.flattenRecords(records, entityName);\n\n // Step 2: Analyze dependencies between all flattened records\n this.analyzeDependencies();\n\n // Step 3: Detect circular dependencies\n const circularDeps = this.detectCircularDependencies();\n\n // Step 4: Perform topological sort\n const sortedRecords = this.topologicalSort();\n\n // Step 5: Build dependency graph for debugging\n const dependencyGraph = new Map<string, Set<string>>();\n for (const record of this.flattenedRecords) {\n dependencyGraph.set(record.id, record.dependencies);\n }\n\n // Step 6: Group records into dependency levels for parallel processing\n const dependencyLevels = this.groupByDependencyLevels(sortedRecords, dependencyGraph);\n\n return {\n sortedRecords,\n circularDependencies: circularDeps,\n dependencyGraph,\n dependencyLevels\n };\n }\n\n /**\n * Flattens all records including nested relatedEntities\n */\n private flattenRecords(\n records: RecordData[],\n entityName: string,\n parentContext?: FlattenedRecord['parentContext'],\n depth: number = 0,\n pathPrefix: string = '',\n parentRecordId?: string\n ): void {\n for (let i = 0; i < records.length; i++) {\n const record = records[i];\n const recordId = `${entityName}_${this.recordCounter++}`;\n const path = pathPrefix ? `${pathPrefix}/${entityName}[${i}]` : `${entityName}[${i}]`;\n\n const flattenedRecord: FlattenedRecord = {\n record,\n entityName,\n parentContext,\n depth,\n path,\n dependencies: new Set(),\n id: recordId,\n originalIndex: i\n };\n\n // If this has a parent, add dependency on the parent\n if (parentRecordId) {\n flattenedRecord.dependencies.add(parentRecordId);\n }\n\n this.flattenedRecords.push(flattenedRecord);\n this.recordIdMap.set(recordId, flattenedRecord);\n\n // Recursively flatten related entities\n if (record.relatedEntities) {\n for (const [relatedEntityName, relatedRecords] of Object.entries(record.relatedEntities)) {\n this.flattenRecords(\n relatedRecords,\n relatedEntityName,\n {\n entityName,\n record,\n recordIndex: i\n },\n depth + 1,\n path,\n recordId // Pass current record ID as parent for children\n );\n }\n }\n }\n }\n\n /**\n * Analyzes dependencies between all flattened records\n */\n private analyzeDependencies(): void {\n for (const record of this.flattenedRecords) {\n // Get entity info for foreign key relationships\n const entityInfo = this.getEntityInfo(record.entityName);\n if (!entityInfo) continue;\n\n // Analyze field dependencies\n if (record.record.fields) {\n for (const [fieldName, fieldValue] of Object.entries(record.record.fields)) {\n if (typeof fieldValue === 'string') {\n // Handle @lookup references\n if (fieldValue.startsWith(METADATA_KEYWORDS.LOOKUP)) {\n const dependency = this.findLookupDependency(fieldValue, record);\n if (dependency) {\n record.dependencies.add(dependency);\n }\n }\n // Handle @root references - these create dependencies on the root record\n else if (fieldValue.startsWith(METADATA_KEYWORDS.ROOT)) {\n const rootDependency = this.findRootDependency(record);\n if (rootDependency) {\n record.dependencies.add(rootDependency);\n }\n }\n // @parent references don't create explicit dependencies in our flattened structure\n // because parent is guaranteed to be processed before children due to the way\n // we flatten records (parent always comes before its children)\n }\n }\n }\n\n // Check foreign key dependencies\n this.analyzeForeignKeyDependencies(record, entityInfo);\n }\n }\n\n /**\n * Analyzes foreign key dependencies based on EntityInfo\n */\n private analyzeForeignKeyDependencies(record: FlattenedRecord, entityInfo: EntityInfo): void {\n // Check all foreign key fields\n for (const field of entityInfo.ForeignKeys) {\n const fieldValue = record.record.fields?.[field.Name];\n if (fieldValue && typeof fieldValue === 'string' && !fieldValue.startsWith('@')) {\n // This is a direct foreign key value, find the referenced record\n const relatedEntityInfo = this.getEntityInfo(field.RelatedEntity);\n if (relatedEntityInfo) {\n const dependency = this.findRecordByPrimaryKey(\n field.RelatedEntity,\n fieldValue,\n relatedEntityInfo\n );\n if (dependency) {\n record.dependencies.add(dependency);\n }\n }\n }\n }\n }\n\n /**\n * Finds a record that matches a @lookup reference\n */\n private findLookupDependency(lookupValue: string, currentRecord: FlattenedRecord): string | null {\n // Parse lookup format: @lookup:EntityName.Field=Value or @lookup:Field=Value\n const lookupStr = lookupValue.substring(8); // Remove '@lookup:'\n \n // Handle the ?create syntax by removing it\n const cleanLookup = lookupStr.split('?')[0];\n \n // Parse entity name if present\n let targetEntity: string;\n let criteria: string;\n \n if (cleanLookup.includes('.')) {\n const parts = cleanLookup.split('.');\n targetEntity = parts[0];\n criteria = parts.slice(1).join('.');\n } else {\n // Same entity if not specified\n targetEntity = currentRecord.entityName;\n criteria = cleanLookup;\n }\n\n // Parse criteria (can be multiple with &)\n const criteriaMap = new Map<string, string>();\n for (const pair of criteria.split('&')) {\n const [field, value] = pair.split('=');\n if (field && value) {\n let resolvedValue = value.trim();\n \n // Special handling for nested @lookup references in lookup criteria\n // This creates a dependency on the looked-up record\n if (resolvedValue.startsWith(METADATA_KEYWORDS.LOOKUP)) {\n const nestedDependency = this.findLookupDependency(resolvedValue, currentRecord);\n if (nestedDependency) {\n // Add this as a dependency of the current record\n currentRecord.dependencies.add(nestedDependency);\n // Continue processing - we can't resolve the actual value here\n // but we've recorded the dependency\n }\n }\n // Special handling for @root references in lookup criteria\n else if (resolvedValue.startsWith(METADATA_KEYWORDS.ROOT)) {\n // Add dependency on root record\n const rootDep = this.findRootDependency(currentRecord);\n if (rootDep) {\n currentRecord.dependencies.add(rootDep);\n }\n // Note: We can't resolve the actual value here, but we've recorded the dependency\n }\n // Special handling for @parent references in lookup criteria\n // If the value is @parent:field, we need to resolve it from the parent context\n else if (resolvedValue.startsWith(METADATA_KEYWORDS.PARENT) && currentRecord.parentContext) {\n const parentField = resolvedValue.substring(METADATA_KEYWORDS.PARENT.length);\n \n // Try to resolve from parent context\n const parentValue = currentRecord.parentContext.record.fields?.[parentField] ||\n currentRecord.parentContext.record.primaryKey?.[parentField];\n \n if (parentValue && typeof parentValue === 'string') {\n // Check if parent value is also a @parent reference (nested parent refs)\n if (parentValue.startsWith(METADATA_KEYWORDS.PARENT)) {\n // Find the parent record to get its parent context\n const parentRecord = this.flattenedRecords.find(r =>\n r.record === currentRecord.parentContext!.record &&\n r.entityName === currentRecord.parentContext!.entityName\n );\n\n if (parentRecord && parentRecord.parentContext) {\n const grandParentField = parentValue.substring(METADATA_KEYWORDS.PARENT.length);\n const grandParentValue = parentRecord.parentContext.record.fields?.[grandParentField] ||\n parentRecord.parentContext.record.primaryKey?.[grandParentField];\n if (grandParentValue && typeof grandParentValue === 'string' && !grandParentValue.startsWith('@')) {\n resolvedValue = grandParentValue;\n }\n }\n } else if (!parentValue.startsWith('@')) {\n resolvedValue = parentValue;\n }\n }\n }\n \n criteriaMap.set(field.trim(), resolvedValue);\n }\n }\n\n // Find matching record in our flattened list\n for (const candidate of this.flattenedRecords) {\n if (candidate.entityName !== targetEntity) continue;\n if (candidate.id === currentRecord.id) continue; // Skip self\n\n // Check if all criteria match\n let allMatch = true;\n for (const [field, value] of criteriaMap) {\n let candidateValue = candidate.record.fields?.[field] || \n candidate.record.primaryKey?.[field];\n let lookupValue = value;\n \n // Resolve candidate value if it's a @parent reference\n if (typeof candidateValue === 'string' && candidateValue.startsWith(METADATA_KEYWORDS.PARENT) && candidate.parentContext) {\n const parentField = candidateValue.substring(METADATA_KEYWORDS.PARENT.length);\n const parentRecord = candidate.parentContext.record;\n candidateValue = parentRecord.fields?.[parentField] || parentRecord.primaryKey?.[parentField];\n\n // If the parent field is also a @parent reference, resolve it recursively\n if (typeof candidateValue === 'string' && candidateValue.startsWith(METADATA_KEYWORDS.PARENT)) {\n // Find the candidate's parent in our flattened list\n const candidateParent = this.flattenedRecords.find(r => \n r.record === candidate.parentContext!.record && \n r.entityName === candidate.parentContext!.entityName\n );\n if (candidateParent?.parentContext) {\n const grandParentField = candidateValue.substring(8);\n candidateValue = candidateParent.parentContext.record.fields?.[grandParentField] || \n candidateParent.parentContext.record.primaryKey?.[grandParentField];\n }\n }\n }\n \n // Resolve lookup value if it contains @parent reference\n if (typeof lookupValue === 'string' && lookupValue.includes(METADATA_KEYWORDS.PARENT)) {\n // Handle cases like \"@parent:AgentID\" or embedded references\n if (lookupValue.startsWith(METADATA_KEYWORDS.PARENT) && currentRecord.parentContext) {\n const parentField = lookupValue.substring(METADATA_KEYWORDS.PARENT.length);\n lookupValue = currentRecord.parentContext.record.fields?.[parentField] ||\n currentRecord.parentContext.record.primaryKey?.[parentField];\n\n // If still a reference, try to resolve from the parent's parent\n if (typeof lookupValue === 'string' && lookupValue.startsWith(METADATA_KEYWORDS.PARENT)) {\n const currentParent = this.flattenedRecords.find(r =>\n r.record === currentRecord.parentContext!.record &&\n r.entityName === currentRecord.parentContext!.entityName\n );\n if (currentParent?.parentContext) {\n const grandParentField = lookupValue.substring(METADATA_KEYWORDS.PARENT.length);\n lookupValue = currentParent.parentContext.record.fields?.[grandParentField] ||\n currentParent.parentContext.record.primaryKey?.[grandParentField];\n }\n }\n }\n }\n\n // Special case: if both values are @parent references pointing to the same parent field,\n // and they have the same parent context, they match\n if (value.startsWith(METADATA_KEYWORDS.PARENT) && candidateValue === value && \n currentRecord.parentContext && candidate.parentContext) {\n // Check if they share the same parent\n if (currentRecord.parentContext.record === candidate.parentContext.record) {\n // Same parent, same reference - they will resolve to the same value\n continue; // This criterion matches\n }\n }\n \n if (candidateValue !== lookupValue) {\n allMatch = false;\n break;\n }\n }\n\n if (allMatch) {\n return candidate.id;\n }\n }\n\n return null;\n }\n\n /**\n * Finds the root record for a given record\n */\n private findRootDependency(record: FlattenedRecord): string | null {\n // If this record has no parent, it IS the root, no dependency\n if (!record.parentContext) {\n return null;\n }\n \n // Walk up the parent chain to find the root\n let current = record;\n while (current.parentContext) {\n // Try to find the parent record in our flattened list\n const parentRecord = this.flattenedRecords.find(r => \n r.record === current.parentContext!.record && \n r.entityName === current.parentContext!.entityName\n );\n \n if (!parentRecord) {\n // Parent not found, something is wrong\n return null;\n }\n \n // If this parent has no parent, it's the root\n if (!parentRecord.parentContext) {\n return parentRecord.id;\n }\n \n current = parentRecord;\n }\n \n return null;\n }\n\n /**\n * Finds a record by its primary key value\n */\n private findRecordByPrimaryKey(\n entityName: string,\n primaryKeyValue: string,\n entityInfo: EntityInfo\n ): string | null {\n // Get primary key field name\n const primaryKeyField = entityInfo.PrimaryKeys[0]?.Name;\n if (!primaryKeyField) return null;\n\n for (const candidate of this.flattenedRecords) {\n if (candidate.entityName !== entityName) continue;\n\n const candidateValue = candidate.record.primaryKey?.[primaryKeyField] ||\n candidate.record.fields?.[primaryKeyField];\n if (candidateValue === primaryKeyValue) {\n return candidate.id;\n }\n }\n\n return null;\n }\n\n /**\n * Gets EntityInfo from cache or metadata\n */\n private getEntityInfo(entityName: string): EntityInfo | null {\n if (!this.entityInfoCache.has(entityName)) {\n const info = this.metadata.EntityByName(entityName);\n if (info) {\n this.entityInfoCache.set(entityName, info);\n }\n }\n return this.entityInfoCache.get(entityName) || null;\n }\n\n /**\n * Detects circular dependencies in the dependency graph\n */\n private detectCircularDependencies(): string[][] {\n const cycles: string[][] = [];\n const visited = new Set<string>();\n const recursionStack = new Set<string>();\n\n const detectCycle = (recordId: string, path: string[]): boolean => {\n visited.add(recordId);\n recursionStack.add(recordId);\n path.push(recordId);\n\n const record = this.recordIdMap.get(recordId);\n if (record) {\n for (const depId of record.dependencies) {\n if (!visited.has(depId)) {\n if (detectCycle(depId, [...path])) {\n return true;\n }\n } else if (recursionStack.has(depId)) {\n // Found a cycle\n const cycleStart = path.indexOf(depId);\n const cycle = path.slice(cycleStart);\n cycle.push(depId); // Complete the cycle\n cycles.push(cycle);\n return true;\n }\n }\n }\n\n recursionStack.delete(recordId);\n return false;\n };\n\n // Check all records for cycles\n for (const record of this.flattenedRecords) {\n if (!visited.has(record.id)) {\n detectCycle(record.id, []);\n }\n }\n\n return cycles;\n }\n\n /**\n * Performs topological sort on the dependency graph\n */\n private topologicalSort(): FlattenedRecord[] {\n const result: FlattenedRecord[] = [];\n const visited = new Set<string>();\n const tempStack = new Set<string>();\n\n const visit = (recordId: string): boolean => {\n if (tempStack.has(recordId)) {\n // Circular dependency - we've already detected these\n return false;\n }\n\n if (visited.has(recordId)) {\n return true;\n }\n\n tempStack.add(recordId);\n\n const record = this.recordIdMap.get(recordId);\n if (record) {\n // Visit dependencies first\n for (const depId of record.dependencies) {\n visit(depId);\n }\n }\n\n tempStack.delete(recordId);\n visited.add(recordId);\n \n if (record) {\n result.push(record);\n }\n\n return true;\n };\n\n // Process all records, starting with those that have no dependencies\n // First, process records with no dependencies\n for (const record of this.flattenedRecords) {\n if (record.dependencies.size === 0 && !visited.has(record.id)) {\n visit(record.id);\n }\n }\n\n // Then process any remaining records (handles disconnected components)\n for (const record of this.flattenedRecords) {\n if (!visited.has(record.id)) {\n visit(record.id);\n }\n }\n\n return result;\n }\n\n /**\n * Groups sorted records into dependency levels for parallel processing\n * Records in the same level have no dependencies on each other and can be processed in parallel\n */\n private groupByDependencyLevels(\n sortedRecords: FlattenedRecord[],\n dependencyGraph: Map<string, Set<string>>\n ): FlattenedRecord[][] {\n const levels: FlattenedRecord[][] = [];\n const recordLevels = new Map<string, number>();\n \n // Calculate the level for each record\n for (const record of sortedRecords) {\n let maxDependencyLevel = -1;\n \n // Find the maximum level of all dependencies\n for (const depId of record.dependencies) {\n const depLevel = recordLevels.get(depId);\n if (depLevel !== undefined && depLevel > maxDependencyLevel) {\n maxDependencyLevel = depLevel;\n }\n }\n \n // This record's level is one more than its highest dependency\n const recordLevel = maxDependencyLevel + 1;\n recordLevels.set(record.id, recordLevel);\n \n // Add to the appropriate level array\n if (!levels[recordLevel]) {\n levels[recordLevel] = [];\n }\n levels[recordLevel].push(record);\n }\n \n return levels;\n }\n\n /**\n * Build reverse dependency map from forward dependencies\n * Maps: record ID -> list of records that depend on it\n *\n * This is essential for deletion ordering - we need to know what depends on a record\n * before we can safely delete it.\n */\n public buildReverseDependencyMap(\n records: FlattenedRecord[]\n ): Map<string, ReverseDependency[]> {\n const reverseMap = new Map<string, ReverseDependency[]>();\n\n for (const record of records) {\n // For each dependency this record has...\n for (const depId of record.dependencies) {\n // Add this record as a dependent of that dependency\n if (!reverseMap.has(depId)) {\n reverseMap.set(depId, []);\n }\n\n reverseMap.get(depId)!.push({\n recordId: depId,\n dependentId: record.id,\n entityName: record.entityName,\n fieldName: this.findForeignKeyFieldForDependency(record, depId),\n filePath: record.path\n });\n }\n }\n\n return reverseMap;\n }\n\n /**\n * Find the foreign key field that creates a dependency\n * Used for better error reporting\n */\n private findForeignKeyFieldForDependency(\n record: FlattenedRecord,\n dependencyId: string\n ): string | null {\n const entityInfo = this.getEntityInfo(record.entityName);\n if (!entityInfo) return null;\n\n const dependentRecord = this.recordIdMap.get(dependencyId);\n if (!dependentRecord) return null;\n\n // Check all foreign key fields\n for (const field of entityInfo.ForeignKeys) {\n const fieldValue = record.record.fields?.[field.Name];\n\n // Check if this field references the dependent record\n if (fieldValue && typeof fieldValue === 'string') {\n // Handle @lookup references\n if (fieldValue.startsWith(METADATA_KEYWORDS.LOOKUP)) {\n const resolvedDep = this.findLookupDependency(fieldValue, record);\n if (resolvedDep === dependencyId) {\n return field.Name;\n }\n }\n // Handle direct foreign key values\n else if (!fieldValue.startsWith('@')) {\n const relatedEntityInfo = this.getEntityInfo(field.RelatedEntity);\n if (relatedEntityInfo) {\n const dep = this.findRecordByPrimaryKey(\n field.RelatedEntity,\n fieldValue,\n relatedEntityInfo\n );\n if (dep === dependencyId) {\n return field.Name;\n }\n }\n }\n }\n }\n\n return null;\n }\n\n /**\n * Perform reverse topological sort for deletion order\n * Returns records grouped by dependency level, with leaf nodes (highest dependency level) first\n *\n * For deletions, we want to delete in reverse order of creation:\n * - Records at highest forward dependency levels (leaf nodes) delete FIRST\n * - Records at level 0 (root nodes with no dependencies) delete LAST\n *\n * This is simply the reverse of the forward topological sort used for creates.\n */\n public reverseTopologicalSort(\n records: FlattenedRecord[],\n reverseDependencies: Map<string, ReverseDependency[]>\n ): FlattenedRecord[][] {\n // Calculate forward dependency levels (same as creation order)\n const recordLevels = new Map<string, number>();\n\n // Calculate the level for each record based on its FORWARD dependencies\n for (const record of records) {\n let maxDependencyLevel = -1;\n\n // Find the maximum level of all dependencies (things this record depends ON)\n for (const depId of record.dependencies) {\n const depLevel = recordLevels.get(depId);\n if (depLevel !== undefined && depLevel > maxDependencyLevel) {\n maxDependencyLevel = depLevel;\n }\n }\n\n // This record's level is one more than its highest dependency\n const recordLevel = maxDependencyLevel + 1;\n recordLevels.set(record.id, recordLevel);\n }\n\n // Group records by level\n const forwardLevels: FlattenedRecord[][] = [];\n for (const record of records) {\n const level = recordLevels.get(record.id) || 0;\n\n if (!forwardLevels[level]) {\n forwardLevels[level] = [];\n }\n forwardLevels[level].push(record);\n }\n\n // Reverse the array for deletion order\n // Forward level 0 (roots) becomes last to delete\n // Forward level N (leaves) becomes first to delete\n return forwardLevels.reverse();\n }\n\n /**\n * Find all transitive dependents of a set of records\n * This is useful for finding all records that must be deleted when deleting a parent\n *\n * @param recordIds Set of record IDs to find dependents for\n * @param reverseDependencies Reverse dependency map\n * @returns Set of all record IDs that depend on the input records (transitively)\n */\n public findTransitiveDependents(\n recordIds: Set<string>,\n reverseDependencies: Map<string, ReverseDependency[]>\n ): Set<string> {\n const dependents = new Set<string>();\n const visited = new Set<string>();\n\n // BFS to find all transitive dependents\n const queue = Array.from(recordIds);\n\n while (queue.length > 0) {\n const recordId = queue.shift()!;\n if (visited.has(recordId)) continue;\n visited.add(recordId);\n\n const deps = reverseDependencies.get(recordId) || [];\n\n for (const dep of deps) {\n // Add dependent to result set\n dependents.add(dep.dependentId);\n\n // Queue for processing its dependents\n queue.push(dep.dependentId);\n }\n }\n\n return dependents;\n }\n}"]}
|
|
1
|
+
{"version":3,"file":"record-dependency-analyzer.js","sourceRoot":"","sources":["../../src/lib/record-dependency-analyzer.ts"],"names":[],"mappings":"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","sourcesContent":["import { Metadata, EntityInfo } from '@memberjunction/core';\nimport { RecordData } from './sync-engine';\nimport { METADATA_KEYWORDS, isNonKeywordAtSymbol } from '../constants/metadata-keywords';\n\n/**\n * Represents a flattened record with its context and dependencies\n */\nexport interface FlattenedRecord {\n record: RecordData;\n entityName: string;\n parentContext?: {\n entityName: string;\n record: RecordData;\n recordIndex: number;\n };\n depth: number;\n path: string; // Path to this record for debugging\n dependencies: Set<string>; // Set of record IDs this record depends on\n id: string; // Unique identifier for this record in the flattened list\n originalIndex: number; // Original index in the source array\n}\n\n/**\n * Represents a reverse dependency relationship\n * (which records depend on a given record)\n */\nexport interface ReverseDependency {\n recordId: string; // The record being referenced\n dependentId: string; // The record that depends on it\n entityName: string; // Entity of the dependent\n fieldName: string | null; // Foreign key field name (if known)\n filePath: string; // Location of dependent record\n}\n\n/**\n * Result of dependency analysis\n */\nexport interface DependencyAnalysisResult {\n sortedRecords: FlattenedRecord[];\n circularDependencies: string[][];\n dependencyGraph: Map<string, Set<string>>;\n dependencyLevels?: FlattenedRecord[][]; // Records grouped by dependency level for parallel processing\n}\n\n/**\n * Analyzes and sorts records based on their dependencies\n */\nexport class RecordDependencyAnalyzer {\n private metadata: Metadata;\n private flattenedRecords: FlattenedRecord[] = [];\n private recordIdMap: Map<string, FlattenedRecord> = new Map();\n private entityInfoCache: Map<string, EntityInfo> = new Map();\n private recordCounter: number = 0;\n\n constructor() {\n this.metadata = new Metadata();\n }\n\n /**\n * Main entry point: analyzes all records in a file and returns them in dependency order\n */\n public async analyzeFileRecords(\n records: RecordData[],\n entityName: string\n ): Promise<DependencyAnalysisResult> {\n // Reset state\n this.flattenedRecords = [];\n this.recordIdMap.clear();\n this.recordCounter = 0;\n\n // Step 1: Flatten all records (including nested relatedEntities)\n this.flattenRecords(records, entityName);\n\n // Step 2: Analyze dependencies between all flattened records\n this.analyzeDependencies();\n\n // Step 3: Detect circular dependencies\n const circularDeps = this.detectCircularDependencies();\n\n // Step 4: Perform topological sort\n const sortedRecords = this.topologicalSort();\n\n // Step 5: Build dependency graph for debugging\n const dependencyGraph = new Map<string, Set<string>>();\n for (const record of this.flattenedRecords) {\n dependencyGraph.set(record.id, record.dependencies);\n }\n\n // Step 6: Group records into dependency levels for parallel processing\n const dependencyLevels = this.groupByDependencyLevels(sortedRecords, dependencyGraph);\n\n return {\n sortedRecords,\n circularDependencies: circularDeps,\n dependencyGraph,\n dependencyLevels\n };\n }\n\n /**\n * Flattens all records including nested relatedEntities\n */\n private flattenRecords(\n records: RecordData[],\n entityName: string,\n parentContext?: FlattenedRecord['parentContext'],\n depth: number = 0,\n pathPrefix: string = '',\n parentRecordId?: string\n ): void {\n for (let i = 0; i < records.length; i++) {\n const record = records[i];\n const recordId = `${entityName}_${this.recordCounter++}`;\n const path = pathPrefix ? `${pathPrefix}/${entityName}[${i}]` : `${entityName}[${i}]`;\n\n // Validate that the record has a 'fields' property (required)\n if (!record.fields) {\n const hint = 'field' in record ? ' Did you mean \"fields\" instead of \"field\"?' : '';\n throw new Error(\n `Record at ${path} is missing required \"fields\" property.${hint} ` +\n `Each record must have a \"fields\" object containing the entity field values.`\n );\n }\n\n const flattenedRecord: FlattenedRecord = {\n record,\n entityName,\n parentContext,\n depth,\n path,\n dependencies: new Set(),\n id: recordId,\n originalIndex: i\n };\n\n // If this has a parent, add dependency on the parent\n if (parentRecordId) {\n flattenedRecord.dependencies.add(parentRecordId);\n }\n\n this.flattenedRecords.push(flattenedRecord);\n this.recordIdMap.set(recordId, flattenedRecord);\n\n // Recursively flatten related entities\n if (record.relatedEntities) {\n for (const [relatedEntityName, relatedRecords] of Object.entries(record.relatedEntities)) {\n this.flattenRecords(\n relatedRecords,\n relatedEntityName,\n {\n entityName,\n record,\n recordIndex: i\n },\n depth + 1,\n path,\n recordId // Pass current record ID as parent for children\n );\n }\n }\n }\n }\n\n /**\n * Analyzes dependencies between all flattened records\n */\n private analyzeDependencies(): void {\n for (const record of this.flattenedRecords) {\n // Get entity info for foreign key relationships\n const entityInfo = this.getEntityInfo(record.entityName);\n if (!entityInfo) continue;\n\n // Analyze field dependencies\n if (record.record.fields) {\n for (const [fieldName, fieldValue] of Object.entries(record.record.fields)) {\n if (typeof fieldValue === 'string') {\n // Handle @lookup references\n if (fieldValue.startsWith(METADATA_KEYWORDS.LOOKUP)) {\n const dependency = this.findLookupDependency(fieldValue, record);\n if (dependency) {\n record.dependencies.add(dependency);\n }\n }\n // Handle @root references - these create dependencies on the root record\n else if (fieldValue.startsWith(METADATA_KEYWORDS.ROOT)) {\n const rootDependency = this.findRootDependency(record);\n if (rootDependency) {\n record.dependencies.add(rootDependency);\n }\n }\n // @parent references don't create explicit dependencies in our flattened structure\n // because parent is guaranteed to be processed before children due to the way\n // we flatten records (parent always comes before its children)\n }\n }\n }\n\n // Check foreign key dependencies\n this.analyzeForeignKeyDependencies(record, entityInfo);\n }\n }\n\n /**\n * Analyzes foreign key dependencies based on EntityInfo\n */\n private analyzeForeignKeyDependencies(record: FlattenedRecord, entityInfo: EntityInfo): void {\n // Check all foreign key fields\n for (const field of entityInfo.ForeignKeys) {\n const fieldValue = record.record.fields?.[field.Name];\n if (fieldValue && typeof fieldValue === 'string' && !fieldValue.startsWith('@')) {\n // This is a direct foreign key value, find the referenced record\n const relatedEntityInfo = this.getEntityInfo(field.RelatedEntity);\n if (relatedEntityInfo) {\n const dependency = this.findRecordByPrimaryKey(\n field.RelatedEntity,\n fieldValue,\n relatedEntityInfo\n );\n if (dependency) {\n record.dependencies.add(dependency);\n }\n }\n }\n }\n }\n\n /**\n * Finds a record that matches a @lookup reference\n */\n private findLookupDependency(lookupValue: string, currentRecord: FlattenedRecord): string | null {\n // Parse lookup format: @lookup:EntityName.Field=Value or @lookup:Field=Value\n const lookupStr = lookupValue.substring(8); // Remove '@lookup:'\n \n // Handle the ?create syntax by removing it\n const cleanLookup = lookupStr.split('?')[0];\n \n // Parse entity name if present\n let targetEntity: string;\n let criteria: string;\n \n if (cleanLookup.includes('.')) {\n const parts = cleanLookup.split('.');\n targetEntity = parts[0];\n criteria = parts.slice(1).join('.');\n } else {\n // Same entity if not specified\n targetEntity = currentRecord.entityName;\n criteria = cleanLookup;\n }\n\n // Parse criteria (can be multiple with &)\n const criteriaMap = new Map<string, string>();\n for (const pair of criteria.split('&')) {\n const [field, value] = pair.split('=');\n if (field && value) {\n let resolvedValue = value.trim();\n \n // Special handling for nested @lookup references in lookup criteria\n // This creates a dependency on the looked-up record\n if (resolvedValue.startsWith(METADATA_KEYWORDS.LOOKUP)) {\n const nestedDependency = this.findLookupDependency(resolvedValue, currentRecord);\n if (nestedDependency) {\n // Add this as a dependency of the current record\n currentRecord.dependencies.add(nestedDependency);\n // Continue processing - we can't resolve the actual value here\n // but we've recorded the dependency\n }\n }\n // Special handling for @root references in lookup criteria\n else if (resolvedValue.startsWith(METADATA_KEYWORDS.ROOT)) {\n // Add dependency on root record\n const rootDep = this.findRootDependency(currentRecord);\n if (rootDep) {\n currentRecord.dependencies.add(rootDep);\n }\n // Note: We can't resolve the actual value here, but we've recorded the dependency\n }\n // Special handling for @parent references in lookup criteria\n // If the value is @parent:field, we need to resolve it from the parent context\n else if (resolvedValue.startsWith(METADATA_KEYWORDS.PARENT) && currentRecord.parentContext) {\n const parentField = resolvedValue.substring(METADATA_KEYWORDS.PARENT.length);\n \n // Try to resolve from parent context\n const parentValue = currentRecord.parentContext.record.fields?.[parentField] ||\n currentRecord.parentContext.record.primaryKey?.[parentField];\n \n if (parentValue && typeof parentValue === 'string') {\n // Check if parent value is also a @parent reference (nested parent refs)\n if (parentValue.startsWith(METADATA_KEYWORDS.PARENT)) {\n // Find the parent record to get its parent context\n const parentRecord = this.flattenedRecords.find(r =>\n r.record === currentRecord.parentContext!.record &&\n r.entityName === currentRecord.parentContext!.entityName\n );\n\n if (parentRecord && parentRecord.parentContext) {\n const grandParentField = parentValue.substring(METADATA_KEYWORDS.PARENT.length);\n const grandParentValue = parentRecord.parentContext.record.fields?.[grandParentField] ||\n parentRecord.parentContext.record.primaryKey?.[grandParentField];\n if (grandParentValue && typeof grandParentValue === 'string' && !grandParentValue.startsWith('@')) {\n resolvedValue = grandParentValue;\n }\n }\n } else if (!parentValue.startsWith('@')) {\n resolvedValue = parentValue;\n }\n }\n }\n \n criteriaMap.set(field.trim(), resolvedValue);\n }\n }\n\n // Find matching record in our flattened list\n for (const candidate of this.flattenedRecords) {\n if (candidate.entityName !== targetEntity) continue;\n if (candidate.id === currentRecord.id) continue; // Skip self\n\n // Check if all criteria match\n let allMatch = true;\n for (const [field, value] of criteriaMap) {\n let candidateValue = candidate.record.fields?.[field] || \n candidate.record.primaryKey?.[field];\n let lookupValue = value;\n \n // Resolve candidate value if it's a @parent reference\n if (typeof candidateValue === 'string' && candidateValue.startsWith(METADATA_KEYWORDS.PARENT) && candidate.parentContext) {\n const parentField = candidateValue.substring(METADATA_KEYWORDS.PARENT.length);\n const parentRecord = candidate.parentContext.record;\n candidateValue = parentRecord.fields?.[parentField] || parentRecord.primaryKey?.[parentField];\n\n // If the parent field is also a @parent reference, resolve it recursively\n if (typeof candidateValue === 'string' && candidateValue.startsWith(METADATA_KEYWORDS.PARENT)) {\n // Find the candidate's parent in our flattened list\n const candidateParent = this.flattenedRecords.find(r => \n r.record === candidate.parentContext!.record && \n r.entityName === candidate.parentContext!.entityName\n );\n if (candidateParent?.parentContext) {\n const grandParentField = candidateValue.substring(8);\n candidateValue = candidateParent.parentContext.record.fields?.[grandParentField] || \n candidateParent.parentContext.record.primaryKey?.[grandParentField];\n }\n }\n }\n \n // Resolve lookup value if it contains @parent reference\n if (typeof lookupValue === 'string' && lookupValue.includes(METADATA_KEYWORDS.PARENT)) {\n // Handle cases like \"@parent:AgentID\" or embedded references\n if (lookupValue.startsWith(METADATA_KEYWORDS.PARENT) && currentRecord.parentContext) {\n const parentField = lookupValue.substring(METADATA_KEYWORDS.PARENT.length);\n lookupValue = currentRecord.parentContext.record.fields?.[parentField] ||\n currentRecord.parentContext.record.primaryKey?.[parentField];\n\n // If still a reference, try to resolve from the parent's parent\n if (typeof lookupValue === 'string' && lookupValue.startsWith(METADATA_KEYWORDS.PARENT)) {\n const currentParent = this.flattenedRecords.find(r =>\n r.record === currentRecord.parentContext!.record &&\n r.entityName === currentRecord.parentContext!.entityName\n );\n if (currentParent?.parentContext) {\n const grandParentField = lookupValue.substring(METADATA_KEYWORDS.PARENT.length);\n lookupValue = currentParent.parentContext.record.fields?.[grandParentField] ||\n currentParent.parentContext.record.primaryKey?.[grandParentField];\n }\n }\n }\n }\n\n // Special case: if both values are @parent references pointing to the same parent field,\n // and they have the same parent context, they match\n if (value.startsWith(METADATA_KEYWORDS.PARENT) && candidateValue === value && \n currentRecord.parentContext && candidate.parentContext) {\n // Check if they share the same parent\n if (currentRecord.parentContext.record === candidate.parentContext.record) {\n // Same parent, same reference - they will resolve to the same value\n continue; // This criterion matches\n }\n }\n \n if (candidateValue !== lookupValue) {\n allMatch = false;\n break;\n }\n }\n\n if (allMatch) {\n return candidate.id;\n }\n }\n\n return null;\n }\n\n /**\n * Finds the root record for a given record\n */\n private findRootDependency(record: FlattenedRecord): string | null {\n // If this record has no parent, it IS the root, no dependency\n if (!record.parentContext) {\n return null;\n }\n \n // Walk up the parent chain to find the root\n let current = record;\n while (current.parentContext) {\n // Try to find the parent record in our flattened list\n const parentRecord = this.flattenedRecords.find(r => \n r.record === current.parentContext!.record && \n r.entityName === current.parentContext!.entityName\n );\n \n if (!parentRecord) {\n // Parent not found, something is wrong\n return null;\n }\n \n // If this parent has no parent, it's the root\n if (!parentRecord.parentContext) {\n return parentRecord.id;\n }\n \n current = parentRecord;\n }\n \n return null;\n }\n\n /**\n * Finds a record by its primary key value\n */\n private findRecordByPrimaryKey(\n entityName: string,\n primaryKeyValue: string,\n entityInfo: EntityInfo\n ): string | null {\n // Get primary key field name\n const primaryKeyField = entityInfo.PrimaryKeys[0]?.Name;\n if (!primaryKeyField) return null;\n\n for (const candidate of this.flattenedRecords) {\n if (candidate.entityName !== entityName) continue;\n\n const candidateValue = candidate.record.primaryKey?.[primaryKeyField] ||\n candidate.record.fields?.[primaryKeyField];\n if (candidateValue === primaryKeyValue) {\n return candidate.id;\n }\n }\n\n return null;\n }\n\n /**\n * Gets EntityInfo from cache or metadata\n */\n private getEntityInfo(entityName: string): EntityInfo | null {\n if (!this.entityInfoCache.has(entityName)) {\n const info = this.metadata.EntityByName(entityName);\n if (info) {\n this.entityInfoCache.set(entityName, info);\n }\n }\n return this.entityInfoCache.get(entityName) || null;\n }\n\n /**\n * Detects circular dependencies in the dependency graph\n */\n private detectCircularDependencies(): string[][] {\n const cycles: string[][] = [];\n const visited = new Set<string>();\n const recursionStack = new Set<string>();\n\n const detectCycle = (recordId: string, path: string[]): boolean => {\n visited.add(recordId);\n recursionStack.add(recordId);\n path.push(recordId);\n\n const record = this.recordIdMap.get(recordId);\n if (record) {\n for (const depId of record.dependencies) {\n if (!visited.has(depId)) {\n if (detectCycle(depId, [...path])) {\n return true;\n }\n } else if (recursionStack.has(depId)) {\n // Found a cycle\n const cycleStart = path.indexOf(depId);\n const cycle = path.slice(cycleStart);\n cycle.push(depId); // Complete the cycle\n cycles.push(cycle);\n return true;\n }\n }\n }\n\n recursionStack.delete(recordId);\n return false;\n };\n\n // Check all records for cycles\n for (const record of this.flattenedRecords) {\n if (!visited.has(record.id)) {\n detectCycle(record.id, []);\n }\n }\n\n return cycles;\n }\n\n /**\n * Performs topological sort on the dependency graph\n */\n private topologicalSort(): FlattenedRecord[] {\n const result: FlattenedRecord[] = [];\n const visited = new Set<string>();\n const tempStack = new Set<string>();\n\n const visit = (recordId: string): boolean => {\n if (tempStack.has(recordId)) {\n // Circular dependency - we've already detected these\n return false;\n }\n\n if (visited.has(recordId)) {\n return true;\n }\n\n tempStack.add(recordId);\n\n const record = this.recordIdMap.get(recordId);\n if (record) {\n // Visit dependencies first\n for (const depId of record.dependencies) {\n visit(depId);\n }\n }\n\n tempStack.delete(recordId);\n visited.add(recordId);\n \n if (record) {\n result.push(record);\n }\n\n return true;\n };\n\n // Process all records, starting with those that have no dependencies\n // First, process records with no dependencies\n for (const record of this.flattenedRecords) {\n if (record.dependencies.size === 0 && !visited.has(record.id)) {\n visit(record.id);\n }\n }\n\n // Then process any remaining records (handles disconnected components)\n for (const record of this.flattenedRecords) {\n if (!visited.has(record.id)) {\n visit(record.id);\n }\n }\n\n return result;\n }\n\n /**\n * Groups sorted records into dependency levels for parallel processing\n * Records in the same level have no dependencies on each other and can be processed in parallel\n */\n private groupByDependencyLevels(\n sortedRecords: FlattenedRecord[],\n dependencyGraph: Map<string, Set<string>>\n ): FlattenedRecord[][] {\n const levels: FlattenedRecord[][] = [];\n const recordLevels = new Map<string, number>();\n \n // Calculate the level for each record\n for (const record of sortedRecords) {\n let maxDependencyLevel = -1;\n \n // Find the maximum level of all dependencies\n for (const depId of record.dependencies) {\n const depLevel = recordLevels.get(depId);\n if (depLevel !== undefined && depLevel > maxDependencyLevel) {\n maxDependencyLevel = depLevel;\n }\n }\n \n // This record's level is one more than its highest dependency\n const recordLevel = maxDependencyLevel + 1;\n recordLevels.set(record.id, recordLevel);\n \n // Add to the appropriate level array\n if (!levels[recordLevel]) {\n levels[recordLevel] = [];\n }\n levels[recordLevel].push(record);\n }\n \n return levels;\n }\n\n /**\n * Build reverse dependency map from forward dependencies\n * Maps: record ID -> list of records that depend on it\n *\n * This is essential for deletion ordering - we need to know what depends on a record\n * before we can safely delete it.\n */\n public buildReverseDependencyMap(\n records: FlattenedRecord[]\n ): Map<string, ReverseDependency[]> {\n const reverseMap = new Map<string, ReverseDependency[]>();\n\n for (const record of records) {\n // For each dependency this record has...\n for (const depId of record.dependencies) {\n // Add this record as a dependent of that dependency\n if (!reverseMap.has(depId)) {\n reverseMap.set(depId, []);\n }\n\n reverseMap.get(depId)!.push({\n recordId: depId,\n dependentId: record.id,\n entityName: record.entityName,\n fieldName: this.findForeignKeyFieldForDependency(record, depId),\n filePath: record.path\n });\n }\n }\n\n return reverseMap;\n }\n\n /**\n * Find the foreign key field that creates a dependency\n * Used for better error reporting\n */\n private findForeignKeyFieldForDependency(\n record: FlattenedRecord,\n dependencyId: string\n ): string | null {\n const entityInfo = this.getEntityInfo(record.entityName);\n if (!entityInfo) return null;\n\n const dependentRecord = this.recordIdMap.get(dependencyId);\n if (!dependentRecord) return null;\n\n // Check all foreign key fields\n for (const field of entityInfo.ForeignKeys) {\n const fieldValue = record.record.fields?.[field.Name];\n\n // Check if this field references the dependent record\n if (fieldValue && typeof fieldValue === 'string') {\n // Handle @lookup references\n if (fieldValue.startsWith(METADATA_KEYWORDS.LOOKUP)) {\n const resolvedDep = this.findLookupDependency(fieldValue, record);\n if (resolvedDep === dependencyId) {\n return field.Name;\n }\n }\n // Handle direct foreign key values\n else if (!fieldValue.startsWith('@')) {\n const relatedEntityInfo = this.getEntityInfo(field.RelatedEntity);\n if (relatedEntityInfo) {\n const dep = this.findRecordByPrimaryKey(\n field.RelatedEntity,\n fieldValue,\n relatedEntityInfo\n );\n if (dep === dependencyId) {\n return field.Name;\n }\n }\n }\n }\n }\n\n return null;\n }\n\n /**\n * Perform reverse topological sort for deletion order\n * Returns records grouped by dependency level, with leaf nodes (highest dependency level) first\n *\n * For deletions, we want to delete in reverse order of creation:\n * - Records at highest forward dependency levels (leaf nodes) delete FIRST\n * - Records at level 0 (root nodes with no dependencies) delete LAST\n *\n * This is simply the reverse of the forward topological sort used for creates.\n */\n public reverseTopologicalSort(\n records: FlattenedRecord[],\n reverseDependencies: Map<string, ReverseDependency[]>\n ): FlattenedRecord[][] {\n // Calculate forward dependency levels (same as creation order)\n const recordLevels = new Map<string, number>();\n\n // Calculate the level for each record based on its FORWARD dependencies\n for (const record of records) {\n let maxDependencyLevel = -1;\n\n // Find the maximum level of all dependencies (things this record depends ON)\n for (const depId of record.dependencies) {\n const depLevel = recordLevels.get(depId);\n if (depLevel !== undefined && depLevel > maxDependencyLevel) {\n maxDependencyLevel = depLevel;\n }\n }\n\n // This record's level is one more than its highest dependency\n const recordLevel = maxDependencyLevel + 1;\n recordLevels.set(record.id, recordLevel);\n }\n\n // Group records by level\n const forwardLevels: FlattenedRecord[][] = [];\n for (const record of records) {\n const level = recordLevels.get(record.id) || 0;\n\n if (!forwardLevels[level]) {\n forwardLevels[level] = [];\n }\n forwardLevels[level].push(record);\n }\n\n // Reverse the array for deletion order\n // Forward level 0 (roots) becomes last to delete\n // Forward level N (leaves) becomes first to delete\n return forwardLevels.reverse();\n }\n\n /**\n * Find all transitive dependents of a set of records\n * This is useful for finding all records that must be deleted when deleting a parent\n *\n * @param recordIds Set of record IDs to find dependents for\n * @param reverseDependencies Reverse dependency map\n * @returns Set of all record IDs that depend on the input records (transitively)\n */\n public findTransitiveDependents(\n recordIds: Set<string>,\n reverseDependencies: Map<string, ReverseDependency[]>\n ): Set<string> {\n const dependents = new Set<string>();\n const visited = new Set<string>();\n\n // BFS to find all transitive dependents\n const queue = Array.from(recordIds);\n\n while (queue.length > 0) {\n const recordId = queue.shift()!;\n if (visited.has(recordId)) continue;\n visited.add(recordId);\n\n const deps = reverseDependencies.get(recordId) || [];\n\n for (const dep of deps) {\n // Add dependent to result set\n dependents.add(dep.dependentId);\n\n // Queue for processing its dependents\n queue.push(dep.dependentId);\n }\n }\n\n return dependents;\n }\n}"]}
|
|
@@ -209,10 +209,23 @@ class ValidationService {
|
|
|
209
209
|
suggestion: 'Consider flattening the data structure or increasing maxNestingDepth',
|
|
210
210
|
});
|
|
211
211
|
}
|
|
212
|
-
// Validate fields
|
|
213
|
-
if (entityData.fields) {
|
|
214
|
-
|
|
212
|
+
// Validate that 'fields' property exists (required)
|
|
213
|
+
if (!entityData.fields) {
|
|
214
|
+
const context = parentContext
|
|
215
|
+
? `Related entity "${parentContext.field}" in ${parentContext.entity}`
|
|
216
|
+
: `Record`;
|
|
217
|
+
this.addError({
|
|
218
|
+
type: 'field',
|
|
219
|
+
severity: 'error',
|
|
220
|
+
entity: entityInfo.Name,
|
|
221
|
+
file: filePath,
|
|
222
|
+
message: `${context} is missing required "fields" property. Did you mean "fields" instead of "field"?`,
|
|
223
|
+
suggestion: 'Each record must have a "fields" object containing the entity field values',
|
|
224
|
+
});
|
|
225
|
+
return; // Can't continue validation without fields
|
|
215
226
|
}
|
|
227
|
+
// Validate fields
|
|
228
|
+
await this.validateFields(entityData.fields, entityInfo, filePath, parentContext);
|
|
216
229
|
// Track dependencies
|
|
217
230
|
this.trackEntityDependencies(entityData, entityInfo.Name, filePath);
|
|
218
231
|
// Validate related entities
|
|
@@ -884,11 +897,13 @@ class ValidationService {
|
|
|
884
897
|
*/
|
|
885
898
|
async getMatchingFiles(dir, pattern) {
|
|
886
899
|
const files = fs.readdirSync(dir).filter((f) => fs.statSync(path.join(dir, f)).isFile());
|
|
900
|
+
// Strip leading **/ from glob patterns (we only match in current directory)
|
|
901
|
+
const normalizedPattern = pattern.replace(/^\*\*\//, '');
|
|
887
902
|
// Simple glob pattern matching
|
|
888
|
-
if (
|
|
903
|
+
if (normalizedPattern === '*.json') {
|
|
889
904
|
return files.filter((f) => f.endsWith('.json') && !f.startsWith('.mj-'));
|
|
890
905
|
}
|
|
891
|
-
else if (
|
|
906
|
+
else if (normalizedPattern === '.*.json') {
|
|
892
907
|
return files.filter((f) => f.startsWith('.') && f.endsWith('.json') && !f.startsWith('.mj-'));
|
|
893
908
|
}
|
|
894
909
|
return files;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ValidationService.js","sourceRoot":"","sources":["../../src/services/ValidationService.ts"],"names":[],"mappings":"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","sourcesContent":["import { EntityFieldInfo, EntityInfo, Metadata, RunView } from '@memberjunction/core';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport {\n ValidationResult,\n ValidationError,\n ValidationWarning,\n ValidationOptions,\n FileValidationResult,\n EntityDependency,\n ParsedReference,\n ReferenceType,\n} from '../types/validation';\nimport { RecordData } from '../lib/sync-engine';\nimport { getSystemUser } from '../lib/provider-utils';\nimport {\n METADATA_KEYWORDS,\n METADATA_KEYWORD_PREFIXES,\n isMetadataKeyword,\n getMetadataKeywordType,\n extractKeywordValue\n} from '../constants/metadata-keywords';\n\n// Type aliases for clarity\ntype EntityData = RecordData;\ntype EntitySyncConfig = any;\n\nexport class ValidationService {\n private metadata: Metadata;\n private errors: ValidationError[] = [];\n private warnings: ValidationWarning[] = [];\n private entityDependencies: Map<string, EntityDependency> = new Map();\n private processedEntities: Set<string> = new Set();\n private options: ValidationOptions;\n private userRoleCache: Map<string, string[]> = new Map();\n\n constructor(options: Partial<ValidationOptions> = {}) {\n this.metadata = new Metadata();\n this.options = {\n verbose: false,\n outputFormat: 'human',\n maxNestingDepth: 10,\n checkBestPractices: true,\n ...options,\n };\n }\n\n /**\n * Validates all metadata files in the specified directory\n */\n public async validateDirectory(dir: string): Promise<ValidationResult> {\n // Validate that include and exclude are not used together\n if (this.options.include && this.options.exclude) {\n throw new Error('Cannot specify both --include and --exclude options. Please use one or the other.');\n }\n\n this.reset();\n\n const configPath = path.join(dir, '.mj-sync.json');\n if (!fs.existsSync(configPath)) {\n this.addError({\n type: 'entity',\n severity: 'error',\n file: dir,\n message: 'No .mj-sync.json configuration file found in directory',\n });\n return this.getResult();\n }\n\n const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));\n\n // Load user role configuration and cache if enabled\n if (config.userRoleValidation?.enabled) {\n await this.loadUserRoles();\n }\n\n const directories = await this.getDirectoriesInOrder(dir, config);\n\n let totalFiles = 0;\n let totalEntities = 0;\n const fileResults = new Map<string, FileValidationResult>();\n\n for (const subDir of directories) {\n const subDirPath = path.join(dir, subDir);\n const result = await this.validateEntityDirectory(subDirPath);\n if (result) {\n totalFiles += result.files;\n totalEntities += result.entities;\n for (const [file, fileResult] of result.fileResults) {\n fileResults.set(file, fileResult);\n }\n }\n }\n\n // Validate dependency order\n await this.validateDependencyOrder(directories);\n\n return {\n isValid: this.errors.length === 0,\n errors: this.errors,\n warnings: this.warnings,\n summary: {\n totalFiles,\n totalEntities,\n totalErrors: this.errors.length,\n totalWarnings: this.warnings.length,\n fileResults,\n },\n };\n }\n\n /**\n * Validates a single entity directory\n */\n private async validateEntityDirectory(dir: string): Promise<{ files: number; entities: number; fileResults: Map<string, FileValidationResult> } | null> {\n // Check for .mj-folder.json first (new format)\n let configPath = path.join(dir, '.mj-folder.json');\n let config: any;\n \n if (fs.existsSync(configPath)) {\n config = JSON.parse(fs.readFileSync(configPath, 'utf8'));\n // .mj-folder.json uses entityName field\n if (!config.entityName) {\n this.addError({\n type: 'validation',\n severity: 'error',\n file: configPath,\n message: 'Missing entityName field in .mj-folder.json',\n });\n return null;\n }\n config.entity = config.entityName; // Normalize to entity field\n } else {\n // Fall back to .mj-sync.json (legacy format)\n configPath = path.join(dir, '.mj-sync.json');\n if (!fs.existsSync(configPath)) {\n return null;\n }\n config = JSON.parse(fs.readFileSync(configPath, 'utf8'));\n }\n\n // Validate entity name exists\n if (!config.entity || config.entity.trim() === '') {\n this.addError({\n type: 'validation',\n severity: 'error',\n file: configPath,\n message: 'Entity name is empty or missing',\n });\n return null;\n }\n\n const entityInfo = this.metadata.EntityByName(config.entity);\n\n if (!entityInfo) {\n this.addError({\n type: 'entity',\n severity: 'error',\n file: configPath,\n message: `Entity \"${config.entity}\" not found in metadata`,\n });\n return null;\n }\n\n const files = await this.getMatchingFiles(dir, config.filePattern);\n let totalEntities = 0;\n const fileResults = new Map<string, FileValidationResult>();\n\n for (const file of files) {\n const filePath = path.join(dir, file);\n const result = await this.validateFile(filePath, entityInfo, config);\n totalEntities += result.entityCount;\n fileResults.set(filePath, result);\n }\n\n return { files: files.length, entities: totalEntities, fileResults };\n }\n\n /**\n * Validates a single metadata file\n */\n private async validateFile(filePath: string, entityInfo: any, config: EntitySyncConfig): Promise<FileValidationResult> {\n const fileErrors: ValidationError[] = [];\n let entityCount = 0;\n\n try {\n const content = fs.readFileSync(filePath, 'utf8');\n const data = JSON.parse(content);\n const entities = Array.isArray(data) ? data : [data];\n entityCount = entities.length;\n\n for (const entityData of entities) {\n await this.validateEntityData(entityData, entityInfo, filePath, config);\n }\n } catch (error) {\n fileErrors.push({\n type: 'entity',\n severity: 'error',\n file: filePath,\n message: `Failed to parse JSON: ${error instanceof Error ? error.message : String(error)}`,\n });\n }\n\n // Collect errors and warnings for this file\n const currentFileErrors = this.errors.filter((e) => e.file === filePath);\n const currentFileWarnings = this.warnings.filter((w) => w.file === filePath);\n\n return {\n file: filePath,\n entityCount,\n errors: currentFileErrors,\n warnings: currentFileWarnings,\n };\n }\n\n /**\n * Validates a single entity data object\n */\n private async validateEntityData(\n entityData: EntityData,\n entityInfo: any,\n filePath: string,\n config: EntitySyncConfig,\n parentContext?: { entity: string; field: string },\n depth: number = 0,\n ): Promise<void> {\n // Check nesting depth\n if (depth > this.options.maxNestingDepth) {\n this.addWarning({\n type: 'nesting',\n severity: 'warning',\n entity: entityInfo.Name,\n file: filePath,\n message: `Nesting depth ${depth} exceeds recommended maximum of ${this.options.maxNestingDepth}`,\n suggestion: 'Consider flattening the data structure or increasing maxNestingDepth',\n });\n }\n\n // Validate fields\n if (entityData.fields) {\n await this.validateFields(entityData.fields, entityInfo, filePath, parentContext);\n }\n\n // Track dependencies\n this.trackEntityDependencies(entityData, entityInfo.Name, filePath);\n\n // Validate related entities\n if (entityData.relatedEntities) {\n for (const [relatedEntityName, relatedData] of Object.entries(entityData.relatedEntities)) {\n const relatedEntityInfo = this.metadata.EntityByName(relatedEntityName);\n if (!relatedEntityInfo) {\n this.addError({\n type: 'entity',\n severity: 'error',\n entity: entityInfo.Name,\n file: filePath,\n message: `Related entity \"${relatedEntityName}\" not found in metadata`,\n });\n continue;\n }\n\n const relatedEntities = Array.isArray(relatedData) ? relatedData : [relatedData];\n for (const relatedEntity of relatedEntities) {\n await this.validateEntityData(relatedEntity, relatedEntityInfo, filePath, config, { entity: entityInfo.Name, field: relatedEntityName }, depth + 1);\n }\n }\n }\n }\n\n /**\n * Validates entity fields\n */\n private async validateFields(\n fields: Record<string, any>,\n entityInfo: EntityInfo,\n filePath: string,\n parentContext?: { entity: string; field: string },\n ): Promise<void> {\n const entityFields = entityInfo.Fields;\n const fieldMap = new Map(entityFields.map((f) => [f.Name, f]));\n\n for (const [fieldName, fieldValue] of Object.entries(fields)) {\n const fieldInfo = fieldMap.get(fieldName);\n\n if (!fieldInfo) {\n // Check if this might be a virtual property (getter/setter)\n try {\n const entityInstance = await this.metadata.GetEntityObject(entityInfo.Name);\n // we use this approach instead of checking Entity Fields because\n // some sub-classes implement setter properties that allow you to set\n // values that are not physically in the database but are resolved by the sub-class\n // a good example is the sub-class for AI Prompts that has a property called TemplateText\n // that is automatically resolved into a separate record in the Templates/Template Contents entity\n const hasProperty = fieldName in entityInstance;\n\n if (!hasProperty) {\n this.addError({\n type: 'field',\n severity: 'error',\n entity: entityInfo.Name,\n field: fieldName,\n file: filePath,\n message: `Field \"${fieldName}\" does not exist on entity \"${entityInfo.Name}\"`,\n });\n continue;\n }\n\n continue;\n } catch (error) {\n // If we can't create an entity instance, fall back to error\n this.addError({\n type: 'field',\n severity: 'error',\n entity: entityInfo.Name,\n field: fieldName,\n file: filePath,\n message: `Field \"${fieldName}\" does not exist on entity \"${entityInfo.Name}\"`,\n });\n continue;\n }\n }\n\n // Check if field is settable (not system field)\n if (fieldInfo.ReadOnly || fieldName.startsWith('__mj_')) {\n this.addError({\n type: 'field',\n severity: 'error',\n entity: entityInfo.Name,\n field: fieldName,\n file: filePath,\n message: `Field \"${fieldName}\" is a read-only or system field and cannot be set`,\n suggestion: 'Remove this field from your metadata file',\n });\n continue;\n }\n\n // Validate field value and references\n await this.validateFieldValue(fieldValue, fieldInfo, entityInfo, filePath, parentContext);\n }\n\n // Check for required fields\n if (this.options.checkBestPractices) {\n for (const field of entityFields) {\n // Skip if field allows null or has a value already\n if (field.AllowsNull || fields[field.Name]) {\n continue;\n }\n\n // Skip if field has a default value\n if (field.DefaultValue !== null && field.DefaultValue !== undefined) {\n continue;\n }\n\n // Skip virtual/computed fields (foreign key reference fields)\n // These are typically named without 'ID' suffix but have a corresponding FK field\n const relatedEntityField = field.RelatedEntity;\n const correspondingFKField = entityFields.find((f: any) => f.Name === field.Name + 'ID' && f.IsForeignKey);\n if (relatedEntityField && correspondingFKField) {\n continue;\n }\n\n // Skip fields that are marked as AutoUpdateOnly or ReadOnly\n if (field.AutoIncrement || field.ReadOnly) {\n continue;\n }\n\n // Skip if this is a parent context and the field can be inherited\n if (parentContext && (field.Name === parentContext.field || field.Name === parentContext.field + 'ID')) {\n continue;\n }\n\n // Special case: Skip TemplateID if TemplateText is provided (virtual property)\n if (field.Name === 'TemplateID' && fields['TemplateText']) {\n continue;\n }\n\n // Skip Template field if TemplateText is provided\n if (field.Name === 'Template' && fields['TemplateText']) {\n continue;\n }\n\n this.addWarning({\n type: 'bestpractice',\n severity: 'warning',\n entity: entityInfo.Name,\n field: field.Name,\n file: filePath,\n message: `Required field \"${field.Name}\" is missing`,\n suggestion: `Add \"${field.Name}\" to the fields object`,\n });\n }\n }\n }\n\n /**\n * Validates field values and references\n */\n private async validateFieldValue(\n value: any,\n fieldInfo: EntityFieldInfo,\n entityInfo: EntityInfo,\n filePath: string,\n parentContext?: { entity: string; field: string },\n ): Promise<void> {\n if (typeof value === 'string' && this.isValidReference(value)) {\n await this.validateReference(value, fieldInfo, entityInfo, filePath, parentContext);\n // Skip further validation for references as they will be resolved later\n return;\n }\n\n // Validate field value against value list if applicable\n await this.validateFieldValueList(value, fieldInfo, entityInfo, filePath);\n\n // Validate UserID fields against allowed roles\n if (fieldInfo.Name === 'UserID' && typeof value === 'string' && value.length > 0) {\n // Get the sync config from the file's directory\n const dir = path.dirname(filePath);\n\n // Walk up to find the root sync config with userRoleValidation\n let currentDir = dir;\n let config = null;\n while (currentDir && currentDir !== path.parse(currentDir).root) {\n const currentConfigPath = path.join(currentDir, '.mj-sync.json');\n if (fs.existsSync(currentConfigPath)) {\n try {\n const currentConfig = JSON.parse(fs.readFileSync(currentConfigPath, 'utf8'));\n if (currentConfig.userRoleValidation) {\n config = currentConfig;\n break;\n }\n } catch {\n // Ignore parse errors\n }\n }\n currentDir = path.dirname(currentDir);\n }\n\n if (config?.userRoleValidation?.enabled) {\n await this.validateUserRole(value, entityInfo.Name, fieldInfo.Name, filePath, config);\n }\n }\n\n // Add other type validation here if needed\n }\n\n /**\n * Validates field value against the field's value list if applicable\n */\n private async validateFieldValueList(\n value: any,\n fieldInfo: EntityFieldInfo,\n entityInfo: EntityInfo,\n filePath: string\n ): Promise<void> {\n // Skip validation if value is null/undefined (handled by required field check)\n if (value === null || value === undefined || value === '') {\n return;\n }\n\n // Check if this field has a value list constraint\n if (fieldInfo.ValueListType !== 'List') {\n return;\n }\n\n // Get the allowed values from EntityFieldValues\n const entityFieldValues = fieldInfo.EntityFieldValues;\n if (!entityFieldValues || !Array.isArray(entityFieldValues) || entityFieldValues.length === 0) {\n // No values defined, skip validation\n return;\n }\n\n // Extract the allowed values\n const allowedValues = entityFieldValues.map((efv: any) => efv.Value);\n \n // Convert value to string for comparison (in case it's a number or boolean)\n const stringValue = String(value);\n \n // Check if the value is in the allowed list\n if (!allowedValues.includes(stringValue)) {\n // Check case-insensitive match as a warning\n const caseInsensitiveMatch = allowedValues.find((av: string) => \n av.toLowerCase() === stringValue.toLowerCase()\n );\n \n if (caseInsensitiveMatch) {\n this.addWarning({\n type: 'validation',\n severity: 'warning',\n entity: entityInfo.Name,\n field: fieldInfo.Name,\n file: filePath,\n message: `Field \"${fieldInfo.Name}\" has value \"${stringValue}\" which differs in case from allowed value \"${caseInsensitiveMatch}\"`,\n suggestion: `Use \"${caseInsensitiveMatch}\" for consistency`,\n });\n } else {\n // Format the allowed values list for display\n const allowedValuesList = allowedValues.length <= 10 \n ? allowedValues.join(', ')\n : allowedValues.slice(0, 10).join(', ') + `, ... (${allowedValues.length - 10} more)`;\n \n this.addError({\n type: 'field',\n severity: 'error',\n entity: entityInfo.Name,\n field: fieldInfo.Name,\n file: filePath,\n message: `Field \"${fieldInfo.Name}\" has invalid value \"${stringValue}\"`,\n suggestion: `Allowed values are: ${allowedValuesList}`,\n });\n }\n }\n }\n\n /**\n * Check if a string is actually a MetadataSync reference (not just any @ string)\n */\n private isValidReference(value: string): boolean {\n return isMetadataKeyword(value);\n }\n\n /**\n * Validates special references (@file:, @lookup:, etc.)\n */\n private async validateReference(\n reference: string,\n fieldInfo: EntityFieldInfo,\n entityInfo: EntityInfo,\n filePath: string,\n parentContext?: { entity: string; field: string },\n ): Promise<void> {\n const parsed = this.parseReference(reference);\n if (!parsed) {\n this.addError({\n type: 'reference',\n severity: 'error',\n entity: entityInfo.Name,\n field: fieldInfo.Name,\n file: filePath,\n message: `Invalid reference format: \"${reference}\"`,\n });\n return;\n }\n\n switch (parsed.type) {\n case METADATA_KEYWORDS.FILE:\n await this.validateFileReference(parsed.value, filePath, entityInfo.Name, fieldInfo.Name);\n break;\n case METADATA_KEYWORDS.LOOKUP:\n await this.validateLookupReference(parsed, filePath, entityInfo.Name, fieldInfo.Name);\n break;\n case METADATA_KEYWORDS.TEMPLATE:\n await this.validateTemplateReference(parsed.value, filePath, entityInfo.Name, fieldInfo.Name);\n break;\n case METADATA_KEYWORDS.PARENT:\n this.validateParentReference(parsed.value, parentContext, filePath, entityInfo.Name, fieldInfo.Name);\n break;\n case METADATA_KEYWORDS.ROOT:\n this.validateRootReference(parsed.value, parentContext, filePath, entityInfo.Name, fieldInfo.Name);\n break;\n }\n }\n\n /**\n * Parses a reference string\n */\n private parseReference(reference: string): ParsedReference | null {\n const patterns: [ReferenceType, RegExp][] = [\n [METADATA_KEYWORDS.FILE, /^@file:(.+)$/],\n [METADATA_KEYWORDS.LOOKUP, /^@lookup:([^.]+)\\.(.+)$/],\n [METADATA_KEYWORDS.TEMPLATE, /^@template:(.+)$/],\n [METADATA_KEYWORDS.PARENT, /^@parent:(.+)$/],\n [METADATA_KEYWORDS.ROOT, /^@root:(.+)$/],\n [METADATA_KEYWORDS.ENV, /^@env:(.+)$/],\n ];\n\n for (const [type, pattern] of patterns) {\n const match = reference.match(pattern);\n if (match) {\n if (type === METADATA_KEYWORDS.LOOKUP) {\n const [, entity, remaining] = match;\n \n // Check if this has ?create syntax\n const hasCreate = remaining.includes('?create');\n const lookupPart = hasCreate ? remaining.split('?')[0] : remaining;\n \n // Parse all lookup fields (can be multiple with &)\n const lookupPairs = lookupPart.split('&');\n const fields: Array<{field: string, value: string}> = [];\n \n for (const pair of lookupPairs) {\n const fieldMatch = pair.match(/^(.+?)=(.+)$/);\n if (fieldMatch) {\n const [, field, value] = fieldMatch;\n fields.push({ field: field.trim(), value: value.trim() });\n }\n }\n \n // For backward compatibility, use the first field as primary\n const primaryField = fields.length > 0 ? fields[0] : { field: '', value: '' };\n \n // Parse additional fields for creation if ?create is present\n const additionalFields: Record<string, any> = {};\n if (hasCreate && remaining.includes('?create&')) {\n const createPart = remaining.split('?create&')[1];\n const pairs = createPart.split('&');\n for (const pair of pairs) {\n const [key, val] = pair.split('=');\n if (key && val) {\n additionalFields[key] = decodeURIComponent(val);\n }\n }\n }\n\n return { \n type, \n value: primaryField.value, \n entity, \n field: primaryField.field,\n fields, // Include all fields for validation\n createIfMissing: hasCreate, \n additionalFields \n };\n }\n return { type, value: match[1] };\n }\n }\n\n return null;\n }\n\n /**\n * Validates @file: references\n */\n private async validateFileReference(filePath: string, sourceFile: string, entityName: string, fieldName: string, visitedFiles?: Set<string>): Promise<void> {\n const dir = path.dirname(sourceFile);\n const resolvedPath = path.resolve(dir, filePath);\n\n // Initialize visited files set if not provided (for circular reference detection)\n const visited = visitedFiles || new Set<string>();\n \n // Check for circular references\n if (visited.has(resolvedPath)) {\n this.addError({\n type: 'reference',\n severity: 'error',\n entity: entityName,\n field: fieldName,\n file: sourceFile,\n message: `Circular @file reference detected: \"${filePath}\"`,\n details: `Path ${resolvedPath} is already being processed`,\n suggestion: 'Restructure your file references to avoid circular dependencies',\n });\n return;\n }\n\n if (!fs.existsSync(resolvedPath)) {\n this.addError({\n type: 'reference',\n severity: 'error',\n entity: entityName,\n field: fieldName,\n file: sourceFile,\n message: `File reference not found: \"${filePath}\"`,\n suggestion: `Create file at: ${resolvedPath}`,\n });\n return;\n }\n\n // Add to visited set\n visited.add(resolvedPath);\n\n // Read the file and check for references\n try {\n const content = fs.readFileSync(resolvedPath, 'utf-8');\n \n // Check for {@include} references in all file types\n await this.validateIncludeReferences(content, resolvedPath, new Set([resolvedPath]));\n \n // If it's a JSON file, parse and validate nested @ references\n if (resolvedPath.endsWith('.json')) {\n try {\n const jsonContent = JSON.parse(content);\n \n // Check if JSON contains @include directives that need preprocessing\n const jsonString = JSON.stringify(jsonContent);\n const hasIncludes = jsonString.includes('\"@include\"') || jsonString.includes('\"@include.');\n \n if (hasIncludes) {\n await this.validateJsonIncludes(jsonContent, resolvedPath);\n }\n \n // Recursively validate all @ references in the JSON structure\n await this.validateJsonReferences(jsonContent, resolvedPath, entityName, visited);\n } catch (parseError) {\n // Not valid JSON or error parsing, treat as text file (already validated {@include} above)\n if (this.options.verbose) {\n console.log(`File ${resolvedPath} is not valid JSON, treating as text file`);\n }\n }\n }\n } catch (error) {\n this.addError({\n type: 'reference',\n severity: 'error',\n entity: entityName,\n field: fieldName,\n file: sourceFile,\n message: `Failed to read file reference: \"${filePath}\"`,\n details: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Validates @lookup: references\n */\n private async validateLookupReference(parsed: ParsedReference, sourceFile: string, entityName: string, fieldName: string): Promise<void> {\n const lookupEntity = this.metadata.EntityByName(parsed.entity!);\n\n if (!lookupEntity) {\n this.addError({\n type: 'reference',\n severity: 'error',\n entity: entityName,\n field: fieldName,\n file: sourceFile,\n message: `Lookup entity \"${parsed.entity}\" not found`,\n suggestion: 'Check entity name spelling and case',\n });\n return;\n }\n\n // For multi-field lookups, validate all fields\n if (parsed.fields && parsed.fields.length > 0) {\n for (const {field} of parsed.fields) {\n const lookupField = lookupEntity.Fields.find((f: any) => f.Name === field);\n if (!lookupField) {\n this.addError({\n type: 'reference',\n severity: 'error',\n entity: entityName,\n field: fieldName,\n file: sourceFile,\n message: `Lookup field \"${field}\" not found on entity \"${parsed.entity}\"`,\n suggestion: `Available fields: ${lookupEntity.Fields.map((f: any) => f.Name).join(', ')}`,\n });\n }\n }\n } else if (parsed.field) {\n // Fallback for single field lookup (backward compatibility)\n const lookupField = lookupEntity.Fields.find((f: any) => f.Name === parsed.field);\n if (!lookupField) {\n this.addError({\n type: 'reference',\n severity: 'error',\n entity: entityName,\n field: fieldName,\n file: sourceFile,\n message: `Lookup field \"${parsed.field}\" not found on entity \"${parsed.entity}\"`,\n suggestion: `Available fields: ${lookupEntity.Fields.map((f: any) => f.Name).join(', ')}`,\n });\n }\n }\n\n // Track dependency\n this.addEntityDependency(entityName, parsed.entity!);\n }\n\n /**\n * Validates @template: references\n */\n private async validateTemplateReference(templatePath: string, sourceFile: string, entityName: string, fieldName: string): Promise<void> {\n const dir = path.dirname(sourceFile);\n const resolvedPath = path.resolve(dir, templatePath);\n\n if (!fs.existsSync(resolvedPath)) {\n this.addError({\n type: 'reference',\n severity: 'error',\n entity: entityName,\n field: fieldName,\n file: sourceFile,\n message: `Template file not found: \"${templatePath}\"`,\n suggestion: `Create template at: ${resolvedPath}`,\n });\n return;\n }\n\n // Validate template is valid JSON\n try {\n JSON.parse(fs.readFileSync(resolvedPath, 'utf8'));\n } catch (error) {\n this.addError({\n type: 'reference',\n severity: 'error',\n entity: entityName,\n field: fieldName,\n file: sourceFile,\n message: `Template file is not valid JSON: \"${templatePath}\"`,\n details: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Validates @parent: references\n */\n private validateParentReference(\n _fieldName: string,\n parentContext: { entity: string; field: string } | undefined,\n sourceFile: string,\n entityName: string,\n currentFieldName: string,\n ): void {\n if (!parentContext) {\n this.addError({\n type: 'reference',\n severity: 'error',\n entity: entityName,\n field: currentFieldName,\n file: sourceFile,\n message: `@parent: reference used but no parent context exists`,\n suggestion: '@parent: can only be used in nested/related entities',\n });\n }\n }\n\n /**\n * Validates @root: references\n */\n private validateRootReference(\n _fieldName: string,\n parentContext: { entity: string; field: string } | undefined,\n sourceFile: string,\n entityName: string,\n currentFieldName: string,\n ): void {\n if (!parentContext) {\n this.addError({\n type: 'reference',\n severity: 'error',\n entity: entityName,\n field: currentFieldName,\n file: sourceFile,\n message: `@root: reference used but no root context exists`,\n suggestion: '@root: can only be used in nested/related entities',\n });\n }\n }\n\n /**\n * Track entity dependencies\n */\n private trackEntityDependencies(entityData: EntityData, entityName: string, filePath: string): void {\n if (!this.entityDependencies.has(entityName)) {\n this.entityDependencies.set(entityName, {\n entityName,\n dependsOn: new Set(),\n file: filePath,\n });\n }\n\n // Track dependencies from lookups in fields\n if (entityData.fields) {\n for (const value of Object.values(entityData.fields)) {\n if (typeof value === 'string' && value.startsWith(METADATA_KEYWORDS.LOOKUP)) {\n const parsed = this.parseReference(value);\n if (parsed?.entity) {\n this.addEntityDependency(entityName, parsed.entity);\n }\n }\n }\n }\n }\n\n /**\n * Add an entity dependency\n */\n private addEntityDependency(from: string, to: string): void {\n // Don't add self-references as dependencies (e.g., ParentID in hierarchical structures)\n if (from === to) {\n return;\n }\n \n if (!this.entityDependencies.has(from)) {\n this.entityDependencies.set(from, {\n entityName: from,\n dependsOn: new Set(),\n file: '',\n });\n }\n this.entityDependencies.get(from)!.dependsOn.add(to);\n }\n\n /**\n * Validates dependency order\n */\n private async validateDependencyOrder(directoryOrder: string[]): Promise<void> {\n // Build a map of entity to directory\n const entityToDirectory = new Map<string, string>();\n\n for (const dir of directoryOrder) {\n // This is simplified - in reality we'd need to read the .mj-sync.json\n // to get the actual entity name\n entityToDirectory.set(dir, dir);\n }\n\n // Check for circular dependencies\n const visited = new Set<string>();\n const recursionStack = new Set<string>();\n\n for (const [entity] of this.entityDependencies) {\n if (!visited.has(entity)) {\n this.checkCircularDependency(entity, visited, recursionStack);\n }\n }\n\n // Check if current order satisfies dependencies\n const orderViolations = this.checkDependencyOrder(directoryOrder);\n if (orderViolations.length > 0) {\n // Suggest a corrected order\n const suggestedOrder = this.topologicalSort();\n\n for (const violation of orderViolations) {\n this.addError({\n type: 'dependency',\n severity: 'error',\n entity: violation.entity,\n file: violation.file,\n message: `Entity '${violation.entity}' depends on '${violation.dependency}' but is processed before it`,\n suggestion: `Reorder directories to: [${suggestedOrder.join(', ')}]`,\n });\n }\n }\n }\n\n /**\n * Check for circular dependencies\n */\n private checkCircularDependency(entity: string, visited: Set<string>, recursionStack: Set<string>, path: string[] = []): boolean {\n visited.add(entity);\n recursionStack.add(entity);\n path.push(entity);\n\n const deps = this.entityDependencies.get(entity);\n if (deps) {\n for (const dep of deps.dependsOn) {\n if (!visited.has(dep)) {\n if (this.checkCircularDependency(dep, visited, recursionStack, [...path])) {\n return true;\n }\n } else if (recursionStack.has(dep)) {\n // Found circular dependency\n const cycle = [...path, dep];\n const cycleStart = cycle.indexOf(dep);\n const cyclePath = cycle.slice(cycleStart).join(' → ');\n\n this.addError({\n type: 'circular',\n severity: 'error',\n entity: entity,\n file: deps.file,\n message: `Circular dependency detected: ${cyclePath}`,\n suggestion: 'Restructure your entities to avoid circular references',\n });\n return true;\n }\n }\n }\n\n recursionStack.delete(entity);\n return false;\n }\n\n /**\n * Get directories in order based on config\n */\n private async getDirectoriesInOrder(rootDir: string, config: any): Promise<string[]> {\n const allDirs = fs\n .readdirSync(rootDir)\n .filter((f) => fs.statSync(path.join(rootDir, f)).isDirectory())\n .filter((d) => !d.startsWith('.'));\n\n let orderedDirs: string[];\n if (config.directoryOrder && Array.isArray(config.directoryOrder)) {\n const ordered = config.directoryOrder.filter((d: string) => allDirs.includes(d));\n const remaining = allDirs.filter((d) => !ordered.includes(d)).sort();\n orderedDirs = [...ordered, ...remaining];\n } else {\n orderedDirs = allDirs.sort();\n }\n\n // Apply include/exclude filters if specified\n return this.applyDirectoryFilters(orderedDirs);\n }\n\n /**\n * Apply include/exclude filters to directory list\n */\n private applyDirectoryFilters(directories: string[]): string[] {\n let filteredDirs = directories;\n\n // Apply include filter (whitelist)\n if (this.options.include && this.options.include.length > 0) {\n const minimatch = require('minimatch').minimatch;\n filteredDirs = directories.filter(dirName => {\n return this.options.include!.some(pattern =>\n minimatch(dirName, pattern, { nocase: true })\n );\n });\n }\n\n // Apply exclude filter (blacklist)\n if (this.options.exclude && this.options.exclude.length > 0) {\n const minimatch = require('minimatch').minimatch;\n filteredDirs = filteredDirs.filter(dirName => {\n return !this.options.exclude!.some(pattern =>\n minimatch(dirName, pattern, { nocase: true })\n );\n });\n }\n\n return filteredDirs;\n }\n\n /**\n * Get files matching pattern\n */\n private async getMatchingFiles(dir: string, pattern: string): Promise<string[]> {\n const files = fs.readdirSync(dir).filter((f) => fs.statSync(path.join(dir, f)).isFile());\n\n // Simple glob pattern matching\n if (pattern === '*.json') {\n return files.filter((f) => f.endsWith('.json') && !f.startsWith('.mj-'));\n } else if (pattern === '.*.json') {\n return files.filter((f) => f.startsWith('.') && f.endsWith('.json') && !f.startsWith('.mj-'));\n }\n\n return files;\n }\n\n /**\n * Add an error\n */\n private addError(error: ValidationError): void {\n this.errors.push(error);\n }\n\n /**\n * Add a warning\n */\n private addWarning(warning: ValidationWarning): void {\n this.warnings.push(warning);\n }\n\n /**\n * Check if current directory order satisfies dependencies\n */\n private checkDependencyOrder(directoryOrder: string[]): Array<{ entity: string; dependency: string; file: string }> {\n const violations: Array<{ entity: string; dependency: string; file: string }> = [];\n const processedEntities = new Set<string>();\n\n for (const dir of directoryOrder) {\n // In real implementation, we'd read .mj-sync.json to get entity name\n const entityName = dir; // Simplified for now\n\n const deps = this.entityDependencies.get(entityName);\n if (deps) {\n for (const dep of deps.dependsOn) {\n if (!processedEntities.has(dep) && directoryOrder.includes(dep)) {\n violations.push({\n entity: entityName,\n dependency: dep,\n file: deps.file,\n });\n }\n }\n }\n\n processedEntities.add(entityName);\n }\n\n return violations;\n }\n\n /**\n * Perform topological sort on entity dependencies\n */\n private topologicalSort(): string[] {\n const result: string[] = [];\n const visited = new Set<string>();\n const tempStack = new Set<string>();\n\n const visit = (entity: string): boolean => {\n if (tempStack.has(entity)) {\n // Circular dependency, already handled by checkCircularDependency\n return false;\n }\n\n if (visited.has(entity)) {\n return true;\n }\n\n tempStack.add(entity);\n\n const deps = this.entityDependencies.get(entity);\n if (deps) {\n for (const dep of deps.dependsOn) {\n if (!visit(dep)) {\n return false;\n }\n }\n }\n\n tempStack.delete(entity);\n visited.add(entity);\n result.push(entity);\n\n return true;\n };\n\n // Visit all entities\n for (const entity of this.entityDependencies.keys()) {\n if (!visited.has(entity)) {\n visit(entity);\n }\n }\n\n return result;\n }\n\n /**\n * Reset validation state\n */\n private reset(): void {\n this.errors = [];\n this.warnings = [];\n this.entityDependencies.clear();\n this.processedEntities.clear();\n this.userRoleCache.clear();\n }\n\n /**\n * Get validation result\n */\n private getResult(): ValidationResult {\n return {\n isValid: this.errors.length === 0,\n errors: this.errors,\n warnings: this.warnings,\n summary: {\n totalFiles: 0,\n totalEntities: 0,\n totalErrors: this.errors.length,\n totalWarnings: this.warnings.length,\n fileResults: new Map(),\n },\n };\n }\n\n /**\n * Load user roles from the database into cache\n */\n private async loadUserRoles(): Promise<void> {\n try {\n const rv = new RunView();\n const systemUser = getSystemUser();\n\n // Load all user roles with role names\n const result = await rv.RunView(\n {\n EntityName: 'User Roles',\n ExtraFilter: '',\n OrderBy: 'UserID',\n MaxRows: 10000,\n },\n systemUser,\n );\n\n if (!result.Success) {\n this.addWarning({\n type: 'validation',\n severity: 'warning',\n file: 'system',\n message: 'Failed to load user roles for validation',\n details: result.ErrorMessage,\n });\n return;\n }\n\n // Group roles by UserID\n for (const userRole of result.Results || []) {\n const userId = userRole.UserID;\n const roleName = userRole.Role;\n\n if (!this.userRoleCache.has(userId)) {\n this.userRoleCache.set(userId, []);\n }\n this.userRoleCache.get(userId)!.push(roleName);\n }\n\n if (this.options.verbose) {\n console.log(`Loaded roles for ${this.userRoleCache.size} users`);\n }\n } catch (error) {\n this.addWarning({\n type: 'validation',\n severity: 'warning',\n file: 'system',\n message: 'Error loading user roles for validation',\n details: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Validate a UserID field value against allowed roles\n */\n private async validateUserRole(userId: string, entityName: string, fieldName: string, filePath: string, config: any): Promise<void> {\n // Skip if user role validation is not enabled\n if (!config.userRoleValidation?.enabled) {\n return;\n }\n\n const userRoles = this.userRoleCache.get(userId);\n const allowedRoles = config.userRoleValidation.allowedRoles || [];\n const allowUsersWithoutRoles = config.userRoleValidation.allowUsersWithoutRoles || false;\n\n if (!userRoles || userRoles.length === 0) {\n if (!allowUsersWithoutRoles) {\n this.addError({\n type: 'validation',\n severity: 'error',\n entity: entityName,\n field: fieldName,\n file: filePath,\n message: `UserID '${userId}' does not have any assigned roles`,\n suggestion:\n allowedRoles.length > 0\n ? `User must have one of these roles: ${allowedRoles.join(', ')}`\n : 'Assign appropriate roles to this user or set allowUsersWithoutRoles: true',\n });\n }\n return;\n }\n\n // Check if user has at least one allowed role\n if (allowedRoles.length > 0) {\n const hasAllowedRole = userRoles.some((role) => allowedRoles.includes(role));\n if (!hasAllowedRole) {\n this.addError({\n type: 'validation',\n severity: 'error',\n entity: entityName,\n field: fieldName,\n file: filePath,\n message: `UserID '${userId}' has roles [${userRoles.join(', ')}] but none are in allowed list`,\n suggestion: `Allowed roles: ${allowedRoles.join(', ')}`,\n });\n }\n }\n }\n\n /**\n * Validates {@include} references within file content\n * \n * Recursively checks all {@include path} references in file content to ensure:\n * - Referenced files exist\n * - No circular references occur\n * - Include paths are valid\n * \n * @param content - The file content to validate\n * @param filePath - Path of the file being validated\n * @param visitedPaths - Set of already visited paths for circular reference detection\n */\n private async validateIncludeReferences(content: string, filePath: string, visitedPaths: Set<string>): Promise<void> {\n // Pattern to match {@include path} references\n const includePattern = /\\{@include\\s+([^\\}]+)\\s*\\}/g;\n let match: RegExpExecArray | null;\n \n while ((match = includePattern.exec(content)) !== null) {\n const [fullMatch, includePath] = match;\n const trimmedPath = includePath.trim();\n \n // Resolve the include path relative to the current file's directory\n const currentDir = path.dirname(filePath);\n const resolvedPath = path.resolve(currentDir, trimmedPath);\n \n // Check for circular reference\n if (visitedPaths.has(resolvedPath)) {\n this.addError({\n type: 'reference',\n severity: 'error',\n file: filePath,\n message: `Circular {@include} reference detected: \"${trimmedPath}\"`,\n details: `Path ${resolvedPath} is already being processed`,\n suggestion: 'Restructure your includes to avoid circular references',\n });\n continue;\n }\n \n // Check if the included file exists\n if (!fs.existsSync(resolvedPath)) {\n this.addError({\n type: 'reference',\n severity: 'error',\n file: filePath,\n message: `{@include} file not found: \"${trimmedPath}\"`,\n suggestion: `Create file at: ${resolvedPath}`,\n });\n continue;\n }\n \n // Recursively validate the included file\n try {\n const includedContent = fs.readFileSync(resolvedPath, 'utf-8');\n const newVisitedPaths = new Set(visitedPaths);\n newVisitedPaths.add(resolvedPath);\n await this.validateIncludeReferences(includedContent, resolvedPath, newVisitedPaths);\n } catch (error) {\n this.addError({\n type: 'reference',\n severity: 'error',\n file: filePath,\n message: `Failed to read {@include} file: \"${trimmedPath}\"`,\n details: error instanceof Error ? error.message : String(error),\n });\n }\n }\n }\n\n /**\n * Validates @include directives in JSON files\n */\n private async validateJsonIncludes(jsonContent: any, sourceFile: string): Promise<void> {\n // Process based on data type\n if (Array.isArray(jsonContent)) {\n for (const item of jsonContent) {\n if (typeof item === 'string' && item.startsWith(`${METADATA_KEYWORDS.INCLUDE}:`)) {\n const includePath = extractKeywordValue(item) as string;\n await this.validateIncludeFile(includePath.trim(), sourceFile);\n } else if (item && typeof item === 'object') {\n await this.validateJsonIncludes(item, sourceFile);\n }\n }\n } else if (jsonContent && typeof jsonContent === 'object') {\n for (const [key, value] of Object.entries(jsonContent)) {\n if (key === METADATA_KEYWORDS.INCLUDE || key.startsWith(`${METADATA_KEYWORDS.INCLUDE}.`)) {\n let includeFile: string;\n if (typeof value === 'string') {\n includeFile = value;\n } else if (value && typeof value === 'object' && 'file' in value) {\n includeFile = (value as any).file;\n } else {\n this.addError({\n type: 'reference',\n severity: 'error',\n file: sourceFile,\n message: `Invalid @include directive format for key \"${key}\"`,\n suggestion: 'Use either a string path or an object with a \"file\" property',\n });\n continue;\n }\n await this.validateIncludeFile(includeFile, sourceFile);\n } else if (value && typeof value === 'object') {\n await this.validateJsonIncludes(value, sourceFile);\n }\n }\n }\n }\n\n /**\n * Validates a single include file path\n */\n private async validateIncludeFile(includePath: string, sourceFile: string): Promise<void> {\n const dir = path.dirname(sourceFile);\n const resolvedPath = path.resolve(dir, includePath);\n \n if (!fs.existsSync(resolvedPath)) {\n this.addError({\n type: 'reference',\n severity: 'error',\n file: sourceFile,\n message: `@include file not found: \"${includePath}\"`,\n suggestion: `Create file at: ${resolvedPath}`,\n });\n }\n }\n\n /**\n * Recursively validates all @ references in a JSON structure\n */\n private async validateJsonReferences(\n obj: any,\n sourceFile: string,\n entityName: string,\n visitedFiles: Set<string>,\n parentContext?: { entity: string; field: string }\n ): Promise<void> {\n if (obj === null || obj === undefined) {\n return;\n }\n\n if (Array.isArray(obj)) {\n for (const item of obj) {\n await this.validateJsonReferences(item, sourceFile, entityName, visitedFiles, parentContext);\n }\n } else if (typeof obj === 'object') {\n for (const [key, value] of Object.entries(obj)) {\n if (typeof value === 'string' && this.isValidReference(value)) {\n // Process different reference types\n if (value.startsWith(METADATA_KEYWORDS.FILE)) {\n const filePath = extractKeywordValue(value) as string;\n // Recursively validate the file reference (with circular detection)\n await this.validateFileReference(filePath, sourceFile, entityName, key, visitedFiles);\n } else if (value.startsWith(METADATA_KEYWORDS.LOOKUP)) {\n // Parse and validate lookup reference\n const parsed = this.parseReference(value);\n if (parsed) {\n await this.validateLookupReference(parsed, sourceFile, entityName, key);\n }\n } else if (value.startsWith(METADATA_KEYWORDS.TEMPLATE)) {\n const templatePath = extractKeywordValue(value) as string;\n await this.validateTemplateReference(templatePath, sourceFile, entityName, key);\n } else if (value.startsWith(METADATA_KEYWORDS.PARENT)) {\n const parsed = this.parseReference(value);\n if (parsed) {\n this.validateParentReference(parsed.value, parentContext, sourceFile, entityName, key);\n }\n } else if (value.startsWith(METADATA_KEYWORDS.ROOT)) {\n const parsed = this.parseReference(value);\n if (parsed) {\n this.validateRootReference(parsed.value, parentContext, sourceFile, entityName, key);\n }\n } else if (value.startsWith(METADATA_KEYWORDS.ENV)) {\n const envVar = extractKeywordValue(value) as string;\n if (!process.env[envVar]) {\n this.addWarning({\n type: 'validation',\n severity: 'warning',\n entity: entityName,\n field: key,\n file: sourceFile,\n message: `Environment variable \"${envVar}\" is not currently set`,\n suggestion: `Ensure this variable is set before running push operations`,\n });\n }\n }\n } else if (value && typeof value === 'object') {\n // Recursively process nested objects\n await this.validateJsonReferences(value, sourceFile, entityName, visitedFiles, parentContext);\n }\n }\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ValidationService.js","sourceRoot":"","sources":["../../src/services/ValidationService.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAAsF;AACtF,uCAAyB;AACzB,2CAA6B;AAY7B,0DAAsD;AACtD,sEAMwC;AAMxC,MAAa,iBAAiB;IACpB,QAAQ,CAAW;IACnB,MAAM,GAAsB,EAAE,CAAC;IAC/B,QAAQ,GAAwB,EAAE,CAAC;IACnC,kBAAkB,GAAkC,IAAI,GAAG,EAAE,CAAC;IAC9D,iBAAiB,GAAgB,IAAI,GAAG,EAAE,CAAC;IAC3C,OAAO,CAAoB;IAC3B,aAAa,GAA0B,IAAI,GAAG,EAAE,CAAC;IAEzD,YAAY,UAAsC,EAAE;QAClD,IAAI,CAAC,QAAQ,GAAG,IAAI,eAAQ,EAAE,CAAC;QAC/B,IAAI,CAAC,OAAO,GAAG;YACb,OAAO,EAAE,KAAK;YACd,YAAY,EAAE,OAAO;YACrB,eAAe,EAAE,EAAE;YACnB,kBAAkB,EAAE,IAAI;YACxB,GAAG,OAAO;SACX,CAAC;IACJ,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,iBAAiB,CAAC,GAAW;QACxC,0DAA0D;QAC1D,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YACjD,MAAM,IAAI,KAAK,CAAC,mFAAmF,CAAC,CAAC;QACvG,CAAC;QAED,IAAI,CAAC,KAAK,EAAE,CAAC;QAEb,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;QACnD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC/B,IAAI,CAAC,QAAQ,CAAC;gBACZ,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,OAAO;gBACjB,IAAI,EAAE,GAAG;gBACT,OAAO,EAAE,wDAAwD;aAClE,CAAC,CAAC;YACH,OAAO,IAAI,CAAC,SAAS,EAAE,CAAC;QAC1B,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;QAE/D,oDAAoD;QACpD,IAAI,MAAM,CAAC,kBAAkB,EAAE,OAAO,EAAE,CAAC;YACvC,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;QAC7B,CAAC;QAED,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAElE,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,IAAI,aAAa,GAAG,CAAC,CAAC;QACtB,MAAM,WAAW,GAAG,IAAI,GAAG,EAAgC,CAAC;QAE5D,KAAK,MAAM,MAAM,IAAI,WAAW,EAAE,CAAC;YACjC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAC1C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC;YAC9D,IAAI,MAAM,EAAE,CAAC;gBACX,UAAU,IAAI,MAAM,CAAC,KAAK,CAAC;gBAC3B,aAAa,IAAI,MAAM,CAAC,QAAQ,CAAC;gBACjC,KAAK,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;oBACpD,WAAW,CAAC,GAAG,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;gBACpC,CAAC;YACH,CAAC;QACH,CAAC;QAED,4BAA4B;QAC5B,MAAM,IAAI,CAAC,uBAAuB,CAAC,WAAW,CAAC,CAAC;QAEhD,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC;YACjC,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,OAAO,EAAE;gBACP,UAAU;gBACV,aAAa;gBACb,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM;gBAC/B,aAAa,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM;gBACnC,WAAW;aACZ;SACF,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,uBAAuB,CAAC,GAAW;QAC/C,+CAA+C;QAC/C,IAAI,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;QACnD,IAAI,MAAW,CAAC;QAEhB,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC9B,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;YACzD,wCAAwC;YACxC,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;gBACvB,IAAI,CAAC,QAAQ,CAAC;oBACZ,IAAI,EAAE,YAAY;oBAClB,QAAQ,EAAE,OAAO;oBACjB,IAAI,EAAE,UAAU;oBAChB,OAAO,EAAE,6CAA6C;iBACvD,CAAC,CAAC;gBACH,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,4BAA4B;QACjE,CAAC;aAAM,CAAC;YACN,6CAA6C;YAC7C,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;YAC7C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC/B,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;QAC3D,CAAC;QAED,8BAA8B;QAC9B,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAClD,IAAI,CAAC,QAAQ,CAAC;gBACZ,IAAI,EAAE,YAAY;gBAClB,QAAQ,EAAE,OAAO;gBACjB,IAAI,EAAE,UAAU;gBAChB,OAAO,EAAE,iCAAiC;aAC3C,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAE7D,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,IAAI,CAAC,QAAQ,CAAC;gBACZ,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,OAAO;gBACjB,IAAI,EAAE,UAAU;gBAChB,OAAO,EAAE,WAAW,MAAM,CAAC,MAAM,yBAAyB;aAC3D,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;QACnE,IAAI,aAAa,GAAG,CAAC,CAAC;QACtB,MAAM,WAAW,GAAG,IAAI,GAAG,EAAgC,CAAC;QAE5D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YACtC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;YACrE,aAAa,IAAI,MAAM,CAAC,WAAW,CAAC;YACpC,WAAW,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACpC,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,WAAW,EAAE,CAAC;IACvE,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,YAAY,CAAC,QAAgB,EAAE,UAAe,EAAE,MAAwB;QACpF,MAAM,UAAU,GAAsB,EAAE,CAAC;QACzC,IAAI,WAAW,GAAG,CAAC,CAAC;QAEpB,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAClD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACjC,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACrD,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC;YAE9B,KAAK,MAAM,UAAU,IAAI,QAAQ,EAAE,CAAC;gBAClC,MAAM,IAAI,CAAC,kBAAkB,CAAC,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;YAC1E,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,UAAU,CAAC,IAAI,CAAC;gBACd,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,OAAO;gBACjB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,yBAAyB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;aAC3F,CAAC,CAAC;QACL,CAAC;QAED,4CAA4C;QAC5C,MAAM,iBAAiB,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;QACzE,MAAM,mBAAmB,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;QAE7E,OAAO;YACL,IAAI,EAAE,QAAQ;YACd,WAAW;YACX,MAAM,EAAE,iBAAiB;YACzB,QAAQ,EAAE,mBAAmB;SAC9B,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,kBAAkB,CAC9B,UAAsB,EACtB,UAAe,EACf,QAAgB,EAChB,MAAwB,EACxB,aAAiD,EACjD,QAAgB,CAAC;QAEjB,sBAAsB;QACtB,IAAI,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC;YACzC,IAAI,CAAC,UAAU,CAAC;gBACd,IAAI,EAAE,SAAS;gBACf,QAAQ,EAAE,SAAS;gBACnB,MAAM,EAAE,UAAU,CAAC,IAAI;gBACvB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,iBAAiB,KAAK,mCAAmC,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE;gBAChG,UAAU,EAAE,sEAAsE;aACnF,CAAC,CAAC;QACL,CAAC;QAED,oDAAoD;QACpD,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;YACvB,MAAM,OAAO,GAAG,aAAa;gBAC3B,CAAC,CAAC,mBAAmB,aAAa,CAAC,KAAK,QAAQ,aAAa,CAAC,MAAM,EAAE;gBACtE,CAAC,CAAC,QAAQ,CAAC;YACb,IAAI,CAAC,QAAQ,CAAC;gBACZ,IAAI,EAAE,OAAO;gBACb,QAAQ,EAAE,OAAO;gBACjB,MAAM,EAAE,UAAU,CAAC,IAAI;gBACvB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,GAAG,OAAO,mFAAmF;gBACtG,UAAU,EAAE,4EAA4E;aACzF,CAAC,CAAC;YACH,OAAO,CAAC,2CAA2C;QACrD,CAAC;QAED,kBAAkB;QAClB,MAAM,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;QAElF,qBAAqB;QACrB,IAAI,CAAC,uBAAuB,CAAC,UAAU,EAAE,UAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAEpE,4BAA4B;QAC5B,IAAI,UAAU,CAAC,eAAe,EAAE,CAAC;YAC/B,KAAK,MAAM,CAAC,iBAAiB,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;gBAC1F,MAAM,iBAAiB,GAAG,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC;gBACxE,IAAI,CAAC,iBAAiB,EAAE,CAAC;oBACvB,IAAI,CAAC,QAAQ,CAAC;wBACZ,IAAI,EAAE,QAAQ;wBACd,QAAQ,EAAE,OAAO;wBACjB,MAAM,EAAE,UAAU,CAAC,IAAI;wBACvB,IAAI,EAAE,QAAQ;wBACd,OAAO,EAAE,mBAAmB,iBAAiB,yBAAyB;qBACvE,CAAC,CAAC;oBACH,SAAS;gBACX,CAAC;gBAED,MAAM,eAAe,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;gBACjF,KAAK,MAAM,aAAa,IAAI,eAAe,EAAE,CAAC;oBAC5C,MAAM,IAAI,CAAC,kBAAkB,CAAC,aAAa,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,iBAAiB,EAAE,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;gBACtJ,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,cAAc,CAC1B,MAA2B,EAC3B,UAAsB,EACtB,QAAgB,EAChB,aAAiD;QAEjD,MAAM,YAAY,GAAG,UAAU,CAAC,MAAM,CAAC;QACvC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAE/D,KAAK,MAAM,CAAC,SAAS,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC7D,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAE1C,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,4DAA4D;gBAC5D,IAAI,CAAC;oBACH,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;oBAC5E,iEAAiE;oBACjE,qEAAqE;oBACrE,mFAAmF;oBACnF,yFAAyF;oBACzF,kGAAkG;oBAClG,MAAM,WAAW,GAAG,SAAS,IAAI,cAAc,CAAC;oBAEhD,IAAI,CAAC,WAAW,EAAE,CAAC;wBACjB,IAAI,CAAC,QAAQ,CAAC;4BACZ,IAAI,EAAE,OAAO;4BACb,QAAQ,EAAE,OAAO;4BACjB,MAAM,EAAE,UAAU,CAAC,IAAI;4BACvB,KAAK,EAAE,SAAS;4BAChB,IAAI,EAAE,QAAQ;4BACd,OAAO,EAAE,UAAU,SAAS,+BAA+B,UAAU,CAAC,IAAI,GAAG;yBAC9E,CAAC,CAAC;wBACH,SAAS;oBACX,CAAC;oBAED,SAAS;gBACX,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,4DAA4D;oBAC5D,IAAI,CAAC,QAAQ,CAAC;wBACZ,IAAI,EAAE,OAAO;wBACb,QAAQ,EAAE,OAAO;wBACjB,MAAM,EAAE,UAAU,CAAC,IAAI;wBACvB,KAAK,EAAE,SAAS;wBAChB,IAAI,EAAE,QAAQ;wBACd,OAAO,EAAE,UAAU,SAAS,+BAA+B,UAAU,CAAC,IAAI,GAAG;qBAC9E,CAAC,CAAC;oBACH,SAAS;gBACX,CAAC;YACH,CAAC;YAED,gDAAgD;YAChD,IAAI,SAAS,CAAC,QAAQ,IAAI,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBACxD,IAAI,CAAC,QAAQ,CAAC;oBACZ,IAAI,EAAE,OAAO;oBACb,QAAQ,EAAE,OAAO;oBACjB,MAAM,EAAE,UAAU,CAAC,IAAI;oBACvB,KAAK,EAAE,SAAS;oBAChB,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,UAAU,SAAS,oDAAoD;oBAChF,UAAU,EAAE,2CAA2C;iBACxD,CAAC,CAAC;gBACH,SAAS;YACX,CAAC;YAED,sCAAsC;YACtC,MAAM,IAAI,CAAC,kBAAkB,CAAC,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;QAC5F,CAAC;QAED,4BAA4B;QAC5B,IAAI,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC;YACpC,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;gBACjC,mDAAmD;gBACnD,IAAI,KAAK,CAAC,UAAU,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC3C,SAAS;gBACX,CAAC;gBAED,oCAAoC;gBACpC,IAAI,KAAK,CAAC,YAAY,KAAK,IAAI,IAAI,KAAK,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;oBACpE,SAAS;gBACX,CAAC;gBAED,8DAA8D;gBAC9D,kFAAkF;gBAClF,MAAM,kBAAkB,GAAG,KAAK,CAAC,aAAa,CAAC;gBAC/C,MAAM,oBAAoB,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,YAAY,CAAC,CAAC;gBAC3G,IAAI,kBAAkB,IAAI,oBAAoB,EAAE,CAAC;oBAC/C,SAAS;gBACX,CAAC;gBAED,4DAA4D;gBAC5D,IAAI,KAAK,CAAC,aAAa,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;oBAC1C,SAAS;gBACX,CAAC;gBAED,kEAAkE;gBAClE,IAAI,aAAa,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,aAAa,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,aAAa,CAAC,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC;oBACvG,SAAS;gBACX,CAAC;gBAED,+EAA+E;gBAC/E,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,IAAI,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC;oBAC1D,SAAS;gBACX,CAAC;gBAED,kDAAkD;gBAClD,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC;oBACxD,SAAS;gBACX,CAAC;gBAED,IAAI,CAAC,UAAU,CAAC;oBACd,IAAI,EAAE,cAAc;oBACpB,QAAQ,EAAE,SAAS;oBACnB,MAAM,EAAE,UAAU,CAAC,IAAI;oBACvB,KAAK,EAAE,KAAK,CAAC,IAAI;oBACjB,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,mBAAmB,KAAK,CAAC,IAAI,cAAc;oBACpD,UAAU,EAAE,QAAQ,KAAK,CAAC,IAAI,wBAAwB;iBACvD,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,kBAAkB,CAC9B,KAAU,EACV,SAA0B,EAC1B,UAAsB,EACtB,QAAgB,EAChB,aAAiD;QAEjD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9D,MAAM,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;YACpF,wEAAwE;YACxE,OAAO;QACT,CAAC;QAED,wDAAwD;QACxD,MAAM,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;QAE1E,+CAA+C;QAC/C,IAAI,SAAS,CAAC,IAAI,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjF,gDAAgD;YAChD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YAEnC,+DAA+D;YAC/D,IAAI,UAAU,GAAG,GAAG,CAAC;YACrB,IAAI,MAAM,GAAG,IAAI,CAAC;YAClB,OAAO,UAAU,IAAI,UAAU,KAAK,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC;gBAChE,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;gBACjE,IAAI,EAAE,CAAC,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC;oBACrC,IAAI,CAAC;wBACH,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC,CAAC;wBAC7E,IAAI,aAAa,CAAC,kBAAkB,EAAE,CAAC;4BACrC,MAAM,GAAG,aAAa,CAAC;4BACvB,MAAM;wBACR,CAAC;oBACH,CAAC;oBAAC,MAAM,CAAC;wBACP,sBAAsB;oBACxB,CAAC;gBACH,CAAC;gBACD,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;YACxC,CAAC;YAED,IAAI,MAAM,EAAE,kBAAkB,EAAE,OAAO,EAAE,CAAC;gBACxC,MAAM,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;YACxF,CAAC;QACH,CAAC;QAED,2CAA2C;IAC7C,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,sBAAsB,CAClC,KAAU,EACV,SAA0B,EAC1B,UAAsB,EACtB,QAAgB;QAEhB,+EAA+E;QAC/E,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;YAC1D,OAAO;QACT,CAAC;QAED,kDAAkD;QAClD,IAAI,SAAS,CAAC,aAAa,KAAK,MAAM,EAAE,CAAC;YACvC,OAAO;QACT,CAAC;QAED,gDAAgD;QAChD,MAAM,iBAAiB,GAAG,SAAS,CAAC,iBAAiB,CAAC;QACtD,IAAI,CAAC,iBAAiB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,iBAAiB,CAAC,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9F,qCAAqC;YACrC,OAAO;QACT,CAAC;QAED,6BAA6B;QAC7B,MAAM,aAAa,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC,GAAQ,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAErE,4EAA4E;QAC5E,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAElC,4CAA4C;QAC5C,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;YACzC,4CAA4C;YAC5C,MAAM,oBAAoB,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,EAAU,EAAE,EAAE,CAC7D,EAAE,CAAC,WAAW,EAAE,KAAK,WAAW,CAAC,WAAW,EAAE,CAC/C,CAAC;YAEF,IAAI,oBAAoB,EAAE,CAAC;gBACzB,IAAI,CAAC,UAAU,CAAC;oBACd,IAAI,EAAE,YAAY;oBAClB,QAAQ,EAAE,SAAS;oBACnB,MAAM,EAAE,UAAU,CAAC,IAAI;oBACvB,KAAK,EAAE,SAAS,CAAC,IAAI;oBACrB,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,UAAU,SAAS,CAAC,IAAI,gBAAgB,WAAW,+CAA+C,oBAAoB,GAAG;oBAClI,UAAU,EAAE,QAAQ,oBAAoB,mBAAmB;iBAC5D,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,6CAA6C;gBAC7C,MAAM,iBAAiB,GAAG,aAAa,CAAC,MAAM,IAAI,EAAE;oBAClD,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC;oBAC1B,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,UAAU,aAAa,CAAC,MAAM,GAAG,EAAE,QAAQ,CAAC;gBAExF,IAAI,CAAC,QAAQ,CAAC;oBACZ,IAAI,EAAE,OAAO;oBACb,QAAQ,EAAE,OAAO;oBACjB,MAAM,EAAE,UAAU,CAAC,IAAI;oBACvB,KAAK,EAAE,SAAS,CAAC,IAAI;oBACrB,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,UAAU,SAAS,CAAC,IAAI,wBAAwB,WAAW,GAAG;oBACvE,UAAU,EAAE,uBAAuB,iBAAiB,EAAE;iBACvD,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACK,gBAAgB,CAAC,KAAa;QACpC,OAAO,IAAA,qCAAiB,EAAC,KAAK,CAAC,CAAC;IAClC,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,iBAAiB,CAC7B,SAAiB,EACjB,SAA0B,EAC1B,UAAsB,EACtB,QAAgB,EAChB,aAAiD;QAEjD,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;QAC9C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,IAAI,CAAC,QAAQ,CAAC;gBACZ,IAAI,EAAE,WAAW;gBACjB,QAAQ,EAAE,OAAO;gBACjB,MAAM,EAAE,UAAU,CAAC,IAAI;gBACvB,KAAK,EAAE,SAAS,CAAC,IAAI;gBACrB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,8BAA8B,SAAS,GAAG;aACpD,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;YACpB,KAAK,qCAAiB,CAAC,IAAI;gBACzB,MAAM,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;gBAC1F,MAAM;YACR,KAAK,qCAAiB,CAAC,MAAM;gBAC3B,MAAM,IAAI,CAAC,uBAAuB,CAAC,MAAM,EAAE,QAAQ,EAAE,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;gBACtF,MAAM;YACR,KAAK,qCAAiB,CAAC,QAAQ;gBAC7B,MAAM,IAAI,CAAC,yBAAyB,CAAC,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;gBAC9F,MAAM;YACR,KAAK,qCAAiB,CAAC,MAAM;gBAC3B,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;gBACrG,MAAM;YACR,KAAK,qCAAiB,CAAC,IAAI;gBACzB,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;gBACnG,MAAM;QACV,CAAC;IACH,CAAC;IAED;;OAEG;IACK,cAAc,CAAC,SAAiB;QACtC,MAAM,QAAQ,GAA8B;YAC1C,CAAC,qCAAiB,CAAC,IAAI,EAAE,cAAc,CAAC;YACxC,CAAC,qCAAiB,CAAC,MAAM,EAAE,yBAAyB,CAAC;YACrD,CAAC,qCAAiB,CAAC,QAAQ,EAAE,kBAAkB,CAAC;YAChD,CAAC,qCAAiB,CAAC,MAAM,EAAE,gBAAgB,CAAC;YAC5C,CAAC,qCAAiB,CAAC,IAAI,EAAE,cAAc,CAAC;YACxC,CAAC,qCAAiB,CAAC,GAAG,EAAE,aAAa,CAAC;SACvC,CAAC;QAEF,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,QAAQ,EAAE,CAAC;YACvC,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACvC,IAAI,KAAK,EAAE,CAAC;gBACV,IAAI,IAAI,KAAK,qCAAiB,CAAC,MAAM,EAAE,CAAC;oBACtC,MAAM,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,GAAG,KAAK,CAAC;oBAEpC,mCAAmC;oBACnC,MAAM,SAAS,GAAG,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;oBAChD,MAAM,UAAU,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;oBAEnE,mDAAmD;oBACnD,MAAM,WAAW,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;oBAC1C,MAAM,MAAM,GAA0C,EAAE,CAAC;oBAEzD,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;wBAC/B,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;wBAC9C,IAAI,UAAU,EAAE,CAAC;4BACf,MAAM,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,UAAU,CAAC;4BACpC,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;wBAC5D,CAAC;oBACH,CAAC;oBAED,6DAA6D;oBAC7D,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;oBAE9E,6DAA6D;oBAC7D,MAAM,gBAAgB,GAAwB,EAAE,CAAC;oBACjD,IAAI,SAAS,IAAI,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;wBAChD,MAAM,UAAU,GAAG,SAAS,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;wBAClD,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;wBACpC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;4BACzB,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;4BACnC,IAAI,GAAG,IAAI,GAAG,EAAE,CAAC;gCACf,gBAAgB,CAAC,GAAG,CAAC,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;4BAClD,CAAC;wBACH,CAAC;oBACH,CAAC;oBAED,OAAO;wBACL,IAAI;wBACJ,KAAK,EAAE,YAAY,CAAC,KAAK;wBACzB,MAAM;wBACN,KAAK,EAAE,YAAY,CAAC,KAAK;wBACzB,MAAM,EAAE,oCAAoC;wBAC5C,eAAe,EAAE,SAAS;wBAC1B,gBAAgB;qBACjB,CAAC;gBACJ,CAAC;gBACD,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YACnC,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,qBAAqB,CAAC,QAAgB,EAAE,UAAkB,EAAE,UAAkB,EAAE,SAAiB,EAAE,YAA0B;QACzI,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QACrC,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QAEjD,kFAAkF;QAClF,MAAM,OAAO,GAAG,YAAY,IAAI,IAAI,GAAG,EAAU,CAAC;QAElD,gCAAgC;QAChC,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;YAC9B,IAAI,CAAC,QAAQ,CAAC;gBACZ,IAAI,EAAE,WAAW;gBACjB,QAAQ,EAAE,OAAO;gBACjB,MAAM,EAAE,UAAU;gBAClB,KAAK,EAAE,SAAS;gBAChB,IAAI,EAAE,UAAU;gBAChB,OAAO,EAAE,uCAAuC,QAAQ,GAAG;gBAC3D,OAAO,EAAE,QAAQ,YAAY,6BAA6B;gBAC1D,UAAU,EAAE,iEAAiE;aAC9E,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YACjC,IAAI,CAAC,QAAQ,CAAC;gBACZ,IAAI,EAAE,WAAW;gBACjB,QAAQ,EAAE,OAAO;gBACjB,MAAM,EAAE,UAAU;gBAClB,KAAK,EAAE,SAAS;gBAChB,IAAI,EAAE,UAAU;gBAChB,OAAO,EAAE,8BAA8B,QAAQ,GAAG;gBAClD,UAAU,EAAE,mBAAmB,YAAY,EAAE;aAC9C,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,qBAAqB;QACrB,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAE1B,yCAAyC;QACzC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;YAEvD,oDAAoD;YACpD,MAAM,IAAI,CAAC,yBAAyB,CAAC,OAAO,EAAE,YAAY,EAAE,IAAI,GAAG,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAErF,8DAA8D;YAC9D,IAAI,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;gBACnC,IAAI,CAAC;oBACH,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;oBAExC,qEAAqE;oBACrE,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;oBAC/C,MAAM,WAAW,GAAG,UAAU,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;oBAE3F,IAAI,WAAW,EAAE,CAAC;wBAChB,MAAM,IAAI,CAAC,oBAAoB,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;oBAC7D,CAAC;oBAED,8DAA8D;oBAC9D,MAAM,IAAI,CAAC,sBAAsB,CAAC,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;gBACpF,CAAC;gBAAC,OAAO,UAAU,EAAE,CAAC;oBACpB,2FAA2F;oBAC3F,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;wBACzB,OAAO,CAAC,GAAG,CAAC,QAAQ,YAAY,2CAA2C,CAAC,CAAC;oBAC/E,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,QAAQ,CAAC;gBACZ,IAAI,EAAE,WAAW;gBACjB,QAAQ,EAAE,OAAO;gBACjB,MAAM,EAAE,UAAU;gBAClB,KAAK,EAAE,SAAS;gBAChB,IAAI,EAAE,UAAU;gBAChB,OAAO,EAAE,mCAAmC,QAAQ,GAAG;gBACvD,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;aAChE,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,uBAAuB,CAAC,MAAuB,EAAE,UAAkB,EAAE,UAAkB,EAAE,SAAiB;QACtH,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,MAAM,CAAC,MAAO,CAAC,CAAC;QAEhE,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,IAAI,CAAC,QAAQ,CAAC;gBACZ,IAAI,EAAE,WAAW;gBACjB,QAAQ,EAAE,OAAO;gBACjB,MAAM,EAAE,UAAU;gBAClB,KAAK,EAAE,SAAS;gBAChB,IAAI,EAAE,UAAU;gBAChB,OAAO,EAAE,kBAAkB,MAAM,CAAC,MAAM,aAAa;gBACrD,UAAU,EAAE,qCAAqC;aAClD,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,+CAA+C;QAC/C,IAAI,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9C,KAAK,MAAM,EAAC,KAAK,EAAC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBACpC,MAAM,WAAW,GAAG,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC;gBAC3E,IAAI,CAAC,WAAW,EAAE,CAAC;oBACjB,IAAI,CAAC,QAAQ,CAAC;wBACZ,IAAI,EAAE,WAAW;wBACjB,QAAQ,EAAE,OAAO;wBACjB,MAAM,EAAE,UAAU;wBAClB,KAAK,EAAE,SAAS;wBAChB,IAAI,EAAE,UAAU;wBAChB,OAAO,EAAE,iBAAiB,KAAK,0BAA0B,MAAM,CAAC,MAAM,GAAG;wBACzE,UAAU,EAAE,qBAAqB,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;qBAC1F,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;aAAM,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YACxB,4DAA4D;YAC5D,MAAM,WAAW,GAAG,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,KAAK,CAAC,CAAC;YAClF,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,IAAI,CAAC,QAAQ,CAAC;oBACZ,IAAI,EAAE,WAAW;oBACjB,QAAQ,EAAE,OAAO;oBACjB,MAAM,EAAE,UAAU;oBAClB,KAAK,EAAE,SAAS;oBAChB,IAAI,EAAE,UAAU;oBAChB,OAAO,EAAE,iBAAiB,MAAM,CAAC,KAAK,0BAA0B,MAAM,CAAC,MAAM,GAAG;oBAChF,UAAU,EAAE,qBAAqB,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;iBAC1F,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,mBAAmB;QACnB,IAAI,CAAC,mBAAmB,CAAC,UAAU,EAAE,MAAM,CAAC,MAAO,CAAC,CAAC;IACvD,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,yBAAyB,CAAC,YAAoB,EAAE,UAAkB,EAAE,UAAkB,EAAE,SAAiB;QACrH,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QACrC,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;QAErD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YACjC,IAAI,CAAC,QAAQ,CAAC;gBACZ,IAAI,EAAE,WAAW;gBACjB,QAAQ,EAAE,OAAO;gBACjB,MAAM,EAAE,UAAU;gBAClB,KAAK,EAAE,SAAS;gBAChB,IAAI,EAAE,UAAU;gBAChB,OAAO,EAAE,6BAA6B,YAAY,GAAG;gBACrD,UAAU,EAAE,uBAAuB,YAAY,EAAE;aAClD,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,kCAAkC;QAClC,IAAI,CAAC;YACH,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;QACpD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,QAAQ,CAAC;gBACZ,IAAI,EAAE,WAAW;gBACjB,QAAQ,EAAE,OAAO;gBACjB,MAAM,EAAE,UAAU;gBAClB,KAAK,EAAE,SAAS;gBAChB,IAAI,EAAE,UAAU;gBAChB,OAAO,EAAE,qCAAqC,YAAY,GAAG;gBAC7D,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;aAChE,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;OAEG;IACK,uBAAuB,CAC7B,UAAkB,EAClB,aAA4D,EAC5D,UAAkB,EAClB,UAAkB,EAClB,gBAAwB;QAExB,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,IAAI,CAAC,QAAQ,CAAC;gBACZ,IAAI,EAAE,WAAW;gBACjB,QAAQ,EAAE,OAAO;gBACjB,MAAM,EAAE,UAAU;gBAClB,KAAK,EAAE,gBAAgB;gBACvB,IAAI,EAAE,UAAU;gBAChB,OAAO,EAAE,sDAAsD;gBAC/D,UAAU,EAAE,sDAAsD;aACnE,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;OAEG;IACK,qBAAqB,CAC3B,UAAkB,EAClB,aAA4D,EAC5D,UAAkB,EAClB,UAAkB,EAClB,gBAAwB;QAExB,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,IAAI,CAAC,QAAQ,CAAC;gBACZ,IAAI,EAAE,WAAW;gBACjB,QAAQ,EAAE,OAAO;gBACjB,MAAM,EAAE,UAAU;gBAClB,KAAK,EAAE,gBAAgB;gBACvB,IAAI,EAAE,UAAU;gBAChB,OAAO,EAAE,kDAAkD;gBAC3D,UAAU,EAAE,oDAAoD;aACjE,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;OAEG;IACK,uBAAuB,CAAC,UAAsB,EAAE,UAAkB,EAAE,QAAgB;QAC1F,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;YAC7C,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,UAAU,EAAE;gBACtC,UAAU;gBACV,SAAS,EAAE,IAAI,GAAG,EAAE;gBACpB,IAAI,EAAE,QAAQ;aACf,CAAC,CAAC;QACL,CAAC;QAED,4CAA4C;QAC5C,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;YACtB,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;gBACrD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,UAAU,CAAC,qCAAiB,CAAC,MAAM,CAAC,EAAE,CAAC;oBAC5E,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;oBAC1C,IAAI,MAAM,EAAE,MAAM,EAAE,CAAC;wBACnB,IAAI,CAAC,mBAAmB,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;oBACtD,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACK,mBAAmB,CAAC,IAAY,EAAE,EAAU;QAClD,wFAAwF;QACxF,IAAI,IAAI,KAAK,EAAE,EAAE,CAAC;YAChB,OAAO;QACT,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACvC,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,EAAE;gBAChC,UAAU,EAAE,IAAI;gBAChB,SAAS,EAAE,IAAI,GAAG,EAAE;gBACpB,IAAI,EAAE,EAAE;aACT,CAAC,CAAC;QACL,CAAC;QACD,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACvD,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,uBAAuB,CAAC,cAAwB;QAC5D,qCAAqC;QACrC,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAkB,CAAC;QAEpD,KAAK,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;YACjC,sEAAsE;YACtE,gCAAgC;YAChC,iBAAiB,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAClC,CAAC;QAED,kCAAkC;QAClC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;QAClC,MAAM,cAAc,GAAG,IAAI,GAAG,EAAU,CAAC;QAEzC,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC/C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBACzB,IAAI,CAAC,uBAAuB,CAAC,MAAM,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC;YAChE,CAAC;QACH,CAAC;QAED,gDAAgD;QAChD,MAAM,eAAe,GAAG,IAAI,CAAC,oBAAoB,CAAC,cAAc,CAAC,CAAC;QAClE,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC/B,4BAA4B;YAC5B,MAAM,cAAc,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;YAE9C,KAAK,MAAM,SAAS,IAAI,eAAe,EAAE,CAAC;gBACxC,IAAI,CAAC,QAAQ,CAAC;oBACZ,IAAI,EAAE,YAAY;oBAClB,QAAQ,EAAE,OAAO;oBACjB,MAAM,EAAE,SAAS,CAAC,MAAM;oBACxB,IAAI,EAAE,SAAS,CAAC,IAAI;oBACpB,OAAO,EAAE,WAAW,SAAS,CAAC,MAAM,iBAAiB,SAAS,CAAC,UAAU,8BAA8B;oBACvG,UAAU,EAAE,4BAA4B,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;iBACrE,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACK,uBAAuB,CAAC,MAAc,EAAE,OAAoB,EAAE,cAA2B,EAAE,OAAiB,EAAE;QACpH,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACpB,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC3B,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAElB,MAAM,IAAI,GAAG,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACjD,IAAI,IAAI,EAAE,CAAC;YACT,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACjC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;oBACtB,IAAI,IAAI,CAAC,uBAAuB,CAAC,GAAG,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC;wBAC1E,OAAO,IAAI,CAAC;oBACd,CAAC;gBACH,CAAC;qBAAM,IAAI,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;oBACnC,4BAA4B;oBAC5B,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,CAAC,CAAC;oBAC7B,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;oBACtC,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;oBAEtD,IAAI,CAAC,QAAQ,CAAC;wBACZ,IAAI,EAAE,UAAU;wBAChB,QAAQ,EAAE,OAAO;wBACjB,MAAM,EAAE,MAAM;wBACd,IAAI,EAAE,IAAI,CAAC,IAAI;wBACf,OAAO,EAAE,iCAAiC,SAAS,EAAE;wBACrD,UAAU,EAAE,wDAAwD;qBACrE,CAAC,CAAC;oBACH,OAAO,IAAI,CAAC;gBACd,CAAC;YACH,CAAC;QACH,CAAC;QAED,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,qBAAqB,CAAC,OAAe,EAAE,MAAW;QAC9D,MAAM,OAAO,GAAG,EAAE;aACf,WAAW,CAAC,OAAO,CAAC;aACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;aAC/D,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;QAErC,IAAI,WAAqB,CAAC;QAC1B,IAAI,MAAM,CAAC,cAAc,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC;YAClE,MAAM,OAAO,GAAG,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;YACjF,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACrE,WAAW,GAAG,CAAC,GAAG,OAAO,EAAE,GAAG,SAAS,CAAC,CAAC;QAC3C,CAAC;aAAM,CAAC;YACN,WAAW,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;QAC/B,CAAC;QAED,6CAA6C;QAC7C,OAAO,IAAI,CAAC,qBAAqB,CAAC,WAAW,CAAC,CAAC;IACjD,CAAC;IAED;;OAEG;IACK,qBAAqB,CAAC,WAAqB;QACjD,IAAI,YAAY,GAAG,WAAW,CAAC;QAE/B,mCAAmC;QACnC,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5D,MAAM,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC;YACjD,YAAY,GAAG,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE;gBAC1C,OAAO,IAAI,CAAC,OAAO,CAAC,OAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAC1C,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAC9C,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC;QAED,mCAAmC;QACnC,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5D,MAAM,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC;YACjD,YAAY,GAAG,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE;gBAC3C,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,OAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAC3C,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAC9C,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC;QAED,OAAO,YAAY,CAAC;IACtB,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,gBAAgB,CAAC,GAAW,EAAE,OAAe;QACzD,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;QAEzF,4EAA4E;QAC5E,MAAM,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QAEzD,+BAA+B;QAC/B,IAAI,iBAAiB,KAAK,QAAQ,EAAE,CAAC;YACnC,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;QAC3E,CAAC;aAAM,IAAI,iBAAiB,KAAK,SAAS,EAAE,CAAC;YAC3C,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;QAChG,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;OAEG;IACK,QAAQ,CAAC,KAAsB;QACrC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;IAED;;OAEG;IACK,UAAU,CAAC,OAA0B;QAC3C,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAED;;OAEG;IACK,oBAAoB,CAAC,cAAwB;QACnD,MAAM,UAAU,GAAgE,EAAE,CAAC;QACnF,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAU,CAAC;QAE5C,KAAK,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;YACjC,qEAAqE;YACrE,MAAM,UAAU,GAAG,GAAG,CAAC,CAAC,qBAAqB;YAE7C,MAAM,IAAI,GAAG,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YACrD,IAAI,IAAI,EAAE,CAAC;gBACT,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;oBACjC,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,cAAc,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;wBAChE,UAAU,CAAC,IAAI,CAAC;4BACd,MAAM,EAAE,UAAU;4BAClB,UAAU,EAAE,GAAG;4BACf,IAAI,EAAE,IAAI,CAAC,IAAI;yBAChB,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;YACH,CAAC;YAED,iBAAiB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACpC,CAAC;QAED,OAAO,UAAU,CAAC;IACpB,CAAC;IAED;;OAEG;IACK,eAAe;QACrB,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;QAClC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;QAEpC,MAAM,KAAK,GAAG,CAAC,MAAc,EAAW,EAAE;YACxC,IAAI,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC1B,kEAAkE;gBAClE,OAAO,KAAK,CAAC;YACf,CAAC;YAED,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBACxB,OAAO,IAAI,CAAC;YACd,CAAC;YAED,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAEtB,MAAM,IAAI,GAAG,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACjD,IAAI,IAAI,EAAE,CAAC;gBACT,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;oBACjC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;wBAChB,OAAO,KAAK,CAAC;oBACf,CAAC;gBACH,CAAC;YACH,CAAC;YAED,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACpB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAEpB,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;QAEF,qBAAqB;QACrB,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,EAAE,CAAC;YACpD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBACzB,KAAK,CAAC,MAAM,CAAC,CAAC;YAChB,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACK,KAAK;QACX,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QACjB,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;QACnB,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,CAAC;QAChC,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,CAAC;QAC/B,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;IAC7B,CAAC;IAED;;OAEG;IACK,SAAS;QACf,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC;YACjC,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,OAAO,EAAE;gBACP,UAAU,EAAE,CAAC;gBACb,aAAa,EAAE,CAAC;gBAChB,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM;gBAC/B,aAAa,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM;gBACnC,WAAW,EAAE,IAAI,GAAG,EAAE;aACvB;SACF,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,aAAa;QACzB,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,IAAI,cAAO,EAAE,CAAC;YACzB,MAAM,UAAU,GAAG,IAAA,8BAAa,GAAE,CAAC;YAEnC,sCAAsC;YACtC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAC7B;gBACE,UAAU,EAAE,YAAY;gBACxB,WAAW,EAAE,EAAE;gBACf,OAAO,EAAE,QAAQ;gBACjB,OAAO,EAAE,KAAK;aACf,EACD,UAAU,CACX,CAAC;YAEF,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,IAAI,CAAC,UAAU,CAAC;oBACd,IAAI,EAAE,YAAY;oBAClB,QAAQ,EAAE,SAAS;oBACnB,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,0CAA0C;oBACnD,OAAO,EAAE,MAAM,CAAC,YAAY;iBAC7B,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YAED,wBAAwB;YACxB,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;gBAC5C,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;gBAC/B,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC;gBAE/B,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;oBACpC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;gBACrC,CAAC;gBACD,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACjD,CAAC;YAED,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;gBACzB,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,CAAC,aAAa,CAAC,IAAI,QAAQ,CAAC,CAAC;YACnE,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,UAAU,CAAC;gBACd,IAAI,EAAE,YAAY;gBAClB,QAAQ,EAAE,SAAS;gBACnB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,yCAAyC;gBAClD,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;aAChE,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,gBAAgB,CAAC,MAAc,EAAE,UAAkB,EAAE,SAAiB,EAAE,QAAgB,EAAE,MAAW;QACjH,8CAA8C;QAC9C,IAAI,CAAC,MAAM,CAAC,kBAAkB,EAAE,OAAO,EAAE,CAAC;YACxC,OAAO;QACT,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACjD,MAAM,YAAY,GAAG,MAAM,CAAC,kBAAkB,CAAC,YAAY,IAAI,EAAE,CAAC;QAClE,MAAM,sBAAsB,GAAG,MAAM,CAAC,kBAAkB,CAAC,sBAAsB,IAAI,KAAK,CAAC;QAEzF,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzC,IAAI,CAAC,sBAAsB,EAAE,CAAC;gBAC5B,IAAI,CAAC,QAAQ,CAAC;oBACZ,IAAI,EAAE,YAAY;oBAClB,QAAQ,EAAE,OAAO;oBACjB,MAAM,EAAE,UAAU;oBAClB,KAAK,EAAE,SAAS;oBAChB,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,WAAW,MAAM,oCAAoC;oBAC9D,UAAU,EACR,YAAY,CAAC,MAAM,GAAG,CAAC;wBACrB,CAAC,CAAC,sCAAsC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;wBACjE,CAAC,CAAC,2EAA2E;iBAClF,CAAC,CAAC;YACL,CAAC;YACD,OAAO;QACT,CAAC;QAED,8CAA8C;QAC9C,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,MAAM,cAAc,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;YAC7E,IAAI,CAAC,cAAc,EAAE,CAAC;gBACpB,IAAI,CAAC,QAAQ,CAAC;oBACZ,IAAI,EAAE,YAAY;oBAClB,QAAQ,EAAE,OAAO;oBACjB,MAAM,EAAE,UAAU;oBAClB,KAAK,EAAE,SAAS;oBAChB,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,WAAW,MAAM,gBAAgB,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,gCAAgC;oBAC9F,UAAU,EAAE,kBAAkB,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;iBACxD,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;;;;;;;;;OAWG;IACK,KAAK,CAAC,yBAAyB,CAAC,OAAe,EAAE,QAAgB,EAAE,YAAyB;QAClG,8CAA8C;QAC9C,MAAM,cAAc,GAAG,6BAA6B,CAAC;QACrD,IAAI,KAA6B,CAAC;QAElC,OAAO,CAAC,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YACvD,MAAM,CAAC,SAAS,EAAE,WAAW,CAAC,GAAG,KAAK,CAAC;YACvC,MAAM,WAAW,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC;YAEvC,oEAAoE;YACpE,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YAC1C,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;YAE3D,+BAA+B;YAC/B,IAAI,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;gBACnC,IAAI,CAAC,QAAQ,CAAC;oBACZ,IAAI,EAAE,WAAW;oBACjB,QAAQ,EAAE,OAAO;oBACjB,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,4CAA4C,WAAW,GAAG;oBACnE,OAAO,EAAE,QAAQ,YAAY,6BAA6B;oBAC1D,UAAU,EAAE,wDAAwD;iBACrE,CAAC,CAAC;gBACH,SAAS;YACX,CAAC;YAED,oCAAoC;YACpC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;gBACjC,IAAI,CAAC,QAAQ,CAAC;oBACZ,IAAI,EAAE,WAAW;oBACjB,QAAQ,EAAE,OAAO;oBACjB,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,+BAA+B,WAAW,GAAG;oBACtD,UAAU,EAAE,mBAAmB,YAAY,EAAE;iBAC9C,CAAC,CAAC;gBACH,SAAS;YACX,CAAC;YAED,yCAAyC;YACzC,IAAI,CAAC;gBACH,MAAM,eAAe,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;gBAC/D,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,CAAC;gBAC9C,eAAe,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;gBAClC,MAAM,IAAI,CAAC,yBAAyB,CAAC,eAAe,EAAE,YAAY,EAAE,eAAe,CAAC,CAAC;YACvF,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,QAAQ,CAAC;oBACZ,IAAI,EAAE,WAAW;oBACjB,QAAQ,EAAE,OAAO;oBACjB,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,oCAAoC,WAAW,GAAG;oBAC3D,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;iBAChE,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,oBAAoB,CAAC,WAAgB,EAAE,UAAkB;QACrE,6BAA6B;QAC7B,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;YAC/B,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;gBAC/B,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,qCAAiB,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC;oBACjF,MAAM,WAAW,GAAG,IAAA,uCAAmB,EAAC,IAAI,CAAW,CAAC;oBACxD,MAAM,IAAI,CAAC,mBAAmB,CAAC,WAAW,CAAC,IAAI,EAAE,EAAE,UAAU,CAAC,CAAC;gBACjE,CAAC;qBAAM,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;oBAC5C,MAAM,IAAI,CAAC,oBAAoB,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;gBACpD,CAAC;YACH,CAAC;QACH,CAAC;aAAM,IAAI,WAAW,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;YAC1D,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;gBACvD,IAAI,GAAG,KAAK,qCAAiB,CAAC,OAAO,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,qCAAiB,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC;oBACzF,IAAI,WAAmB,CAAC;oBACxB,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;wBAC9B,WAAW,GAAG,KAAK,CAAC;oBACtB,CAAC;yBAAM,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,IAAI,KAAK,EAAE,CAAC;wBACjE,WAAW,GAAI,KAAa,CAAC,IAAI,CAAC;oBACpC,CAAC;yBAAM,CAAC;wBACN,IAAI,CAAC,QAAQ,CAAC;4BACZ,IAAI,EAAE,WAAW;4BACjB,QAAQ,EAAE,OAAO;4BACjB,IAAI,EAAE,UAAU;4BAChB,OAAO,EAAE,8CAA8C,GAAG,GAAG;4BAC7D,UAAU,EAAE,8DAA8D;yBAC3E,CAAC,CAAC;wBACH,SAAS;oBACX,CAAC;oBACD,MAAM,IAAI,CAAC,mBAAmB,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;gBAC1D,CAAC;qBAAM,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;oBAC9C,MAAM,IAAI,CAAC,oBAAoB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;gBACrD,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,mBAAmB,CAAC,WAAmB,EAAE,UAAkB;QACvE,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QACrC,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QAEpD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YACjC,IAAI,CAAC,QAAQ,CAAC;gBACZ,IAAI,EAAE,WAAW;gBACjB,QAAQ,EAAE,OAAO;gBACjB,IAAI,EAAE,UAAU;gBAChB,OAAO,EAAE,6BAA6B,WAAW,GAAG;gBACpD,UAAU,EAAE,mBAAmB,YAAY,EAAE;aAC9C,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,sBAAsB,CAClC,GAAQ,EACR,UAAkB,EAClB,UAAkB,EAClB,YAAyB,EACzB,aAAiD;QAEjD,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACtC,OAAO;QACT,CAAC;QAED,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YACvB,KAAK,MAAM,IAAI,IAAI,GAAG,EAAE,CAAC;gBACvB,MAAM,IAAI,CAAC,sBAAsB,CAAC,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,CAAC,CAAC;YAC/F,CAAC;QACH,CAAC;aAAM,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YACnC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC/C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC9D,oCAAoC;oBACpC,IAAI,KAAK,CAAC,UAAU,CAAC,qCAAiB,CAAC,IAAI,CAAC,EAAE,CAAC;wBAC7C,MAAM,QAAQ,GAAG,IAAA,uCAAmB,EAAC,KAAK,CAAW,CAAC;wBACtD,oEAAoE;wBACpE,MAAM,IAAI,CAAC,qBAAqB,CAAC,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,EAAE,YAAY,CAAC,CAAC;oBACxF,CAAC;yBAAM,IAAI,KAAK,CAAC,UAAU,CAAC,qCAAiB,CAAC,MAAM,CAAC,EAAE,CAAC;wBACtD,sCAAsC;wBACtC,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;wBAC1C,IAAI,MAAM,EAAE,CAAC;4BACX,MAAM,IAAI,CAAC,uBAAuB,CAAC,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;wBAC1E,CAAC;oBACH,CAAC;yBAAM,IAAI,KAAK,CAAC,UAAU,CAAC,qCAAiB,CAAC,QAAQ,CAAC,EAAE,CAAC;wBACxD,MAAM,YAAY,GAAG,IAAA,uCAAmB,EAAC,KAAK,CAAW,CAAC;wBAC1D,MAAM,IAAI,CAAC,yBAAyB,CAAC,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;oBAClF,CAAC;yBAAM,IAAI,KAAK,CAAC,UAAU,CAAC,qCAAiB,CAAC,MAAM,CAAC,EAAE,CAAC;wBACtD,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;wBAC1C,IAAI,MAAM,EAAE,CAAC;4BACX,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;wBACzF,CAAC;oBACH,CAAC;yBAAM,IAAI,KAAK,CAAC,UAAU,CAAC,qCAAiB,CAAC,IAAI,CAAC,EAAE,CAAC;wBACpD,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;wBAC1C,IAAI,MAAM,EAAE,CAAC;4BACX,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;wBACvF,CAAC;oBACH,CAAC;yBAAM,IAAI,KAAK,CAAC,UAAU,CAAC,qCAAiB,CAAC,GAAG,CAAC,EAAE,CAAC;wBACnD,MAAM,MAAM,GAAG,IAAA,uCAAmB,EAAC,KAAK,CAAW,CAAC;wBACpD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;4BACzB,IAAI,CAAC,UAAU,CAAC;gCACd,IAAI,EAAE,YAAY;gCAClB,QAAQ,EAAE,SAAS;gCACnB,MAAM,EAAE,UAAU;gCAClB,KAAK,EAAE,GAAG;gCACV,IAAI,EAAE,UAAU;gCAChB,OAAO,EAAE,yBAAyB,MAAM,wBAAwB;gCAChE,UAAU,EAAE,4DAA4D;6BACzE,CAAC,CAAC;wBACL,CAAC;oBACH,CAAC;gBACH,CAAC;qBAAM,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;oBAC9C,qCAAqC;oBACrC,MAAM,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,CAAC,CAAC;gBAChG,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;CACF;AAr6CD,8CAq6CC","sourcesContent":["import { EntityFieldInfo, EntityInfo, Metadata, RunView } from '@memberjunction/core';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport {\n ValidationResult,\n ValidationError,\n ValidationWarning,\n ValidationOptions,\n FileValidationResult,\n EntityDependency,\n ParsedReference,\n ReferenceType,\n} from '../types/validation';\nimport { RecordData } from '../lib/sync-engine';\nimport { getSystemUser } from '../lib/provider-utils';\nimport {\n METADATA_KEYWORDS,\n METADATA_KEYWORD_PREFIXES,\n isMetadataKeyword,\n getMetadataKeywordType,\n extractKeywordValue\n} from '../constants/metadata-keywords';\n\n// Type aliases for clarity\ntype EntityData = RecordData;\ntype EntitySyncConfig = any;\n\nexport class ValidationService {\n private metadata: Metadata;\n private errors: ValidationError[] = [];\n private warnings: ValidationWarning[] = [];\n private entityDependencies: Map<string, EntityDependency> = new Map();\n private processedEntities: Set<string> = new Set();\n private options: ValidationOptions;\n private userRoleCache: Map<string, string[]> = new Map();\n\n constructor(options: Partial<ValidationOptions> = {}) {\n this.metadata = new Metadata();\n this.options = {\n verbose: false,\n outputFormat: 'human',\n maxNestingDepth: 10,\n checkBestPractices: true,\n ...options,\n };\n }\n\n /**\n * Validates all metadata files in the specified directory\n */\n public async validateDirectory(dir: string): Promise<ValidationResult> {\n // Validate that include and exclude are not used together\n if (this.options.include && this.options.exclude) {\n throw new Error('Cannot specify both --include and --exclude options. Please use one or the other.');\n }\n\n this.reset();\n\n const configPath = path.join(dir, '.mj-sync.json');\n if (!fs.existsSync(configPath)) {\n this.addError({\n type: 'entity',\n severity: 'error',\n file: dir,\n message: 'No .mj-sync.json configuration file found in directory',\n });\n return this.getResult();\n }\n\n const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));\n\n // Load user role configuration and cache if enabled\n if (config.userRoleValidation?.enabled) {\n await this.loadUserRoles();\n }\n\n const directories = await this.getDirectoriesInOrder(dir, config);\n\n let totalFiles = 0;\n let totalEntities = 0;\n const fileResults = new Map<string, FileValidationResult>();\n\n for (const subDir of directories) {\n const subDirPath = path.join(dir, subDir);\n const result = await this.validateEntityDirectory(subDirPath);\n if (result) {\n totalFiles += result.files;\n totalEntities += result.entities;\n for (const [file, fileResult] of result.fileResults) {\n fileResults.set(file, fileResult);\n }\n }\n }\n\n // Validate dependency order\n await this.validateDependencyOrder(directories);\n\n return {\n isValid: this.errors.length === 0,\n errors: this.errors,\n warnings: this.warnings,\n summary: {\n totalFiles,\n totalEntities,\n totalErrors: this.errors.length,\n totalWarnings: this.warnings.length,\n fileResults,\n },\n };\n }\n\n /**\n * Validates a single entity directory\n */\n private async validateEntityDirectory(dir: string): Promise<{ files: number; entities: number; fileResults: Map<string, FileValidationResult> } | null> {\n // Check for .mj-folder.json first (new format)\n let configPath = path.join(dir, '.mj-folder.json');\n let config: any;\n \n if (fs.existsSync(configPath)) {\n config = JSON.parse(fs.readFileSync(configPath, 'utf8'));\n // .mj-folder.json uses entityName field\n if (!config.entityName) {\n this.addError({\n type: 'validation',\n severity: 'error',\n file: configPath,\n message: 'Missing entityName field in .mj-folder.json',\n });\n return null;\n }\n config.entity = config.entityName; // Normalize to entity field\n } else {\n // Fall back to .mj-sync.json (legacy format)\n configPath = path.join(dir, '.mj-sync.json');\n if (!fs.existsSync(configPath)) {\n return null;\n }\n config = JSON.parse(fs.readFileSync(configPath, 'utf8'));\n }\n\n // Validate entity name exists\n if (!config.entity || config.entity.trim() === '') {\n this.addError({\n type: 'validation',\n severity: 'error',\n file: configPath,\n message: 'Entity name is empty or missing',\n });\n return null;\n }\n\n const entityInfo = this.metadata.EntityByName(config.entity);\n\n if (!entityInfo) {\n this.addError({\n type: 'entity',\n severity: 'error',\n file: configPath,\n message: `Entity \"${config.entity}\" not found in metadata`,\n });\n return null;\n }\n\n const files = await this.getMatchingFiles(dir, config.filePattern);\n let totalEntities = 0;\n const fileResults = new Map<string, FileValidationResult>();\n\n for (const file of files) {\n const filePath = path.join(dir, file);\n const result = await this.validateFile(filePath, entityInfo, config);\n totalEntities += result.entityCount;\n fileResults.set(filePath, result);\n }\n\n return { files: files.length, entities: totalEntities, fileResults };\n }\n\n /**\n * Validates a single metadata file\n */\n private async validateFile(filePath: string, entityInfo: any, config: EntitySyncConfig): Promise<FileValidationResult> {\n const fileErrors: ValidationError[] = [];\n let entityCount = 0;\n\n try {\n const content = fs.readFileSync(filePath, 'utf8');\n const data = JSON.parse(content);\n const entities = Array.isArray(data) ? data : [data];\n entityCount = entities.length;\n\n for (const entityData of entities) {\n await this.validateEntityData(entityData, entityInfo, filePath, config);\n }\n } catch (error) {\n fileErrors.push({\n type: 'entity',\n severity: 'error',\n file: filePath,\n message: `Failed to parse JSON: ${error instanceof Error ? error.message : String(error)}`,\n });\n }\n\n // Collect errors and warnings for this file\n const currentFileErrors = this.errors.filter((e) => e.file === filePath);\n const currentFileWarnings = this.warnings.filter((w) => w.file === filePath);\n\n return {\n file: filePath,\n entityCount,\n errors: currentFileErrors,\n warnings: currentFileWarnings,\n };\n }\n\n /**\n * Validates a single entity data object\n */\n private async validateEntityData(\n entityData: EntityData,\n entityInfo: any,\n filePath: string,\n config: EntitySyncConfig,\n parentContext?: { entity: string; field: string },\n depth: number = 0,\n ): Promise<void> {\n // Check nesting depth\n if (depth > this.options.maxNestingDepth) {\n this.addWarning({\n type: 'nesting',\n severity: 'warning',\n entity: entityInfo.Name,\n file: filePath,\n message: `Nesting depth ${depth} exceeds recommended maximum of ${this.options.maxNestingDepth}`,\n suggestion: 'Consider flattening the data structure or increasing maxNestingDepth',\n });\n }\n\n // Validate that 'fields' property exists (required)\n if (!entityData.fields) {\n const context = parentContext\n ? `Related entity \"${parentContext.field}\" in ${parentContext.entity}`\n : `Record`;\n this.addError({\n type: 'field',\n severity: 'error',\n entity: entityInfo.Name,\n file: filePath,\n message: `${context} is missing required \"fields\" property. Did you mean \"fields\" instead of \"field\"?`,\n suggestion: 'Each record must have a \"fields\" object containing the entity field values',\n });\n return; // Can't continue validation without fields\n }\n\n // Validate fields\n await this.validateFields(entityData.fields, entityInfo, filePath, parentContext);\n\n // Track dependencies\n this.trackEntityDependencies(entityData, entityInfo.Name, filePath);\n\n // Validate related entities\n if (entityData.relatedEntities) {\n for (const [relatedEntityName, relatedData] of Object.entries(entityData.relatedEntities)) {\n const relatedEntityInfo = this.metadata.EntityByName(relatedEntityName);\n if (!relatedEntityInfo) {\n this.addError({\n type: 'entity',\n severity: 'error',\n entity: entityInfo.Name,\n file: filePath,\n message: `Related entity \"${relatedEntityName}\" not found in metadata`,\n });\n continue;\n }\n\n const relatedEntities = Array.isArray(relatedData) ? relatedData : [relatedData];\n for (const relatedEntity of relatedEntities) {\n await this.validateEntityData(relatedEntity, relatedEntityInfo, filePath, config, { entity: entityInfo.Name, field: relatedEntityName }, depth + 1);\n }\n }\n }\n }\n\n /**\n * Validates entity fields\n */\n private async validateFields(\n fields: Record<string, any>,\n entityInfo: EntityInfo,\n filePath: string,\n parentContext?: { entity: string; field: string },\n ): Promise<void> {\n const entityFields = entityInfo.Fields;\n const fieldMap = new Map(entityFields.map((f) => [f.Name, f]));\n\n for (const [fieldName, fieldValue] of Object.entries(fields)) {\n const fieldInfo = fieldMap.get(fieldName);\n\n if (!fieldInfo) {\n // Check if this might be a virtual property (getter/setter)\n try {\n const entityInstance = await this.metadata.GetEntityObject(entityInfo.Name);\n // we use this approach instead of checking Entity Fields because\n // some sub-classes implement setter properties that allow you to set\n // values that are not physically in the database but are resolved by the sub-class\n // a good example is the sub-class for AI Prompts that has a property called TemplateText\n // that is automatically resolved into a separate record in the Templates/Template Contents entity\n const hasProperty = fieldName in entityInstance;\n\n if (!hasProperty) {\n this.addError({\n type: 'field',\n severity: 'error',\n entity: entityInfo.Name,\n field: fieldName,\n file: filePath,\n message: `Field \"${fieldName}\" does not exist on entity \"${entityInfo.Name}\"`,\n });\n continue;\n }\n\n continue;\n } catch (error) {\n // If we can't create an entity instance, fall back to error\n this.addError({\n type: 'field',\n severity: 'error',\n entity: entityInfo.Name,\n field: fieldName,\n file: filePath,\n message: `Field \"${fieldName}\" does not exist on entity \"${entityInfo.Name}\"`,\n });\n continue;\n }\n }\n\n // Check if field is settable (not system field)\n if (fieldInfo.ReadOnly || fieldName.startsWith('__mj_')) {\n this.addError({\n type: 'field',\n severity: 'error',\n entity: entityInfo.Name,\n field: fieldName,\n file: filePath,\n message: `Field \"${fieldName}\" is a read-only or system field and cannot be set`,\n suggestion: 'Remove this field from your metadata file',\n });\n continue;\n }\n\n // Validate field value and references\n await this.validateFieldValue(fieldValue, fieldInfo, entityInfo, filePath, parentContext);\n }\n\n // Check for required fields\n if (this.options.checkBestPractices) {\n for (const field of entityFields) {\n // Skip if field allows null or has a value already\n if (field.AllowsNull || fields[field.Name]) {\n continue;\n }\n\n // Skip if field has a default value\n if (field.DefaultValue !== null && field.DefaultValue !== undefined) {\n continue;\n }\n\n // Skip virtual/computed fields (foreign key reference fields)\n // These are typically named without 'ID' suffix but have a corresponding FK field\n const relatedEntityField = field.RelatedEntity;\n const correspondingFKField = entityFields.find((f: any) => f.Name === field.Name + 'ID' && f.IsForeignKey);\n if (relatedEntityField && correspondingFKField) {\n continue;\n }\n\n // Skip fields that are marked as AutoUpdateOnly or ReadOnly\n if (field.AutoIncrement || field.ReadOnly) {\n continue;\n }\n\n // Skip if this is a parent context and the field can be inherited\n if (parentContext && (field.Name === parentContext.field || field.Name === parentContext.field + 'ID')) {\n continue;\n }\n\n // Special case: Skip TemplateID if TemplateText is provided (virtual property)\n if (field.Name === 'TemplateID' && fields['TemplateText']) {\n continue;\n }\n\n // Skip Template field if TemplateText is provided\n if (field.Name === 'Template' && fields['TemplateText']) {\n continue;\n }\n\n this.addWarning({\n type: 'bestpractice',\n severity: 'warning',\n entity: entityInfo.Name,\n field: field.Name,\n file: filePath,\n message: `Required field \"${field.Name}\" is missing`,\n suggestion: `Add \"${field.Name}\" to the fields object`,\n });\n }\n }\n }\n\n /**\n * Validates field values and references\n */\n private async validateFieldValue(\n value: any,\n fieldInfo: EntityFieldInfo,\n entityInfo: EntityInfo,\n filePath: string,\n parentContext?: { entity: string; field: string },\n ): Promise<void> {\n if (typeof value === 'string' && this.isValidReference(value)) {\n await this.validateReference(value, fieldInfo, entityInfo, filePath, parentContext);\n // Skip further validation for references as they will be resolved later\n return;\n }\n\n // Validate field value against value list if applicable\n await this.validateFieldValueList(value, fieldInfo, entityInfo, filePath);\n\n // Validate UserID fields against allowed roles\n if (fieldInfo.Name === 'UserID' && typeof value === 'string' && value.length > 0) {\n // Get the sync config from the file's directory\n const dir = path.dirname(filePath);\n\n // Walk up to find the root sync config with userRoleValidation\n let currentDir = dir;\n let config = null;\n while (currentDir && currentDir !== path.parse(currentDir).root) {\n const currentConfigPath = path.join(currentDir, '.mj-sync.json');\n if (fs.existsSync(currentConfigPath)) {\n try {\n const currentConfig = JSON.parse(fs.readFileSync(currentConfigPath, 'utf8'));\n if (currentConfig.userRoleValidation) {\n config = currentConfig;\n break;\n }\n } catch {\n // Ignore parse errors\n }\n }\n currentDir = path.dirname(currentDir);\n }\n\n if (config?.userRoleValidation?.enabled) {\n await this.validateUserRole(value, entityInfo.Name, fieldInfo.Name, filePath, config);\n }\n }\n\n // Add other type validation here if needed\n }\n\n /**\n * Validates field value against the field's value list if applicable\n */\n private async validateFieldValueList(\n value: any,\n fieldInfo: EntityFieldInfo,\n entityInfo: EntityInfo,\n filePath: string\n ): Promise<void> {\n // Skip validation if value is null/undefined (handled by required field check)\n if (value === null || value === undefined || value === '') {\n return;\n }\n\n // Check if this field has a value list constraint\n if (fieldInfo.ValueListType !== 'List') {\n return;\n }\n\n // Get the allowed values from EntityFieldValues\n const entityFieldValues = fieldInfo.EntityFieldValues;\n if (!entityFieldValues || !Array.isArray(entityFieldValues) || entityFieldValues.length === 0) {\n // No values defined, skip validation\n return;\n }\n\n // Extract the allowed values\n const allowedValues = entityFieldValues.map((efv: any) => efv.Value);\n \n // Convert value to string for comparison (in case it's a number or boolean)\n const stringValue = String(value);\n \n // Check if the value is in the allowed list\n if (!allowedValues.includes(stringValue)) {\n // Check case-insensitive match as a warning\n const caseInsensitiveMatch = allowedValues.find((av: string) => \n av.toLowerCase() === stringValue.toLowerCase()\n );\n \n if (caseInsensitiveMatch) {\n this.addWarning({\n type: 'validation',\n severity: 'warning',\n entity: entityInfo.Name,\n field: fieldInfo.Name,\n file: filePath,\n message: `Field \"${fieldInfo.Name}\" has value \"${stringValue}\" which differs in case from allowed value \"${caseInsensitiveMatch}\"`,\n suggestion: `Use \"${caseInsensitiveMatch}\" for consistency`,\n });\n } else {\n // Format the allowed values list for display\n const allowedValuesList = allowedValues.length <= 10 \n ? allowedValues.join(', ')\n : allowedValues.slice(0, 10).join(', ') + `, ... (${allowedValues.length - 10} more)`;\n \n this.addError({\n type: 'field',\n severity: 'error',\n entity: entityInfo.Name,\n field: fieldInfo.Name,\n file: filePath,\n message: `Field \"${fieldInfo.Name}\" has invalid value \"${stringValue}\"`,\n suggestion: `Allowed values are: ${allowedValuesList}`,\n });\n }\n }\n }\n\n /**\n * Check if a string is actually a MetadataSync reference (not just any @ string)\n */\n private isValidReference(value: string): boolean {\n return isMetadataKeyword(value);\n }\n\n /**\n * Validates special references (@file:, @lookup:, etc.)\n */\n private async validateReference(\n reference: string,\n fieldInfo: EntityFieldInfo,\n entityInfo: EntityInfo,\n filePath: string,\n parentContext?: { entity: string; field: string },\n ): Promise<void> {\n const parsed = this.parseReference(reference);\n if (!parsed) {\n this.addError({\n type: 'reference',\n severity: 'error',\n entity: entityInfo.Name,\n field: fieldInfo.Name,\n file: filePath,\n message: `Invalid reference format: \"${reference}\"`,\n });\n return;\n }\n\n switch (parsed.type) {\n case METADATA_KEYWORDS.FILE:\n await this.validateFileReference(parsed.value, filePath, entityInfo.Name, fieldInfo.Name);\n break;\n case METADATA_KEYWORDS.LOOKUP:\n await this.validateLookupReference(parsed, filePath, entityInfo.Name, fieldInfo.Name);\n break;\n case METADATA_KEYWORDS.TEMPLATE:\n await this.validateTemplateReference(parsed.value, filePath, entityInfo.Name, fieldInfo.Name);\n break;\n case METADATA_KEYWORDS.PARENT:\n this.validateParentReference(parsed.value, parentContext, filePath, entityInfo.Name, fieldInfo.Name);\n break;\n case METADATA_KEYWORDS.ROOT:\n this.validateRootReference(parsed.value, parentContext, filePath, entityInfo.Name, fieldInfo.Name);\n break;\n }\n }\n\n /**\n * Parses a reference string\n */\n private parseReference(reference: string): ParsedReference | null {\n const patterns: [ReferenceType, RegExp][] = [\n [METADATA_KEYWORDS.FILE, /^@file:(.+)$/],\n [METADATA_KEYWORDS.LOOKUP, /^@lookup:([^.]+)\\.(.+)$/],\n [METADATA_KEYWORDS.TEMPLATE, /^@template:(.+)$/],\n [METADATA_KEYWORDS.PARENT, /^@parent:(.+)$/],\n [METADATA_KEYWORDS.ROOT, /^@root:(.+)$/],\n [METADATA_KEYWORDS.ENV, /^@env:(.+)$/],\n ];\n\n for (const [type, pattern] of patterns) {\n const match = reference.match(pattern);\n if (match) {\n if (type === METADATA_KEYWORDS.LOOKUP) {\n const [, entity, remaining] = match;\n \n // Check if this has ?create syntax\n const hasCreate = remaining.includes('?create');\n const lookupPart = hasCreate ? remaining.split('?')[0] : remaining;\n \n // Parse all lookup fields (can be multiple with &)\n const lookupPairs = lookupPart.split('&');\n const fields: Array<{field: string, value: string}> = [];\n \n for (const pair of lookupPairs) {\n const fieldMatch = pair.match(/^(.+?)=(.+)$/);\n if (fieldMatch) {\n const [, field, value] = fieldMatch;\n fields.push({ field: field.trim(), value: value.trim() });\n }\n }\n \n // For backward compatibility, use the first field as primary\n const primaryField = fields.length > 0 ? fields[0] : { field: '', value: '' };\n \n // Parse additional fields for creation if ?create is present\n const additionalFields: Record<string, any> = {};\n if (hasCreate && remaining.includes('?create&')) {\n const createPart = remaining.split('?create&')[1];\n const pairs = createPart.split('&');\n for (const pair of pairs) {\n const [key, val] = pair.split('=');\n if (key && val) {\n additionalFields[key] = decodeURIComponent(val);\n }\n }\n }\n\n return { \n type, \n value: primaryField.value, \n entity, \n field: primaryField.field,\n fields, // Include all fields for validation\n createIfMissing: hasCreate, \n additionalFields \n };\n }\n return { type, value: match[1] };\n }\n }\n\n return null;\n }\n\n /**\n * Validates @file: references\n */\n private async validateFileReference(filePath: string, sourceFile: string, entityName: string, fieldName: string, visitedFiles?: Set<string>): Promise<void> {\n const dir = path.dirname(sourceFile);\n const resolvedPath = path.resolve(dir, filePath);\n\n // Initialize visited files set if not provided (for circular reference detection)\n const visited = visitedFiles || new Set<string>();\n \n // Check for circular references\n if (visited.has(resolvedPath)) {\n this.addError({\n type: 'reference',\n severity: 'error',\n entity: entityName,\n field: fieldName,\n file: sourceFile,\n message: `Circular @file reference detected: \"${filePath}\"`,\n details: `Path ${resolvedPath} is already being processed`,\n suggestion: 'Restructure your file references to avoid circular dependencies',\n });\n return;\n }\n\n if (!fs.existsSync(resolvedPath)) {\n this.addError({\n type: 'reference',\n severity: 'error',\n entity: entityName,\n field: fieldName,\n file: sourceFile,\n message: `File reference not found: \"${filePath}\"`,\n suggestion: `Create file at: ${resolvedPath}`,\n });\n return;\n }\n\n // Add to visited set\n visited.add(resolvedPath);\n\n // Read the file and check for references\n try {\n const content = fs.readFileSync(resolvedPath, 'utf-8');\n \n // Check for {@include} references in all file types\n await this.validateIncludeReferences(content, resolvedPath, new Set([resolvedPath]));\n \n // If it's a JSON file, parse and validate nested @ references\n if (resolvedPath.endsWith('.json')) {\n try {\n const jsonContent = JSON.parse(content);\n \n // Check if JSON contains @include directives that need preprocessing\n const jsonString = JSON.stringify(jsonContent);\n const hasIncludes = jsonString.includes('\"@include\"') || jsonString.includes('\"@include.');\n \n if (hasIncludes) {\n await this.validateJsonIncludes(jsonContent, resolvedPath);\n }\n \n // Recursively validate all @ references in the JSON structure\n await this.validateJsonReferences(jsonContent, resolvedPath, entityName, visited);\n } catch (parseError) {\n // Not valid JSON or error parsing, treat as text file (already validated {@include} above)\n if (this.options.verbose) {\n console.log(`File ${resolvedPath} is not valid JSON, treating as text file`);\n }\n }\n }\n } catch (error) {\n this.addError({\n type: 'reference',\n severity: 'error',\n entity: entityName,\n field: fieldName,\n file: sourceFile,\n message: `Failed to read file reference: \"${filePath}\"`,\n details: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Validates @lookup: references\n */\n private async validateLookupReference(parsed: ParsedReference, sourceFile: string, entityName: string, fieldName: string): Promise<void> {\n const lookupEntity = this.metadata.EntityByName(parsed.entity!);\n\n if (!lookupEntity) {\n this.addError({\n type: 'reference',\n severity: 'error',\n entity: entityName,\n field: fieldName,\n file: sourceFile,\n message: `Lookup entity \"${parsed.entity}\" not found`,\n suggestion: 'Check entity name spelling and case',\n });\n return;\n }\n\n // For multi-field lookups, validate all fields\n if (parsed.fields && parsed.fields.length > 0) {\n for (const {field} of parsed.fields) {\n const lookupField = lookupEntity.Fields.find((f: any) => f.Name === field);\n if (!lookupField) {\n this.addError({\n type: 'reference',\n severity: 'error',\n entity: entityName,\n field: fieldName,\n file: sourceFile,\n message: `Lookup field \"${field}\" not found on entity \"${parsed.entity}\"`,\n suggestion: `Available fields: ${lookupEntity.Fields.map((f: any) => f.Name).join(', ')}`,\n });\n }\n }\n } else if (parsed.field) {\n // Fallback for single field lookup (backward compatibility)\n const lookupField = lookupEntity.Fields.find((f: any) => f.Name === parsed.field);\n if (!lookupField) {\n this.addError({\n type: 'reference',\n severity: 'error',\n entity: entityName,\n field: fieldName,\n file: sourceFile,\n message: `Lookup field \"${parsed.field}\" not found on entity \"${parsed.entity}\"`,\n suggestion: `Available fields: ${lookupEntity.Fields.map((f: any) => f.Name).join(', ')}`,\n });\n }\n }\n\n // Track dependency\n this.addEntityDependency(entityName, parsed.entity!);\n }\n\n /**\n * Validates @template: references\n */\n private async validateTemplateReference(templatePath: string, sourceFile: string, entityName: string, fieldName: string): Promise<void> {\n const dir = path.dirname(sourceFile);\n const resolvedPath = path.resolve(dir, templatePath);\n\n if (!fs.existsSync(resolvedPath)) {\n this.addError({\n type: 'reference',\n severity: 'error',\n entity: entityName,\n field: fieldName,\n file: sourceFile,\n message: `Template file not found: \"${templatePath}\"`,\n suggestion: `Create template at: ${resolvedPath}`,\n });\n return;\n }\n\n // Validate template is valid JSON\n try {\n JSON.parse(fs.readFileSync(resolvedPath, 'utf8'));\n } catch (error) {\n this.addError({\n type: 'reference',\n severity: 'error',\n entity: entityName,\n field: fieldName,\n file: sourceFile,\n message: `Template file is not valid JSON: \"${templatePath}\"`,\n details: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Validates @parent: references\n */\n private validateParentReference(\n _fieldName: string,\n parentContext: { entity: string; field: string } | undefined,\n sourceFile: string,\n entityName: string,\n currentFieldName: string,\n ): void {\n if (!parentContext) {\n this.addError({\n type: 'reference',\n severity: 'error',\n entity: entityName,\n field: currentFieldName,\n file: sourceFile,\n message: `@parent: reference used but no parent context exists`,\n suggestion: '@parent: can only be used in nested/related entities',\n });\n }\n }\n\n /**\n * Validates @root: references\n */\n private validateRootReference(\n _fieldName: string,\n parentContext: { entity: string; field: string } | undefined,\n sourceFile: string,\n entityName: string,\n currentFieldName: string,\n ): void {\n if (!parentContext) {\n this.addError({\n type: 'reference',\n severity: 'error',\n entity: entityName,\n field: currentFieldName,\n file: sourceFile,\n message: `@root: reference used but no root context exists`,\n suggestion: '@root: can only be used in nested/related entities',\n });\n }\n }\n\n /**\n * Track entity dependencies\n */\n private trackEntityDependencies(entityData: EntityData, entityName: string, filePath: string): void {\n if (!this.entityDependencies.has(entityName)) {\n this.entityDependencies.set(entityName, {\n entityName,\n dependsOn: new Set(),\n file: filePath,\n });\n }\n\n // Track dependencies from lookups in fields\n if (entityData.fields) {\n for (const value of Object.values(entityData.fields)) {\n if (typeof value === 'string' && value.startsWith(METADATA_KEYWORDS.LOOKUP)) {\n const parsed = this.parseReference(value);\n if (parsed?.entity) {\n this.addEntityDependency(entityName, parsed.entity);\n }\n }\n }\n }\n }\n\n /**\n * Add an entity dependency\n */\n private addEntityDependency(from: string, to: string): void {\n // Don't add self-references as dependencies (e.g., ParentID in hierarchical structures)\n if (from === to) {\n return;\n }\n \n if (!this.entityDependencies.has(from)) {\n this.entityDependencies.set(from, {\n entityName: from,\n dependsOn: new Set(),\n file: '',\n });\n }\n this.entityDependencies.get(from)!.dependsOn.add(to);\n }\n\n /**\n * Validates dependency order\n */\n private async validateDependencyOrder(directoryOrder: string[]): Promise<void> {\n // Build a map of entity to directory\n const entityToDirectory = new Map<string, string>();\n\n for (const dir of directoryOrder) {\n // This is simplified - in reality we'd need to read the .mj-sync.json\n // to get the actual entity name\n entityToDirectory.set(dir, dir);\n }\n\n // Check for circular dependencies\n const visited = new Set<string>();\n const recursionStack = new Set<string>();\n\n for (const [entity] of this.entityDependencies) {\n if (!visited.has(entity)) {\n this.checkCircularDependency(entity, visited, recursionStack);\n }\n }\n\n // Check if current order satisfies dependencies\n const orderViolations = this.checkDependencyOrder(directoryOrder);\n if (orderViolations.length > 0) {\n // Suggest a corrected order\n const suggestedOrder = this.topologicalSort();\n\n for (const violation of orderViolations) {\n this.addError({\n type: 'dependency',\n severity: 'error',\n entity: violation.entity,\n file: violation.file,\n message: `Entity '${violation.entity}' depends on '${violation.dependency}' but is processed before it`,\n suggestion: `Reorder directories to: [${suggestedOrder.join(', ')}]`,\n });\n }\n }\n }\n\n /**\n * Check for circular dependencies\n */\n private checkCircularDependency(entity: string, visited: Set<string>, recursionStack: Set<string>, path: string[] = []): boolean {\n visited.add(entity);\n recursionStack.add(entity);\n path.push(entity);\n\n const deps = this.entityDependencies.get(entity);\n if (deps) {\n for (const dep of deps.dependsOn) {\n if (!visited.has(dep)) {\n if (this.checkCircularDependency(dep, visited, recursionStack, [...path])) {\n return true;\n }\n } else if (recursionStack.has(dep)) {\n // Found circular dependency\n const cycle = [...path, dep];\n const cycleStart = cycle.indexOf(dep);\n const cyclePath = cycle.slice(cycleStart).join(' → ');\n\n this.addError({\n type: 'circular',\n severity: 'error',\n entity: entity,\n file: deps.file,\n message: `Circular dependency detected: ${cyclePath}`,\n suggestion: 'Restructure your entities to avoid circular references',\n });\n return true;\n }\n }\n }\n\n recursionStack.delete(entity);\n return false;\n }\n\n /**\n * Get directories in order based on config\n */\n private async getDirectoriesInOrder(rootDir: string, config: any): Promise<string[]> {\n const allDirs = fs\n .readdirSync(rootDir)\n .filter((f) => fs.statSync(path.join(rootDir, f)).isDirectory())\n .filter((d) => !d.startsWith('.'));\n\n let orderedDirs: string[];\n if (config.directoryOrder && Array.isArray(config.directoryOrder)) {\n const ordered = config.directoryOrder.filter((d: string) => allDirs.includes(d));\n const remaining = allDirs.filter((d) => !ordered.includes(d)).sort();\n orderedDirs = [...ordered, ...remaining];\n } else {\n orderedDirs = allDirs.sort();\n }\n\n // Apply include/exclude filters if specified\n return this.applyDirectoryFilters(orderedDirs);\n }\n\n /**\n * Apply include/exclude filters to directory list\n */\n private applyDirectoryFilters(directories: string[]): string[] {\n let filteredDirs = directories;\n\n // Apply include filter (whitelist)\n if (this.options.include && this.options.include.length > 0) {\n const minimatch = require('minimatch').minimatch;\n filteredDirs = directories.filter(dirName => {\n return this.options.include!.some(pattern =>\n minimatch(dirName, pattern, { nocase: true })\n );\n });\n }\n\n // Apply exclude filter (blacklist)\n if (this.options.exclude && this.options.exclude.length > 0) {\n const minimatch = require('minimatch').minimatch;\n filteredDirs = filteredDirs.filter(dirName => {\n return !this.options.exclude!.some(pattern =>\n minimatch(dirName, pattern, { nocase: true })\n );\n });\n }\n\n return filteredDirs;\n }\n\n /**\n * Get files matching pattern\n */\n private async getMatchingFiles(dir: string, pattern: string): Promise<string[]> {\n const files = fs.readdirSync(dir).filter((f) => fs.statSync(path.join(dir, f)).isFile());\n\n // Strip leading **/ from glob patterns (we only match in current directory)\n const normalizedPattern = pattern.replace(/^\\*\\*\\//, '');\n\n // Simple glob pattern matching\n if (normalizedPattern === '*.json') {\n return files.filter((f) => f.endsWith('.json') && !f.startsWith('.mj-'));\n } else if (normalizedPattern === '.*.json') {\n return files.filter((f) => f.startsWith('.') && f.endsWith('.json') && !f.startsWith('.mj-'));\n }\n\n return files;\n }\n\n /**\n * Add an error\n */\n private addError(error: ValidationError): void {\n this.errors.push(error);\n }\n\n /**\n * Add a warning\n */\n private addWarning(warning: ValidationWarning): void {\n this.warnings.push(warning);\n }\n\n /**\n * Check if current directory order satisfies dependencies\n */\n private checkDependencyOrder(directoryOrder: string[]): Array<{ entity: string; dependency: string; file: string }> {\n const violations: Array<{ entity: string; dependency: string; file: string }> = [];\n const processedEntities = new Set<string>();\n\n for (const dir of directoryOrder) {\n // In real implementation, we'd read .mj-sync.json to get entity name\n const entityName = dir; // Simplified for now\n\n const deps = this.entityDependencies.get(entityName);\n if (deps) {\n for (const dep of deps.dependsOn) {\n if (!processedEntities.has(dep) && directoryOrder.includes(dep)) {\n violations.push({\n entity: entityName,\n dependency: dep,\n file: deps.file,\n });\n }\n }\n }\n\n processedEntities.add(entityName);\n }\n\n return violations;\n }\n\n /**\n * Perform topological sort on entity dependencies\n */\n private topologicalSort(): string[] {\n const result: string[] = [];\n const visited = new Set<string>();\n const tempStack = new Set<string>();\n\n const visit = (entity: string): boolean => {\n if (tempStack.has(entity)) {\n // Circular dependency, already handled by checkCircularDependency\n return false;\n }\n\n if (visited.has(entity)) {\n return true;\n }\n\n tempStack.add(entity);\n\n const deps = this.entityDependencies.get(entity);\n if (deps) {\n for (const dep of deps.dependsOn) {\n if (!visit(dep)) {\n return false;\n }\n }\n }\n\n tempStack.delete(entity);\n visited.add(entity);\n result.push(entity);\n\n return true;\n };\n\n // Visit all entities\n for (const entity of this.entityDependencies.keys()) {\n if (!visited.has(entity)) {\n visit(entity);\n }\n }\n\n return result;\n }\n\n /**\n * Reset validation state\n */\n private reset(): void {\n this.errors = [];\n this.warnings = [];\n this.entityDependencies.clear();\n this.processedEntities.clear();\n this.userRoleCache.clear();\n }\n\n /**\n * Get validation result\n */\n private getResult(): ValidationResult {\n return {\n isValid: this.errors.length === 0,\n errors: this.errors,\n warnings: this.warnings,\n summary: {\n totalFiles: 0,\n totalEntities: 0,\n totalErrors: this.errors.length,\n totalWarnings: this.warnings.length,\n fileResults: new Map(),\n },\n };\n }\n\n /**\n * Load user roles from the database into cache\n */\n private async loadUserRoles(): Promise<void> {\n try {\n const rv = new RunView();\n const systemUser = getSystemUser();\n\n // Load all user roles with role names\n const result = await rv.RunView(\n {\n EntityName: 'User Roles',\n ExtraFilter: '',\n OrderBy: 'UserID',\n MaxRows: 10000,\n },\n systemUser,\n );\n\n if (!result.Success) {\n this.addWarning({\n type: 'validation',\n severity: 'warning',\n file: 'system',\n message: 'Failed to load user roles for validation',\n details: result.ErrorMessage,\n });\n return;\n }\n\n // Group roles by UserID\n for (const userRole of result.Results || []) {\n const userId = userRole.UserID;\n const roleName = userRole.Role;\n\n if (!this.userRoleCache.has(userId)) {\n this.userRoleCache.set(userId, []);\n }\n this.userRoleCache.get(userId)!.push(roleName);\n }\n\n if (this.options.verbose) {\n console.log(`Loaded roles for ${this.userRoleCache.size} users`);\n }\n } catch (error) {\n this.addWarning({\n type: 'validation',\n severity: 'warning',\n file: 'system',\n message: 'Error loading user roles for validation',\n details: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Validate a UserID field value against allowed roles\n */\n private async validateUserRole(userId: string, entityName: string, fieldName: string, filePath: string, config: any): Promise<void> {\n // Skip if user role validation is not enabled\n if (!config.userRoleValidation?.enabled) {\n return;\n }\n\n const userRoles = this.userRoleCache.get(userId);\n const allowedRoles = config.userRoleValidation.allowedRoles || [];\n const allowUsersWithoutRoles = config.userRoleValidation.allowUsersWithoutRoles || false;\n\n if (!userRoles || userRoles.length === 0) {\n if (!allowUsersWithoutRoles) {\n this.addError({\n type: 'validation',\n severity: 'error',\n entity: entityName,\n field: fieldName,\n file: filePath,\n message: `UserID '${userId}' does not have any assigned roles`,\n suggestion:\n allowedRoles.length > 0\n ? `User must have one of these roles: ${allowedRoles.join(', ')}`\n : 'Assign appropriate roles to this user or set allowUsersWithoutRoles: true',\n });\n }\n return;\n }\n\n // Check if user has at least one allowed role\n if (allowedRoles.length > 0) {\n const hasAllowedRole = userRoles.some((role) => allowedRoles.includes(role));\n if (!hasAllowedRole) {\n this.addError({\n type: 'validation',\n severity: 'error',\n entity: entityName,\n field: fieldName,\n file: filePath,\n message: `UserID '${userId}' has roles [${userRoles.join(', ')}] but none are in allowed list`,\n suggestion: `Allowed roles: ${allowedRoles.join(', ')}`,\n });\n }\n }\n }\n\n /**\n * Validates {@include} references within file content\n * \n * Recursively checks all {@include path} references in file content to ensure:\n * - Referenced files exist\n * - No circular references occur\n * - Include paths are valid\n * \n * @param content - The file content to validate\n * @param filePath - Path of the file being validated\n * @param visitedPaths - Set of already visited paths for circular reference detection\n */\n private async validateIncludeReferences(content: string, filePath: string, visitedPaths: Set<string>): Promise<void> {\n // Pattern to match {@include path} references\n const includePattern = /\\{@include\\s+([^\\}]+)\\s*\\}/g;\n let match: RegExpExecArray | null;\n \n while ((match = includePattern.exec(content)) !== null) {\n const [fullMatch, includePath] = match;\n const trimmedPath = includePath.trim();\n \n // Resolve the include path relative to the current file's directory\n const currentDir = path.dirname(filePath);\n const resolvedPath = path.resolve(currentDir, trimmedPath);\n \n // Check for circular reference\n if (visitedPaths.has(resolvedPath)) {\n this.addError({\n type: 'reference',\n severity: 'error',\n file: filePath,\n message: `Circular {@include} reference detected: \"${trimmedPath}\"`,\n details: `Path ${resolvedPath} is already being processed`,\n suggestion: 'Restructure your includes to avoid circular references',\n });\n continue;\n }\n \n // Check if the included file exists\n if (!fs.existsSync(resolvedPath)) {\n this.addError({\n type: 'reference',\n severity: 'error',\n file: filePath,\n message: `{@include} file not found: \"${trimmedPath}\"`,\n suggestion: `Create file at: ${resolvedPath}`,\n });\n continue;\n }\n \n // Recursively validate the included file\n try {\n const includedContent = fs.readFileSync(resolvedPath, 'utf-8');\n const newVisitedPaths = new Set(visitedPaths);\n newVisitedPaths.add(resolvedPath);\n await this.validateIncludeReferences(includedContent, resolvedPath, newVisitedPaths);\n } catch (error) {\n this.addError({\n type: 'reference',\n severity: 'error',\n file: filePath,\n message: `Failed to read {@include} file: \"${trimmedPath}\"`,\n details: error instanceof Error ? error.message : String(error),\n });\n }\n }\n }\n\n /**\n * Validates @include directives in JSON files\n */\n private async validateJsonIncludes(jsonContent: any, sourceFile: string): Promise<void> {\n // Process based on data type\n if (Array.isArray(jsonContent)) {\n for (const item of jsonContent) {\n if (typeof item === 'string' && item.startsWith(`${METADATA_KEYWORDS.INCLUDE}:`)) {\n const includePath = extractKeywordValue(item) as string;\n await this.validateIncludeFile(includePath.trim(), sourceFile);\n } else if (item && typeof item === 'object') {\n await this.validateJsonIncludes(item, sourceFile);\n }\n }\n } else if (jsonContent && typeof jsonContent === 'object') {\n for (const [key, value] of Object.entries(jsonContent)) {\n if (key === METADATA_KEYWORDS.INCLUDE || key.startsWith(`${METADATA_KEYWORDS.INCLUDE}.`)) {\n let includeFile: string;\n if (typeof value === 'string') {\n includeFile = value;\n } else if (value && typeof value === 'object' && 'file' in value) {\n includeFile = (value as any).file;\n } else {\n this.addError({\n type: 'reference',\n severity: 'error',\n file: sourceFile,\n message: `Invalid @include directive format for key \"${key}\"`,\n suggestion: 'Use either a string path or an object with a \"file\" property',\n });\n continue;\n }\n await this.validateIncludeFile(includeFile, sourceFile);\n } else if (value && typeof value === 'object') {\n await this.validateJsonIncludes(value, sourceFile);\n }\n }\n }\n }\n\n /**\n * Validates a single include file path\n */\n private async validateIncludeFile(includePath: string, sourceFile: string): Promise<void> {\n const dir = path.dirname(sourceFile);\n const resolvedPath = path.resolve(dir, includePath);\n \n if (!fs.existsSync(resolvedPath)) {\n this.addError({\n type: 'reference',\n severity: 'error',\n file: sourceFile,\n message: `@include file not found: \"${includePath}\"`,\n suggestion: `Create file at: ${resolvedPath}`,\n });\n }\n }\n\n /**\n * Recursively validates all @ references in a JSON structure\n */\n private async validateJsonReferences(\n obj: any,\n sourceFile: string,\n entityName: string,\n visitedFiles: Set<string>,\n parentContext?: { entity: string; field: string }\n ): Promise<void> {\n if (obj === null || obj === undefined) {\n return;\n }\n\n if (Array.isArray(obj)) {\n for (const item of obj) {\n await this.validateJsonReferences(item, sourceFile, entityName, visitedFiles, parentContext);\n }\n } else if (typeof obj === 'object') {\n for (const [key, value] of Object.entries(obj)) {\n if (typeof value === 'string' && this.isValidReference(value)) {\n // Process different reference types\n if (value.startsWith(METADATA_KEYWORDS.FILE)) {\n const filePath = extractKeywordValue(value) as string;\n // Recursively validate the file reference (with circular detection)\n await this.validateFileReference(filePath, sourceFile, entityName, key, visitedFiles);\n } else if (value.startsWith(METADATA_KEYWORDS.LOOKUP)) {\n // Parse and validate lookup reference\n const parsed = this.parseReference(value);\n if (parsed) {\n await this.validateLookupReference(parsed, sourceFile, entityName, key);\n }\n } else if (value.startsWith(METADATA_KEYWORDS.TEMPLATE)) {\n const templatePath = extractKeywordValue(value) as string;\n await this.validateTemplateReference(templatePath, sourceFile, entityName, key);\n } else if (value.startsWith(METADATA_KEYWORDS.PARENT)) {\n const parsed = this.parseReference(value);\n if (parsed) {\n this.validateParentReference(parsed.value, parentContext, sourceFile, entityName, key);\n }\n } else if (value.startsWith(METADATA_KEYWORDS.ROOT)) {\n const parsed = this.parseReference(value);\n if (parsed) {\n this.validateRootReference(parsed.value, parentContext, sourceFile, entityName, key);\n }\n } else if (value.startsWith(METADATA_KEYWORDS.ENV)) {\n const envVar = extractKeywordValue(value) as string;\n if (!process.env[envVar]) {\n this.addWarning({\n type: 'validation',\n severity: 'warning',\n entity: entityName,\n field: key,\n file: sourceFile,\n message: `Environment variable \"${envVar}\" is not currently set`,\n suggestion: `Ensure this variable is set before running push operations`,\n });\n }\n }\n } else if (value && typeof value === 'object') {\n // Recursively process nested objects\n await this.validateJsonReferences(value, sourceFile, entityName, visitedFiles, parentContext);\n }\n }\n }\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/metadata-sync",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.130.0",
|
|
4
4
|
"description": "MemberJunction metadata synchronization CLI tool",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"metadata",
|
|
@@ -26,12 +26,12 @@
|
|
|
26
26
|
"build": "tsc -b"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@memberjunction/core": "2.
|
|
30
|
-
"@memberjunction/core-entities": "2.
|
|
31
|
-
"@memberjunction/core-entities-server": "2.
|
|
32
|
-
"@memberjunction/global": "2.
|
|
33
|
-
"@memberjunction/graphql-dataprovider": "2.
|
|
34
|
-
"@memberjunction/sqlserver-dataprovider": "2.
|
|
29
|
+
"@memberjunction/core": "2.130.0",
|
|
30
|
+
"@memberjunction/core-entities": "2.130.0",
|
|
31
|
+
"@memberjunction/core-entities-server": "2.130.0",
|
|
32
|
+
"@memberjunction/global": "2.130.0",
|
|
33
|
+
"@memberjunction/graphql-dataprovider": "2.130.0",
|
|
34
|
+
"@memberjunction/sqlserver-dataprovider": "2.130.0",
|
|
35
35
|
"axios": "^1.6.8",
|
|
36
36
|
"chalk": "^4.1.2",
|
|
37
37
|
"chokidar": "^3.6.0",
|