@diffson/core 1.0.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/.turbo/turbo-build.log +1 -0
- package/.turbo/turbo-test.log +96 -0
- package/.turbo/turbo-typecheck.log +2 -0
- package/dist/contract/constant/DiffConstants.d.ts +9 -0
- package/dist/contract/constant/DiffConstants.d.ts.map +1 -0
- package/dist/contract/constant/DiffConstants.js +9 -0
- package/dist/contract/constant/DiffConstants.js.map +1 -0
- package/dist/contract/constant/PresetName.d.ts +7 -0
- package/dist/contract/constant/PresetName.d.ts.map +1 -0
- package/dist/contract/constant/PresetName.js +8 -0
- package/dist/contract/constant/PresetName.js.map +1 -0
- package/dist/contract/constant/index.d.ts +3 -0
- package/dist/contract/constant/index.d.ts.map +1 -0
- package/dist/contract/constant/index.js +3 -0
- package/dist/contract/constant/index.js.map +1 -0
- package/dist/contract/index.d.ts +3 -0
- package/dist/contract/index.d.ts.map +1 -0
- package/dist/contract/index.js +3 -0
- package/dist/contract/index.js.map +1 -0
- package/dist/contract/type/ArrayComparator.d.ts +9 -0
- package/dist/contract/type/ArrayComparator.d.ts.map +1 -0
- package/dist/contract/type/ArrayComparator.js +3 -0
- package/dist/contract/type/ArrayComparator.js.map +1 -0
- package/dist/contract/type/ComparatorOrchestrator.d.ts +10 -0
- package/dist/contract/type/ComparatorOrchestrator.d.ts.map +1 -0
- package/dist/contract/type/ComparatorOrchestrator.js +3 -0
- package/dist/contract/type/ComparatorOrchestrator.js.map +1 -0
- package/dist/contract/type/DiffService.d.ts +28 -0
- package/dist/contract/type/DiffService.d.ts.map +1 -0
- package/dist/contract/type/DiffService.js +3 -0
- package/dist/contract/type/DiffService.js.map +1 -0
- package/dist/contract/type/JsonTypes.d.ts +6 -0
- package/dist/contract/type/JsonTypes.d.ts.map +1 -0
- package/dist/contract/type/JsonTypes.js +2 -0
- package/dist/contract/type/JsonTypes.js.map +1 -0
- package/dist/contract/type/NullComparator.d.ts +7 -0
- package/dist/contract/type/NullComparator.d.ts.map +1 -0
- package/dist/contract/type/NullComparator.js +3 -0
- package/dist/contract/type/NullComparator.js.map +1 -0
- package/dist/contract/type/ObjectComparator.d.ts +9 -0
- package/dist/contract/type/ObjectComparator.d.ts.map +1 -0
- package/dist/contract/type/ObjectComparator.js +3 -0
- package/dist/contract/type/ObjectComparator.js.map +1 -0
- package/dist/contract/type/OtherComparator.d.ts +8 -0
- package/dist/contract/type/OtherComparator.d.ts.map +1 -0
- package/dist/contract/type/OtherComparator.js +3 -0
- package/dist/contract/type/OtherComparator.js.map +1 -0
- package/dist/contract/type/PrimitiveComparator.d.ts +7 -0
- package/dist/contract/type/PrimitiveComparator.d.ts.map +1 -0
- package/dist/contract/type/PrimitiveComparator.js +3 -0
- package/dist/contract/type/PrimitiveComparator.js.map +1 -0
- package/dist/contract/type/Result.d.ts +8 -0
- package/dist/contract/type/Result.d.ts.map +1 -0
- package/dist/contract/type/Result.js +8 -0
- package/dist/contract/type/Result.js.map +1 -0
- package/dist/contract/type/SingleNodeDifference.d.ts +8 -0
- package/dist/contract/type/SingleNodeDifference.d.ts.map +1 -0
- package/dist/contract/type/SingleNodeDifference.js +13 -0
- package/dist/contract/type/SingleNodeDifference.js.map +1 -0
- package/dist/contract/type/index.d.ts +11 -0
- package/dist/contract/type/index.d.ts.map +1 -0
- package/dist/contract/type/index.js +11 -0
- package/dist/contract/type/index.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/service/comparator/ComparatorOrchestrator.d.ts +14 -0
- package/dist/service/comparator/ComparatorOrchestrator.d.ts.map +1 -0
- package/dist/service/comparator/ComparatorOrchestrator.js +56 -0
- package/dist/service/comparator/ComparatorOrchestrator.js.map +1 -0
- package/dist/service/comparator/array/AbstractArray.d.ts +12 -0
- package/dist/service/comparator/array/AbstractArray.d.ts.map +1 -0
- package/dist/service/comparator/array/AbstractArray.js +41 -0
- package/dist/service/comparator/array/AbstractArray.js.map +1 -0
- package/dist/service/comparator/array/SequentialArrayComparator.d.ts +10 -0
- package/dist/service/comparator/array/SequentialArrayComparator.d.ts.map +1 -0
- package/dist/service/comparator/array/SequentialArrayComparator.js +50 -0
- package/dist/service/comparator/array/SequentialArrayComparator.js.map +1 -0
- package/dist/service/comparator/array/SimilarArrayComparator.d.ts +22 -0
- package/dist/service/comparator/array/SimilarArrayComparator.d.ts.map +1 -0
- package/dist/service/comparator/array/SimilarArrayComparator.js +153 -0
- package/dist/service/comparator/array/SimilarArrayComparator.js.map +1 -0
- package/dist/service/comparator/array/index.d.ts +4 -0
- package/dist/service/comparator/array/index.d.ts.map +1 -0
- package/dist/service/comparator/array/index.js +4 -0
- package/dist/service/comparator/array/index.js.map +1 -0
- package/dist/service/comparator/index.d.ts +7 -0
- package/dist/service/comparator/index.d.ts.map +1 -0
- package/dist/service/comparator/index.js +7 -0
- package/dist/service/comparator/index.js.map +1 -0
- package/dist/service/comparator/nulls/DefaultNullComparator.d.ts +7 -0
- package/dist/service/comparator/nulls/DefaultNullComparator.d.ts.map +1 -0
- package/dist/service/comparator/nulls/DefaultNullComparator.js +7 -0
- package/dist/service/comparator/nulls/DefaultNullComparator.js.map +1 -0
- package/dist/service/comparator/nulls/index.d.ts +2 -0
- package/dist/service/comparator/nulls/index.d.ts.map +1 -0
- package/dist/service/comparator/nulls/index.js +2 -0
- package/dist/service/comparator/nulls/index.js.map +1 -0
- package/dist/service/comparator/object/AbstractObject.d.ts +17 -0
- package/dist/service/comparator/object/AbstractObject.d.ts.map +1 -0
- package/dist/service/comparator/object/AbstractObject.js +91 -0
- package/dist/service/comparator/object/AbstractObject.js.map +1 -0
- package/dist/service/comparator/object/LeftJoinObjectComparator.d.ts +9 -0
- package/dist/service/comparator/object/LeftJoinObjectComparator.d.ts.map +1 -0
- package/dist/service/comparator/object/LeftJoinObjectComparator.js +26 -0
- package/dist/service/comparator/object/LeftJoinObjectComparator.js.map +1 -0
- package/dist/service/comparator/object/UnionKeyObjectComparator.d.ts +9 -0
- package/dist/service/comparator/object/UnionKeyObjectComparator.d.ts.map +1 -0
- package/dist/service/comparator/object/UnionKeyObjectComparator.js +27 -0
- package/dist/service/comparator/object/UnionKeyObjectComparator.js.map +1 -0
- package/dist/service/comparator/object/index.d.ts +4 -0
- package/dist/service/comparator/object/index.d.ts.map +1 -0
- package/dist/service/comparator/object/index.js +4 -0
- package/dist/service/comparator/object/index.js.map +1 -0
- package/dist/service/comparator/other/DefaultOtherComparator.d.ts +7 -0
- package/dist/service/comparator/other/DefaultOtherComparator.d.ts.map +1 -0
- package/dist/service/comparator/other/DefaultOtherComparator.js +14 -0
- package/dist/service/comparator/other/DefaultOtherComparator.js.map +1 -0
- package/dist/service/comparator/other/index.d.ts +2 -0
- package/dist/service/comparator/other/index.d.ts.map +1 -0
- package/dist/service/comparator/other/index.js +2 -0
- package/dist/service/comparator/other/index.js.map +1 -0
- package/dist/service/comparator/primitive/DefaultPrimitiveComparator.d.ts +7 -0
- package/dist/service/comparator/primitive/DefaultPrimitiveComparator.d.ts.map +1 -0
- package/dist/service/comparator/primitive/DefaultPrimitiveComparator.js +17 -0
- package/dist/service/comparator/primitive/DefaultPrimitiveComparator.js.map +1 -0
- package/dist/service/comparator/primitive/index.d.ts +2 -0
- package/dist/service/comparator/primitive/index.d.ts.map +1 -0
- package/dist/service/comparator/primitive/index.js +2 -0
- package/dist/service/comparator/primitive/index.js.map +1 -0
- package/dist/service/diff/DiffContext.d.ts +14 -0
- package/dist/service/diff/DiffContext.d.ts.map +1 -0
- package/dist/service/diff/DiffContext.js +30 -0
- package/dist/service/diff/DiffContext.js.map +1 -0
- package/dist/service/diff/DiffService.d.ts +27 -0
- package/dist/service/diff/DiffService.d.ts.map +1 -0
- package/dist/service/diff/DiffService.js +185 -0
- package/dist/service/diff/DiffService.js.map +1 -0
- package/dist/service/diff/PathTracker.d.ts +22 -0
- package/dist/service/diff/PathTracker.d.ts.map +1 -0
- package/dist/service/diff/PathTracker.js +57 -0
- package/dist/service/diff/PathTracker.js.map +1 -0
- package/dist/service/diff/index.d.ts +2 -0
- package/dist/service/diff/index.d.ts.map +1 -0
- package/dist/service/diff/index.js +2 -0
- package/dist/service/diff/index.js.map +1 -0
- package/dist/service/index.d.ts +3 -0
- package/dist/service/index.d.ts.map +1 -0
- package/dist/service/index.js +3 -0
- package/dist/service/index.js.map +1 -0
- package/dist/util/TypeGuards.d.ts +7 -0
- package/dist/util/TypeGuards.d.ts.map +1 -0
- package/dist/util/TypeGuards.js +33 -0
- package/dist/util/TypeGuards.js.map +1 -0
- package/dist/util/index.d.ts +2 -0
- package/dist/util/index.d.ts.map +1 -0
- package/dist/util/index.js +2 -0
- package/dist/util/index.js.map +1 -0
- package/package.json +40 -0
- package/src/contract/constant/DiffConstants.ts +10 -0
- package/src/contract/constant/PresetName.ts +6 -0
- package/src/contract/constant/index.ts +2 -0
- package/src/contract/index.ts +2 -0
- package/src/contract/type/ArrayComparator.ts +15 -0
- package/src/contract/type/ComparatorOrchestrator.ts +16 -0
- package/src/contract/type/DiffService.ts +31 -0
- package/src/contract/type/JsonTypes.ts +3 -0
- package/src/contract/type/NullComparator.ts +9 -0
- package/src/contract/type/ObjectComparator.ts +15 -0
- package/src/contract/type/OtherComparator.ts +14 -0
- package/src/contract/type/PrimitiveComparator.ts +13 -0
- package/src/contract/type/Result.ts +7 -0
- package/src/contract/type/SingleNodeDifference.ts +13 -0
- package/src/contract/type/index.ts +10 -0
- package/src/index.ts +17 -0
- package/src/service/comparator/ComparatorOrchestrator.ts +50 -0
- package/src/service/comparator/array/AbstractArray.ts +34 -0
- package/src/service/comparator/array/SequentialArrayComparator.test.ts +46 -0
- package/src/service/comparator/array/SequentialArrayComparator.ts +48 -0
- package/src/service/comparator/array/SimilarArrayComparator.test.ts +37 -0
- package/src/service/comparator/array/SimilarArrayComparator.ts +211 -0
- package/src/service/comparator/array/index.ts +3 -0
- package/src/service/comparator/index.ts +6 -0
- package/src/service/comparator/nulls/DefaultNullComparator.test.ts +38 -0
- package/src/service/comparator/nulls/DefaultNullComparator.ts +9 -0
- package/src/service/comparator/nulls/index.ts +1 -0
- package/src/service/comparator/object/AbstractObject.ts +102 -0
- package/src/service/comparator/object/LeftJoinObjectComparator.test.ts +71 -0
- package/src/service/comparator/object/LeftJoinObjectComparator.ts +18 -0
- package/src/service/comparator/object/UnionKeyObjectComparator.test.ts +20 -0
- package/src/service/comparator/object/UnionKeyObjectComparator.ts +19 -0
- package/src/service/comparator/object/index.ts +3 -0
- package/src/service/comparator/other/DefaultOtherComparator.test.ts +48 -0
- package/src/service/comparator/other/DefaultOtherComparator.ts +23 -0
- package/src/service/comparator/other/index.ts +1 -0
- package/src/service/comparator/primitive/DefaultPrimitiveComparator.test.ts +50 -0
- package/src/service/comparator/primitive/DefaultPrimitiveComparator.ts +27 -0
- package/src/service/comparator/primitive/index.ts +1 -0
- package/src/service/diff/Diff.test.ts +113 -0
- package/src/service/diff/DiffContext.ts +37 -0
- package/src/service/diff/DiffService.test.ts +292 -0
- package/src/service/diff/DiffService.ts +245 -0
- package/src/service/diff/PathTracker.ts +71 -0
- package/src/service/diff/index.ts +1 -0
- package/src/service/index.ts +2 -0
- package/src/util/TypeGuards.test.ts +90 -0
- package/src/util/TypeGuards.ts +33 -0
- package/src/util/index.ts +1 -0
- package/tsconfig.json +11 -0
- package/tsconfig.tsbuildinfo +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/util/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@diffson/core",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"imports": {
|
|
8
|
+
"#contract": "./src/contract/index.ts",
|
|
9
|
+
"#service": "./src/service/index.ts"
|
|
10
|
+
},
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"import": {
|
|
14
|
+
"@diffson/source": "./src/index.ts",
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"default": "./dist/index.js"
|
|
17
|
+
},
|
|
18
|
+
"require": {
|
|
19
|
+
"@diffson/source": "./src/index.ts",
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"default": "./dist/index.js"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"./package.json": "./package.json"
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "tsc",
|
|
28
|
+
"test": "bun test",
|
|
29
|
+
"typecheck": "tsc --noEmit",
|
|
30
|
+
"clean": "rm -rf dist node_modules"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@wendellhu/redi": "latest",
|
|
34
|
+
"is-json": "latest"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/bun": "latest",
|
|
38
|
+
"typescript": "^5.7.0"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export const DIFFERENT = false;
|
|
2
|
+
export const SAME = true;
|
|
3
|
+
export const SPLIT_PATH = "\\.";
|
|
4
|
+
export const MERGE_PATH = ".";
|
|
5
|
+
|
|
6
|
+
export const OBJECT_NULL = null;
|
|
7
|
+
export const TYPE_MODIFY = "MODIFY";
|
|
8
|
+
export const TYPE_ADD = "ADD";
|
|
9
|
+
export const TYPE_DELETE = "DELETE";
|
|
10
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { createIdentifier } from "@wendellhu/redi";
|
|
2
|
+
import type { JsonArray, JsonValue } from "./JsonTypes";
|
|
3
|
+
import type { DiffContext } from "../../service/diff/DiffContext";
|
|
4
|
+
import type { PathTracker } from "../../service/diff/PathTracker";
|
|
5
|
+
|
|
6
|
+
export interface IArrayComparator {
|
|
7
|
+
diffArray(a: JsonArray, b: JsonArray, pathTracker: PathTracker): DiffContext;
|
|
8
|
+
diffElement(
|
|
9
|
+
a: JsonValue | undefined,
|
|
10
|
+
b: JsonValue | undefined,
|
|
11
|
+
pathTracker: PathTracker
|
|
12
|
+
): DiffContext;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const IArrayComparator = createIdentifier<IArrayComparator>("IArrayComparator");
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { createIdentifier } from "@wendellhu/redi";
|
|
2
|
+
import type { JsonValue } from "./JsonTypes";
|
|
3
|
+
import type { DiffContext } from "../../service/diff/DiffContext";
|
|
4
|
+
import type { PathTracker } from "../../service/diff/PathTracker";
|
|
5
|
+
import type { IArrayComparator } from "./ArrayComparator";
|
|
6
|
+
|
|
7
|
+
export interface IComparatorOrchestrator {
|
|
8
|
+
diffElement(
|
|
9
|
+
a: JsonValue | undefined,
|
|
10
|
+
b: JsonValue | undefined,
|
|
11
|
+
pathTracker: PathTracker
|
|
12
|
+
): DiffContext;
|
|
13
|
+
getArrayComparator(): IArrayComparator;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const IComparatorOrchestrator = createIdentifier<IComparatorOrchestrator>("IComparatorOrchestrator");
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { createIdentifier } from "@wendellhu/redi";
|
|
2
|
+
import type { JsonValue } from "./JsonTypes";
|
|
3
|
+
import type { Result } from "./Result";
|
|
4
|
+
|
|
5
|
+
export interface IDiffService {
|
|
6
|
+
/**
|
|
7
|
+
* Diff two JSON strings
|
|
8
|
+
* @param leftJson - Left JSON string
|
|
9
|
+
* @param rightJson - Right JSON string
|
|
10
|
+
* @returns Array of differences
|
|
11
|
+
*/
|
|
12
|
+
diffJson(leftJson: string, rightJson: string, options?: {
|
|
13
|
+
noisePath?: string[];
|
|
14
|
+
specialPath?: string[];
|
|
15
|
+
parseNestedJson?: boolean;
|
|
16
|
+
}): Result[];
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Diff two JSON objects directly
|
|
20
|
+
* @param left - Left JSON value
|
|
21
|
+
* @param right - Right JSON value
|
|
22
|
+
* @returns Array of differences
|
|
23
|
+
*/
|
|
24
|
+
diffElement(left: JsonValue, right: JsonValue, options?: {
|
|
25
|
+
noisePath?: string[];
|
|
26
|
+
specialPath?: string[];
|
|
27
|
+
parseNestedJson?: boolean;
|
|
28
|
+
}): Result[];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const IDiffService = createIdentifier<IDiffService>("IDiffService");
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { createIdentifier } from "@wendellhu/redi";
|
|
2
|
+
import type { DiffContext } from "../../service/diff/DiffContext";
|
|
3
|
+
import type { PathTracker } from "../../service/diff/PathTracker";
|
|
4
|
+
|
|
5
|
+
export interface INullComparator {
|
|
6
|
+
diff(a: null, b: null, pathTracker: PathTracker): DiffContext;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const INullComparator = createIdentifier<INullComparator>("INullComparator");
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { createIdentifier } from "@wendellhu/redi";
|
|
2
|
+
import type { JsonObject, JsonValue } from "./JsonTypes";
|
|
3
|
+
import type { DiffContext } from "../../service/diff/DiffContext";
|
|
4
|
+
import type { PathTracker } from "../../service/diff/PathTracker";
|
|
5
|
+
|
|
6
|
+
export interface IObjectComparator {
|
|
7
|
+
diff(a: JsonObject, b: JsonObject, pathTracker: PathTracker): DiffContext;
|
|
8
|
+
diffElement(
|
|
9
|
+
a: JsonValue | undefined,
|
|
10
|
+
b: JsonValue | undefined,
|
|
11
|
+
pathTracker: PathTracker
|
|
12
|
+
): DiffContext;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const IObjectComparator = createIdentifier<IObjectComparator>("IObjectComparator");
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { createIdentifier } from "@wendellhu/redi";
|
|
2
|
+
import type { JsonValue } from "./JsonTypes";
|
|
3
|
+
import type { DiffContext } from "../../service/diff/DiffContext";
|
|
4
|
+
import type { PathTracker } from "../../service/diff/PathTracker";
|
|
5
|
+
|
|
6
|
+
export interface IOtherComparator {
|
|
7
|
+
diff(
|
|
8
|
+
a: JsonValue | undefined,
|
|
9
|
+
b: JsonValue | undefined,
|
|
10
|
+
pathTracker: PathTracker
|
|
11
|
+
): DiffContext;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const IOtherComparator = createIdentifier<IOtherComparator>("IOtherComparator");
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { createIdentifier } from "@wendellhu/redi";
|
|
2
|
+
import type { DiffContext } from "../../service/diff/DiffContext";
|
|
3
|
+
import type { PathTracker } from "../../service/diff/PathTracker";
|
|
4
|
+
|
|
5
|
+
export interface IPrimitiveComparator {
|
|
6
|
+
diff(
|
|
7
|
+
a: string | number | boolean,
|
|
8
|
+
b: string | number | boolean,
|
|
9
|
+
pathTracker: PathTracker
|
|
10
|
+
): DiffContext;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const IPrimitiveComparator = createIdentifier<IPrimitiveComparator>("IPrimitiveComparator");
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export class SingleNodeDifference {
|
|
2
|
+
leftPath: string;
|
|
3
|
+
rightPath: string;
|
|
4
|
+
left: unknown;
|
|
5
|
+
right: unknown;
|
|
6
|
+
|
|
7
|
+
constructor(leftPath: string, rightPath: string, left: unknown, right: unknown) {
|
|
8
|
+
this.leftPath = leftPath;
|
|
9
|
+
this.rightPath = rightPath;
|
|
10
|
+
this.left = left;
|
|
11
|
+
this.right = right;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from "./JsonTypes";
|
|
2
|
+
export * from "./Result";
|
|
3
|
+
export * from "./SingleNodeDifference";
|
|
4
|
+
export * from "./ComparatorOrchestrator";
|
|
5
|
+
export * from "./ObjectComparator";
|
|
6
|
+
export * from "./ArrayComparator";
|
|
7
|
+
export * from "./PrimitiveComparator";
|
|
8
|
+
export * from "./NullComparator";
|
|
9
|
+
export * from "./OtherComparator";
|
|
10
|
+
export * from "./DiffService";
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Public API - Types
|
|
2
|
+
export type { JsonValue, JsonObject, JsonArray } from "./contract/type/JsonTypes";
|
|
3
|
+
export { Result } from "./contract/type/Result";
|
|
4
|
+
export * from "./contract/type/DiffService";
|
|
5
|
+
|
|
6
|
+
// Public API - Constants
|
|
7
|
+
export {
|
|
8
|
+
TYPE_ADD,
|
|
9
|
+
TYPE_DELETE,
|
|
10
|
+
TYPE_MODIFY,
|
|
11
|
+
} from "./contract/constant";
|
|
12
|
+
|
|
13
|
+
// Public API - Enums
|
|
14
|
+
export { PresetName } from "./contract/constant/PresetName";
|
|
15
|
+
|
|
16
|
+
// Public API - Service
|
|
17
|
+
export { DiffService } from "./service";
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Inject } from "@wendellhu/redi";
|
|
2
|
+
import {
|
|
3
|
+
type IComparatorOrchestrator,
|
|
4
|
+
type IObjectComparator,
|
|
5
|
+
IObjectComparator as IObjectComparatorToken,
|
|
6
|
+
type IArrayComparator,
|
|
7
|
+
IArrayComparator as IArrayComparatorToken,
|
|
8
|
+
type IPrimitiveComparator,
|
|
9
|
+
IPrimitiveComparator as IPrimitiveComparatorToken,
|
|
10
|
+
type INullComparator,
|
|
11
|
+
INullComparator as INullComparatorToken,
|
|
12
|
+
type IOtherComparator,
|
|
13
|
+
IOtherComparator as IOtherComparatorToken,
|
|
14
|
+
type JsonValue,
|
|
15
|
+
} from "../../contract/type";
|
|
16
|
+
import { DiffContext } from "../diff/DiffContext";
|
|
17
|
+
import type { PathTracker } from "../diff/PathTracker";
|
|
18
|
+
import { isJsonObject, isJsonArray, isJsonPrimitive, isJsonNull } from "../../util";
|
|
19
|
+
|
|
20
|
+
export class ComparatorOrchestrator implements IComparatorOrchestrator {
|
|
21
|
+
constructor(
|
|
22
|
+
@Inject(IObjectComparatorToken) protected objectComparator: IObjectComparator,
|
|
23
|
+
@Inject(IArrayComparatorToken) protected arrayComparator: IArrayComparator,
|
|
24
|
+
@Inject(IPrimitiveComparatorToken) protected primitiveComparator: IPrimitiveComparator,
|
|
25
|
+
@Inject(INullComparatorToken) protected nullComparator: INullComparator,
|
|
26
|
+
@Inject(IOtherComparatorToken) protected otherComparator: IOtherComparator
|
|
27
|
+
) {}
|
|
28
|
+
|
|
29
|
+
diffElement(
|
|
30
|
+
a: JsonValue | undefined,
|
|
31
|
+
b: JsonValue | undefined,
|
|
32
|
+
pathTracker: PathTracker
|
|
33
|
+
): DiffContext {
|
|
34
|
+
if (isJsonObject(a) && isJsonObject(b)) {
|
|
35
|
+
return this.objectComparator.diff(a, b, pathTracker);
|
|
36
|
+
} else if (isJsonArray(a) && isJsonArray(b)) {
|
|
37
|
+
return this.arrayComparator.diffArray(a, b, pathTracker);
|
|
38
|
+
} else if (isJsonPrimitive(a) && isJsonPrimitive(b)) {
|
|
39
|
+
return this.primitiveComparator.diff(a, b, pathTracker);
|
|
40
|
+
} else if (isJsonNull(a) && isJsonNull(b)) {
|
|
41
|
+
return this.nullComparator.diff(a, b, pathTracker);
|
|
42
|
+
} else {
|
|
43
|
+
return this.otherComparator.diff(a, b, pathTracker);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
getArrayComparator(): IArrayComparator {
|
|
48
|
+
return this.arrayComparator;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Inject } from "@wendellhu/redi";
|
|
2
|
+
import type { IArrayComparator, IComparatorOrchestrator, JsonArray, JsonValue } from "../../../contract/type";
|
|
3
|
+
import { IComparatorOrchestrator as IComparatorOrchestratorToken } from "../../../contract/type";
|
|
4
|
+
import { DiffContext } from "../../diff/DiffContext";
|
|
5
|
+
import type { PathTracker } from "../../diff/PathTracker";
|
|
6
|
+
import { DIFFERENT } from "../../../contract/constant";
|
|
7
|
+
|
|
8
|
+
export abstract class AbstractArray implements IArrayComparator {
|
|
9
|
+
constructor(
|
|
10
|
+
@Inject(IComparatorOrchestratorToken) protected orchestrator: IComparatorOrchestrator
|
|
11
|
+
) {}
|
|
12
|
+
|
|
13
|
+
abstract diffArray(a: JsonArray, b: JsonArray, pathTracker: PathTracker): DiffContext;
|
|
14
|
+
|
|
15
|
+
diffElement(a: JsonValue | undefined, b: JsonValue | undefined, pathTracker: PathTracker): DiffContext {
|
|
16
|
+
return this.orchestrator.diffElement(a, b, pathTracker);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
protected parentContextAddChildContext(parentResult: DiffContext, childResult: DiffContext): void {
|
|
20
|
+
if (childResult.isSame() === DIFFERENT) {
|
|
21
|
+
for (const singleNodeDifference of childResult.getDiffResultModels()) {
|
|
22
|
+
parentResult.getDiffResultModels().push(singleNodeDifference);
|
|
23
|
+
}
|
|
24
|
+
parentResult.setSame(false);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
protected constructArrayPath(i: number): string {
|
|
29
|
+
if (i === null || i === undefined || i < 0) {
|
|
30
|
+
throw new Error("数组索引号入参为空或者为负。 入参:" + i);
|
|
31
|
+
}
|
|
32
|
+
return "[" + i + "]";
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { describe, it, expect } from "bun:test";
|
|
2
|
+
import { DiffService } from "../../diff/DiffService";
|
|
3
|
+
import { SequentialArrayComparator } from "./SequentialArrayComparator";
|
|
4
|
+
|
|
5
|
+
function createSequentialDiffService(): DiffService {
|
|
6
|
+
return new DiffService().withArrayComparator(SequentialArrayComparator);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
describe("SequentialArrayComparator", () => {
|
|
10
|
+
it("should compare arrays by index", () => {
|
|
11
|
+
const left = { items: [1, 2, 3] };
|
|
12
|
+
const right = { items: [1, 4, 3] };
|
|
13
|
+
|
|
14
|
+
const diffService = createSequentialDiffService();
|
|
15
|
+
const results = diffService.diffElement(left, right);
|
|
16
|
+
|
|
17
|
+
expect(results.length).toBe(1);
|
|
18
|
+
expect(results[0].leftPath).toBe("items.[1]");
|
|
19
|
+
expect(results[0].left).toBe("2");
|
|
20
|
+
expect(results[0].right).toBe("4");
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("should detect added elements", () => {
|
|
24
|
+
const left = { items: [1, 2] };
|
|
25
|
+
const right = { items: [1, 2, 3] };
|
|
26
|
+
|
|
27
|
+
const diffService = createSequentialDiffService();
|
|
28
|
+
const results = diffService.diffElement(left, right);
|
|
29
|
+
|
|
30
|
+
expect(results.length).toBe(1);
|
|
31
|
+
expect(results[0].diffType).toBe("ADD");
|
|
32
|
+
expect(results[0].rightPath).toBe("items.[2]");
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("should detect deleted elements", () => {
|
|
36
|
+
const left = { items: [1, 2, 3] };
|
|
37
|
+
const right = { items: [1, 2] };
|
|
38
|
+
|
|
39
|
+
const diffService = createSequentialDiffService();
|
|
40
|
+
const results = diffService.diffElement(left, right);
|
|
41
|
+
|
|
42
|
+
expect(results.length).toBe(1);
|
|
43
|
+
expect(results[0].diffType).toBe("DELETE");
|
|
44
|
+
expect(results[0].leftPath).toBe("items.[2]");
|
|
45
|
+
});
|
|
46
|
+
});
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Inject } from "@wendellhu/redi";
|
|
2
|
+
import { AbstractArray } from "./AbstractArray";
|
|
3
|
+
import { DiffContext } from "../../diff/DiffContext";
|
|
4
|
+
import type { PathTracker } from "../../diff/PathTracker";
|
|
5
|
+
import type { JsonArray, IComparatorOrchestrator } from "../../../contract/type";
|
|
6
|
+
import { IComparatorOrchestrator as IComparatorOrchestratorToken } from "../../../contract/type";
|
|
7
|
+
|
|
8
|
+
export class SequentialArrayComparator extends AbstractArray {
|
|
9
|
+
constructor(
|
|
10
|
+
@Inject(IComparatorOrchestratorToken) orchestrator: IComparatorOrchestrator
|
|
11
|
+
) {
|
|
12
|
+
super(orchestrator);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
diffArray(a: JsonArray, b: JsonArray, pathTracker: PathTracker): DiffContext {
|
|
16
|
+
const arrayDiffContext = new DiffContext();
|
|
17
|
+
const maxLength = Math.max(a.length, b.length);
|
|
18
|
+
|
|
19
|
+
for (let i = 0; i < maxLength; i++) {
|
|
20
|
+
pathTracker.addAllpath(this.constructArrayPath(i));
|
|
21
|
+
const diffContext = this.generateDiffResult(a, b, i, pathTracker);
|
|
22
|
+
this.parentContextAddChildContext(arrayDiffContext, diffContext);
|
|
23
|
+
pathTracker.removeAllLastPath();
|
|
24
|
+
}
|
|
25
|
+
return arrayDiffContext;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
private generateDiffResult(
|
|
29
|
+
a: JsonArray,
|
|
30
|
+
b: JsonArray,
|
|
31
|
+
i: number,
|
|
32
|
+
pathTracker: PathTracker
|
|
33
|
+
): DiffContext {
|
|
34
|
+
if (i >= a.length && i >= b.length) {
|
|
35
|
+
throw new Error("数组索引号入参超过数组长度。 索引号:" + i + " 数组a:" + a + "数组b:" + b);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
let diffContext: DiffContext;
|
|
39
|
+
if (i < a.length && i < b.length) {
|
|
40
|
+
diffContext = this.diffElement(a[i], b[i], pathTracker);
|
|
41
|
+
} else if (i >= a.length) {
|
|
42
|
+
diffContext = this.diffElement(undefined, b[i], pathTracker);
|
|
43
|
+
} else {
|
|
44
|
+
diffContext = this.diffElement(a[i], undefined, pathTracker);
|
|
45
|
+
}
|
|
46
|
+
return diffContext;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { describe, it, expect } from "bun:test";
|
|
2
|
+
import { DiffService } from "../../diff/DiffService";
|
|
3
|
+
|
|
4
|
+
describe("SimilarArrayComparator", () => {
|
|
5
|
+
it("should match similar elements", () => {
|
|
6
|
+
const left = { items: [{ id: 1, name: "a" }, { id: 2, name: "b" }] };
|
|
7
|
+
const right = { items: [{ id: 2, name: "b" }, { id: 1, name: "a" }] };
|
|
8
|
+
|
|
9
|
+
const diffService = new DiffService();
|
|
10
|
+
const results = diffService.diffElement(left, right);
|
|
11
|
+
|
|
12
|
+
expect(results).toEqual([]);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it("should detect modifications in matched elements", () => {
|
|
16
|
+
const left = { items: [{ id: 1, name: "a" }] };
|
|
17
|
+
const right = { items: [{ id: 1, name: "b" }] };
|
|
18
|
+
|
|
19
|
+
const diffService = new DiffService();
|
|
20
|
+
const results = diffService.diffElement(left, right);
|
|
21
|
+
|
|
22
|
+
expect(results.length).toBe(1);
|
|
23
|
+
expect(results[0].left).toBe("a");
|
|
24
|
+
expect(results[0].right).toBe("b");
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it("should detect added elements", () => {
|
|
28
|
+
const left = { items: [{ id: 1 }] };
|
|
29
|
+
const right = { items: [{ id: 1 }, { id: 2 }] };
|
|
30
|
+
|
|
31
|
+
const diffService = new DiffService();
|
|
32
|
+
const results = diffService.diffElement(left, right);
|
|
33
|
+
|
|
34
|
+
expect(results.length).toBe(1);
|
|
35
|
+
expect(results[0].diffType).toBe("ADD");
|
|
36
|
+
});
|
|
37
|
+
});
|