From 0c136153faa65c23da18d01135a5c9c512b681ce Mon Sep 17 00:00:00 2001 From: Adrien FIGARD Date: Fri, 12 Jul 2024 16:01:02 +0200 Subject: [PATCH] :bulb: Add comments to patches --- .../patches/@graphql-tools+stitch+9.0.3.patch | 23 +++++++++---------- .../patches/json-machete+0.97.1.patch | 6 ++--- patches/@graphql-tools+executor+1.2.1.patch | 15 ++++++++---- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/packages/graphql-mesh/patches/@graphql-tools+stitch+9.0.3.patch b/packages/graphql-mesh/patches/@graphql-tools+stitch+9.0.3.patch index 65caece..a250573 100644 --- a/packages/graphql-mesh/patches/@graphql-tools+stitch+9.0.3.patch +++ b/packages/graphql-mesh/patches/@graphql-tools+stitch+9.0.3.patch @@ -12,23 +12,26 @@ index 5e752ad..3b487f5 100644 const currentNamedType = (0, graphql_1.getNamedType)(c.type); if (finalNamedType.toString() !== currentNamedType.toString()) { diff --git a/node_modules/@graphql-tools/stitch/cjs/typeCandidates.js b/node_modules/@graphql-tools/stitch/cjs/typeCandidates.js -index c915942..c2a322a 100644 +index c915942..ae923fe 100644 --- a/node_modules/@graphql-tools/stitch/cjs/typeCandidates.js +++ b/node_modules/@graphql-tools/stitch/cjs/typeCandidates.js -@@ -119,6 +119,29 @@ function buildTypes({ typeCandidates, directives, stitchingInfo, rootTypeNames, +@@ -119,6 +119,33 @@ function buildTypes({ typeCandidates, directives, stitchingInfo, rootTypeNames, (typeof mergeTypes === 'function' && mergeTypes(typeCandidates[typeName], typeName)) || (Array.isArray(mergeTypes) && mergeTypes.includes(typeName)) || (stitchingInfo != null && typeName in stitchingInfo.mergedTypes)) { + -+ // Custom object-interface stitching ++ // Special handling for object-interface stitching + const candidates = typeCandidates[typeName].sort((a, b) => a.subschema.name.localeCompare(b.subschema.name)); ++ // Check for candidates with different constructors (e.g., object and interface) + if (candidates.some(candidate => candidate.type.constructor !== candidates[0].type.constructor)) { + const candidatesI = candidates.filter((c) => c.type.constructor.name === "GraphQLInterfaceType"); + const candidatesObj = candidates.filter((c) => c.type.constructor.name === "GraphQLObjectType"); ++ // If all the candidates are either interfaces or objects + if (candidatesI.length + candidatesObj.length === candidates.length) { + let finalI = candidatesI[0]; + const otherCandidates = candidatesI.slice(1, candidatesI.length).concat(candidatesObj); + otherCandidates.forEach((otherCandidate) => { ++ // Add fields from other candidates to the final interface + Object.keys(otherCandidate.type._fields).forEach(field => { + if (finalI.type._fields[field] === undefined) { + finalI.type._fields[field] = otherCandidate.type._fields[field]; @@ -37,6 +40,7 @@ index c915942..c2a322a 100644 + }); + typeCandidates[typeName] = [finalI]; + } ++ // Special handling for Date scalar type if it appears among the candidates + if (typeName === "Date") { + typeCandidates[typeName] = candidates.filter((c) => c.type.constructor.name === "GraphQLScalarType"); + } @@ -45,14 +49,12 @@ index c915942..c2a322a 100644 typeMap[typeName] = (0, mergeCandidates_js_1.mergeCandidates)(typeName, typeCandidates[typeName], typeMergingOptions); } else { -@@ -128,6 +151,66 @@ function buildTypes({ typeCandidates, directives, stitchingInfo, rootTypeNames, +@@ -128,6 +155,61 @@ function buildTypes({ typeCandidates, directives, stitchingInfo, rootTypeNames, typeMap[typeName] = candidateSelector(typeCandidates[typeName]).type; } } + -+ /** -+ * Really tidious edge case when an object implements more than 1 interface -+ */ ++ // Handle edge case: object implementing more than one interface + Object.values(typeMap).forEach((type) => { + if (type.constructor.name === "GraphQLObjectType") { + const typeInterfaces = type.getInterfaces(); @@ -72,6 +74,7 @@ index c915942..c2a322a 100644 + } + }) + }) ++ // Ensure duplicate fields are consistent across implementations + Object.keys(duplicateFields).forEach(field => { + if (type.getFields()[field] !== undefined) { + type._fields[field] = duplicateFields[field]; @@ -87,11 +90,7 @@ index c915942..c2a322a 100644 + } + } + }); -+ /** -+ * When an object implements an interface, it needs to have every property -+ * of this interface. Because interfaces have been possibly merged earlier -+ * in this file, this statement is sometimes not true anymore. -+ */ ++ // Ensure object types implement all fields from their interfaces + Object.values(typeMap).forEach((type) => { + if (type.constructor.name === "GraphQLObjectType") { + const typeInterfaces = type.getInterfaces(); diff --git a/packages/graphql-mesh/patches/json-machete+0.97.1.patch b/packages/graphql-mesh/patches/json-machete+0.97.1.patch index 317276e..0e7eae9 100644 --- a/packages/graphql-mesh/patches/json-machete+0.97.1.patch +++ b/packages/graphql-mesh/patches/json-machete+0.97.1.patch @@ -1,7 +1,5 @@ diff --git a/node_modules/json-machete/cjs/healJSONSchema.js b/node_modules/json-machete/cjs/healJSONSchema.js -old mode 100644 -new mode 100755 -index 5d7e615..7d4ed0c +index 5d7e615..88ae5fb 100644 --- a/node_modules/json-machete/cjs/healJSONSchema.js +++ b/node_modules/json-machete/cjs/healJSONSchema.js @@ -40,12 +40,28 @@ exports.AnySchema = { @@ -39,7 +37,7 @@ index 5d7e615..7d4ed0c subSchema.enum) { - debugLogFn?.(`${path} has a pattern or maxLength or minLength or enum but no title. Setting it to ${pathBasedName}`); - subSchema.title = pathBasedName; -+ // Change enum names to be able to merge them ++ // Change the default enum names to be able to merge them + const newEnumName = `ENUM_${maybeDefinitionBasedPath.split('/')[maybeDefinitionBasedPath.split('/').length-1]}` + debugLogFn?.(`${path} has a enum but no title. Setting it to ${newEnumName}`); + subSchema.title = newEnumName; diff --git a/patches/@graphql-tools+executor+1.2.1.patch b/patches/@graphql-tools+executor+1.2.1.patch index 8d34986..5daa021 100644 --- a/patches/@graphql-tools+executor+1.2.1.patch +++ b/patches/@graphql-tools+executor+1.2.1.patch @@ -1,14 +1,17 @@ diff --git a/node_modules/@graphql-tools/executor/cjs/execution/execute.js b/node_modules/@graphql-tools/executor/cjs/execution/execute.js old mode 100644 new mode 100755 -index 791e3df..b6a78f0 +index 791e3df..ae399d9 --- a/node_modules/@graphql-tools/executor/cjs/execution/execute.js +++ b/node_modules/@graphql-tools/executor/cjs/execution/execute.js -@@ -629,7 +629,10 @@ function completeAbstractValue(exeContext, returnType, fieldNodes, info, path, r +@@ -628,8 +628,13 @@ function completeAbstractValue(exeContext, returnType, fieldNodes, info, path, r + return completeObjectValue(exeContext, ensureValidRuntimeType(runtimeType, exeContext, returnType, fieldNodes, info, result), fieldNodes, info, path, result, asyncPayloadRecord); } function ensureValidRuntimeType(runtimeTypeName, exeContext, returnType, fieldNodes, info, result) { ++ // If runtimeTypeName is null or undefined, derive it from the discriminator directive in the returnType if (runtimeTypeName == null) { - throw (0, utils_1.createGraphQLError)(`Abstract type "${returnType.name}" must resolve to an Object type at runtime for field "${info.parentType.name}.${info.fieldName}". Either the "${returnType.name}" type should provide a "resolveType" function or each possible type should provide an "isTypeOf" function.`, { nodes: fieldNodes }); ++ // Extract version suffix from return type name + const suffix = returnType.name.split('_')[1] + runtimeTypeName = Object.values(JSON.parse(returnType.astNode.directives + .find(d => d.name.value === "discriminator").arguments @@ -16,16 +19,18 @@ index 791e3df..b6a78f0 } // releases before 16.0.0 supported returning `GraphQLObjectType` from `resolveType` // TODO: remove in 17.0.0 release -@@ -640,6 +643,15 @@ function ensureValidRuntimeType(runtimeTypeName, exeContext, returnType, fieldNo +@@ -640,6 +645,17 @@ function ensureValidRuntimeType(runtimeTypeName, exeContext, returnType, fieldNo throw (0, utils_1.createGraphQLError)(`Abstract type "${returnType.name}" must resolve to an Object type at runtime for field "${info.parentType.name}.${info.fieldName}" with ` + `value ${(0, utils_1.inspect)(result)}, received "${(0, utils_1.inspect)(runtimeTypeName)}".`); } -+ // Resolve type from mapping of discriminator directive when possible ++ // Resolves the type from the mapping of the discriminator directive when possible. + const mappedTypes = JSON.parse(returnType.astNode.directives + .find(d => d.name.value === "discriminator").arguments + .find(a => a.name.value === "mapping").value.value) -+ Object.keys(mappedTypes).forEach((type) => { ++ Object.keys(mappedTypes).forEach((type) => { ++ // For each key in the mapping object, check if the runtimeTypeName includes the key + if (runtimeTypeName.includes(type)) { ++ // Replace the key with its corresponding mapped type in the runtimeTypeName + runtimeTypeName = runtimeTypeName.replace(type, mappedTypes[type]) + } + })