@docupace/pipeline 1.0.63 → 1.0.64

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,395 @@
1
+ import { mergeChangelogFile } from './merge-changelog.js';
2
+ import mergeTypes, { mergeTypesFile } from './merge-types.js';
3
+ import { existsSync, readFileSync, writeFileSync } from 'fs';
4
+ import mergePackageFile from './merge-package.js';
5
+ import { execSync } from 'child_process';
6
+
7
+ // Default merge configuration
8
+ const defaultMergeConfig = {
9
+ 'CHANGELOG.md': 'changelog',
10
+ '*/CHANGELOG.md': 'changelog',
11
+ '**/CHANGELOG.md': 'changelog',
12
+ 'src/types/graphql.ts': 'types',
13
+ 'codegen.ts': 'ours',
14
+ 'package.json': 'package',
15
+ '*/package.json': 'package',
16
+ '**/package.json': 'package',
17
+ };
18
+
19
+ // Available merge strategies
20
+ const mergeStrategies = {
21
+ changelog: mergeChangelogFile,
22
+ package: mergePackageFile,
23
+ types: mergeTypesFile,
24
+ ours: (filePath) => {
25
+ // Keep our version by checking out the HEAD version (removes conflicts)
26
+ try {
27
+ execSync(`git checkout --ours ${filePath}`);
28
+ execSync(`git add ${filePath}`);
29
+ console.log(
30
+ `📝 Using 'ours' strategy for ${filePath} - reset to HEAD version and marked as resolved`,
31
+ );
32
+ return true;
33
+ } catch (error) {
34
+ throw new Error(`Failed to apply 'ours' strategy: ${error.message}`);
35
+ }
36
+ },
37
+ theirs: (filePath) => {
38
+ // Take their version
39
+ try {
40
+ execSync(`git checkout --theirs ${filePath}`);
41
+ execSync(`git add ${filePath}`);
42
+ console.log(
43
+ `📝 Using 'theirs' strategy for ${filePath} - marked as resolved`,
44
+ );
45
+ return true;
46
+ } catch (error) {
47
+ throw new Error(`Failed to apply 'theirs' strategy: ${error.message}`);
48
+ }
49
+ },
50
+ };
51
+
52
+ /**
53
+ * Get list of conflicted files from git status
54
+ */
55
+ function getConflictedFiles() {
56
+ try {
57
+ const statusOutput = execSync('git status --porcelain', {
58
+ encoding: 'utf-8',
59
+ });
60
+ const conflictedFiles = statusOutput
61
+ .split('\n')
62
+ .filter(
63
+ (line) =>
64
+ line.startsWith('UU ') ||
65
+ line.startsWith('AA ') ||
66
+ line.startsWith('DD '),
67
+ )
68
+ .map((line) => line.substring(3).trim())
69
+ .filter((file) => file.length > 0);
70
+ return conflictedFiles;
71
+ } catch (error) {
72
+ throw new Error(`Failed to get git status: ${error.message}`);
73
+ }
74
+ }
75
+
76
+ /**
77
+ * Load merge configuration from .mergerc file or use defaults
78
+ */
79
+ function loadMergeConfig() {
80
+ const configPath = '.mergerc';
81
+
82
+ if (existsSync(configPath)) {
83
+ try {
84
+ const configContent = readFileSync(configPath, 'utf-8');
85
+ const config = {};
86
+
87
+ configContent.split('\n').forEach((line) => {
88
+ line = line.trim();
89
+ if (line && !line.startsWith('#')) {
90
+ const [pattern, strategy] = line
91
+ .split(/\s+merge=/)
92
+ .map((s) => s.trim());
93
+ if (pattern && strategy) {
94
+ config[pattern] = strategy;
95
+ }
96
+ }
97
+ });
98
+
99
+ return config;
100
+ } catch (error) {
101
+ console.warn(
102
+ `Warning: Could not read ${configPath}, using defaults: ${error.message}`,
103
+ );
104
+ }
105
+ }
106
+
107
+ return defaultMergeConfig;
108
+ }
109
+
110
+ /**
111
+ * Match file path against patterns (supports * and ** wildcards)
112
+ */
113
+ function matchPattern(filePath, pattern) {
114
+ // Handle ** at the beginning of pattern
115
+ if (pattern.startsWith('**/')) {
116
+ // Remove the **/ and check if the path ends with the remaining pattern
117
+ const remainingPattern = pattern.slice(3);
118
+ const regexPattern = remainingPattern
119
+ .replace(/\*/g, '[^/]*')
120
+ .replace(/\./g, '\\.')
121
+ .replace(/\//g, '\\/');
122
+
123
+ const regex = new RegExp(`(^|/)${regexPattern}$`);
124
+ return regex.test(filePath);
125
+ }
126
+
127
+ // For other cases, convert pattern to regex
128
+ const regexPattern = pattern
129
+ .replace(/\*\*/g, '___DOUBLESTAR___')
130
+ .replace(/\*/g, '[^/]*')
131
+ .replace(/___DOUBLESTAR___/g, '.*?')
132
+ .replace(/\./g, '\\.')
133
+ .replace(/\//g, '\\/');
134
+
135
+ const regex = new RegExp(`^${regexPattern}$`);
136
+ return regex.test(filePath);
137
+ }
138
+
139
+ /**
140
+ * Find merge strategy for a given file
141
+ */
142
+ function findMergeStrategy(filePath, config) {
143
+ // Check exact match first
144
+ if (config[filePath]) {
145
+ return config[filePath];
146
+ }
147
+
148
+ // Check pattern matches
149
+ for (const [pattern, strategy] of Object.entries(config)) {
150
+ if (matchPattern(filePath, pattern)) {
151
+ return strategy;
152
+ }
153
+ }
154
+
155
+ return null;
156
+ }
157
+
158
+ /**
159
+ * Create default .mergerc file
160
+ */
161
+ function createDefaultConfig() {
162
+ const configContent = `# Merge configuration file
163
+ # Format: <file-pattern> merge=<strategy>
164
+ # Strategies: changelog, package, types, ours, theirs
165
+
166
+ CHANGELOG.md merge=changelog
167
+ */CHANGELOG.md merge=changelog
168
+ **/CHANGELOG.md merge=changelog
169
+ src/types/graphql.ts merge=types
170
+ codegen.ts merge=ours
171
+ package.json merge=package
172
+ */package.json merge=package
173
+ **/package.json merge=package
174
+ `;
175
+
176
+ writeFileSync('.mergerc', configContent);
177
+ console.log('✅ Created default .mergerc configuration file');
178
+ }
179
+
180
+ export async function autoResolveConflicts(options = {}) {
181
+ const { dryRun = false, verbose = false } = options;
182
+
183
+ // Get conflicted files
184
+ const conflictedFiles = getConflictedFiles();
185
+
186
+ if (conflictedFiles.length === 0) {
187
+ if (verbose) console.log('✅ No conflicted files found');
188
+ return { success: true, resolvedCount: 0, skippedCount: 0, totalCount: 0 };
189
+ }
190
+
191
+ if (verbose) {
192
+ console.log(`Found ${conflictedFiles.length} conflicted files:`);
193
+ conflictedFiles.forEach((file) => console.log(` - ${file}`));
194
+ console.log('');
195
+ }
196
+
197
+ // Load configuration
198
+ const config = loadMergeConfig();
199
+
200
+ if (verbose) {
201
+ console.log('Merge configuration:');
202
+ Object.entries(config).forEach(([pattern, strategy]) => {
203
+ console.log(` ${pattern} -> ${strategy}`);
204
+ });
205
+ console.log('');
206
+ }
207
+
208
+ let resolvedCount = 0;
209
+ let skippedCount = 0;
210
+
211
+ // Process each conflicted file
212
+ for (const filePath of conflictedFiles) {
213
+ const strategy = findMergeStrategy(filePath, config);
214
+
215
+ if (!strategy) {
216
+ if (verbose)
217
+ console.log(`⚠️ No strategy found for ${filePath} - skipping`);
218
+ skippedCount++;
219
+ continue;
220
+ }
221
+
222
+ const mergeFunction = mergeStrategies[strategy];
223
+ if (!mergeFunction) {
224
+ if (verbose)
225
+ console.log(
226
+ `⚠️ Unknown strategy '${strategy}' for ${filePath} - skipping`,
227
+ );
228
+ skippedCount++;
229
+ continue;
230
+ }
231
+
232
+ if (dryRun) {
233
+ if (verbose)
234
+ console.log(`Would apply '${strategy}' strategy to ${filePath}`);
235
+ continue;
236
+ }
237
+
238
+ try {
239
+ if (verbose)
240
+ console.log(`🔧 Applying '${strategy}' strategy to ${filePath}`);
241
+ mergeFunction(filePath);
242
+ resolvedCount++;
243
+ } catch (error) {
244
+ console.error(`❌ Failed to resolve ${filePath}: ${error.message}`);
245
+ skippedCount++;
246
+ }
247
+ }
248
+
249
+ const result = {
250
+ success: skippedCount === 0,
251
+ resolvedCount,
252
+ skippedCount,
253
+ totalCount: conflictedFiles.length,
254
+ };
255
+
256
+ // Summary
257
+ if (verbose) {
258
+ console.log(`\n📊 Summary:`);
259
+ console.log(` Resolved: ${resolvedCount}`);
260
+ console.log(` Skipped: ${skippedCount}`);
261
+ console.log(` Total: ${conflictedFiles.length}`);
262
+
263
+ if (resolvedCount > 0 && !dryRun) {
264
+ console.log(`\n✅ Successfully resolved ${resolvedCount} conflicts`);
265
+ if (skippedCount === 0) {
266
+ console.log(
267
+ '🎉 All conflicts resolved! You can now commit the changes.',
268
+ );
269
+ }
270
+ }
271
+ }
272
+
273
+ return result;
274
+ }
275
+
276
+ export function setupResolve(program) {
277
+ program
278
+ .command('resolve-conflicts')
279
+ .description('Automatically resolve conflicts based on configuration')
280
+ .option(
281
+ '-c, --config <path>',
282
+ 'Path to merge configuration file',
283
+ '.mergerc',
284
+ )
285
+ .option('-n, --dry-run', 'Show what would be done without making changes')
286
+ .option('-v, --verbose', 'Verbose output')
287
+ .action(async (options) => {
288
+ try {
289
+ const result = await autoResolveConflicts(options);
290
+
291
+ if (!result.success) {
292
+ console.error(
293
+ `❌ Auto-resolve failed: ${result.skippedCount} files could not be resolved`,
294
+ );
295
+ process.exit(1);
296
+ }
297
+ } catch (error) {
298
+ console.error(`❌ Auto-resolve failed: ${error.message}`);
299
+ process.exit(1);
300
+ }
301
+ });
302
+
303
+ // New merge command
304
+
305
+ // Individual strategy commands
306
+ program
307
+ .command('resolve-changelog-conflicts')
308
+ .description('Merge changelog files by removing conflict markers')
309
+ .argument('<file>', 'File with merge conflicts')
310
+ .action(async (file) => {
311
+ try {
312
+ mergeChangelogFile(file);
313
+ console.log('✅ Changelog merge completed successfully');
314
+ } catch (error) {
315
+ console.error(`❌ Changelog merge failed: ${error.message}`);
316
+ process.exit(1);
317
+ }
318
+ });
319
+
320
+ program
321
+ .command('resolve-package-conflicts')
322
+ .description('Merge package.json files by resolving version conflicts')
323
+ .argument('<file>', 'File with merge conflicts')
324
+ .action(async (file) => {
325
+ try {
326
+ await mergePackageFile(file);
327
+ console.log('✅ Package merge completed successfully');
328
+ } catch (error) {
329
+ console.error(`❌ Package merge failed: ${error.message}`);
330
+ process.exit(1);
331
+ }
332
+ });
333
+
334
+ program
335
+ .command('resolve-type-conflicts')
336
+ .description('Merge types files with balanced brace checking')
337
+ .argument('<file>', 'File with merge conflicts')
338
+ .action(async (file) => {
339
+ try {
340
+ await mergeTypes(file);
341
+ console.log('✅ Types merge completed successfully');
342
+ } catch (error) {
343
+ console.error(`❌ Types merge failed: ${error.message}`);
344
+ process.exit(1);
345
+ }
346
+ });
347
+
348
+ // Configuration commands
349
+ program
350
+ .command('init')
351
+ .description('Create default .mergerc configuration file')
352
+ .action(() => {
353
+ if (existsSync('.mergerc')) {
354
+ console.log('⚠️ .mergerc already exists. Use --force to overwrite.');
355
+ return;
356
+ }
357
+ createDefaultConfig();
358
+ });
359
+
360
+ program
361
+ .command('config')
362
+ .description('Show current merge configuration')
363
+ .action(() => {
364
+ const config = loadMergeConfig();
365
+ console.log('Current merge configuration:');
366
+ Object.entries(config).forEach(([pattern, strategy]) => {
367
+ console.log(` ${pattern.padEnd(30)} -> ${strategy}`);
368
+ });
369
+ });
370
+
371
+ program
372
+ .command('status')
373
+ .description('Show conflicted files and their assigned strategies')
374
+ .action(() => {
375
+ try {
376
+ const conflictedFiles = getConflictedFiles();
377
+ const config = loadMergeConfig();
378
+
379
+ if (conflictedFiles.length === 0) {
380
+ console.log('✅ No conflicted files found');
381
+ return;
382
+ }
383
+
384
+ console.log('Conflicted files and their strategies:');
385
+ conflictedFiles.forEach((file) => {
386
+ const strategy = findMergeStrategy(file, config);
387
+ const status = strategy ? `-> ${strategy}` : '-> no strategy';
388
+ console.log(` ${file.padEnd(40)} ${status}`);
389
+ });
390
+ } catch (error) {
391
+ console.error(`❌ Failed to get status: ${error.message}`);
392
+ process.exit(1);
393
+ }
394
+ });
395
+ }
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env node
2
+ import dotenv from 'dotenv';
3
+ dotenv.config({ path: ['.env.pipeline.local', 'config/.env.pipeline.local'] });
4
+
5
+ import { Command } from 'commander';
6
+ import { setupMerge } from './cli-merge.js';
7
+ import { setupResolve } from './cli-resolve.js';
8
+ import { setupMergeAll } from './cli-merge-all.js';
9
+
10
+ const args = process.argv;
11
+ const program = new Command();
12
+
13
+ /**
14
+ * Reusable auto-resolve function
15
+ * @param {Object} options - Options object with config, dryRun, verbose properties
16
+ * @returns {Object} - Result object with counts and success status
17
+ */
18
+
19
+ // Main program
20
+ program
21
+ .name('merge-cli')
22
+ .description(
23
+ 'Automatically resolve git merge conflicts based on file patterns',
24
+ )
25
+ .version('1.0.0');
26
+
27
+ // Auto-resolve command (now uses the reusable function)
28
+
29
+ setupResolve(program);
30
+ setupMerge(program);
31
+ setupMergeAll(program);
32
+ // Parse command line arguments
33
+ program.parse(args);
34
+
35
+ // Show help if no arguments provided
36
+ if (!args.slice(2).length) {
37
+ program.outputHelp();
38
+ }
@@ -0,0 +1,87 @@
1
+ import fs from 'fs';
2
+ import { execSync } from 'child_process';
3
+
4
+ /**
5
+ * Simple changelog merger class
6
+ */
7
+
8
+ class ChangelogMerger {
9
+ constructor() {
10
+ this.content = '';
11
+ }
12
+
13
+ /**
14
+ * Parse a file with merge conflicts and clean up conflict markers
15
+ */
16
+ parseConflict(content) {
17
+ const lines = content.split('\n');
18
+ const cleanedLines = [];
19
+
20
+ for (const line of lines) {
21
+ if (line.startsWith('<<<<<<<')) {
22
+ // Remove conflict start marker
23
+ continue;
24
+ } else if (line.startsWith('=======')) {
25
+ // Replace separator with empty line
26
+ cleanedLines.push('');
27
+ continue;
28
+ } else if (line.startsWith('>>>>>>>')) {
29
+ // Remove conflict end marker
30
+ continue;
31
+ } else {
32
+ // Keep all other lines
33
+ cleanedLines.push(line);
34
+ }
35
+ }
36
+
37
+ this.content = cleanedLines.join('\n');
38
+ }
39
+
40
+ /**
41
+ * Generate the merged changelog content
42
+ */
43
+ generateMerged() {
44
+ return this.content;
45
+ }
46
+ }
47
+
48
+ /**
49
+ * Changelog merge strategy - removes conflict markers and combines content
50
+ * @param {string} conflictContent - Content with conflict markers
51
+ * @returns {string} - Merged content
52
+ */
53
+ export function mergeChangelog(conflictContent) {
54
+ const merger = new ChangelogMerger();
55
+ merger.parseConflict(conflictContent);
56
+ return merger.generateMerged();
57
+ }
58
+
59
+ /**
60
+ * Main function for processing a file with merge conflicts
61
+ */
62
+ export function mergeChangelogFile(filePath) {
63
+ try {
64
+ // Read the file (which contains the conflict markers)
65
+ const fileContent = fs.readFileSync(filePath, 'utf-8');
66
+ const result = mergeChangelog(fileContent);
67
+
68
+ // Write result back to the same file
69
+ fs.writeFileSync(filePath, result);
70
+
71
+ // Add file to git staging area to mark as resolved
72
+ try {
73
+ execSync(`git add ${filePath}`);
74
+ console.log('📝 File added to git staging area');
75
+ } catch (error) {
76
+ console.log(
77
+ '⚠️ Could not add file to git (may not be in a git repository)',
78
+ );
79
+ }
80
+
81
+ console.log('Changelog merge completed successfully');
82
+ return true;
83
+ } catch (error) {
84
+ console.error(`Merge failed: ${error.message}`);
85
+ throw error;
86
+ }
87
+ }
@@ -0,0 +1,106 @@
1
+ import fs from 'fs';
2
+ import { mergeDriver } from '../lib/merge-driver.js';
3
+
4
+ /**
5
+ * Custom merge logic for package.json files
6
+ * Resolves version conflicts by taking HEAD version
7
+ * @param {string} headContent - Content from HEAD (current branch)
8
+ * @param {string} branchContent - Content from incoming branch
9
+ * @returns {string} - Merged content
10
+ * @throws {Error} - If conflicts are not version-only
11
+ */
12
+ function packageMergeLogic(headContent, branchContent) {
13
+ // Check if this is a version-only conflict
14
+ if (isVersionOnlyConflict(headContent, branchContent)) {
15
+ // Take the HEAD version
16
+ return headContent;
17
+ } else {
18
+ // Throw error to keep the conflict unresolved
19
+ throw new Error('Conflict contains more than just version differences');
20
+ }
21
+ }
22
+
23
+ /**
24
+ * Check if conflict is version-only
25
+ * @param {string} headContent - Content from HEAD
26
+ * @param {string} branchContent - Content from branch
27
+ * @returns {boolean} - True if only version differs
28
+ */
29
+ function isVersionOnlyConflict(headContent, branchContent) {
30
+ const headVersionMatch = headContent.match(/"version"\s*:\s*"([^"]+)"/);
31
+ const branchVersionMatch = branchContent.match(/"version"\s*:\s*"([^"]+)"/);
32
+
33
+ if (!headVersionMatch || !branchVersionMatch) {
34
+ return false;
35
+ }
36
+
37
+ // Remove version lines and check if there's any other content
38
+ const headWithoutVersion = headContent
39
+ .replace(/"version"\s*:\s*"[^"]+",?\s*/g, '')
40
+ .trim();
41
+ const branchWithoutVersion = branchContent
42
+ .replace(/"version"\s*:\s*"[^"]+",?\s*/g, '')
43
+ .trim();
44
+
45
+ // If both are empty after removing version, it's version-only
46
+ // Also handle case where there might be whitespace or comma differences
47
+ if (!headWithoutVersion && !branchWithoutVersion) {
48
+ return true;
49
+ }
50
+
51
+ // Additional check: if the only difference is trailing comma or whitespace
52
+ const normalizeContent = (content) => {
53
+ return content
54
+ .replace(/,\s*$/, '') // Remove trailing comma
55
+ .replace(/\s+/g, ' ') // Normalize whitespace
56
+ .trim();
57
+ };
58
+
59
+ return (
60
+ normalizeContent(headWithoutVersion) ===
61
+ normalizeContent(branchWithoutVersion)
62
+ );
63
+ }
64
+
65
+ /**
66
+ * Main function to merge package.json conflicts using merge-driver
67
+ * @param {string} filePath - Path to package.json file
68
+ * @returns {Promise<boolean>} - True if successful
69
+ */
70
+ export async function mergePackageFile(filePath) {
71
+ try {
72
+ // Check if file exists
73
+ if (!fs.existsSync(filePath)) {
74
+ throw new Error(`File not found: ${filePath}`);
75
+ }
76
+
77
+ console.log(`🔄 Merging package.json conflicts in: ${filePath}`);
78
+
79
+ // Use merge driver with custom package.json merge logic
80
+ const result = await mergeDriver(filePath, packageMergeLogic);
81
+
82
+ // Log results
83
+ if (result.success) {
84
+ console.log('✅ Package merge completed successfully');
85
+ if (result.totalConflicts > 0) {
86
+ console.log(
87
+ ` Resolved ${result.resolvedConflicts} version-only conflicts`,
88
+ );
89
+ }
90
+ } else {
91
+ console.log('⚠️ Package merge partially completed');
92
+ console.log(
93
+ ` ${result.resolvedConflicts} of ${result.totalConflicts} conflicts resolved`,
94
+ );
95
+ console.log(' Non-version conflicts require manual resolution');
96
+ }
97
+
98
+ return result.success;
99
+ } catch (error) {
100
+ console.error(`❌ Merge failed: ${error.message}`);
101
+ throw error;
102
+ }
103
+ }
104
+
105
+ // Default export
106
+ export default mergePackageFile;
@@ -0,0 +1,82 @@
1
+ import { mergeDriver } from '../lib/merge-driver.js';
2
+
3
+ /**
4
+ * Codegen-specific merge logic for handling balanced braces and removing duplicates
5
+ * @param {string} headContent - Content from HEAD (current branch)
6
+ * @param {string} branchContent - Content from the incoming branch
7
+ * @returns {string} - Merged content
8
+ * @throws {Error} - If conflicts cannot be automatically merged
9
+ */
10
+ function codegenMergeLogic(headContent, branchContent) {
11
+ // Check if braces are balanced in both head and branch content
12
+ const headOpenBraces = (headContent.match(/\{/g) || []).length;
13
+ const headCloseBraces = (headContent.match(/\}/g) || []).length;
14
+ const branchOpenBraces = (branchContent.match(/\{/g) || []).length;
15
+ const branchCloseBraces = (branchContent.match(/\}/g) || []).length;
16
+
17
+ // Check if head content has balanced braces
18
+ const headHasBraces = headOpenBraces > 0 || headCloseBraces > 0;
19
+ const headBalanced = headOpenBraces === headCloseBraces;
20
+
21
+ // Check if branch content has balanced braces
22
+ const branchHasBraces = branchOpenBraces > 0 || branchCloseBraces > 0;
23
+ const branchBalanced = branchOpenBraces === branchCloseBraces;
24
+
25
+ // If either has braces and they're not balanced, we can't merge
26
+ if (
27
+ (headHasBraces && !headBalanced) ||
28
+ (branchHasBraces && !branchBalanced)
29
+ ) {
30
+ throw new Error('Unbalanced braces detected - cannot merge automatically');
31
+ }
32
+
33
+ // If both have balanced braces, combine them as-is
34
+ if (headHasBraces && branchHasBraces && headBalanced && branchBalanced) {
35
+ return headContent + '\n' + branchContent;
36
+ }
37
+
38
+ // If neither has braces, combine and remove duplicates
39
+ if (!headHasBraces && !branchHasBraces) {
40
+ const headLines = headContent.split('\n').filter((line) => line);
41
+ const branchLines = branchContent.split('\n').filter((line) => line);
42
+
43
+ // Use Set to remove duplicates while preserving order
44
+ const uniqueLines = [...new Set([...headLines, ...branchLines])];
45
+
46
+ return uniqueLines.join('\n');
47
+ }
48
+
49
+ // Mixed case: one has braces, one doesn't - combine as-is
50
+ return headContent + '\n' + branchContent;
51
+ }
52
+
53
+ /**
54
+ * Main function to merge codegen conflicts in a types file
55
+ * @param {string} filePath - Path to the file with conflicts
56
+ * @returns {Promise<Object>} - Result object with merge details
57
+ */
58
+ export async function mergeTypesFile(filePath) {
59
+ try {
60
+ console.log('Starting codegen merge for types file...');
61
+
62
+ // Use the merge driver with our custom codegen logic
63
+ const result = await mergeDriver(filePath, codegenMergeLogic);
64
+
65
+ if (result.success) {
66
+ console.log('✅ Codegen merge completed successfully');
67
+ } else {
68
+ console.log('⚠️ Codegen merge completed with unresolved conflicts');
69
+ }
70
+
71
+ return result;
72
+ } catch (error) {
73
+ console.error(`Codegen merge failed: ${error.message}`);
74
+ throw error;
75
+ }
76
+ }
77
+
78
+ // Export the merge logic function for direct use if needed
79
+ export { codegenMergeLogic };
80
+
81
+ // Default export
82
+ export default mergeTypesFile;