sf-git-merge-driver 1.3.0 → 1.4.0-dev-159.21317248282-1
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 +30 -6
- package/lib/commands/git/merge/driver/run.js +3 -5
- package/lib/commands/git/merge/driver/run.js.map +1 -1
- package/lib/constant/conflictConstant.d.ts +3 -3
- package/lib/constant/conflictConstant.js +3 -3
- package/lib/constant/conflictConstant.js.map +1 -1
- package/lib/constant/metadataConstant.d.ts +1 -0
- package/lib/constant/metadataConstant.js +7 -0
- package/lib/constant/metadataConstant.js.map +1 -1
- package/lib/constant/parserConstant.d.ts +6 -0
- package/lib/constant/parserConstant.js +6 -0
- package/lib/constant/parserConstant.js.map +1 -1
- package/lib/driver/MergeDriver.d.ts +3 -0
- package/lib/driver/MergeDriver.js +5 -1
- package/lib/driver/MergeDriver.js.map +1 -1
- package/lib/merger/ConflictMarkerBuilder.d.ts +3 -0
- package/lib/merger/ConflictMarkerBuilder.js +33 -0
- package/lib/merger/ConflictMarkerBuilder.js.map +1 -0
- package/lib/merger/ConflictMarkerFormatter.d.ts +14 -0
- package/lib/merger/ConflictMarkerFormatter.js +43 -0
- package/lib/merger/ConflictMarkerFormatter.js.map +1 -0
- package/lib/merger/JsonMerger.d.ts +3 -0
- package/lib/merger/JsonMerger.js +19 -194
- package/lib/merger/JsonMerger.js.map +1 -1
- package/lib/merger/MergeContext.d.ts +17 -0
- package/lib/merger/MergeContext.js +2 -0
- package/lib/merger/MergeContext.js.map +1 -0
- package/lib/merger/MergeOrchestrator.d.ts +13 -0
- package/lib/merger/MergeOrchestrator.js +46 -0
- package/lib/merger/MergeOrchestrator.js.map +1 -0
- package/lib/merger/MergeScenarioFactory.d.ts +2 -0
- package/lib/merger/MergeScenarioFactory.js +22 -0
- package/lib/merger/MergeScenarioFactory.js.map +1 -0
- package/lib/merger/XmlMerger.d.ts +5 -0
- package/lib/merger/XmlMerger.js +19 -16
- package/lib/merger/XmlMerger.js.map +1 -1
- package/lib/merger/nodes/KeyedArrayMergeNode.d.ts +12 -0
- package/lib/merger/nodes/KeyedArrayMergeNode.js +67 -0
- package/lib/merger/nodes/KeyedArrayMergeNode.js.map +1 -0
- package/lib/merger/nodes/MergeNode.d.ts +5 -0
- package/lib/merger/nodes/MergeNode.js +2 -0
- package/lib/merger/nodes/MergeNode.js.map +1 -0
- package/lib/merger/nodes/MergeNodeFactory.d.ts +9 -0
- package/lib/merger/nodes/MergeNodeFactory.js +21 -0
- package/lib/merger/nodes/MergeNodeFactory.js.map +1 -0
- package/lib/merger/nodes/ObjectMergeNode.d.ts +20 -0
- package/lib/merger/nodes/ObjectMergeNode.js +49 -0
- package/lib/merger/nodes/ObjectMergeNode.js.map +1 -0
- package/lib/merger/nodes/TextArrayMergeNode.d.ts +12 -0
- package/lib/merger/nodes/TextArrayMergeNode.js +66 -0
- package/lib/merger/nodes/TextArrayMergeNode.js.map +1 -0
- package/lib/merger/nodes/TextMergeNode.d.ts +12 -0
- package/lib/merger/nodes/TextMergeNode.js +36 -0
- package/lib/merger/nodes/TextMergeNode.js.map +1 -0
- package/lib/merger/nodes/nodeUtils.d.ts +5 -0
- package/lib/merger/nodes/nodeUtils.js +20 -0
- package/lib/merger/nodes/nodeUtils.js.map +1 -0
- package/lib/merger/strategies/AllPresentStrategy.d.ts +7 -0
- package/lib/merger/strategies/AllPresentStrategy.js +36 -0
- package/lib/merger/strategies/AllPresentStrategy.js.map +1 -0
- package/lib/merger/strategies/AncestorAndLocalStrategy.d.ts +8 -0
- package/lib/merger/strategies/AncestorAndLocalStrategy.js +64 -0
- package/lib/merger/strategies/AncestorAndLocalStrategy.js.map +1 -0
- package/lib/merger/strategies/AncestorAndOtherStrategy.d.ts +8 -0
- package/lib/merger/strategies/AncestorAndOtherStrategy.js +64 -0
- package/lib/merger/strategies/AncestorAndOtherStrategy.js.map +1 -0
- package/lib/merger/strategies/AncestorOnlyStrategy.d.ts +6 -0
- package/lib/merger/strategies/AncestorOnlyStrategy.js +19 -0
- package/lib/merger/strategies/AncestorOnlyStrategy.js.map +1 -0
- package/lib/merger/strategies/LocalAndOtherStrategy.d.ts +7 -0
- package/lib/merger/strategies/LocalAndOtherStrategy.js +45 -0
- package/lib/merger/strategies/LocalAndOtherStrategy.js.map +1 -0
- package/lib/merger/strategies/LocalOnlyStrategy.d.ts +6 -0
- package/lib/merger/strategies/LocalOnlyStrategy.js +14 -0
- package/lib/merger/strategies/LocalOnlyStrategy.js.map +1 -0
- package/lib/merger/strategies/NoneStrategy.d.ts +6 -0
- package/lib/merger/strategies/NoneStrategy.js +8 -0
- package/lib/merger/strategies/NoneStrategy.js.map +1 -0
- package/lib/merger/strategies/OtherOnlyStrategy.d.ts +6 -0
- package/lib/merger/strategies/OtherOnlyStrategy.js +14 -0
- package/lib/merger/strategies/OtherOnlyStrategy.js.map +1 -0
- package/lib/merger/strategies/ScenarioStrategy.d.ts +5 -0
- package/lib/merger/strategies/ScenarioStrategy.js +2 -0
- package/lib/merger/strategies/ScenarioStrategy.js.map +1 -0
- package/lib/merger/strategies/ScenarioStrategyFactory.d.ts +3 -0
- package/lib/merger/strategies/ScenarioStrategyFactory.js +23 -0
- package/lib/merger/strategies/ScenarioStrategyFactory.js.map +1 -0
- package/lib/merger/strategies/TextMergeStrategy.d.ts +32 -0
- package/lib/merger/strategies/TextMergeStrategy.js +80 -0
- package/lib/merger/strategies/TextMergeStrategy.js.map +1 -0
- package/lib/service/MetadataService.js +2 -0
- package/lib/service/MetadataService.js.map +1 -1
- package/lib/service/NamespaceHandler.js +1 -2
- package/lib/service/NamespaceHandler.js.map +1 -1
- package/lib/service/installService.js +5 -3
- package/lib/service/installService.js.map +1 -1
- package/lib/types/conflictTypes.d.ts +1 -1
- package/lib/types/mergeResult.d.ts +8 -0
- package/lib/types/mergeResult.js +33 -0
- package/lib/types/mergeResult.js.map +1 -0
- package/lib/types/mergeScenario.d.ts +0 -1
- package/lib/types/mergeScenario.js +0 -20
- package/lib/types/mergeScenario.js.map +1 -1
- package/lib/utils/mergeUtils.d.ts +0 -4
- package/lib/utils/mergeUtils.js +0 -7
- package/lib/utils/mergeUtils.js.map +1 -1
- package/npm-shrinkwrap.json +724 -721
- package/oclif.manifest.json +4 -4
- package/package.json +9 -9
- package/lib/merger/conflictMarker.d.ts +0 -12
- package/lib/merger/conflictMarker.js +0 -37
- package/lib/merger/conflictMarker.js.map +0 -1
- package/lib/merger/textAttribute.d.ts +0 -3
- package/lib/merger/textAttribute.js +0 -56
- package/lib/merger/textAttribute.js.map +0 -1
package/README.md
CHANGED
|
@@ -36,6 +36,30 @@ sequenceDiagram
|
|
|
36
36
|
Git->>Dev: Clean commit (no conflicts)
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
+
## Conflict Style
|
|
40
|
+
|
|
41
|
+
This merge driver follows the **zdiff3** conflict style philosophy:
|
|
42
|
+
|
|
43
|
+
- **Shows the most compact diff possible**: Only the specific conflicting elements are marked, not entire file sections
|
|
44
|
+
- **Includes ancestor context**: Conflicts display the base (ancestor) version alongside local and remote changes
|
|
45
|
+
- **Respects Git configuration**: Conflict marker size and labels are configurable via Git's standard parameters (`-L`, `-S`, `-X`, `-Y` flags)
|
|
46
|
+
|
|
47
|
+
Example conflict output:
|
|
48
|
+
```xml
|
|
49
|
+
<<<<<<< ours
|
|
50
|
+
<field>localValue</field>
|
|
51
|
+
||||||| base
|
|
52
|
+
<field>originalValue</field>
|
|
53
|
+
=======
|
|
54
|
+
<field>remoteValue</field>
|
|
55
|
+
>>>>>>> theirs
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
This approach helps you understand:
|
|
59
|
+
1. What the original value was (`base`)
|
|
60
|
+
2. What your branch changed it to (`ours`)
|
|
61
|
+
3. What the other branch changed it to (`theirs`)
|
|
62
|
+
|
|
39
63
|
## Installation (30 seconds)
|
|
40
64
|
|
|
41
65
|
```bash
|
|
@@ -255,7 +279,7 @@ EXAMPLES
|
|
|
255
279
|
$ sf git merge driver install
|
|
256
280
|
```
|
|
257
281
|
|
|
258
|
-
_See code: [src/commands/git/merge/driver/install.ts](https://github.com/scolladon/sf-git-merge-driver/blob/v1.
|
|
282
|
+
_See code: [src/commands/git/merge/driver/install.ts](https://github.com/scolladon/sf-git-merge-driver/blob/v1.4.0-dev-159.21317248282-1/src/commands/git/merge/driver/install.ts)_
|
|
259
283
|
|
|
260
284
|
## `sf git merge driver run`
|
|
261
285
|
|
|
@@ -272,9 +296,9 @@ FLAGS
|
|
|
272
296
|
-L, --conflict-marker-size=<value> [default: 7] number of characters to show for conflict markers
|
|
273
297
|
-O, --ancestor-file=<value> (required) path to the common ancestor version of the file
|
|
274
298
|
-P, --output-file=<value> (required) path to the file where the merged content will be written
|
|
275
|
-
-S, --ancestor-conflict-tag=<value> [default:
|
|
276
|
-
-X, --local-conflict-tag=<value> [default:
|
|
277
|
-
-Y, --other-conflict-tag=<value> [default:
|
|
299
|
+
-S, --ancestor-conflict-tag=<value> [default: base] string used to tag ancestor version in conflicts
|
|
300
|
+
-X, --local-conflict-tag=<value> [default: ours] string used to tag local version in conflicts
|
|
301
|
+
-Y, --other-conflict-tag=<value> [default: theirs] string used to tag other version in conflicts
|
|
278
302
|
|
|
279
303
|
GLOBAL FLAGS
|
|
280
304
|
--flags-dir=<value> Import flag values from a directory.
|
|
@@ -299,7 +323,7 @@ EXAMPLES
|
|
|
299
323
|
- output-file is the path to the file where the merged content will be written
|
|
300
324
|
```
|
|
301
325
|
|
|
302
|
-
_See code: [src/commands/git/merge/driver/run.ts](https://github.com/scolladon/sf-git-merge-driver/blob/v1.
|
|
326
|
+
_See code: [src/commands/git/merge/driver/run.ts](https://github.com/scolladon/sf-git-merge-driver/blob/v1.4.0-dev-159.21317248282-1/src/commands/git/merge/driver/run.ts)_
|
|
303
327
|
|
|
304
328
|
## `sf git merge driver uninstall`
|
|
305
329
|
|
|
@@ -329,7 +353,7 @@ EXAMPLES
|
|
|
329
353
|
$ sf git merge driver uninstall
|
|
330
354
|
```
|
|
331
355
|
|
|
332
|
-
_See code: [src/commands/git/merge/driver/uninstall.ts](https://github.com/scolladon/sf-git-merge-driver/blob/v1.
|
|
356
|
+
_See code: [src/commands/git/merge/driver/uninstall.ts](https://github.com/scolladon/sf-git-merge-driver/blob/v1.4.0-dev-159.21317248282-1/src/commands/git/merge/driver/uninstall.ts)_
|
|
333
357
|
<!-- commandsstop -->
|
|
334
358
|
## Changelog
|
|
335
359
|
|
|
@@ -4,7 +4,6 @@ import { Flags, SfCommand } from '@salesforce/sf-plugins-core';
|
|
|
4
4
|
import { DEFAULT_ANCESTOR_CONFLICT_TAG, DEFAULT_CONFLICT_MARKER_SIZE, DEFAULT_LOCAL_CONFLICT_TAG, DEFAULT_OTHER_CONFLICT_TAG, } from '../../../../constant/conflictConstant.js';
|
|
5
5
|
import { PLUGIN_NAME } from '../../../../constant/pluginConstant.js';
|
|
6
6
|
import { MergeDriver } from '../../../../driver/MergeDriver.js';
|
|
7
|
-
import { ConflictMarker } from '../../../../merger/conflictMarker.js';
|
|
8
7
|
import { log } from '../../../../utils/LoggingDecorator.js';
|
|
9
8
|
import { Logger } from '../../../../utils/LoggingService.js';
|
|
10
9
|
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
|
|
@@ -65,16 +64,15 @@ export default class Run extends SfCommand {
|
|
|
65
64
|
async run() {
|
|
66
65
|
Logger.info('Merge starting');
|
|
67
66
|
const { flags } = await this.parse(Run);
|
|
68
|
-
const
|
|
67
|
+
const config = {
|
|
69
68
|
conflictMarkerSize: flags['conflict-marker-size'],
|
|
70
69
|
ancestorConflictTag: flags['ancestor-conflict-tag'],
|
|
71
70
|
localConflictTag: flags['local-conflict-tag'],
|
|
72
71
|
otherConflictTag: flags['other-conflict-tag'],
|
|
73
72
|
};
|
|
74
|
-
ConflictMarker.setConflictConfig(conflicConfig);
|
|
75
73
|
Logger.debug(`flags: ${JSON.stringify(flags)}`);
|
|
76
|
-
Logger.debug(`
|
|
77
|
-
const mergeDriver = new MergeDriver();
|
|
74
|
+
Logger.debug(`config: ${JSON.stringify(config)}`);
|
|
75
|
+
const mergeDriver = new MergeDriver(config);
|
|
78
76
|
const hasConflict = await mergeDriver.mergeFiles(flags['ancestor-file'], flags['local-file'], flags['other-file']);
|
|
79
77
|
Logger.info(`Merge completed with ${hasConflict ? 'conflicts' : 'no conflicts'}`);
|
|
80
78
|
process.exitCode = hasConflict ? ERROR_EXIT_CODE : SUCCESS_EXIT_CODE;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../../../../src/commands/git/merge/driver/run.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAA;AAC9D,OAAO,EACL,6BAA6B,EAC7B,4BAA4B,EAC5B,0BAA0B,EAC1B,0BAA0B,GAC3B,MAAM,0CAA0C,CAAA;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,wCAAwC,CAAA;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAA;
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../../../../src/commands/git/merge/driver/run.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ export declare const DEFAULT_CONFLICT_MARKER_SIZE = 7;
|
|
|
2
2
|
export declare const ANCESTOR_CONFLICT_MARKER = "|";
|
|
3
3
|
export declare const LOCAL_CONFLICT_MARKER = "<";
|
|
4
4
|
export declare const OTHER_CONFLICT_MARKER = ">";
|
|
5
|
-
export declare const DEFAULT_ANCESTOR_CONFLICT_TAG = "
|
|
6
|
-
export declare const DEFAULT_LOCAL_CONFLICT_TAG = "
|
|
7
|
-
export declare const DEFAULT_OTHER_CONFLICT_TAG = "
|
|
5
|
+
export declare const DEFAULT_ANCESTOR_CONFLICT_TAG = "base";
|
|
6
|
+
export declare const DEFAULT_LOCAL_CONFLICT_TAG = "ours";
|
|
7
|
+
export declare const DEFAULT_OTHER_CONFLICT_TAG = "theirs";
|
|
8
8
|
export declare const SEPARATOR = "=";
|
|
@@ -2,8 +2,8 @@ export const DEFAULT_CONFLICT_MARKER_SIZE = 7;
|
|
|
2
2
|
export const ANCESTOR_CONFLICT_MARKER = '|';
|
|
3
3
|
export const LOCAL_CONFLICT_MARKER = '<';
|
|
4
4
|
export const OTHER_CONFLICT_MARKER = '>';
|
|
5
|
-
export const DEFAULT_ANCESTOR_CONFLICT_TAG = '
|
|
6
|
-
export const DEFAULT_LOCAL_CONFLICT_TAG = '
|
|
7
|
-
export const DEFAULT_OTHER_CONFLICT_TAG = '
|
|
5
|
+
export const DEFAULT_ANCESTOR_CONFLICT_TAG = 'base';
|
|
6
|
+
export const DEFAULT_LOCAL_CONFLICT_TAG = 'ours';
|
|
7
|
+
export const DEFAULT_OTHER_CONFLICT_TAG = 'theirs';
|
|
8
8
|
export const SEPARATOR = '=';
|
|
9
9
|
//# sourceMappingURL=conflictConstant.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conflictConstant.js","sourceRoot":"","sources":["../../src/constant/conflictConstant.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,CAAA;AAC7C,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAG,CAAA;AAC3C,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,CAAA;AACxC,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,CAAA;AACxC,MAAM,CAAC,MAAM,6BAA6B,GAAG,MAAM,CAAA;AACnD,MAAM,CAAC,MAAM,0BAA0B,GAAG,
|
|
1
|
+
{"version":3,"file":"conflictConstant.js","sourceRoot":"","sources":["../../src/constant/conflictConstant.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,CAAA;AAC7C,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAG,CAAA;AAC3C,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,CAAA;AACxC,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,CAAA;AACxC,MAAM,CAAC,MAAM,6BAA6B,GAAG,MAAM,CAAA;AACnD,MAAM,CAAC,MAAM,0BAA0B,GAAG,MAAM,CAAA;AAChD,MAAM,CAAC,MAAM,0BAA0B,GAAG,QAAQ,CAAA;AAClD,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,CAAA"}
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
export const SALESFORCE_EOL = '\n';
|
|
2
|
+
// Patterns for manifest files (like package.xml, destructiveChanges.xml)
|
|
3
|
+
export const MANIFEST_PATTERNS = [
|
|
4
|
+
'package.xml',
|
|
5
|
+
'destructiveChanges.xml',
|
|
6
|
+
'destructiveChangesPre.xml',
|
|
7
|
+
'destructiveChangesPost.xml',
|
|
8
|
+
];
|
|
2
9
|
export const METADATA_TYPES_PATTERNS = [
|
|
3
10
|
'labels', // CustomLabels
|
|
4
11
|
'label', // CustomLabels decomposed
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metadataConstant.js","sourceRoot":"","sources":["../../src/constant/metadataConstant.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,CAAA;AAElC,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,QAAQ,EAAE,eAAe;IACzB,OAAO,EAAE,0BAA0B;IACnC,SAAS,EAAE,UAAU;IACrB,eAAe,EAAE,gBAAgB;IACjC,uBAAuB,EAAE,2BAA2B;IACpD,aAAa;IACb,0BAA0B;IAC1B,kBAAkB;IAClB,qBAAqB;IACrB,mCAAmC;IACnC,0BAA0B;IAC1B,iBAAiB;IACjB,YAAY;IACZ,kBAAkB;IAClB,YAAY;IACZ,sBAAsB;IACtB,YAAY;IACZ,gBAAgB;IAChB,gBAAgB;IAChB,oBAAoB,EAAE,qBAAqB;IAC3C,gCAAgC,EAAE,iCAAiC;IACnE,qBAAqB,EAAE,sBAAsB;IAC7C,cAAc,EAAE,eAAe;IAC/B,qBAAqB,EAAE,0BAA0B;IACjD,kBAAkB;IAClB,kBAAkB;IAClB,sBAAsB;IACtB,UAAU,EAAE,WAAW;IACvB,eAAe,EAAE,sBAAsB;IACvC,qBAAqB;IACrB,oBAAoB;IACpB,0BAA0B;IAC1B,yBAAyB;IACzB,cAAc;IACd,cAAc;IACd,cAAc;IACd,iBAAiB,EAAE,kBAAkB;IACrC,mBAAmB,EAAE,oBAAoB;IACzC,iBAAiB,EAAE,kBAAkB;IACrC,uBAAuB,EAAE,wBAAwB;IACjD,cAAc,EAAE,gBAAgB;IAChC,gBAAgB,EAAE,YAAY;IAC9B,kBAAkB;IAClB,2BAA2B,EAAE,wBAAwB;IACrD,6BAA6B;IAC7B,aAAa,EAAE,eAAe;IAC9B,mBAAmB,EAAE,0BAA0B;CAChD,CAAA"}
|
|
1
|
+
{"version":3,"file":"metadataConstant.js","sourceRoot":"","sources":["../../src/constant/metadataConstant.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,CAAA;AAElC,yEAAyE;AACzE,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,aAAa;IACb,wBAAwB;IACxB,2BAA2B;IAC3B,4BAA4B;CAC7B,CAAA;AAED,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,QAAQ,EAAE,eAAe;IACzB,OAAO,EAAE,0BAA0B;IACnC,SAAS,EAAE,UAAU;IACrB,eAAe,EAAE,gBAAgB;IACjC,uBAAuB,EAAE,2BAA2B;IACpD,aAAa;IACb,0BAA0B;IAC1B,kBAAkB;IAClB,qBAAqB;IACrB,mCAAmC;IACnC,0BAA0B;IAC1B,iBAAiB;IACjB,YAAY;IACZ,kBAAkB;IAClB,YAAY;IACZ,sBAAsB;IACtB,YAAY;IACZ,gBAAgB;IAChB,gBAAgB;IAChB,oBAAoB,EAAE,qBAAqB;IAC3C,gCAAgC,EAAE,iCAAiC;IACnE,qBAAqB,EAAE,sBAAsB;IAC7C,cAAc,EAAE,eAAe;IAC/B,qBAAqB,EAAE,0BAA0B;IACjD,kBAAkB;IAClB,kBAAkB;IAClB,sBAAsB;IACtB,UAAU,EAAE,WAAW;IACvB,eAAe,EAAE,sBAAsB;IACvC,qBAAqB;IACrB,oBAAoB;IACpB,0BAA0B;IAC1B,yBAAyB;IACzB,cAAc;IACd,cAAc;IACd,cAAc;IACd,iBAAiB,EAAE,kBAAkB;IACrC,mBAAmB,EAAE,oBAAoB;IACzC,iBAAiB,EAAE,kBAAkB;IACrC,uBAAuB,EAAE,wBAAwB;IACjD,cAAc,EAAE,gBAAgB;IAChC,gBAAgB,EAAE,YAAY;IAC9B,kBAAkB;IAClB,2BAA2B,EAAE,wBAAwB;IACrD,6BAA6B;IAC7B,aAAa,EAAE,eAAe;IAC9B,mBAAmB,EAAE,0BAA0B;CAChD,CAAA"}
|
|
@@ -1 +1,7 @@
|
|
|
1
1
|
export declare const TEXT_TAG = "#text";
|
|
2
|
+
export declare const XML_DECL = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
|
|
3
|
+
export declare const XML_COMMENT_PROP_NAME = "#xml__comment";
|
|
4
|
+
export declare const CDATA_PROP_NAME = "__cdata";
|
|
5
|
+
export declare const XML_INDENT = " ";
|
|
6
|
+
export declare const NAMESPACE_PREFIX = "@_";
|
|
7
|
+
export declare const NAMESPACE_ROOT = ":@";
|
|
@@ -1,2 +1,8 @@
|
|
|
1
1
|
export const TEXT_TAG = '#text';
|
|
2
|
+
export const XML_DECL = '<?xml version="1.0" encoding="UTF-8"?>\n';
|
|
3
|
+
export const XML_COMMENT_PROP_NAME = '#xml__comment';
|
|
4
|
+
export const CDATA_PROP_NAME = '__cdata';
|
|
5
|
+
export const XML_INDENT = ' ';
|
|
6
|
+
export const NAMESPACE_PREFIX = '@_';
|
|
7
|
+
export const NAMESPACE_ROOT = ':@';
|
|
2
8
|
//# sourceMappingURL=parserConstant.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parserConstant.js","sourceRoot":"","sources":["../../src/constant/parserConstant.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,QAAQ,GAAG,OAAO,CAAA"}
|
|
1
|
+
{"version":3,"file":"parserConstant.js","sourceRoot":"","sources":["../../src/constant/parserConstant.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,QAAQ,GAAG,OAAO,CAAA;AAC/B,MAAM,CAAC,MAAM,QAAQ,GAAG,0CAA0C,CAAA;AAClE,MAAM,CAAC,MAAM,qBAAqB,GAAG,eAAe,CAAA;AACpD,MAAM,CAAC,MAAM,eAAe,GAAG,SAAS,CAAA;AACxC,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAA;AAChC,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAA;AACpC,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,CAAA"}
|
|
@@ -6,12 +6,16 @@ import { log } from '../utils/LoggingDecorator.js';
|
|
|
6
6
|
import { Logger } from '../utils/LoggingService.js';
|
|
7
7
|
import { detectEol, normalizeEol } from '../utils/mergeUtils.js';
|
|
8
8
|
export class MergeDriver {
|
|
9
|
+
config;
|
|
10
|
+
constructor(config) {
|
|
11
|
+
this.config = config;
|
|
12
|
+
}
|
|
9
13
|
async mergeFiles(ancestorFile, ourFile, theirFile) {
|
|
10
14
|
// Read all three versions
|
|
11
15
|
const [ancestorContent, ourContent, theirContent] = await Promise.all([ancestorFile, ourFile, theirFile]
|
|
12
16
|
.map(normalize)
|
|
13
17
|
.map(path => readFile(path, 'utf8')));
|
|
14
|
-
const xmlMerger = new XmlMerger();
|
|
18
|
+
const xmlMerger = new XmlMerger(this.config);
|
|
15
19
|
try {
|
|
16
20
|
const mergedContent = xmlMerger.mergeThreeWay(ancestorContent, ourContent, theirContent);
|
|
17
21
|
const targetEol = detectEol(ourContent);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MergeDriver.js","sourceRoot":"","sources":["../../src/driver/MergeDriver.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;
|
|
1
|
+
{"version":3,"file":"MergeDriver.js","sourceRoot":"","sources":["../../src/driver/MergeDriver.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAElD,OAAO,EAAE,GAAG,EAAE,MAAM,8BAA8B,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAA;AACnD,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAEhE,MAAM,OAAO,WAAW;IACO;IAA7B,YAA6B,MAAmB;QAAnB,WAAM,GAAN,MAAM,CAAa;IAAG,CAAC;IAG9C,AAAN,KAAK,CAAC,UAAU,CACd,YAAoB,EACpB,OAAe,EACf,SAAiB;QAEjB,0BAA0B;QAC1B,MAAM,CAAC,eAAe,EAAE,UAAU,EAAE,YAAY,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CACnE,CAAC,YAAY,EAAE,OAAO,EAAE,SAAS,CAAC;aAC/B,GAAG,CAAC,SAAS,CAAC;aACd,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CACvC,CAAA;QAED,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAE5C,IAAI,CAAC;YACH,MAAM,aAAa,GAAG,SAAS,CAAC,aAAa,CAC3C,eAAe,EACf,UAAU,EACV,YAAY,CACb,CAAA;YAED,MAAM,SAAS,GAAG,SAAS,CAAC,UAAU,CAAC,CAAA;YACvC,MAAM,eAAe,GAAG,YAAY,CAAC,aAAa,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;YACrE,MAAM,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,eAAe,CAAC,CAAA;YAEpD,OAAO,aAAa,CAAC,WAAW,CAAA;QAClC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAA;YACnC,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAA;YAC/B,MAAM,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,CAAA;YAC/C,OAAO,IAAI,CAAA;QACb,CAAC;IACH,CAAC;CACF;AAjCO;IADL,GAAG;6CAiCH"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { MergeConfig } from '../types/conflictTypes.js';
|
|
2
|
+
import type { JsonArray, JsonObject } from '../types/jsonTypes.js';
|
|
3
|
+
export declare const buildConflictMarkers: (config: MergeConfig, local: JsonObject | JsonArray, ancestor: JsonObject | JsonArray, other: JsonObject | JsonArray) => JsonArray;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { isEmpty } from 'lodash-es';
|
|
2
|
+
import { ANCESTOR_CONFLICT_MARKER, LOCAL_CONFLICT_MARKER, OTHER_CONFLICT_MARKER, SEPARATOR, } from '../constant/conflictConstant.js';
|
|
3
|
+
import { SALESFORCE_EOL } from '../constant/metadataConstant.js';
|
|
4
|
+
import { TEXT_TAG } from '../constant/parserConstant.js';
|
|
5
|
+
const buildMarker = (marker, size, tag) => {
|
|
6
|
+
return `${marker.repeat(size)} ${tag}`;
|
|
7
|
+
};
|
|
8
|
+
const buildSeparator = (size) => {
|
|
9
|
+
return `${SEPARATOR.repeat(size)}`;
|
|
10
|
+
};
|
|
11
|
+
const getEmptyValue = () => {
|
|
12
|
+
return { [TEXT_TAG]: SALESFORCE_EOL };
|
|
13
|
+
};
|
|
14
|
+
const getMarkerValue = (marker, withEol = false) => {
|
|
15
|
+
return { [TEXT_TAG]: `${withEol ? SALESFORCE_EOL : ''}${marker}` };
|
|
16
|
+
};
|
|
17
|
+
export const buildConflictMarkers = (config, local, ancestor, other) => {
|
|
18
|
+
const localMarker = buildMarker(LOCAL_CONFLICT_MARKER, config.conflictMarkerSize, config.localConflictTag);
|
|
19
|
+
const baseMarker = buildMarker(ANCESTOR_CONFLICT_MARKER, config.conflictMarkerSize, config.ancestorConflictTag);
|
|
20
|
+
const otherMarker = buildMarker(OTHER_CONFLICT_MARKER, config.conflictMarkerSize, config.otherConflictTag);
|
|
21
|
+
const separatorMarker = buildSeparator(config.conflictMarkerSize);
|
|
22
|
+
const [localValue, ancestorValue, otherValue] = [local, ancestor, other].map(value => (isEmpty(value) ? getEmptyValue() : value));
|
|
23
|
+
return [
|
|
24
|
+
getMarkerValue(localMarker, true),
|
|
25
|
+
localValue,
|
|
26
|
+
getMarkerValue(baseMarker),
|
|
27
|
+
ancestorValue,
|
|
28
|
+
getMarkerValue(separatorMarker),
|
|
29
|
+
otherValue,
|
|
30
|
+
getMarkerValue(otherMarker),
|
|
31
|
+
];
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=ConflictMarkerBuilder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConflictMarkerBuilder.js","sourceRoot":"","sources":["../../src/merger/ConflictMarkerBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EACL,wBAAwB,EACxB,qBAAqB,EACrB,qBAAqB,EACrB,SAAS,GACV,MAAM,iCAAiC,CAAA;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAA;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAA;AAIxD,MAAM,WAAW,GAAG,CAAC,MAAc,EAAE,IAAY,EAAE,GAAW,EAAU,EAAE;IACxE,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,GAAG,EAAE,CAAA;AACxC,CAAC,CAAA;AAED,MAAM,cAAc,GAAG,CAAC,IAAY,EAAU,EAAE;IAC9C,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAA;AACpC,CAAC,CAAA;AAED,MAAM,aAAa,GAAG,GAAe,EAAE;IACrC,OAAO,EAAE,CAAC,QAAQ,CAAC,EAAE,cAAc,EAAE,CAAA;AACvC,CAAC,CAAA;AAED,MAAM,cAAc,GAAG,CACrB,MAAc,EACd,UAAmB,KAAK,EACZ,EAAE;IACd,OAAO,EAAE,CAAC,QAAQ,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,EAAE,CAAA;AACpE,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,MAAmB,EACnB,KAA6B,EAC7B,QAAgC,EAChC,KAA6B,EAClB,EAAE;IACb,MAAM,WAAW,GAAG,WAAW,CAC7B,qBAAqB,EACrB,MAAM,CAAC,kBAAkB,EACzB,MAAM,CAAC,gBAAgB,CACxB,CAAA;IACD,MAAM,UAAU,GAAG,WAAW,CAC5B,wBAAwB,EACxB,MAAM,CAAC,kBAAkB,EACzB,MAAM,CAAC,mBAAmB,CAC3B,CAAA;IACD,MAAM,WAAW,GAAG,WAAW,CAC7B,qBAAqB,EACrB,MAAM,CAAC,kBAAkB,EACzB,MAAM,CAAC,gBAAgB,CACxB,CAAA;IACD,MAAM,eAAe,GAAG,cAAc,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAA;IAEjE,MAAM,CAAC,UAAU,EAAE,aAAa,EAAE,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,GAAG,CAC1E,KAAK,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CACpD,CAAA;IAED,OAAO;QACL,cAAc,CAAC,WAAW,EAAE,IAAI,CAAC;QACjC,UAAU;QACV,cAAc,CAAC,UAAU,CAAC;QAC1B,aAAa;QACb,cAAc,CAAC,eAAe,CAAC;QAC/B,UAAU;QACV,cAAc,CAAC,WAAW,CAAC;KAC5B,CAAA;AACH,CAAC,CAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { MergeConfig } from '../types/conflictTypes.js';
|
|
2
|
+
export declare class ConflictMarkerFormatter {
|
|
3
|
+
private readonly localMarker;
|
|
4
|
+
private readonly ancestorMarker;
|
|
5
|
+
private readonly separator;
|
|
6
|
+
private readonly otherMarker;
|
|
7
|
+
private readonly localEntity;
|
|
8
|
+
private readonly otherEntity;
|
|
9
|
+
private readonly indentRegex;
|
|
10
|
+
constructor(config: MergeConfig);
|
|
11
|
+
correctConflictIndent(xml: string): string;
|
|
12
|
+
handleSpecialEntities(xml: string): string;
|
|
13
|
+
private escapeRegex;
|
|
14
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { ANCESTOR_CONFLICT_MARKER, LOCAL_CONFLICT_MARKER, OTHER_CONFLICT_MARKER, SEPARATOR, } from '../constant/conflictConstant.js';
|
|
2
|
+
export class ConflictMarkerFormatter {
|
|
3
|
+
localMarker;
|
|
4
|
+
ancestorMarker;
|
|
5
|
+
separator;
|
|
6
|
+
otherMarker;
|
|
7
|
+
localEntity;
|
|
8
|
+
otherEntity;
|
|
9
|
+
indentRegex;
|
|
10
|
+
constructor(config) {
|
|
11
|
+
const size = config.conflictMarkerSize;
|
|
12
|
+
// Build marker strings from config size
|
|
13
|
+
this.localMarker = LOCAL_CONFLICT_MARKER.repeat(size);
|
|
14
|
+
this.ancestorMarker = ANCESTOR_CONFLICT_MARKER.repeat(size);
|
|
15
|
+
this.separator = SEPARATOR.repeat(size);
|
|
16
|
+
this.otherMarker = OTHER_CONFLICT_MARKER.repeat(size);
|
|
17
|
+
// Build entity-escaped versions for XML processing
|
|
18
|
+
this.localEntity = '<'.repeat(size);
|
|
19
|
+
this.otherEntity = '>'.repeat(size);
|
|
20
|
+
// Build regex pattern for indent correction
|
|
21
|
+
// Matches any of the conflict markers at start of content
|
|
22
|
+
const escapedMarkers = [
|
|
23
|
+
this.escapeRegex(this.localMarker),
|
|
24
|
+
this.escapeRegex(this.ancestorMarker),
|
|
25
|
+
this.escapeRegex(this.separator),
|
|
26
|
+
this.escapeRegex(this.otherMarker),
|
|
27
|
+
].join('|');
|
|
28
|
+
this.indentRegex = new RegExp(`[ \\t]+(${escapedMarkers})`, 'g');
|
|
29
|
+
}
|
|
30
|
+
correctConflictIndent(xml) {
|
|
31
|
+
return xml.replace(this.indentRegex, '$1').replace(/^[ \t]*[\n\r]+/gm, '');
|
|
32
|
+
}
|
|
33
|
+
handleSpecialEntities(xml) {
|
|
34
|
+
return xml
|
|
35
|
+
.replaceAll('&#160;', ' ')
|
|
36
|
+
.replaceAll(this.localEntity, this.localMarker)
|
|
37
|
+
.replaceAll(this.otherEntity, this.otherMarker);
|
|
38
|
+
}
|
|
39
|
+
escapeRegex(str) {
|
|
40
|
+
return str.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&');
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=ConflictMarkerFormatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConflictMarkerFormatter.js","sourceRoot":"","sources":["../../src/merger/ConflictMarkerFormatter.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,wBAAwB,EACxB,qBAAqB,EACrB,qBAAqB,EACrB,SAAS,GACV,MAAM,iCAAiC,CAAA;AAGxC,MAAM,OAAO,uBAAuB;IACjB,WAAW,CAAQ;IACnB,cAAc,CAAQ;IACtB,SAAS,CAAQ;IACjB,WAAW,CAAQ;IACnB,WAAW,CAAQ;IACnB,WAAW,CAAQ;IACnB,WAAW,CAAQ;IAEpC,YAAY,MAAmB;QAC7B,MAAM,IAAI,GAAG,MAAM,CAAC,kBAAkB,CAAA;QAEtC,wCAAwC;QACxC,IAAI,CAAC,WAAW,GAAG,qBAAqB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QACrD,IAAI,CAAC,cAAc,GAAG,wBAAwB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QAC3D,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QACvC,IAAI,CAAC,WAAW,GAAG,qBAAqB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QAErD,mDAAmD;QACnD,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QACtC,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QAEtC,4CAA4C;QAC5C,0DAA0D;QAC1D,MAAM,cAAc,GAAG;YACrB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC;YAClC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,cAAc,CAAC;YACrC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC;YAChC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC;SACnC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACX,IAAI,CAAC,WAAW,GAAG,IAAI,MAAM,CAAC,WAAW,cAAc,GAAG,EAAE,GAAG,CAAC,CAAA;IAClE,CAAC;IAED,qBAAqB,CAAC,GAAW;QAC/B,OAAO,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAA;IAC5E,CAAC;IAED,qBAAqB,CAAC,GAAW;QAC/B,OAAO,GAAG;aACP,UAAU,CAAC,YAAY,EAAE,QAAQ,CAAC;aAClC,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC;aAC9C,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,CAAA;IACnD,CAAC;IAEO,WAAW,CAAC,GAAW;QAC7B,OAAO,GAAG,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAA;IACnD,CAAC;CACF"}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import type { MergeConfig } from '../types/conflictTypes.js';
|
|
1
2
|
import type { JsonArray, JsonObject } from '../types/jsonTypes.js';
|
|
2
3
|
export declare class JsonMerger {
|
|
4
|
+
private readonly orchestrator;
|
|
5
|
+
constructor(config: MergeConfig);
|
|
3
6
|
mergeThreeWay(ancestor: JsonObject | JsonArray, local: JsonObject | JsonArray, other: JsonObject | JsonArray): {
|
|
4
7
|
output: JsonArray;
|
|
5
8
|
hasConflict: boolean;
|
package/lib/merger/JsonMerger.js
CHANGED
|
@@ -1,212 +1,37 @@
|
|
|
1
1
|
import { __decorate } from "tslib";
|
|
2
|
-
import { deepEqual } from 'fast-equals';
|
|
3
|
-
import { isEmpty, keyBy } from 'lodash-es';
|
|
4
|
-
import { MetadataService } from '../service/MetadataService.js';
|
|
5
2
|
import { NamespaceHandler } from '../service/NamespaceHandler.js';
|
|
6
|
-
import {
|
|
3
|
+
import { combineResults } from '../types/mergeResult.js';
|
|
7
4
|
import { log } from '../utils/LoggingDecorator.js';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
5
|
+
import { MergeOrchestrator } from './MergeOrchestrator.js';
|
|
6
|
+
import { defaultNodeFactory } from './nodes/MergeNodeFactory.js';
|
|
7
|
+
import { getUniqueSortedProps } from './nodes/nodeUtils.js';
|
|
11
8
|
export class JsonMerger {
|
|
9
|
+
orchestrator;
|
|
10
|
+
constructor(config) {
|
|
11
|
+
this.orchestrator = new MergeOrchestrator(config, defaultNodeFactory);
|
|
12
|
+
}
|
|
12
13
|
mergeThreeWay(ancestor, local, other) {
|
|
13
14
|
const namespaceHandler = new NamespaceHandler();
|
|
14
15
|
const namespaces = namespaceHandler.processNamespaces(ancestor, local, other);
|
|
15
|
-
const
|
|
16
|
-
const acc = [];
|
|
16
|
+
const results = [];
|
|
17
17
|
const props = getUniqueSortedProps(ancestor, local, other);
|
|
18
18
|
for (const key of props) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
case MergeScenario.ANCESTOR_AND_OTHER:
|
|
26
|
-
acc.push(handleAncestorAndother(key, ancestor, other));
|
|
27
|
-
break;
|
|
28
|
-
case MergeScenario.ANCESTOR_AND_LOCAL:
|
|
29
|
-
acc.push(handleAncestorAndlocal(key, ancestor, local));
|
|
30
|
-
break;
|
|
31
|
-
default: {
|
|
32
|
-
const obj = {
|
|
33
|
-
[key]: merge(ancestor[key], local[key], other[key]),
|
|
34
|
-
};
|
|
35
|
-
acc.push([obj]);
|
|
36
|
-
break;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
19
|
+
const result = this.orchestrator.merge(ancestor[key], local[key], other[key], undefined, {
|
|
20
|
+
name: key,
|
|
21
|
+
existsInLocal: key in local,
|
|
22
|
+
existsInOther: key in other,
|
|
23
|
+
});
|
|
24
|
+
results.push(result);
|
|
39
25
|
}
|
|
40
|
-
const
|
|
41
|
-
namespaceHandler.addNamespacesToResult(
|
|
26
|
+
const combined = combineResults(results);
|
|
27
|
+
namespaceHandler.addNamespacesToResult(combined.output, namespaces);
|
|
42
28
|
return {
|
|
43
|
-
output:
|
|
44
|
-
hasConflict:
|
|
29
|
+
output: combined.output,
|
|
30
|
+
hasConflict: combined.hasConflict,
|
|
45
31
|
};
|
|
46
32
|
}
|
|
47
33
|
}
|
|
48
34
|
__decorate([
|
|
49
35
|
log
|
|
50
36
|
], JsonMerger.prototype, "mergeThreeWay", null);
|
|
51
|
-
function merge(ancestor, local, other) {
|
|
52
|
-
const acc = [];
|
|
53
|
-
const props = getUniqueSortedProps(ancestor, local, other);
|
|
54
|
-
for (const key of props) {
|
|
55
|
-
let values = [];
|
|
56
|
-
const ancestorOfKey = ancestor[key];
|
|
57
|
-
const localOfKey = local[key];
|
|
58
|
-
const otherOfKey = other[key];
|
|
59
|
-
if (isObject(ancestorOfKey, localOfKey, otherOfKey)) {
|
|
60
|
-
const [ancestorkey, ourkey, theirkey] = [
|
|
61
|
-
ancestorOfKey,
|
|
62
|
-
localOfKey,
|
|
63
|
-
otherOfKey,
|
|
64
|
-
].map(ensureArray);
|
|
65
|
-
values = mergeArrays(ancestorkey, ourkey, theirkey, key);
|
|
66
|
-
}
|
|
67
|
-
else {
|
|
68
|
-
values = mergeTextAttribute(ancestorOfKey, localOfKey, otherOfKey, key);
|
|
69
|
-
}
|
|
70
|
-
acc.push(values);
|
|
71
|
-
}
|
|
72
|
-
return acc.flat();
|
|
73
|
-
}
|
|
74
|
-
function toJsonArray(inputObj) {
|
|
75
|
-
const acc = [];
|
|
76
|
-
for (const attribute of getUniqueSortedProps(inputObj)) {
|
|
77
|
-
const values = [];
|
|
78
|
-
const inputObjOfAttr = inputObj[attribute];
|
|
79
|
-
if (typeof inputObjOfAttr === 'object') {
|
|
80
|
-
const inputObjAtt = ensureArray(inputObjOfAttr);
|
|
81
|
-
for (const key of getUniqueSortedProps(inputObjAtt)) {
|
|
82
|
-
const inputObjKeyOfKey = inputObjAtt[key];
|
|
83
|
-
values.push({ [attribute]: toJsonArray(inputObjKeyOfKey) });
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
else {
|
|
87
|
-
values.push(generateObj(inputObjOfAttr, attribute));
|
|
88
|
-
}
|
|
89
|
-
acc.push(values);
|
|
90
|
-
}
|
|
91
|
-
return acc.flat();
|
|
92
|
-
}
|
|
93
|
-
const handlelocalAndother = (key, local, other) => {
|
|
94
|
-
const obj = {};
|
|
95
|
-
obj[key] = merge({}, local[key], other[key]);
|
|
96
|
-
const acc = [];
|
|
97
|
-
// Functional choice: Don't use deepEqual because it would tax performence when the ancestor is empty at a too high level of the metadata tree
|
|
98
|
-
// merge will functionally do the same itself while perfoming its normal function
|
|
99
|
-
acc.push(obj);
|
|
100
|
-
return acc;
|
|
101
|
-
};
|
|
102
|
-
const handleAncestorAndother = (key, ancestor, other) => {
|
|
103
|
-
const acc = [];
|
|
104
|
-
if (!deepEqual(ancestor, other)) {
|
|
105
|
-
const ancestorProp = {
|
|
106
|
-
[key]: toJsonArray(ancestor[key]),
|
|
107
|
-
};
|
|
108
|
-
const otherProp = {
|
|
109
|
-
[key]: toJsonArray(other[key]),
|
|
110
|
-
};
|
|
111
|
-
ConflictMarker.addConflictMarkers(acc, {}, ancestorProp, otherProp);
|
|
112
|
-
}
|
|
113
|
-
return acc;
|
|
114
|
-
};
|
|
115
|
-
const handleAncestorAndlocal = (key, ancestor, local) => {
|
|
116
|
-
const acc = [];
|
|
117
|
-
if (!deepEqual(ancestor, local)) {
|
|
118
|
-
const localProp = {
|
|
119
|
-
[key]: toJsonArray(local[key]),
|
|
120
|
-
};
|
|
121
|
-
const ancestorProp = {
|
|
122
|
-
[key]: toJsonArray(ancestor[key]),
|
|
123
|
-
};
|
|
124
|
-
ConflictMarker.addConflictMarkers(acc, localProp, ancestorProp, {});
|
|
125
|
-
}
|
|
126
|
-
return acc;
|
|
127
|
-
};
|
|
128
|
-
const mergeArrays = (ancestor, local, other, attribute) => {
|
|
129
|
-
const keyField = MetadataService.getKeyFieldExtractor(attribute);
|
|
130
|
-
if (!keyField) {
|
|
131
|
-
// const scenario: MergeScenario = getScenario(ancestor, local, other)
|
|
132
|
-
const arr = [];
|
|
133
|
-
// obj[attribute] = unionWith(local, other, deepEqual)
|
|
134
|
-
// obj[attribute] = mergeTextAttribute(local, other, deepEqual, attribute)
|
|
135
|
-
// obj[attribute] = []
|
|
136
|
-
ConflictMarker.addConflictMarkers(arr, toJsonArray({ [attribute]: local }), toJsonArray({ [attribute]: ancestor }), toJsonArray({ [attribute]: other }));
|
|
137
|
-
return arr.flat();
|
|
138
|
-
// return mergeTextAttribute(ancestor, local, other, attribute).flat()
|
|
139
|
-
}
|
|
140
|
-
const [keyedAnc, keyedlocal, keyedother] = [ancestor, local, other].map(arr => keyBy(arr, keyField));
|
|
141
|
-
return mergeByKeyField(keyedAnc, keyedlocal, keyedother, attribute);
|
|
142
|
-
};
|
|
143
|
-
const mergeByKeyField = (ancestor, local, other, attribute) => {
|
|
144
|
-
const acc = [];
|
|
145
|
-
const props = getUniqueSortedProps(ancestor, local, other);
|
|
146
|
-
for (const key of props) {
|
|
147
|
-
const ancestorOfKey = ancestor[key];
|
|
148
|
-
const localOfKey = local[key];
|
|
149
|
-
const otherOfKey = other[key];
|
|
150
|
-
const scenario = getScenario(ancestorOfKey, localOfKey, otherOfKey);
|
|
151
|
-
const obj = {};
|
|
152
|
-
switch (scenario) {
|
|
153
|
-
case MergeScenario.OTHER_ONLY:
|
|
154
|
-
obj[attribute] = merge({}, {}, otherOfKey);
|
|
155
|
-
break;
|
|
156
|
-
case MergeScenario.LOCAL_ONLY:
|
|
157
|
-
obj[attribute] = merge({}, localOfKey, {});
|
|
158
|
-
break;
|
|
159
|
-
case MergeScenario.ANCESTOR_ONLY:
|
|
160
|
-
break;
|
|
161
|
-
case MergeScenario.LOCAL_AND_OTHER:
|
|
162
|
-
if (deepEqual(localOfKey, otherOfKey)) {
|
|
163
|
-
obj[attribute] = merge({}, {}, otherOfKey);
|
|
164
|
-
}
|
|
165
|
-
else {
|
|
166
|
-
obj[attribute] = merge({}, localOfKey, otherOfKey);
|
|
167
|
-
}
|
|
168
|
-
break;
|
|
169
|
-
case MergeScenario.ANCESTOR_AND_OTHER:
|
|
170
|
-
if (!deepEqual(ancestorOfKey, otherOfKey)) {
|
|
171
|
-
const ancestorProp = {
|
|
172
|
-
[attribute]: merge({}, ancestorOfKey, {}),
|
|
173
|
-
};
|
|
174
|
-
const otherProp = {
|
|
175
|
-
[attribute]: merge({}, {}, otherOfKey),
|
|
176
|
-
};
|
|
177
|
-
ConflictMarker.addConflictMarkers(acc, {}, ancestorProp, otherProp);
|
|
178
|
-
}
|
|
179
|
-
break;
|
|
180
|
-
case MergeScenario.ANCESTOR_AND_LOCAL:
|
|
181
|
-
if (!deepEqual(ancestorOfKey, localOfKey)) {
|
|
182
|
-
const localProp = {
|
|
183
|
-
[attribute]: merge({}, localOfKey, {}),
|
|
184
|
-
};
|
|
185
|
-
const ancestorProp = {
|
|
186
|
-
[attribute]: merge({}, ancestorOfKey, {}),
|
|
187
|
-
};
|
|
188
|
-
ConflictMarker.addConflictMarkers(acc, localProp, ancestorProp, {});
|
|
189
|
-
}
|
|
190
|
-
break;
|
|
191
|
-
case MergeScenario.ALL:
|
|
192
|
-
if (deepEqual(localOfKey, otherOfKey)) {
|
|
193
|
-
obj[attribute] = merge({}, {}, otherOfKey);
|
|
194
|
-
}
|
|
195
|
-
else if (deepEqual(ancestorOfKey, localOfKey)) {
|
|
196
|
-
obj[attribute] = merge({}, {}, otherOfKey);
|
|
197
|
-
}
|
|
198
|
-
else if (deepEqual(ancestorOfKey, otherOfKey)) {
|
|
199
|
-
obj[attribute] = merge({}, localOfKey, {});
|
|
200
|
-
}
|
|
201
|
-
else {
|
|
202
|
-
obj[attribute] = merge(ancestorOfKey, localOfKey, otherOfKey);
|
|
203
|
-
}
|
|
204
|
-
break;
|
|
205
|
-
}
|
|
206
|
-
if (!isEmpty(obj)) {
|
|
207
|
-
acc.push(obj);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
return acc;
|
|
211
|
-
};
|
|
212
37
|
//# sourceMappingURL=JsonMerger.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JsonMerger.js","sourceRoot":"","sources":["../../src/merger/JsonMerger.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"JsonMerger.js","sourceRoot":"","sources":["../../src/merger/JsonMerger.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAA;AAIjE,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,EAAE,GAAG,EAAE,MAAM,8BAA8B,CAAA;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAA;AAChE,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAA;AAE3D,MAAM,OAAO,UAAU;IACJ,YAAY,CAAmB;IAEhD,YAAY,MAAmB;QAC7B,IAAI,CAAC,YAAY,GAAG,IAAI,iBAAiB,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAA;IACvE,CAAC;IAGM,aAAa,CAClB,QAAgC,EAChC,KAA6B,EAC7B,KAA6B;QAE7B,MAAM,gBAAgB,GAAG,IAAI,gBAAgB,EAAE,CAAA;QAC/C,MAAM,UAAU,GAAG,gBAAgB,CAAC,iBAAiB,CACnD,QAAQ,EACR,KAAK,EACL,KAAK,CACN,CAAA;QAED,MAAM,OAAO,GAAkB,EAAE,CAAA;QACjC,MAAM,KAAK,GAAG,oBAAoB,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,CAAA;QAE1D,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;YACxB,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CACpC,QAAQ,CAAC,GAAG,CAAC,EACb,KAAK,CAAC,GAAG,CAAC,EACV,KAAK,CAAC,GAAG,CAAC,EACV,SAAS,EACT;gBACE,IAAI,EAAE,GAAG;gBACT,aAAa,EAAE,GAAG,IAAI,KAAK;gBAC3B,aAAa,EAAE,GAAG,IAAI,KAAK;aAC5B,CACF,CAAA;YACD,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QACtB,CAAC;QAED,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,CAAC,CAAA;QACxC,gBAAgB,CAAC,qBAAqB,CAAC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;QAEnE,OAAO;YACL,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,WAAW,EAAE,QAAQ,CAAC,WAAW;SAClC,CAAA;IACH,CAAC;CACF;AAtCQ;IADN,GAAG;+CAsCH"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { MergeConfig } from '../types/conflictTypes.js';
|
|
2
|
+
import type { JsonValue } from '../types/jsonTypes.js';
|
|
3
|
+
import type { MergeNodeFactory } from './nodes/MergeNodeFactory.js';
|
|
4
|
+
export interface RootKeyInfo {
|
|
5
|
+
readonly name: string;
|
|
6
|
+
readonly existsInLocal: boolean;
|
|
7
|
+
readonly existsInOther: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface MergeContext {
|
|
10
|
+
readonly config: MergeConfig;
|
|
11
|
+
readonly ancestor: JsonValue;
|
|
12
|
+
readonly local: JsonValue;
|
|
13
|
+
readonly other: JsonValue;
|
|
14
|
+
readonly attribute: string | undefined;
|
|
15
|
+
readonly nodeFactory: MergeNodeFactory;
|
|
16
|
+
readonly rootKey: RootKeyInfo | undefined;
|
|
17
|
+
}
|