@memberjunction/metadata-sync 2.112.0 → 2.113.1

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.
Files changed (42) hide show
  1. package/README.md +136 -61
  2. package/dist/constants/metadata-keywords.d.ts +282 -0
  3. package/dist/constants/metadata-keywords.js +364 -0
  4. package/dist/constants/metadata-keywords.js.map +1 -0
  5. package/dist/lib/EntityPropertyExtractor.d.ts +1 -1
  6. package/dist/lib/EntityPropertyExtractor.js +4 -18
  7. package/dist/lib/EntityPropertyExtractor.js.map +1 -1
  8. package/dist/lib/FieldExternalizer.d.ts +1 -1
  9. package/dist/lib/FieldExternalizer.js +6 -5
  10. package/dist/lib/FieldExternalizer.js.map +1 -1
  11. package/dist/lib/RecordProcessor.d.ts +1 -1
  12. package/dist/lib/RecordProcessor.js +14 -12
  13. package/dist/lib/RecordProcessor.js.map +1 -1
  14. package/dist/lib/RelatedEntityHandler.d.ts +1 -1
  15. package/dist/lib/RelatedEntityHandler.js +5 -5
  16. package/dist/lib/RelatedEntityHandler.js.map +1 -1
  17. package/dist/lib/json-preprocessor.js +7 -6
  18. package/dist/lib/json-preprocessor.js.map +1 -1
  19. package/dist/lib/provider-utils.d.ts +1 -1
  20. package/dist/lib/provider-utils.js +19 -16
  21. package/dist/lib/provider-utils.js.map +1 -1
  22. package/dist/lib/record-dependency-analyzer.js +44 -37
  23. package/dist/lib/record-dependency-analyzer.js.map +1 -1
  24. package/dist/lib/singleton-manager.d.ts +1 -1
  25. package/dist/lib/singleton-manager.js.map +1 -1
  26. package/dist/lib/sync-engine.d.ts +1 -1
  27. package/dist/lib/sync-engine.js +36 -44
  28. package/dist/lib/sync-engine.js.map +1 -1
  29. package/dist/services/PullService.d.ts +1 -1
  30. package/dist/services/PullService.js +18 -22
  31. package/dist/services/PullService.js.map +1 -1
  32. package/dist/services/PushService.d.ts +1 -1
  33. package/dist/services/PushService.js +21 -15
  34. package/dist/services/PushService.js.map +1 -1
  35. package/dist/services/ValidationService.js +32 -44
  36. package/dist/services/ValidationService.js.map +1 -1
  37. package/dist/services/WatchService.d.ts +1 -1
  38. package/dist/services/WatchService.js +14 -13
  39. package/dist/services/WatchService.js.map +1 -1
  40. package/dist/types/validation.d.ts +6 -1
  41. package/dist/types/validation.js.map +1 -1
  42. package/package.json +7 -6
@@ -1 +1 @@
1
- {"version":3,"file":"PushService.js","sourceRoot":"","sources":["../../src/services/PushService.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs-extra';\nimport path from 'path';\nimport fastGlob from 'fast-glob';\nimport { BaseEntity, Metadata, UserInfo, EntitySaveOptions } from '@memberjunction/global';\nimport { SyncEngine, RecordData } from '../lib/sync-engine';\nimport { loadEntityConfig, loadSyncConfig } from '../config';\nimport { FileBackupManager } from '../lib/file-backup-manager';\nimport { configManager } from '../lib/config-manager';\nimport { SQLLogger } from '../lib/sql-logger';\nimport { TransactionManager } from '../lib/transaction-manager';\nimport { JsonWriteHelper } from '../lib/json-write-helper';\nimport { RecordDependencyAnalyzer, FlattenedRecord } from '../lib/record-dependency-analyzer';\nimport { JsonPreprocessor } from '../lib/json-preprocessor';\nimport type { SqlLoggingSession, SQLServerDataProvider } from '@memberjunction/sqlserver-dataprovider';\n\n// Configuration for parallel processing\nconst PARALLEL_BATCH_SIZE = 1; // Number of records to process in parallel at each dependency level\n/// TEMPORARILY DISABLED PARALLEL BY SETTING TO 1 as we were having some issues\n\nexport interface PushOptions {\n dir?: string;\n dryRun?: boolean;\n verbose?: boolean;\n noValidate?: boolean;\n parallelBatchSize?: number; // Number of records to process in parallel (default: 10)\n}\n\nexport interface PushCallbacks {\n onProgress?: (message: string) => void;\n onSuccess?: (message: string) => void;\n onError?: (message: string) => void;\n onWarn?: (message: string) => void;\n onLog?: (message: string) => void;\n onConfirm?: (message: string) => Promise<boolean>;\n}\n\nexport interface PushResult {\n created: number;\n updated: number;\n unchanged: number;\n deleted: number;\n skipped: number;\n errors: number;\n warnings: string[];\n sqlLogPath?: string;\n}\n\nexport interface EntityPushResult {\n created: number;\n updated: number;\n unchanged: number;\n deleted: number;\n skipped: number;\n errors: number;\n}\n\nexport class PushService {\n private syncEngine: SyncEngine;\n private contextUser: UserInfo;\n private warnings: string[] = [];\n private syncConfig: any;\n\n constructor(syncEngine: SyncEngine, contextUser: UserInfo) {\n this.syncEngine = syncEngine;\n this.contextUser = contextUser;\n }\n\n async push(options: PushOptions, callbacks?: PushCallbacks): Promise<PushResult> {\n this.warnings = [];\n\n const fileBackupManager = new FileBackupManager();\n\n // Load sync config for SQL logging settings and autoCreateMissingRecords flag\n // If dir option is specified, load from that directory, otherwise use original CWD\n const configDir = options.dir ? path.resolve(configManager.getOriginalCwd(), options.dir) : configManager.getOriginalCwd();\n this.syncConfig = await loadSyncConfig(configDir);\n\n // Display warnings for special flags that are enabled\n if (this.syncConfig?.push?.alwaysPush && !options.dryRun) {\n callbacks?.onWarn?.('\\n⚡ WARNING: alwaysPush is enabled - ALL records will be saved to database regardless of changes\\n');\n }\n if (this.syncConfig?.push?.autoCreateMissingRecords && !options.dryRun) {\n callbacks?.onWarn?.('\\n🔧 WARNING: autoCreateMissingRecords is enabled - Missing records with primaryKey will be created\\n');\n }\n\n if (options.verbose) {\n callbacks?.onLog?.(`Original working directory: ${configManager.getOriginalCwd()}`);\n callbacks?.onLog?.(`Config directory (with dir option): ${configDir}`);\n callbacks?.onLog?.(`Config file path: ${path.join(configDir, '.mj-sync.json')}`);\n callbacks?.onLog?.(`Full sync config loaded: ${JSON.stringify(this.syncConfig, null, 2)}`);\n callbacks?.onLog?.(`SQL logging config: ${JSON.stringify(this.syncConfig?.sqlLogging)}`);\n }\n\n const sqlLogger = new SQLLogger(this.syncConfig);\n const transactionManager = new TransactionManager(sqlLogger);\n\n if (options.verbose) {\n callbacks?.onLog?.(`SQLLogger enabled status: ${sqlLogger.enabled}`);\n }\n\n // Setup SQL logging session with the provider if enabled\n let sqlLoggingSession: SqlLoggingSession | null = null;\n\n try {\n // Initialize SQL logger if enabled and not dry-run\n if (sqlLogger.enabled && !options.dryRun) {\n const provider = Metadata.Provider as SQLServerDataProvider;\n\n if (options.verbose) {\n callbacks?.onLog?.(`SQL logging enabled: ${sqlLogger.enabled}`);\n callbacks?.onLog?.(`Provider type: ${provider?.constructor?.name || 'Unknown'}`);\n callbacks?.onLog?.(`Has CreateSqlLogger: ${typeof provider?.CreateSqlLogger === 'function'}`);\n }\n\n if (provider && typeof provider.CreateSqlLogger === 'function') {\n // Generate filename with timestamp\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n const filename = this.syncConfig.sqlLogging?.formatAsMigration ? `MetadataSync_Push_${timestamp}.sql` : `push_${timestamp}.sql`;\n\n // Use .sql-log-push directory in the config directory (where sync was initiated)\n const outputDir = path.join(configDir, this.syncConfig?.sqlLogging?.outputDirectory || './sql-log-push');\n const filepath = path.join(outputDir, filename);\n\n // Ensure the directory exists\n await fs.ensureDir(path.dirname(filepath));\n\n // Create the SQL logging session\n sqlLoggingSession = await provider.CreateSqlLogger(filepath, {\n formatAsMigration: this.syncConfig.sqlLogging?.formatAsMigration || false,\n description: 'MetadataSync push operation',\n statementTypes: 'mutations',\n prettyPrint: true,\n filterPatterns: this.syncConfig.sqlLogging?.filterPatterns,\n filterType: this.syncConfig.sqlLogging?.filterType,\n });\n\n if (options.verbose) {\n callbacks?.onLog?.(`📝 SQL logging enabled: ${filepath}`);\n }\n } else {\n if (options.verbose) {\n callbacks?.onWarn?.('SQL logging requested but provider does not support it');\n }\n }\n }\n\n // Find entity directories to process\n // Note: If options.dir is specified, configDir already points to that directory\n // So we don't need to pass it as specificDir\n const entityDirs = this.findEntityDirectories(configDir, undefined, this.syncConfig?.directoryOrder);\n\n if (entityDirs.length === 0) {\n throw new Error('No entity directories found');\n }\n\n if (options.verbose) {\n callbacks?.onLog?.(`Found ${entityDirs.length} entity ${entityDirs.length === 1 ? 'directory' : 'directories'} to process`);\n }\n\n // Initialize file backup manager (unless in dry-run mode)\n if (!options.dryRun) {\n await fileBackupManager.initialize();\n if (options.verbose) {\n callbacks?.onLog?.('📁 File backup manager initialized');\n }\n }\n\n // Process each entity directory\n let totalCreated = 0;\n let totalUpdated = 0;\n let totalUnchanged = 0;\n let totalDeleted = 0;\n let totalSkipped = 0;\n let totalErrors = 0;\n\n // Begin transaction if not in dry-run mode\n if (!options.dryRun) {\n await transactionManager.beginTransaction();\n }\n\n try {\n for (const entityDir of entityDirs) {\n const entityConfig = await loadEntityConfig(entityDir);\n if (!entityConfig) {\n const warning = `Skipping ${entityDir} - no valid entity configuration`;\n this.warnings.push(warning);\n callbacks?.onWarn?.(warning);\n totalSkipped++; // Count skipped directories\n continue;\n }\n\n // Show folder with spinner at start\n const dirName = path.relative(process.cwd(), entityDir) || '.';\n callbacks?.onLog?.(`\\n📁 ${dirName}:`);\n\n // Use onProgress for animated spinner if available\n if (callbacks?.onProgress) {\n callbacks.onProgress(`Processing ${dirName}...`);\n } else {\n callbacks?.onLog?.(` ⏳ Processing...`);\n }\n\n if (options.verbose && callbacks?.onLog) {\n callbacks.onLog(`Processing ${entityConfig.entity} in ${entityDir}`);\n }\n\n const result = await this.processEntityDirectory(entityDir, entityConfig, options, fileBackupManager, callbacks);\n\n // Stop the spinner if we were using onProgress\n if (callbacks?.onProgress && callbacks?.onSuccess) {\n callbacks.onSuccess(`Processed ${dirName}`);\n }\n\n // Show per-directory summary\n const dirTotal = result.created + result.updated + result.unchanged + result.deleted + result.skipped;\n if (dirTotal > 0 || result.errors > 0) {\n callbacks?.onLog?.(` Total processed: ${dirTotal} records`);\n if (result.created > 0) {\n callbacks?.onLog?.(` ✓ Created: ${result.created}`);\n }\n if (result.updated > 0) {\n callbacks?.onLog?.(` ✓ Updated: ${result.updated}`);\n }\n if (result.deleted > 0) {\n callbacks?.onLog?.(` ✓ Deleted: ${result.deleted}`);\n }\n if (result.unchanged > 0) {\n callbacks?.onLog?.(` - Unchanged: ${result.unchanged}`);\n }\n if (result.skipped > 0) {\n callbacks?.onLog?.(` - Skipped: ${result.skipped}`);\n }\n if (result.errors > 0) {\n callbacks?.onLog?.(` ✗ Errors: ${result.errors}`);\n }\n }\n\n totalCreated += result.created;\n totalUpdated += result.updated;\n totalUnchanged += result.unchanged;\n totalDeleted += result.deleted;\n totalSkipped += result.skipped;\n totalErrors += result.errors;\n }\n\n // Commit transaction if successful\n if (!options.dryRun && totalErrors === 0) {\n await transactionManager.commitTransaction();\n }\n } catch (error) {\n // Rollback transaction on error\n if (!options.dryRun) {\n callbacks?.onLog?.('\\n⚠️ Rolling back database transaction due to error...');\n await transactionManager.rollbackTransaction();\n callbacks?.onLog?.('✓ Database transaction rolled back successfully\\n');\n }\n throw error;\n }\n\n // Commit file backups if successful and not in dry-run mode\n if (!options.dryRun && totalErrors === 0) {\n await fileBackupManager.cleanup();\n if (options.verbose) {\n callbacks?.onLog?.('✅ File backups committed');\n }\n }\n\n // Close SQL logging session if it was created\n let sqlLogPath: string | undefined;\n if (sqlLoggingSession) {\n sqlLogPath = sqlLoggingSession.filePath;\n await sqlLoggingSession.dispose();\n if (options.verbose) {\n callbacks?.onLog?.(`📝 SQL log written to: ${sqlLogPath}`);\n }\n }\n\n return {\n created: totalCreated,\n updated: totalUpdated,\n unchanged: totalUnchanged,\n deleted: totalDeleted,\n skipped: totalSkipped,\n errors: totalErrors,\n warnings: this.warnings,\n sqlLogPath,\n };\n } catch (error) {\n // Rollback file backups on error\n if (!options.dryRun) {\n try {\n await fileBackupManager.rollback();\n callbacks?.onWarn?.('File backups rolled back due to error');\n } catch (rollbackError) {\n callbacks?.onWarn?.(`Failed to rollback file backups: ${rollbackError}`);\n }\n }\n\n // Close SQL logging session on error\n if (sqlLoggingSession) {\n try {\n await sqlLoggingSession.dispose();\n } catch (disposeError) {\n callbacks?.onWarn?.(`Failed to close SQL logging session: ${disposeError}`);\n }\n }\n\n throw error;\n }\n }\n\n private async processEntityDirectory(\n entityDir: string,\n entityConfig: any,\n options: PushOptions,\n fileBackupManager: FileBackupManager,\n callbacks?: PushCallbacks\n ): Promise<EntityPushResult> {\n let created = 0;\n let updated = 0;\n let unchanged = 0;\n let deleted = 0;\n let skipped = 0;\n let errors = 0;\n\n // Find all JSON files in the directory\n const pattern = entityConfig.filePattern || '*.json';\n const files = await fastGlob(pattern, {\n cwd: entityDir,\n absolute: true,\n onlyFiles: true,\n dot: true,\n ignore: ['**/node_modules/**', '**/.mj-*.json'],\n });\n\n if (options.verbose) {\n callbacks?.onLog?.(`Found ${files.length} files to process`);\n }\n\n // Process each file\n for (const filePath of files) {\n try {\n // Backup the file before any modifications (unless dry-run)\n if (!options.dryRun) {\n await fileBackupManager.backupFile(filePath);\n }\n\n // Read the raw file data first\n const rawFileData = await fs.readJson(filePath);\n\n // Only preprocess if there are @include directives\n let fileData = rawFileData;\n const jsonString = JSON.stringify(rawFileData);\n const hasIncludes = jsonString.includes('\"@include\"') || jsonString.includes('\"@include.');\n\n if (hasIncludes) {\n // Preprocess the JSON file to handle @include directives\n // Create a new preprocessor instance for each file to ensure clean state\n const jsonPreprocessor = new JsonPreprocessor();\n fileData = await jsonPreprocessor.processFile(filePath);\n }\n\n const records = Array.isArray(fileData) ? fileData : [fileData];\n const isArray = Array.isArray(fileData);\n\n // Analyze dependencies and get sorted records\n const analyzer = new RecordDependencyAnalyzer();\n const analysisResult = await analyzer.analyzeFileRecords(records, entityConfig.entity);\n\n if (analysisResult.circularDependencies.length > 0) {\n callbacks?.onWarn?.(`⚠️ Circular dependencies detected in ${filePath}`);\n for (const cycle of analysisResult.circularDependencies) {\n callbacks?.onWarn?.(` Cycle: ${cycle.join(' → ')}`);\n }\n }\n\n if (options.verbose) {\n callbacks?.onLog?.(` Analyzed ${analysisResult.sortedRecords.length} records (including nested)`);\n }\n\n // Create batch context for in-memory entity resolution\n // Note: While JavaScript is single-threaded, async operations can interleave.\n // Map operations themselves are atomic, but we ensure records are added to\n // the context AFTER successful save to maintain consistency.\n const batchContext = new Map<string, BaseEntity>();\n\n // Process records using dependency levels for parallel processing\n if (analysisResult.dependencyLevels && analysisResult.dependencyLevels.length > 0) {\n // Use parallel processing with dependency levels\n for (let levelIndex = 0; levelIndex < analysisResult.dependencyLevels.length; levelIndex++) {\n const level = analysisResult.dependencyLevels[levelIndex];\n\n if (options.verbose && level.length > 1) {\n callbacks?.onLog?.(` Processing dependency level ${levelIndex} with ${level.length} records in parallel...`);\n }\n\n // Process records in this level in parallel batches\n const batchSize = options.parallelBatchSize || PARALLEL_BATCH_SIZE;\n for (let i = 0; i < level.length; i += batchSize) {\n const batch = level.slice(i, Math.min(i + batchSize, level.length));\n\n // Process batch in parallel\n const batchResults = await Promise.all(\n batch.map(async (flattenedRecord) => {\n try {\n const result = await this.processFlattenedRecord(\n flattenedRecord,\n entityDir,\n options,\n batchContext,\n callbacks,\n entityConfig\n );\n return { success: true, result };\n } catch (error) {\n // Return error instead of throwing to handle after Promise.all\n return { success: false, error, record: flattenedRecord };\n }\n })\n );\n\n // Process results and check for errors\n for (const batchResult of batchResults) {\n if (!batchResult.success) {\n // Fail fast on first error with detailed logging\n const err = batchResult.error as Error;\n const rec = batchResult.record as FlattenedRecord;\n\n // Log concise summary - detailed error was already logged by processFlattenedRecord\n callbacks?.onLog?.(`\\n❌ Processing failed for ${rec.entityName} at ${rec.path}`);\n callbacks?.onLog?.(` ${err.message}\\n`);\n\n // Throw concise error to trigger rollback\n throw err;\n }\n\n // Update stats for successful results\n const result = batchResult.result!;\n if (result.isDuplicate) {\n skipped++; // Count duplicates as skipped\n } else {\n if (result.status === 'created') created++;\n else if (result.status === 'updated') updated++;\n else if (result.status === 'unchanged') unchanged++;\n else if (result.status === 'deleted') deleted++;\n else if (result.status === 'skipped') skipped++;\n else if (result.status === 'error') errors++;\n }\n }\n }\n }\n } else {\n // Fallback to sequential processing if no dependency levels available\n for (const flattenedRecord of analysisResult.sortedRecords) {\n try {\n const result = await this.processFlattenedRecord(flattenedRecord, entityDir, options, batchContext, callbacks, entityConfig);\n\n // Update stats\n if (result.isDuplicate) {\n skipped++; // Count duplicates as skipped\n } else {\n if (result.status === 'created') created++;\n else if (result.status === 'updated') updated++;\n else if (result.status === 'unchanged') unchanged++;\n else if (result.status === 'deleted') deleted++;\n else if (result.status === 'skipped') skipped++;\n else if (result.status === 'error') errors++;\n }\n } catch (recordError) {\n const errorMsg = `Error processing ${flattenedRecord.entityName} record at ${flattenedRecord.path}: ${recordError}`;\n callbacks?.onError?.(errorMsg);\n errors++;\n }\n }\n }\n\n // Write back to file (handles both single records and arrays)\n if (!options.dryRun) {\n if (isArray) {\n await JsonWriteHelper.writeOrderedRecordData(filePath, records);\n } else {\n // For single record files, write back the single record\n await JsonWriteHelper.writeOrderedRecordData(filePath, records[0]);\n }\n }\n } catch (fileError) {\n // Error details already logged by lower-level handlers, just re-throw\n throw fileError;\n }\n }\n\n return { created, updated, unchanged, deleted, skipped, errors };\n }\n\n private async processFlattenedRecord(\n flattenedRecord: FlattenedRecord,\n entityDir: string,\n options: PushOptions,\n batchContext: Map<string, BaseEntity>,\n callbacks?: PushCallbacks,\n entityConfig?: any\n ): Promise<{ status: 'created' | 'updated' | 'unchanged' | 'error' | 'deleted' | 'skipped'; isDuplicate?: boolean }> {\n const metadata = new Metadata();\n const { record, entityName, parentContext, id: recordId } = flattenedRecord;\n\n // Check if this record has a deleteRecord directive\n if (record.deleteRecord && record.deleteRecord.delete === true) {\n return await this.processDeleteRecord(flattenedRecord, entityDir, options, callbacks);\n }\n\n // Use the unique record ID from the flattened record for batch context\n // This ensures we can properly find parent entities even when they're new\n const lookupKey = recordId;\n\n // Check if already in batch context\n let entity = batchContext.get(lookupKey);\n if (entity) {\n // Already processed\n return { status: 'unchanged', isDuplicate: true };\n }\n\n // Get or create entity instance\n entity = await metadata.GetEntityObject(entityName, this.contextUser);\n if (!entity) {\n throw new Error(`Failed to create entity object for ${entityName}`);\n }\n\n // Check if record exists\n const primaryKey = record.primaryKey;\n let exists = false;\n let isNew = false;\n\n if (primaryKey && Object.keys(primaryKey).length > 0) {\n // First check if the record exists using the sync engine's loadEntity method\n // This avoids the \"Error in BaseEntity.Load\" message for missing records\n const existingEntity = await this.syncEngine.loadEntity(entityName, primaryKey);\n\n if (existingEntity) {\n // Record exists, use the loaded entity\n entity = existingEntity;\n exists = true;\n } else {\n // Record doesn't exist in database\n const autoCreate = this.syncConfig?.push?.autoCreateMissingRecords ?? false;\n const pkDisplay = Object.entries(primaryKey)\n .map(([key, value]) => `${key}=${value}`)\n .join(', ');\n\n if (!autoCreate) {\n const warning = `Record not found: ${entityName} with primaryKey {${pkDisplay}}. To auto-create missing records, set push.autoCreateMissingRecords=true in .mj-sync.json`;\n this.warnings.push(warning);\n callbacks?.onWarn?.(warning);\n return { status: 'error', isDuplicate: false }; // This will be counted as error, not skipped\n } else {\n // Log that we're creating the missing record\n if (options.verbose) {\n callbacks?.onLog?.(`📝 Creating missing ${entityName} record with primaryKey {${pkDisplay}}`);\n }\n }\n }\n }\n\n if (!exists) {\n entity.NewRecord();\n isNew = true;\n\n // Set primary key values for new records if provided\n if (primaryKey) {\n for (const [pkField, pkValue] of Object.entries(primaryKey)) {\n entity.Set(pkField, pkValue);\n }\n }\n }\n\n // Apply defaults if entityConfig is provided\n if (entityConfig) {\n const defaults = await this.syncEngine.buildDefaults(flattenedRecord.path, entityConfig);\n\n // Apply defaults only to fields not explicitly set in record.fields\n for (const [field, value] of Object.entries(defaults)) {\n if (!(field in record.fields) && field in entity) {\n entity.Set(field, value);\n }\n }\n }\n\n // Store original field values to preserve @ references\n const originalFields = { ...record.fields };\n\n // Get parent entity from context if available\n let parentEntity: BaseEntity | null = null;\n if (parentContext) {\n // Find the parent's flattened record ID\n // The parent record was flattened before this child, so it should have a lower ID number\n const parentRecordId = flattenedRecord.dependencies.values().next().value;\n if (parentRecordId) {\n parentEntity = batchContext.get(parentRecordId) || null;\n }\n\n if (!parentEntity) {\n // Parent should have been processed before child due to dependency ordering\n throw new Error(\n `Parent entity not found in batch context for ${entityName}. Parent dependencies: ${Array.from(flattenedRecord.dependencies).join(', ')}`\n );\n }\n }\n\n // Process field values with parent context and batch context\n // Process each field with better error reporting\n for (const [fieldName, fieldValue] of Object.entries(record.fields)) {\n try {\n const processedValue = await this.syncEngine.processFieldValue(\n fieldValue,\n entityDir,\n parentEntity,\n null, // rootRecord\n 0,\n batchContext // Pass batch context for lookups\n );\n entity.Set(fieldName, processedValue);\n } catch (fieldError: any) {\n // Enhanced error reporting for field processing failures\n const primaryKeyInfo = record.primaryKey ? JSON.stringify(record.primaryKey) : 'NEW';\n\n // Helper to log to both console and callbacks\n const logError = (msg: string) => {\n console.error(msg);\n callbacks?.onLog?.(msg);\n };\n\n // Check if this is a lookup failure\n if (fieldError.message?.includes('Lookup failed:')) {\n logError(`\\n❌ LOOKUP FAILURE in ${entityName} (${primaryKeyInfo})`);\n logError(` Field: ${fieldName}`);\n logError(` Value: ${fieldValue}`);\n logError(` Error: ${fieldError.message}`);\n logError(` Tip: Check if the referenced record exists in the target entity\\n`);\n } else if (fieldError.message?.includes('Entity not found:')) {\n logError(`\\n❌ ENTITY NOT FOUND in ${entityName} (${primaryKeyInfo})`);\n logError(` Field: ${fieldName}`);\n logError(` Value: ${fieldValue}`);\n logError(` Error: ${fieldError.message}`);\n logError(` Tip: Check if the entity name is spelled correctly\\n`);\n } else if (fieldError.message?.includes('Field') && fieldError.message?.includes('not found')) {\n logError(`\\n❌ FIELD NOT FOUND in ${entityName} (${primaryKeyInfo})`);\n logError(` Field: ${fieldName}`);\n logError(` Value: ${fieldValue}`);\n logError(` Error: ${fieldError.message}`);\n logError(` Tip: Check if the field name exists in the target entity\\n`);\n } else if (fieldError.message?.includes('File not found:')) {\n logError(`\\n❌ FILE NOT FOUND in ${entityName} (${primaryKeyInfo})`);\n logError(` Field: ${fieldName}`);\n logError(` Value: ${fieldValue}`);\n logError(` Error: ${fieldError.message}`);\n logError(` Tip: Check if the file path is correct relative to ${entityDir}\\n`);\n } else {\n logError(`\\n❌ FIELD PROCESSING ERROR in ${entityName} (${primaryKeyInfo})`);\n logError(` Field: ${fieldName}`);\n logError(` Value: ${fieldValue}`);\n logError(` Error: ${fieldError.message}\\n`);\n }\n\n // Re-throw with enhanced context\n throw new Error(`Failed to process field '${fieldName}' in ${entityName}: ${fieldError.message}`);\n }\n }\n\n // Check if the record is actually dirty before considering it changed\n let isDirty = entity.Dirty;\n\n // Force dirty state if alwaysPush is enabled\n const alwaysPush = this.syncConfig?.push?.alwaysPush ?? false;\n if (alwaysPush && !isNew) {\n isDirty = true;\n }\n\n // Also check if file content has changed (for @file references)\n if (!isDirty && !isNew && record.sync) {\n const currentChecksum = await this.syncEngine.calculateChecksumWithFileContent(originalFields, entityDir);\n if (currentChecksum !== record.sync.checksum) {\n isDirty = true;\n if (options.verbose) {\n callbacks?.onLog?.(`📄 File content changed for ${entityName} record (checksum mismatch)`);\n }\n }\n }\n\n if (options.dryRun) {\n if (exists) {\n callbacks?.onLog?.(`[DRY RUN] Would update ${entityName} record`);\n return { status: 'updated' };\n } else {\n callbacks?.onLog?.(`[DRY RUN] Would create ${entityName} record`);\n return { status: 'created' };\n }\n }\n\n // If updating an existing record that's dirty, show what changed\n if (!isNew && isDirty) {\n const changes = entity.GetChangesSinceLastSave();\n const changeKeys = Object.keys(changes);\n if (changeKeys.length > 0) {\n // Get primary key info for display\n const entityInfo = this.syncEngine.getEntityInfo(entityName);\n const primaryKeyDisplay: string[] = [];\n if (entityInfo) {\n for (const pk of entityInfo.PrimaryKeys) {\n primaryKeyDisplay.push(`${pk.Name}: ${entity.Get(pk.Name)}`);\n }\n }\n\n callbacks?.onLog?.(`📝 Updating ${entityName} record:`);\n if (primaryKeyDisplay.length > 0) {\n callbacks?.onLog?.(` Primary Key: ${primaryKeyDisplay.join(', ')}`);\n }\n callbacks?.onLog?.(` Changes:`);\n for (const fieldName of changeKeys) {\n const field = entity.GetFieldByName(fieldName);\n const oldValue = field ? field.OldValue : undefined;\n const newValue = (changes as any)[fieldName];\n callbacks?.onLog?.(` ${fieldName}: ${this.formatFieldValue(oldValue)} → ${this.formatFieldValue(newValue)}`);\n }\n }\n }\n\n // Save the record with detailed error logging\n const recordName = entity.Get('Name');\n const entityRecordId = entity.Get('ID');\n\n let saveResult;\n try {\n // Pass IgnoreDirtyState option when alwaysPush is enabled\n const saveOptions = alwaysPush ? { IgnoreDirtyState: true } : undefined;\n saveResult = await entity.Save(saveOptions);\n } catch (saveError: any) {\n // Helper to log to both console and callbacks\n const logError = (msg: string) => {\n console.error(msg);\n callbacks?.onLog?.(msg);\n };\n\n logError(`\\n❌ SAVE EXCEPTION for ${entityName}`);\n logError(` Record ID: ${entityRecordId || 'NEW'}`);\n logError(` Record Name: ${recordName || 'N/A'}`);\n logError(` File Path: ${flattenedRecord.path}`);\n logError(` Error: ${saveError.message || saveError}`);\n\n // Check for specific error patterns\n if (saveError.message?.includes('Cannot insert the value NULL')) {\n logError(` Tip: A required field is NULL. Check the entity's required fields.`);\n } else if (saveError.message?.includes('FOREIGN KEY constraint')) {\n logError(` Tip: Foreign key constraint violation. Check that referenced records exist.`);\n } else if (saveError.message?.includes('duplicate key')) {\n logError(` Tip: Duplicate key violation. A record with these values already exists.`);\n } else if (saveError.message?.includes('Incorrect syntax')) {\n logError(` Tip: SQL syntax error. Check for special characters in field values.`);\n }\n\n // Log problematic field values for debugging\n logError(`\\n Failed entity field values:`);\n for (const field of entity.Fields) {\n const value = entity.Get(field.Name);\n if (value !== null && value !== undefined) {\n const displayValue = typeof value === 'string' && value.length > 100 ? value.substring(0, 100) + '...' : value;\n logError(` ${field.Name}: ${displayValue}`);\n }\n }\n logError(''); // Empty line for readability\n throw saveError;\n }\n\n if (!saveResult) {\n // Helper to log to both console and callbacks\n const logError = (msg: string) => {\n console.error(msg);\n callbacks?.onLog?.(msg);\n };\n\n logError(`\\n❌ SAVE RETURNED FALSE for ${entityName}`);\n logError(` Record ID: ${entityRecordId || 'NEW'}`);\n logError(` Record Name: ${recordName || 'N/A'}`);\n logError(` File Path: ${flattenedRecord.path}`);\n\n // Log the LatestResult for debugging\n if (entity.LatestResult) {\n if (entity.LatestResult.Message) {\n logError(` Database Message: ${entity.LatestResult.Message}`);\n }\n if (entity.LatestResult.Errors && entity.LatestResult.Errors.length > 0) {\n logError(` Errors:`);\n entity.LatestResult.Errors.forEach((err: any, idx: number) => {\n const errorMsg = typeof err === 'string' ? err : err?.message || JSON.stringify(err);\n logError(` ${idx + 1}. ${errorMsg}`);\n });\n }\n if ((entity.LatestResult as any).SQL) {\n // Don't log the full SQL as it might be huge, just indicate it's available\n logError(` SQL Statement: [Available - check entity.LatestResult.SQL if needed]`);\n }\n }\n\n // Log field values that might be problematic\n logError(`\\n Entity field values:`);\n for (const field of entity.Fields) {\n const value = entity.Get(field.Name);\n if (value !== null && value !== undefined) {\n const displayValue = typeof value === 'string' && value.length > 100 ? value.substring(0, 100) + '...' : value;\n logError(` ${field.Name}: ${displayValue}`);\n }\n }\n logError(''); // Empty line for readability\n // Build detailed error information\n const entityInfo = this.syncEngine.getEntityInfo(entityName);\n const primaryKeyInfo: string[] = [];\n const fieldInfo: string[] = [];\n\n // Collect primary key information\n if (entityInfo) {\n for (const pk of entityInfo.PrimaryKeys) {\n const pkValue = entity.Get(pk.Name);\n primaryKeyInfo.push(`${pk.Name}=${this.formatFieldValue(pkValue)}`);\n }\n }\n\n // Collect field values that were being saved\n for (const [fieldName, fieldValue] of Object.entries(record.fields)) {\n const processedValue = entity.Get(fieldName);\n fieldInfo.push(`${fieldName}=${this.formatFieldValue(processedValue)}`);\n }\n\n // Get the actual error details from the entity\n const errorMessage = entity.LatestResult?.Message || 'Unknown error';\n const errorDetails =\n entity.LatestResult?.Errors?.map((err) => (typeof err === 'string' ? err : err?.message || JSON.stringify(err)))?.join(', ') || '';\n\n // Log detailed error information\n callbacks?.onError?.(`\\n❌ FATAL ERROR: Failed to save ${entityName} record`);\n callbacks?.onError?.(` Entity: ${entityName}`);\n if (primaryKeyInfo.length > 0) {\n callbacks?.onError?.(` Primary Key: {${primaryKeyInfo.join(', ')}}`);\n }\n callbacks?.onError?.(` Record Path: ${flattenedRecord.path}`);\n callbacks?.onError?.(` Is New Record: ${isNew}`);\n callbacks?.onError?.(` Field Values Being Saved:`);\n for (const field of fieldInfo) {\n callbacks?.onError?.(` - ${field}`);\n }\n callbacks?.onError?.(` SQL Error: ${errorMessage}`);\n if (errorDetails) {\n callbacks?.onError?.(` Additional Details: ${errorDetails}`);\n }\n\n // Check for common issues\n if (errorMessage.includes('conversion failed') || errorMessage.includes('GUID')) {\n callbacks?.onError?.(` ⚠️ This appears to be a GUID/UUID format error. Check that all ID fields contain valid GUIDs.`);\n }\n if (errorMessage.includes('transaction')) {\n callbacks?.onError?.(` ⚠️ Transaction error detected. The database transaction may be corrupted.`);\n }\n\n // Throw error to trigger rollback and stop processing\n throw new Error(`Failed to save ${entityName} record at ${flattenedRecord.path}: ${errorMessage}`);\n }\n\n // Add to batch context AFTER save so it has an ID for child @parent:ID references\n // Use the recordId (lookupKey) as the key so child records can find this parent\n batchContext.set(lookupKey, entity);\n\n // Update primaryKey for new records\n if (isNew) {\n const entityInfo = this.syncEngine.getEntityInfo(entityName);\n if (entityInfo) {\n const newPrimaryKey: Record<string, any> = {};\n for (const pk of entityInfo.PrimaryKeys) {\n newPrimaryKey[pk.Name] = entity.Get(pk.Name);\n }\n record.primaryKey = newPrimaryKey;\n }\n }\n\n // Only update sync metadata if the record was actually dirty (changed)\n if (isNew || isDirty) {\n record.sync = {\n lastModified: new Date().toISOString(),\n checksum: await this.syncEngine.calculateChecksumWithFileContent(originalFields, entityDir),\n };\n if (options.verbose) {\n callbacks?.onLog?.(` ✓ Updated sync metadata (record was ${isNew ? 'new' : 'changed'})`);\n }\n } else if (options.verbose) {\n callbacks?.onLog?.(` - Skipped sync metadata update (no changes detected)`);\n }\n\n // Restore original field values to preserve @ references\n record.fields = originalFields;\n\n return {\n status: isNew ? 'created' : isDirty ? 'updated' : 'unchanged',\n isDuplicate: false,\n };\n }\n\n private formatFieldValue(value: any): string {\n if (value === null || value === undefined) return 'null';\n if (typeof value === 'string') {\n // Truncate long strings and show quotes\n if (value.length > 50) {\n return `\"${value.substring(0, 47)}...\"`;\n }\n return `\"${value}\"`;\n }\n if (typeof value === 'object') {\n const str = JSON.stringify(value);\n return str.length > 50 ? `\"${str.substring(0, 47)}...\"` : `\"${str}\"`;\n }\n return String(value);\n }\n\n private async processDeleteRecord(\n flattenedRecord: FlattenedRecord,\n _entityDir: string,\n options: PushOptions,\n callbacks?: PushCallbacks\n ): Promise<{ status: 'deleted' | 'skipped' | 'unchanged'; isDuplicate?: boolean }> {\n const { record, entityName } = flattenedRecord;\n\n // Validate that we have a primary key for deletion\n if (!record.primaryKey || Object.keys(record.primaryKey).length === 0) {\n throw new Error(`Cannot delete ${entityName} record without primaryKey. Please specify primaryKey fields.`);\n }\n\n // Check if the deletion has already been processed\n if (record.deleteRecord?.deletedAt) {\n if (options.verbose) {\n callbacks?.onLog?.(` ℹ️ Record already deleted on ${record.deleteRecord.deletedAt}`);\n }\n // Return unchanged since the record is already in the desired state (deleted)\n return { status: 'unchanged', isDuplicate: false };\n }\n\n // Load the entity to verify it exists\n const existingEntity = await this.syncEngine.loadEntity(entityName, record.primaryKey);\n\n if (!existingEntity) {\n const pkDisplay = Object.entries(record.primaryKey)\n .map(([key, value]) => `${key}=${value}`)\n .join(', ');\n\n const warning = `Record not found for deletion: ${entityName} with primaryKey {${pkDisplay}}`;\n this.warnings.push(warning);\n callbacks?.onWarn?.(warning);\n\n // Mark as deleted anyway since it doesn't exist\n if (!record.deleteRecord) {\n record.deleteRecord = { delete: true };\n }\n record.deleteRecord.deletedAt = undefined; // Indicate it was not found\n record.deleteRecord.notFound = true;\n\n return { status: 'skipped', isDuplicate: false };\n }\n\n // Log the deletion\n const entityInfo = this.syncEngine.getEntityInfo(entityName);\n const primaryKeyDisplay: string[] = [];\n if (entityInfo) {\n for (const pk of entityInfo.PrimaryKeys) {\n primaryKeyDisplay.push(`${pk.Name}: ${existingEntity.Get(pk.Name)}`);\n }\n }\n\n callbacks?.onLog?.(`🗑️ Deleting ${entityName} record:`);\n if (primaryKeyDisplay.length > 0) {\n callbacks?.onLog?.(` Primary Key: ${primaryKeyDisplay.join(', ')}`);\n }\n\n // Additional info if available\n const recordName = existingEntity.Get('Name');\n if (recordName) {\n callbacks?.onLog?.(` Name: ${recordName}`);\n }\n\n if (options.dryRun) {\n callbacks?.onLog?.(`[DRY RUN] Would delete ${entityName} record`);\n return { status: 'deleted', isDuplicate: false };\n }\n\n // Delete the record\n try {\n const deleteResult = await existingEntity.Delete();\n\n if (!deleteResult) {\n // Check the LatestResult for error details\n const errorMessage = existingEntity.LatestResult?.Message || 'Unknown error';\n const errorDetails =\n existingEntity.LatestResult?.Errors?.map((err) => (typeof err === 'string' ? err : err?.message || JSON.stringify(err)))?.join(\n ', '\n ) || '';\n\n callbacks?.onError?.(`\\n❌ Failed to delete ${entityName} record`);\n callbacks?.onError?.(` Primary Key: {${primaryKeyDisplay.join(', ')}}`);\n callbacks?.onError?.(` Error: ${errorMessage}`);\n if (errorDetails) {\n callbacks?.onError?.(` Details: ${errorDetails}`);\n }\n\n throw new Error(`Failed to delete ${entityName} record: ${errorMessage}`);\n }\n\n // Update the deleteRecord section with deletedAt timestamp\n if (!record.deleteRecord) {\n record.deleteRecord = { delete: true };\n }\n record.deleteRecord.deletedAt = new Date().toISOString();\n\n // Remove notFound flag if it exists since we successfully found and deleted the record\n if (record.deleteRecord.notFound) {\n delete record.deleteRecord.notFound;\n }\n\n if (options.verbose) {\n callbacks?.onLog?.(` ✓ Successfully deleted ${entityName} record`);\n }\n\n return { status: 'deleted', isDuplicate: false };\n } catch (deleteError: any) {\n console.error(`\\n❌ DELETE EXCEPTION for ${entityName}`);\n console.error(` Primary Key: {${primaryKeyDisplay.join(', ')}}`);\n console.error(` Error: ${deleteError.message || deleteError}`);\n\n // Check for specific error patterns\n if (deleteError.message?.includes('FOREIGN KEY constraint')) {\n console.error(` Tip: This record is referenced by other records and cannot be deleted.`);\n console.error(` Consider deleting dependent records first.`);\n } else if (deleteError.message?.includes('permission')) {\n console.error(` Tip: You may not have permission to delete this record.`);\n }\n\n throw deleteError;\n }\n }\n\n private _buildBatchContextKey(entityName: string, record: RecordData): string {\n // Build a unique key for the batch context based on entity name and identifying fields\n const keyParts = [entityName];\n\n // Use primary key if available\n if (record.primaryKey) {\n for (const [field, value] of Object.entries(record.primaryKey)) {\n keyParts.push(`${field}=${value}`);\n }\n } else {\n // Use a combination of important fields as fallback\n const identifyingFields = ['Name', 'ID', 'Code', 'Email'];\n for (const field of identifyingFields) {\n if (record.fields[field]) {\n keyParts.push(`${field}=${record.fields[field]}`);\n }\n }\n }\n\n return keyParts.join('|');\n }\n\n private findEntityDirectories(baseDir: string, specificDir?: string, directoryOrder?: string[]): string[] {\n const dirs: string[] = [];\n\n if (specificDir) {\n // Process specific directory\n const fullPath = path.resolve(baseDir, specificDir);\n if (fs.existsSync(fullPath) && fs.statSync(fullPath).isDirectory()) {\n // Check if this directory has an entity configuration\n const configPath = path.join(fullPath, '.mj-sync.json');\n if (fs.existsSync(configPath)) {\n try {\n const config = fs.readJsonSync(configPath);\n if (config.entity) {\n // It's an entity directory, add it\n dirs.push(fullPath);\n } else {\n // It's a container directory, search its subdirectories\n this.findEntityDirectoriesRecursive(fullPath, dirs);\n }\n } catch {\n // Invalid config, skip\n }\n }\n }\n } else {\n // Find all entity directories\n this.findEntityDirectoriesRecursive(baseDir, dirs);\n }\n\n // Apply directory ordering if specified\n if (directoryOrder && directoryOrder.length > 0 && !specificDir) {\n // Create a map of directory name to order index\n const orderMap = new Map<string, number>();\n directoryOrder.forEach((dir, index) => {\n orderMap.set(dir, index);\n });\n\n // Sort directories based on the order map\n dirs.sort((a, b) => {\n const nameA = path.basename(a);\n const nameB = path.basename(b);\n const orderA = orderMap.get(nameA) ?? Number.MAX_SAFE_INTEGER;\n const orderB = orderMap.get(nameB) ?? Number.MAX_SAFE_INTEGER;\n\n // If both have specified orders, use them\n if (orderA !== Number.MAX_SAFE_INTEGER || orderB !== Number.MAX_SAFE_INTEGER) {\n return orderA - orderB;\n }\n\n // Otherwise, maintain original order (stable sort)\n return 0;\n });\n }\n\n return dirs;\n }\n\n private findEntityDirectoriesRecursive(dir: string, dirs: string[]): void {\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n if (entry.isDirectory() && !entry.name.startsWith('.') && entry.name !== 'node_modules') {\n const fullPath = path.join(dir, entry.name);\n const configPath = path.join(fullPath, '.mj-sync.json');\n\n if (fs.existsSync(configPath)) {\n try {\n const config = fs.readJsonSync(configPath);\n if (config.entity) {\n dirs.push(fullPath);\n }\n } catch {\n // Skip invalid config files\n }\n } else {\n // Recurse into subdirectories\n this.findEntityDirectoriesRecursive(fullPath, dirs);\n }\n }\n }\n }\n}\n"]}
1
+ {"version":3,"file":"PushService.js","sourceRoot":"","sources":["../../src/services/PushService.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs-extra';\nimport path from 'path';\nimport fastGlob from 'fast-glob';\nimport { BaseEntity, Metadata, UserInfo, EntitySaveOptions } from '@memberjunction/core';\nimport { SyncEngine, RecordData } from '../lib/sync-engine';\nimport { loadEntityConfig, loadSyncConfig } from '../config';\nimport { FileBackupManager } from '../lib/file-backup-manager';\nimport { configManager } from '../lib/config-manager';\nimport { SQLLogger } from '../lib/sql-logger';\nimport { TransactionManager } from '../lib/transaction-manager';\nimport { JsonWriteHelper } from '../lib/json-write-helper';\nimport { RecordDependencyAnalyzer, FlattenedRecord } from '../lib/record-dependency-analyzer';\nimport { JsonPreprocessor } from '../lib/json-preprocessor';\nimport type { SqlLoggingSession, SQLServerDataProvider } from '@memberjunction/sqlserver-dataprovider';\n\n// Configuration for parallel processing\nconst PARALLEL_BATCH_SIZE = 1; // Number of records to process in parallel at each dependency level\n/// TEMPORARILY DISABLED PARALLEL BY SETTING TO 1 as we were having some issues\n\nexport interface PushOptions {\n dir?: string;\n dryRun?: boolean;\n verbose?: boolean;\n noValidate?: boolean;\n parallelBatchSize?: number; // Number of records to process in parallel (default: 10)\n}\n\nexport interface PushCallbacks {\n onProgress?: (message: string) => void;\n onSuccess?: (message: string) => void;\n onError?: (message: string) => void;\n onWarn?: (message: string) => void;\n onLog?: (message: string) => void;\n onConfirm?: (message: string) => Promise<boolean>;\n}\n\nexport interface PushResult {\n created: number;\n updated: number;\n unchanged: number;\n deleted: number;\n skipped: number;\n errors: number;\n warnings: string[];\n sqlLogPath?: string;\n}\n\nexport interface EntityPushResult {\n created: number;\n updated: number;\n unchanged: number;\n deleted: number;\n skipped: number;\n errors: number;\n}\n\nexport class PushService {\n private syncEngine: SyncEngine;\n private contextUser: UserInfo;\n private warnings: string[] = [];\n private syncConfig: any;\n \n constructor(syncEngine: SyncEngine, contextUser: UserInfo) {\n this.syncEngine = syncEngine;\n this.contextUser = contextUser;\n }\n \n async push(options: PushOptions, callbacks?: PushCallbacks): Promise<PushResult> {\n this.warnings = [];\n \n const fileBackupManager = new FileBackupManager();\n \n // Load sync config for SQL logging settings and autoCreateMissingRecords flag\n // If dir option is specified, load from that directory, otherwise use original CWD\n const configDir = options.dir ? path.resolve(configManager.getOriginalCwd(), options.dir) : configManager.getOriginalCwd();\n this.syncConfig = await loadSyncConfig(configDir);\n \n // Display warnings for special flags that are enabled\n if (this.syncConfig?.push?.alwaysPush && !options.dryRun) {\n callbacks?.onWarn?.('\\n⚡ WARNING: alwaysPush is enabled - ALL records will be saved to database regardless of changes\\n');\n }\n if (this.syncConfig?.push?.autoCreateMissingRecords && !options.dryRun) {\n callbacks?.onWarn?.('\\n🔧 WARNING: autoCreateMissingRecords is enabled - Missing records with primaryKey will be created\\n');\n }\n \n if (options.verbose) {\n callbacks?.onLog?.(`Original working directory: ${configManager.getOriginalCwd()}`);\n callbacks?.onLog?.(`Config directory (with dir option): ${configDir}`);\n callbacks?.onLog?.(`Config file path: ${path.join(configDir, '.mj-sync.json')}`);\n callbacks?.onLog?.(`Full sync config loaded: ${JSON.stringify(this.syncConfig, null, 2)}`);\n callbacks?.onLog?.(`SQL logging config: ${JSON.stringify(this.syncConfig?.sqlLogging)}`);\n }\n \n const sqlLogger = new SQLLogger(this.syncConfig);\n const transactionManager = new TransactionManager(sqlLogger);\n \n if (options.verbose) {\n callbacks?.onLog?.(`SQLLogger enabled status: ${sqlLogger.enabled}`);\n }\n \n // Setup SQL logging session with the provider if enabled\n let sqlLoggingSession: SqlLoggingSession | null = null;\n \n try {\n // Initialize SQL logger if enabled and not dry-run\n if (sqlLogger.enabled && !options.dryRun) {\n const provider = Metadata.Provider as SQLServerDataProvider;\n \n if (options.verbose) {\n callbacks?.onLog?.(`SQL logging enabled: ${sqlLogger.enabled}`);\n callbacks?.onLog?.(`Provider type: ${provider?.constructor?.name || 'Unknown'}`);\n callbacks?.onLog?.(`Has CreateSqlLogger: ${typeof provider?.CreateSqlLogger === 'function'}`);\n }\n \n if (provider && typeof provider.CreateSqlLogger === 'function') {\n // Generate filename with timestamp\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n const filename = this.syncConfig.sqlLogging?.formatAsMigration \n ? `MetadataSync_Push_${timestamp}.sql`\n : `push_${timestamp}.sql`;\n \n // Use .sql-log-push directory in the config directory (where sync was initiated)\n const outputDir = path.join(configDir, this.syncConfig?.sqlLogging?.outputDirectory || './sql-log-push');\n const filepath = path.join(outputDir, filename);\n \n // Ensure the directory exists\n await fs.ensureDir(path.dirname(filepath));\n \n // Create the SQL logging session\n sqlLoggingSession = await provider.CreateSqlLogger(filepath, {\n formatAsMigration: this.syncConfig.sqlLogging?.formatAsMigration || false,\n description: 'MetadataSync push operation',\n statementTypes: \"mutations\",\n prettyPrint: true,\n filterPatterns: this.syncConfig.sqlLogging?.filterPatterns,\n filterType: this.syncConfig.sqlLogging?.filterType,\n });\n \n if (options.verbose) {\n callbacks?.onLog?.(`📝 SQL logging enabled: ${filepath}`);\n }\n } else {\n if (options.verbose) {\n callbacks?.onWarn?.('SQL logging requested but provider does not support it');\n }\n }\n }\n \n // Find entity directories to process\n // Note: If options.dir is specified, configDir already points to that directory\n // So we don't need to pass it as specificDir\n const entityDirs = this.findEntityDirectories(configDir, undefined, this.syncConfig?.directoryOrder);\n \n if (entityDirs.length === 0) {\n throw new Error('No entity directories found');\n }\n \n if (options.verbose) {\n callbacks?.onLog?.(`Found ${entityDirs.length} entity ${entityDirs.length === 1 ? 'directory' : 'directories'} to process`);\n }\n \n // Initialize file backup manager (unless in dry-run mode)\n if (!options.dryRun) {\n await fileBackupManager.initialize();\n if (options.verbose) {\n callbacks?.onLog?.('📁 File backup manager initialized');\n }\n }\n \n // Process each entity directory\n let totalCreated = 0;\n let totalUpdated = 0;\n let totalUnchanged = 0;\n let totalDeleted = 0;\n let totalSkipped = 0;\n let totalErrors = 0;\n \n // Begin transaction if not in dry-run mode\n if (!options.dryRun) {\n await transactionManager.beginTransaction();\n }\n \n try {\n for (const entityDir of entityDirs) {\n const entityConfig = await loadEntityConfig(entityDir);\n if (!entityConfig) {\n const warning = `Skipping ${entityDir} - no valid entity configuration`;\n this.warnings.push(warning);\n callbacks?.onWarn?.(warning);\n totalSkipped++; // Count skipped directories\n continue;\n }\n \n // Show folder with spinner at start\n const dirName = path.relative(process.cwd(), entityDir) || '.';\n callbacks?.onLog?.(`\\n📁 ${dirName}:`);\n \n // Use onProgress for animated spinner if available\n if (callbacks?.onProgress) {\n callbacks.onProgress(`Processing ${dirName}...`);\n } else {\n callbacks?.onLog?.(` ⏳ Processing...`);\n }\n \n if (options.verbose && callbacks?.onLog) {\n callbacks.onLog(`Processing ${entityConfig.entity} in ${entityDir}`);\n }\n \n const result = await this.processEntityDirectory(\n entityDir,\n entityConfig,\n options,\n fileBackupManager,\n callbacks\n );\n \n // Stop the spinner if we were using onProgress\n if (callbacks?.onProgress && callbacks?.onSuccess) {\n callbacks.onSuccess(`Processed ${dirName}`);\n }\n \n // Show per-directory summary\n const dirTotal = result.created + result.updated + result.unchanged + result.deleted + result.skipped;\n if (dirTotal > 0 || result.errors > 0) {\n callbacks?.onLog?.(` Total processed: ${dirTotal} records`);\n if (result.created > 0) {\n callbacks?.onLog?.(` ✓ Created: ${result.created}`);\n }\n if (result.updated > 0) {\n callbacks?.onLog?.(` ✓ Updated: ${result.updated}`);\n }\n if (result.deleted > 0) {\n callbacks?.onLog?.(` ✓ Deleted: ${result.deleted}`);\n }\n if (result.unchanged > 0) {\n callbacks?.onLog?.(` - Unchanged: ${result.unchanged}`);\n }\n if (result.skipped > 0) {\n callbacks?.onLog?.(` - Skipped: ${result.skipped}`);\n }\n if (result.errors > 0) {\n callbacks?.onLog?.(` ✗ Errors: ${result.errors}`);\n }\n }\n \n totalCreated += result.created;\n totalUpdated += result.updated;\n totalUnchanged += result.unchanged;\n totalDeleted += result.deleted;\n totalSkipped += result.skipped;\n totalErrors += result.errors;\n }\n \n // Commit transaction if successful\n if (!options.dryRun && totalErrors === 0) {\n await transactionManager.commitTransaction();\n }\n } catch (error) {\n // Rollback transaction on error\n if (!options.dryRun) {\n callbacks?.onLog?.('\\n⚠️ Rolling back database transaction due to error...');\n await transactionManager.rollbackTransaction();\n callbacks?.onLog?.('✓ Database transaction rolled back successfully\\n');\n }\n throw error;\n }\n \n // Commit file backups if successful and not in dry-run mode\n if (!options.dryRun && totalErrors === 0) {\n await fileBackupManager.cleanup();\n if (options.verbose) {\n callbacks?.onLog?.('✅ File backups committed');\n }\n }\n \n // Close SQL logging session if it was created\n let sqlLogPath: string | undefined;\n if (sqlLoggingSession) {\n sqlLogPath = sqlLoggingSession.filePath;\n await sqlLoggingSession.dispose();\n if (options.verbose) {\n callbacks?.onLog?.(`📝 SQL log written to: ${sqlLogPath}`);\n }\n }\n \n return {\n created: totalCreated,\n updated: totalUpdated,\n unchanged: totalUnchanged,\n deleted: totalDeleted,\n skipped: totalSkipped,\n errors: totalErrors,\n warnings: this.warnings,\n sqlLogPath\n };\n \n } catch (error) {\n // Rollback file backups on error\n if (!options.dryRun) {\n try {\n await fileBackupManager.rollback();\n callbacks?.onWarn?.('File backups rolled back due to error');\n } catch (rollbackError) {\n callbacks?.onWarn?.(`Failed to rollback file backups: ${rollbackError}`);\n }\n }\n \n // Close SQL logging session on error\n if (sqlLoggingSession) {\n try {\n await sqlLoggingSession.dispose();\n } catch (disposeError) {\n callbacks?.onWarn?.(`Failed to close SQL logging session: ${disposeError}`);\n }\n }\n \n throw error;\n }\n }\n \n private async processEntityDirectory(\n entityDir: string,\n entityConfig: any,\n options: PushOptions,\n fileBackupManager: FileBackupManager,\n callbacks?: PushCallbacks\n ): Promise<EntityPushResult> {\n let created = 0;\n let updated = 0;\n let unchanged = 0;\n let deleted = 0;\n let skipped = 0;\n let errors = 0;\n \n // Find all JSON files in the directory\n const pattern = entityConfig.filePattern || '*.json';\n const files = await fastGlob(pattern, {\n cwd: entityDir,\n absolute: true,\n onlyFiles: true,\n dot: true,\n ignore: ['**/node_modules/**', '**/.mj-*.json']\n });\n \n if (options.verbose) {\n callbacks?.onLog?.(`Found ${files.length} files to process`);\n }\n \n // Process each file\n for (const filePath of files) {\n try {\n // Backup the file before any modifications (unless dry-run)\n if (!options.dryRun) {\n await fileBackupManager.backupFile(filePath);\n }\n \n // Read the raw file data first\n const rawFileData = await fs.readJson(filePath);\n \n // Only preprocess if there are @include directives\n let fileData = rawFileData;\n const jsonString = JSON.stringify(rawFileData);\n const hasIncludes = jsonString.includes('\"@include\"') || jsonString.includes('\"@include.');\n \n if (hasIncludes) {\n // Preprocess the JSON file to handle @include directives\n // Create a new preprocessor instance for each file to ensure clean state\n const jsonPreprocessor = new JsonPreprocessor();\n fileData = await jsonPreprocessor.processFile(filePath);\n }\n \n const records = Array.isArray(fileData) ? fileData : [fileData];\n const isArray = Array.isArray(fileData);\n \n // Analyze dependencies and get sorted records\n const analyzer = new RecordDependencyAnalyzer();\n const analysisResult = await analyzer.analyzeFileRecords(records, entityConfig.entity);\n \n if (analysisResult.circularDependencies.length > 0) {\n callbacks?.onWarn?.(`⚠️ Circular dependencies detected in ${filePath}`);\n for (const cycle of analysisResult.circularDependencies) {\n callbacks?.onWarn?.(` Cycle: ${cycle.join(' → ')}`);\n }\n }\n \n if (options.verbose) {\n callbacks?.onLog?.(` Analyzed ${analysisResult.sortedRecords.length} records (including nested)`);\n }\n \n // Create batch context for in-memory entity resolution\n // Note: While JavaScript is single-threaded, async operations can interleave.\n // Map operations themselves are atomic, but we ensure records are added to\n // the context AFTER successful save to maintain consistency.\n const batchContext = new Map<string, BaseEntity>();\n \n // Process records using dependency levels for parallel processing\n if (analysisResult.dependencyLevels && analysisResult.dependencyLevels.length > 0) {\n // Use parallel processing with dependency levels\n for (let levelIndex = 0; levelIndex < analysisResult.dependencyLevels.length; levelIndex++) {\n const level = analysisResult.dependencyLevels[levelIndex];\n \n if (options.verbose && level.length > 1) {\n callbacks?.onLog?.(` Processing dependency level ${levelIndex} with ${level.length} records in parallel...`);\n }\n \n // Process records in this level in parallel batches\n const batchSize = options.parallelBatchSize || PARALLEL_BATCH_SIZE;\n for (let i = 0; i < level.length; i += batchSize) {\n const batch = level.slice(i, Math.min(i + batchSize, level.length));\n \n // Process batch in parallel\n const batchResults = await Promise.all(\n batch.map(async (flattenedRecord) => {\n try {\n const result = await this.processFlattenedRecord(\n flattenedRecord,\n entityDir,\n options,\n batchContext,\n callbacks,\n entityConfig\n );\n return { success: true, result };\n } catch (error) {\n // Return error instead of throwing to handle after Promise.all\n return { success: false, error, record: flattenedRecord };\n }\n })\n );\n \n // Process results and check for errors\n for (const batchResult of batchResults) {\n if (!batchResult.success) {\n // Fail fast on first error with detailed logging\n const err = batchResult.error as Error;\n const rec = batchResult.record as FlattenedRecord;\n\n // Log concise summary - detailed error was already logged by processFlattenedRecord\n callbacks?.onLog?.(`\\n❌ Processing failed for ${rec.entityName} at ${rec.path}`);\n callbacks?.onLog?.(` ${err.message}\\n`);\n\n // Throw concise error to trigger rollback\n throw err;\n }\n \n // Update stats for successful results\n const result = batchResult.result!;\n if (result.isDuplicate) {\n skipped++; // Count duplicates as skipped\n } else {\n if (result.status === 'created') created++;\n else if (result.status === 'updated') updated++;\n else if (result.status === 'unchanged') unchanged++;\n else if (result.status === 'deleted') deleted++;\n else if (result.status === 'skipped') skipped++;\n else if (result.status === 'error') errors++;\n }\n }\n }\n }\n } else {\n // Fallback to sequential processing if no dependency levels available\n for (const flattenedRecord of analysisResult.sortedRecords) {\n try {\n const result = await this.processFlattenedRecord(\n flattenedRecord,\n entityDir,\n options,\n batchContext,\n callbacks,\n entityConfig\n );\n \n // Update stats\n if (result.isDuplicate) {\n skipped++; // Count duplicates as skipped\n } else {\n if (result.status === 'created') created++;\n else if (result.status === 'updated') updated++;\n else if (result.status === 'unchanged') unchanged++;\n else if (result.status === 'deleted') deleted++;\n else if (result.status === 'skipped') skipped++;\n else if (result.status === 'error') errors++;\n }\n } catch (recordError) {\n const errorMsg = `Error processing ${flattenedRecord.entityName} record at ${flattenedRecord.path}: ${recordError}`;\n callbacks?.onError?.(errorMsg);\n errors++;\n }\n }\n }\n \n // Write back to file (handles both single records and arrays)\n if (!options.dryRun) {\n if (isArray) {\n await JsonWriteHelper.writeOrderedRecordData(filePath, records);\n } else {\n // For single record files, write back the single record\n await JsonWriteHelper.writeOrderedRecordData(filePath, records[0]);\n }\n }\n } catch (fileError) {\n // Error details already logged by lower-level handlers, just re-throw\n throw fileError;\n }\n }\n \n return { created, updated, unchanged, deleted, skipped, errors };\n }\n \n private async processFlattenedRecord(\n flattenedRecord: FlattenedRecord,\n entityDir: string,\n options: PushOptions,\n batchContext: Map<string, BaseEntity>,\n callbacks?: PushCallbacks,\n entityConfig?: any\n ): Promise<{ status: 'created' | 'updated' | 'unchanged' | 'error' | 'deleted' | 'skipped'; isDuplicate?: boolean }> {\n const metadata = new Metadata();\n const { record, entityName, parentContext, id: recordId } = flattenedRecord;\n \n // Check if this record has a deleteRecord directive\n if (record.deleteRecord && record.deleteRecord.delete === true) {\n return await this.processDeleteRecord(flattenedRecord, entityDir, options, callbacks);\n }\n \n // Use the unique record ID from the flattened record for batch context\n // This ensures we can properly find parent entities even when they're new\n const lookupKey = recordId;\n \n // Check if already in batch context\n let entity = batchContext.get(lookupKey);\n if (entity) {\n // Already processed\n return { status: 'unchanged', isDuplicate: true };\n }\n \n // Get or create entity instance\n entity = await metadata.GetEntityObject(entityName, this.contextUser);\n if (!entity) {\n throw new Error(`Failed to create entity object for ${entityName}`);\n }\n \n // Check if record exists\n const primaryKey = record.primaryKey;\n let exists = false;\n let isNew = false;\n \n if (primaryKey && Object.keys(primaryKey).length > 0) {\n // First check if the record exists using the sync engine's loadEntity method\n // This avoids the \"Error in BaseEntity.Load\" message for missing records\n const existingEntity = await this.syncEngine.loadEntity(entityName, primaryKey);\n \n if (existingEntity) {\n // Record exists, use the loaded entity\n entity = existingEntity;\n exists = true;\n } else {\n // Record doesn't exist in database\n const autoCreate = this.syncConfig?.push?.autoCreateMissingRecords ?? false;\n const pkDisplay = Object.entries(primaryKey)\n .map(([key, value]) => `${key}=${value}`)\n .join(', ');\n \n if (!autoCreate) {\n const warning = `Record not found: ${entityName} with primaryKey {${pkDisplay}}. To auto-create missing records, set push.autoCreateMissingRecords=true in .mj-sync.json`;\n this.warnings.push(warning);\n callbacks?.onWarn?.(warning);\n return { status: 'error', isDuplicate: false }; // This will be counted as error, not skipped\n } else {\n // Log that we're creating the missing record\n if (options.verbose) {\n callbacks?.onLog?.(`📝 Creating missing ${entityName} record with primaryKey {${pkDisplay}}`);\n }\n }\n }\n }\n \n if (!exists) {\n entity.NewRecord();\n isNew = true;\n\n // Set primary key values for new records if provided\n if (primaryKey) {\n for (const [pkField, pkValue] of Object.entries(primaryKey)) {\n entity.Set(pkField, pkValue);\n }\n }\n }\n\n // Apply defaults if entityConfig is provided\n if (entityConfig) {\n const defaults = await this.syncEngine.buildDefaults(flattenedRecord.path, entityConfig);\n\n // Apply defaults only to fields not explicitly set in record.fields\n for (const [field, value] of Object.entries(defaults)) {\n if (!(field in record.fields) && field in entity) {\n entity.Set(field, value);\n }\n }\n }\n\n // Store original field values to preserve @ references\n const originalFields = { ...record.fields };\n \n // Get parent entity from context if available\n let parentEntity: BaseEntity | null = null;\n if (parentContext) {\n // Find the parent's flattened record ID\n // The parent record was flattened before this child, so it should have a lower ID number\n const parentRecordId = flattenedRecord.dependencies.values().next().value;\n if (parentRecordId) {\n parentEntity = batchContext.get(parentRecordId) || null;\n }\n \n if (!parentEntity) {\n // Parent should have been processed before child due to dependency ordering\n throw new Error(`Parent entity not found in batch context for ${entityName}. Parent dependencies: ${Array.from(flattenedRecord.dependencies).join(', ')}`);\n }\n }\n \n // Process field values with parent context and batch context\n // Process each field with better error reporting\n for (const [fieldName, fieldValue] of Object.entries(record.fields)) {\n try {\n const processedValue = await this.syncEngine.processFieldValue(\n fieldValue,\n entityDir,\n parentEntity,\n null, // rootRecord\n 0,\n batchContext // Pass batch context for lookups\n );\n entity.Set(fieldName, processedValue);\n } catch (fieldError: any) {\n // Enhanced error reporting for field processing failures\n const primaryKeyInfo = record.primaryKey ? JSON.stringify(record.primaryKey) : 'NEW';\n\n // Helper to log to both console and callbacks\n const logError = (msg: string) => {\n console.error(msg);\n callbacks?.onLog?.(msg);\n };\n\n // Check if this is a lookup failure\n if (fieldError.message?.includes('Lookup failed:')) {\n logError(`\\n❌ LOOKUP FAILURE in ${entityName} (${primaryKeyInfo})`);\n logError(` Field: ${fieldName}`);\n logError(` Value: ${fieldValue}`);\n logError(` Error: ${fieldError.message}`);\n logError(` Tip: Check if the referenced record exists in the target entity\\n`);\n } else if (fieldError.message?.includes('Entity not found:')) {\n logError(`\\n❌ ENTITY NOT FOUND in ${entityName} (${primaryKeyInfo})`);\n logError(` Field: ${fieldName}`);\n logError(` Value: ${fieldValue}`);\n logError(` Error: ${fieldError.message}`);\n logError(` Tip: Check if the entity name is spelled correctly\\n`);\n } else if (fieldError.message?.includes('Field') && fieldError.message?.includes('not found')) {\n logError(`\\n❌ FIELD NOT FOUND in ${entityName} (${primaryKeyInfo})`);\n logError(` Field: ${fieldName}`);\n logError(` Value: ${fieldValue}`);\n logError(` Error: ${fieldError.message}`);\n logError(` Tip: Check if the field name exists in the target entity\\n`);\n } else if (fieldError.message?.includes('File not found:')) {\n logError(`\\n❌ FILE NOT FOUND in ${entityName} (${primaryKeyInfo})`);\n logError(` Field: ${fieldName}`);\n logError(` Value: ${fieldValue}`);\n logError(` Error: ${fieldError.message}`);\n logError(` Tip: Check if the file path is correct relative to ${entityDir}\\n`);\n } else {\n logError(`\\n❌ FIELD PROCESSING ERROR in ${entityName} (${primaryKeyInfo})`);\n logError(` Field: ${fieldName}`);\n logError(` Value: ${fieldValue}`);\n logError(` Error: ${fieldError.message}\\n`);\n }\n\n // Re-throw with enhanced context\n throw new Error(`Failed to process field '${fieldName}' in ${entityName}: ${fieldError.message}`);\n }\n }\n \n // Check if the record is actually dirty before considering it changed\n let isDirty = entity.Dirty;\n \n // Force dirty state if alwaysPush is enabled\n const alwaysPush = this.syncConfig?.push?.alwaysPush ?? false;\n if (alwaysPush && !isNew) {\n isDirty = true;\n }\n \n // Also check if file content has changed (for @file references)\n if (!isDirty && !isNew && record.sync) {\n const currentChecksum = await this.syncEngine.calculateChecksumWithFileContent(originalFields, entityDir);\n if (currentChecksum !== record.sync.checksum) {\n isDirty = true;\n if (options.verbose) {\n callbacks?.onLog?.(`📄 File content changed for ${entityName} record (checksum mismatch)`);\n }\n }\n }\n \n if (options.dryRun) {\n if (exists) {\n callbacks?.onLog?.(`[DRY RUN] Would update ${entityName} record`);\n return { status: 'updated' };\n } else {\n callbacks?.onLog?.(`[DRY RUN] Would create ${entityName} record`);\n return { status: 'created' };\n }\n }\n \n // If updating an existing record that's dirty, show what changed\n if (!isNew && isDirty) {\n const changes = entity.GetChangesSinceLastSave();\n const changeKeys = Object.keys(changes);\n if (changeKeys.length > 0) {\n // Get primary key info for display\n const entityInfo = this.syncEngine.getEntityInfo(entityName);\n const primaryKeyDisplay: string[] = [];\n if (entityInfo) {\n for (const pk of entityInfo.PrimaryKeys) {\n primaryKeyDisplay.push(`${pk.Name}: ${entity.Get(pk.Name)}`);\n }\n }\n \n callbacks?.onLog?.(`📝 Updating ${entityName} record:`);\n if (primaryKeyDisplay.length > 0) {\n callbacks?.onLog?.(` Primary Key: ${primaryKeyDisplay.join(', ')}`);\n }\n callbacks?.onLog?.(` Changes:`);\n for (const fieldName of changeKeys) {\n const field = entity.GetFieldByName(fieldName);\n const oldValue = field ? field.OldValue : undefined;\n const newValue = (changes as any)[fieldName];\n callbacks?.onLog?.(` ${fieldName}: ${this.formatFieldValue(oldValue)} → ${this.formatFieldValue(newValue)}`);\n }\n }\n }\n \n // Save the record with detailed error logging\n const recordName = entity.Get('Name');\n const entityRecordId = entity.Get('ID');\n \n let saveResult;\n try {\n // Pass IgnoreDirtyState option when alwaysPush is enabled\n const saveOptions = alwaysPush ? { IgnoreDirtyState: true } : undefined;\n saveResult = await entity.Save(saveOptions);\n } catch (saveError: any) {\n // Helper to log to both console and callbacks\n const logError = (msg: string) => {\n console.error(msg);\n callbacks?.onLog?.(msg);\n };\n\n logError(`\\n❌ SAVE EXCEPTION for ${entityName}`);\n logError(` Record ID: ${entityRecordId || 'NEW'}`);\n logError(` Record Name: ${recordName || 'N/A'}`);\n logError(` File Path: ${flattenedRecord.path}`);\n logError(` Error: ${saveError.message || saveError}`);\n\n // Check for specific error patterns\n if (saveError.message?.includes('Cannot insert the value NULL')) {\n logError(` Tip: A required field is NULL. Check the entity's required fields.`);\n } else if (saveError.message?.includes('FOREIGN KEY constraint')) {\n logError(` Tip: Foreign key constraint violation. Check that referenced records exist.`);\n } else if (saveError.message?.includes('duplicate key')) {\n logError(` Tip: Duplicate key violation. A record with these values already exists.`);\n } else if (saveError.message?.includes('Incorrect syntax')) {\n logError(` Tip: SQL syntax error. Check for special characters in field values.`);\n }\n\n // Log problematic field values for debugging\n logError(`\\n Failed entity field values:`);\n for (const field of entity.Fields) {\n const value = entity.Get(field.Name);\n if (value !== null && value !== undefined) {\n const displayValue = typeof value === 'string' && value.length > 100\n ? value.substring(0, 100) + '...'\n : value;\n logError(` ${field.Name}: ${displayValue}`);\n }\n }\n logError(''); // Empty line for readability\n throw saveError;\n }\n \n if (!saveResult) {\n // Helper to log to both console and callbacks\n const logError = (msg: string) => {\n console.error(msg);\n callbacks?.onLog?.(msg);\n };\n\n logError(`\\n❌ SAVE RETURNED FALSE for ${entityName}`);\n logError(` Record ID: ${entityRecordId || 'NEW'}`);\n logError(` Record Name: ${recordName || 'N/A'}`);\n logError(` File Path: ${flattenedRecord.path}`);\n\n // Log the LatestResult for debugging\n if (entity.LatestResult) {\n if (entity.LatestResult.Message) {\n logError(` Database Message: ${entity.LatestResult.Message}`);\n }\n if (entity.LatestResult.Errors && entity.LatestResult.Errors.length > 0) {\n logError(` Errors:`);\n entity.LatestResult.Errors.forEach((err: any, idx: number) => {\n const errorMsg = typeof err === 'string' ? err : (err?.message || JSON.stringify(err));\n logError(` ${idx + 1}. ${errorMsg}`);\n });\n }\n if ((entity.LatestResult as any).SQL) {\n // Don't log the full SQL as it might be huge, just indicate it's available\n logError(` SQL Statement: [Available - check entity.LatestResult.SQL if needed]`);\n }\n }\n\n // Log field values that might be problematic\n logError(`\\n Entity field values:`);\n for (const field of entity.Fields) {\n const value = entity.Get(field.Name);\n if (value !== null && value !== undefined) {\n const displayValue = typeof value === 'string' && value.length > 100\n ? value.substring(0, 100) + '...'\n : value;\n logError(` ${field.Name}: ${displayValue}`);\n }\n }\n logError(''); // Empty line for readability\n // Build detailed error information\n const entityInfo = this.syncEngine.getEntityInfo(entityName);\n const primaryKeyInfo: string[] = [];\n const fieldInfo: string[] = [];\n \n // Collect primary key information\n if (entityInfo) {\n for (const pk of entityInfo.PrimaryKeys) {\n const pkValue = entity.Get(pk.Name);\n primaryKeyInfo.push(`${pk.Name}=${this.formatFieldValue(pkValue)}`);\n }\n }\n \n // Collect field values that were being saved\n for (const [fieldName, fieldValue] of Object.entries(record.fields)) {\n const processedValue = entity.Get(fieldName);\n fieldInfo.push(`${fieldName}=${this.formatFieldValue(processedValue)}`);\n }\n \n // Get the actual error details from the entity\n const errorMessage = entity.LatestResult?.Message || 'Unknown error';\n const errorDetails = entity.LatestResult?.Errors?.map(err => \n typeof err === 'string' ? err : (err?.message || JSON.stringify(err))\n )?.join(', ') || '';\n \n // Log detailed error information\n callbacks?.onError?.(`\\n❌ FATAL ERROR: Failed to save ${entityName} record`);\n callbacks?.onError?.(` Entity: ${entityName}`);\n if (primaryKeyInfo.length > 0) {\n callbacks?.onError?.(` Primary Key: {${primaryKeyInfo.join(', ')}}`);\n }\n callbacks?.onError?.(` Record Path: ${flattenedRecord.path}`);\n callbacks?.onError?.(` Is New Record: ${isNew}`);\n callbacks?.onError?.(` Field Values Being Saved:`);\n for (const field of fieldInfo) {\n callbacks?.onError?.(` - ${field}`);\n }\n callbacks?.onError?.(` SQL Error: ${errorMessage}`);\n if (errorDetails) {\n callbacks?.onError?.(` Additional Details: ${errorDetails}`);\n }\n \n // Check for common issues\n if (errorMessage.includes('conversion failed') || errorMessage.includes('GUID')) {\n callbacks?.onError?.(` ⚠️ This appears to be a GUID/UUID format error. Check that all ID fields contain valid GUIDs.`);\n }\n if (errorMessage.includes('transaction')) {\n callbacks?.onError?.(` ⚠️ Transaction error detected. The database transaction may be corrupted.`);\n }\n \n // Throw error to trigger rollback and stop processing\n throw new Error(`Failed to save ${entityName} record at ${flattenedRecord.path}: ${errorMessage}`);\n }\n \n // Add to batch context AFTER save so it has an ID for child @parent:ID references\n // Use the recordId (lookupKey) as the key so child records can find this parent\n batchContext.set(lookupKey, entity);\n \n // Update primaryKey for new records\n if (isNew) {\n const entityInfo = this.syncEngine.getEntityInfo(entityName);\n if (entityInfo) {\n const newPrimaryKey: Record<string, any> = {};\n for (const pk of entityInfo.PrimaryKeys) {\n newPrimaryKey[pk.Name] = entity.Get(pk.Name);\n }\n record.primaryKey = newPrimaryKey;\n }\n }\n \n // Only update sync metadata if the record was actually dirty (changed)\n if (isNew || isDirty) {\n record.sync = {\n lastModified: new Date().toISOString(),\n checksum: await this.syncEngine.calculateChecksumWithFileContent(originalFields, entityDir)\n };\n if (options.verbose) {\n callbacks?.onLog?.(` ✓ Updated sync metadata (record was ${isNew ? 'new' : 'changed'})`);\n }\n } else if (options.verbose) {\n callbacks?.onLog?.(` - Skipped sync metadata update (no changes detected)`);\n }\n \n // Restore original field values to preserve @ references\n record.fields = originalFields;\n \n return { \n status: isNew ? 'created' : (isDirty ? 'updated' : 'unchanged'),\n isDuplicate: false\n };\n }\n \n private formatFieldValue(value: any): string {\n if (value === null || value === undefined) return 'null';\n if (typeof value === 'string') {\n // Truncate long strings and show quotes\n if (value.length > 50) {\n return `\"${value.substring(0, 47)}...\"`;\n }\n return `\"${value}\"`;\n }\n if (typeof value === 'object') {\n const str = JSON.stringify(value);\n return str.length > 50 ? `\"${str.substring(0, 47)}...\"` : `\"${str}\"`;\n }\n return String(value);\n }\n \n private async processDeleteRecord(\n flattenedRecord: FlattenedRecord,\n _entityDir: string,\n options: PushOptions,\n callbacks?: PushCallbacks\n ): Promise<{ status: 'deleted' | 'skipped' | 'unchanged'; isDuplicate?: boolean }> {\n const { record, entityName } = flattenedRecord;\n \n // Validate that we have a primary key for deletion\n if (!record.primaryKey || Object.keys(record.primaryKey).length === 0) {\n throw new Error(`Cannot delete ${entityName} record without primaryKey. Please specify primaryKey fields.`);\n }\n \n // Check if the deletion has already been processed\n if (record.deleteRecord?.deletedAt) {\n if (options.verbose) {\n callbacks?.onLog?.(` ℹ️ Record already deleted on ${record.deleteRecord.deletedAt}`);\n }\n // Return unchanged since the record is already in the desired state (deleted)\n return { status: 'unchanged', isDuplicate: false };\n }\n \n // Load the entity to verify it exists\n const existingEntity = await this.syncEngine.loadEntity(entityName, record.primaryKey);\n \n if (!existingEntity) {\n const pkDisplay = Object.entries(record.primaryKey)\n .map(([key, value]) => `${key}=${value}`)\n .join(', ');\n \n const warning = `Record not found for deletion: ${entityName} with primaryKey {${pkDisplay}}`;\n this.warnings.push(warning);\n callbacks?.onWarn?.(warning);\n \n // Mark as deleted anyway since it doesn't exist\n if (!record.deleteRecord) {\n record.deleteRecord = { delete: true };\n }\n record.deleteRecord.deletedAt = undefined; // Indicate it was not found\n record.deleteRecord.notFound = true;\n \n return { status: 'skipped', isDuplicate: false };\n }\n \n // Log the deletion\n const entityInfo = this.syncEngine.getEntityInfo(entityName);\n const primaryKeyDisplay: string[] = [];\n if (entityInfo) {\n for (const pk of entityInfo.PrimaryKeys) {\n primaryKeyDisplay.push(`${pk.Name}: ${existingEntity.Get(pk.Name)}`);\n }\n }\n \n callbacks?.onLog?.(`🗑️ Deleting ${entityName} record:`);\n if (primaryKeyDisplay.length > 0) {\n callbacks?.onLog?.(` Primary Key: ${primaryKeyDisplay.join(', ')}`);\n }\n \n // Additional info if available\n const recordName = existingEntity.Get('Name');\n if (recordName) {\n callbacks?.onLog?.(` Name: ${recordName}`);\n }\n \n if (options.dryRun) {\n callbacks?.onLog?.(`[DRY RUN] Would delete ${entityName} record`);\n return { status: 'deleted', isDuplicate: false };\n }\n \n // Delete the record\n try {\n const deleteResult = await existingEntity.Delete();\n \n if (!deleteResult) {\n // Check the LatestResult for error details\n const errorMessage = existingEntity.LatestResult?.Message || 'Unknown error';\n const errorDetails = existingEntity.LatestResult?.Errors?.map(err => \n typeof err === 'string' ? err : (err?.message || JSON.stringify(err))\n )?.join(', ') || '';\n \n callbacks?.onError?.(`\\n❌ Failed to delete ${entityName} record`);\n callbacks?.onError?.(` Primary Key: {${primaryKeyDisplay.join(', ')}}`);\n callbacks?.onError?.(` Error: ${errorMessage}`);\n if (errorDetails) {\n callbacks?.onError?.(` Details: ${errorDetails}`);\n }\n \n throw new Error(`Failed to delete ${entityName} record: ${errorMessage}`);\n }\n \n // Update the deleteRecord section with deletedAt timestamp\n if (!record.deleteRecord) {\n record.deleteRecord = { delete: true };\n }\n record.deleteRecord.deletedAt = new Date().toISOString();\n \n // Remove notFound flag if it exists since we successfully found and deleted the record\n if (record.deleteRecord.notFound) {\n delete record.deleteRecord.notFound;\n }\n \n if (options.verbose) {\n callbacks?.onLog?.(` ✓ Successfully deleted ${entityName} record`);\n }\n \n return { status: 'deleted', isDuplicate: false };\n \n } catch (deleteError: any) {\n console.error(`\\n❌ DELETE EXCEPTION for ${entityName}`);\n console.error(` Primary Key: {${primaryKeyDisplay.join(', ')}}`);\n console.error(` Error: ${deleteError.message || deleteError}`);\n \n // Check for specific error patterns\n if (deleteError.message?.includes('FOREIGN KEY constraint')) {\n console.error(` Tip: This record is referenced by other records and cannot be deleted.`);\n console.error(` Consider deleting dependent records first.`);\n } else if (deleteError.message?.includes('permission')) {\n console.error(` Tip: You may not have permission to delete this record.`);\n }\n \n throw deleteError;\n }\n }\n \n private _buildBatchContextKey(entityName: string, record: RecordData): string {\n // Build a unique key for the batch context based on entity name and identifying fields\n const keyParts = [entityName];\n \n // Use primary key if available\n if (record.primaryKey) {\n for (const [field, value] of Object.entries(record.primaryKey)) {\n keyParts.push(`${field}=${value}`);\n }\n } else {\n // Use a combination of important fields as fallback\n const identifyingFields = ['Name', 'ID', 'Code', 'Email'];\n for (const field of identifyingFields) {\n if (record.fields[field]) {\n keyParts.push(`${field}=${record.fields[field]}`);\n }\n }\n }\n \n return keyParts.join('|');\n }\n \n private findEntityDirectories(baseDir: string, specificDir?: string, directoryOrder?: string[]): string[] {\n const dirs: string[] = [];\n \n if (specificDir) {\n // Process specific directory\n const fullPath = path.resolve(baseDir, specificDir);\n if (fs.existsSync(fullPath) && fs.statSync(fullPath).isDirectory()) {\n // Check if this directory has an entity configuration\n const configPath = path.join(fullPath, '.mj-sync.json');\n if (fs.existsSync(configPath)) {\n try {\n const config = fs.readJsonSync(configPath);\n if (config.entity) {\n // It's an entity directory, add it\n dirs.push(fullPath);\n } else {\n // It's a container directory, search its subdirectories\n this.findEntityDirectoriesRecursive(fullPath, dirs);\n }\n } catch {\n // Invalid config, skip\n }\n }\n }\n } else {\n // Find all entity directories\n this.findEntityDirectoriesRecursive(baseDir, dirs);\n }\n \n // Apply directory ordering if specified\n if (directoryOrder && directoryOrder.length > 0 && !specificDir) {\n // Create a map of directory name to order index\n const orderMap = new Map<string, number>();\n directoryOrder.forEach((dir, index) => {\n orderMap.set(dir, index);\n });\n \n // Sort directories based on the order map\n dirs.sort((a, b) => {\n const nameA = path.basename(a);\n const nameB = path.basename(b);\n const orderA = orderMap.get(nameA) ?? Number.MAX_SAFE_INTEGER;\n const orderB = orderMap.get(nameB) ?? Number.MAX_SAFE_INTEGER;\n \n // If both have specified orders, use them\n if (orderA !== Number.MAX_SAFE_INTEGER || orderB !== Number.MAX_SAFE_INTEGER) {\n return orderA - orderB;\n }\n \n // Otherwise, maintain original order (stable sort)\n return 0;\n });\n }\n \n return dirs;\n }\n\n private findEntityDirectoriesRecursive(dir: string, dirs: string[]): void {\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n \n for (const entry of entries) {\n if (entry.isDirectory() && !entry.name.startsWith('.') && entry.name !== 'node_modules') {\n const fullPath = path.join(dir, entry.name);\n const configPath = path.join(fullPath, '.mj-sync.json');\n \n if (fs.existsSync(configPath)) {\n try {\n const config = fs.readJsonSync(configPath);\n if (config.entity) {\n dirs.push(fullPath);\n }\n } catch {\n // Skip invalid config files\n }\n } else {\n // Recurse into subdirectories\n this.findEntityDirectoriesRecursive(fullPath, dirs);\n }\n }\n }\n }\n}"]}
@@ -24,10 +24,11 @@ var __importStar = (this && this.__importStar) || function (mod) {
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.ValidationService = void 0;
27
- const global_1 = require("@memberjunction/global");
27
+ const core_1 = require("@memberjunction/core");
28
28
  const fs = __importStar(require("fs"));
29
29
  const path = __importStar(require("path"));
30
30
  const provider_utils_1 = require("../lib/provider-utils");
31
+ const metadata_keywords_1 = require("../constants/metadata-keywords");
31
32
  class ValidationService {
32
33
  metadata;
33
34
  errors = [];
@@ -37,7 +38,7 @@ class ValidationService {
37
38
  options;
38
39
  userRoleCache = new Map();
39
40
  constructor(options = {}) {
40
- this.metadata = new global_1.Metadata();
41
+ this.metadata = new core_1.Metadata();
41
42
  this.options = {
42
43
  verbose: false,
43
44
  outputFormat: 'human',
@@ -435,20 +436,7 @@ class ValidationService {
435
436
  * Check if a string is actually a MetadataSync reference (not just any @ string)
436
437
  */
437
438
  isValidReference(value) {
438
- if (typeof value !== 'string' || !value.startsWith('@')) {
439
- return false;
440
- }
441
- // List of valid reference prefixes
442
- const validPrefixes = [
443
- '@file:',
444
- '@lookup:',
445
- '@template:',
446
- '@parent:',
447
- '@root:',
448
- '@env:',
449
- '@include', // Can be @include or @include.
450
- ];
451
- return validPrefixes.some((prefix) => value.startsWith(prefix));
439
+ return (0, metadata_keywords_1.isMetadataKeyword)(value);
452
440
  }
453
441
  /**
454
442
  * Validates special references (@file:, @lookup:, etc.)
@@ -467,19 +455,19 @@ class ValidationService {
467
455
  return;
468
456
  }
469
457
  switch (parsed.type) {
470
- case '@file:':
458
+ case metadata_keywords_1.METADATA_KEYWORDS.FILE:
471
459
  await this.validateFileReference(parsed.value, filePath, entityInfo.Name, fieldInfo.Name);
472
460
  break;
473
- case '@lookup:':
461
+ case metadata_keywords_1.METADATA_KEYWORDS.LOOKUP:
474
462
  await this.validateLookupReference(parsed, filePath, entityInfo.Name, fieldInfo.Name);
475
463
  break;
476
- case '@template:':
464
+ case metadata_keywords_1.METADATA_KEYWORDS.TEMPLATE:
477
465
  await this.validateTemplateReference(parsed.value, filePath, entityInfo.Name, fieldInfo.Name);
478
466
  break;
479
- case '@parent:':
467
+ case metadata_keywords_1.METADATA_KEYWORDS.PARENT:
480
468
  this.validateParentReference(parsed.value, parentContext, filePath, entityInfo.Name, fieldInfo.Name);
481
469
  break;
482
- case '@root:':
470
+ case metadata_keywords_1.METADATA_KEYWORDS.ROOT:
483
471
  this.validateRootReference(parsed.value, parentContext, filePath, entityInfo.Name, fieldInfo.Name);
484
472
  break;
485
473
  }
@@ -489,17 +477,17 @@ class ValidationService {
489
477
  */
490
478
  parseReference(reference) {
491
479
  const patterns = [
492
- ['@file:', /^@file:(.+)$/],
493
- ['@lookup:', /^@lookup:([^.]+)\.(.+)$/],
494
- ['@template:', /^@template:(.+)$/],
495
- ['@parent:', /^@parent:(.+)$/],
496
- ['@root:', /^@root:(.+)$/],
497
- ['@env:', /^@env:(.+)$/],
480
+ [metadata_keywords_1.METADATA_KEYWORDS.FILE, /^@file:(.+)$/],
481
+ [metadata_keywords_1.METADATA_KEYWORDS.LOOKUP, /^@lookup:([^.]+)\.(.+)$/],
482
+ [metadata_keywords_1.METADATA_KEYWORDS.TEMPLATE, /^@template:(.+)$/],
483
+ [metadata_keywords_1.METADATA_KEYWORDS.PARENT, /^@parent:(.+)$/],
484
+ [metadata_keywords_1.METADATA_KEYWORDS.ROOT, /^@root:(.+)$/],
485
+ [metadata_keywords_1.METADATA_KEYWORDS.ENV, /^@env:(.+)$/],
498
486
  ];
499
487
  for (const [type, pattern] of patterns) {
500
488
  const match = reference.match(pattern);
501
489
  if (match) {
502
- if (type === '@lookup:') {
490
+ if (type === metadata_keywords_1.METADATA_KEYWORDS.LOOKUP) {
503
491
  const [, entity, remaining] = match;
504
492
  // Check if this has ?create syntax
505
493
  const hasCreate = remaining.includes('?create');
@@ -535,7 +523,7 @@ class ValidationService {
535
523
  field: primaryField.field,
536
524
  fields, // Include all fields for validation
537
525
  createIfMissing: hasCreate,
538
- additionalFields,
526
+ additionalFields
539
527
  };
540
528
  }
541
529
  return { type, value: match[1] };
@@ -749,7 +737,7 @@ class ValidationService {
749
737
  // Track dependencies from lookups in fields
750
738
  if (entityData.fields) {
751
739
  for (const value of Object.values(entityData.fields)) {
752
- if (typeof value === 'string' && value.startsWith('@lookup:')) {
740
+ if (typeof value === 'string' && value.startsWith(metadata_keywords_1.METADATA_KEYWORDS.LOOKUP)) {
753
741
  const parsed = this.parseReference(value);
754
742
  if (parsed?.entity) {
755
743
  this.addEntityDependency(entityName, parsed.entity);
@@ -981,7 +969,7 @@ class ValidationService {
981
969
  */
982
970
  async loadUserRoles() {
983
971
  try {
984
- const rv = new global_1.RunView();
972
+ const rv = new core_1.RunView();
985
973
  const systemUser = (0, provider_utils_1.getSystemUser)();
986
974
  // Load all user roles with role names
987
975
  const result = await rv.RunView({
@@ -1136,9 +1124,9 @@ class ValidationService {
1136
1124
  // Process based on data type
1137
1125
  if (Array.isArray(jsonContent)) {
1138
1126
  for (const item of jsonContent) {
1139
- if (typeof item === 'string' && item.startsWith('@include:')) {
1140
- const includePath = item.substring(9).trim();
1141
- await this.validateIncludeFile(includePath, sourceFile);
1127
+ if (typeof item === 'string' && item.startsWith(`${metadata_keywords_1.METADATA_KEYWORDS.INCLUDE}:`)) {
1128
+ const includePath = (0, metadata_keywords_1.extractKeywordValue)(item);
1129
+ await this.validateIncludeFile(includePath.trim(), sourceFile);
1142
1130
  }
1143
1131
  else if (item && typeof item === 'object') {
1144
1132
  await this.validateJsonIncludes(item, sourceFile);
@@ -1147,7 +1135,7 @@ class ValidationService {
1147
1135
  }
1148
1136
  else if (jsonContent && typeof jsonContent === 'object') {
1149
1137
  for (const [key, value] of Object.entries(jsonContent)) {
1150
- if (key === '@include' || key.startsWith('@include.')) {
1138
+ if (key === metadata_keywords_1.METADATA_KEYWORDS.INCLUDE || key.startsWith(`${metadata_keywords_1.METADATA_KEYWORDS.INCLUDE}.`)) {
1151
1139
  let includeFile;
1152
1140
  if (typeof value === 'string') {
1153
1141
  includeFile = value;
@@ -1205,36 +1193,36 @@ class ValidationService {
1205
1193
  for (const [key, value] of Object.entries(obj)) {
1206
1194
  if (typeof value === 'string' && this.isValidReference(value)) {
1207
1195
  // Process different reference types
1208
- if (value.startsWith('@file:')) {
1209
- const filePath = value.substring(6);
1196
+ if (value.startsWith(metadata_keywords_1.METADATA_KEYWORDS.FILE)) {
1197
+ const filePath = (0, metadata_keywords_1.extractKeywordValue)(value);
1210
1198
  // Recursively validate the file reference (with circular detection)
1211
1199
  await this.validateFileReference(filePath, sourceFile, entityName, key, visitedFiles);
1212
1200
  }
1213
- else if (value.startsWith('@lookup:')) {
1201
+ else if (value.startsWith(metadata_keywords_1.METADATA_KEYWORDS.LOOKUP)) {
1214
1202
  // Parse and validate lookup reference
1215
1203
  const parsed = this.parseReference(value);
1216
1204
  if (parsed) {
1217
1205
  await this.validateLookupReference(parsed, sourceFile, entityName, key);
1218
1206
  }
1219
1207
  }
1220
- else if (value.startsWith('@template:')) {
1221
- const templatePath = value.substring(10);
1208
+ else if (value.startsWith(metadata_keywords_1.METADATA_KEYWORDS.TEMPLATE)) {
1209
+ const templatePath = (0, metadata_keywords_1.extractKeywordValue)(value);
1222
1210
  await this.validateTemplateReference(templatePath, sourceFile, entityName, key);
1223
1211
  }
1224
- else if (value.startsWith('@parent:')) {
1212
+ else if (value.startsWith(metadata_keywords_1.METADATA_KEYWORDS.PARENT)) {
1225
1213
  const parsed = this.parseReference(value);
1226
1214
  if (parsed) {
1227
1215
  this.validateParentReference(parsed.value, parentContext, sourceFile, entityName, key);
1228
1216
  }
1229
1217
  }
1230
- else if (value.startsWith('@root:')) {
1218
+ else if (value.startsWith(metadata_keywords_1.METADATA_KEYWORDS.ROOT)) {
1231
1219
  const parsed = this.parseReference(value);
1232
1220
  if (parsed) {
1233
1221
  this.validateRootReference(parsed.value, parentContext, sourceFile, entityName, key);
1234
1222
  }
1235
1223
  }
1236
- else if (value.startsWith('@env:')) {
1237
- const envVar = value.substring(5);
1224
+ else if (value.startsWith(metadata_keywords_1.METADATA_KEYWORDS.ENV)) {
1225
+ const envVar = (0, metadata_keywords_1.extractKeywordValue)(value);
1238
1226
  if (!process.env[envVar]) {
1239
1227
  this.addWarning({
1240
1228
  type: 'validation',