@memberjunction/metadata-sync 2.49.0 → 2.51.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 +423 -2
- package/dist/commands/pull/index.d.ts +1 -0
- package/dist/commands/pull/index.js +82 -10
- package/dist/commands/pull/index.js.map +1 -1
- package/dist/commands/push/index.d.ts +4 -0
- package/dist/commands/push/index.js +196 -22
- package/dist/commands/push/index.js.map +1 -1
- package/dist/commands/validate/index.d.ts +15 -0
- package/dist/commands/validate/index.js +149 -0
- package/dist/commands/validate/index.js.map +1 -0
- package/dist/lib/provider-utils.d.ts +2 -2
- package/dist/lib/provider-utils.js +3 -4
- package/dist/lib/provider-utils.js.map +1 -1
- package/dist/lib/sync-engine.js +27 -2
- package/dist/lib/sync-engine.js.map +1 -1
- package/dist/services/FormattingService.d.ts +44 -0
- package/dist/services/FormattingService.js +561 -0
- package/dist/services/FormattingService.js.map +1 -0
- package/dist/services/ValidationService.d.ts +110 -0
- package/dist/services/ValidationService.js +737 -0
- package/dist/services/ValidationService.js.map +1 -0
- package/dist/types/validation.d.ts +98 -0
- package/dist/types/validation.js +97 -0
- package/dist/types/validation.js.map +1 -0
- package/oclif.manifest.json +98 -1
- package/package.json +7 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/pull/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Pull command implementation for MetadataSync\n * @module commands/pull\n * \n * This module implements the pull command which retrieves metadata records from\n * the MemberJunction database and saves them as local JSON files. It supports:\n * - Filtering records with SQL expressions\n * - Pulling related entities with foreign key relationships\n * - Externalizing large text fields to separate files\n * - Creating multi-record JSON files\n * - Recursive directory search for entity configurations\n */\n\nimport { Command, Flags } from '@oclif/core';\nimport fs from 'fs-extra';\nimport path from 'path';\nimport { select } from '@inquirer/prompts';\nimport ora from 'ora-classic';\nimport { loadMJConfig, loadEntityConfig, RelatedEntityConfig } from '../../config';\nimport { SyncEngine, RecordData } from '../../lib/sync-engine';\nimport { RunView, Metadata, EntityInfo } from '@memberjunction/core';\nimport { getSystemUser, initializeProvider, cleanupProvider } from '../../lib/provider-utils';\nimport { configManager } from '../../lib/config-manager';\nimport { getSyncEngine, resetSyncEngine } from '../../lib/singleton-manager';\n\n/**\n * Pull metadata records from database to local files\n * \n * @class Pull\n * @extends Command\n * \n * @example\n * ```bash\n * # Pull all records for an entity\n * mj-sync pull --entity=\"AI Prompts\"\n * \n * # Pull with filter\n * mj-sync pull --entity=\"AI Prompts\" --filter=\"CategoryID='123'\"\n * \n * # Pull to multi-record file\n * mj-sync pull --entity=\"AI Prompts\" --multi-file=\"all-prompts.json\"\n * ```\n */\nexport default class Pull extends Command {\n static description = 'Pull metadata from database to local files';\n \n static examples = [\n `<%= config.bin %> <%= command.id %> --entity=\"AI Prompts\"`,\n `<%= config.bin %> <%= command.id %> --entity=\"AI Prompts\" --filter=\"CategoryID='customer-service-id'\"`,\n ];\n \n static flags = {\n entity: Flags.string({ description: 'Entity name to pull', required: true }),\n filter: Flags.string({ description: 'Additional filter for pulling specific records' }),\n 'dry-run': Flags.boolean({ description: 'Show what would be pulled without actually pulling' }),\n 'multi-file': Flags.string({ description: 'Create a single file with multiple records (provide filename)' }),\n verbose: Flags.boolean({ char: 'v', description: 'Show detailed output' }),\n };\n \n async run(): Promise<void> {\n const { flags } = await this.parse(Pull);\n const spinner = ora();\n \n try {\n // Load MJ config first (before changing directory)\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 // Stop spinner before provider initialization (which logs to console)\n spinner.stop();\n \n // Initialize data provider\n const provider = await initializeProvider(mjConfig);\n \n // Get singleton sync engine\n const syncEngine = await getSyncEngine(getSystemUser());\n \n // Show success after all initialization is complete\n spinner.succeed('Configuration and metadata loaded');\n \n let targetDir: string;\n let entityConfig: any;\n \n // Check if we should use a specific target directory\n const envTargetDir = process.env.METADATA_SYNC_TARGET_DIR;\n if (envTargetDir) {\n if (flags.verbose) {\n console.log(`Using specified target directory: ${envTargetDir}`);\n }\n process.chdir(envTargetDir);\n targetDir = process.cwd();\n \n // Load entity config from the current directory\n entityConfig = await loadEntityConfig(targetDir);\n if (!entityConfig) {\n this.error(`No .mj-sync.json found in ${targetDir}`);\n }\n if (entityConfig.entity !== flags.entity) {\n this.error(`Directory ${targetDir} is configured for entity \"${entityConfig.entity}\", not \"${flags.entity}\"`);\n }\n } else {\n // Original behavior - find entity directory\n const entityDirs = await this.findEntityDirectories(flags.entity);\n \n if (entityDirs.length === 0) {\n this.error(`No directory found for entity \"${flags.entity}\". Run \"mj-sync init\" first.`);\n }\n \n if (entityDirs.length === 1) {\n targetDir = entityDirs[0];\n } else {\n // Multiple directories found, ask user\n targetDir = await select({\n message: `Multiple directories found for entity \"${flags.entity}\". Which one to use?`,\n choices: entityDirs.map(dir => ({ name: dir, value: dir }))\n });\n }\n \n entityConfig = await loadEntityConfig(targetDir);\n if (!entityConfig) {\n this.error(`Invalid entity configuration in ${targetDir}`);\n }\n }\n \n // Show configuration notice only if relevant\n if (entityConfig.pull?.appendRecordsToExistingFile && entityConfig.pull?.newFileName) {\n const targetFile = path.join(targetDir, entityConfig.pull.newFileName.endsWith('.json') \n ? entityConfig.pull.newFileName \n : `${entityConfig.pull.newFileName}.json`);\n \n if (await fs.pathExists(targetFile)) {\n // File exists - inform about append behavior\n this.log(`\\n📝 Configuration: New records will be appended to existing file '${path.basename(targetFile)}'`);\n }\n // If file doesn't exist, no need to mention anything special - we're just creating it\n }\n \n // Pull records\n spinner.start(`Pulling ${flags.entity} records`);\n const rv = new RunView();\n \n let filter = '';\n if (flags.filter) {\n filter = flags.filter;\n } else if (entityConfig.pull?.filter) {\n filter = entityConfig.pull.filter;\n }\n \n const result = await rv.RunView({\n EntityName: flags.entity,\n ExtraFilter: filter,\n ResultType: 'entity_object'\n }, getSystemUser());\n \n if (!result.Success) {\n this.error(`Failed to pull records: ${result.ErrorMessage}`);\n }\n \n spinner.succeed(`Found ${result.Results.length} records`);\n \n if (flags['dry-run']) {\n this.log(`\\nDry run mode - would pull ${result.Results.length} records to ${targetDir}`);\n return;\n }\n \n // Check if we need to wait for async property loading\n if (entityConfig.pull?.externalizeFields && result.Results.length > 0) {\n const metadata = new Metadata();\n const entityInfo = metadata.EntityByName(flags.entity);\n if (entityInfo) {\n const externalizeConfig = entityConfig.pull.externalizeFields;\n let fieldsToExternalize: string[] = [];\n \n if (Array.isArray(externalizeConfig)) {\n if (externalizeConfig.length > 0 && typeof externalizeConfig[0] === 'string') {\n // Simple string array\n fieldsToExternalize = externalizeConfig as string[];\n } else {\n // New pattern format\n fieldsToExternalize = (externalizeConfig as Array<{field: string; pattern: string}>)\n .map(item => item.field);\n }\n } else {\n // Object format\n fieldsToExternalize = Object.keys(externalizeConfig);\n }\n \n // Get all field names from entity metadata\n const metadataFieldNames = entityInfo.Fields.map(f => f.Name);\n \n // Check if any externalized fields are NOT in metadata (likely computed properties)\n const computedFields = fieldsToExternalize.filter(f => !metadataFieldNames.includes(f));\n \n if (computedFields.length > 0) {\n spinner.start(`Waiting 5 seconds for async property loading in ${flags.entity} (${computedFields.join(', ')})...`);\n await new Promise(resolve => setTimeout(resolve, 5000));\n spinner.succeed('Async property loading wait complete');\n }\n }\n }\n \n // Process each record\n const entityInfo = syncEngine.getEntityInfo(flags.entity);\n if (!entityInfo) {\n this.error(`Entity information not found for: ${flags.entity}`);\n }\n \n spinner.start('Processing records');\n let processed = 0;\n let updated = 0;\n let created = 0;\n let skipped = 0;\n \n // If multi-file flag is set, collect all records\n if (flags['multi-file']) {\n const allRecords: RecordData[] = [];\n \n for (const record of result.Results) {\n try {\n // Build primary key\n const primaryKey: Record<string, any> = {};\n for (const pk of entityInfo.PrimaryKeys) {\n primaryKey[pk.Name] = record[pk.Name];\n }\n \n // Process record for multi-file\n const recordData = await this.processRecordData(record, primaryKey, targetDir, entityConfig, syncEngine, flags, true);\n allRecords.push(recordData);\n processed++;\n \n if (flags.verbose) {\n spinner.text = `Processing records (${processed}/${result.Results.length})`;\n }\n } catch (error) {\n this.warn(`Failed to process record: ${(error as any).message || error}`);\n }\n }\n \n // Write all records to single file\n if (allRecords.length > 0) {\n const fileName = flags['multi-file'].endsWith('.json') ? flags['multi-file'] : `${flags['multi-file']}.json`;\n const filePath = path.join(targetDir, fileName);\n await fs.writeJson(filePath, allRecords, { spaces: 2 });\n spinner.succeed(`Pulled ${processed} records to ${filePath}`);\n }\n } else {\n // Smart update logic for single-file-per-record\n spinner.text = 'Scanning for existing files...';\n \n // Find existing files\n const filePattern = entityConfig.pull?.filePattern || entityConfig.filePattern || '*.json';\n const existingFiles = await this.findExistingFiles(targetDir, filePattern);\n \n if (flags.verbose) {\n this.log(`Found ${existingFiles.length} existing files matching pattern '${filePattern}'`);\n existingFiles.forEach(f => this.log(` - ${path.basename(f)}`));\n }\n \n // Load existing records and build lookup map\n const existingRecordsMap = await this.loadExistingRecords(existingFiles, entityInfo);\n \n if (flags.verbose) {\n this.log(`Loaded ${existingRecordsMap.size} existing records from files`);\n }\n \n // Separate records into new and existing\n const newRecords: Array<{ record: any; primaryKey: Record<string, any> }> = [];\n const existingRecordsToUpdate: Array<{ record: any; primaryKey: Record<string, any>; filePath: string }> = [];\n \n for (const record of result.Results) {\n // Build primary key\n const primaryKey: Record<string, any> = {};\n for (const pk of entityInfo.PrimaryKeys) {\n primaryKey[pk.Name] = record[pk.Name];\n }\n \n // Create lookup key\n const lookupKey = this.createPrimaryKeyLookup(primaryKey);\n const existingFileInfo = existingRecordsMap.get(lookupKey);\n \n if (existingFileInfo) {\n // Record exists locally\n if (entityConfig.pull?.updateExistingRecords !== false) {\n existingRecordsToUpdate.push({ record, primaryKey, filePath: existingFileInfo.filePath });\n } else {\n skipped++;\n if (flags.verbose) {\n this.log(`Skipping existing record: ${lookupKey}`);\n }\n }\n } else {\n // Record doesn't exist locally\n if (entityConfig.pull?.createNewFileIfNotFound !== false) {\n newRecords.push({ record, primaryKey });\n } else {\n skipped++;\n if (flags.verbose) {\n this.log(`Skipping new record (createNewFileIfNotFound=false): ${lookupKey}`);\n }\n }\n }\n }\n \n // Track which files have been backed up to avoid duplicates\n const backedUpFiles = new Set<string>();\n \n // Process existing records updates\n for (const { record, primaryKey, filePath } of existingRecordsToUpdate) {\n try {\n spinner.text = `Updating existing records (${updated + 1}/${existingRecordsToUpdate.length})`;\n \n // Create backup if configured (only once per file)\n if (entityConfig.pull?.backupBeforeUpdate && !backedUpFiles.has(filePath)) {\n await this.createBackup(filePath, entityConfig.pull?.backupDirectory);\n backedUpFiles.add(filePath);\n }\n \n // Load existing file data\n const existingData = await fs.readJson(filePath);\n \n // Find the specific existing record that matches this primary key\n let existingRecordData: RecordData;\n if (Array.isArray(existingData)) {\n // Find the matching record in the array\n const matchingRecord = existingData.find(r => \n this.createPrimaryKeyLookup(r.primaryKey || {}) === this.createPrimaryKeyLookup(primaryKey)\n );\n existingRecordData = matchingRecord || existingData[0]; // Fallback to first if not found\n } else {\n existingRecordData = existingData;\n }\n \n // Process the new record data (isNewRecord = false for updates)\n const newRecordData = await this.processRecordData(record, primaryKey, targetDir, entityConfig, syncEngine, flags, false, existingRecordData);\n \n // Apply merge strategy\n const mergedData = await this.mergeRecords(\n existingRecordData,\n newRecordData,\n entityConfig.pull?.mergeStrategy || 'merge',\n entityConfig.pull?.preserveFields || []\n );\n \n // Write updated data\n if (Array.isArray(existingData)) {\n // Update the record in the array\n const index = existingData.findIndex(r => \n this.createPrimaryKeyLookup(r.primaryKey || {}) === this.createPrimaryKeyLookup(primaryKey)\n );\n if (index >= 0) {\n existingData[index] = mergedData;\n await fs.writeJson(filePath, existingData, { spaces: 2 });\n }\n } else {\n await fs.writeJson(filePath, mergedData, { spaces: 2 });\n }\n \n updated++;\n processed++;\n \n if (flags.verbose) {\n this.log(`Updated: ${filePath}`);\n }\n } catch (error) {\n this.warn(`Failed to update record: ${(error as any).message || error}`);\n }\n }\n \n // Process new records\n if (newRecords.length > 0) {\n spinner.text = `Creating new records (0/${newRecords.length})`;\n \n if (entityConfig.pull?.appendRecordsToExistingFile && entityConfig.pull?.newFileName) {\n // Append all new records to a single file\n const fileName = entityConfig.pull.newFileName.endsWith('.json') \n ? entityConfig.pull.newFileName \n : `${entityConfig.pull.newFileName}.json`;\n const filePath = path.join(targetDir, fileName);\n \n // Load existing file if it exists\n let existingData: RecordData[] = [];\n if (await fs.pathExists(filePath)) {\n const fileData = await fs.readJson(filePath);\n existingData = Array.isArray(fileData) ? fileData : [fileData];\n }\n \n // Process and append all new records\n for (const { record, primaryKey } of newRecords) {\n try {\n // For new records, pass isNewRecord = true (default)\n const recordData = await this.processRecordData(record, primaryKey, targetDir, entityConfig, syncEngine, flags, true);\n existingData.push(recordData);\n created++;\n processed++;\n \n if (flags.verbose) {\n spinner.text = `Creating new records (${created}/${newRecords.length})`;\n }\n } catch (error) {\n this.warn(`Failed to process new record: ${(error as any).message || error}`);\n }\n }\n \n // Write the combined data\n await fs.writeJson(filePath, existingData, { spaces: 2 });\n \n if (flags.verbose) {\n this.log(`Appended ${created} new records to: ${filePath}`);\n }\n } else {\n // Create individual files for each new record\n for (const { record, primaryKey } of newRecords) {\n try {\n await this.processRecord(record, primaryKey, targetDir, entityConfig, syncEngine, flags);\n created++;\n processed++;\n \n if (flags.verbose) {\n spinner.text = `Creating new records (${created}/${newRecords.length})`;\n }\n } catch (error) {\n this.warn(`Failed to process new record: ${(error as any).message || error}`);\n }\n }\n }\n }\n \n // Final status\n const statusParts = [`Processed ${processed} records`];\n if (updated > 0) statusParts.push(`updated ${updated}`);\n if (created > 0) statusParts.push(`created ${created}`);\n if (skipped > 0) statusParts.push(`skipped ${skipped}`);\n \n spinner.succeed(statusParts.join(', '));\n }\n \n } catch (error) {\n spinner.fail('Pull failed');\n \n // Enhanced error logging for debugging\n this.log('\\n=== Pull 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(`- Entity: ${flags.entity || 'not specified'}`);\n this.log(`- Filter: ${flags.filter || 'none'}`);\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('No directory found for entity')) {\n this.log(`\\nHint: This appears to be an entity directory configuration issue.`);\n this.log(`Run \"mj-sync init\" to create directories or ensure .mj-sync.json files exist.`);\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('Failed to pull records')) {\n this.log(`\\nHint: This appears to be a database query issue.`);\n this.log(`Check if the entity name \"${flags.entity}\" is correct and exists in the database.`);\n } else if (errorMessage.includes('Entity information not found')) {\n this.log(`\\nHint: The entity \"${flags.entity}\" was not found in metadata.`);\n this.log(`Check the entity name spelling and ensure it exists in the database.`);\n }\n \n this.error(error as Error);\n } finally {\n // Clean up database connection and reset singletons\n await cleanupProvider();\n resetSyncEngine();\n \n // Exit process to prevent background MJ tasks from throwing errors\n process.exit(0);\n }\n }\n \n /**\n * Find directories containing configuration for the specified entity\n * \n * Recursively searches the current working directory for .mj-sync.json files\n * that specify the given entity name. Returns all matching directories to\n * allow user selection when multiple locations exist.\n * \n * @param entityName - Name of the entity to search for\n * @returns Promise resolving to array of directory paths\n * @private\n */\n private async findEntityDirectories(entityName: string): Promise<string[]> {\n const dirs: string[] = [];\n \n // Search for directories with matching entity config\n const searchDirs = async (dir: string) => {\n const entries = await fs.readdir(dir, { withFileTypes: true });\n \n for (const entry of entries) {\n if (entry.isDirectory()) {\n const fullPath = path.join(dir, entry.name);\n const config = await loadEntityConfig(fullPath);\n \n if (config && config.entity === entityName) {\n dirs.push(fullPath);\n } else {\n // Recurse\n await searchDirs(fullPath);\n }\n }\n }\n };\n \n await searchDirs(configManager.getOriginalCwd());\n return dirs;\n }\n \n /**\n * Process a single record and save to file\n * \n * Converts a database record into the file format and writes it to disk.\n * This is a wrapper around processRecordData that handles file writing.\n * \n * @param record - Raw database record\n * @param primaryKey - Primary key fields and values\n * @param targetDir - Directory to save the file\n * @param entityConfig - Entity configuration with pull settings\n * @param syncEngine - Sync engine instance\n * @returns Promise that resolves when file is written\n * @private\n */\n private async processRecord(\n record: any, \n primaryKey: Record<string, any>,\n targetDir: string, \n entityConfig: any,\n syncEngine: SyncEngine,\n flags: any\n ): Promise<void> {\n const recordData = await this.processRecordData(record, primaryKey, targetDir, entityConfig, syncEngine, flags, true);\n \n // Determine file path\n const fileName = this.buildFileName(primaryKey, entityConfig);\n const filePath = path.join(targetDir, fileName);\n \n // Write JSON file\n await fs.writeJson(filePath, recordData, { spaces: 2 });\n }\n \n /**\n * Process record data for storage\n * \n * Transforms a raw database record into the RecordData format used for file storage.\n * Handles field externalization, related entity pulling, and checksum calculation.\n * \n * @param record - Raw database record\n * @param primaryKey - Primary key fields and values \n * @param targetDir - Directory where files will be saved\n * @param entityConfig - Entity configuration with defaults and settings\n * @param syncEngine - Sync engine for checksum calculation\n * @param flags - Command flags\n * @param isNewRecord - Whether this is a new record\n * @param existingRecordData - Existing record data to preserve field selection\n * @param currentDepth - Current recursion depth for recursive entities\n * @param ancestryPath - Set of IDs in current ancestry chain to prevent circular references\n * @returns Promise resolving to formatted RecordData\n * @private\n */\n private async processRecordData(\n record: any, \n primaryKey: Record<string, any>,\n targetDir: string, \n entityConfig: any,\n syncEngine: SyncEngine,\n flags?: any,\n isNewRecord: boolean = true,\n existingRecordData?: RecordData,\n currentDepth: number = 0,\n ancestryPath: Set<string> = new Set()\n ): Promise<RecordData> {\n // Build record data - we'll restructure at the end for proper ordering\n const fields: Record<string, any> = {};\n const relatedEntities: Record<string, RecordData[]> = {};\n \n // Debug: Log all fields in first record (only in verbose mode)\n if (flags?.verbose) {\n const recordKeys = Object.keys(record);\n console.log('\\n=== DEBUG: Processing record ===');\n console.log('Entity:', entityConfig.entity);\n console.log('Total fields:', recordKeys.length);\n console.log('Field names:', recordKeys.filter(k => !k.startsWith('__mj_')).join(', '));\n console.log('Has TemplateText?:', recordKeys.includes('TemplateText'));\n console.log('externalizeFields config:', entityConfig.pull?.externalizeFields);\n }\n \n // Get the underlying data from the entity object\n // If it's an entity object, it will have a GetAll() method\n let dataToProcess = record;\n if (typeof record.GetAll === 'function') {\n // It's an entity object, get the underlying data\n dataToProcess = record.GetAll();\n }\n \n // Get externalize configuration for pattern lookup\n const externalizeConfig = entityConfig.pull?.externalizeFields;\n let externalizeMap = new Map<string, string | undefined>();\n \n if (externalizeConfig) {\n if (Array.isArray(externalizeConfig)) {\n if (externalizeConfig.length > 0 && typeof externalizeConfig[0] === 'string') {\n // Simple string array\n (externalizeConfig as string[]).forEach(f => externalizeMap.set(f, undefined));\n } else {\n // New pattern format\n (externalizeConfig as Array<{field: string; pattern: string}>).forEach(item => \n externalizeMap.set(item.field, item.pattern)\n );\n }\n } else {\n // Object format\n Object.keys(externalizeConfig).forEach(f => externalizeMap.set(f, undefined));\n }\n }\n \n // Process regular fields from the underlying data\n for (const [fieldName, fieldValue] of Object.entries(dataToProcess)) {\n // Skip primary key fields\n if (primaryKey[fieldName] !== undefined) {\n continue;\n }\n \n // Skip internal fields\n if (fieldName.startsWith('__mj_')) {\n continue;\n }\n \n // Skip excluded fields\n if (entityConfig.pull?.excludeFields?.includes(fieldName)) {\n continue;\n }\n \n // Skip fields already externalized\n if (fields[fieldName]) {\n continue;\n }\n \n // Skip virtual/computed fields - check entity metadata\n const metadata = new Metadata();\n const entityInfo = metadata.EntityByName(entityConfig.entity);\n \n \n if (entityInfo) {\n const fieldInfo = entityInfo.Fields.find(f => f.Name === fieldName);\n if (fieldInfo && !fieldInfo.IsVirtual) {\n // Field exists in metadata and is not virtual, keep it\n } else if (fieldInfo && fieldInfo.IsVirtual) {\n // Skip virtual fields\n continue;\n } else if (!fieldInfo) {\n // Field not in metadata at all\n // Check if it's explicitly configured for externalization, lookup, or exclusion\n const isConfiguredField = \n entityConfig.pull?.externalizeFields?.includes(fieldName) ||\n entityConfig.pull?.lookupFields?.[fieldName] ||\n entityConfig.pull?.excludeFields?.includes(fieldName);\n \n \n if (!isConfiguredField) {\n // Skip fields not in metadata and not explicitly configured\n continue;\n }\n // Otherwise, allow the field to be processed since it's explicitly configured\n }\n }\n \n // Check if this field should be converted to a lookup\n const lookupConfig = entityConfig.pull?.lookupFields?.[fieldName];\n if (lookupConfig && fieldValue) {\n // Convert foreign key to @lookup reference\n const lookupValue = await this.convertToLookup(\n fieldValue,\n lookupConfig.entity,\n lookupConfig.field,\n syncEngine\n );\n if (lookupValue) {\n fields[fieldName] = lookupValue;\n continue;\n }\n }\n \n // Check if this is an external file field\n if (await this.shouldExternalizeField(fieldName, fieldValue, entityConfig)) {\n // Check if this field is preserved and already has a @file: reference\n const isPreservedField = entityConfig.pull?.preserveFields?.includes(fieldName);\n const existingFieldValue = existingRecordData?.fields?.[fieldName];\n \n if (isPreservedField && existingFieldValue && typeof existingFieldValue === 'string' && existingFieldValue.startsWith('@file:')) {\n // Field is preserved and has existing @file: reference - update the existing file\n const existingFilePath = existingFieldValue.replace('@file:', '');\n const fullPath = path.join(targetDir, existingFilePath);\n \n // Ensure directory exists\n await fs.ensureDir(path.dirname(fullPath));\n \n // Write the content to the existing file path\n await fs.writeFile(fullPath, String(fieldValue), 'utf-8');\n \n // Keep the existing @file: reference\n fields[fieldName] = existingFieldValue;\n } else {\n // Normal externalization - create new file\n const pattern = externalizeMap.get(fieldName);\n const fileName = await this.createExternalFile(\n targetDir,\n record,\n primaryKey,\n fieldName,\n String(fieldValue),\n entityConfig,\n pattern\n );\n fields[fieldName] = fileName; // fileName already includes @file: prefix if pattern-based\n }\n } else {\n fields[fieldName] = fieldValue;\n }\n }\n \n // Now check for externalized fields that might be computed properties\n // We process ALL externalized fields, including those not in the data\n if (entityConfig.pull?.externalizeFields && typeof record.GetAll === 'function') {\n const externalizeConfig = entityConfig.pull.externalizeFields;\n \n // Normalize configuration to array format\n let externalizeItems: Array<{field: string; pattern?: string}> = [];\n if (Array.isArray(externalizeConfig)) {\n if (externalizeConfig.length > 0 && typeof externalizeConfig[0] === 'string') {\n // Simple string array\n externalizeItems = (externalizeConfig as string[]).map(f => ({field: f}));\n } else {\n // Already in the new format\n externalizeItems = externalizeConfig as Array<{field: string; pattern: string}>;\n }\n } else {\n // Object format\n externalizeItems = Object.entries(externalizeConfig).map(([field, config]) => ({\n field,\n pattern: undefined // Will use default pattern\n }));\n }\n \n // Get the keys from the underlying data to identify computed properties\n const dataKeys = Object.keys(dataToProcess);\n \n for (const externalItem of externalizeItems) {\n const externalField = externalItem.field;\n \n // Only process fields that are NOT in the underlying data\n // (these are likely computed properties)\n if (dataKeys.includes(externalField)) {\n continue; // This was already processed in the main loop\n }\n \n try {\n // Use bracket notation to access properties (including getters)\n const fieldValue = record[externalField];\n if (fieldValue !== undefined && fieldValue !== null && fieldValue !== '') {\n if (await this.shouldExternalizeField(externalField, fieldValue, entityConfig)) {\n // Check if this field is preserved and already has a @file: reference\n const isPreservedField = entityConfig.pull?.preserveFields?.includes(externalField);\n const existingFieldValue = existingRecordData?.fields?.[externalField];\n \n if (isPreservedField && existingFieldValue && typeof existingFieldValue === 'string' && existingFieldValue.startsWith('@file:')) {\n // Field is preserved and has existing @file: reference - update the existing file\n const existingFilePath = existingFieldValue.replace('@file:', '');\n const fullPath = path.join(targetDir, existingFilePath);\n \n // Ensure directory exists\n await fs.ensureDir(path.dirname(fullPath));\n \n // Write the content to the existing file path\n await fs.writeFile(fullPath, String(fieldValue), 'utf-8');\n \n // Keep the existing @file: reference\n fields[externalField] = existingFieldValue;\n } else {\n // Normal externalization - create new file\n const fileName = await this.createExternalFile(\n targetDir,\n record,\n primaryKey,\n externalField,\n String(fieldValue),\n entityConfig,\n externalItem.pattern\n );\n fields[externalField] = fileName; // fileName already includes @file: prefix if pattern-based\n }\n } else {\n // Include the field value if not externalized\n fields[externalField] = fieldValue;\n }\n }\n } catch (error) {\n // Property might not exist, that's okay\n if (flags?.verbose) {\n console.log(`Could not get property ${externalField}: ${error}`);\n }\n }\n }\n }\n \n // Pull related entities if configured\n if (entityConfig.pull?.relatedEntities) {\n const related = await this.pullRelatedEntities(\n record,\n entityConfig.pull.relatedEntities,\n syncEngine,\n entityConfig,\n flags,\n currentDepth,\n ancestryPath\n );\n Object.assign(relatedEntities, related);\n }\n \n // Get entity metadata to check defaults\n const metadata = new Metadata();\n const entityInfo = metadata.EntityByName(entityConfig.entity);\n \n // Filter out null values and fields matching their defaults\n const cleanedFields: Record<string, any> = {};\n \n // Get the set of fields that existed in the original record (if updating)\n const existingFieldNames = existingRecordData?.fields ? new Set(Object.keys(existingRecordData.fields)) : new Set<string>();\n \n for (const [fieldName, fieldValue] of Object.entries(fields)) {\n let includeField = false;\n \n if (!isNewRecord && existingFieldNames.has(fieldName)) {\n // For updates: Always preserve fields that existed in the original record\n includeField = true;\n } else {\n // For new records or new fields in existing records:\n // Skip null/undefined/empty string values\n if (fieldValue === null || fieldValue === undefined || fieldValue === '') {\n includeField = false;\n } else if (entityInfo) {\n // Check if value matches the field's default\n const fieldInfo = entityInfo.Fields.find(f => f.Name === fieldName);\n if (fieldInfo && fieldInfo.DefaultValue !== null && fieldInfo.DefaultValue !== undefined) {\n // Compare with default value\n if (fieldValue === fieldInfo.DefaultValue) {\n includeField = false;\n }\n // Special handling for boolean defaults (might be stored as strings)\n else if (typeof fieldValue === 'boolean' && \n (fieldInfo.DefaultValue === (fieldValue ? '1' : '0') || \n fieldInfo.DefaultValue === (fieldValue ? 'true' : 'false'))) {\n includeField = false;\n }\n // Special handling for numeric defaults that might be strings\n else if (typeof fieldValue === 'number' && String(fieldValue) === String(fieldInfo.DefaultValue)) {\n includeField = false;\n } else {\n includeField = true;\n }\n } else {\n // No default value defined, include if not null/empty\n includeField = true;\n }\n } else {\n // No entity info, include if not null/empty\n includeField = true;\n }\n }\n \n if (includeField) {\n cleanedFields[fieldName] = fieldValue;\n }\n }\n \n // Calculate checksum on cleaned fields\n const checksum = syncEngine.calculateChecksum(cleanedFields);\n \n // Build the final record data with proper ordering\n // Use a new object to ensure property order\n const recordData: RecordData = {} as RecordData;\n \n // 1. User fields first\n recordData.fields = cleanedFields;\n \n // 2. Related entities (if any)\n if (Object.keys(relatedEntities).length > 0) {\n recordData.relatedEntities = relatedEntities;\n }\n \n // 3. Primary key (system field)\n recordData.primaryKey = primaryKey;\n \n // 4. Sync metadata (system field)\n recordData.sync = {\n lastModified: new Date().toISOString(),\n checksum: checksum\n };\n \n return recordData;\n }\n \n /**\n * Convert a foreign key value to a @lookup reference\n * \n * Looks up the related record and creates a @lookup string that can be\n * resolved during push operations.\n * \n * @param foreignKeyValue - The foreign key value (ID)\n * @param targetEntity - Name of the target entity\n * @param targetField - Field in target entity to use for lookup\n * @param syncEngine - Sync engine instance\n * @returns @lookup string or null if lookup fails\n * @private\n */\n private async convertToLookup(\n foreignKeyValue: any,\n targetEntity: string,\n targetField: string,\n syncEngine: SyncEngine\n ): Promise<string | null> {\n try {\n // Get the related record\n const metadata = new Metadata();\n const targetEntityInfo = metadata.EntityByName(targetEntity);\n if (!targetEntityInfo) {\n this.warn(`Could not find entity ${targetEntity} for lookup`);\n return null;\n }\n \n // Load the related record\n const primaryKeyField = targetEntityInfo.PrimaryKeys?.[0]?.Name || 'ID';\n const rv = new RunView();\n const result = await rv.RunView({\n EntityName: targetEntity,\n ExtraFilter: `${primaryKeyField} = '${String(foreignKeyValue).replace(/'/g, \"''\")}'`,\n ResultType: 'entity_object'\n }, getSystemUser());\n \n if (!result.Success || result.Results.length === 0) {\n this.warn(`Could not find ${targetEntity} with ${primaryKeyField} = ${foreignKeyValue}`);\n return null;\n }\n \n const relatedRecord = result.Results[0];\n const lookupValue = relatedRecord[targetField];\n \n if (!lookupValue) {\n this.warn(`${targetEntity} record missing ${targetField} field`);\n return null;\n }\n \n // Return the @lookup reference\n return `@lookup:${targetEntity}.${targetField}=${lookupValue}`;\n } catch (error) {\n this.warn(`Failed to create lookup for ${targetEntity}: ${error}`);\n return null;\n }\n }\n \n /**\n * Determine if a field should be saved to an external file\n * \n * Checks if a field is configured for externalization or contains substantial\n * text content that would be better stored in a separate file.\n * \n * @param fieldName - Name of the field to check\n * @param fieldValue - Value of the field\n * @param entityConfig - Entity configuration with externalization settings\n * @returns Promise resolving to true if field should be externalized\n * @private\n */\n private async shouldExternalizeField(\n fieldName: string, \n fieldValue: any,\n entityConfig: any\n ): Promise<boolean> {\n \n // Only externalize string fields\n if (typeof fieldValue !== 'string') {\n return false;\n }\n \n // Check if field is configured for externalization\n const externalizeConfig = entityConfig.pull?.externalizeFields;\n if (!externalizeConfig) {\n return false;\n }\n \n if (Array.isArray(externalizeConfig)) {\n if (externalizeConfig.length > 0 && typeof externalizeConfig[0] === 'string') {\n // Simple string array\n return (externalizeConfig as string[]).includes(fieldName);\n } else {\n // New pattern format\n return (externalizeConfig as Array<{field: string; pattern: string}>)\n .some(item => item.field === fieldName);\n }\n } else {\n // Object format\n return fieldName in externalizeConfig;\n }\n }\n \n /**\n * Create an external file for a field value\n * \n * Saves large text content to a separate file and returns the filename.\n * Automatically determines appropriate file extension based on field name\n * and content type (e.g., .md for prompts, .html for templates).\n * Uses the entity's name field for the filename if available.\n * \n * @param targetDir - Directory to save the file\n * @param record - Full record to extract name field from\n * @param primaryKey - Primary key for filename generation fallback\n * @param fieldName - Name of the field being externalized\n * @param content - Content to write to the file\n * @param entityConfig - Entity configuration\n * @returns Promise resolving to the created filename\n * @private\n */\n private async createExternalFile(\n targetDir: string,\n record: any,\n primaryKey: Record<string, any>,\n fieldName: string,\n content: string,\n entityConfig: any,\n pattern?: string\n ): Promise<string> {\n // If pattern is provided, use it to generate the full path\n if (pattern) {\n // Replace placeholders in the pattern\n let resolvedPattern = pattern;\n \n // Get entity metadata for field lookups\n const metadata = new Metadata();\n const entityInfo = metadata.EntityByName(entityConfig.entity);\n \n // Replace {Name} with the entity's name field value\n if (entityInfo) {\n const nameField = entityInfo.Fields.find(f => f.IsNameField);\n if (nameField && record[nameField.Name]) {\n const nameValue = String(record[nameField.Name])\n .replace(/[^a-zA-Z0-9\\-_ ]/g, '') // Remove disallowed characters\n .replace(/\\s+/g, '-') // Replace spaces with -\n .toLowerCase(); // Make lowercase\n resolvedPattern = resolvedPattern.replace(/{Name}/g, nameValue);\n }\n }\n \n // Replace {ID} with the primary key\n const idValue = primaryKey.ID || Object.values(primaryKey)[0];\n if (idValue) {\n resolvedPattern = resolvedPattern.replace(/{ID}/g, String(idValue).toLowerCase());\n }\n \n // Replace {FieldName} with the current field name\n resolvedPattern = resolvedPattern.replace(/{FieldName}/g, fieldName.toLowerCase());\n \n // Replace any other {field} placeholders with field values from the record\n const placeholderRegex = /{(\\w+)}/g;\n resolvedPattern = resolvedPattern.replace(placeholderRegex, (match, fieldName) => {\n const value = record[fieldName];\n if (value !== undefined && value !== null) {\n return String(value)\n .replace(/[^a-zA-Z0-9\\-_ ]/g, '')\n .replace(/\\s+/g, '-')\n .toLowerCase();\n }\n return match; // Keep placeholder if field not found\n });\n \n // Extract the file path from the pattern\n const filePath = path.join(targetDir, resolvedPattern.replace('@file:', ''));\n \n // Ensure directory exists\n await fs.ensureDir(path.dirname(filePath));\n \n // Write the file\n await fs.writeFile(filePath, content, 'utf-8');\n \n // Return the pattern as-is (it includes @file: prefix)\n return resolvedPattern;\n }\n \n // Original logic for non-pattern based externalization\n let extension = '.md'; // default to markdown\n \n const externalizeConfig = entityConfig.pull?.externalizeFields;\n if (externalizeConfig && !Array.isArray(externalizeConfig) && externalizeConfig[fieldName]?.extension) {\n extension = externalizeConfig[fieldName].extension;\n // Ensure extension starts with a dot\n if (!extension.startsWith('.')) {\n extension = '.' + extension;\n }\n }\n \n // Try to use the entity's name field for the filename\n let baseFileName: string;\n \n // Get entity metadata to find the name field\n const metadata = new Metadata();\n const entityInfo = metadata.EntityByName(entityConfig.entity);\n \n if (entityInfo) {\n // Find the name field\n const nameField = entityInfo.Fields.find(f => f.IsNameField);\n if (nameField && record[nameField.Name]) {\n // Use the name field value, sanitized for filesystem\n const nameValue = String(record[nameField.Name]);\n // Remove disallowed characters (don't replace with _), replace spaces with -, and lowercase\n baseFileName = nameValue\n .replace(/[^a-zA-Z0-9\\-_ ]/g, '') // Remove disallowed characters\n .replace(/\\s+/g, '-') // Replace spaces with -\n .toLowerCase(); // Make lowercase\n } else {\n // Fallback to primary key\n baseFileName = this.buildFileName(primaryKey, null).replace('.json', '');\n }\n } else {\n // Fallback to primary key\n baseFileName = this.buildFileName(primaryKey, null).replace('.json', '');\n }\n \n // Remove dot prefix from baseFileName if it exists (it will be a dot-prefixed name from buildFileName)\n const cleanBaseFileName = baseFileName.startsWith('.') ? baseFileName.substring(1) : baseFileName;\n const fileName = `.${cleanBaseFileName}.${fieldName.toLowerCase()}${extension}`;\n const filePath = path.join(targetDir, fileName);\n \n await fs.writeFile(filePath, content, 'utf-8');\n \n return fileName;\n }\n \n /**\n * Build a filename from primary key values\n * \n * Creates a safe filename based on the entity's primary key values.\n * Handles GUIDs by using first 8 characters, sanitizes special characters,\n * and creates composite names for multi-field keys.\n * Files are prefixed with a dot to follow the metadata file convention.\n * \n * @param primaryKey - Primary key fields and values\n * @param entityConfig - Entity configuration (for future extension)\n * @returns Filename with .json extension\n * @private\n */\n private buildFileName(primaryKey: Record<string, any>, entityConfig: any): string {\n // Use primary key values to build filename\n const keys = Object.values(primaryKey);\n \n if (keys.length === 1 && typeof keys[0] === 'string') {\n // Single string key - use as base if it's a guid\n const key = keys[0];\n if (key.match(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i)) {\n // It's a GUID, use first 8 chars, prefixed with dot, lowercase\n return `.${key.substring(0, 8).toLowerCase()}.json`;\n }\n // Use the whole key if not too long, prefixed with dot\n if (key.length <= 50) {\n return `.${key.replace(/[^a-zA-Z0-9\\-_]/g, '').toLowerCase()}.json`;\n }\n }\n \n // Multiple keys or numeric - create composite name, prefixed with dot\n return '.' + keys.map(k => String(k).replace(/[^a-zA-Z0-9\\-_]/g, '').toLowerCase()).join('-') + '.json';\n }\n \n /**\n * Pull related entities for a parent record\n * \n * Retrieves child records that have foreign key relationships to the parent.\n * Converts foreign key values to @parent references and supports nested\n * related entities for deep object graphs.\n * NEW: Supports automatic recursive patterns for self-referencing entities.\n * \n * @param parentRecord - Parent entity record\n * @param relatedConfig - Configuration for related entities to pull\n * @param syncEngine - Sync engine instance\n * @param entityConfig - Entity configuration\n * @param flags - Command flags\n * @param currentDepth - Current recursion depth for recursive entities\n * @param ancestryPath - Set of IDs in current ancestry chain to prevent circular references\n * @returns Promise resolving to map of entity names to related records\n * @private\n */\n private async pullRelatedEntities(\n parentRecord: any,\n relatedConfig: Record<string, RelatedEntityConfig>,\n syncEngine: SyncEngine,\n entityConfig: any,\n flags?: any,\n currentDepth: number = 0,\n ancestryPath: Set<string> = new Set()\n ): Promise<Record<string, RecordData[]>> {\n const relatedEntities: Record<string, RecordData[]> = {};\n \n for (const [key, config] of Object.entries(relatedConfig)) {\n try {\n // Get entity metadata to find primary key\n const metadata = new Metadata();\n const parentEntity = metadata.EntityByName(entityConfig.entity);\n if (!parentEntity) {\n this.warn(`Could not find entity metadata for ${entityConfig.entity}`);\n continue;\n }\n \n // Get the parent's primary key value (usually ID)\n const primaryKeyField = parentEntity.PrimaryKeys?.[0]?.Name || 'ID';\n const parentKeyValue = parentRecord[primaryKeyField];\n if (!parentKeyValue) {\n this.warn(`Parent record missing primary key field ${primaryKeyField}`);\n continue;\n }\n \n // Build filter for related records\n // The foreignKey is the field in the CHILD entity that points to this parent\n let filter = `${config.foreignKey} = '${String(parentKeyValue).replace(/'/g, \"''\")}'`;\n if (config.filter) {\n filter += ` AND (${config.filter})`;\n }\n \n \n // Pull related records\n const rv = new RunView();\n const result = await rv.RunView({\n EntityName: config.entity,\n ExtraFilter: filter,\n ResultType: 'entity_object'\n }, getSystemUser());\n \n if (!result.Success) {\n this.warn(`Failed to pull related ${config.entity}: ${result.ErrorMessage}`);\n continue;\n }\n \n // Get child entity metadata\n const childEntity = metadata.EntityByName(config.entity);\n if (!childEntity) {\n this.warn(`Could not find entity metadata for ${config.entity}`);\n continue;\n }\n \n // Check if we need to wait for async property loading for related entities\n if (config.externalizeFields && result.Results.length > 0) {\n let fieldsToExternalize: string[] = [];\n \n if (Array.isArray(config.externalizeFields)) {\n if (config.externalizeFields.length > 0 && typeof config.externalizeFields[0] === 'string') {\n // Simple string array\n fieldsToExternalize = config.externalizeFields as string[];\n } else {\n // New pattern format\n fieldsToExternalize = (config.externalizeFields as Array<{field: string; pattern: string}>)\n .map(item => item.field);\n }\n } else {\n // Object format\n fieldsToExternalize = Object.keys(config.externalizeFields);\n }\n \n // Get all field names from entity metadata\n const metadataFieldNames = childEntity.Fields.map(f => f.Name);\n \n // Check if any externalized fields are NOT in metadata (likely computed properties)\n const computedFields = fieldsToExternalize.filter(f => !metadataFieldNames.includes(f));\n \n if (computedFields.length > 0) {\n console.log(`Waiting 5 seconds for async property loading in related entity ${config.entity} (${computedFields.join(', ')})...`);\n await new Promise(resolve => setTimeout(resolve, 5000));\n }\n }\n \n // Process each related record\n const relatedRecords: RecordData[] = [];\n \n if (flags?.verbose && result.Results.length > 0) {\n this.log(`Found ${result.Results.length} related ${config.entity} records at depth ${currentDepth}`);\n }\n \n for (const relatedRecord of result.Results) {\n // Build primary key for the related record\n const relatedPrimaryKey: Record<string, any> = {};\n for (const pk of childEntity.PrimaryKeys) {\n relatedPrimaryKey[pk.Name] = relatedRecord[pk.Name];\n }\n \n // Check for circular references in the current ancestry path\n const recordId = String(relatedPrimaryKey[childEntity.PrimaryKeys[0]?.Name || 'ID']);\n if (config.recursive && ancestryPath.has(recordId)) {\n if (flags?.verbose) {\n this.log(`Skipping circular reference for ${config.entity} with ID: ${recordId} (detected in ancestry path)`);\n }\n continue;\n }\n \n // Create new ancestry path for this branch (only track current hierarchy chain)\n const newAncestryPath = new Set(ancestryPath);\n if (config.recursive) {\n newAncestryPath.add(recordId);\n }\n \n // Determine related entities configuration for recursion\n let childRelatedConfig = config.relatedEntities;\n \n // If recursive is enabled, continue recursive fetching at child level\n if (config.recursive) {\n const maxDepth = config.maxDepth || 10;\n \n if (currentDepth < maxDepth) {\n // Create recursive configuration that references the same entity\n childRelatedConfig = {\n [key]: {\n ...config,\n // Keep same configuration but increment depth internally\n }\n };\n \n if (flags?.verbose) {\n this.log(`Processing recursive level ${currentDepth + 1} for ${config.entity} record ${recordId}`);\n }\n } else {\n // At max depth, don't recurse further\n childRelatedConfig = undefined;\n if (flags?.verbose) {\n this.log(`Max depth ${maxDepth} reached for recursive entity ${config.entity} at record ${recordId}`);\n }\n }\n }\n \n // Process the related record using the same logic as parent records\n const relatedData = await this.processRecordData(\n relatedRecord,\n relatedPrimaryKey,\n '', // Not used for related entities since we don't externalize their fields\n { \n entity: config.entity,\n pull: {\n excludeFields: config.excludeFields || entityConfig.pull?.excludeFields,\n lookupFields: config.lookupFields || entityConfig.pull?.lookupFields,\n externalizeFields: config.externalizeFields,\n relatedEntities: childRelatedConfig\n }\n },\n syncEngine,\n flags,\n true, // isNewRecord\n undefined, // existingRecordData\n currentDepth + 1,\n newAncestryPath\n );\n \n // Convert foreign key reference to @parent\n if (relatedData.fields[config.foreignKey]) {\n relatedData.fields[config.foreignKey] = `@parent:${primaryKeyField}`;\n }\n \n // The processRecordData method already filters nulls and defaults\n // No need to do it again here\n \n relatedRecords.push(relatedData);\n }\n \n if (relatedRecords.length > 0) {\n relatedEntities[key] = relatedRecords;\n }\n } catch (error) {\n this.warn(`Error pulling related ${key}: ${error}`);\n }\n }\n \n return relatedEntities;\n }\n \n /**\n * Find which field in the parent record contains a specific value\n * \n * Used to convert foreign key references to @parent references by finding\n * the parent field that contains the foreign key value. Typically finds\n * the primary key field but can match any field.\n * \n * @param parentRecord - Parent record to search\n * @param value - Value to search for\n * @returns Field name containing the value, or null if not found\n * @private\n */\n private findParentField(parentRecord: any, value: any): string | null {\n // Find which field in the parent contains this value\n // Typically this will be the primary key field\n for (const [fieldName, fieldValue] of Object.entries(parentRecord)) {\n if (fieldValue === value && !fieldName.startsWith('__mj_')) {\n return fieldName;\n }\n }\n return null;\n }\n \n /**\n * Find existing files in a directory matching a pattern\n * \n * Searches for files that match the configured file pattern, used to identify\n * which records already exist locally for smart update functionality.\n * \n * @param dir - Directory to search in\n * @param pattern - Glob pattern to match files (e.g., \"*.json\")\n * @returns Promise resolving to array of file paths\n * @private\n */\n private async findExistingFiles(dir: string, pattern: string): Promise<string[]> {\n const files: string[] = [];\n \n try {\n const entries = await fs.readdir(dir, { withFileTypes: true });\n \n for (const entry of entries) {\n if (entry.isFile()) {\n const fileName = entry.name;\n \n // Simple pattern matching - could be enhanced with proper glob support\n if (pattern === '*.json' && fileName.endsWith('.json')) {\n files.push(path.join(dir, fileName));\n } else if (pattern === '.*.json' && fileName.startsWith('.') && fileName.endsWith('.json')) {\n // Handle dot-prefixed JSON files\n files.push(path.join(dir, fileName));\n } else if (pattern === fileName) {\n files.push(path.join(dir, fileName));\n }\n // TODO: Add more sophisticated glob pattern matching if needed\n }\n }\n } catch (error) {\n // Directory might not exist yet\n if ((error as any).code !== 'ENOENT') {\n throw error;\n }\n }\n \n return files;\n }\n \n /**\n * Load existing records from files and build a lookup map\n * \n * Reads all existing files and creates a map from primary key to file location,\n * enabling efficient lookup during the update process.\n * \n * @param files - Array of file paths to load\n * @param entityInfo - Entity metadata for primary key information\n * @returns Map from primary key string to file info\n * @private\n */\n private async loadExistingRecords(\n files: string[], \n entityInfo: EntityInfo\n ): Promise<Map<string, { filePath: string; recordData: RecordData }>> {\n const recordsMap = new Map<string, { filePath: string; recordData: RecordData }>();\n \n for (const filePath of files) {\n try {\n const fileData = await fs.readJson(filePath);\n const records = Array.isArray(fileData) ? fileData : [fileData];\n \n for (const record of records) {\n if (record.primaryKey) {\n const lookupKey = this.createPrimaryKeyLookup(record.primaryKey);\n recordsMap.set(lookupKey, { filePath, recordData: record });\n }\n }\n } catch (error) {\n // Skip files that can't be parsed\n this.warn(`Could not load file ${filePath}: ${error}`);\n }\n }\n \n return recordsMap;\n }\n \n /**\n * Create a string lookup key from primary key values\n * \n * Generates a consistent string representation of primary key values\n * for use in maps and comparisons.\n * \n * @param primaryKey - Primary key field names and values\n * @returns String representation of the primary key\n * @private\n */\n private createPrimaryKeyLookup(primaryKey: Record<string, any>): string {\n const keys = Object.keys(primaryKey).sort();\n return keys.map(k => `${k}:${primaryKey[k]}`).join('|');\n }\n \n /**\n * Merge two record data objects based on configured strategy\n * \n * Combines existing and new record data according to the merge strategy:\n * - 'overwrite': Replace all fields with new values\n * - 'merge': Combine fields, with new values taking precedence\n * - 'skip': Keep existing record unchanged\n * \n * @param existing - Existing record data\n * @param newData - New record data from database\n * @param strategy - Merge strategy to apply\n * @param preserveFields - Field names that should never be overwritten\n * @returns Merged record data\n * @private\n */\n private async mergeRecords(\n existing: RecordData,\n newData: RecordData,\n strategy: 'overwrite' | 'merge' | 'skip',\n preserveFields: string[]\n ): Promise<RecordData> {\n if (strategy === 'skip') {\n return existing;\n }\n \n if (strategy === 'overwrite') {\n // Build with proper ordering\n const result: RecordData = {} as RecordData;\n \n // 1. Fields first\n result.fields = { ...newData.fields };\n \n // Restore preserved fields from existing\n if (preserveFields.length > 0 && existing.fields) {\n for (const field of preserveFields) {\n if (field in existing.fields) {\n result.fields[field] = existing.fields[field];\n }\n }\n }\n \n // 2. Related entities (if any)\n if (newData.relatedEntities) {\n result.relatedEntities = newData.relatedEntities;\n }\n \n // 3. Primary key\n result.primaryKey = newData.primaryKey;\n \n // 4. Sync metadata\n result.sync = newData.sync;\n \n return result;\n }\n \n // Default 'merge' strategy\n // Build with proper ordering\n const result: RecordData = {} as RecordData;\n \n // 1. Fields first\n result.fields = { ...existing.fields, ...newData.fields };\n \n // Restore preserved fields\n if (preserveFields.length > 0 && existing.fields) {\n for (const field of preserveFields) {\n if (field in existing.fields) {\n result.fields[field] = existing.fields[field];\n }\n }\n }\n \n // 2. Related entities (if any)\n if (existing.relatedEntities || newData.relatedEntities) {\n result.relatedEntities = {\n ...existing.relatedEntities,\n ...newData.relatedEntities\n };\n }\n \n // 3. Primary key\n result.primaryKey = newData.primaryKey || existing.primaryKey;\n \n // 4. Sync metadata\n result.sync = newData.sync;\n \n return result;\n }\n \n /**\n * Create a backup of a file before updating\n * \n * Creates a timestamped backup copy of the file in a backup directory\n * with the original filename, timestamp suffix, and .backup extension.\n * The backup directory defaults to .backups but can be configured.\n * \n * @param filePath - Path to the file to backup\n * @param backupDirName - Name of the backup directory (optional)\n * @returns Promise that resolves when backup is created\n * @private\n */\n private async createBackup(filePath: string, backupDirName?: string): Promise<void> {\n const dir = path.dirname(filePath);\n const fileName = path.basename(filePath);\n const backupDir = path.join(dir, backupDirName || '.backups');\n \n // Ensure backup directory exists\n await fs.ensureDir(backupDir);\n \n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n // Remove .json extension, add timestamp, then add .backup extension\n const backupFileName = fileName.replace(/\\.json$/, `.${timestamp}.backup`);\n const backupPath = path.join(backupDir, backupFileName);\n \n try {\n await fs.copy(filePath, backupPath);\n } catch (error) {\n this.warn(`Could not create backup of ${filePath}: ${error}`);\n }\n }\n}"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/pull/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Pull command implementation for MetadataSync\n * @module commands/pull\n * \n * This module implements the pull command which retrieves metadata records from\n * the MemberJunction database and saves them as local JSON files. It supports:\n * - Filtering records with SQL expressions\n * - Pulling related entities with foreign key relationships\n * - Externalizing large text fields to separate files\n * - Creating multi-record JSON files\n * - Recursive directory search for entity configurations\n */\n\nimport { Command, Flags } from '@oclif/core';\nimport fs from 'fs-extra';\nimport path from 'path';\nimport { select } from '@inquirer/prompts';\nimport ora from 'ora-classic';\nimport { loadMJConfig, loadEntityConfig, RelatedEntityConfig } from '../../config';\nimport { SyncEngine, RecordData } from '../../lib/sync-engine';\nimport { RunView, Metadata, EntityInfo } from '@memberjunction/core';\nimport { getSystemUser, initializeProvider } from '../../lib/provider-utils';\nimport { configManager } from '../../lib/config-manager';\nimport { getSyncEngine, resetSyncEngine } from '../../lib/singleton-manager';\nimport chalk from 'chalk';\n\n/**\n * Pull metadata records from database to local files\n * \n * @class Pull\n * @extends Command\n * \n * @example\n * ```bash\n * # Pull all records for an entity\n * mj-sync pull --entity=\"AI Prompts\"\n * \n * # Pull with filter\n * mj-sync pull --entity=\"AI Prompts\" --filter=\"CategoryID='123'\"\n * \n * # Pull to multi-record file\n * mj-sync pull --entity=\"AI Prompts\" --multi-file=\"all-prompts.json\"\n * ```\n */\nexport default class Pull extends Command {\n static description = 'Pull metadata from database to local files';\n \n static examples = [\n `<%= config.bin %> <%= command.id %> --entity=\"AI Prompts\"`,\n `<%= config.bin %> <%= command.id %> --entity=\"AI Prompts\" --filter=\"CategoryID='customer-service-id'\"`,\n ];\n \n static flags = {\n entity: Flags.string({ description: 'Entity name to pull', required: true }),\n filter: Flags.string({ description: 'Additional filter for pulling specific records' }),\n 'dry-run': Flags.boolean({ description: 'Show what would be pulled without actually pulling' }),\n 'multi-file': Flags.string({ description: 'Create a single file with multiple records (provide filename)' }),\n verbose: Flags.boolean({ char: 'v', description: 'Show detailed output' }),\n 'no-validate': Flags.boolean({ description: 'Skip validation before pull' }),\n };\n \n async run(): Promise<void> {\n const { flags } = await this.parse(Pull);\n const spinner = ora();\n \n try {\n // Load MJ config first (before changing directory)\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 // Stop spinner before provider initialization (which logs to console)\n spinner.stop();\n \n // Initialize data provider\n const provider = await initializeProvider(mjConfig);\n \n // Get singleton sync engine\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 // 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 validationResult = await validator.validateDirectory(configManager.getOriginalCwd());\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 // Ask for confirmation\n const shouldContinue = await select({\n message: 'Validation failed with errors. Do you want to continue anyway?',\n choices: [\n { name: 'No, fix the errors first', value: false },\n { name: 'Yes, continue anyway', value: true }\n ],\n default: false\n });\n \n if (!shouldContinue) {\n this.error('Pull cancelled due to validation errors.');\n }\n }\n } else {\n this.log(chalk.green('✓ Validation passed'));\n }\n }\n \n let targetDir: string;\n let entityConfig: any;\n \n // Check if we should use a specific target directory\n const envTargetDir = process.env.METADATA_SYNC_TARGET_DIR;\n if (envTargetDir) {\n if (flags.verbose) {\n console.log(`Using specified target directory: ${envTargetDir}`);\n }\n process.chdir(envTargetDir);\n targetDir = process.cwd();\n \n // Load entity config from the current directory\n entityConfig = await loadEntityConfig(targetDir);\n if (!entityConfig) {\n this.error(`No .mj-sync.json found in ${targetDir}`);\n }\n if (entityConfig.entity !== flags.entity) {\n this.error(`Directory ${targetDir} is configured for entity \"${entityConfig.entity}\", not \"${flags.entity}\"`);\n }\n } else {\n // Original behavior - find entity directory\n const entityDirs = await this.findEntityDirectories(flags.entity);\n \n if (entityDirs.length === 0) {\n this.error(`No directory found for entity \"${flags.entity}\". Run \"mj-sync init\" first.`);\n }\n \n if (entityDirs.length === 1) {\n targetDir = entityDirs[0];\n } else {\n // Multiple directories found, ask user\n targetDir = await select({\n message: `Multiple directories found for entity \"${flags.entity}\". Which one to use?`,\n choices: entityDirs.map(dir => ({ name: dir, value: dir }))\n });\n }\n \n entityConfig = await loadEntityConfig(targetDir);\n if (!entityConfig) {\n this.error(`Invalid entity configuration in ${targetDir}`);\n }\n }\n \n // Show configuration notice only if relevant and in verbose mode\n if (flags.verbose && entityConfig.pull?.appendRecordsToExistingFile && entityConfig.pull?.newFileName) {\n const targetFile = path.join(targetDir, entityConfig.pull.newFileName.endsWith('.json') \n ? entityConfig.pull.newFileName \n : `${entityConfig.pull.newFileName}.json`);\n \n if (await fs.pathExists(targetFile)) {\n // File exists - inform about append behavior\n this.log(`\\n📝 Configuration: New records will be appended to existing file '${path.basename(targetFile)}'`);\n }\n // If file doesn't exist, no need to mention anything special - we're just creating it\n }\n \n // Pull records\n spinner.start(`Pulling ${flags.entity} records`);\n const rv = new RunView();\n \n let filter = '';\n if (flags.filter) {\n filter = flags.filter;\n } else if (entityConfig.pull?.filter) {\n filter = entityConfig.pull.filter;\n }\n \n const result = await rv.RunView({\n EntityName: flags.entity,\n ExtraFilter: filter,\n ResultType: 'entity_object'\n }, getSystemUser());\n \n if (!result.Success) {\n this.error(`Failed to pull records: ${result.ErrorMessage}`);\n }\n \n spinner.succeed(`Found ${result.Results.length} records`);\n \n if (flags['dry-run']) {\n this.log(`\\nDry run mode - would pull ${result.Results.length} records to ${targetDir}`);\n return;\n }\n \n // Check if we need to wait for async property loading\n if (entityConfig.pull?.externalizeFields && result.Results.length > 0) {\n const metadata = new Metadata();\n const entityInfo = metadata.EntityByName(flags.entity);\n if (entityInfo) {\n const externalizeConfig = entityConfig.pull.externalizeFields;\n let fieldsToExternalize: string[] = [];\n \n if (Array.isArray(externalizeConfig)) {\n if (externalizeConfig.length > 0 && typeof externalizeConfig[0] === 'string') {\n // Simple string array\n fieldsToExternalize = externalizeConfig as string[];\n } else {\n // New pattern format\n fieldsToExternalize = (externalizeConfig as Array<{field: string; pattern: string}>)\n .map(item => item.field);\n }\n } else {\n // Object format\n fieldsToExternalize = Object.keys(externalizeConfig);\n }\n \n // Get all field names from entity metadata\n const metadataFieldNames = entityInfo.Fields.map(f => f.Name);\n \n // Check if any externalized fields are NOT in metadata (likely computed properties)\n const computedFields = fieldsToExternalize.filter(f => !metadataFieldNames.includes(f));\n \n if (computedFields.length > 0) {\n if (flags.verbose) {\n spinner.start(`Waiting 5 seconds for async property loading in ${flags.entity} (${computedFields.join(', ')})...`);\n }\n await new Promise(resolve => setTimeout(resolve, 5000));\n if (flags.verbose) {\n spinner.succeed('Async property loading wait complete');\n } else {\n spinner.stop();\n }\n }\n }\n }\n \n // Process each record\n const entityInfo = syncEngine.getEntityInfo(flags.entity);\n if (!entityInfo) {\n this.error(`Entity information not found for: ${flags.entity}`);\n }\n \n spinner.start('Processing records');\n let processed = 0;\n let updated = 0;\n let created = 0;\n let skipped = 0;\n \n // If multi-file flag is set, collect all records\n if (flags['multi-file']) {\n const allRecords: RecordData[] = [];\n \n for (const record of result.Results) {\n try {\n // Build primary key\n const primaryKey: Record<string, any> = {};\n for (const pk of entityInfo.PrimaryKeys) {\n primaryKey[pk.Name] = record[pk.Name];\n }\n \n // Process record for multi-file\n const recordData = await this.processRecordData(record, primaryKey, targetDir, entityConfig, syncEngine, flags, true);\n allRecords.push(recordData);\n processed++;\n \n if (flags.verbose) {\n spinner.text = `Processing records (${processed}/${result.Results.length})`;\n }\n } catch (error) {\n this.warn(`Failed to process record: ${(error as any).message || error}`);\n }\n }\n \n // Write all records to single file\n if (allRecords.length > 0) {\n const fileName = flags['multi-file'].endsWith('.json') ? flags['multi-file'] : `${flags['multi-file']}.json`;\n const filePath = path.join(targetDir, fileName);\n await fs.writeJson(filePath, allRecords, { spaces: 2 });\n spinner.succeed(`Pulled ${processed} records to ${path.basename(filePath)}`);\n }\n } else {\n // Smart update logic for single-file-per-record\n if (flags.verbose) {\n spinner.text = 'Scanning for existing files...';\n }\n \n // Find existing files\n const filePattern = entityConfig.pull?.filePattern || entityConfig.filePattern || '*.json';\n const existingFiles = await this.findExistingFiles(targetDir, filePattern);\n \n if (flags.verbose) {\n this.log(`Found ${existingFiles.length} existing files matching pattern '${filePattern}'`);\n existingFiles.forEach(f => this.log(` - ${path.basename(f)}`));\n }\n \n // Load existing records and build lookup map\n const existingRecordsMap = await this.loadExistingRecords(existingFiles, entityInfo);\n \n if (flags.verbose) {\n this.log(`Loaded ${existingRecordsMap.size} existing records from files`);\n }\n \n // Separate records into new and existing\n const newRecords: Array<{ record: any; primaryKey: Record<string, any> }> = [];\n const existingRecordsToUpdate: Array<{ record: any; primaryKey: Record<string, any>; filePath: string }> = [];\n \n for (const record of result.Results) {\n // Build primary key\n const primaryKey: Record<string, any> = {};\n for (const pk of entityInfo.PrimaryKeys) {\n primaryKey[pk.Name] = record[pk.Name];\n }\n \n // Create lookup key\n const lookupKey = this.createPrimaryKeyLookup(primaryKey);\n const existingFileInfo = existingRecordsMap.get(lookupKey);\n \n if (existingFileInfo) {\n // Record exists locally\n if (entityConfig.pull?.updateExistingRecords !== false) {\n existingRecordsToUpdate.push({ record, primaryKey, filePath: existingFileInfo.filePath });\n } else {\n skipped++;\n if (flags.verbose) {\n this.log(`Skipping existing record: ${lookupKey}`);\n }\n }\n } else {\n // Record doesn't exist locally\n if (entityConfig.pull?.createNewFileIfNotFound !== false) {\n newRecords.push({ record, primaryKey });\n } else {\n skipped++;\n if (flags.verbose) {\n this.log(`Skipping new record (createNewFileIfNotFound=false): ${lookupKey}`);\n }\n }\n }\n }\n \n // Track which files have been backed up to avoid duplicates\n const backedUpFiles = new Set<string>();\n \n // Process existing records updates\n for (const { record, primaryKey, filePath } of existingRecordsToUpdate) {\n try {\n spinner.text = `Updating existing records (${updated + 1}/${existingRecordsToUpdate.length})`;\n \n // Create backup if configured (only once per file)\n if (entityConfig.pull?.backupBeforeUpdate && !backedUpFiles.has(filePath)) {\n await this.createBackup(filePath, entityConfig.pull?.backupDirectory);\n backedUpFiles.add(filePath);\n }\n \n // Load existing file data\n const existingData = await fs.readJson(filePath);\n \n // Find the specific existing record that matches this primary key\n let existingRecordData: RecordData;\n if (Array.isArray(existingData)) {\n // Find the matching record in the array\n const matchingRecord = existingData.find(r => \n this.createPrimaryKeyLookup(r.primaryKey || {}) === this.createPrimaryKeyLookup(primaryKey)\n );\n existingRecordData = matchingRecord || existingData[0]; // Fallback to first if not found\n } else {\n existingRecordData = existingData;\n }\n \n // Process the new record data (isNewRecord = false for updates)\n const newRecordData = await this.processRecordData(record, primaryKey, targetDir, entityConfig, syncEngine, flags, false, existingRecordData);\n \n // Apply merge strategy\n const mergedData = await this.mergeRecords(\n existingRecordData,\n newRecordData,\n entityConfig.pull?.mergeStrategy || 'merge',\n entityConfig.pull?.preserveFields || []\n );\n \n // Write updated data\n if (Array.isArray(existingData)) {\n // Update the record in the array\n const index = existingData.findIndex(r => \n this.createPrimaryKeyLookup(r.primaryKey || {}) === this.createPrimaryKeyLookup(primaryKey)\n );\n if (index >= 0) {\n existingData[index] = mergedData;\n await fs.writeJson(filePath, existingData, { spaces: 2 });\n }\n } else {\n await fs.writeJson(filePath, mergedData, { spaces: 2 });\n }\n \n updated++;\n processed++;\n \n if (flags.verbose) {\n this.log(`Updated: ${filePath}`);\n }\n } catch (error) {\n this.warn(`Failed to update record: ${(error as any).message || error}`);\n }\n }\n \n // Process new records\n if (newRecords.length > 0) {\n spinner.text = `Creating new records (0/${newRecords.length})`;\n \n if (entityConfig.pull?.appendRecordsToExistingFile && entityConfig.pull?.newFileName) {\n // Append all new records to a single file\n const fileName = entityConfig.pull.newFileName.endsWith('.json') \n ? entityConfig.pull.newFileName \n : `${entityConfig.pull.newFileName}.json`;\n const filePath = path.join(targetDir, fileName);\n \n // Load existing file if it exists\n let existingData: RecordData[] = [];\n if (await fs.pathExists(filePath)) {\n const fileData = await fs.readJson(filePath);\n existingData = Array.isArray(fileData) ? fileData : [fileData];\n }\n \n // Process and append all new records\n for (const { record, primaryKey } of newRecords) {\n try {\n // For new records, pass isNewRecord = true (default)\n const recordData = await this.processRecordData(record, primaryKey, targetDir, entityConfig, syncEngine, flags, true);\n existingData.push(recordData);\n created++;\n processed++;\n \n if (flags.verbose) {\n spinner.text = `Creating new records (${created}/${newRecords.length})`;\n }\n } catch (error) {\n this.warn(`Failed to process new record: ${(error as any).message || error}`);\n }\n }\n \n // Write the combined data\n await fs.writeJson(filePath, existingData, { spaces: 2 });\n \n if (flags.verbose) {\n this.log(`Appended ${created} new records to: ${filePath}`);\n }\n } else {\n // Create individual files for each new record\n for (const { record, primaryKey } of newRecords) {\n try {\n await this.processRecord(record, primaryKey, targetDir, entityConfig, syncEngine, flags);\n created++;\n processed++;\n \n if (flags.verbose) {\n spinner.text = `Creating new records (${created}/${newRecords.length})`;\n }\n } catch (error) {\n this.warn(`Failed to process new record: ${(error as any).message || error}`);\n }\n }\n }\n }\n \n // Final status\n const statusParts = [`Processed ${processed} records`];\n if (updated > 0) statusParts.push(`updated ${updated}`);\n if (created > 0) statusParts.push(`created ${created}`);\n if (skipped > 0) statusParts.push(`skipped ${skipped}`);\n \n spinner.succeed(statusParts.join(', '));\n }\n \n } catch (error) {\n spinner.fail('Pull failed');\n \n // Enhanced error logging for debugging\n this.log('\\n=== Pull 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(`- Entity: ${flags.entity || 'not specified'}`);\n this.log(`- Filter: ${flags.filter || 'none'}`);\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('No directory found for entity')) {\n this.log(`\\nHint: This appears to be an entity directory configuration issue.`);\n this.log(`Run \"mj-sync init\" to create directories or ensure .mj-sync.json files exist.`);\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('Failed to pull records')) {\n this.log(`\\nHint: This appears to be a database query issue.`);\n this.log(`Check if the entity name \"${flags.entity}\" is correct and exists in the database.`);\n } else if (errorMessage.includes('Entity information not found')) {\n this.log(`\\nHint: The entity \"${flags.entity}\" was not found in metadata.`);\n this.log(`Check the entity name spelling and ensure it exists in the database.`);\n }\n \n this.error(error as Error);\n } finally {\n // Reset singletons\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 /**\n * Find directories containing configuration for the specified entity\n * \n * Recursively searches the current working directory for .mj-sync.json files\n * that specify the given entity name. Returns all matching directories to\n * allow user selection when multiple locations exist.\n * \n * @param entityName - Name of the entity to search for\n * @returns Promise resolving to array of directory paths\n * @private\n */\n private async findEntityDirectories(entityName: string): Promise<string[]> {\n const dirs: string[] = [];\n \n // Search for directories with matching entity config\n const searchDirs = async (dir: string) => {\n const entries = await fs.readdir(dir, { withFileTypes: true });\n \n for (const entry of entries) {\n if (entry.isDirectory()) {\n const fullPath = path.join(dir, entry.name);\n const config = await loadEntityConfig(fullPath);\n \n if (config && config.entity === entityName) {\n dirs.push(fullPath);\n } else {\n // Recurse\n await searchDirs(fullPath);\n }\n }\n }\n };\n \n await searchDirs(configManager.getOriginalCwd());\n return dirs;\n }\n \n /**\n * Process a single record and save to file\n * \n * Converts a database record into the file format and writes it to disk.\n * This is a wrapper around processRecordData that handles file writing.\n * \n * @param record - Raw database record\n * @param primaryKey - Primary key fields and values\n * @param targetDir - Directory to save the file\n * @param entityConfig - Entity configuration with pull settings\n * @param syncEngine - Sync engine instance\n * @returns Promise that resolves when file is written\n * @private\n */\n private async processRecord(\n record: any, \n primaryKey: Record<string, any>,\n targetDir: string, \n entityConfig: any,\n syncEngine: SyncEngine,\n flags: any\n ): Promise<void> {\n const recordData = await this.processRecordData(record, primaryKey, targetDir, entityConfig, syncEngine, flags, true);\n \n // Determine file path\n const fileName = this.buildFileName(primaryKey, entityConfig);\n const filePath = path.join(targetDir, fileName);\n \n // Write JSON file\n await fs.writeJson(filePath, recordData, { spaces: 2 });\n }\n \n /**\n * Process record data for storage\n * \n * Transforms a raw database record into the RecordData format used for file storage.\n * Handles field externalization, related entity pulling, and checksum calculation.\n * \n * @param record - Raw database record\n * @param primaryKey - Primary key fields and values \n * @param targetDir - Directory where files will be saved\n * @param entityConfig - Entity configuration with defaults and settings\n * @param syncEngine - Sync engine for checksum calculation\n * @param flags - Command flags\n * @param isNewRecord - Whether this is a new record\n * @param existingRecordData - Existing record data to preserve field selection\n * @param currentDepth - Current recursion depth for recursive entities\n * @param ancestryPath - Set of IDs in current ancestry chain to prevent circular references\n * @returns Promise resolving to formatted RecordData\n * @private\n */\n private async processRecordData(\n record: any, \n primaryKey: Record<string, any>,\n targetDir: string, \n entityConfig: any,\n syncEngine: SyncEngine,\n flags?: any,\n isNewRecord: boolean = true,\n existingRecordData?: RecordData,\n currentDepth: number = 0,\n ancestryPath: Set<string> = new Set()\n ): Promise<RecordData> {\n // Build record data - we'll restructure at the end for proper ordering\n const fields: Record<string, any> = {};\n const relatedEntities: Record<string, RecordData[]> = {};\n \n // Debug: Log all fields in first record (only in verbose mode)\n if (flags?.verbose) {\n const recordKeys = Object.keys(record);\n console.log('\\n=== DEBUG: Processing record ===');\n console.log('Entity:', entityConfig.entity);\n console.log('Total fields:', recordKeys.length);\n console.log('Field names:', recordKeys.filter(k => !k.startsWith('__mj_')).join(', '));\n console.log('Has TemplateText?:', recordKeys.includes('TemplateText'));\n console.log('externalizeFields config:', entityConfig.pull?.externalizeFields);\n }\n \n // Get the underlying data from the entity object\n // If it's an entity object, it will have a GetAll() method\n let dataToProcess = record;\n if (typeof record.GetAll === 'function') {\n // It's an entity object, get the underlying data\n dataToProcess = record.GetAll();\n }\n \n // Get externalize configuration for pattern lookup\n const externalizeConfig = entityConfig.pull?.externalizeFields;\n let externalizeMap = new Map<string, string | undefined>();\n \n if (externalizeConfig) {\n if (Array.isArray(externalizeConfig)) {\n if (externalizeConfig.length > 0 && typeof externalizeConfig[0] === 'string') {\n // Simple string array\n (externalizeConfig as string[]).forEach(f => externalizeMap.set(f, undefined));\n } else {\n // New pattern format\n (externalizeConfig as Array<{field: string; pattern: string}>).forEach(item => \n externalizeMap.set(item.field, item.pattern)\n );\n }\n } else {\n // Object format\n Object.keys(externalizeConfig).forEach(f => externalizeMap.set(f, undefined));\n }\n }\n \n // Process regular fields from the underlying data\n for (const [fieldName, fieldValue] of Object.entries(dataToProcess)) {\n // Skip primary key fields\n if (primaryKey[fieldName] !== undefined) {\n continue;\n }\n \n // Skip internal fields\n if (fieldName.startsWith('__mj_')) {\n continue;\n }\n \n // Skip excluded fields\n if (entityConfig.pull?.excludeFields?.includes(fieldName)) {\n continue;\n }\n \n // Skip fields already externalized\n if (fields[fieldName]) {\n continue;\n }\n \n // Skip virtual/computed fields - check entity metadata\n const metadata = new Metadata();\n const entityInfo = metadata.EntityByName(entityConfig.entity);\n \n \n if (entityInfo) {\n const fieldInfo = entityInfo.Fields.find(f => f.Name === fieldName);\n if (fieldInfo && !fieldInfo.IsVirtual) {\n // Field exists in metadata and is not virtual, keep it\n } else if (fieldInfo && fieldInfo.IsVirtual) {\n // Skip virtual fields\n continue;\n } else if (!fieldInfo) {\n // Field not in metadata at all\n // Check if it's explicitly configured for externalization, lookup, or exclusion\n const isConfiguredField = \n entityConfig.pull?.externalizeFields?.includes(fieldName) ||\n entityConfig.pull?.lookupFields?.[fieldName] ||\n entityConfig.pull?.excludeFields?.includes(fieldName);\n \n \n if (!isConfiguredField) {\n // Skip fields not in metadata and not explicitly configured\n continue;\n }\n // Otherwise, allow the field to be processed since it's explicitly configured\n }\n }\n \n // Check if this field should be converted to a lookup\n const lookupConfig = entityConfig.pull?.lookupFields?.[fieldName];\n if (lookupConfig && fieldValue) {\n // Convert foreign key to @lookup reference\n const lookupValue = await this.convertToLookup(\n fieldValue,\n lookupConfig.entity,\n lookupConfig.field,\n syncEngine\n );\n if (lookupValue) {\n fields[fieldName] = lookupValue;\n continue;\n }\n }\n \n // Check if this is an external file field\n if (await this.shouldExternalizeField(fieldName, fieldValue, entityConfig)) {\n // Check if this field is preserved and already has a @file: reference\n const isPreservedField = entityConfig.pull?.preserveFields?.includes(fieldName);\n const existingFieldValue = existingRecordData?.fields?.[fieldName];\n \n if (isPreservedField && existingFieldValue && typeof existingFieldValue === 'string' && existingFieldValue.startsWith('@file:')) {\n // Field is preserved and has existing @file: reference - update the existing file\n const existingFilePath = existingFieldValue.replace('@file:', '');\n const fullPath = path.join(targetDir, existingFilePath);\n \n // Ensure directory exists\n await fs.ensureDir(path.dirname(fullPath));\n \n // Write the content to the existing file path\n await fs.writeFile(fullPath, String(fieldValue), 'utf-8');\n \n // Keep the existing @file: reference\n fields[fieldName] = existingFieldValue;\n } else {\n // Normal externalization - create new file\n const pattern = externalizeMap.get(fieldName);\n const fileName = await this.createExternalFile(\n targetDir,\n record,\n primaryKey,\n fieldName,\n String(fieldValue),\n entityConfig,\n pattern\n );\n fields[fieldName] = fileName; // fileName already includes @file: prefix if pattern-based\n }\n } else {\n fields[fieldName] = fieldValue;\n }\n }\n \n // Now check for externalized fields that might be computed properties\n // We process ALL externalized fields, including those not in the data\n if (entityConfig.pull?.externalizeFields && typeof record.GetAll === 'function') {\n const externalizeConfig = entityConfig.pull.externalizeFields;\n \n // Normalize configuration to array format\n let externalizeItems: Array<{field: string; pattern?: string}> = [];\n if (Array.isArray(externalizeConfig)) {\n if (externalizeConfig.length > 0 && typeof externalizeConfig[0] === 'string') {\n // Simple string array\n externalizeItems = (externalizeConfig as string[]).map(f => ({field: f}));\n } else {\n // Already in the new format\n externalizeItems = externalizeConfig as Array<{field: string; pattern: string}>;\n }\n } else {\n // Object format\n externalizeItems = Object.entries(externalizeConfig).map(([field, config]) => ({\n field,\n pattern: undefined // Will use default pattern\n }));\n }\n \n // Get the keys from the underlying data to identify computed properties\n const dataKeys = Object.keys(dataToProcess);\n \n for (const externalItem of externalizeItems) {\n const externalField = externalItem.field;\n \n // Only process fields that are NOT in the underlying data\n // (these are likely computed properties)\n if (dataKeys.includes(externalField)) {\n continue; // This was already processed in the main loop\n }\n \n try {\n // Use bracket notation to access properties (including getters)\n const fieldValue = record[externalField];\n if (fieldValue !== undefined && fieldValue !== null && fieldValue !== '') {\n if (await this.shouldExternalizeField(externalField, fieldValue, entityConfig)) {\n // Check if this field is preserved and already has a @file: reference\n const isPreservedField = entityConfig.pull?.preserveFields?.includes(externalField);\n const existingFieldValue = existingRecordData?.fields?.[externalField];\n \n if (isPreservedField && existingFieldValue && typeof existingFieldValue === 'string' && existingFieldValue.startsWith('@file:')) {\n // Field is preserved and has existing @file: reference - update the existing file\n const existingFilePath = existingFieldValue.replace('@file:', '');\n const fullPath = path.join(targetDir, existingFilePath);\n \n // Ensure directory exists\n await fs.ensureDir(path.dirname(fullPath));\n \n // Write the content to the existing file path\n await fs.writeFile(fullPath, String(fieldValue), 'utf-8');\n \n // Keep the existing @file: reference\n fields[externalField] = existingFieldValue;\n } else {\n // Normal externalization - create new file\n const fileName = await this.createExternalFile(\n targetDir,\n record,\n primaryKey,\n externalField,\n String(fieldValue),\n entityConfig,\n externalItem.pattern\n );\n fields[externalField] = fileName; // fileName already includes @file: prefix if pattern-based\n }\n } else {\n // Include the field value if not externalized\n fields[externalField] = fieldValue;\n }\n }\n } catch (error) {\n // Property might not exist, that's okay\n if (flags?.verbose) {\n console.log(`Could not get property ${externalField}: ${error}`);\n }\n }\n }\n }\n \n // Pull related entities if configured\n if (entityConfig.pull?.relatedEntities) {\n const related = await this.pullRelatedEntities(\n record,\n entityConfig.pull.relatedEntities,\n syncEngine,\n entityConfig,\n flags,\n currentDepth,\n ancestryPath\n );\n Object.assign(relatedEntities, related);\n }\n \n // Get entity metadata to check defaults\n const metadata = new Metadata();\n const entityInfo = metadata.EntityByName(entityConfig.entity);\n \n // Filter out null values and fields matching their defaults\n const cleanedFields: Record<string, any> = {};\n \n // Get the set of fields that existed in the original record (if updating)\n const existingFieldNames = existingRecordData?.fields ? new Set(Object.keys(existingRecordData.fields)) : new Set<string>();\n \n for (const [fieldName, fieldValue] of Object.entries(fields)) {\n let includeField = false;\n \n if (!isNewRecord && existingFieldNames.has(fieldName)) {\n // For updates: Always preserve fields that existed in the original record\n includeField = true;\n } else {\n // For new records or new fields in existing records:\n // Skip null/undefined/empty string values\n if (fieldValue === null || fieldValue === undefined || fieldValue === '') {\n includeField = false;\n } else if (entityInfo) {\n // Check if value matches the field's default\n const fieldInfo = entityInfo.Fields.find(f => f.Name === fieldName);\n if (fieldInfo && fieldInfo.DefaultValue !== null && fieldInfo.DefaultValue !== undefined) {\n // Compare with default value\n if (fieldValue === fieldInfo.DefaultValue) {\n includeField = false;\n }\n // Special handling for boolean defaults (might be stored as strings)\n else if (typeof fieldValue === 'boolean' && \n (fieldInfo.DefaultValue === (fieldValue ? '1' : '0') || \n fieldInfo.DefaultValue === (fieldValue ? 'true' : 'false'))) {\n includeField = false;\n }\n // Special handling for numeric defaults that might be strings\n else if (typeof fieldValue === 'number' && String(fieldValue) === String(fieldInfo.DefaultValue)) {\n includeField = false;\n } else {\n includeField = true;\n }\n } else {\n // No default value defined, include if not null/empty\n includeField = true;\n }\n } else {\n // No entity info, include if not null/empty\n includeField = true;\n }\n }\n \n if (includeField) {\n cleanedFields[fieldName] = fieldValue;\n }\n }\n \n // Calculate checksum on cleaned fields\n const checksum = syncEngine.calculateChecksum(cleanedFields);\n \n // Build the final record data with proper ordering\n // Use a new object to ensure property order\n const recordData: RecordData = {} as RecordData;\n \n // 1. User fields first\n recordData.fields = cleanedFields;\n \n // 2. Related entities (if any)\n if (Object.keys(relatedEntities).length > 0) {\n recordData.relatedEntities = relatedEntities;\n }\n \n // 3. Primary key (system field)\n recordData.primaryKey = primaryKey;\n \n // 4. Sync metadata (system field)\n recordData.sync = {\n lastModified: new Date().toISOString(),\n checksum: checksum\n };\n \n return recordData;\n }\n \n /**\n * Convert a foreign key value to a @lookup reference\n * \n * Looks up the related record and creates a @lookup string that can be\n * resolved during push operations.\n * \n * @param foreignKeyValue - The foreign key value (ID)\n * @param targetEntity - Name of the target entity\n * @param targetField - Field in target entity to use for lookup\n * @param syncEngine - Sync engine instance\n * @returns @lookup string or null if lookup fails\n * @private\n */\n private async convertToLookup(\n foreignKeyValue: any,\n targetEntity: string,\n targetField: string,\n syncEngine: SyncEngine\n ): Promise<string | null> {\n try {\n // Get the related record\n const metadata = new Metadata();\n const targetEntityInfo = metadata.EntityByName(targetEntity);\n if (!targetEntityInfo) {\n this.warn(`Could not find entity ${targetEntity} for lookup`);\n return null;\n }\n \n // Load the related record\n const primaryKeyField = targetEntityInfo.PrimaryKeys?.[0]?.Name || 'ID';\n const rv = new RunView();\n const result = await rv.RunView({\n EntityName: targetEntity,\n ExtraFilter: `${primaryKeyField} = '${String(foreignKeyValue).replace(/'/g, \"''\")}'`,\n ResultType: 'entity_object'\n }, getSystemUser());\n \n if (!result.Success || result.Results.length === 0) {\n this.warn(`Could not find ${targetEntity} with ${primaryKeyField} = ${foreignKeyValue}`);\n return null;\n }\n \n const relatedRecord = result.Results[0];\n const lookupValue = relatedRecord[targetField];\n \n if (!lookupValue) {\n this.warn(`${targetEntity} record missing ${targetField} field`);\n return null;\n }\n \n // Return the @lookup reference\n return `@lookup:${targetEntity}.${targetField}=${lookupValue}`;\n } catch (error) {\n this.warn(`Failed to create lookup for ${targetEntity}: ${error}`);\n return null;\n }\n }\n \n /**\n * Determine if a field should be saved to an external file\n * \n * Checks if a field is configured for externalization or contains substantial\n * text content that would be better stored in a separate file.\n * \n * @param fieldName - Name of the field to check\n * @param fieldValue - Value of the field\n * @param entityConfig - Entity configuration with externalization settings\n * @returns Promise resolving to true if field should be externalized\n * @private\n */\n private async shouldExternalizeField(\n fieldName: string, \n fieldValue: any,\n entityConfig: any\n ): Promise<boolean> {\n \n // Only externalize string fields\n if (typeof fieldValue !== 'string') {\n return false;\n }\n \n // Check if field is configured for externalization\n const externalizeConfig = entityConfig.pull?.externalizeFields;\n if (!externalizeConfig) {\n return false;\n }\n \n if (Array.isArray(externalizeConfig)) {\n if (externalizeConfig.length > 0 && typeof externalizeConfig[0] === 'string') {\n // Simple string array\n return (externalizeConfig as string[]).includes(fieldName);\n } else {\n // New pattern format\n return (externalizeConfig as Array<{field: string; pattern: string}>)\n .some(item => item.field === fieldName);\n }\n } else {\n // Object format\n return fieldName in externalizeConfig;\n }\n }\n \n /**\n * Create an external file for a field value\n * \n * Saves large text content to a separate file and returns the filename.\n * Automatically determines appropriate file extension based on field name\n * and content type (e.g., .md for prompts, .html for templates).\n * Uses the entity's name field for the filename if available.\n * \n * @param targetDir - Directory to save the file\n * @param record - Full record to extract name field from\n * @param primaryKey - Primary key for filename generation fallback\n * @param fieldName - Name of the field being externalized\n * @param content - Content to write to the file\n * @param entityConfig - Entity configuration\n * @returns Promise resolving to the created filename\n * @private\n */\n private async createExternalFile(\n targetDir: string,\n record: any,\n primaryKey: Record<string, any>,\n fieldName: string,\n content: string,\n entityConfig: any,\n pattern?: string\n ): Promise<string> {\n // If pattern is provided, use it to generate the full path\n if (pattern) {\n // Replace placeholders in the pattern\n let resolvedPattern = pattern;\n \n // Get entity metadata for field lookups\n const metadata = new Metadata();\n const entityInfo = metadata.EntityByName(entityConfig.entity);\n \n // Replace {Name} with the entity's name field value\n if (entityInfo) {\n const nameField = entityInfo.Fields.find(f => f.IsNameField);\n if (nameField && record[nameField.Name]) {\n const nameValue = String(record[nameField.Name])\n .replace(/[^a-zA-Z0-9\\-_ ]/g, '') // Remove disallowed characters\n .replace(/\\s+/g, '-') // Replace spaces with -\n .toLowerCase(); // Make lowercase\n resolvedPattern = resolvedPattern.replace(/{Name}/g, nameValue);\n }\n }\n \n // Replace {ID} with the primary key\n const idValue = primaryKey.ID || Object.values(primaryKey)[0];\n if (idValue) {\n resolvedPattern = resolvedPattern.replace(/{ID}/g, String(idValue).toLowerCase());\n }\n \n // Replace {FieldName} with the current field name\n resolvedPattern = resolvedPattern.replace(/{FieldName}/g, fieldName.toLowerCase());\n \n // Replace any other {field} placeholders with field values from the record\n const placeholderRegex = /{(\\w+)}/g;\n resolvedPattern = resolvedPattern.replace(placeholderRegex, (match, fieldName) => {\n const value = record[fieldName];\n if (value !== undefined && value !== null) {\n return String(value)\n .replace(/[^a-zA-Z0-9\\-_ ]/g, '')\n .replace(/\\s+/g, '-')\n .toLowerCase();\n }\n return match; // Keep placeholder if field not found\n });\n \n // Extract the file path from the pattern\n const filePath = path.join(targetDir, resolvedPattern.replace('@file:', ''));\n \n // Ensure directory exists\n await fs.ensureDir(path.dirname(filePath));\n \n // Write the file\n await fs.writeFile(filePath, content, 'utf-8');\n \n // Return the pattern as-is (it includes @file: prefix)\n return resolvedPattern;\n }\n \n // Original logic for non-pattern based externalization\n let extension = '.md'; // default to markdown\n \n const externalizeConfig = entityConfig.pull?.externalizeFields;\n if (externalizeConfig && !Array.isArray(externalizeConfig) && externalizeConfig[fieldName]?.extension) {\n extension = externalizeConfig[fieldName].extension;\n // Ensure extension starts with a dot\n if (!extension.startsWith('.')) {\n extension = '.' + extension;\n }\n }\n \n // Try to use the entity's name field for the filename\n let baseFileName: string;\n \n // Get entity metadata to find the name field\n const metadata = new Metadata();\n const entityInfo = metadata.EntityByName(entityConfig.entity);\n \n if (entityInfo) {\n // Find the name field\n const nameField = entityInfo.Fields.find(f => f.IsNameField);\n if (nameField && record[nameField.Name]) {\n // Use the name field value, sanitized for filesystem\n const nameValue = String(record[nameField.Name]);\n // Remove disallowed characters (don't replace with _), replace spaces with -, and lowercase\n baseFileName = nameValue\n .replace(/[^a-zA-Z0-9\\-_ ]/g, '') // Remove disallowed characters\n .replace(/\\s+/g, '-') // Replace spaces with -\n .toLowerCase(); // Make lowercase\n } else {\n // Fallback to primary key\n baseFileName = this.buildFileName(primaryKey, null).replace('.json', '');\n }\n } else {\n // Fallback to primary key\n baseFileName = this.buildFileName(primaryKey, null).replace('.json', '');\n }\n \n // Remove dot prefix from baseFileName if it exists (it will be a dot-prefixed name from buildFileName)\n const cleanBaseFileName = baseFileName.startsWith('.') ? baseFileName.substring(1) : baseFileName;\n const fileName = `.${cleanBaseFileName}.${fieldName.toLowerCase()}${extension}`;\n const filePath = path.join(targetDir, fileName);\n \n await fs.writeFile(filePath, content, 'utf-8');\n \n return fileName;\n }\n \n /**\n * Build a filename from primary key values\n * \n * Creates a safe filename based on the entity's primary key values.\n * Handles GUIDs by using first 8 characters, sanitizes special characters,\n * and creates composite names for multi-field keys.\n * Files are prefixed with a dot to follow the metadata file convention.\n * \n * @param primaryKey - Primary key fields and values\n * @param entityConfig - Entity configuration (for future extension)\n * @returns Filename with .json extension\n * @private\n */\n private buildFileName(primaryKey: Record<string, any>, entityConfig: any): string {\n // Use primary key values to build filename\n const keys = Object.values(primaryKey);\n \n if (keys.length === 1 && typeof keys[0] === 'string') {\n // Single string key - use as base if it's a guid\n const key = keys[0];\n if (key.match(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i)) {\n // It's a GUID, use first 8 chars, prefixed with dot, lowercase\n return `.${key.substring(0, 8).toLowerCase()}.json`;\n }\n // Use the whole key if not too long, prefixed with dot\n if (key.length <= 50) {\n return `.${key.replace(/[^a-zA-Z0-9\\-_]/g, '').toLowerCase()}.json`;\n }\n }\n \n // Multiple keys or numeric - create composite name, prefixed with dot\n return '.' + keys.map(k => String(k).replace(/[^a-zA-Z0-9\\-_]/g, '').toLowerCase()).join('-') + '.json';\n }\n \n /**\n * Pull related entities for a parent record\n * \n * Retrieves child records that have foreign key relationships to the parent.\n * Converts foreign key values to @parent references and supports nested\n * related entities for deep object graphs.\n * NEW: Supports automatic recursive patterns for self-referencing entities.\n * \n * @param parentRecord - Parent entity record\n * @param relatedConfig - Configuration for related entities to pull\n * @param syncEngine - Sync engine instance\n * @param entityConfig - Entity configuration\n * @param flags - Command flags\n * @param currentDepth - Current recursion depth for recursive entities\n * @param ancestryPath - Set of IDs in current ancestry chain to prevent circular references\n * @returns Promise resolving to map of entity names to related records\n * @private\n */\n private async pullRelatedEntities(\n parentRecord: any,\n relatedConfig: Record<string, RelatedEntityConfig>,\n syncEngine: SyncEngine,\n entityConfig: any,\n flags?: any,\n currentDepth: number = 0,\n ancestryPath: Set<string> = new Set()\n ): Promise<Record<string, RecordData[]>> {\n const relatedEntities: Record<string, RecordData[]> = {};\n \n for (const [key, config] of Object.entries(relatedConfig)) {\n try {\n // Get entity metadata to find primary key\n const metadata = new Metadata();\n const parentEntity = metadata.EntityByName(entityConfig.entity);\n if (!parentEntity) {\n this.warn(`Could not find entity metadata for ${entityConfig.entity}`);\n continue;\n }\n \n // Get the parent's primary key value (usually ID)\n const primaryKeyField = parentEntity.PrimaryKeys?.[0]?.Name || 'ID';\n const parentKeyValue = parentRecord[primaryKeyField];\n if (!parentKeyValue) {\n this.warn(`Parent record missing primary key field ${primaryKeyField}`);\n continue;\n }\n \n // Build filter for related records\n // The foreignKey is the field in the CHILD entity that points to this parent\n let filter = `${config.foreignKey} = '${String(parentKeyValue).replace(/'/g, \"''\")}'`;\n if (config.filter) {\n filter += ` AND (${config.filter})`;\n }\n \n \n // Pull related records\n const rv = new RunView();\n const result = await rv.RunView({\n EntityName: config.entity,\n ExtraFilter: filter,\n ResultType: 'entity_object'\n }, getSystemUser());\n \n if (!result.Success) {\n this.warn(`Failed to pull related ${config.entity}: ${result.ErrorMessage}`);\n continue;\n }\n \n // Get child entity metadata\n const childEntity = metadata.EntityByName(config.entity);\n if (!childEntity) {\n this.warn(`Could not find entity metadata for ${config.entity}`);\n continue;\n }\n \n // Check if we need to wait for async property loading for related entities\n if (config.externalizeFields && result.Results.length > 0) {\n let fieldsToExternalize: string[] = [];\n \n if (Array.isArray(config.externalizeFields)) {\n if (config.externalizeFields.length > 0 && typeof config.externalizeFields[0] === 'string') {\n // Simple string array\n fieldsToExternalize = config.externalizeFields as string[];\n } else {\n // New pattern format\n fieldsToExternalize = (config.externalizeFields as Array<{field: string; pattern: string}>)\n .map(item => item.field);\n }\n } else {\n // Object format\n fieldsToExternalize = Object.keys(config.externalizeFields);\n }\n \n // Get all field names from entity metadata\n const metadataFieldNames = childEntity.Fields.map(f => f.Name);\n \n // Check if any externalized fields are NOT in metadata (likely computed properties)\n const computedFields = fieldsToExternalize.filter(f => !metadataFieldNames.includes(f));\n \n if (computedFields.length > 0) {\n if (flags?.verbose) {\n console.log(`Waiting 5 seconds for async property loading in related entity ${config.entity} (${computedFields.join(', ')})...`);\n }\n await new Promise(resolve => setTimeout(resolve, 5000));\n }\n }\n \n // Process each related record\n const relatedRecords: RecordData[] = [];\n \n if (flags?.verbose && result.Results.length > 0) {\n this.log(`Found ${result.Results.length} related ${config.entity} records at depth ${currentDepth}`);\n }\n \n for (const relatedRecord of result.Results) {\n // Build primary key for the related record\n const relatedPrimaryKey: Record<string, any> = {};\n for (const pk of childEntity.PrimaryKeys) {\n relatedPrimaryKey[pk.Name] = relatedRecord[pk.Name];\n }\n \n // Check for circular references in the current ancestry path\n const recordId = String(relatedPrimaryKey[childEntity.PrimaryKeys[0]?.Name || 'ID']);\n if (config.recursive && ancestryPath.has(recordId)) {\n if (flags?.verbose) {\n this.log(`Skipping circular reference for ${config.entity} with ID: ${recordId} (detected in ancestry path)`);\n }\n continue;\n }\n \n // Create new ancestry path for this branch (only track current hierarchy chain)\n const newAncestryPath = new Set(ancestryPath);\n if (config.recursive) {\n newAncestryPath.add(recordId);\n }\n \n // Determine related entities configuration for recursion\n let childRelatedConfig = config.relatedEntities;\n \n // If recursive is enabled, continue recursive fetching at child level\n if (config.recursive) {\n const maxDepth = config.maxDepth || 10;\n \n if (currentDepth < maxDepth) {\n // Create recursive configuration that references the same entity\n childRelatedConfig = {\n [key]: {\n ...config,\n // Keep same configuration but increment depth internally\n }\n };\n \n if (flags?.verbose) {\n this.log(`Processing recursive level ${currentDepth + 1} for ${config.entity} record ${recordId}`);\n }\n } else {\n // At max depth, don't recurse further\n childRelatedConfig = undefined;\n if (flags?.verbose) {\n this.log(`Max depth ${maxDepth} reached for recursive entity ${config.entity} at record ${recordId}`);\n }\n }\n }\n \n // Process the related record using the same logic as parent records\n const relatedData = await this.processRecordData(\n relatedRecord,\n relatedPrimaryKey,\n '', // Not used for related entities since we don't externalize their fields\n { \n entity: config.entity,\n pull: {\n excludeFields: config.excludeFields || entityConfig.pull?.excludeFields,\n lookupFields: config.lookupFields || entityConfig.pull?.lookupFields,\n externalizeFields: config.externalizeFields,\n relatedEntities: childRelatedConfig\n }\n },\n syncEngine,\n flags,\n true, // isNewRecord\n undefined, // existingRecordData\n currentDepth + 1,\n newAncestryPath\n );\n \n // Convert foreign key reference to @parent\n if (relatedData.fields[config.foreignKey]) {\n relatedData.fields[config.foreignKey] = `@parent:${primaryKeyField}`;\n }\n \n // The processRecordData method already filters nulls and defaults\n // No need to do it again here\n \n relatedRecords.push(relatedData);\n }\n \n if (relatedRecords.length > 0) {\n relatedEntities[key] = relatedRecords;\n }\n } catch (error) {\n this.warn(`Error pulling related ${key}: ${error}`);\n }\n }\n \n return relatedEntities;\n }\n \n /**\n * Find which field in the parent record contains a specific value\n * \n * Used to convert foreign key references to @parent references by finding\n * the parent field that contains the foreign key value. Typically finds\n * the primary key field but can match any field.\n * \n * @param parentRecord - Parent record to search\n * @param value - Value to search for\n * @returns Field name containing the value, or null if not found\n * @private\n */\n private findParentField(parentRecord: any, value: any): string | null {\n // Find which field in the parent contains this value\n // Typically this will be the primary key field\n for (const [fieldName, fieldValue] of Object.entries(parentRecord)) {\n if (fieldValue === value && !fieldName.startsWith('__mj_')) {\n return fieldName;\n }\n }\n return null;\n }\n \n /**\n * Find existing files in a directory matching a pattern\n * \n * Searches for files that match the configured file pattern, used to identify\n * which records already exist locally for smart update functionality.\n * \n * @param dir - Directory to search in\n * @param pattern - Glob pattern to match files (e.g., \"*.json\")\n * @returns Promise resolving to array of file paths\n * @private\n */\n private async findExistingFiles(dir: string, pattern: string): Promise<string[]> {\n const files: string[] = [];\n \n try {\n const entries = await fs.readdir(dir, { withFileTypes: true });\n \n for (const entry of entries) {\n if (entry.isFile()) {\n const fileName = entry.name;\n \n // Simple pattern matching - could be enhanced with proper glob support\n if (pattern === '*.json' && fileName.endsWith('.json')) {\n files.push(path.join(dir, fileName));\n } else if (pattern === '.*.json' && fileName.startsWith('.') && fileName.endsWith('.json')) {\n // Handle dot-prefixed JSON files\n files.push(path.join(dir, fileName));\n } else if (pattern === fileName) {\n files.push(path.join(dir, fileName));\n }\n // TODO: Add more sophisticated glob pattern matching if needed\n }\n }\n } catch (error) {\n // Directory might not exist yet\n if ((error as any).code !== 'ENOENT') {\n throw error;\n }\n }\n \n return files;\n }\n \n /**\n * Load existing records from files and build a lookup map\n * \n * Reads all existing files and creates a map from primary key to file location,\n * enabling efficient lookup during the update process.\n * \n * @param files - Array of file paths to load\n * @param entityInfo - Entity metadata for primary key information\n * @returns Map from primary key string to file info\n * @private\n */\n private async loadExistingRecords(\n files: string[], \n entityInfo: EntityInfo\n ): Promise<Map<string, { filePath: string; recordData: RecordData }>> {\n const recordsMap = new Map<string, { filePath: string; recordData: RecordData }>();\n \n for (const filePath of files) {\n try {\n const fileData = await fs.readJson(filePath);\n const records = Array.isArray(fileData) ? fileData : [fileData];\n \n for (const record of records) {\n if (record.primaryKey) {\n const lookupKey = this.createPrimaryKeyLookup(record.primaryKey);\n recordsMap.set(lookupKey, { filePath, recordData: record });\n }\n }\n } catch (error) {\n // Skip files that can't be parsed\n this.warn(`Could not load file ${filePath}: ${error}`);\n }\n }\n \n return recordsMap;\n }\n \n /**\n * Create a string lookup key from primary key values\n * \n * Generates a consistent string representation of primary key values\n * for use in maps and comparisons.\n * \n * @param primaryKey - Primary key field names and values\n * @returns String representation of the primary key\n * @private\n */\n private createPrimaryKeyLookup(primaryKey: Record<string, any>): string {\n const keys = Object.keys(primaryKey).sort();\n return keys.map(k => `${k}:${primaryKey[k]}`).join('|');\n }\n \n /**\n * Merge two record data objects based on configured strategy\n * \n * Combines existing and new record data according to the merge strategy:\n * - 'overwrite': Replace all fields with new values\n * - 'merge': Combine fields, with new values taking precedence\n * - 'skip': Keep existing record unchanged\n * \n * @param existing - Existing record data\n * @param newData - New record data from database\n * @param strategy - Merge strategy to apply\n * @param preserveFields - Field names that should never be overwritten\n * @returns Merged record data\n * @private\n */\n private async mergeRecords(\n existing: RecordData,\n newData: RecordData,\n strategy: 'overwrite' | 'merge' | 'skip',\n preserveFields: string[]\n ): Promise<RecordData> {\n if (strategy === 'skip') {\n return existing;\n }\n \n if (strategy === 'overwrite') {\n // Build with proper ordering\n const result: RecordData = {} as RecordData;\n \n // 1. Fields first\n result.fields = { ...newData.fields };\n \n // Restore preserved fields from existing\n if (preserveFields.length > 0 && existing.fields) {\n for (const field of preserveFields) {\n if (field in existing.fields) {\n result.fields[field] = existing.fields[field];\n }\n }\n }\n \n // 2. Related entities (if any)\n if (newData.relatedEntities) {\n result.relatedEntities = newData.relatedEntities;\n }\n \n // 3. Primary key\n result.primaryKey = newData.primaryKey;\n \n // 4. Sync metadata\n result.sync = newData.sync;\n \n return result;\n }\n \n // Default 'merge' strategy\n // Build with proper ordering\n const result: RecordData = {} as RecordData;\n \n // 1. Fields first\n result.fields = { ...existing.fields, ...newData.fields };\n \n // Restore preserved fields\n if (preserveFields.length > 0 && existing.fields) {\n for (const field of preserveFields) {\n if (field in existing.fields) {\n result.fields[field] = existing.fields[field];\n }\n }\n }\n \n // 2. Related entities (if any)\n if (existing.relatedEntities || newData.relatedEntities) {\n result.relatedEntities = {\n ...existing.relatedEntities,\n ...newData.relatedEntities\n };\n }\n \n // 3. Primary key\n result.primaryKey = newData.primaryKey || existing.primaryKey;\n \n // 4. Sync metadata\n result.sync = newData.sync;\n \n return result;\n }\n \n /**\n * Create a backup of a file before updating\n * \n * Creates a timestamped backup copy of the file in a backup directory\n * with the original filename, timestamp suffix, and .backup extension.\n * The backup directory defaults to .backups but can be configured.\n * \n * @param filePath - Path to the file to backup\n * @param backupDirName - Name of the backup directory (optional)\n * @returns Promise that resolves when backup is created\n * @private\n */\n private async createBackup(filePath: string, backupDirName?: string): Promise<void> {\n const dir = path.dirname(filePath);\n const fileName = path.basename(filePath);\n const backupDir = path.join(dir, backupDirName || '.backups');\n \n // Ensure backup directory exists\n await fs.ensureDir(backupDir);\n \n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n // Remove .json extension, add timestamp, then add .backup extension\n const backupFileName = fileName.replace(/\\.json$/, `.${timestamp}.backup`);\n const backupPath = path.join(backupDir, backupFileName);\n \n try {\n await fs.copy(filePath, backupPath);\n } catch (error) {\n this.warn(`Could not create backup of ${filePath}: ${error}`);\n }\n }\n}"]}
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import { Command } from '@oclif/core';
|
|
2
2
|
export default class Push extends Command {
|
|
3
3
|
static description: string;
|
|
4
|
+
private warnings;
|
|
5
|
+
private errors;
|
|
4
6
|
static examples: string[];
|
|
5
7
|
static flags: {
|
|
6
8
|
dir: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
7
9
|
'dry-run': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
8
10
|
ci: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
9
11
|
verbose: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
12
|
+
'no-validate': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
10
13
|
};
|
|
14
|
+
warn(input: string | Error): string | Error;
|
|
11
15
|
run(): Promise<void>;
|
|
12
16
|
private processEntityDirectory;
|
|
13
17
|
private processJsonFiles;
|