@memberjunction/metadata-sync 2.52.0 → 2.53.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +138 -1
- package/dist/commands/push/index.d.ts +4 -0
- package/dist/commands/push/index.js +100 -10
- package/dist/commands/push/index.js.map +1 -1
- package/dist/config.d.ts +23 -0
- package/dist/config.js.map +1 -1
- package/dist/lib/provider-utils.d.ts +4 -2
- package/dist/lib/provider-utils.js +26 -4
- package/dist/lib/provider-utils.js.map +1 -1
- package/dist/lib/sync-engine.d.ts +4 -1
- package/dist/lib/sync-engine.js +49 -16
- package/dist/lib/sync-engine.js.map +1 -1
- package/dist/services/ValidationService.d.ts +9 -0
- package/dist/services/ValidationService.js +268 -70
- package/dist/services/ValidationService.js.map +1 -1
- package/dist/types/validation.d.ts +6 -2
- package/dist/types/validation.js.map +1 -1
- package/oclif.manifest.json +25 -25
- package/package.json +7 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/push/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { Command, Flags } from '@oclif/core';\nimport fs from 'fs-extra';\nimport path from 'path';\nimport { confirm } from '@inquirer/prompts';\nimport ora from 'ora-classic';\nimport fastGlob from 'fast-glob';\nimport chalk from 'chalk';\nimport { loadMJConfig, loadSyncConfig, loadEntityConfig } from '../../config';\nimport { SyncEngine, RecordData } from '../../lib/sync-engine';\nimport { initializeProvider, findEntityDirectories, getSystemUser } from '../../lib/provider-utils';\nimport { BaseEntity, LogStatus, Metadata } from '@memberjunction/core';\nimport { configManager } from '../../lib/config-manager';\nimport { getSyncEngine, resetSyncEngine } from '../../lib/singleton-manager';\nimport { SQLServerDataProvider, type SqlLoggingSession } from '@memberjunction/sqlserver-dataprovider';\nimport { uuidv4 } from '@memberjunction/global';\nimport { FileBackupManager } from '../../lib/file-backup-manager';\n\nexport default class Push extends Command {\n static description = 'Push local file changes to the database';\n \n private warnings: string[] = [];\n private errors: string[] = [];\n private processedRecords: Map<string, { filePath: string; arrayIndex?: number; lineNumber?: number }> = new Map();\n \n static examples = [\n `<%= config.bin %> <%= command.id %>`,\n `<%= config.bin %> <%= command.id %> --dry-run`,\n `<%= config.bin %> <%= command.id %> --dir=\"ai-prompts\"`,\n `<%= config.bin %> <%= command.id %> --ci`,\n ];\n \n static flags = {\n dir: Flags.string({ description: 'Specific entity directory to push' }),\n 'dry-run': Flags.boolean({ description: 'Show what would be pushed without actually pushing' }),\n ci: Flags.boolean({ description: 'CI mode - no prompts, fail on issues' }),\n verbose: Flags.boolean({ char: 'v', description: 'Show detailed field-level output' }),\n 'no-validate': Flags.boolean({ description: 'Skip validation before push' }),\n };\n \n // Override warn to collect warnings\n warn(input: string | Error): string | Error {\n const message = typeof input === 'string' ? input : input.message;\n this.warnings.push(message);\n return super.warn(input);\n }\n \n async run(): Promise<void> {\n const { flags } = await this.parse(Push);\n const spinner = ora();\n let sqlLogger: SqlLoggingSession | null = null;\n const fileBackupManager = new FileBackupManager();\n let hasActiveTransaction = false;\n const startTime = Date.now();\n \n // Reset the processed records tracking for this push operation\n this.processedRecords.clear();\n \n try {\n // Load configurations\n spinner.start('Loading configuration');\n const mjConfig = loadMJConfig();\n if (!mjConfig) {\n this.error('No mj.config.cjs found in current directory or parent directories');\n }\n \n // Load sync config from target directory if --dir is specified, otherwise from current directory\n const syncConfigDir = flags.dir ? path.resolve(configManager.getOriginalCwd(), flags.dir) : configManager.getOriginalCwd();\n const syncConfig = await loadSyncConfig(syncConfigDir);\n \n // Stop spinner before provider initialization (which logs to console)\n spinner.stop();\n \n // Initialize data provider\n await initializeProvider(mjConfig);\n \n // Initialize sync engine using singleton pattern\n const syncEngine = await getSyncEngine(getSystemUser());\n \n // Show success after all initialization is complete\n if (flags.verbose) {\n spinner.succeed('Configuration and metadata loaded');\n } else {\n spinner.stop();\n }\n \n // Initialize SQL logging AFTER provider setup is complete\n if (syncConfig?.sqlLogging?.enabled) {\n const outputDir = syncConfig.sqlLogging.outputDirectory || './sql_logging';\n const formatAsMigration = syncConfig.sqlLogging.formatAsMigration || false;\n \n // Ensure output directory exists\n const fullOutputDir = path.resolve(outputDir);\n await fs.ensureDir(fullOutputDir);\n \n // Generate filename with timestamp and directory name\n const now = new Date();\n const humanReadableTimestamp = now.toISOString()\n .replace('T', '_')\n .replace(/:/g, '-')\n .slice(0, -5); // Remove milliseconds and Z\n \n // Get directory name for filename\n const targetDir = flags.dir ? path.resolve(configManager.getOriginalCwd(), flags.dir) : configManager.getOriginalCwd();\n const dirName = path.basename(targetDir);\n \n const filename = formatAsMigration \n ? `V${now.toISOString().replace(/[:.T-]/g, '').slice(0, -5)}__MetadataSync_Push.sql`\n : `metadata-sync-push_${dirName}_${humanReadableTimestamp}.sql`;\n const logFilePath = path.join(fullOutputDir, filename);\n \n // Import and access the data provider from the provider utils\n const { getDataProvider } = await import('../../lib/provider-utils');\n const dataProvider = getDataProvider();\n \n if (dataProvider && typeof dataProvider.CreateSqlLogger === 'function') {\n sqlLogger = await dataProvider.CreateSqlLogger(logFilePath, {\n formatAsMigration,\n description: 'MetadataSync Push Operation',\n statementTypes: 'mutations', // Only log mutations (data changes)\n batchSeparator: 'GO', // Add GO statements for SQL Server batch processing\n prettyPrint: true // Enable pretty printing for readable output\n });\n \n if (flags.verbose) {\n this.log(`📝 SQL logging enabled: ${path.relative(process.cwd(), logFilePath)}`);\n }\n } else {\n this.warn('SQL logging requested but data provider does not support CreateSqlLogger');\n }\n }\n \n // Find entity directories to process\n const entityDirs = findEntityDirectories(configManager.getOriginalCwd(), flags.dir, syncConfig?.directoryOrder);\n \n if (entityDirs.length === 0) {\n this.error('No entity directories found');\n }\n \n if (flags.verbose) {\n this.log(`Found ${entityDirs.length} entity ${entityDirs.length === 1 ? 'directory' : 'directories'} to process`);\n }\n \n // Run validation unless disabled\n if (!flags['no-validate']) {\n const { ValidationService } = await import('../../services/ValidationService');\n const { FormattingService } = await import('../../services/FormattingService');\n \n spinner.start('Validating metadata...');\n const validator = new ValidationService({ verbose: flags.verbose });\n const formatter = new FormattingService();\n \n const targetDir = flags.dir ? path.resolve(configManager.getOriginalCwd(), flags.dir) : configManager.getOriginalCwd();\n const validationResult = await validator.validateDirectory(targetDir);\n spinner.stop();\n \n if (!validationResult.isValid || validationResult.warnings.length > 0) {\n // Show validation results\n this.log('\\n' + formatter.formatValidationResult(validationResult, flags.verbose));\n \n if (!validationResult.isValid) {\n // In CI mode, fail immediately\n if (flags.ci) {\n this.error('Validation failed. Cannot proceed with push.');\n }\n \n // Otherwise, ask for confirmation\n const shouldContinue = await confirm({\n message: 'Validation failed with errors. Do you want to continue anyway?',\n default: false\n });\n \n if (!shouldContinue) {\n this.error('Push cancelled due to validation errors.');\n }\n }\n } else {\n this.log(chalk.green('✓ Validation passed'));\n }\n }\n \n // Initialize file backup manager (unless in dry-run mode)\n if (!flags['dry-run']) {\n await fileBackupManager.initialize();\n if (flags.verbose) {\n this.log('📁 File backup manager initialized');\n }\n }\n \n // Start a database transaction for the entire push operation (unless in dry-run mode)\n // IMPORTANT: We start the transaction AFTER metadata loading and validation to avoid\n // transaction conflicts with background refresh operations\n if (!flags['dry-run']) {\n const { getDataProvider } = await import('../../lib/provider-utils');\n const dataProvider = getDataProvider();\n \n // Ensure we have SQLServerDataProvider for transaction support\n if (!(dataProvider instanceof SQLServerDataProvider)) {\n const errorMsg = 'MetadataSync requires SQLServerDataProvider for transaction support. Current provider does not support transactions.';\n \n // Rollback file backups since we're not proceeding\n try {\n await fileBackupManager.rollback();\n } catch (rollbackError) {\n this.warn(`Failed to rollback file backup initialization: ${rollbackError}`);\n }\n \n this.error(errorMsg);\n }\n \n if (dataProvider && typeof dataProvider.BeginTransaction === 'function') {\n try {\n await dataProvider.BeginTransaction();\n hasActiveTransaction = true;\n if (flags.verbose) {\n this.log('🔄 Transaction started - all changes will be committed or rolled back as a unit');\n }\n } catch (error) {\n // Transaction start failure is critical - we should not proceed without it\n const errorMsg = `Failed to start database transaction: ${error instanceof Error ? error.message : String(error)}`;\n \n // Rollback file backups since we're not proceeding\n try {\n await fileBackupManager.rollback();\n } catch (rollbackError) {\n this.warn(`Failed to rollback file backup initialization: ${rollbackError}`);\n }\n \n this.error(errorMsg);\n }\n } else {\n // No transaction support is also critical for data integrity\n const errorMsg = 'Transaction support not available - cannot ensure data integrity';\n \n // Rollback file backups since we're not proceeding\n try {\n await fileBackupManager.rollback();\n } catch (rollbackError) {\n this.warn(`Failed to rollback file backup initialization: ${rollbackError}`);\n }\n \n this.error(errorMsg);\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 for (const entityDir of entityDirs) {\n const entityConfig = await loadEntityConfig(entityDir);\n if (!entityConfig) {\n this.warn(`Skipping ${entityDir} - no valid entity configuration`);\n continue;\n }\n \n if (flags.verbose) {\n this.log(`\\nProcessing ${entityConfig.entity} in ${entityDir}`);\n }\n \n const result = await this.processEntityDirectory(\n entityDir,\n entityConfig,\n syncEngine,\n flags,\n syncConfig,\n fileBackupManager\n );\n \n // Show per-directory summary\n const dirName = path.relative(process.cwd(), entityDir) || '.';\n const dirTotal = result.created + result.updated + result.unchanged;\n if (dirTotal > 0 || result.errors > 0) {\n this.log(`\\n📁 ${dirName}:`);\n this.log(` Total processed: ${dirTotal} unique records`);\n if (result.created > 0) {\n this.log(` ✓ Created: ${result.created}`);\n }\n if (result.updated > 0) {\n this.log(` ✓ Updated: ${result.updated}`);\n }\n if (result.unchanged > 0) {\n this.log(` - Unchanged: ${result.unchanged}`);\n }\n if (result.errors > 0) {\n this.log(` ✗ 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 // Summary using FormattingService\n const endTime = Date.now();\n const { FormattingService } = await import('../../services/FormattingService');\n const formatter = new FormattingService();\n \n this.log('\\n' + formatter.formatSyncSummary('push', {\n created: totalCreated,\n updated: totalUpdated,\n unchanged: totalUnchanged,\n deleted: 0,\n skipped: 0,\n errors: totalErrors,\n duration: endTime - startTime\n }));\n \n // Handle transaction commit/rollback\n if (!flags['dry-run'] && hasActiveTransaction) {\n const dataProvider = Metadata.Provider as SQLServerDataProvider;\n \n // We know we have an active transaction at this point\n if (dataProvider) {\n let shouldCommit = true;\n \n // If there are any errors, always rollback\n if (totalErrors > 0 || this.errors.length > 0) {\n shouldCommit = false;\n this.log('\\n❌ Errors detected - rolling back all changes');\n }\n // If there are warnings, ask user (unless in CI mode)\n else if (this.warnings.length > 0) {\n // Filter out transaction-related warnings since we're now using transactions\n const nonTransactionWarnings = this.warnings.filter(w => \n !w.includes('Transaction support not available') && \n !w.includes('Failed to start transaction')\n );\n \n if (nonTransactionWarnings.length > 0) {\n if (flags.ci) {\n // In CI mode, rollback on warnings\n shouldCommit = false;\n this.log('\\n⚠️ Warnings detected in CI mode - rolling back all changes');\n } else {\n // Show warnings to user\n this.log('\\n⚠️ The following warnings were encountered:');\n for (const warning of nonTransactionWarnings) {\n this.log(` - ${warning}`);\n }\n \n // Ask user whether to commit or rollback\n shouldCommit = await confirm({\n message: 'Do you want to commit these changes despite the warnings?',\n default: false // Default to rollback\n });\n }\n }\n }\n \n try {\n if (shouldCommit) {\n await dataProvider.CommitTransaction();\n this.log('\\n✅ All changes committed successfully');\n \n // Clean up file backups after successful commit\n await fileBackupManager.cleanup();\n } else {\n // User chose to rollback or errors/warnings in CI mode\n this.log('\\n🔙 Rolling back all changes...');\n \n // Rollback database transaction\n await dataProvider.RollbackTransaction();\n \n // Rollback file changes\n this.log('🔙 Rolling back file changes...');\n await fileBackupManager.rollback();\n \n this.log('✅ Rollback completed - no changes were made to the database or files');\n }\n } catch (error) {\n // Try to rollback on any error\n this.log('\\n❌ Transaction error - attempting to roll back changes');\n try {\n await dataProvider.RollbackTransaction();\n this.log('✅ Database rollback completed');\n } catch (rollbackError) {\n this.log('❌ Database rollback failed: ' + (rollbackError instanceof Error ? rollbackError.message : String(rollbackError)));\n }\n \n // Also rollback file changes\n try {\n this.log('🔙 Rolling back file changes...');\n await fileBackupManager.rollback();\n this.log('✅ File rollback completed');\n } catch (fileRollbackError) {\n this.log('❌ File rollback failed: ' + (fileRollbackError instanceof Error ? fileRollbackError.message : String(fileRollbackError)));\n }\n \n throw error;\n }\n }\n }\n \n // Exit with error if there were errors in CI mode\n if ((totalErrors > 0 || this.errors.length > 0 || (this.warnings.length > 0 && flags.ci)) && flags.ci) {\n this.error('Push failed in CI mode');\n }\n \n } catch (error) {\n spinner.fail('Push failed');\n \n // Try to rollback the transaction and files if not in dry-run mode\n if (!flags['dry-run']) {\n const { getDataProvider } = await import('../../lib/provider-utils');\n const dataProvider = getDataProvider();\n \n // Rollback database transaction if we have one\n if (hasActiveTransaction && dataProvider && typeof dataProvider.RollbackTransaction === 'function') {\n try {\n this.log('\\n🔙 Rolling back database transaction due to error...');\n await dataProvider.RollbackTransaction();\n this.log('✅ Database rollback completed');\n } catch (rollbackError) {\n this.log('❌ Database rollback failed: ' + (rollbackError instanceof Error ? rollbackError.message : String(rollbackError)));\n }\n }\n \n // Rollback file changes\n try {\n this.log('🔙 Rolling back file changes...');\n await fileBackupManager.rollback();\n this.log('✅ File rollback completed - all files restored to original state');\n } catch (fileRollbackError) {\n this.log('❌ File rollback failed: ' + (fileRollbackError instanceof Error ? fileRollbackError.message : String(fileRollbackError)));\n }\n }\n \n // Enhanced error logging for debugging\n this.log('\\n=== Push Error Details ===');\n this.log(`Error type: ${error?.constructor?.name || 'Unknown'}`);\n this.log(`Error message: ${error instanceof Error ? error.message : String(error)}`);\n \n if (error instanceof Error && error.stack) {\n this.log(`\\nStack trace:`);\n this.log(error.stack);\n }\n \n // Log context information\n this.log(`\\nContext:`);\n this.log(`- Working directory: ${configManager.getOriginalCwd()}`);\n this.log(`- Flags: ${JSON.stringify(flags, null, 2)}`);\n \n // Check if error is related to common issues\n const errorMessage = error instanceof Error ? error.message : String(error);\n if (errorMessage.includes('entity directories')) {\n this.log(`\\nHint: This appears to be an entity directory configuration issue.`);\n this.log(`Make sure each entity directory has a .mj-sync.json file.`);\n } else if (errorMessage.includes('database') || errorMessage.includes('connection')) {\n this.log(`\\nHint: This appears to be a database connectivity issue.`);\n this.log(`Check your mj.config.cjs configuration and database connectivity.`);\n } else if (errorMessage.includes('config') || errorMessage.includes('mj.config.cjs')) {\n this.log(`\\nHint: This appears to be a configuration file issue.`);\n this.log(`Make sure mj.config.cjs exists and is properly configured.`);\n }\n \n this.error(error as Error);\n } finally {\n // Dispose SQL logging session if active\n if (sqlLogger) {\n try {\n await sqlLogger.dispose();\n if (flags.verbose) {\n this.log('✅ SQL logging session closed');\n }\n } catch (error) {\n this.warn(`Failed to close SQL logging session: ${error}`);\n }\n }\n \n // Reset sync engine singleton\n resetSyncEngine();\n \n // Exit process to prevent background MJ tasks from throwing errors\n // We don't explicitly close the connection - let the process termination handle it\n process.exit(0);\n }\n }\n \n private async processEntityDirectory(\n entityDir: string,\n entityConfig: any,\n syncEngine: SyncEngine,\n flags: any,\n syncConfig: any,\n fileBackupManager?: FileBackupManager\n ): Promise<{ created: number; updated: number; unchanged: number; errors: number }> {\n const result = { created: 0, updated: 0, unchanged: 0, errors: 0 };\n \n // Find files matching the configured pattern\n const pattern = entityConfig.filePattern || '*.json';\n const jsonFiles = await fastGlob(pattern, {\n cwd: entityDir,\n ignore: ['.mj-sync.json', '.mj-folder.json', '**/*.backup'],\n dot: true, // Include dotfiles (files starting with .)\n onlyFiles: true\n });\n \n if (flags.verbose) {\n this.log(`Processing ${jsonFiles.length} records in ${path.relative(process.cwd(), entityDir) || '.'}`);\n }\n \n // First, process all JSON files in this directory\n await this.processJsonFiles(jsonFiles, entityDir, entityConfig, syncEngine, flags, result, fileBackupManager);\n \n // Then, recursively process subdirectories\n const entries = await fs.readdir(entityDir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isDirectory() && !entry.name.startsWith('.')) {\n const subDir = path.join(entityDir, entry.name);\n \n // Load subdirectory config and merge with parent config\n let subEntityConfig = { ...entityConfig };\n const subDirConfig = await loadEntityConfig(subDir);\n \n if (subDirConfig) {\n // Check if this is a new entity type (has different entity name)\n if (subDirConfig.entity && subDirConfig.entity !== entityConfig.entity) {\n // This is a different entity type, skip it (will be processed separately)\n continue;\n }\n \n // Merge defaults: parent defaults + subdirectory overrides\n subEntityConfig = {\n ...entityConfig,\n ...subDirConfig,\n defaults: {\n ...entityConfig.defaults,\n ...(subDirConfig.defaults || {})\n }\n };\n }\n \n // Process subdirectory with merged config\n const subResult = await this.processEntityDirectory(\n subDir,\n subEntityConfig,\n syncEngine,\n flags,\n syncConfig,\n fileBackupManager\n );\n \n result.created += subResult.created;\n result.updated += subResult.updated;\n result.unchanged += subResult.unchanged;\n result.errors += subResult.errors;\n }\n }\n \n return result;\n }\n \n private async processJsonFiles(\n jsonFiles: string[],\n entityDir: string,\n entityConfig: any,\n syncEngine: SyncEngine,\n flags: any,\n result: { created: number; updated: number; unchanged: number; errors: number },\n fileBackupManager?: FileBackupManager\n ): Promise<void> {\n if (jsonFiles.length === 0) {\n return;\n }\n \n const spinner = ora();\n spinner.start('Processing records');\n \n \n for (const file of jsonFiles) {\n try {\n const filePath = path.join(entityDir, file);\n \n // Backup the file before any modifications (unless dry-run)\n if (!flags['dry-run'] && fileBackupManager) {\n await fileBackupManager.backupFile(filePath);\n }\n \n // Parse JSON with line number tracking\n const { content: fileContent, lineNumbers } = await this.parseJsonWithLineNumbers(filePath);\n \n // Process templates in the loaded content\n const processedContent = await syncEngine.processTemplates(fileContent, entityDir);\n \n // Check if the file contains a single record or an array of records\n const isArray = Array.isArray(processedContent);\n const records: RecordData[] = isArray ? processedContent : [processedContent];\n \n // Build and process defaults (including lookups)\n const defaults = await syncEngine.buildDefaults(filePath, entityConfig);\n \n // Process each record in the file\n for (let i = 0; i < records.length; i++) {\n const recordData = records[i];\n \n // Process the record\n const recordLineNumber = lineNumbers.get(i); // Get line number for this array index\n const pushResult = await this.pushRecord(\n recordData,\n entityConfig.entity,\n path.dirname(filePath),\n file,\n defaults,\n syncEngine,\n flags['dry-run'],\n flags.verbose,\n isArray ? i : undefined,\n fileBackupManager,\n recordLineNumber\n );\n \n if (!flags['dry-run']) {\n // Don't count duplicates in stats\n if (!pushResult.isDuplicate) {\n if (pushResult.isNew) {\n result.created++;\n } else if (pushResult.wasActuallyUpdated) {\n result.updated++;\n } else {\n result.unchanged++;\n }\n }\n \n // Add related entity stats\n if (pushResult.relatedStats) {\n result.created += pushResult.relatedStats.created;\n result.updated += pushResult.relatedStats.updated;\n result.unchanged += pushResult.relatedStats.unchanged;\n \n // Debug logging for related entities\n if (flags.verbose && pushResult.relatedStats.unchanged > 0) {\n this.log(` Related entities: ${pushResult.relatedStats.unchanged} unchanged`);\n }\n }\n }\n \n spinner.text = `Processing records (${result.created + result.updated + result.unchanged + result.errors} processed)`;\n }\n \n // Write back the entire file if it's an array\n if (isArray && !flags['dry-run']) {\n await fs.writeJson(filePath, records, { spaces: 2 });\n }\n \n } catch (error) {\n result.errors++;\n const errorMessage = error instanceof Error ? error.message : String(error);\n const fullErrorMessage = `Failed to process ${file}: ${errorMessage}`;\n this.errors.push(fullErrorMessage);\n this.error(fullErrorMessage, { exit: false });\n }\n }\n \n if (flags.verbose) {\n spinner.succeed(`Processed ${result.created + result.updated + result.unchanged} records from ${jsonFiles.length} files`);\n } else {\n spinner.stop();\n }\n }\n \n private async pushRecord(\n recordData: RecordData,\n entityName: string,\n baseDir: string,\n fileName: string,\n defaults: Record<string, any>,\n syncEngine: SyncEngine,\n dryRun: boolean,\n verbose: boolean = false,\n arrayIndex?: number,\n fileBackupManager?: FileBackupManager,\n lineNumber?: number\n ): Promise<{ isNew: boolean; wasActuallyUpdated: boolean; isDuplicate: boolean; relatedStats?: { created: number; updated: number; unchanged: number } }> {\n // Load or create entity\n let entity: BaseEntity | null = null;\n let isNew = false;\n \n if (recordData.primaryKey) {\n entity = await syncEngine.loadEntity(entityName, recordData.primaryKey);\n \n // Warn if record has primaryKey but wasn't found\n if (!entity) {\n const pkDisplay = Object.entries(recordData.primaryKey)\n .map(([key, value]) => `${key}=${value}`)\n .join(', ');\n \n // Load sync config to check autoCreateMissingRecords setting\n const syncConfig = await loadSyncConfig(configManager.getOriginalCwd());\n const autoCreate = syncConfig?.push?.autoCreateMissingRecords ?? false;\n \n if (!autoCreate) {\n const fileRef = lineNumber ? `${fileName}:${lineNumber}` : fileName;\n this.warn(`⚠️ Record not found: ${entityName} with primaryKey {${pkDisplay}} at ${fileRef}`);\n this.warn(` To auto-create missing records, set push.autoCreateMissingRecords=true in .mj-sync.json`);\n \n // Skip this record\n return { isNew: false, wasActuallyUpdated: false, isDuplicate: false };\n } else {\n if (verbose) {\n this.log(` Auto-creating missing ${entityName} record with primaryKey {${pkDisplay}}`);\n }\n }\n }\n }\n \n if (!entity) {\n // New record\n entity = await syncEngine.createEntityObject(entityName);\n entity.NewRecord();\n isNew = true;\n \n // Handle primary keys for new records\n const entityInfo = syncEngine.getEntityInfo(entityName);\n if (entityInfo) {\n for (const pk of entityInfo.PrimaryKeys) {\n if (!pk.AutoIncrement) {\n // Check if we have a value in primaryKey object\n if (recordData.primaryKey?.[pk.Name]) {\n // User specified a primary key for new record, set it on entity directly\n // Don't add to fields as it will be in primaryKey section\n (entity as any)[pk.Name] = recordData.primaryKey[pk.Name];\n if (verbose) {\n this.log(` Using specified primary key ${pk.Name}: ${recordData.primaryKey[pk.Name]}`);\n }\n } else if (pk.Type.toLowerCase() === 'uniqueidentifier' && !recordData.fields[pk.Name]) {\n // Generate UUID for this primary key and set it on entity directly\n const uuid = uuidv4();\n // Don't add to fields as it will be in primaryKey section after save\n if (verbose) {\n this.log(` Generated UUID for primary key ${pk.Name}: ${uuid}`);\n }\n // Set the generated UUID on the entity\n (entity as any)[pk.Name] = uuid;\n }\n }\n }\n }\n }\n \n // Apply defaults first\n for (const [field, value] of Object.entries(defaults)) {\n if (field in entity) {\n (entity as any)[field] = value;\n }\n }\n \n // Apply record fields\n for (const [field, value] of Object.entries(recordData.fields)) {\n if (field in entity) {\n try {\n const processedValue = await syncEngine.processFieldValue(value, baseDir, null, null);\n if (verbose) {\n this.log(` Setting ${field}: ${JSON.stringify(value)} -> ${JSON.stringify(processedValue)}`);\n }\n (entity as any)[field] = processedValue;\n } catch (error) {\n throw new Error(`Failed to process field '${field}': ${error}`);\n }\n } else {\n this.warn(`Field '${field}' does not exist on entity '${entityName}'`);\n }\n }\n \n if (dryRun) {\n this.log(`Would ${isNew ? 'create' : 'update'} ${entityName} record`);\n return { isNew, wasActuallyUpdated: true, isDuplicate: false, relatedStats: undefined };\n }\n \n // Check for duplicate processing (but only for existing records that were loaded)\n let isDuplicate = false;\n if (!isNew && entity) {\n const fullFilePath = path.join(baseDir, fileName);\n isDuplicate = this.checkAndTrackRecord(entityName, entity, fullFilePath, arrayIndex, lineNumber);\n }\n \n // Check if the record is dirty before saving\n let wasActuallyUpdated = false;\n if (!isNew && entity.Dirty) {\n // Record is dirty, get the changes\n const changes = entity.GetChangesSinceLastSave();\n const changeKeys = Object.keys(changes);\n if (changeKeys.length > 0) {\n wasActuallyUpdated = true;\n \n // Get primary key info for display\n const entityInfo = 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 this.log(''); // Add newline before update output\n this.log(`📝 Updating ${entityName} record:`);\n if (primaryKeyDisplay.length > 0) {\n this.log(` Primary Key: ${primaryKeyDisplay.join(', ')}`);\n }\n this.log(` 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 this.log(` ${fieldName}: ${oldValue} → ${newValue}`);\n }\n }\n } else if (isNew) {\n wasActuallyUpdated = true;\n }\n \n // Save the record\n const saved = await entity.Save();\n if (!saved) {\n const message = entity.LatestResult?.Message;\n if (message) {\n throw new Error(`Failed to save record: ${message}`);\n }\n \n const errors = entity.LatestResult?.Errors?.map(err => \n typeof err === 'string' ? err : (err?.message || JSON.stringify(err))\n )?.join(', ') || 'Unknown error';\n throw new Error(`Failed to save record: ${errors}`);\n }\n \n // Process related entities after saving parent\n let relatedStats;\n if (recordData.relatedEntities && !dryRun) {\n const fullFilePath = path.join(baseDir, fileName);\n relatedStats = await this.processRelatedEntities(\n recordData.relatedEntities,\n entity,\n entity, // root is same as parent for top level\n baseDir,\n syncEngine,\n verbose,\n fileBackupManager,\n 1, // indentLevel\n fullFilePath,\n arrayIndex\n );\n }\n \n // Update the local file with new primary key if created\n if (isNew) {\n const entityInfo = 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 recordData.primaryKey = newPrimaryKey;\n }\n \n // Track the new record now that we have its primary key\n const fullFilePath = path.join(baseDir, fileName);\n this.checkAndTrackRecord(entityName, entity, fullFilePath, arrayIndex, lineNumber);\n }\n \n // Always update sync metadata\n // This ensures related entities are persisted with their metadata\n recordData.sync = {\n lastModified: new Date().toISOString(),\n checksum: syncEngine.calculateChecksum(recordData.fields)\n };\n \n // Write back to file only if it's a single record (not part of an array)\n // Array records are written back in bulk after all records are processed\n if (arrayIndex === undefined) {\n const filePath = path.join(baseDir, fileName);\n await fs.writeJson(filePath, recordData, { spaces: 2 });\n }\n \n return { isNew, wasActuallyUpdated, isDuplicate, relatedStats };\n }\n \n private async processRelatedEntities(\n relatedEntities: Record<string, RecordData[]>,\n parentEntity: BaseEntity,\n rootEntity: BaseEntity,\n baseDir: string,\n syncEngine: SyncEngine,\n verbose: boolean = false,\n fileBackupManager?: FileBackupManager,\n indentLevel: number = 1,\n parentFilePath?: string,\n parentArrayIndex?: number\n ): Promise<{ created: number; updated: number; unchanged: number }> {\n const indent = ' '.repeat(indentLevel);\n const stats = { created: 0, updated: 0, unchanged: 0 };\n \n for (const [entityName, records] of Object.entries(relatedEntities)) {\n if (verbose) {\n this.log(`${indent}↳ Processing ${records.length} related ${entityName} records`);\n }\n \n for (const relatedRecord of records) {\n try {\n // Load or create entity\n let entity = null;\n let isNew = false;\n \n if (relatedRecord.primaryKey) {\n entity = await syncEngine.loadEntity(entityName, relatedRecord.primaryKey);\n \n // Warn if record has primaryKey but wasn't found\n if (!entity) {\n const pkDisplay = Object.entries(relatedRecord.primaryKey)\n .map(([key, value]) => `${key}=${value}`)\n .join(', ');\n \n // Load sync config to check autoCreateMissingRecords setting\n const syncConfig = await loadSyncConfig(configManager.getOriginalCwd());\n const autoCreate = syncConfig?.push?.autoCreateMissingRecords ?? false;\n \n if (!autoCreate) {\n const fileRef = parentFilePath ? path.relative(configManager.getOriginalCwd(), parentFilePath) : 'unknown';\n this.warn(`${indent}⚠️ Related record not found: ${entityName} with primaryKey {${pkDisplay}} at ${fileRef}`);\n this.warn(`${indent} To auto-create missing records, set push.autoCreateMissingRecords=true in .mj-sync.json`);\n \n // Skip this record\n continue;\n } else {\n if (verbose) {\n this.log(`${indent} Auto-creating missing related ${entityName} record with primaryKey {${pkDisplay}}`);\n }\n }\n }\n }\n \n if (!entity) {\n entity = await syncEngine.createEntityObject(entityName);\n entity.NewRecord();\n isNew = true;\n \n // Handle primary keys for new related entity records\n const entityInfo = syncEngine.getEntityInfo(entityName);\n if (entityInfo) {\n for (const pk of entityInfo.PrimaryKeys) {\n if (!pk.AutoIncrement) {\n // Check if we have a value in primaryKey object\n if (relatedRecord.primaryKey?.[pk.Name]) {\n // User specified a primary key for new record, set it on entity directly\n // Don't add to fields as it will be in primaryKey section\n (entity as any)[pk.Name] = relatedRecord.primaryKey[pk.Name];\n if (verbose) {\n this.log(`${indent} Using specified primary key ${pk.Name}: ${relatedRecord.primaryKey[pk.Name]}`);\n }\n } else if (pk.Type.toLowerCase() === 'uniqueidentifier' && !relatedRecord.fields[pk.Name]) {\n // Generate UUID for this primary key and set it on entity directly\n const uuid = uuidv4();\n // Don't add to fields as it will be in primaryKey section after save\n (entity as any)[pk.Name] = uuid;\n if (verbose) {\n this.log(`${indent} Generated UUID for primary key ${pk.Name}: ${uuid}`);\n }\n }\n }\n }\n }\n }\n \n // Apply fields with parent/root context\n for (const [field, value] of Object.entries(relatedRecord.fields)) {\n if (field in entity) {\n try {\n const processedValue = await syncEngine.processFieldValue(\n value, \n baseDir, \n parentEntity, \n rootEntity\n );\n if (verbose) {\n this.log(`${indent} Setting ${field}: ${JSON.stringify(value)} -> ${JSON.stringify(processedValue)}`);\n }\n (entity as any)[field] = processedValue;\n } catch (error) {\n throw new Error(`Failed to process field '${field}' in ${entityName}: ${error}`);\n }\n } else {\n this.warn(`${indent} Field '${field}' does not exist on entity '${entityName}'`);\n }\n }\n \n // Check for duplicate processing (but only for existing records that were loaded)\n let isDuplicate = false;\n if (!isNew && entity) {\n // Use parent file path for related entities since they're defined in the parent's file\n const relatedFilePath = parentFilePath || path.join(baseDir, 'unknown');\n isDuplicate = this.checkAndTrackRecord(entityName, entity, relatedFilePath, parentArrayIndex);\n }\n \n // Check if the record is dirty before saving\n let wasActuallyUpdated = false;\n if (!isNew && entity.Dirty) {\n // Record is dirty, get the changes\n const changes = entity.GetChangesSinceLastSave();\n const changeKeys = Object.keys(changes);\n if (changeKeys.length > 0) {\n wasActuallyUpdated = true;\n \n // Get primary key info for display\n const entityInfo = 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 this.log(''); // Add newline before update output\n this.log(`${indent}📝 Updating related ${entityName} record:`);\n if (primaryKeyDisplay.length > 0) {\n this.log(`${indent} Primary Key: ${primaryKeyDisplay.join(', ')}`);\n }\n this.log(`${indent} 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 this.log(`${indent} ${fieldName}: ${oldValue} → ${newValue}`);\n }\n }\n } else if (isNew) {\n wasActuallyUpdated = true;\n }\n \n // Save the related entity\n const saved = await entity.Save();\n if (!saved) {\n const message = entity.LatestResult?.Message;\n if (message) {\n throw new Error(`Failed to save related ${entityName}: ${message}`);\n }\n \n const errors = entity.LatestResult?.Errors?.map(err => \n typeof err === 'string' ? err : (err?.message || JSON.stringify(err))\n )?.join(', ') || 'Unknown error';\n throw new Error(`Failed to save related ${entityName}: ${errors}`);\n }\n \n // Update stats - don't count duplicates\n if (!isDuplicate) {\n if (isNew) {\n stats.created++;\n } else if (wasActuallyUpdated) {\n stats.updated++;\n } else {\n stats.unchanged++;\n }\n }\n \n if (verbose && wasActuallyUpdated) {\n this.log(`${indent} ✓ ${isNew ? 'Created' : 'Updated'} ${entityName} record`);\n } else if (verbose && !wasActuallyUpdated) {\n this.log(`${indent} - No changes to ${entityName} record`);\n }\n \n // Update the related record with primary key and sync metadata\n const entityInfo = syncEngine.getEntityInfo(entityName);\n if (entityInfo) {\n // Update primary key if new\n if (isNew) {\n relatedRecord.primaryKey = {};\n for (const pk of entityInfo.PrimaryKeys) {\n relatedRecord.primaryKey[pk.Name] = entity.Get(pk.Name);\n }\n \n // Track the new related entity now that we have its primary key\n const relatedFilePath = parentFilePath || path.join(baseDir, 'unknown');\n this.checkAndTrackRecord(entityName, entity, relatedFilePath, parentArrayIndex);\n }\n \n // Always update sync metadata\n relatedRecord.sync = {\n lastModified: new Date().toISOString(),\n checksum: syncEngine.calculateChecksum(relatedRecord.fields)\n };\n }\n \n // Process nested related entities if any\n if (relatedRecord.relatedEntities) {\n const nestedStats = await this.processRelatedEntities(\n relatedRecord.relatedEntities,\n entity,\n rootEntity,\n baseDir,\n syncEngine,\n verbose,\n fileBackupManager,\n indentLevel + 1,\n parentFilePath,\n parentArrayIndex\n );\n \n // Accumulate nested stats\n stats.created += nestedStats.created;\n stats.updated += nestedStats.updated;\n stats.unchanged += nestedStats.unchanged;\n }\n } catch (error) {\n throw new Error(`Failed to process related ${entityName}: ${error}`);\n }\n }\n }\n \n return stats;\n }\n \n /**\n * Generate a unique tracking key for a record based on entity name and primary key values\n */\n private generateRecordKey(entityName: string, entity: BaseEntity): string {\n const entityInfo = entity.EntityInfo;\n const primaryKeyValues: string[] = [];\n \n if (entityInfo && entityInfo.PrimaryKeys.length > 0) {\n for (const pk of entityInfo.PrimaryKeys) {\n const value = entity.Get(pk.Name);\n primaryKeyValues.push(`${pk.Name}:${value}`);\n }\n }\n \n return `${entityName}|${primaryKeyValues.join('|')}`;\n }\n \n /**\n * Check if a record has already been processed and warn if duplicate\n */\n private checkAndTrackRecord(\n entityName: string, \n entity: BaseEntity, \n filePath?: string,\n arrayIndex?: number,\n lineNumber?: number\n ): boolean {\n const recordKey = this.generateRecordKey(entityName, entity);\n \n const existing = this.processedRecords.get(recordKey);\n if (existing) {\n const primaryKeyDisplay = entity.EntityInfo?.PrimaryKeys\n .map(pk => `${pk.Name}: ${entity.Get(pk.Name)}`)\n .join(', ') || 'unknown';\n \n // Format file location with clickable link for VSCode\n // Create maps with just the line numbers we have\n const currentLineMap = lineNumber ? new Map([[arrayIndex || 0, lineNumber]]) : undefined;\n const originalLineMap = existing.lineNumber ? new Map([[existing.arrayIndex || 0, existing.lineNumber]]) : undefined;\n \n const currentLocation = this.formatFileLocation(filePath, arrayIndex, currentLineMap);\n const originalLocation = this.formatFileLocation(existing.filePath, existing.arrayIndex, originalLineMap);\n \n this.warn(`⚠️ Duplicate record detected for ${entityName} (${primaryKeyDisplay})`);\n this.warn(` Current location: ${currentLocation}`);\n this.warn(` Original location: ${originalLocation}`);\n this.warn(` The duplicate update will proceed, but you should review your data for unintended duplicates.`);\n \n return true; // is duplicate\n }\n \n // Track the record with its source location\n this.processedRecords.set(recordKey, {\n filePath: filePath || 'unknown',\n arrayIndex,\n lineNumber\n });\n return false; // not duplicate\n }\n \n /**\n * Parse JSON file and track line numbers for array elements\n */\n private async parseJsonWithLineNumbers(filePath: string): Promise<{\n content: any;\n lineNumbers: Map<number, number>; // arrayIndex -> lineNumber\n }> {\n const fileText = await fs.readFile(filePath, 'utf-8');\n const lines = fileText.split('\\n');\n const lineNumbers = new Map<number, number>();\n \n // Parse the JSON\n const content = JSON.parse(fileText);\n \n // If it's an array, try to find where each element starts\n if (Array.isArray(content)) {\n let inString = false;\n let bracketDepth = 0;\n let currentIndex = -1;\n \n for (let lineNum = 0; lineNum < lines.length; lineNum++) {\n const line = lines[lineNum];\n \n // Simple tracking of string boundaries and bracket depth\n for (let i = 0; i < line.length; i++) {\n const char = line[i];\n const prevChar = i > 0 ? line[i - 1] : '';\n \n if (char === '\"' && prevChar !== '\\\\') {\n inString = !inString;\n }\n \n if (!inString) {\n if (char === '{') {\n bracketDepth++;\n // If we're at depth 1 in the main array, this is a new object\n if (bracketDepth === 1 && line.trim().startsWith('{')) {\n currentIndex++;\n lineNumbers.set(currentIndex, lineNum + 1); // 1-based line numbers\n }\n } else if (char === '}') {\n bracketDepth--;\n }\n }\n }\n }\n }\n \n return { content, lineNumbers };\n }\n \n /**\n * Format file location with clickable link for VSCode\n */\n private formatFileLocation(filePath?: string, arrayIndex?: number, lineNumbers?: Map<number, number>): string {\n if (!filePath || filePath === 'unknown') {\n return 'unknown';\n }\n \n // Get absolute path for better VSCode integration\n const absolutePath = path.resolve(filePath);\n \n // Try to get actual line number from our tracking\n let lineNumber = 1;\n if (arrayIndex !== undefined && lineNumbers && lineNumbers.has(arrayIndex)) {\n lineNumber = lineNumbers.get(arrayIndex)!;\n } else if (arrayIndex !== undefined) {\n // Fallback estimation if we don't have actual line numbers\n lineNumber = 2 + (arrayIndex * 15);\n }\n \n // Create clickable file path for VSCode - format: file:line\n // VSCode will make this clickable in the terminal\n return `${absolutePath}:${lineNumber}`;\n }\n}"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/push/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { Command, Flags } from '@oclif/core';\nimport fs from 'fs-extra';\nimport path from 'path';\nimport { confirm } from '@inquirer/prompts';\nimport ora from 'ora-classic';\nimport fastGlob from 'fast-glob';\nimport chalk from 'chalk';\nimport { loadMJConfig, loadSyncConfig, loadEntityConfig } from '../../config';\nimport { SyncEngine, RecordData } from '../../lib/sync-engine';\nimport { initializeProvider, findEntityDirectories, getSystemUser } from '../../lib/provider-utils';\nimport { BaseEntity, LogStatus, Metadata } from '@memberjunction/core';\nimport { configManager } from '../../lib/config-manager';\nimport { getSyncEngine, resetSyncEngine } from '../../lib/singleton-manager';\nimport { SQLServerDataProvider, type SqlLoggingSession } from '@memberjunction/sqlserver-dataprovider';\nimport { uuidv4 } from '@memberjunction/global';\nimport { FileBackupManager } from '../../lib/file-backup-manager';\n\nexport default class Push extends Command {\n static description = 'Push local file changes to the database';\n \n private warnings: string[] = [];\n private errors: string[] = [];\n private processedRecords: Map<string, { filePath: string; arrayIndex?: number; lineNumber?: number }> = new Map();\n \n static examples = [\n `<%= config.bin %> <%= command.id %>`,\n `<%= config.bin %> <%= command.id %> --dry-run`,\n `<%= config.bin %> <%= command.id %> --dir=\"ai-prompts\"`,\n `<%= config.bin %> <%= command.id %> --ci`,\n ];\n \n static flags = {\n dir: Flags.string({ description: 'Specific entity directory to push' }),\n 'dry-run': Flags.boolean({ description: 'Show what would be pushed without actually pushing' }),\n ci: Flags.boolean({ description: 'CI mode - no prompts, fail on issues' }),\n verbose: Flags.boolean({ char: 'v', description: 'Show detailed field-level output' }),\n 'no-validate': Flags.boolean({ description: 'Skip validation before push' }),\n };\n \n // Override warn to collect warnings\n warn(input: string | Error): string | Error {\n const message = typeof input === 'string' ? input : input.message;\n this.warnings.push(message);\n return super.warn(input);\n }\n \n async run(): Promise<void> {\n const { flags } = await this.parse(Push);\n const spinner = ora();\n let sqlLogger: SqlLoggingSession | null = null;\n const fileBackupManager = new FileBackupManager();\n let hasActiveTransaction = false;\n const startTime = Date.now();\n \n // Reset the processed records tracking for this push operation\n this.processedRecords.clear();\n \n try {\n // Load configurations\n spinner.start('Loading configuration');\n const mjConfig = loadMJConfig();\n if (!mjConfig) {\n this.error('No mj.config.cjs found in current directory or parent directories');\n }\n \n // Load sync config from target directory if --dir is specified, otherwise from current directory\n const syncConfigDir = flags.dir ? path.resolve(configManager.getOriginalCwd(), flags.dir) : configManager.getOriginalCwd();\n const syncConfig = await loadSyncConfig(syncConfigDir);\n \n // Stop spinner before provider initialization (which logs to console)\n spinner.stop();\n \n // Initialize data provider\n await initializeProvider(mjConfig);\n \n // Initialize sync engine using singleton pattern\n const syncEngine = await getSyncEngine(getSystemUser());\n \n // Show success after all initialization is complete\n if (flags.verbose) {\n spinner.succeed('Configuration and metadata loaded');\n } else {\n spinner.stop();\n }\n \n // Initialize SQL logging AFTER provider setup is complete\n if (syncConfig?.sqlLogging?.enabled) {\n const outputDir = syncConfig.sqlLogging.outputDirectory || './sql_logging';\n const formatAsMigration = syncConfig.sqlLogging.formatAsMigration || false;\n \n // Ensure output directory exists\n const fullOutputDir = path.resolve(outputDir);\n await fs.ensureDir(fullOutputDir);\n \n // Generate filename with timestamp and directory name\n const now = new Date();\n const humanReadableTimestamp = now.toISOString()\n .replace('T', '_')\n .replace(/:/g, '-')\n .slice(0, -5); // Remove milliseconds and Z\n \n // Get directory name for filename\n const targetDir = flags.dir ? path.resolve(configManager.getOriginalCwd(), flags.dir) : configManager.getOriginalCwd();\n const dirName = path.basename(targetDir);\n \n const filename = formatAsMigration \n ? `V${now.toISOString().replace(/[:.T-]/g, '').slice(0, -5)}__MetadataSync_Push.sql`\n : `metadata-sync-push_${dirName}_${humanReadableTimestamp}.sql`;\n const logFilePath = path.join(fullOutputDir, filename);\n \n // Import and access the data provider from the provider utils\n const { getDataProvider } = await import('../../lib/provider-utils');\n const dataProvider = getDataProvider();\n \n if (dataProvider && typeof dataProvider.CreateSqlLogger === 'function') {\n sqlLogger = await dataProvider.CreateSqlLogger(logFilePath, {\n formatAsMigration,\n description: 'MetadataSync Push Operation',\n statementTypes: 'mutations', // Only log mutations (data changes)\n batchSeparator: 'GO', // Add GO statements for SQL Server batch processing\n prettyPrint: true // Enable pretty printing for readable output\n });\n \n if (flags.verbose) {\n this.log(`📝 SQL logging enabled: ${path.relative(process.cwd(), logFilePath)}`);\n }\n } else {\n this.warn('SQL logging requested but data provider does not support CreateSqlLogger');\n }\n }\n \n // Find entity directories to process\n const entityDirs = findEntityDirectories(configManager.getOriginalCwd(), flags.dir, syncConfig?.directoryOrder, syncConfig?.ignoreDirectories);\n \n if (entityDirs.length === 0) {\n this.error('No entity directories found');\n }\n \n if (flags.verbose) {\n this.log(`Found ${entityDirs.length} entity ${entityDirs.length === 1 ? 'directory' : 'directories'} to process`);\n }\n \n // Run validation unless disabled\n if (!flags['no-validate']) {\n const { ValidationService } = await import('../../services/ValidationService');\n const { FormattingService } = await import('../../services/FormattingService');\n \n spinner.start('Validating metadata...');\n const validator = new ValidationService({ verbose: flags.verbose });\n const formatter = new FormattingService();\n \n const targetDir = flags.dir ? path.resolve(configManager.getOriginalCwd(), flags.dir) : configManager.getOriginalCwd();\n const validationResult = await validator.validateDirectory(targetDir);\n spinner.stop();\n \n if (!validationResult.isValid || validationResult.warnings.length > 0) {\n // Show validation results\n this.log('\\n' + formatter.formatValidationResult(validationResult, flags.verbose));\n \n if (!validationResult.isValid) {\n // In CI mode, fail immediately\n if (flags.ci) {\n this.error('Validation failed. Cannot proceed with push.');\n }\n \n // Otherwise, ask for confirmation\n const shouldContinue = await confirm({\n message: 'Validation failed with errors. Do you want to continue anyway?',\n default: false\n });\n \n if (!shouldContinue) {\n this.log(chalk.yellow('\\n⚠️ Push cancelled due to validation errors.'));\n // Exit cleanly without throwing an error\n return;\n }\n }\n } else {\n this.log(chalk.green('✓ Validation passed'));\n }\n }\n \n // Initialize file backup manager (unless in dry-run mode)\n if (!flags['dry-run']) {\n await fileBackupManager.initialize();\n if (flags.verbose) {\n this.log('📁 File backup manager initialized');\n }\n }\n \n // Start a database transaction for the entire push operation (unless in dry-run mode)\n // IMPORTANT: We start the transaction AFTER metadata loading and validation to avoid\n // transaction conflicts with background refresh operations\n if (!flags['dry-run']) {\n const { getDataProvider } = await import('../../lib/provider-utils');\n const dataProvider = getDataProvider();\n \n // Ensure we have SQLServerDataProvider for transaction support\n if (!(dataProvider instanceof SQLServerDataProvider)) {\n const errorMsg = 'MetadataSync requires SQLServerDataProvider for transaction support. Current provider does not support transactions.';\n \n // Rollback file backups since we're not proceeding\n try {\n await fileBackupManager.rollback();\n } catch (rollbackError) {\n this.warn(`Failed to rollback file backup initialization: ${rollbackError}`);\n }\n \n this.error(errorMsg);\n }\n \n if (dataProvider && typeof dataProvider.BeginTransaction === 'function') {\n try {\n await dataProvider.BeginTransaction();\n hasActiveTransaction = true;\n if (flags.verbose) {\n this.log('🔄 Transaction started - all changes will be committed or rolled back as a unit');\n }\n } catch (error) {\n // Transaction start failure is critical - we should not proceed without it\n const errorMsg = `Failed to start database transaction: ${error instanceof Error ? error.message : String(error)}`;\n \n // Rollback file backups since we're not proceeding\n try {\n await fileBackupManager.rollback();\n } catch (rollbackError) {\n this.warn(`Failed to rollback file backup initialization: ${rollbackError}`);\n }\n \n this.error(errorMsg);\n }\n } else {\n // No transaction support is also critical for data integrity\n const errorMsg = 'Transaction support not available - cannot ensure data integrity';\n \n // Rollback file backups since we're not proceeding\n try {\n await fileBackupManager.rollback();\n } catch (rollbackError) {\n this.warn(`Failed to rollback file backup initialization: ${rollbackError}`);\n }\n \n this.error(errorMsg);\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 for (const entityDir of entityDirs) {\n const entityConfig = await loadEntityConfig(entityDir);\n if (!entityConfig) {\n this.warn(`Skipping ${entityDir} - no valid entity configuration`);\n continue;\n }\n \n if (flags.verbose) {\n this.log(`\\nProcessing ${entityConfig.entity} in ${entityDir}`);\n }\n \n // Combine root ignoreDirectories with entity-level ignoreDirectories\n const initialIgnoreDirectories = [\n ...(syncConfig?.ignoreDirectories || []),\n ...(entityConfig?.ignoreDirectories || [])\n ];\n \n const result = await this.processEntityDirectory(\n entityDir,\n entityConfig,\n syncEngine,\n flags,\n syncConfig,\n fileBackupManager,\n initialIgnoreDirectories\n );\n \n // Show per-directory summary\n const dirName = path.relative(process.cwd(), entityDir) || '.';\n const dirTotal = result.created + result.updated + result.unchanged;\n if (dirTotal > 0 || result.errors > 0) {\n this.log(`\\n📁 ${dirName}:`);\n this.log(` Total processed: ${dirTotal} unique records`);\n if (result.created > 0) {\n this.log(` ✓ Created: ${result.created}`);\n }\n if (result.updated > 0) {\n this.log(` ✓ Updated: ${result.updated}`);\n }\n if (result.unchanged > 0) {\n this.log(` - Unchanged: ${result.unchanged}`);\n }\n if (result.errors > 0) {\n this.log(` ✗ 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 // Summary using FormattingService\n const endTime = Date.now();\n const { FormattingService } = await import('../../services/FormattingService');\n const formatter = new FormattingService();\n \n this.log('\\n' + formatter.formatSyncSummary('push', {\n created: totalCreated,\n updated: totalUpdated,\n unchanged: totalUnchanged,\n deleted: 0,\n skipped: 0,\n errors: totalErrors,\n duration: endTime - startTime\n }));\n \n // Handle transaction commit/rollback\n if (!flags['dry-run'] && hasActiveTransaction) {\n const dataProvider = Metadata.Provider as SQLServerDataProvider;\n \n // We know we have an active transaction at this point\n if (dataProvider) {\n let shouldCommit = true;\n \n // If there are any errors, always rollback\n if (totalErrors > 0 || this.errors.length > 0) {\n shouldCommit = false;\n this.log('\\n❌ Errors detected - rolling back all changes');\n }\n // If there are warnings, ask user (unless in CI mode)\n else if (this.warnings.length > 0) {\n // Filter out transaction-related warnings since we're now using transactions\n const nonTransactionWarnings = this.warnings.filter(w => \n !w.includes('Transaction support not available') && \n !w.includes('Failed to start transaction')\n );\n \n if (nonTransactionWarnings.length > 0) {\n if (flags.ci) {\n // In CI mode, rollback on warnings\n shouldCommit = false;\n this.log('\\n⚠️ Warnings detected in CI mode - rolling back all changes');\n } else {\n // Show warnings to user\n this.log('\\n⚠️ The following warnings were encountered:');\n for (const warning of nonTransactionWarnings) {\n this.log(` - ${warning}`);\n }\n \n // Ask user whether to commit or rollback\n shouldCommit = await confirm({\n message: 'Do you want to commit these changes despite the warnings?',\n default: false // Default to rollback\n });\n }\n }\n }\n \n try {\n if (shouldCommit) {\n await dataProvider.CommitTransaction();\n this.log('\\n✅ All changes committed successfully');\n \n // Clean up file backups after successful commit\n await fileBackupManager.cleanup();\n } else {\n // User chose to rollback or errors/warnings in CI mode\n this.log('\\n🔙 Rolling back all changes...');\n \n // Rollback database transaction\n await dataProvider.RollbackTransaction();\n \n // Rollback file changes\n this.log('🔙 Rolling back file changes...');\n await fileBackupManager.rollback();\n \n this.log('✅ Rollback completed - no changes were made to the database or files');\n }\n } catch (error) {\n // Try to rollback on any error\n this.log('\\n❌ Transaction error - attempting to roll back changes');\n try {\n await dataProvider.RollbackTransaction();\n this.log('✅ Database rollback completed');\n } catch (rollbackError) {\n this.log('❌ Database rollback failed: ' + (rollbackError instanceof Error ? rollbackError.message : String(rollbackError)));\n }\n \n // Also rollback file changes\n try {\n this.log('🔙 Rolling back file changes...');\n await fileBackupManager.rollback();\n this.log('✅ File rollback completed');\n } catch (fileRollbackError) {\n this.log('❌ File rollback failed: ' + (fileRollbackError instanceof Error ? fileRollbackError.message : String(fileRollbackError)));\n }\n \n throw error;\n }\n }\n }\n \n // Exit with error if there were errors in CI mode\n if ((totalErrors > 0 || this.errors.length > 0 || (this.warnings.length > 0 && flags.ci)) && flags.ci) {\n this.error('Push failed in CI mode');\n }\n \n } catch (error) {\n spinner.fail('Push failed');\n \n // Try to rollback the transaction and files if not in dry-run mode\n if (!flags['dry-run']) {\n const { getDataProvider } = await import('../../lib/provider-utils');\n const dataProvider = getDataProvider();\n \n // Rollback database transaction if we have one\n if (hasActiveTransaction && dataProvider && typeof dataProvider.RollbackTransaction === 'function') {\n try {\n this.log('\\n🔙 Rolling back database transaction due to error...');\n await dataProvider.RollbackTransaction();\n this.log('✅ Database rollback completed');\n } catch (rollbackError) {\n this.log('❌ Database rollback failed: ' + (rollbackError instanceof Error ? rollbackError.message : String(rollbackError)));\n }\n }\n \n // Rollback file changes\n try {\n this.log('🔙 Rolling back file changes...');\n await fileBackupManager.rollback();\n this.log('✅ File rollback completed - all files restored to original state');\n } catch (fileRollbackError) {\n this.log('❌ File rollback failed: ' + (fileRollbackError instanceof Error ? fileRollbackError.message : String(fileRollbackError)));\n }\n }\n \n // Enhanced error logging for debugging\n this.log('\\n=== Push Error Details ===');\n this.log(`Error type: ${error?.constructor?.name || 'Unknown'}`);\n this.log(`Error message: ${error instanceof Error ? error.message : String(error)}`);\n \n if (error instanceof Error && error.stack) {\n this.log(`\\nStack trace:`);\n this.log(error.stack);\n }\n \n // Log context information\n this.log(`\\nContext:`);\n this.log(`- Working directory: ${configManager.getOriginalCwd()}`);\n this.log(`- Flags: ${JSON.stringify(flags, null, 2)}`);\n \n // Check if error is related to common issues\n const errorMessage = error instanceof Error ? error.message : String(error);\n if (errorMessage.includes('entity directories')) {\n this.log(`\\nHint: This appears to be an entity directory configuration issue.`);\n this.log(`Make sure each entity directory has a .mj-sync.json file.`);\n } else if (errorMessage.includes('database') || errorMessage.includes('connection')) {\n this.log(`\\nHint: This appears to be a database connectivity issue.`);\n this.log(`Check your mj.config.cjs configuration and database connectivity.`);\n } else if (errorMessage.includes('config') || errorMessage.includes('mj.config.cjs')) {\n this.log(`\\nHint: This appears to be a configuration file issue.`);\n this.log(`Make sure mj.config.cjs exists and is properly configured.`);\n }\n \n this.error(error as Error);\n } finally {\n // Dispose SQL logging session if active\n if (sqlLogger) {\n try {\n await sqlLogger.dispose();\n if (flags.verbose) {\n this.log('✅ SQL logging session closed');\n }\n } catch (error) {\n this.warn(`Failed to close SQL logging session: ${error}`);\n }\n }\n \n // Reset sync engine singleton\n resetSyncEngine();\n \n // Exit process to prevent background MJ tasks from throwing errors\n // We don't explicitly close the connection - let the process termination handle it\n process.exit(0);\n }\n }\n \n private async processEntityDirectory(\n entityDir: string,\n entityConfig: any,\n syncEngine: SyncEngine,\n flags: any,\n syncConfig: any,\n fileBackupManager?: FileBackupManager,\n parentIgnoreDirectories?: string[]\n ): Promise<{ created: number; updated: number; unchanged: number; errors: number }> {\n const result = { created: 0, updated: 0, unchanged: 0, errors: 0 };\n \n // Find files matching the configured pattern\n const pattern = entityConfig.filePattern || '*.json';\n const jsonFiles = await fastGlob(pattern, {\n cwd: entityDir,\n ignore: ['.mj-sync.json', '.mj-folder.json', '**/*.backup'],\n dot: true, // Include dotfiles (files starting with .)\n onlyFiles: true\n });\n \n // Check if no JSON files were found\n if (jsonFiles.length === 0) {\n const relativePath = path.relative(process.cwd(), entityDir) || '.';\n const parentPath = path.dirname(entityDir);\n const dirName = path.basename(entityDir);\n \n // Check if this is a subdirectory (not a top-level entity directory)\n const isSubdirectory = parentPath !== path.resolve(configManager.getOriginalCwd(), flags.dir || '.');\n \n if (isSubdirectory) {\n // For subdirectories, make it a warning instead of an error\n let warningMessage = `No JSON files found in ${relativePath} matching pattern: ${pattern}`;\n \n // Try to be more helpful by checking what files do exist\n const allFiles = await fastGlob('*', {\n cwd: entityDir,\n onlyFiles: true,\n dot: true\n });\n \n if (allFiles.length > 0) {\n warningMessage += `\\n Files found: ${allFiles.slice(0, 3).join(', ')}`;\n if (allFiles.length > 3) {\n warningMessage += ` (and ${allFiles.length - 3} more)`;\n }\n }\n \n const rootConfigPath = path.join(configManager.getOriginalCwd(), flags.dir || '.', '.mj-sync.json');\n warningMessage += `\\n 💡 If this directory should be ignored, add \"${dirName}\" to the \"ignoreDirectories\" array in:\\n ${rootConfigPath}`;\n \n this.warn(warningMessage);\n return result; // Return early without processing further\n } else {\n // For top-level entity directories, this is still an error\n const configFile = path.join(entityDir, '.mj-sync.json');\n let errorMessage = `No JSON files found in ${relativePath} matching pattern: ${pattern}\\n`;\n errorMessage += `\\nPlease check:\\n`;\n errorMessage += ` 1. Files exist with the expected extension (.json)\\n`;\n errorMessage += ` 2. The filePattern in ${configFile} matches your files\\n`;\n errorMessage += ` 3. Files are not in ignored patterns: .mj-sync.json, .mj-folder.json, *.backup\\n`;\n \n // Try to be more helpful by checking what files do exist\n const allFiles = await fastGlob('*', {\n cwd: entityDir,\n onlyFiles: true,\n dot: true\n });\n \n if (allFiles.length > 0) {\n errorMessage += `\\nFiles found in directory: ${allFiles.slice(0, 5).join(', ')}`;\n if (allFiles.length > 5) {\n errorMessage += ` (and ${allFiles.length - 5} more)`;\n }\n }\n \n throw new Error(errorMessage);\n }\n }\n \n if (flags.verbose) {\n this.log(`Processing ${jsonFiles.length} records in ${path.relative(process.cwd(), entityDir) || '.'}`);\n }\n \n // First, process all JSON files in this directory\n await this.processJsonFiles(jsonFiles, entityDir, entityConfig, syncEngine, flags, result, fileBackupManager);\n \n // Then, recursively process subdirectories\n const entries = await fs.readdir(entityDir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isDirectory() && !entry.name.startsWith('.')) {\n // Build cumulative ignore list: parent + current directory's ignores\n const currentDirConfig = await loadSyncConfig(entityDir);\n const currentEntityConfig = await loadEntityConfig(entityDir);\n const cumulativeIgnoreDirectories = [\n ...(parentIgnoreDirectories || []),\n ...(currentDirConfig?.ignoreDirectories || []),\n ...(currentEntityConfig?.ignoreDirectories || [])\n ];\n \n // Check if this directory should be ignored\n if (cumulativeIgnoreDirectories.some((pattern: string) => {\n // Simple pattern matching: exact name or ends with pattern\n return entry.name === pattern || entry.name.endsWith(pattern);\n })) {\n if (flags.verbose) {\n this.log(` Ignoring directory: ${entry.name} (matched ignore pattern)`);\n }\n continue;\n }\n \n const subDir = path.join(entityDir, entry.name);\n \n // Load subdirectory config and merge with parent config\n let subEntityConfig = { ...entityConfig };\n const subDirConfig = await loadEntityConfig(subDir);\n \n if (subDirConfig) {\n // Check if this is a new entity type (has different entity name)\n if (subDirConfig.entity && subDirConfig.entity !== entityConfig.entity) {\n // This is a different entity type, skip it (will be processed separately)\n continue;\n }\n \n // Merge defaults: parent defaults + subdirectory overrides\n subEntityConfig = {\n ...entityConfig,\n ...subDirConfig,\n defaults: {\n ...entityConfig.defaults,\n ...(subDirConfig.defaults || {})\n }\n };\n }\n \n // Process subdirectory with merged config and cumulative ignore directories\n const subResult = await this.processEntityDirectory(\n subDir,\n subEntityConfig,\n syncEngine,\n flags,\n syncConfig,\n fileBackupManager,\n cumulativeIgnoreDirectories\n );\n \n result.created += subResult.created;\n result.updated += subResult.updated;\n result.unchanged += subResult.unchanged;\n result.errors += subResult.errors;\n }\n }\n \n return result;\n }\n \n private async processJsonFiles(\n jsonFiles: string[],\n entityDir: string,\n entityConfig: any,\n syncEngine: SyncEngine,\n flags: any,\n result: { created: number; updated: number; unchanged: number; errors: number },\n fileBackupManager?: FileBackupManager\n ): Promise<void> {\n if (jsonFiles.length === 0) {\n return;\n }\n \n const spinner = ora();\n spinner.start('Processing records');\n \n \n for (const file of jsonFiles) {\n try {\n const filePath = path.join(entityDir, file);\n \n // Backup the file before any modifications (unless dry-run)\n if (!flags['dry-run'] && fileBackupManager) {\n await fileBackupManager.backupFile(filePath);\n }\n \n // Parse JSON with line number tracking\n const { content: fileContent, lineNumbers } = await this.parseJsonWithLineNumbers(filePath);\n \n // Process templates in the loaded content\n const processedContent = await syncEngine.processTemplates(fileContent, entityDir);\n \n // Check if the file contains a single record or an array of records\n const isArray = Array.isArray(processedContent);\n const records: RecordData[] = isArray ? processedContent : [processedContent];\n \n // Build and process defaults (including lookups)\n const defaults = await syncEngine.buildDefaults(filePath, entityConfig);\n \n // Process each record in the file\n for (let i = 0; i < records.length; i++) {\n const recordData = records[i];\n \n // Process the record\n const recordLineNumber = lineNumbers.get(i); // Get line number for this array index\n const pushResult = await this.pushRecord(\n recordData,\n entityConfig.entity,\n path.dirname(filePath),\n file,\n defaults,\n syncEngine,\n flags['dry-run'],\n flags.verbose,\n isArray ? i : undefined,\n fileBackupManager,\n recordLineNumber\n );\n \n if (!flags['dry-run']) {\n // Don't count duplicates in stats\n if (!pushResult.isDuplicate) {\n if (pushResult.isNew) {\n result.created++;\n } else if (pushResult.wasActuallyUpdated) {\n result.updated++;\n } else {\n result.unchanged++;\n }\n }\n \n // Add related entity stats\n if (pushResult.relatedStats) {\n result.created += pushResult.relatedStats.created;\n result.updated += pushResult.relatedStats.updated;\n result.unchanged += pushResult.relatedStats.unchanged;\n \n // Debug logging for related entities\n if (flags.verbose && pushResult.relatedStats.unchanged > 0) {\n this.log(` Related entities: ${pushResult.relatedStats.unchanged} unchanged`);\n }\n }\n }\n \n spinner.text = `Processing records (${result.created + result.updated + result.unchanged + result.errors} processed)`;\n }\n \n // Write back the entire file if it's an array\n if (isArray && !flags['dry-run']) {\n await fs.writeJson(filePath, records, { spaces: 2 });\n }\n \n } catch (error) {\n result.errors++;\n const errorMessage = error instanceof Error ? error.message : String(error);\n const fullErrorMessage = `Failed to process ${file}: ${errorMessage}`;\n this.errors.push(fullErrorMessage);\n this.error(fullErrorMessage, { exit: false });\n this.log(' ⚠️ This error will cause all changes to be rolled back at the end of processing');\n }\n }\n \n if (flags.verbose) {\n spinner.succeed(`Processed ${result.created + result.updated + result.unchanged} records from ${jsonFiles.length} files`);\n } else {\n spinner.stop();\n }\n }\n \n private async pushRecord(\n recordData: RecordData,\n entityName: string,\n baseDir: string,\n fileName: string,\n defaults: Record<string, any>,\n syncEngine: SyncEngine,\n dryRun: boolean,\n verbose: boolean = false,\n arrayIndex?: number,\n fileBackupManager?: FileBackupManager,\n lineNumber?: number\n ): Promise<{ isNew: boolean; wasActuallyUpdated: boolean; isDuplicate: boolean; relatedStats?: { created: number; updated: number; unchanged: number } }> {\n // Load or create entity\n let entity: BaseEntity | null = null;\n let isNew = false;\n \n if (recordData.primaryKey) {\n entity = await syncEngine.loadEntity(entityName, recordData.primaryKey);\n \n // Warn if record has primaryKey but wasn't found\n if (!entity) {\n const pkDisplay = Object.entries(recordData.primaryKey)\n .map(([key, value]) => `${key}=${value}`)\n .join(', ');\n \n // Load sync config to check autoCreateMissingRecords setting\n const syncConfig = await loadSyncConfig(configManager.getOriginalCwd());\n const autoCreate = syncConfig?.push?.autoCreateMissingRecords ?? false;\n \n if (!autoCreate) {\n const fileRef = lineNumber ? `${fileName}:${lineNumber}` : fileName;\n this.warn(`⚠️ Record not found: ${entityName} with primaryKey {${pkDisplay}} at ${fileRef}`);\n this.warn(` To auto-create missing records, set push.autoCreateMissingRecords=true in .mj-sync.json`);\n \n // Skip this record\n return { isNew: false, wasActuallyUpdated: false, isDuplicate: false };\n } else {\n if (verbose) {\n this.log(` Auto-creating missing ${entityName} record with primaryKey {${pkDisplay}}`);\n }\n }\n }\n }\n \n if (!entity) {\n // New record\n entity = await syncEngine.createEntityObject(entityName);\n entity.NewRecord();\n isNew = true;\n \n // Handle primary keys for new records\n const entityInfo = syncEngine.getEntityInfo(entityName);\n if (entityInfo) {\n for (const pk of entityInfo.PrimaryKeys) {\n if (!pk.AutoIncrement) {\n // Check if we have a value in primaryKey object\n if (recordData.primaryKey?.[pk.Name]) {\n // User specified a primary key for new record, set it on entity directly\n // Don't add to fields as it will be in primaryKey section\n (entity as any)[pk.Name] = recordData.primaryKey[pk.Name];\n if (verbose) {\n this.log(` Using specified primary key ${pk.Name}: ${recordData.primaryKey[pk.Name]}`);\n }\n } else if (pk.Type.toLowerCase() === 'uniqueidentifier' && !recordData.fields[pk.Name]) {\n // Generate UUID for this primary key and set it on entity directly\n const uuid = uuidv4();\n // Don't add to fields as it will be in primaryKey section after save\n if (verbose) {\n this.log(` Generated UUID for primary key ${pk.Name}: ${uuid}`);\n }\n // Set the generated UUID on the entity\n (entity as any)[pk.Name] = uuid;\n }\n }\n }\n }\n }\n \n // Apply defaults first\n for (const [field, value] of Object.entries(defaults)) {\n if (field in entity) {\n (entity as any)[field] = value;\n }\n }\n \n // Apply record fields\n for (const [field, value] of Object.entries(recordData.fields)) {\n if (field in entity) {\n try {\n const processedValue = await syncEngine.processFieldValue(value, baseDir, null, null);\n if (verbose) {\n this.log(` Setting ${field}: ${this.formatFieldValue(value)} -> ${this.formatFieldValue(processedValue)}`);\n }\n (entity as any)[field] = processedValue;\n } catch (error) {\n throw new Error(`Failed to process field '${field}': ${error}`);\n }\n } else {\n this.warn(`Field '${field}' does not exist on entity '${entityName}'`);\n }\n }\n \n if (dryRun) {\n this.log(`Would ${isNew ? 'create' : 'update'} ${entityName} record`);\n return { isNew, wasActuallyUpdated: true, isDuplicate: false, relatedStats: undefined };\n }\n \n // Check for duplicate processing (but only for existing records that were loaded)\n let isDuplicate = false;\n if (!isNew && entity) {\n const fullFilePath = path.join(baseDir, fileName);\n isDuplicate = this.checkAndTrackRecord(entityName, entity, fullFilePath, arrayIndex, lineNumber);\n }\n \n // Check if the record is dirty before saving\n let wasActuallyUpdated = false;\n if (!isNew && entity.Dirty) {\n // Record is dirty, get the changes\n const changes = entity.GetChangesSinceLastSave();\n const changeKeys = Object.keys(changes);\n if (changeKeys.length > 0) {\n wasActuallyUpdated = true;\n \n // Get primary key info for display\n const entityInfo = 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 this.log(''); // Add newline before update output\n this.log(`📝 Updating ${entityName} record:`);\n if (primaryKeyDisplay.length > 0) {\n this.log(` Primary Key: ${primaryKeyDisplay.join(', ')}`);\n }\n this.log(` 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 this.log(` ${fieldName}: ${this.formatFieldValue(oldValue)} → ${this.formatFieldValue(newValue)}`);\n }\n }\n } else if (isNew) {\n wasActuallyUpdated = true;\n }\n \n // Save the record\n const saved = await entity.Save();\n if (!saved) {\n const message = entity.LatestResult?.Message;\n if (message) {\n throw new Error(`Failed to save record: ${message}`);\n }\n \n const errors = entity.LatestResult?.Errors?.map(err => \n typeof err === 'string' ? err : (err?.message || JSON.stringify(err))\n )?.join(', ') || 'Unknown error';\n throw new Error(`Failed to save record: ${errors}`);\n }\n \n // Process related entities after saving parent\n let relatedStats;\n if (recordData.relatedEntities && !dryRun) {\n const fullFilePath = path.join(baseDir, fileName);\n relatedStats = await this.processRelatedEntities(\n recordData.relatedEntities,\n entity,\n entity, // root is same as parent for top level\n baseDir,\n syncEngine,\n verbose,\n fileBackupManager,\n 1, // indentLevel\n fullFilePath,\n arrayIndex\n );\n }\n \n // Update the local file with new primary key if created\n if (isNew) {\n const entityInfo = 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 recordData.primaryKey = newPrimaryKey;\n }\n \n // Track the new record now that we have its primary key\n const fullFilePath = path.join(baseDir, fileName);\n this.checkAndTrackRecord(entityName, entity, fullFilePath, arrayIndex, lineNumber);\n }\n \n // Always update sync metadata\n // This ensures related entities are persisted with their metadata\n recordData.sync = {\n lastModified: new Date().toISOString(),\n checksum: syncEngine.calculateChecksum(recordData.fields)\n };\n \n // Write back to file only if it's a single record (not part of an array)\n // Array records are written back in bulk after all records are processed\n if (arrayIndex === undefined) {\n const filePath = path.join(baseDir, fileName);\n await fs.writeJson(filePath, recordData, { spaces: 2 });\n }\n \n return { isNew, wasActuallyUpdated, isDuplicate, relatedStats };\n }\n \n private async processRelatedEntities(\n relatedEntities: Record<string, RecordData[]>,\n parentEntity: BaseEntity,\n rootEntity: BaseEntity,\n baseDir: string,\n syncEngine: SyncEngine,\n verbose: boolean = false,\n fileBackupManager?: FileBackupManager,\n indentLevel: number = 1,\n parentFilePath?: string,\n parentArrayIndex?: number\n ): Promise<{ created: number; updated: number; unchanged: number }> {\n const indent = ' '.repeat(indentLevel);\n const stats = { created: 0, updated: 0, unchanged: 0 };\n \n for (const [entityName, records] of Object.entries(relatedEntities)) {\n if (verbose) {\n this.log(`${indent}↳ Processing ${records.length} related ${entityName} records`);\n }\n \n for (const relatedRecord of records) {\n try {\n // Load or create entity\n let entity = null;\n let isNew = false;\n \n if (relatedRecord.primaryKey) {\n entity = await syncEngine.loadEntity(entityName, relatedRecord.primaryKey);\n \n // Warn if record has primaryKey but wasn't found\n if (!entity) {\n const pkDisplay = Object.entries(relatedRecord.primaryKey)\n .map(([key, value]) => `${key}=${value}`)\n .join(', ');\n \n // Load sync config to check autoCreateMissingRecords setting\n const syncConfig = await loadSyncConfig(configManager.getOriginalCwd());\n const autoCreate = syncConfig?.push?.autoCreateMissingRecords ?? false;\n \n if (!autoCreate) {\n const fileRef = parentFilePath ? path.relative(configManager.getOriginalCwd(), parentFilePath) : 'unknown';\n this.warn(`${indent}⚠️ Related record not found: ${entityName} with primaryKey {${pkDisplay}} at ${fileRef}`);\n this.warn(`${indent} To auto-create missing records, set push.autoCreateMissingRecords=true in .mj-sync.json`);\n \n // Skip this record\n continue;\n } else {\n if (verbose) {\n this.log(`${indent} Auto-creating missing related ${entityName} record with primaryKey {${pkDisplay}}`);\n }\n }\n }\n }\n \n if (!entity) {\n entity = await syncEngine.createEntityObject(entityName);\n entity.NewRecord();\n isNew = true;\n \n // Handle primary keys for new related entity records\n const entityInfo = syncEngine.getEntityInfo(entityName);\n if (entityInfo) {\n for (const pk of entityInfo.PrimaryKeys) {\n if (!pk.AutoIncrement) {\n // Check if we have a value in primaryKey object\n if (relatedRecord.primaryKey?.[pk.Name]) {\n // User specified a primary key for new record, set it on entity directly\n // Don't add to fields as it will be in primaryKey section\n (entity as any)[pk.Name] = relatedRecord.primaryKey[pk.Name];\n if (verbose) {\n this.log(`${indent} Using specified primary key ${pk.Name}: ${relatedRecord.primaryKey[pk.Name]}`);\n }\n } else if (pk.Type.toLowerCase() === 'uniqueidentifier' && !relatedRecord.fields[pk.Name]) {\n // Generate UUID for this primary key and set it on entity directly\n const uuid = uuidv4();\n // Don't add to fields as it will be in primaryKey section after save\n (entity as any)[pk.Name] = uuid;\n if (verbose) {\n this.log(`${indent} Generated UUID for primary key ${pk.Name}: ${uuid}`);\n }\n }\n }\n }\n }\n }\n \n // Apply fields with parent/root context\n for (const [field, value] of Object.entries(relatedRecord.fields)) {\n if (field in entity) {\n try {\n const processedValue = await syncEngine.processFieldValue(\n value, \n baseDir, \n parentEntity, \n rootEntity\n );\n if (verbose) {\n this.log(`${indent} Setting ${field}: ${this.formatFieldValue(value)} -> ${this.formatFieldValue(processedValue)}`);\n }\n (entity as any)[field] = processedValue;\n } catch (error) {\n throw new Error(`Failed to process field '${field}' in ${entityName}: ${error}`);\n }\n } else {\n this.warn(`${indent} Field '${field}' does not exist on entity '${entityName}'`);\n }\n }\n \n // Check for duplicate processing (but only for existing records that were loaded)\n let isDuplicate = false;\n if (!isNew && entity) {\n // Use parent file path for related entities since they're defined in the parent's file\n const relatedFilePath = parentFilePath || path.join(baseDir, 'unknown');\n isDuplicate = this.checkAndTrackRecord(entityName, entity, relatedFilePath, parentArrayIndex);\n }\n \n // Check if the record is dirty before saving\n let wasActuallyUpdated = false;\n if (!isNew && entity.Dirty) {\n // Record is dirty, get the changes\n const changes = entity.GetChangesSinceLastSave();\n const changeKeys = Object.keys(changes);\n if (changeKeys.length > 0) {\n wasActuallyUpdated = true;\n \n // Get primary key info for display\n const entityInfo = 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 this.log(''); // Add newline before update output\n this.log(`${indent}📝 Updating related ${entityName} record:`);\n if (primaryKeyDisplay.length > 0) {\n this.log(`${indent} Primary Key: ${primaryKeyDisplay.join(', ')}`);\n }\n this.log(`${indent} 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 this.log(`${indent} ${fieldName}: ${this.formatFieldValue(oldValue)} → ${this.formatFieldValue(newValue)}`);\n }\n }\n } else if (isNew) {\n wasActuallyUpdated = true;\n }\n \n // Save the related entity\n const saved = await entity.Save();\n if (!saved) {\n const message = entity.LatestResult?.Message;\n if (message) {\n throw new Error(`Failed to save related ${entityName}: ${message}`);\n }\n \n const errors = entity.LatestResult?.Errors?.map(err => \n typeof err === 'string' ? err : (err?.message || JSON.stringify(err))\n )?.join(', ') || 'Unknown error';\n throw new Error(`Failed to save related ${entityName}: ${errors}`);\n }\n \n // Update stats - don't count duplicates\n if (!isDuplicate) {\n if (isNew) {\n stats.created++;\n } else if (wasActuallyUpdated) {\n stats.updated++;\n } else {\n stats.unchanged++;\n }\n }\n \n if (verbose && wasActuallyUpdated) {\n this.log(`${indent} ✓ ${isNew ? 'Created' : 'Updated'} ${entityName} record`);\n } else if (verbose && !wasActuallyUpdated) {\n this.log(`${indent} - No changes to ${entityName} record`);\n }\n \n // Update the related record with primary key and sync metadata\n const entityInfo = syncEngine.getEntityInfo(entityName);\n if (entityInfo) {\n // Update primary key if new\n if (isNew) {\n relatedRecord.primaryKey = {};\n for (const pk of entityInfo.PrimaryKeys) {\n relatedRecord.primaryKey[pk.Name] = entity.Get(pk.Name);\n }\n \n // Track the new related entity now that we have its primary key\n const relatedFilePath = parentFilePath || path.join(baseDir, 'unknown');\n this.checkAndTrackRecord(entityName, entity, relatedFilePath, parentArrayIndex);\n }\n \n // Always update sync metadata\n relatedRecord.sync = {\n lastModified: new Date().toISOString(),\n checksum: syncEngine.calculateChecksum(relatedRecord.fields)\n };\n }\n \n // Process nested related entities if any\n if (relatedRecord.relatedEntities) {\n const nestedStats = await this.processRelatedEntities(\n relatedRecord.relatedEntities,\n entity,\n rootEntity,\n baseDir,\n syncEngine,\n verbose,\n fileBackupManager,\n indentLevel + 1,\n parentFilePath,\n parentArrayIndex\n );\n \n // Accumulate nested stats\n stats.created += nestedStats.created;\n stats.updated += nestedStats.updated;\n stats.unchanged += nestedStats.unchanged;\n }\n } catch (error) {\n throw new Error(`Failed to process related ${entityName}: ${error}`);\n }\n }\n }\n \n return stats;\n }\n \n /**\n * Generate a unique tracking key for a record based on entity name and primary key values\n */\n private generateRecordKey(entityName: string, entity: BaseEntity): string {\n const entityInfo = entity.EntityInfo;\n const primaryKeyValues: string[] = [];\n \n if (entityInfo && entityInfo.PrimaryKeys.length > 0) {\n for (const pk of entityInfo.PrimaryKeys) {\n const value = entity.Get(pk.Name);\n primaryKeyValues.push(`${pk.Name}:${value}`);\n }\n }\n \n return `${entityName}|${primaryKeyValues.join('|')}`;\n }\n \n /**\n * Check if a record has already been processed and warn if duplicate\n */\n private checkAndTrackRecord(\n entityName: string, \n entity: BaseEntity, \n filePath?: string,\n arrayIndex?: number,\n lineNumber?: number\n ): boolean {\n const recordKey = this.generateRecordKey(entityName, entity);\n \n const existing = this.processedRecords.get(recordKey);\n if (existing) {\n const primaryKeyDisplay = entity.EntityInfo?.PrimaryKeys\n .map(pk => `${pk.Name}: ${entity.Get(pk.Name)}`)\n .join(', ') || 'unknown';\n \n // Format file location with clickable link for VSCode\n // Create maps with just the line numbers we have\n const currentLineMap = lineNumber ? new Map([[arrayIndex || 0, lineNumber]]) : undefined;\n const originalLineMap = existing.lineNumber ? new Map([[existing.arrayIndex || 0, existing.lineNumber]]) : undefined;\n \n const currentLocation = this.formatFileLocation(filePath, arrayIndex, currentLineMap);\n const originalLocation = this.formatFileLocation(existing.filePath, existing.arrayIndex, originalLineMap);\n \n this.warn(`⚠️ Duplicate record detected for ${entityName} (${primaryKeyDisplay})`);\n this.warn(` Current location: ${currentLocation}`);\n this.warn(` Original location: ${originalLocation}`);\n this.warn(` The duplicate update will proceed, but you should review your data for unintended duplicates.`);\n \n return true; // is duplicate\n }\n \n // Track the record with its source location\n this.processedRecords.set(recordKey, {\n filePath: filePath || 'unknown',\n arrayIndex,\n lineNumber\n });\n return false; // not duplicate\n }\n \n /**\n * Format field value for console display\n */\n private formatFieldValue(value: any, maxLength: number = 50): string {\n // Convert value to string representation\n let strValue = JSON.stringify(value);\n \n // Trim the string\n strValue = strValue.trim();\n \n // If it's longer than maxLength, truncate and add ellipsis\n if (strValue.length > maxLength) {\n return strValue.substring(0, maxLength) + '...';\n }\n \n return strValue;\n }\n\n /**\n * Parse JSON file and track line numbers for array elements\n */\n private async parseJsonWithLineNumbers(filePath: string): Promise<{\n content: any;\n lineNumbers: Map<number, number>; // arrayIndex -> lineNumber\n }> {\n const fileText = await fs.readFile(filePath, 'utf-8');\n const lines = fileText.split('\\n');\n const lineNumbers = new Map<number, number>();\n \n // Parse the JSON\n const content = JSON.parse(fileText);\n \n // If it's an array, try to find where each element starts\n if (Array.isArray(content)) {\n let inString = false;\n let bracketDepth = 0;\n let currentIndex = -1;\n \n for (let lineNum = 0; lineNum < lines.length; lineNum++) {\n const line = lines[lineNum];\n \n // Simple tracking of string boundaries and bracket depth\n for (let i = 0; i < line.length; i++) {\n const char = line[i];\n const prevChar = i > 0 ? line[i - 1] : '';\n \n if (char === '\"' && prevChar !== '\\\\') {\n inString = !inString;\n }\n \n if (!inString) {\n if (char === '{') {\n bracketDepth++;\n // If we're at depth 1 in the main array, this is a new object\n if (bracketDepth === 1 && line.trim().startsWith('{')) {\n currentIndex++;\n lineNumbers.set(currentIndex, lineNum + 1); // 1-based line numbers\n }\n } else if (char === '}') {\n bracketDepth--;\n }\n }\n }\n }\n }\n \n return { content, lineNumbers };\n }\n \n /**\n * Format file location with clickable link for VSCode\n */\n private formatFileLocation(filePath?: string, arrayIndex?: number, lineNumbers?: Map<number, number>): string {\n if (!filePath || filePath === 'unknown') {\n return 'unknown';\n }\n \n // Get absolute path for better VSCode integration\n const absolutePath = path.resolve(filePath);\n \n // Try to get actual line number from our tracking\n let lineNumber = 1;\n if (arrayIndex !== undefined && lineNumbers && lineNumbers.has(arrayIndex)) {\n lineNumber = lineNumbers.get(arrayIndex)!;\n } else if (arrayIndex !== undefined) {\n // Fallback estimation if we don't have actual line numbers\n lineNumber = 2 + (arrayIndex * 15);\n }\n \n // Create clickable file path for VSCode - format: file:line\n // VSCode will make this clickable in the terminal\n return `${absolutePath}:${lineNumber}`;\n }\n}"]}
|
package/dist/config.d.ts
CHANGED
|
@@ -54,6 +54,13 @@ export interface SyncConfig {
|
|
|
54
54
|
* Directories not listed in this array will be processed after the ordered ones in alphabetical order.
|
|
55
55
|
*/
|
|
56
56
|
directoryOrder?: string[];
|
|
57
|
+
/**
|
|
58
|
+
* Directories to ignore during processing
|
|
59
|
+
* Can be directory names or glob patterns relative to the location of the .mj-sync.json file
|
|
60
|
+
* Cumulative: subdirectories inherit and add to parent ignoreDirectories
|
|
61
|
+
* Examples: ["output", "examples", "temp"]
|
|
62
|
+
*/
|
|
63
|
+
ignoreDirectories?: string[];
|
|
57
64
|
/** Push command configuration */
|
|
58
65
|
push?: {
|
|
59
66
|
/** Whether to validate records before pushing to database */
|
|
@@ -82,6 +89,15 @@ export interface SyncConfig {
|
|
|
82
89
|
/** File patterns to ignore during watch */
|
|
83
90
|
ignorePatterns?: string[];
|
|
84
91
|
};
|
|
92
|
+
/** User role validation configuration */
|
|
93
|
+
userRoleValidation?: {
|
|
94
|
+
/** Whether to enable user role validation for UserID fields */
|
|
95
|
+
enabled?: boolean;
|
|
96
|
+
/** List of role names that are allowed to be referenced in metadata */
|
|
97
|
+
allowedRoles?: string[];
|
|
98
|
+
/** Whether to allow users without any roles (defaults to false) */
|
|
99
|
+
allowUsersWithoutRoles?: boolean;
|
|
100
|
+
};
|
|
85
101
|
}
|
|
86
102
|
/**
|
|
87
103
|
* Configuration for related entity synchronization
|
|
@@ -146,6 +162,13 @@ export interface EntityConfig {
|
|
|
146
162
|
filePattern?: string;
|
|
147
163
|
/** Default field values applied to all records in this directory */
|
|
148
164
|
defaults?: Record<string, any>;
|
|
165
|
+
/**
|
|
166
|
+
* Directories to ignore during processing
|
|
167
|
+
* Can be directory names or glob patterns relative to the location of the .mj-sync.json file
|
|
168
|
+
* Cumulative: subdirectories inherit and add to parent ignoreDirectories
|
|
169
|
+
* Examples: ["output", "examples", "temp"]
|
|
170
|
+
*/
|
|
171
|
+
ignoreDirectories?: string[];
|
|
149
172
|
/** Pull command specific configuration */
|
|
150
173
|
pull?: {
|
|
151
174
|
/** Glob pattern for finding existing files to update (defaults to filePattern) */
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;;;;;AAGH,gDAAwB;AACxB,wDAA0B;AAC1B,yDAAqD;AAkNrD;;;;;;;;;;;;;;;GAeG;AACH,SAAgB,YAAY;IAC1B,OAAO,8BAAa,CAAC,YAAY,EAAE,CAAC;AACtC,CAAC;AAFD,oCAEC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACI,KAAK,UAAU,cAAc,CAAC,GAAW;IAC9C,MAAM,UAAU,GAAG,cAAI,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;IAEnD,IAAI,MAAM,kBAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QACpC,IAAI,CAAC;YACH,OAAO,MAAM,kBAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QACvC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,KAAK,CAAC,CAAC;YACnD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAbD,wCAaC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACI,KAAK,UAAU,gBAAgB,CAAC,GAAW;IAChD,MAAM,UAAU,GAAG,cAAI,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;IAEnD,IAAI,MAAM,kBAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QACpC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,kBAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;YAC7C,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBAClB,OAAO,MAAM,CAAC;YAChB,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAfD,4CAeC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACI,KAAK,UAAU,gBAAgB,CAAC,GAAW;IAChD,MAAM,UAAU,GAAG,cAAI,CAAC,IAAI,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;IAErD,IAAI,MAAM,kBAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QACpC,IAAI,CAAC;YACH,OAAO,MAAM,kBAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QACvC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;YACrD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAbD,4CAaC","sourcesContent":["/**\n * @fileoverview Configuration types and loaders for MetadataSync\n * @module config\n * \n * This module defines configuration interfaces and provides utilities for loading\n * various configuration files used by the MetadataSync tool. It supports:\n * - MemberJunction database configuration (mj.config.cjs)\n * - Sync configuration (.mj-sync.json)\n * - Entity-specific configuration (.mj-sync.json with entity field)\n * - Folder-level defaults (.mj-folder.json)\n */\n\nimport { cosmiconfigSync } from 'cosmiconfig';\nimport path from 'path';\nimport fs from 'fs-extra';\nimport { configManager } from './lib/config-manager';\n\n/**\n * MemberJunction database configuration\n * \n * Defines connection parameters and settings for connecting to the MemberJunction\n * database. Typically loaded from mj.config.cjs in the project root.\n */\nexport interface MJConfig {\n /** Database server hostname or IP address */\n dbHost: string;\n /** Database server port (defaults to 1433 for SQL Server) */\n dbPort?: number;\n /** Database name to connect to */\n dbDatabase: string;\n /** Database authentication username */\n dbUsername: string;\n /** Database authentication password */\n dbPassword: string;\n /** Whether to trust the server certificate (Y/N) */\n dbTrustServerCertificate?: string;\n /** Whether to encrypt the connection (Y/N, auto-detected for Azure SQL) */\n dbEncrypt?: string;\n /** SQL Server instance name (for named instances) */\n dbInstanceName?: string;\n /** Schema name for MemberJunction core tables (defaults to __mj) */\n mjCoreSchema?: string;\n /** Allow additional properties for extensibility */\n [key: string]: any;\n}\n\n/**\n * Global sync configuration\n * \n * Defines settings that apply to the entire sync process, including push/pull\n * behaviors and watch mode configuration. Stored in .mj-sync.json at the root.\n */\nexport interface SyncConfig {\n /** Version of the sync configuration format */\n version: string;\n /** Glob pattern for finding data files (defaults to \"*.json\") */\n filePattern?: string;\n /** \n * Directory processing order (only applies to root-level config, not inherited by subdirectories)\n * Specifies the order in which subdirectories should be processed to handle dependencies.\n * Directories not listed in this array will be processed after the ordered ones in alphabetical order.\n */\n directoryOrder?: string[];\n /** Push command configuration */\n push?: {\n /** Whether to validate records before pushing to database */\n validateBeforePush?: boolean;\n /** Whether to require user confirmation before push */\n requireConfirmation?: boolean;\n /** \n * Whether to automatically create new records when a primaryKey exists but record is not found\n * Defaults to false - will warn instead of creating\n */\n autoCreateMissingRecords?: boolean;\n };\n /** SQL logging configuration (only applies to root-level config, not inherited by subdirectories) */\n sqlLogging?: {\n /** Whether to enable SQL logging during push operations */\n enabled?: boolean;\n /** Directory to output SQL log files (relative to command execution directory, defaults to './sql_logging') */\n outputDirectory?: string;\n /** Whether to format SQL as migration-ready files with Flyway schema placeholders */\n formatAsMigration?: boolean;\n };\n /** Watch command configuration */\n watch?: {\n /** Milliseconds to wait before processing file changes */\n debounceMs?: number;\n /** File patterns to ignore during watch */\n ignorePatterns?: string[];\n };\n}\n\n/**\n * Configuration for related entity synchronization\n * \n * Defines how to pull and push related entities that have foreign key relationships\n * with a parent entity. Supports nested relationships for deep object graphs.\n * NEW: Supports automatic recursive patterns for self-referencing entities.\n */\nexport interface RelatedEntityConfig {\n /** Name of the related entity to sync */\n entity: string;\n /** Field name that contains the foreign key reference to parent (e.g., \"PromptID\") */\n foreignKey: string;\n /** Optional SQL filter to apply when pulling related records */\n filter?: string;\n /** \n * Enable recursive fetching for self-referencing entities\n * When true, automatically fetches all levels of the hierarchy until no more children found\n */\n recursive?: boolean;\n /** \n * Maximum depth for recursive fetching (optional, defaults to 10)\n * Prevents infinite loops and controls memory usage\n * Only applies when recursive is true\n */\n maxDepth?: number;\n /** Fields to externalize to separate files for this related entity */\n externalizeFields?: string[] | {\n [fieldName: string]: {\n /** File extension to use (e.g., \".md\", \".txt\", \".html\") */\n extension?: string;\n }\n } | Array<{\n /** Field name to externalize */\n field: string;\n /** Pattern for the output file. Supports placeholders from the entity */\n pattern: string;\n }>;\n /** Fields to exclude from the pulled data for this related entity */\n excludeFields?: string[];\n /** Foreign key fields to convert to @lookup references for this related entity */\n lookupFields?: {\n [fieldName: string]: {\n entity: string;\n field: string;\n };\n };\n /** Nested related entities for deep object graphs */\n relatedEntities?: Record<string, RelatedEntityConfig>;\n}\n\n/**\n * Entity-specific configuration\n * \n * Defines settings for a specific entity type within a directory. Stored in\n * .mj-sync.json files that contain an \"entity\" field. Supports defaults,\n * file patterns, and related entity configuration.\n */\nexport interface EntityConfig {\n /** Name of the entity this directory contains */\n entity: string;\n /** Glob pattern for finding data files (defaults to \"*.json\") */\n filePattern?: string;\n /** Default field values applied to all records in this directory */\n defaults?: Record<string, any>;\n /** Pull command specific configuration */\n pull?: {\n /** Glob pattern for finding existing files to update (defaults to filePattern) */\n filePattern?: string;\n /** Whether to create new files for records not found locally */\n createNewFileIfNotFound?: boolean;\n /** Filename for new records when createNewFileIfNotFound is true */\n newFileName?: string;\n /** Whether to append multiple new records to a single file */\n appendRecordsToExistingFile?: boolean;\n /** Whether to update existing records found in local files */\n updateExistingRecords?: boolean;\n /** Fields to preserve during updates (never overwrite these) */\n preserveFields?: string[];\n /** Strategy for merging updates: \"overwrite\" | \"merge\" | \"skip\" */\n mergeStrategy?: 'overwrite' | 'merge' | 'skip';\n /** Create backup files before updating existing files */\n backupBeforeUpdate?: boolean;\n /** Directory name for backup files (defaults to \".backups\") */\n backupDirectory?: string;\n /** SQL filter to apply when pulling records from database */\n filter?: string;\n /** Configuration for pulling related entities */\n relatedEntities?: Record<string, RelatedEntityConfig>;\n /** Fields to externalize to separate files with optional configuration */\n externalizeFields?: string[] | {\n [fieldName: string]: {\n /** File extension to use (e.g., \".md\", \".txt\", \".html\") */\n extension?: string;\n }\n } | Array<{\n /** Field name to externalize */\n field: string;\n /** Pattern for the output file. Supports placeholders:\n * - {Name}: Entity's name field value\n * - {ID}: Entity's ID\n * - {FieldName}: The field being externalized\n * - Any other {FieldName} from the entity\n * Example: \"@file:templates/{Name}.template.md\"\n */\n pattern: string;\n }>;\n /** Fields to exclude from the pulled data (e.g., [\"TemplateID\"]) */\n excludeFields?: string[];\n /** Foreign key fields to convert to @lookup references */\n lookupFields?: {\n /** Field name in this entity (e.g., \"CategoryID\") */\n [fieldName: string]: {\n /** Target entity name (e.g., \"AI Prompt Categories\") */\n entity: string;\n /** Field in target entity to use for lookup (e.g., \"Name\") */\n field: string;\n };\n };\n };\n}\n\n/**\n * Folder-level configuration\n * \n * Defines default values that cascade down to all subdirectories. Stored in\n * .mj-folder.json files. Child folders can override parent defaults.\n */\nexport interface FolderConfig {\n /** Default field values that apply to all entities in this folder and subfolders */\n defaults: Record<string, any>;\n}\n\n/**\n * Load MemberJunction configuration from the filesystem\n * \n * Searches for mj.config.cjs starting from the current directory and walking up\n * the directory tree. Uses cosmiconfig for flexible configuration loading.\n * \n * @returns MJConfig object if found, null if not found or invalid\n * \n * @example\n * ```typescript\n * const config = loadMJConfig();\n * if (config) {\n * console.log(`Connecting to ${config.dbHost}:${config.dbPort || 1433}`);\n * }\n * ```\n */\nexport function loadMJConfig(): MJConfig | null {\n return configManager.loadMJConfig();\n}\n\n/**\n * Load sync configuration from a directory\n * \n * Loads .mj-sync.json file from the specified directory. This file can contain\n * either global sync configuration (no entity field) or entity-specific\n * configuration (with entity field).\n * \n * @param dir - Directory path to load configuration from\n * @returns Promise resolving to SyncConfig if found and valid, null otherwise\n * \n * @example\n * ```typescript\n * const syncConfig = await loadSyncConfig('/path/to/project');\n * if (syncConfig?.push?.requireConfirmation) {\n * // Show confirmation prompt\n * }\n * ```\n */\nexport async function loadSyncConfig(dir: string): Promise<SyncConfig | null> {\n const configPath = path.join(dir, '.mj-sync.json');\n \n if (await fs.pathExists(configPath)) {\n try {\n return await fs.readJson(configPath);\n } catch (error) {\n console.error('Error loading sync config:', error);\n return null;\n }\n }\n \n return null;\n}\n\n/**\n * Load entity-specific configuration from a directory\n * \n * Loads .mj-sync.json file that contains an \"entity\" field, indicating this\n * directory contains data for a specific entity type. Returns null if the\n * file doesn't exist or doesn't contain an entity field.\n * \n * @param dir - Directory path to load configuration from\n * @returns Promise resolving to EntityConfig if found and valid, null otherwise\n * \n * @example\n * ```typescript\n * const entityConfig = await loadEntityConfig('./ai-prompts');\n * if (entityConfig) {\n * console.log(`Directory contains ${entityConfig.entity} records`);\n * }\n * ```\n */\nexport async function loadEntityConfig(dir: string): Promise<EntityConfig | null> {\n const configPath = path.join(dir, '.mj-sync.json');\n \n if (await fs.pathExists(configPath)) {\n try {\n const config = await fs.readJson(configPath);\n if (config.entity) {\n return config;\n }\n } catch (error) {\n console.error('Error loading entity config:', error);\n }\n }\n \n return null;\n}\n\n/**\n * Load folder-level configuration\n * \n * Loads .mj-folder.json file that contains default values to be applied to\n * all entities in this folder and its subfolders. Used for cascading defaults\n * in deep directory structures.\n * \n * @param dir - Directory path to load configuration from\n * @returns Promise resolving to FolderConfig if found and valid, null otherwise\n * \n * @example\n * ```typescript\n * const folderConfig = await loadFolderConfig('./templates');\n * if (folderConfig?.defaults) {\n * // Apply folder defaults to records\n * }\n * ```\n */\nexport async function loadFolderConfig(dir: string): Promise<FolderConfig | null> {\n const configPath = path.join(dir, '.mj-folder.json');\n \n if (await fs.pathExists(configPath)) {\n try {\n return await fs.readJson(configPath);\n } catch (error) {\n console.error('Error loading folder config:', error);\n return null;\n }\n }\n \n return null;\n}"]}
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;;;;;AAGH,gDAAwB;AACxB,wDAA0B;AAC1B,yDAAqD;AAyOrD;;;;;;;;;;;;;;;GAeG;AACH,SAAgB,YAAY;IAC1B,OAAO,8BAAa,CAAC,YAAY,EAAE,CAAC;AACtC,CAAC;AAFD,oCAEC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACI,KAAK,UAAU,cAAc,CAAC,GAAW;IAC9C,MAAM,UAAU,GAAG,cAAI,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;IAEnD,IAAI,MAAM,kBAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QACpC,IAAI,CAAC;YACH,OAAO,MAAM,kBAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QACvC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,KAAK,CAAC,CAAC;YACnD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAbD,wCAaC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACI,KAAK,UAAU,gBAAgB,CAAC,GAAW;IAChD,MAAM,UAAU,GAAG,cAAI,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;IAEnD,IAAI,MAAM,kBAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QACpC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,kBAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;YAC7C,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBAClB,OAAO,MAAM,CAAC;YAChB,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAfD,4CAeC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACI,KAAK,UAAU,gBAAgB,CAAC,GAAW;IAChD,MAAM,UAAU,GAAG,cAAI,CAAC,IAAI,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;IAErD,IAAI,MAAM,kBAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QACpC,IAAI,CAAC;YACH,OAAO,MAAM,kBAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QACvC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;YACrD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAbD,4CAaC","sourcesContent":["/**\n * @fileoverview Configuration types and loaders for MetadataSync\n * @module config\n * \n * This module defines configuration interfaces and provides utilities for loading\n * various configuration files used by the MetadataSync tool. It supports:\n * - MemberJunction database configuration (mj.config.cjs)\n * - Sync configuration (.mj-sync.json)\n * - Entity-specific configuration (.mj-sync.json with entity field)\n * - Folder-level defaults (.mj-folder.json)\n */\n\nimport { cosmiconfigSync } from 'cosmiconfig';\nimport path from 'path';\nimport fs from 'fs-extra';\nimport { configManager } from './lib/config-manager';\n\n/**\n * MemberJunction database configuration\n * \n * Defines connection parameters and settings for connecting to the MemberJunction\n * database. Typically loaded from mj.config.cjs in the project root.\n */\nexport interface MJConfig {\n /** Database server hostname or IP address */\n dbHost: string;\n /** Database server port (defaults to 1433 for SQL Server) */\n dbPort?: number;\n /** Database name to connect to */\n dbDatabase: string;\n /** Database authentication username */\n dbUsername: string;\n /** Database authentication password */\n dbPassword: string;\n /** Whether to trust the server certificate (Y/N) */\n dbTrustServerCertificate?: string;\n /** Whether to encrypt the connection (Y/N, auto-detected for Azure SQL) */\n dbEncrypt?: string;\n /** SQL Server instance name (for named instances) */\n dbInstanceName?: string;\n /** Schema name for MemberJunction core tables (defaults to __mj) */\n mjCoreSchema?: string;\n /** Allow additional properties for extensibility */\n [key: string]: any;\n}\n\n/**\n * Global sync configuration\n * \n * Defines settings that apply to the entire sync process, including push/pull\n * behaviors and watch mode configuration. Stored in .mj-sync.json at the root.\n */\nexport interface SyncConfig {\n /** Version of the sync configuration format */\n version: string;\n /** Glob pattern for finding data files (defaults to \"*.json\") */\n filePattern?: string;\n /** \n * Directory processing order (only applies to root-level config, not inherited by subdirectories)\n * Specifies the order in which subdirectories should be processed to handle dependencies.\n * Directories not listed in this array will be processed after the ordered ones in alphabetical order.\n */\n directoryOrder?: string[];\n /** \n * Directories to ignore during processing\n * Can be directory names or glob patterns relative to the location of the .mj-sync.json file\n * Cumulative: subdirectories inherit and add to parent ignoreDirectories\n * Examples: [\"output\", \"examples\", \"temp\"]\n */\n ignoreDirectories?: string[];\n /** Push command configuration */\n push?: {\n /** Whether to validate records before pushing to database */\n validateBeforePush?: boolean;\n /** Whether to require user confirmation before push */\n requireConfirmation?: boolean;\n /** \n * Whether to automatically create new records when a primaryKey exists but record is not found\n * Defaults to false - will warn instead of creating\n */\n autoCreateMissingRecords?: boolean;\n };\n /** SQL logging configuration (only applies to root-level config, not inherited by subdirectories) */\n sqlLogging?: {\n /** Whether to enable SQL logging during push operations */\n enabled?: boolean;\n /** Directory to output SQL log files (relative to command execution directory, defaults to './sql_logging') */\n outputDirectory?: string;\n /** Whether to format SQL as migration-ready files with Flyway schema placeholders */\n formatAsMigration?: boolean;\n };\n /** Watch command configuration */\n watch?: {\n /** Milliseconds to wait before processing file changes */\n debounceMs?: number;\n /** File patterns to ignore during watch */\n ignorePatterns?: string[];\n };\n /** User role validation configuration */\n userRoleValidation?: {\n /** Whether to enable user role validation for UserID fields */\n enabled?: boolean;\n /** List of role names that are allowed to be referenced in metadata */\n allowedRoles?: string[];\n /** Whether to allow users without any roles (defaults to false) */\n allowUsersWithoutRoles?: boolean;\n };\n}\n\n/**\n * Configuration for related entity synchronization\n * \n * Defines how to pull and push related entities that have foreign key relationships\n * with a parent entity. Supports nested relationships for deep object graphs.\n * NEW: Supports automatic recursive patterns for self-referencing entities.\n */\nexport interface RelatedEntityConfig {\n /** Name of the related entity to sync */\n entity: string;\n /** Field name that contains the foreign key reference to parent (e.g., \"PromptID\") */\n foreignKey: string;\n /** Optional SQL filter to apply when pulling related records */\n filter?: string;\n /** \n * Enable recursive fetching for self-referencing entities\n * When true, automatically fetches all levels of the hierarchy until no more children found\n */\n recursive?: boolean;\n /** \n * Maximum depth for recursive fetching (optional, defaults to 10)\n * Prevents infinite loops and controls memory usage\n * Only applies when recursive is true\n */\n maxDepth?: number;\n /** Fields to externalize to separate files for this related entity */\n externalizeFields?: string[] | {\n [fieldName: string]: {\n /** File extension to use (e.g., \".md\", \".txt\", \".html\") */\n extension?: string;\n }\n } | Array<{\n /** Field name to externalize */\n field: string;\n /** Pattern for the output file. Supports placeholders from the entity */\n pattern: string;\n }>;\n /** Fields to exclude from the pulled data for this related entity */\n excludeFields?: string[];\n /** Foreign key fields to convert to @lookup references for this related entity */\n lookupFields?: {\n [fieldName: string]: {\n entity: string;\n field: string;\n };\n };\n /** Nested related entities for deep object graphs */\n relatedEntities?: Record<string, RelatedEntityConfig>;\n}\n\n/**\n * Entity-specific configuration\n * \n * Defines settings for a specific entity type within a directory. Stored in\n * .mj-sync.json files that contain an \"entity\" field. Supports defaults,\n * file patterns, and related entity configuration.\n */\nexport interface EntityConfig {\n /** Name of the entity this directory contains */\n entity: string;\n /** Glob pattern for finding data files (defaults to \"*.json\") */\n filePattern?: string;\n /** Default field values applied to all records in this directory */\n defaults?: Record<string, any>;\n /** \n * Directories to ignore during processing\n * Can be directory names or glob patterns relative to the location of the .mj-sync.json file\n * Cumulative: subdirectories inherit and add to parent ignoreDirectories\n * Examples: [\"output\", \"examples\", \"temp\"]\n */\n ignoreDirectories?: string[];\n /** Pull command specific configuration */\n pull?: {\n /** Glob pattern for finding existing files to update (defaults to filePattern) */\n filePattern?: string;\n /** Whether to create new files for records not found locally */\n createNewFileIfNotFound?: boolean;\n /** Filename for new records when createNewFileIfNotFound is true */\n newFileName?: string;\n /** Whether to append multiple new records to a single file */\n appendRecordsToExistingFile?: boolean;\n /** Whether to update existing records found in local files */\n updateExistingRecords?: boolean;\n /** Fields to preserve during updates (never overwrite these) */\n preserveFields?: string[];\n /** Strategy for merging updates: \"overwrite\" | \"merge\" | \"skip\" */\n mergeStrategy?: 'overwrite' | 'merge' | 'skip';\n /** Create backup files before updating existing files */\n backupBeforeUpdate?: boolean;\n /** Directory name for backup files (defaults to \".backups\") */\n backupDirectory?: string;\n /** SQL filter to apply when pulling records from database */\n filter?: string;\n /** Configuration for pulling related entities */\n relatedEntities?: Record<string, RelatedEntityConfig>;\n /** Fields to externalize to separate files with optional configuration */\n externalizeFields?: string[] | {\n [fieldName: string]: {\n /** File extension to use (e.g., \".md\", \".txt\", \".html\") */\n extension?: string;\n }\n } | Array<{\n /** Field name to externalize */\n field: string;\n /** Pattern for the output file. Supports placeholders:\n * - {Name}: Entity's name field value\n * - {ID}: Entity's ID\n * - {FieldName}: The field being externalized\n * - Any other {FieldName} from the entity\n * Example: \"@file:templates/{Name}.template.md\"\n */\n pattern: string;\n }>;\n /** Fields to exclude from the pulled data (e.g., [\"TemplateID\"]) */\n excludeFields?: string[];\n /** Foreign key fields to convert to @lookup references */\n lookupFields?: {\n /** Field name in this entity (e.g., \"CategoryID\") */\n [fieldName: string]: {\n /** Target entity name (e.g., \"AI Prompt Categories\") */\n entity: string;\n /** Field in target entity to use for lookup (e.g., \"Name\") */\n field: string;\n };\n };\n };\n}\n\n/**\n * Folder-level configuration\n * \n * Defines default values that cascade down to all subdirectories. Stored in\n * .mj-folder.json files. Child folders can override parent defaults.\n */\nexport interface FolderConfig {\n /** Default field values that apply to all entities in this folder and subfolders */\n defaults: Record<string, any>;\n}\n\n/**\n * Load MemberJunction configuration from the filesystem\n * \n * Searches for mj.config.cjs starting from the current directory and walking up\n * the directory tree. Uses cosmiconfig for flexible configuration loading.\n * \n * @returns MJConfig object if found, null if not found or invalid\n * \n * @example\n * ```typescript\n * const config = loadMJConfig();\n * if (config) {\n * console.log(`Connecting to ${config.dbHost}:${config.dbPort || 1433}`);\n * }\n * ```\n */\nexport function loadMJConfig(): MJConfig | null {\n return configManager.loadMJConfig();\n}\n\n/**\n * Load sync configuration from a directory\n * \n * Loads .mj-sync.json file from the specified directory. This file can contain\n * either global sync configuration (no entity field) or entity-specific\n * configuration (with entity field).\n * \n * @param dir - Directory path to load configuration from\n * @returns Promise resolving to SyncConfig if found and valid, null otherwise\n * \n * @example\n * ```typescript\n * const syncConfig = await loadSyncConfig('/path/to/project');\n * if (syncConfig?.push?.requireConfirmation) {\n * // Show confirmation prompt\n * }\n * ```\n */\nexport async function loadSyncConfig(dir: string): Promise<SyncConfig | null> {\n const configPath = path.join(dir, '.mj-sync.json');\n \n if (await fs.pathExists(configPath)) {\n try {\n return await fs.readJson(configPath);\n } catch (error) {\n console.error('Error loading sync config:', error);\n return null;\n }\n }\n \n return null;\n}\n\n/**\n * Load entity-specific configuration from a directory\n * \n * Loads .mj-sync.json file that contains an \"entity\" field, indicating this\n * directory contains data for a specific entity type. Returns null if the\n * file doesn't exist or doesn't contain an entity field.\n * \n * @param dir - Directory path to load configuration from\n * @returns Promise resolving to EntityConfig if found and valid, null otherwise\n * \n * @example\n * ```typescript\n * const entityConfig = await loadEntityConfig('./ai-prompts');\n * if (entityConfig) {\n * console.log(`Directory contains ${entityConfig.entity} records`);\n * }\n * ```\n */\nexport async function loadEntityConfig(dir: string): Promise<EntityConfig | null> {\n const configPath = path.join(dir, '.mj-sync.json');\n \n if (await fs.pathExists(configPath)) {\n try {\n const config = await fs.readJson(configPath);\n if (config.entity) {\n return config;\n }\n } catch (error) {\n console.error('Error loading entity config:', error);\n }\n }\n \n return null;\n}\n\n/**\n * Load folder-level configuration\n * \n * Loads .mj-folder.json file that contains default values to be applied to\n * all entities in this folder and its subfolders. Used for cascading defaults\n * in deep directory structures.\n * \n * @param dir - Directory path to load configuration from\n * @returns Promise resolving to FolderConfig if found and valid, null otherwise\n * \n * @example\n * ```typescript\n * const folderConfig = await loadFolderConfig('./templates');\n * if (folderConfig?.defaults) {\n * // Apply folder defaults to records\n * }\n * ```\n */\nexport async function loadFolderConfig(dir: string): Promise<FolderConfig | null> {\n const configPath = path.join(dir, '.mj-folder.json');\n \n if (await fs.pathExists(configPath)) {\n try {\n return await fs.readJson(configPath);\n } catch (error) {\n console.error('Error loading folder config:', error);\n return null;\n }\n }\n \n return null;\n}"]}
|
|
@@ -51,9 +51,10 @@ export declare function cleanupProvider(): Promise<void>;
|
|
|
51
51
|
*
|
|
52
52
|
* Retrieves the "System" user from MemberJunction's UserCache. This user is
|
|
53
53
|
* typically used for CLI operations where no specific user context exists.
|
|
54
|
+
* The System user must have the Developer role to perform metadata sync operations.
|
|
54
55
|
*
|
|
55
56
|
* @returns The System UserInfo object
|
|
56
|
-
* @throws Error if System user is not found in the cache
|
|
57
|
+
* @throws Error if System user is not found in the cache or doesn't have Developer role
|
|
57
58
|
*
|
|
58
59
|
* @example
|
|
59
60
|
* ```typescript
|
|
@@ -89,6 +90,7 @@ export declare function getDataProvider(): SQLServerDataProvider | null;
|
|
|
89
90
|
* @param dir - Base directory to search from
|
|
90
91
|
* @param specificDir - Optional specific subdirectory name to check
|
|
91
92
|
* @param directoryOrder - Optional array specifying the order directories should be processed
|
|
93
|
+
* @param ignoreDirectories - Optional array of directory patterns to ignore
|
|
92
94
|
* @returns Array of absolute directory paths containing .mj-sync.json files, ordered according to directoryOrder
|
|
93
95
|
*
|
|
94
96
|
* @example
|
|
@@ -103,4 +105,4 @@ export declare function getDataProvider(): SQLServerDataProvider | null;
|
|
|
103
105
|
* const dirs = findEntityDirectories(process.cwd(), undefined, ['prompts', 'agent-types']);
|
|
104
106
|
* ```
|
|
105
107
|
*/
|
|
106
|
-
export declare function findEntityDirectories(dir: string, specificDir?: string, directoryOrder?: string[]): string[];
|
|
108
|
+
export declare function findEntityDirectories(dir: string, specificDir?: string, directoryOrder?: string[], ignoreDirectories?: string[]): string[];
|