@memberjunction/metadata-sync 2.92.0 → 2.93.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.
@@ -450,11 +450,55 @@ class PushService {
450
450
  }
451
451
  }
452
452
  // Process field values with parent context and batch context
453
+ // Process each field with better error reporting
453
454
  for (const [fieldName, fieldValue] of Object.entries(record.fields)) {
454
- const processedValue = await this.syncEngine.processFieldValue(fieldValue, entityDir, parentEntity, null, // rootRecord
455
- 0, batchContext // Pass batch context for lookups
456
- );
457
- entity.Set(fieldName, processedValue);
455
+ try {
456
+ const processedValue = await this.syncEngine.processFieldValue(fieldValue, entityDir, parentEntity, null, // rootRecord
457
+ 0, batchContext // Pass batch context for lookups
458
+ );
459
+ entity.Set(fieldName, processedValue);
460
+ }
461
+ catch (fieldError) {
462
+ // Enhanced error reporting for field processing failures
463
+ const primaryKeyInfo = record.primaryKey ? JSON.stringify(record.primaryKey) : 'NEW';
464
+ // Check if this is a lookup failure
465
+ if (fieldError.message?.includes('Lookup failed:')) {
466
+ console.error(`\n❌ LOOKUP FAILURE in ${entityName} (${primaryKeyInfo})`);
467
+ console.error(` Field: ${fieldName}`);
468
+ console.error(` Value: ${fieldValue}`);
469
+ console.error(` Error: ${fieldError.message}`);
470
+ console.error(` Tip: Check if the referenced record exists in the target entity\n`);
471
+ }
472
+ else if (fieldError.message?.includes('Entity not found:')) {
473
+ console.error(`\n❌ ENTITY NOT FOUND in ${entityName} (${primaryKeyInfo})`);
474
+ console.error(` Field: ${fieldName}`);
475
+ console.error(` Value: ${fieldValue}`);
476
+ console.error(` Error: ${fieldError.message}`);
477
+ console.error(` Tip: Check if the entity name is spelled correctly\n`);
478
+ }
479
+ else if (fieldError.message?.includes('Field') && fieldError.message?.includes('not found')) {
480
+ console.error(`\n❌ FIELD NOT FOUND in ${entityName} (${primaryKeyInfo})`);
481
+ console.error(` Field: ${fieldName}`);
482
+ console.error(` Value: ${fieldValue}`);
483
+ console.error(` Error: ${fieldError.message}`);
484
+ console.error(` Tip: Check if the field name exists in the target entity\n`);
485
+ }
486
+ else if (fieldError.message?.includes('File not found:')) {
487
+ console.error(`\n❌ FILE NOT FOUND in ${entityName} (${primaryKeyInfo})`);
488
+ console.error(` Field: ${fieldName}`);
489
+ console.error(` Value: ${fieldValue}`);
490
+ console.error(` Error: ${fieldError.message}`);
491
+ console.error(` Tip: Check if the file path is correct relative to ${entityDir}\n`);
492
+ }
493
+ else {
494
+ console.error(`\n❌ FIELD PROCESSING ERROR in ${entityName} (${primaryKeyInfo})`);
495
+ console.error(` Field: ${fieldName}`);
496
+ console.error(` Value: ${fieldValue}`);
497
+ console.error(` Error: ${fieldError.message}\n`);
498
+ }
499
+ // Re-throw with enhanced context
500
+ throw new Error(`Failed to process field '${fieldName}' in ${entityName}: ${fieldError.message}`);
501
+ }
458
502
  }
459
503
  // Check if the record is actually dirty before considering it changed
460
504
  let isDirty = entity.Dirty;
@@ -505,8 +549,79 @@ class PushService {
505
549
  }
506
550
  }
507
551
  // Save the record with detailed error logging
508
- const saveResult = await entity.Save();
552
+ const recordName = entity.Get('Name');
553
+ const entityRecordId = entity.Get('ID');
554
+ let saveResult;
555
+ try {
556
+ saveResult = await entity.Save();
557
+ }
558
+ catch (saveError) {
559
+ console.error(`\n❌ SAVE EXCEPTION for ${entityName}`);
560
+ console.error(` Record ID: ${entityRecordId || 'NEW'}`);
561
+ console.error(` Record Name: ${recordName || 'N/A'}`);
562
+ console.error(` File Path: ${flattenedRecord.path}`);
563
+ console.error(` Error: ${saveError.message || saveError}`);
564
+ // Check for specific error patterns
565
+ if (saveError.message?.includes('Cannot insert the value NULL')) {
566
+ console.error(` Tip: A required field is NULL. Check the entity's required fields.`);
567
+ }
568
+ else if (saveError.message?.includes('FOREIGN KEY constraint')) {
569
+ console.error(` Tip: Foreign key constraint violation. Check that referenced records exist.`);
570
+ }
571
+ else if (saveError.message?.includes('duplicate key')) {
572
+ console.error(` Tip: Duplicate key violation. A record with these values already exists.`);
573
+ }
574
+ else if (saveError.message?.includes('Incorrect syntax')) {
575
+ console.error(` Tip: SQL syntax error. Check for special characters in field values.`);
576
+ }
577
+ // Log problematic field values for debugging
578
+ console.error(`\n Failed entity field values:`);
579
+ for (const field of entity.Fields) {
580
+ const value = entity.Get(field.Name);
581
+ if (value !== null && value !== undefined) {
582
+ const displayValue = typeof value === 'string' && value.length > 100
583
+ ? value.substring(0, 100) + '...'
584
+ : value;
585
+ console.error(` ${field.Name}: ${displayValue}`);
586
+ }
587
+ }
588
+ console.error(''); // Empty line for readability
589
+ throw saveError;
590
+ }
509
591
  if (!saveResult) {
592
+ console.error(`\n❌ SAVE RETURNED FALSE for ${entityName}`);
593
+ console.error(` Record ID: ${entityRecordId || 'NEW'}`);
594
+ console.error(` Record Name: ${recordName || 'N/A'}`);
595
+ console.error(` File Path: ${flattenedRecord.path}`);
596
+ // Log the LatestResult for debugging
597
+ if (entity.LatestResult) {
598
+ if (entity.LatestResult.Message) {
599
+ console.error(` Database Message: ${entity.LatestResult.Message}`);
600
+ }
601
+ if (entity.LatestResult.Errors && entity.LatestResult.Errors.length > 0) {
602
+ console.error(` Errors:`);
603
+ entity.LatestResult.Errors.forEach((err, idx) => {
604
+ const errorMsg = typeof err === 'string' ? err : (err?.message || JSON.stringify(err));
605
+ console.error(` ${idx + 1}. ${errorMsg}`);
606
+ });
607
+ }
608
+ if (entity.LatestResult.SQL) {
609
+ // Don't log the full SQL as it might be huge, just indicate it's available
610
+ console.error(` SQL Statement: [Available - check entity.LatestResult.SQL if needed]`);
611
+ }
612
+ }
613
+ // Log field values that might be problematic
614
+ console.error(`\n Entity field values:`);
615
+ for (const field of entity.Fields) {
616
+ const value = entity.Get(field.Name);
617
+ if (value !== null && value !== undefined) {
618
+ const displayValue = typeof value === 'string' && value.length > 100
619
+ ? value.substring(0, 100) + '...'
620
+ : value;
621
+ console.error(` ${field.Name}: ${displayValue}`);
622
+ }
623
+ }
624
+ console.error(''); // Empty line for readability
510
625
  // Build detailed error information
511
626
  const entityInfo = this.syncEngine.getEntityInfo(entityName);
512
627
  const primaryKeyInfo = [];
@@ -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 } 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 errors: number;\n warnings: string[];\n sqlLogPath?: string;\n}\n\nexport interface EntityPushResult {\n created: number;\n updated: number;\n unchanged: 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 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 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 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;\n if (dirTotal > 0 || result.errors > 0) {\n callbacks?.onLog?.(` Total processed: ${dirTotal} unique 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.unchanged > 0) {\n callbacks?.onLog?.(` - Unchanged: ${result.unchanged}`);\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 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?.onError?.('\\n⚠️ Rolling back database transaction due to error...');\n await transactionManager.rollbackTransaction();\n callbacks?.onError?.('✓ Database transaction rolled back successfully');\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 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 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 );\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 callbacks?.onError?.(`\\n❌ BATCH PROCESSING FAILED`);\n callbacks?.onError?.(` Processing halted at dependency level ${levelIndex}`);\n callbacks?.onError?.(` Failed record: ${rec.entityName} at ${rec.path}`);\n callbacks?.onError?.(` Error: ${err.message}`);\n callbacks?.onError?.(` Records in this batch: ${batch.length}`);\n callbacks?.onError?.(` Records successfully processed before failure: ${batchResults.filter(r => r.success).length}`);\n \n // The error has already been logged in detail by processFlattenedRecord\n // Now throw to trigger rollback\n throw new Error(`Batch processing failed: ${err.message}`);\n }\n \n // Update stats for successful results\n const result = batchResult.result!;\n if (!result.isDuplicate) {\n if (result.status === 'created') created++;\n else if (result.status === 'updated') updated++;\n else if (result.status === 'unchanged') unchanged++;\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 );\n \n // Update stats\n if (!result.isDuplicate) {\n if (result.status === 'created') created++;\n else if (result.status === 'updated') updated++;\n else if (result.status === 'unchanged') unchanged++;\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 const errorMsg = `Error reading file ${filePath}: ${fileError}`;\n callbacks?.onError?.(errorMsg);\n errors++;\n }\n }\n \n return { created, updated, unchanged, 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 ): Promise<{ status: 'created' | 'updated' | 'unchanged' | 'error'; isDuplicate?: boolean }> {\n const metadata = new Metadata();\n const { record, entityName, parentContext, id: recordId } = flattenedRecord;\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' };\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 // 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 for (const [fieldName, fieldValue] of Object.entries(record.fields)) {\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 }\n \n // Check if the record is actually dirty before considering it changed\n let isDirty = entity.Dirty;\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 saveResult = await entity.Save();\n if (!saveResult) {\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 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}"]}
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 } 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 errors: number;\n warnings: string[];\n sqlLogPath?: string;\n}\n\nexport interface EntityPushResult {\n created: number;\n updated: number;\n unchanged: 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 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 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 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;\n if (dirTotal > 0 || result.errors > 0) {\n callbacks?.onLog?.(` Total processed: ${dirTotal} unique 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.unchanged > 0) {\n callbacks?.onLog?.(` - Unchanged: ${result.unchanged}`);\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 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?.onError?.('\\n⚠️ Rolling back database transaction due to error...');\n await transactionManager.rollbackTransaction();\n callbacks?.onError?.('✓ Database transaction rolled back successfully');\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 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 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 );\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 callbacks?.onError?.(`\\n❌ BATCH PROCESSING FAILED`);\n callbacks?.onError?.(` Processing halted at dependency level ${levelIndex}`);\n callbacks?.onError?.(` Failed record: ${rec.entityName} at ${rec.path}`);\n callbacks?.onError?.(` Error: ${err.message}`);\n callbacks?.onError?.(` Records in this batch: ${batch.length}`);\n callbacks?.onError?.(` Records successfully processed before failure: ${batchResults.filter(r => r.success).length}`);\n \n // The error has already been logged in detail by processFlattenedRecord\n // Now throw to trigger rollback\n throw new Error(`Batch processing failed: ${err.message}`);\n }\n \n // Update stats for successful results\n const result = batchResult.result!;\n if (!result.isDuplicate) {\n if (result.status === 'created') created++;\n else if (result.status === 'updated') updated++;\n else if (result.status === 'unchanged') unchanged++;\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 );\n \n // Update stats\n if (!result.isDuplicate) {\n if (result.status === 'created') created++;\n else if (result.status === 'updated') updated++;\n else if (result.status === 'unchanged') unchanged++;\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 const errorMsg = `Error reading file ${filePath}: ${fileError}`;\n callbacks?.onError?.(errorMsg);\n errors++;\n }\n }\n \n return { created, updated, unchanged, 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 ): Promise<{ status: 'created' | 'updated' | 'unchanged' | 'error'; isDuplicate?: boolean }> {\n const metadata = new Metadata();\n const { record, entityName, parentContext, id: recordId } = flattenedRecord;\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' };\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 // 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 // Check if this is a lookup failure\n if (fieldError.message?.includes('Lookup failed:')) {\n console.error(`\\n❌ LOOKUP FAILURE in ${entityName} (${primaryKeyInfo})`);\n console.error(` Field: ${fieldName}`);\n console.error(` Value: ${fieldValue}`);\n console.error(` Error: ${fieldError.message}`);\n console.error(` Tip: Check if the referenced record exists in the target entity\\n`);\n } else if (fieldError.message?.includes('Entity not found:')) {\n console.error(`\\n❌ ENTITY NOT FOUND in ${entityName} (${primaryKeyInfo})`);\n console.error(` Field: ${fieldName}`);\n console.error(` Value: ${fieldValue}`);\n console.error(` Error: ${fieldError.message}`);\n console.error(` Tip: Check if the entity name is spelled correctly\\n`);\n } else if (fieldError.message?.includes('Field') && fieldError.message?.includes('not found')) {\n console.error(`\\n❌ FIELD NOT FOUND in ${entityName} (${primaryKeyInfo})`);\n console.error(` Field: ${fieldName}`);\n console.error(` Value: ${fieldValue}`);\n console.error(` Error: ${fieldError.message}`);\n console.error(` Tip: Check if the field name exists in the target entity\\n`);\n } else if (fieldError.message?.includes('File not found:')) {\n console.error(`\\n❌ FILE NOT FOUND in ${entityName} (${primaryKeyInfo})`);\n console.error(` Field: ${fieldName}`);\n console.error(` Value: ${fieldValue}`);\n console.error(` Error: ${fieldError.message}`);\n console.error(` Tip: Check if the file path is correct relative to ${entityDir}\\n`);\n } else {\n console.error(`\\n❌ FIELD PROCESSING ERROR in ${entityName} (${primaryKeyInfo})`);\n console.error(` Field: ${fieldName}`);\n console.error(` Value: ${fieldValue}`);\n console.error(` 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 // 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 saveResult = await entity.Save();\n } catch (saveError: any) {\n console.error(`\\n❌ SAVE EXCEPTION for ${entityName}`);\n console.error(` Record ID: ${entityRecordId || 'NEW'}`);\n console.error(` Record Name: ${recordName || 'N/A'}`);\n console.error(` File Path: ${flattenedRecord.path}`);\n console.error(` Error: ${saveError.message || saveError}`);\n \n // Check for specific error patterns\n if (saveError.message?.includes('Cannot insert the value NULL')) {\n console.error(` Tip: A required field is NULL. Check the entity's required fields.`);\n } else if (saveError.message?.includes('FOREIGN KEY constraint')) {\n console.error(` Tip: Foreign key constraint violation. Check that referenced records exist.`);\n } else if (saveError.message?.includes('duplicate key')) {\n console.error(` Tip: Duplicate key violation. A record with these values already exists.`);\n } else if (saveError.message?.includes('Incorrect syntax')) {\n console.error(` Tip: SQL syntax error. Check for special characters in field values.`);\n }\n \n // Log problematic field values for debugging\n console.error(`\\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 console.error(` ${field.Name}: ${displayValue}`);\n }\n }\n console.error(''); // Empty line for readability\n throw saveError;\n }\n \n if (!saveResult) {\n console.error(`\\n❌ SAVE RETURNED FALSE for ${entityName}`);\n console.error(` Record ID: ${entityRecordId || 'NEW'}`);\n console.error(` Record Name: ${recordName || 'N/A'}`);\n console.error(` File Path: ${flattenedRecord.path}`);\n \n // Log the LatestResult for debugging\n if (entity.LatestResult) {\n if (entity.LatestResult.Message) {\n console.error(` Database Message: ${entity.LatestResult.Message}`);\n }\n if (entity.LatestResult.Errors && entity.LatestResult.Errors.length > 0) {\n console.error(` Errors:`);\n entity.LatestResult.Errors.forEach((err: any, idx: number) => {\n const errorMsg = typeof err === 'string' ? err : (err?.message || JSON.stringify(err));\n console.error(` ${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 console.error(` SQL Statement: [Available - check entity.LatestResult.SQL if needed]`);\n }\n }\n \n // Log field values that might be problematic\n console.error(`\\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 console.error(` ${field.Name}: ${displayValue}`);\n }\n }\n console.error(''); // 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 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}"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/metadata-sync",
3
- "version": "2.92.0",
3
+ "version": "2.93.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.92.0",
30
- "@memberjunction/core-entities": "2.92.0",
31
- "@memberjunction/core-entities-server": "2.92.0",
32
- "@memberjunction/global": "2.92.0",
33
- "@memberjunction/sqlserver-dataprovider": "2.92.0",
34
- "@memberjunction/graphql-dataprovider": "2.92.0",
29
+ "@memberjunction/core": "2.93.0",
30
+ "@memberjunction/core-entities": "2.93.0",
31
+ "@memberjunction/core-entities-server": "2.93.0",
32
+ "@memberjunction/global": "2.93.0",
33
+ "@memberjunction/sqlserver-dataprovider": "2.93.0",
34
+ "@memberjunction/graphql-dataprovider": "2.93.0",
35
35
  "chokidar": "^3.6.0",
36
36
  "cosmiconfig": "9.0.0",
37
37
  "dotenv": "16.4.5",