@memberjunction/metadata-sync 2.67.0 → 2.68.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 +57 -0
- package/dist/config.d.ts +4 -0
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/EntityPropertyExtractor.d.ts +60 -0
- package/dist/lib/EntityPropertyExtractor.js +166 -0
- package/dist/lib/EntityPropertyExtractor.js.map +1 -0
- package/dist/lib/FieldExternalizer.d.ts +62 -0
- package/dist/lib/FieldExternalizer.js +177 -0
- package/dist/lib/FieldExternalizer.js.map +1 -0
- package/dist/lib/RecordProcessor.d.ts +82 -0
- package/dist/lib/RecordProcessor.js +309 -0
- package/dist/lib/RecordProcessor.js.map +1 -0
- package/dist/lib/RelatedEntityHandler.d.ts +75 -0
- package/dist/lib/RelatedEntityHandler.js +273 -0
- package/dist/lib/RelatedEntityHandler.js.map +1 -0
- package/dist/lib/file-write-batch.d.ts +61 -0
- package/dist/lib/file-write-batch.js +180 -0
- package/dist/lib/file-write-batch.js.map +1 -0
- package/dist/lib/json-write-helper.d.ts +39 -0
- package/dist/lib/json-write-helper.js +105 -0
- package/dist/lib/json-write-helper.js.map +1 -0
- package/dist/services/FileResetService.js +2 -1
- package/dist/services/FileResetService.js.map +1 -1
- package/dist/services/PullService.d.ts +22 -2
- package/dist/services/PullService.js +268 -173
- package/dist/services/PullService.js.map +1 -1
- package/dist/services/PushService.js +3 -2
- package/dist/services/PushService.js.map +1 -1
- package/dist/services/WatchService.js +3 -2
- package/dist/services/WatchService.js.map +1 -1
- package/package.json +7 -7
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { JsonWriteOptions } from 'fs-extra';
|
|
2
|
+
import { RecordData } from './sync-engine';
|
|
3
|
+
/**
|
|
4
|
+
* Helper class for writing JSON files with consistent property ordering for RecordData objects.
|
|
5
|
+
* Ensures that all metadata files have the same property order: fields, relatedEntities, primaryKey, sync
|
|
6
|
+
*/
|
|
7
|
+
export declare class JsonWriteHelper {
|
|
8
|
+
/**
|
|
9
|
+
* Write RecordData or arrays of RecordData with consistent property ordering
|
|
10
|
+
* @param filePath - Path to the JSON file to write
|
|
11
|
+
* @param data - RecordData object or array of RecordData objects
|
|
12
|
+
*/
|
|
13
|
+
static writeOrderedRecordData(filePath: string, data: RecordData | RecordData[]): Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* Recursively normalize RecordData objects to ensure correct property ordering
|
|
16
|
+
* @param data - RecordData object, array of RecordData objects, or any nested structure
|
|
17
|
+
* @returns Normalized data with consistent property ordering
|
|
18
|
+
*/
|
|
19
|
+
private static normalizeRecordDataOrder;
|
|
20
|
+
/**
|
|
21
|
+
* Create a RecordData object with explicit property ordering for consistent JSON output
|
|
22
|
+
* @param fields - Entity field data
|
|
23
|
+
* @param relatedEntities - Related entity data
|
|
24
|
+
* @param primaryKey - Primary key data
|
|
25
|
+
* @param sync - Sync metadata
|
|
26
|
+
* @returns RecordData object with guaranteed property order
|
|
27
|
+
*/
|
|
28
|
+
static createOrderedRecordData(fields: Record<string, any>, relatedEntities: Record<string, RecordData[]>, primaryKey: Record<string, any>, sync: {
|
|
29
|
+
lastModified: string;
|
|
30
|
+
checksum: string;
|
|
31
|
+
}): RecordData;
|
|
32
|
+
/**
|
|
33
|
+
* Write regular JSON data (non-RecordData) with standard formatting
|
|
34
|
+
* @param filePath - Path to the JSON file to write
|
|
35
|
+
* @param data - Any JSON-serializable data
|
|
36
|
+
* @param options - Optional JSON write options
|
|
37
|
+
*/
|
|
38
|
+
static writeJson(filePath: string, data: any, options?: JsonWriteOptions): Promise<void>;
|
|
39
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.JsonWriteHelper = void 0;
|
|
7
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
8
|
+
/**
|
|
9
|
+
* Helper class for writing JSON files with consistent property ordering for RecordData objects.
|
|
10
|
+
* Ensures that all metadata files have the same property order: fields, relatedEntities, primaryKey, sync
|
|
11
|
+
*/
|
|
12
|
+
class JsonWriteHelper {
|
|
13
|
+
/**
|
|
14
|
+
* Write RecordData or arrays of RecordData with consistent property ordering
|
|
15
|
+
* @param filePath - Path to the JSON file to write
|
|
16
|
+
* @param data - RecordData object or array of RecordData objects
|
|
17
|
+
*/
|
|
18
|
+
static async writeOrderedRecordData(filePath, data) {
|
|
19
|
+
// Pre-process the data to ensure correct ordering before JSON.stringify
|
|
20
|
+
const normalizedData = this.normalizeRecordDataOrder(data);
|
|
21
|
+
// Use JSON.stringify with proper spacing
|
|
22
|
+
const jsonString = JSON.stringify(normalizedData, null, 2);
|
|
23
|
+
await fs_extra_1.default.writeFile(filePath, jsonString, 'utf8');
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Recursively normalize RecordData objects to ensure correct property ordering
|
|
27
|
+
* @param data - RecordData object, array of RecordData objects, or any nested structure
|
|
28
|
+
* @returns Normalized data with consistent property ordering
|
|
29
|
+
*/
|
|
30
|
+
static normalizeRecordDataOrder(data) {
|
|
31
|
+
if (Array.isArray(data)) {
|
|
32
|
+
return data.map(item => this.normalizeRecordDataOrder(item));
|
|
33
|
+
}
|
|
34
|
+
if (data && typeof data === 'object') {
|
|
35
|
+
// Check if this looks like a RecordData object
|
|
36
|
+
if (data.fields !== undefined) {
|
|
37
|
+
// This is a RecordData object - rebuild with correct order
|
|
38
|
+
const ordered = {};
|
|
39
|
+
// Add properties in desired order: fields, relatedEntities, primaryKey, sync
|
|
40
|
+
if (data.fields !== undefined) {
|
|
41
|
+
ordered.fields = this.normalizeRecordDataOrder(data.fields);
|
|
42
|
+
}
|
|
43
|
+
if (data.relatedEntities !== undefined) {
|
|
44
|
+
ordered.relatedEntities = this.normalizeRecordDataOrder(data.relatedEntities);
|
|
45
|
+
}
|
|
46
|
+
if (data.primaryKey !== undefined) {
|
|
47
|
+
ordered.primaryKey = this.normalizeRecordDataOrder(data.primaryKey);
|
|
48
|
+
}
|
|
49
|
+
if (data.sync !== undefined) {
|
|
50
|
+
ordered.sync = this.normalizeRecordDataOrder(data.sync);
|
|
51
|
+
}
|
|
52
|
+
return ordered;
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
// Regular object - recursively process properties
|
|
56
|
+
const processed = {};
|
|
57
|
+
for (const [key, value] of Object.entries(data)) {
|
|
58
|
+
processed[key] = this.normalizeRecordDataOrder(value);
|
|
59
|
+
}
|
|
60
|
+
return processed;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return data;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Create a RecordData object with explicit property ordering for consistent JSON output
|
|
67
|
+
* @param fields - Entity field data
|
|
68
|
+
* @param relatedEntities - Related entity data
|
|
69
|
+
* @param primaryKey - Primary key data
|
|
70
|
+
* @param sync - Sync metadata
|
|
71
|
+
* @returns RecordData object with guaranteed property order
|
|
72
|
+
*/
|
|
73
|
+
static createOrderedRecordData(fields, relatedEntities, primaryKey, sync) {
|
|
74
|
+
// Use a Map to preserve insertion order, then convert to object
|
|
75
|
+
const orderedProps = new Map();
|
|
76
|
+
// Add properties in the desired order
|
|
77
|
+
orderedProps.set('fields', fields);
|
|
78
|
+
if (Object.keys(relatedEntities).length > 0) {
|
|
79
|
+
orderedProps.set('relatedEntities', relatedEntities);
|
|
80
|
+
}
|
|
81
|
+
orderedProps.set('primaryKey', primaryKey);
|
|
82
|
+
orderedProps.set('sync', sync);
|
|
83
|
+
// Convert Map to object while preserving order
|
|
84
|
+
const recordData = {};
|
|
85
|
+
for (const [key, value] of orderedProps) {
|
|
86
|
+
recordData[key] = value;
|
|
87
|
+
}
|
|
88
|
+
return recordData;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Write regular JSON data (non-RecordData) with standard formatting
|
|
92
|
+
* @param filePath - Path to the JSON file to write
|
|
93
|
+
* @param data - Any JSON-serializable data
|
|
94
|
+
* @param options - Optional JSON write options
|
|
95
|
+
*/
|
|
96
|
+
static async writeJson(filePath, data, options) {
|
|
97
|
+
const defaultOptions = { spaces: 2 };
|
|
98
|
+
const writeOptions = typeof options === 'object' && options !== null
|
|
99
|
+
? { ...defaultOptions, ...options }
|
|
100
|
+
: defaultOptions;
|
|
101
|
+
await fs_extra_1.default.writeJson(filePath, data, writeOptions);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
exports.JsonWriteHelper = JsonWriteHelper;
|
|
105
|
+
//# sourceMappingURL=json-write-helper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-write-helper.js","sourceRoot":"","sources":["../../src/lib/json-write-helper.ts"],"names":[],"mappings":"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","sourcesContent":["import fs, { JsonWriteOptions } from 'fs-extra';\nimport { RecordData } from './sync-engine';\n\n/**\n * Helper class for writing JSON files with consistent property ordering for RecordData objects.\n * Ensures that all metadata files have the same property order: fields, relatedEntities, primaryKey, sync\n */\nexport class JsonWriteHelper {\n \n /**\n * Write RecordData or arrays of RecordData with consistent property ordering\n * @param filePath - Path to the JSON file to write\n * @param data - RecordData object or array of RecordData objects\n */\n static async writeOrderedRecordData(filePath: string, data: RecordData | RecordData[]): Promise<void> {\n // Pre-process the data to ensure correct ordering before JSON.stringify\n const normalizedData = this.normalizeRecordDataOrder(data);\n \n // Use JSON.stringify with proper spacing\n const jsonString = JSON.stringify(normalizedData, null, 2);\n await fs.writeFile(filePath, jsonString, 'utf8');\n }\n\n /**\n * Recursively normalize RecordData objects to ensure correct property ordering\n * @param data - RecordData object, array of RecordData objects, or any nested structure\n * @returns Normalized data with consistent property ordering\n */\n private static normalizeRecordDataOrder(data: any): any {\n if (Array.isArray(data)) {\n return data.map(item => this.normalizeRecordDataOrder(item));\n }\n \n if (data && typeof data === 'object') {\n // Check if this looks like a RecordData object\n if (data.fields !== undefined) {\n // This is a RecordData object - rebuild with correct order\n const ordered: any = {};\n \n // Add properties in desired order: fields, relatedEntities, primaryKey, sync\n if (data.fields !== undefined) {\n ordered.fields = this.normalizeRecordDataOrder(data.fields);\n }\n if (data.relatedEntities !== undefined) {\n ordered.relatedEntities = this.normalizeRecordDataOrder(data.relatedEntities);\n }\n if (data.primaryKey !== undefined) {\n ordered.primaryKey = this.normalizeRecordDataOrder(data.primaryKey);\n }\n if (data.sync !== undefined) {\n ordered.sync = this.normalizeRecordDataOrder(data.sync);\n }\n \n return ordered;\n } else {\n // Regular object - recursively process properties\n const processed: any = {};\n for (const [key, value] of Object.entries(data)) {\n processed[key] = this.normalizeRecordDataOrder(value);\n }\n return processed;\n }\n }\n \n return data;\n }\n\n /**\n * Create a RecordData object with explicit property ordering for consistent JSON output\n * @param fields - Entity field data\n * @param relatedEntities - Related entity data\n * @param primaryKey - Primary key data\n * @param sync - Sync metadata\n * @returns RecordData object with guaranteed property order\n */\n static createOrderedRecordData(\n fields: Record<string, any>,\n relatedEntities: Record<string, RecordData[]>,\n primaryKey: Record<string, any>,\n sync: { lastModified: string; checksum: string }\n ): RecordData {\n // Use a Map to preserve insertion order, then convert to object\n const orderedProps = new Map<string, any>();\n \n // Add properties in the desired order\n orderedProps.set('fields', fields);\n \n if (Object.keys(relatedEntities).length > 0) {\n orderedProps.set('relatedEntities', relatedEntities);\n }\n \n orderedProps.set('primaryKey', primaryKey);\n orderedProps.set('sync', sync);\n \n // Convert Map to object while preserving order\n const recordData = {} as RecordData;\n for (const [key, value] of orderedProps) {\n (recordData as any)[key] = value;\n }\n \n return recordData;\n }\n\n /**\n * Write regular JSON data (non-RecordData) with standard formatting\n * @param filePath - Path to the JSON file to write\n * @param data - Any JSON-serializable data\n * @param options - Optional JSON write options\n */\n static async writeJson(filePath: string, data: any, options?: JsonWriteOptions): Promise<void> {\n const defaultOptions = { spaces: 2 };\n const writeOptions = typeof options === 'object' && options !== null \n ? { ...defaultOptions, ...options }\n : defaultOptions;\n await fs.writeJson(filePath, data, writeOptions);\n }\n}"]}
|
|
@@ -9,6 +9,7 @@ const path_1 = __importDefault(require("path"));
|
|
|
9
9
|
const fast_glob_1 = __importDefault(require("fast-glob"));
|
|
10
10
|
const config_1 = require("../config");
|
|
11
11
|
const config_manager_1 = require("../lib/config-manager");
|
|
12
|
+
const json_write_helper_1 = require("../lib/json-write-helper");
|
|
12
13
|
class FileResetService {
|
|
13
14
|
async resetFiles(options = {}, callbacks) {
|
|
14
15
|
const sections = options.sections || 'both';
|
|
@@ -110,7 +111,7 @@ class FileResetService {
|
|
|
110
111
|
backupsCreated++;
|
|
111
112
|
}
|
|
112
113
|
// Write cleaned content
|
|
113
|
-
await
|
|
114
|
+
await json_write_helper_1.JsonWriteHelper.writeOrderedRecordData(file, cleanedContent);
|
|
114
115
|
modifiedFiles++;
|
|
115
116
|
if (options.verbose) {
|
|
116
117
|
callbacks?.onLog?.(`✓ ${path_1.default.relative(config_manager_1.configManager.getOriginalCwd(), file)}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileResetService.js","sourceRoot":"","sources":["../../src/services/FileResetService.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs-extra';\nimport path from 'path';\nimport fastGlob from 'fast-glob';\nimport { loadSyncConfig } from '../config';\nimport { configManager } from '../lib/config-manager';\n\nexport interface FileResetOptions {\n sections?: 'both' | 'primaryKey' | 'sync';\n dryRun?: boolean;\n noBackup?: boolean;\n verbose?: boolean;\n}\n\nexport interface FileResetCallbacks {\n onProgress?: (message: string) => void;\n onLog?: (message: string) => void;\n onWarn?: (message: string) => void;\n onConfirm?: (message: string) => Promise<boolean>;\n}\n\nexport interface FileResetResult {\n processedFiles: number;\n modifiedFiles: number;\n totalPrimaryKeys: number;\n totalSyncs: number;\n filesWithPrimaryKey: number;\n filesWithSync: number;\n backupsCreated: number;\n}\n\nexport interface FileStats {\n primaryKeyCount: number;\n syncCount: number;\n}\n\nexport class FileResetService {\n \n async resetFiles(options: FileResetOptions = {}, callbacks?: FileResetCallbacks): Promise<FileResetResult> {\n const sections = options.sections || 'both';\n \n // Load sync config\n const syncConfig = await loadSyncConfig(configManager.getOriginalCwd());\n if (!syncConfig) {\n throw new Error('No .mj-sync.json found in current directory');\n }\n \n // Find all metadata JSON files\n callbacks?.onProgress?.('Finding metadata files');\n const pattern = syncConfig.filePattern || '.*.json';\n const files = await fastGlob(pattern, {\n cwd: configManager.getOriginalCwd(),\n absolute: true,\n dot: true,\n ignore: ['.mj-sync.json', '.mj-folder.json'],\n });\n \n if (files.length === 0) {\n callbacks?.onLog?.('No metadata files found');\n return {\n processedFiles: 0,\n modifiedFiles: 0,\n totalPrimaryKeys: 0,\n totalSyncs: 0,\n filesWithPrimaryKey: 0,\n filesWithSync: 0,\n backupsCreated: 0\n };\n }\n \n callbacks?.onLog?.(`Found ${files.length} metadata file${files.length === 1 ? '' : 's'}`);\n \n // Count what will be removed\n let filesWithPrimaryKey = 0;\n let filesWithSync = 0;\n let totalPrimaryKeys = 0;\n let totalSyncs = 0;\n \n for (const file of files) {\n const content = await fs.readJson(file);\n const stats = this.countSections(content);\n if (stats.primaryKeyCount > 0) {\n filesWithPrimaryKey++;\n totalPrimaryKeys += stats.primaryKeyCount;\n }\n if (stats.syncCount > 0) {\n filesWithSync++;\n totalSyncs += stats.syncCount;\n }\n }\n \n // Report what will be removed\n if (sections === 'both' || sections === 'primaryKey') {\n callbacks?.onLog?.(`Will remove ${totalPrimaryKeys} primaryKey section${totalPrimaryKeys === 1 ? '' : 's'} from ${filesWithPrimaryKey} file${filesWithPrimaryKey === 1 ? '' : 's'}`);\n }\n if (sections === 'both' || sections === 'sync') {\n callbacks?.onLog?.(`Will remove ${totalSyncs} sync section${totalSyncs === 1 ? '' : 's'} from ${filesWithSync} file${filesWithSync === 1 ? '' : 's'}`);\n }\n \n if (options.dryRun) {\n callbacks?.onLog?.('Dry run mode - no files will be modified');\n \n if (options.verbose) {\n for (const file of files) {\n const content = await fs.readJson(file);\n const stats = this.countSections(content);\n if (stats.primaryKeyCount > 0 || stats.syncCount > 0) {\n callbacks?.onLog?.(`${path.relative(configManager.getOriginalCwd(), file)}:`);\n if (stats.primaryKeyCount > 0) {\n callbacks?.onLog?.(` - ${stats.primaryKeyCount} primaryKey section${stats.primaryKeyCount === 1 ? '' : 's'}`);\n }\n if (stats.syncCount > 0) {\n callbacks?.onLog?.(` - ${stats.syncCount} sync section${stats.syncCount === 1 ? '' : 's'}`);\n }\n }\n }\n }\n \n return {\n processedFiles: files.length,\n modifiedFiles: 0,\n totalPrimaryKeys,\n totalSyncs,\n filesWithPrimaryKey,\n filesWithSync,\n backupsCreated: 0\n };\n }\n \n // Process files\n callbacks?.onProgress?.('Processing files');\n let processedFiles = 0;\n let modifiedFiles = 0;\n let backupsCreated = 0;\n \n for (const file of files) {\n processedFiles++;\n const content = await fs.readJson(file);\n const originalContent = JSON.stringify(content);\n \n // Remove sections\n const cleanedContent = this.removeSections(content, sections);\n \n // Only write if content changed\n if (JSON.stringify(cleanedContent) !== originalContent) {\n // Create backup if requested\n if (!options.noBackup) {\n const backupPath = `${file}.backup`;\n await fs.writeJson(backupPath, content, { spaces: 2 });\n backupsCreated++;\n }\n \n // Write cleaned content\n await fs.writeJson(file, cleanedContent, { spaces: 2 });\n modifiedFiles++;\n \n if (options.verbose) {\n callbacks?.onLog?.(`✓ ${path.relative(configManager.getOriginalCwd(), file)}`);\n }\n }\n }\n \n return {\n processedFiles,\n modifiedFiles,\n totalPrimaryKeys,\n totalSyncs,\n filesWithPrimaryKey,\n filesWithSync,\n backupsCreated\n };\n }\n \n private countSections(data: any): FileStats {\n let primaryKeyCount = 0;\n let syncCount = 0;\n \n if (Array.isArray(data)) {\n for (const item of data) {\n const stats = this.countSections(item);\n primaryKeyCount += stats.primaryKeyCount;\n syncCount += stats.syncCount;\n }\n } else if (data && typeof data === 'object') {\n if ('primaryKey' in data) primaryKeyCount++;\n if ('sync' in data) syncCount++;\n \n // Check related entities\n if (data.relatedEntities) {\n for (const entityData of Object.values(data.relatedEntities)) {\n const stats = this.countSections(entityData);\n primaryKeyCount += stats.primaryKeyCount;\n syncCount += stats.syncCount;\n }\n }\n }\n \n return { primaryKeyCount, syncCount };\n }\n \n private removeSections(data: any, sections: string): any {\n if (Array.isArray(data)) {\n return data.map(item => this.removeSections(item, sections));\n } else if (data && typeof data === 'object') {\n const cleaned = { ...data };\n \n // Remove specified sections\n if (sections === 'both' || sections === 'primaryKey') {\n delete cleaned.primaryKey;\n }\n if (sections === 'both' || sections === 'sync') {\n delete cleaned.sync;\n }\n \n // Process related entities\n if (cleaned.relatedEntities) {\n const cleanedRelated: any = {};\n for (const [entityName, entityData] of Object.entries(cleaned.relatedEntities)) {\n cleanedRelated[entityName] = this.removeSections(entityData, sections);\n }\n cleaned.relatedEntities = cleanedRelated;\n }\n \n return cleaned;\n }\n \n return data;\n }\n}"]}
|
|
1
|
+
{"version":3,"file":"FileResetService.js","sourceRoot":"","sources":["../../src/services/FileResetService.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs-extra';\nimport path from 'path';\nimport fastGlob from 'fast-glob';\nimport { loadSyncConfig } from '../config';\nimport { configManager } from '../lib/config-manager';\nimport { JsonWriteHelper } from '../lib/json-write-helper';\n\nexport interface FileResetOptions {\n sections?: 'both' | 'primaryKey' | 'sync';\n dryRun?: boolean;\n noBackup?: boolean;\n verbose?: boolean;\n}\n\nexport interface FileResetCallbacks {\n onProgress?: (message: string) => void;\n onLog?: (message: string) => void;\n onWarn?: (message: string) => void;\n onConfirm?: (message: string) => Promise<boolean>;\n}\n\nexport interface FileResetResult {\n processedFiles: number;\n modifiedFiles: number;\n totalPrimaryKeys: number;\n totalSyncs: number;\n filesWithPrimaryKey: number;\n filesWithSync: number;\n backupsCreated: number;\n}\n\nexport interface FileStats {\n primaryKeyCount: number;\n syncCount: number;\n}\n\nexport class FileResetService {\n \n async resetFiles(options: FileResetOptions = {}, callbacks?: FileResetCallbacks): Promise<FileResetResult> {\n const sections = options.sections || 'both';\n \n // Load sync config\n const syncConfig = await loadSyncConfig(configManager.getOriginalCwd());\n if (!syncConfig) {\n throw new Error('No .mj-sync.json found in current directory');\n }\n \n // Find all metadata JSON files\n callbacks?.onProgress?.('Finding metadata files');\n const pattern = syncConfig.filePattern || '.*.json';\n const files = await fastGlob(pattern, {\n cwd: configManager.getOriginalCwd(),\n absolute: true,\n dot: true,\n ignore: ['.mj-sync.json', '.mj-folder.json'],\n });\n \n if (files.length === 0) {\n callbacks?.onLog?.('No metadata files found');\n return {\n processedFiles: 0,\n modifiedFiles: 0,\n totalPrimaryKeys: 0,\n totalSyncs: 0,\n filesWithPrimaryKey: 0,\n filesWithSync: 0,\n backupsCreated: 0\n };\n }\n \n callbacks?.onLog?.(`Found ${files.length} metadata file${files.length === 1 ? '' : 's'}`);\n \n // Count what will be removed\n let filesWithPrimaryKey = 0;\n let filesWithSync = 0;\n let totalPrimaryKeys = 0;\n let totalSyncs = 0;\n \n for (const file of files) {\n const content = await fs.readJson(file);\n const stats = this.countSections(content);\n if (stats.primaryKeyCount > 0) {\n filesWithPrimaryKey++;\n totalPrimaryKeys += stats.primaryKeyCount;\n }\n if (stats.syncCount > 0) {\n filesWithSync++;\n totalSyncs += stats.syncCount;\n }\n }\n \n // Report what will be removed\n if (sections === 'both' || sections === 'primaryKey') {\n callbacks?.onLog?.(`Will remove ${totalPrimaryKeys} primaryKey section${totalPrimaryKeys === 1 ? '' : 's'} from ${filesWithPrimaryKey} file${filesWithPrimaryKey === 1 ? '' : 's'}`);\n }\n if (sections === 'both' || sections === 'sync') {\n callbacks?.onLog?.(`Will remove ${totalSyncs} sync section${totalSyncs === 1 ? '' : 's'} from ${filesWithSync} file${filesWithSync === 1 ? '' : 's'}`);\n }\n \n if (options.dryRun) {\n callbacks?.onLog?.('Dry run mode - no files will be modified');\n \n if (options.verbose) {\n for (const file of files) {\n const content = await fs.readJson(file);\n const stats = this.countSections(content);\n if (stats.primaryKeyCount > 0 || stats.syncCount > 0) {\n callbacks?.onLog?.(`${path.relative(configManager.getOriginalCwd(), file)}:`);\n if (stats.primaryKeyCount > 0) {\n callbacks?.onLog?.(` - ${stats.primaryKeyCount} primaryKey section${stats.primaryKeyCount === 1 ? '' : 's'}`);\n }\n if (stats.syncCount > 0) {\n callbacks?.onLog?.(` - ${stats.syncCount} sync section${stats.syncCount === 1 ? '' : 's'}`);\n }\n }\n }\n }\n \n return {\n processedFiles: files.length,\n modifiedFiles: 0,\n totalPrimaryKeys,\n totalSyncs,\n filesWithPrimaryKey,\n filesWithSync,\n backupsCreated: 0\n };\n }\n \n // Process files\n callbacks?.onProgress?.('Processing files');\n let processedFiles = 0;\n let modifiedFiles = 0;\n let backupsCreated = 0;\n \n for (const file of files) {\n processedFiles++;\n const content = await fs.readJson(file);\n const originalContent = JSON.stringify(content);\n \n // Remove sections\n const cleanedContent = this.removeSections(content, sections);\n \n // Only write if content changed\n if (JSON.stringify(cleanedContent) !== originalContent) {\n // Create backup if requested\n if (!options.noBackup) {\n const backupPath = `${file}.backup`;\n await fs.writeJson(backupPath, content, { spaces: 2 });\n backupsCreated++;\n }\n \n // Write cleaned content\n await JsonWriteHelper.writeOrderedRecordData(file, cleanedContent);\n modifiedFiles++;\n \n if (options.verbose) {\n callbacks?.onLog?.(`✓ ${path.relative(configManager.getOriginalCwd(), file)}`);\n }\n }\n }\n \n return {\n processedFiles,\n modifiedFiles,\n totalPrimaryKeys,\n totalSyncs,\n filesWithPrimaryKey,\n filesWithSync,\n backupsCreated\n };\n }\n \n private countSections(data: any): FileStats {\n let primaryKeyCount = 0;\n let syncCount = 0;\n \n if (Array.isArray(data)) {\n for (const item of data) {\n const stats = this.countSections(item);\n primaryKeyCount += stats.primaryKeyCount;\n syncCount += stats.syncCount;\n }\n } else if (data && typeof data === 'object') {\n if ('primaryKey' in data) primaryKeyCount++;\n if ('sync' in data) syncCount++;\n \n // Check related entities\n if (data.relatedEntities) {\n for (const entityData of Object.values(data.relatedEntities)) {\n const stats = this.countSections(entityData);\n primaryKeyCount += stats.primaryKeyCount;\n syncCount += stats.syncCount;\n }\n }\n }\n \n return { primaryKeyCount, syncCount };\n }\n \n private removeSections(data: any, sections: string): any {\n if (Array.isArray(data)) {\n return data.map(item => this.removeSections(item, sections));\n } else if (data && typeof data === 'object') {\n const cleaned = { ...data };\n \n // Remove specified sections\n if (sections === 'both' || sections === 'primaryKey') {\n delete cleaned.primaryKey;\n }\n if (sections === 'both' || sections === 'sync') {\n delete cleaned.sync;\n }\n \n // Process related entities\n if (cleaned.relatedEntities) {\n const cleanedRelated: any = {};\n for (const [entityName, entityData] of Object.entries(cleaned.relatedEntities)) {\n cleanedRelated[entityName] = this.removeSections(entityData, sections);\n }\n cleaned.relatedEntities = cleanedRelated;\n }\n \n return cleaned;\n }\n \n return data;\n }\n}"]}
|
|
@@ -28,13 +28,33 @@ export interface PullResult {
|
|
|
28
28
|
export declare class PullService {
|
|
29
29
|
private syncEngine;
|
|
30
30
|
private contextUser;
|
|
31
|
+
private createdBackupFiles;
|
|
32
|
+
private createdBackupDirs;
|
|
33
|
+
private fileWriteBatch;
|
|
34
|
+
private recordProcessor;
|
|
31
35
|
constructor(syncEngine: SyncEngine, contextUser: UserInfo);
|
|
32
36
|
pull(options: PullOptions, callbacks?: PullCallbacks): Promise<PullResult>;
|
|
33
|
-
private handleAsyncPropertyLoading;
|
|
34
37
|
private processRecords;
|
|
38
|
+
/**
|
|
39
|
+
* Clean up backup files created during the pull operation
|
|
40
|
+
* Should be called after successful pull operations to remove persistent backup files
|
|
41
|
+
*/
|
|
42
|
+
cleanupBackupFiles(): Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* Remove a backup directory if it's empty
|
|
45
|
+
*/
|
|
46
|
+
private removeEmptyBackupDirectory;
|
|
47
|
+
/**
|
|
48
|
+
* Get the list of backup files created during the current pull operation
|
|
49
|
+
*/
|
|
50
|
+
getCreatedBackupFiles(): string[];
|
|
51
|
+
/**
|
|
52
|
+
* Rollback file changes by restoring from backup files
|
|
53
|
+
* Called when pull operation fails after files have been modified
|
|
54
|
+
*/
|
|
55
|
+
private rollbackFileChanges;
|
|
35
56
|
private processIndividualRecords;
|
|
36
57
|
private processRecord;
|
|
37
|
-
private processRecordData;
|
|
38
58
|
private findEntityDirectories;
|
|
39
59
|
private buildFileName;
|
|
40
60
|
private findExistingFiles;
|