|
1 |
| -import { ParserField, ParserTree, TypeDefinition, TypeSystemDefinition } from '@/Models'; |
| 1 | +import { Options, ParserField, ParserTree, TypeDefinition, TypeSystemDefinition } from '@/Models'; |
2 | 2 | import { Parser } from '@/Parser';
|
3 | 3 | import { mergeArguments } from '@/TreeOperations/merge/arguments';
|
4 | 4 | import { MergeError, ErrorConflict } from '@/TreeOperations/merge/common';
|
5 | 5 | import { isExtensionNode } from '@/TreeOperations/shared';
|
6 | 6 | import { TreeToGraphQL } from '@/TreeToGraphQL';
|
7 |
| -import { generateNodeId, getTypeName } from '@/shared'; |
| 7 | +import { createSchemaDefinition, generateNodeId, getTypeName } from '@/shared'; |
8 | 8 |
|
9 | 9 | const detectConflictOnBaseNode = (n1: ParserField, n2: ParserField) => {
|
10 | 10 | if (n1.data.type !== n2.data.type)
|
@@ -116,22 +116,142 @@ export const mergeTrees = (tree1: ParserTree, tree2: ParserTree) => {
|
116 | 116 | errors,
|
117 | 117 | };
|
118 | 118 | }
|
119 |
| - const t1Nodes = tree1.nodes.filter((t1n) => !mergedNodesT1.find((mtn1) => mtn1 === t1n)); |
| 119 | + const t1Nodes = tree1.nodes |
| 120 | + .filter((t1n) => !mergedNodesT1.find((mtn1) => mtn1 === t1n)) |
| 121 | + .filter((t) => t.data.type !== TypeSystemDefinition.SchemaDefinition); |
120 | 122 | const t2Nodes = filteredTree2Nodes
|
121 | 123 | .filter((t2n) => !mergedNodesT2.find((mtn2) => mtn2 === t2n))
|
122 |
| - .map((n) => ({ ...n, fromLibrary: true })); |
| 124 | + .map((n) => ({ ...n, fromLibrary: true })) |
| 125 | + .filter((t) => t.data.type !== TypeSystemDefinition.SchemaDefinition); |
| 126 | + |
| 127 | + const schemaDefinitionT1Query = tree1.nodes |
| 128 | + .find((n) => n.data.type === TypeSystemDefinition.SchemaDefinition) |
| 129 | + ?.args.find((a) => a.name === 'query'); |
| 130 | + const schemaDefinitionT1QueryName = |
| 131 | + schemaDefinitionT1Query?.type.fieldType.type === Options.name && schemaDefinitionT1Query?.type.fieldType.name; |
| 132 | + const queryNodeT1 = |
| 133 | + schemaDefinitionT1QueryName || |
| 134 | + tree1.nodes.find((n) => n.data.type === TypeDefinition.ObjectTypeDefinition && n.name === 'Query')?.name; |
| 135 | + |
| 136 | + const schemaDefinitionT2Query = tree2.nodes |
| 137 | + .find((n) => n.data.type === TypeSystemDefinition.SchemaDefinition) |
| 138 | + ?.args.find((a) => a.name === 'query'); |
| 139 | + const schemaDefinitionT2QueryName = |
| 140 | + schemaDefinitionT2Query?.type.fieldType.type === Options.name && schemaDefinitionT2Query?.type.fieldType.name; |
| 141 | + const queryNodeT2 = |
| 142 | + schemaDefinitionT2QueryName || |
| 143 | + tree2.nodes.find((n) => n.data.type === TypeDefinition.ObjectTypeDefinition && n.name === 'Query')?.name; |
| 144 | + |
| 145 | + const schemaDefinitionT1Mutation = tree1.nodes |
| 146 | + .find((n) => n.data.type === TypeSystemDefinition.SchemaDefinition) |
| 147 | + ?.args.find((a) => a.name === 'mutation'); |
| 148 | + const schemaDefinitionT1MutationName = |
| 149 | + schemaDefinitionT1Mutation?.type.fieldType.type === Options.name && schemaDefinitionT1Mutation?.type.fieldType.name; |
| 150 | + const mutationNodeT1 = |
| 151 | + schemaDefinitionT1MutationName || |
| 152 | + tree1.nodes.find((n) => n.data.type === TypeDefinition.ObjectTypeDefinition && n.name === 'Mutation')?.name; |
| 153 | + |
| 154 | + const schemaDefinitionT2Mutation = tree2.nodes |
| 155 | + .find((n) => n.data.type === TypeSystemDefinition.SchemaDefinition) |
| 156 | + ?.args.find((a) => a.name === 'mutation'); |
| 157 | + const schemaDefinitionT2MutationName = |
| 158 | + schemaDefinitionT2Mutation?.type.fieldType.type === Options.name && schemaDefinitionT2Mutation?.type.fieldType.name; |
| 159 | + const mutationNodeT2 = |
| 160 | + schemaDefinitionT2MutationName || |
| 161 | + tree2.nodes.find((n) => n.data.type === TypeDefinition.ObjectTypeDefinition && n.name === 'Mutation')?.name; |
| 162 | + |
| 163 | + const schemaDefinitionT1Subscription = tree1.nodes |
| 164 | + .find((n) => n.data.type === TypeSystemDefinition.SchemaDefinition) |
| 165 | + ?.args.find((a) => a.name === 'subscription'); |
| 166 | + const schemaDefinitionT1SubscriptionName = |
| 167 | + schemaDefinitionT1Subscription?.type.fieldType.type === Options.name && |
| 168 | + schemaDefinitionT1Subscription?.type.fieldType.name; |
| 169 | + const subscriptionNodeT1 = |
| 170 | + schemaDefinitionT1SubscriptionName || |
| 171 | + tree1.nodes.find((n) => n.data.type === TypeDefinition.ObjectTypeDefinition && n.name === 'Subscription')?.name; |
| 172 | + |
| 173 | + const schemaDefinitionT2Subscription = tree2.nodes |
| 174 | + .find((n) => n.data.type === TypeSystemDefinition.SchemaDefinition) |
| 175 | + ?.args.find((a) => a.name === 'subscription'); |
| 176 | + const schemaDefinitionT2SubscriptionName = |
| 177 | + schemaDefinitionT2Subscription?.type.fieldType.type === Options.name && |
| 178 | + schemaDefinitionT2Subscription?.type.fieldType.name; |
| 179 | + const subscriptionNodeT2 = |
| 180 | + schemaDefinitionT2SubscriptionName || |
| 181 | + tree2.nodes.find((n) => n.data.type === TypeDefinition.ObjectTypeDefinition && n.name === 'Subscription')?.name; |
| 182 | + |
| 183 | + if (queryNodeT1 && queryNodeT2) { |
| 184 | + if (queryNodeT1 !== queryNodeT2) { |
| 185 | + return { |
| 186 | + __typename: 'error' as const, |
| 187 | + errors: [ |
| 188 | + { |
| 189 | + conflictingNode: 'Schema', |
| 190 | + conflictingField: 'query', |
| 191 | + }, |
| 192 | + ], |
| 193 | + }; |
| 194 | + } |
| 195 | + } |
| 196 | + if (mutationNodeT1 && mutationNodeT2) { |
| 197 | + if (mutationNodeT1 !== mutationNodeT2) { |
| 198 | + return { |
| 199 | + __typename: 'error' as const, |
| 200 | + errors: [ |
| 201 | + { |
| 202 | + conflictingNode: 'Schema', |
| 203 | + conflictingField: 'mutation', |
| 204 | + }, |
| 205 | + ], |
| 206 | + }; |
| 207 | + } |
| 208 | + } |
| 209 | + if (subscriptionNodeT1 && subscriptionNodeT2) { |
| 210 | + if (subscriptionNodeT1 !== subscriptionNodeT2) { |
| 211 | + return { |
| 212 | + __typename: 'error' as const, |
| 213 | + errors: [ |
| 214 | + { |
| 215 | + conflictingNode: 'Schema', |
| 216 | + conflictingField: 'subscription', |
| 217 | + }, |
| 218 | + ], |
| 219 | + }; |
| 220 | + } |
| 221 | + } |
| 222 | + const resultSchemaDefinitionNode: ParserField = createSchemaDefinition({ |
| 223 | + operations: { |
| 224 | + ...(queryNodeT1 && { query: queryNodeT1 }), |
| 225 | + ...(mutationNodeT1 && { mutation: mutationNodeT1 }), |
| 226 | + ...(subscriptionNodeT1 && { subscription: subscriptionNodeT1 }), |
| 227 | + ...(queryNodeT2 && { query: queryNodeT2 }), |
| 228 | + ...(mutationNodeT2 && { mutation: mutationNodeT2 }), |
| 229 | + ...(subscriptionNodeT2 && { subscription: subscriptionNodeT2 }), |
| 230 | + }, |
| 231 | + }); |
123 | 232 | return {
|
124 | 233 | __typename: 'success' as const,
|
125 |
| - nodes: [...t1Nodes, ...mergeResultNodes, ...t2Nodes], |
| 234 | + nodes: [ |
| 235 | + ...t1Nodes, |
| 236 | + ...mergeResultNodes.filter((t) => t.data.type !== TypeSystemDefinition.SchemaDefinition), |
| 237 | + ...t2Nodes, |
| 238 | + ...(resultSchemaDefinitionNode.args.length ? [resultSchemaDefinitionNode] : []), |
| 239 | + ], |
126 | 240 | };
|
127 | 241 | };
|
128 | 242 |
|
129 | 243 | export const mergeSDLs = (sdl1: string, sdl2: string) => {
|
130 | 244 | const t1 = Parser.parse(sdl1);
|
131 | 245 | const t2 = Parser.parse(sdl2);
|
132 |
| - const mergeResult = mergeTrees(t1, { |
133 |
| - nodes: t2.nodes.filter((n) => n.data.type !== TypeSystemDefinition.SchemaDefinition), |
134 |
| - }); |
| 246 | + // find query node in t1 |
| 247 | + const mergeResult = mergeTrees( |
| 248 | + { |
| 249 | + nodes: [...t1.nodes], |
| 250 | + }, |
| 251 | + { |
| 252 | + nodes: [...t2.nodes], |
| 253 | + }, |
| 254 | + ); |
135 | 255 | if (mergeResult.__typename === 'success') {
|
136 | 256 | const sdl = TreeToGraphQL.parse(mergeResult);
|
137 | 257 | return {
|
|
0 commit comments