File tree Expand file tree Collapse file tree 2 files changed +38
-0
lines changed Expand file tree Collapse file tree 2 files changed +38
-0
lines changed Original file line number Diff line number Diff line change @@ -4,6 +4,7 @@ import { SubTypeFormatter } from "../SubTypeFormatter";
4
4
import { BaseType } from "../Type/BaseType" ;
5
5
import { UnionType } from "../Type/UnionType" ;
6
6
import { TypeFormatter } from "../TypeFormatter" ;
7
+ import { mergeDefinitions } from "../Utils/mergeDefinitions" ;
7
8
import { uniqueArray } from "../Utils/uniqueArray" ;
8
9
9
10
export class UnionTypeFormatter implements SubTypeFormatter {
@@ -45,6 +46,18 @@ export class UnionTypeFormatter implements SubTypeFormatter {
45
46
}
46
47
}
47
48
49
+ for ( let idx = 0 ; idx < flattenedDefinitions . length - 1 ; idx ++ ) {
50
+ for ( let comp = idx + 1 ; comp < flattenedDefinitions . length ; ) {
51
+ const merged = mergeDefinitions ( flattenedDefinitions [ idx ] , flattenedDefinitions [ comp ] ) ;
52
+ if ( merged ) {
53
+ flattenedDefinitions [ idx ] = merged ;
54
+ flattenedDefinitions . splice ( comp , 1 ) ;
55
+ } else {
56
+ comp ++ ;
57
+ }
58
+ }
59
+ }
60
+
48
61
return flattenedDefinitions . length > 1
49
62
? {
50
63
anyOf : flattenedDefinitions ,
Original file line number Diff line number Diff line change
1
+ import { Definition } from "../Schema/Definition" ;
2
+ import { uniqueArray } from "./uniqueArray" ;
3
+
4
+ /**
5
+ * Attempt to merge two disjoint definitions into one. Definitions are disjoint
6
+ * (and therefore mergeable) if all of the following are true:
7
+ * 1) Each has a 'type' property, and they share no types in common,
8
+ * 2) The cross-type validation properties 'enum' and 'const' are not on either definition, and
9
+ * 3) The two definitions have no properties besides 'type' in common.
10
+ *
11
+ * Returns the merged definition, or null if the two defs were not disjoint.
12
+ */
13
+ export function mergeDefinitions ( def1 : Definition , def2 : Definition ) : Definition | null {
14
+ const { type : type1 , ...props1 } = def1 ;
15
+ const { type : type2 , ...props2 } = def2 ;
16
+ const types = [ type1 ! , type2 ! ] . flat ( ) ;
17
+ if ( ! type1 || ! type2 || uniqueArray ( types ) . length !== types . length ) {
18
+ return null ;
19
+ }
20
+ const keys = [ Object . keys ( props1 ) , Object . keys ( props2 ) ] . flat ( ) ;
21
+ if ( keys . includes ( "enum" ) || keys . includes ( "const" ) || uniqueArray ( keys ) . length !== keys . length ) {
22
+ return null ;
23
+ }
24
+ return { type : types , ...props1 , ...props2 } ;
25
+ }
You can’t perform that action at this time.
0 commit comments