@memberjunction/metadata-sync 2.51.0 → 2.52.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.
@@ -0,0 +1,15 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class FileReset extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ sections: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
7
+ 'dry-run': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
8
+ 'no-backup': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
9
+ yes: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
10
+ verbose: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
11
+ };
12
+ run(): Promise<void>;
13
+ private countSections;
14
+ private removeSections;
15
+ }
@@ -0,0 +1,221 @@
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
+ const core_1 = require("@oclif/core");
7
+ const fs_extra_1 = __importDefault(require("fs-extra"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const prompts_1 = require("@inquirer/prompts");
10
+ const ora_classic_1 = __importDefault(require("ora-classic"));
11
+ const fast_glob_1 = __importDefault(require("fast-glob"));
12
+ const chalk_1 = __importDefault(require("chalk"));
13
+ const config_1 = require("../../config");
14
+ const config_manager_1 = require("../../lib/config-manager");
15
+ class FileReset extends core_1.Command {
16
+ static description = 'Remove primaryKey and sync sections from metadata JSON files';
17
+ static examples = [
18
+ `<%= config.bin %> <%= command.id %>`,
19
+ `<%= config.bin %> <%= command.id %> --sections=primaryKey`,
20
+ `<%= config.bin %> <%= command.id %> --sections=sync`,
21
+ `<%= config.bin %> <%= command.id %> --dry-run`,
22
+ `<%= config.bin %> <%= command.id %> --no-backup`,
23
+ `<%= config.bin %> <%= command.id %> --yes`,
24
+ ];
25
+ static flags = {
26
+ sections: core_1.Flags.string({
27
+ description: 'Which sections to remove',
28
+ options: ['both', 'primaryKey', 'sync'],
29
+ default: 'both',
30
+ }),
31
+ 'dry-run': core_1.Flags.boolean({
32
+ description: 'Show what would be removed without actually removing'
33
+ }),
34
+ 'no-backup': core_1.Flags.boolean({
35
+ description: 'Skip creating backup files'
36
+ }),
37
+ yes: core_1.Flags.boolean({
38
+ char: 'y',
39
+ description: 'Skip confirmation prompt'
40
+ }),
41
+ verbose: core_1.Flags.boolean({
42
+ char: 'v',
43
+ description: 'Show detailed output'
44
+ }),
45
+ };
46
+ async run() {
47
+ const { flags } = await this.parse(FileReset);
48
+ const spinner = (0, ora_classic_1.default)();
49
+ try {
50
+ // Load sync config
51
+ const syncConfig = await (0, config_1.loadSyncConfig)(config_manager_1.configManager.getOriginalCwd());
52
+ if (!syncConfig) {
53
+ this.error('No .mj-sync.json found in current directory');
54
+ }
55
+ // Find all metadata JSON files
56
+ spinner.start('Finding metadata files');
57
+ const pattern = syncConfig.filePattern || '.*.json';
58
+ const files = await (0, fast_glob_1.default)(pattern, {
59
+ cwd: config_manager_1.configManager.getOriginalCwd(),
60
+ absolute: true,
61
+ ignore: ['.mj-sync.json', '.mj-folder.json'],
62
+ });
63
+ spinner.stop();
64
+ if (files.length === 0) {
65
+ this.log('No metadata files found');
66
+ return;
67
+ }
68
+ this.log(`Found ${files.length} metadata file${files.length === 1 ? '' : 's'}`);
69
+ // Count what will be removed
70
+ let filesWithPrimaryKey = 0;
71
+ let filesWithSync = 0;
72
+ let totalPrimaryKeys = 0;
73
+ let totalSyncs = 0;
74
+ for (const file of files) {
75
+ const content = await fs_extra_1.default.readJson(file);
76
+ const stats = this.countSections(content);
77
+ if (stats.primaryKeyCount > 0) {
78
+ filesWithPrimaryKey++;
79
+ totalPrimaryKeys += stats.primaryKeyCount;
80
+ }
81
+ if (stats.syncCount > 0) {
82
+ filesWithSync++;
83
+ totalSyncs += stats.syncCount;
84
+ }
85
+ }
86
+ // Show what will be removed
87
+ this.log('');
88
+ if (flags.sections === 'both' || flags.sections === 'primaryKey') {
89
+ this.log(`Will remove ${chalk_1.default.yellow(totalPrimaryKeys)} primaryKey section${totalPrimaryKeys === 1 ? '' : 's'} from ${chalk_1.default.yellow(filesWithPrimaryKey)} file${filesWithPrimaryKey === 1 ? '' : 's'}`);
90
+ }
91
+ if (flags.sections === 'both' || flags.sections === 'sync') {
92
+ this.log(`Will remove ${chalk_1.default.yellow(totalSyncs)} sync section${totalSyncs === 1 ? '' : 's'} from ${chalk_1.default.yellow(filesWithSync)} file${filesWithSync === 1 ? '' : 's'}`);
93
+ }
94
+ if (flags['dry-run']) {
95
+ this.log('');
96
+ this.log(chalk_1.default.cyan('Dry run mode - no files will be modified'));
97
+ if (flags.verbose) {
98
+ this.log('');
99
+ for (const file of files) {
100
+ const content = await fs_extra_1.default.readJson(file);
101
+ const stats = this.countSections(content);
102
+ if (stats.primaryKeyCount > 0 || stats.syncCount > 0) {
103
+ this.log(`${path_1.default.relative(config_manager_1.configManager.getOriginalCwd(), file)}:`);
104
+ if (stats.primaryKeyCount > 0) {
105
+ this.log(` - ${stats.primaryKeyCount} primaryKey section${stats.primaryKeyCount === 1 ? '' : 's'}`);
106
+ }
107
+ if (stats.syncCount > 0) {
108
+ this.log(` - ${stats.syncCount} sync section${stats.syncCount === 1 ? '' : 's'}`);
109
+ }
110
+ }
111
+ }
112
+ }
113
+ return;
114
+ }
115
+ // Confirm before proceeding
116
+ if (!flags.yes) {
117
+ const confirmed = await (0, prompts_1.confirm)({
118
+ message: 'Do you want to proceed?',
119
+ default: false,
120
+ });
121
+ if (!confirmed) {
122
+ this.log('Operation cancelled');
123
+ return;
124
+ }
125
+ }
126
+ // Process files
127
+ spinner.start('Processing files');
128
+ let processedFiles = 0;
129
+ let modifiedFiles = 0;
130
+ for (const file of files) {
131
+ processedFiles++;
132
+ const content = await fs_extra_1.default.readJson(file);
133
+ const originalContent = JSON.stringify(content);
134
+ // Remove sections
135
+ const cleanedContent = this.removeSections(content, flags.sections);
136
+ // Only write if content changed
137
+ if (JSON.stringify(cleanedContent) !== originalContent) {
138
+ // Create backup if requested
139
+ if (!flags['no-backup']) {
140
+ const backupPath = `${file}.backup`;
141
+ await fs_extra_1.default.writeJson(backupPath, content, { spaces: 2 });
142
+ }
143
+ // Write cleaned content
144
+ await fs_extra_1.default.writeJson(file, cleanedContent, { spaces: 2 });
145
+ modifiedFiles++;
146
+ if (flags.verbose) {
147
+ spinner.stop();
148
+ this.log(`✓ ${path_1.default.relative(config_manager_1.configManager.getOriginalCwd(), file)}`);
149
+ spinner.start('Processing files');
150
+ }
151
+ }
152
+ }
153
+ spinner.stop();
154
+ // Show summary
155
+ this.log('');
156
+ this.log(chalk_1.default.green(`✓ Reset complete`));
157
+ this.log(` Processed: ${processedFiles} file${processedFiles === 1 ? '' : 's'}`);
158
+ this.log(` Modified: ${modifiedFiles} file${modifiedFiles === 1 ? '' : 's'}`);
159
+ if (!flags['no-backup'] && modifiedFiles > 0) {
160
+ this.log(` Backups created: ${modifiedFiles}`);
161
+ }
162
+ }
163
+ catch (error) {
164
+ spinner.stop();
165
+ this.error(error instanceof Error ? error.message : String(error));
166
+ }
167
+ }
168
+ countSections(data) {
169
+ let primaryKeyCount = 0;
170
+ let syncCount = 0;
171
+ if (Array.isArray(data)) {
172
+ for (const item of data) {
173
+ const stats = this.countSections(item);
174
+ primaryKeyCount += stats.primaryKeyCount;
175
+ syncCount += stats.syncCount;
176
+ }
177
+ }
178
+ else if (data && typeof data === 'object') {
179
+ if ('primaryKey' in data)
180
+ primaryKeyCount++;
181
+ if ('sync' in data)
182
+ syncCount++;
183
+ // Check related entities
184
+ if (data.relatedEntities) {
185
+ for (const entityData of Object.values(data.relatedEntities)) {
186
+ const stats = this.countSections(entityData);
187
+ primaryKeyCount += stats.primaryKeyCount;
188
+ syncCount += stats.syncCount;
189
+ }
190
+ }
191
+ }
192
+ return { primaryKeyCount, syncCount };
193
+ }
194
+ removeSections(data, sections) {
195
+ if (Array.isArray(data)) {
196
+ return data.map(item => this.removeSections(item, sections));
197
+ }
198
+ else if (data && typeof data === 'object') {
199
+ const cleaned = { ...data };
200
+ // Remove specified sections
201
+ if (sections === 'both' || sections === 'primaryKey') {
202
+ delete cleaned.primaryKey;
203
+ }
204
+ if (sections === 'both' || sections === 'sync') {
205
+ delete cleaned.sync;
206
+ }
207
+ // Process related entities
208
+ if (cleaned.relatedEntities) {
209
+ const cleanedRelated = {};
210
+ for (const [entityName, entityData] of Object.entries(cleaned.relatedEntities)) {
211
+ cleanedRelated[entityName] = this.removeSections(entityData, sections);
212
+ }
213
+ cleaned.relatedEntities = cleanedRelated;
214
+ }
215
+ return cleaned;
216
+ }
217
+ return data;
218
+ }
219
+ }
220
+ exports.default = FileReset;
221
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/file-reset/index.ts"],"names":[],"mappings":";;;;;AAAA,sCAA6C;AAC7C,wDAA0B;AAC1B,gDAAwB;AACxB,+CAA4C;AAC5C,8DAA8B;AAC9B,0DAAiC;AACjC,kDAA0B;AAC1B,yCAA8C;AAC9C,6DAAyD;AAEzD,MAAqB,SAAU,SAAQ,cAAO;IAC5C,MAAM,CAAC,WAAW,GAAG,8DAA8D,CAAC;IAEpF,MAAM,CAAC,QAAQ,GAAG;QAChB,qCAAqC;QACrC,2DAA2D;QAC3D,qDAAqD;QACrD,+CAA+C;QAC/C,iDAAiD;QACjD,2CAA2C;KAC5C,CAAC;IAEF,MAAM,CAAC,KAAK,GAAG;QACb,QAAQ,EAAE,YAAK,CAAC,MAAM,CAAC;YACrB,WAAW,EAAE,0BAA0B;YACvC,OAAO,EAAE,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,CAAC;YACvC,OAAO,EAAE,MAAM;SAChB,CAAC;QACF,SAAS,EAAE,YAAK,CAAC,OAAO,CAAC;YACvB,WAAW,EAAE,sDAAsD;SACpE,CAAC;QACF,WAAW,EAAE,YAAK,CAAC,OAAO,CAAC;YACzB,WAAW,EAAE,4BAA4B;SAC1C,CAAC;QACF,GAAG,EAAE,YAAK,CAAC,OAAO,CAAC;YACjB,IAAI,EAAE,GAAG;YACT,WAAW,EAAE,0BAA0B;SACxC,CAAC;QACF,OAAO,EAAE,YAAK,CAAC,OAAO,CAAC;YACrB,IAAI,EAAE,GAAG;YACT,WAAW,EAAE,sBAAsB;SACpC,CAAC;KACH,CAAC;IAEF,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAC9C,MAAM,OAAO,GAAG,IAAA,qBAAG,GAAE,CAAC;QAEtB,IAAI,CAAC;YACH,mBAAmB;YACnB,MAAM,UAAU,GAAG,MAAM,IAAA,uBAAc,EAAC,8BAAa,CAAC,cAAc,EAAE,CAAC,CAAC;YACxE,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,IAAI,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;YAC5D,CAAC;YAED,+BAA+B;YAC/B,OAAO,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;YACxC,MAAM,OAAO,GAAG,UAAU,CAAC,WAAW,IAAI,SAAS,CAAC;YACpD,MAAM,KAAK,GAAG,MAAM,IAAA,mBAAQ,EAAC,OAAO,EAAE;gBACpC,GAAG,EAAE,8BAAa,CAAC,cAAc,EAAE;gBACnC,QAAQ,EAAE,IAAI;gBACd,MAAM,EAAE,CAAC,eAAe,EAAE,iBAAiB,CAAC;aAC7C,CAAC,CAAC;YAEH,OAAO,CAAC,IAAI,EAAE,CAAC;YAEf,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACvB,IAAI,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;gBACpC,OAAO;YACT,CAAC;YAED,IAAI,CAAC,GAAG,CAAC,SAAS,KAAK,CAAC,MAAM,iBAAiB,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YAEhF,6BAA6B;YAC7B,IAAI,mBAAmB,GAAG,CAAC,CAAC;YAC5B,IAAI,aAAa,GAAG,CAAC,CAAC;YACtB,IAAI,gBAAgB,GAAG,CAAC,CAAC;YACzB,IAAI,UAAU,GAAG,CAAC,CAAC;YAEnB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,MAAM,OAAO,GAAG,MAAM,kBAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;gBACxC,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;gBAC1C,IAAI,KAAK,CAAC,eAAe,GAAG,CAAC,EAAE,CAAC;oBAC9B,mBAAmB,EAAE,CAAC;oBACtB,gBAAgB,IAAI,KAAK,CAAC,eAAe,CAAC;gBAC5C,CAAC;gBACD,IAAI,KAAK,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC;oBACxB,aAAa,EAAE,CAAC;oBAChB,UAAU,IAAI,KAAK,CAAC,SAAS,CAAC;gBAChC,CAAC;YACH,CAAC;YAED,4BAA4B;YAC5B,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACb,IAAI,KAAK,CAAC,QAAQ,KAAK,MAAM,IAAI,KAAK,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;gBACjE,IAAI,CAAC,GAAG,CAAC,eAAe,eAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,sBAAsB,gBAAgB,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,SAAS,eAAK,CAAC,MAAM,CAAC,mBAAmB,CAAC,QAAQ,mBAAmB,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YACzM,CAAC;YACD,IAAI,KAAK,CAAC,QAAQ,KAAK,MAAM,IAAI,KAAK,CAAC,QAAQ,KAAK,MAAM,EAAE,CAAC;gBAC3D,IAAI,CAAC,GAAG,CAAC,eAAe,eAAK,CAAC,MAAM,CAAC,UAAU,CAAC,gBAAgB,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,SAAS,eAAK,CAAC,MAAM,CAAC,aAAa,CAAC,QAAQ,aAAa,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YAC3K,CAAC;YAED,IAAI,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;gBACrB,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBACb,IAAI,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC,CAAC;gBAEjE,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;oBAClB,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;oBACb,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;wBACzB,MAAM,OAAO,GAAG,MAAM,kBAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;wBACxC,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;wBAC1C,IAAI,KAAK,CAAC,eAAe,GAAG,CAAC,IAAI,KAAK,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC;4BACrD,IAAI,CAAC,GAAG,CAAC,GAAG,cAAI,CAAC,QAAQ,CAAC,8BAAa,CAAC,cAAc,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;4BACpE,IAAI,KAAK,CAAC,eAAe,GAAG,CAAC,EAAE,CAAC;gCAC9B,IAAI,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,eAAe,sBAAsB,KAAK,CAAC,eAAe,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;4BACvG,CAAC;4BACD,IAAI,KAAK,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC;gCACxB,IAAI,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,SAAS,gBAAgB,KAAK,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;4BACrF,CAAC;wBACH,CAAC;oBACH,CAAC;gBACH,CAAC;gBACD,OAAO;YACT,CAAC;YAED,4BAA4B;YAC5B,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;gBACf,MAAM,SAAS,GAAG,MAAM,IAAA,iBAAO,EAAC;oBAC9B,OAAO,EAAE,yBAAyB;oBAClC,OAAO,EAAE,KAAK;iBACf,CAAC,CAAC;gBAEH,IAAI,CAAC,SAAS,EAAE,CAAC;oBACf,IAAI,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;oBAChC,OAAO;gBACT,CAAC;YACH,CAAC;YAED,gBAAgB;YAChB,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;YAClC,IAAI,cAAc,GAAG,CAAC,CAAC;YACvB,IAAI,aAAa,GAAG,CAAC,CAAC;YAEtB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,cAAc,EAAE,CAAC;gBACjB,MAAM,OAAO,GAAG,MAAM,kBAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;gBACxC,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;gBAEhD,kBAAkB;gBAClB,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;gBAEpE,gCAAgC;gBAChC,IAAI,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,KAAK,eAAe,EAAE,CAAC;oBACvD,6BAA6B;oBAC7B,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC;wBACxB,MAAM,UAAU,GAAG,GAAG,IAAI,SAAS,CAAC;wBACpC,MAAM,kBAAE,CAAC,SAAS,CAAC,UAAU,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;oBACzD,CAAC;oBAED,wBAAwB;oBACxB,MAAM,kBAAE,CAAC,SAAS,CAAC,IAAI,EAAE,cAAc,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;oBACxD,aAAa,EAAE,CAAC;oBAEhB,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;wBAClB,OAAO,CAAC,IAAI,EAAE,CAAC;wBACf,IAAI,CAAC,GAAG,CAAC,KAAK,cAAI,CAAC,QAAQ,CAAC,8BAAa,CAAC,cAAc,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;wBACrE,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;oBACpC,CAAC;gBACH,CAAC;YACH,CAAC;YAED,OAAO,CAAC,IAAI,EAAE,CAAC;YAEf,eAAe;YACf,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACb,IAAI,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC;YAC1C,IAAI,CAAC,GAAG,CAAC,gBAAgB,cAAc,QAAQ,cAAc,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YAClF,IAAI,CAAC,GAAG,CAAC,eAAe,aAAa,QAAQ,aAAa,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YAC/E,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,aAAa,GAAG,CAAC,EAAE,CAAC;gBAC7C,IAAI,CAAC,GAAG,CAAC,sBAAsB,aAAa,EAAE,CAAC,CAAC;YAClD,CAAC;QAEH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACrE,CAAC;IACH,CAAC;IAEO,aAAa,CAAC,IAAS;QAC7B,IAAI,eAAe,GAAG,CAAC,CAAC;QACxB,IAAI,SAAS,GAAG,CAAC,CAAC;QAElB,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;gBACxB,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;gBACvC,eAAe,IAAI,KAAK,CAAC,eAAe,CAAC;gBACzC,SAAS,IAAI,KAAK,CAAC,SAAS,CAAC;YAC/B,CAAC;QACH,CAAC;aAAM,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC5C,IAAI,YAAY,IAAI,IAAI;gBAAE,eAAe,EAAE,CAAC;YAC5C,IAAI,MAAM,IAAI,IAAI;gBAAE,SAAS,EAAE,CAAC;YAEhC,yBAAyB;YACzB,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;gBACzB,KAAK,MAAM,UAAU,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC;oBAC7D,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;oBAC7C,eAAe,IAAI,KAAK,CAAC,eAAe,CAAC;oBACzC,SAAS,IAAI,KAAK,CAAC,SAAS,CAAC;gBAC/B,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,CAAC;IACxC,CAAC;IAEO,cAAc,CAAC,IAAS,EAAE,QAAgB;QAChD,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC/D,CAAC;aAAM,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC5C,MAAM,OAAO,GAAG,EAAE,GAAG,IAAI,EAAE,CAAC;YAE5B,4BAA4B;YAC5B,IAAI,QAAQ,KAAK,MAAM,IAAI,QAAQ,KAAK,YAAY,EAAE,CAAC;gBACrD,OAAO,OAAO,CAAC,UAAU,CAAC;YAC5B,CAAC;YACD,IAAI,QAAQ,KAAK,MAAM,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;gBAC/C,OAAO,OAAO,CAAC,IAAI,CAAC;YACtB,CAAC;YAED,2BAA2B;YAC3B,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;gBAC5B,MAAM,cAAc,GAAQ,EAAE,CAAC;gBAC/B,KAAK,MAAM,CAAC,UAAU,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC;oBAC/E,cAAc,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;gBACzE,CAAC;gBACD,OAAO,CAAC,eAAe,GAAG,cAAc,CAAC;YAC3C,CAAC;YAED,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;;AAvOH,4BAwOC","sourcesContent":["import { Command, Flags } from '@oclif/core';\nimport fs from 'fs-extra';\nimport path from 'path';\nimport { confirm } from '@inquirer/prompts';\nimport ora from 'ora-classic';\nimport fastGlob from 'fast-glob';\nimport chalk from 'chalk';\nimport { loadSyncConfig } from '../../config';\nimport { configManager } from '../../lib/config-manager';\n\nexport default class FileReset extends Command {\n static description = 'Remove primaryKey and sync sections from metadata JSON files';\n \n static examples = [\n `<%= config.bin %> <%= command.id %>`,\n `<%= config.bin %> <%= command.id %> --sections=primaryKey`,\n `<%= config.bin %> <%= command.id %> --sections=sync`,\n `<%= config.bin %> <%= command.id %> --dry-run`,\n `<%= config.bin %> <%= command.id %> --no-backup`,\n `<%= config.bin %> <%= command.id %> --yes`,\n ];\n \n static flags = {\n sections: Flags.string({\n description: 'Which sections to remove',\n options: ['both', 'primaryKey', 'sync'],\n default: 'both',\n }),\n 'dry-run': Flags.boolean({ \n description: 'Show what would be removed without actually removing' \n }),\n 'no-backup': Flags.boolean({ \n description: 'Skip creating backup files' \n }),\n yes: Flags.boolean({ \n char: 'y', \n description: 'Skip confirmation prompt' \n }),\n verbose: Flags.boolean({ \n char: 'v', \n description: 'Show detailed output' \n }),\n };\n \n async run(): Promise<void> {\n const { flags } = await this.parse(FileReset);\n const spinner = ora();\n \n try {\n // Load sync config\n const syncConfig = await loadSyncConfig(configManager.getOriginalCwd());\n if (!syncConfig) {\n this.error('No .mj-sync.json found in current directory');\n }\n \n // Find all metadata JSON files\n spinner.start('Finding metadata files');\n const pattern = syncConfig.filePattern || '.*.json';\n const files = await fastGlob(pattern, {\n cwd: configManager.getOriginalCwd(),\n absolute: true,\n ignore: ['.mj-sync.json', '.mj-folder.json'],\n });\n \n spinner.stop();\n \n if (files.length === 0) {\n this.log('No metadata files found');\n return;\n }\n \n this.log(`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 // Show what will be removed\n this.log('');\n if (flags.sections === 'both' || flags.sections === 'primaryKey') {\n this.log(`Will remove ${chalk.yellow(totalPrimaryKeys)} primaryKey section${totalPrimaryKeys === 1 ? '' : 's'} from ${chalk.yellow(filesWithPrimaryKey)} file${filesWithPrimaryKey === 1 ? '' : 's'}`);\n }\n if (flags.sections === 'both' || flags.sections === 'sync') {\n this.log(`Will remove ${chalk.yellow(totalSyncs)} sync section${totalSyncs === 1 ? '' : 's'} from ${chalk.yellow(filesWithSync)} file${filesWithSync === 1 ? '' : 's'}`);\n }\n \n if (flags['dry-run']) {\n this.log('');\n this.log(chalk.cyan('Dry run mode - no files will be modified'));\n \n if (flags.verbose) {\n this.log('');\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 this.log(`${path.relative(configManager.getOriginalCwd(), file)}:`);\n if (stats.primaryKeyCount > 0) {\n this.log(` - ${stats.primaryKeyCount} primaryKey section${stats.primaryKeyCount === 1 ? '' : 's'}`);\n }\n if (stats.syncCount > 0) {\n this.log(` - ${stats.syncCount} sync section${stats.syncCount === 1 ? '' : 's'}`);\n }\n }\n }\n }\n return;\n }\n \n // Confirm before proceeding\n if (!flags.yes) {\n const confirmed = await confirm({\n message: 'Do you want to proceed?',\n default: false,\n });\n \n if (!confirmed) {\n this.log('Operation cancelled');\n return;\n }\n }\n \n // Process files\n spinner.start('Processing files');\n let processedFiles = 0;\n let modifiedFiles = 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, flags.sections);\n \n // Only write if content changed\n if (JSON.stringify(cleanedContent) !== originalContent) {\n // Create backup if requested\n if (!flags['no-backup']) {\n const backupPath = `${file}.backup`;\n await fs.writeJson(backupPath, content, { spaces: 2 });\n }\n \n // Write cleaned content\n await fs.writeJson(file, cleanedContent, { spaces: 2 });\n modifiedFiles++;\n \n if (flags.verbose) {\n spinner.stop();\n this.log(`✓ ${path.relative(configManager.getOriginalCwd(), file)}`);\n spinner.start('Processing files');\n }\n }\n }\n \n spinner.stop();\n \n // Show summary\n this.log('');\n this.log(chalk.green(`✓ Reset complete`));\n this.log(` Processed: ${processedFiles} file${processedFiles === 1 ? '' : 's'}`);\n this.log(` Modified: ${modifiedFiles} file${modifiedFiles === 1 ? '' : 's'}`);\n if (!flags['no-backup'] && modifiedFiles > 0) {\n this.log(` Backups created: ${modifiedFiles}`);\n }\n \n } catch (error) {\n spinner.stop();\n this.error(error instanceof Error ? error.message : String(error));\n }\n }\n \n private countSections(data: any): { primaryKeyCount: number; syncCount: number } {\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}"]}
@@ -3,6 +3,7 @@ export default class Push extends Command {
3
3
  static description: string;
4
4
  private warnings;
5
5
  private errors;
6
+ private processedRecords;
6
7
  static examples: string[];
7
8
  static flags: {
8
9
  dir: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
@@ -17,4 +18,20 @@ export default class Push extends Command {
17
18
  private processJsonFiles;
18
19
  private pushRecord;
19
20
  private processRelatedEntities;
21
+ /**
22
+ * Generate a unique tracking key for a record based on entity name and primary key values
23
+ */
24
+ private generateRecordKey;
25
+ /**
26
+ * Check if a record has already been processed and warn if duplicate
27
+ */
28
+ private checkAndTrackRecord;
29
+ /**
30
+ * Parse JSON file and track line numbers for array elements
31
+ */
32
+ private parseJsonWithLineNumbers;
33
+ /**
34
+ * Format file location with clickable link for VSCode
35
+ */
36
+ private formatFileLocation;
20
37
  }