@graphql-tools/federation
Version:
Useful tools to create and manipulate GraphQL schemas.
697 lines (696 loc) • 35.7 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getStitchedSchemaFromSupergraphSdl = exports.getSubschemasFromSupergraphSdl = exports.getFieldMergerFromSupergraphSdl = exports.ensureSupergraphSDLAst = void 0;
const graphql_1 = require("graphql");
const executor_http_1 = require("@graphql-tools/executor-http");
const stitch_1 = require("@graphql-tools/stitch");
const utils_1 = require("@graphql-tools/utils");
const utils_js_1 = require("./utils.js");
function ensureSupergraphSDLAst(supergraphSdl) {
return typeof supergraphSdl === 'string'
? (0, graphql_1.parse)(supergraphSdl, { noLocation: true })
: supergraphSdl;
}
exports.ensureSupergraphSDLAst = ensureSupergraphSDLAst;
function getTypeFieldMapFromSupergraphAST(supergraphAST) {
const typeFieldASTMap = new Map();
for (const definition of supergraphAST.definitions) {
if ('fields' in definition) {
const fieldMap = new Map();
typeFieldASTMap.set(definition.name.value, fieldMap);
for (const field of definition.fields || []) {
fieldMap.set(field.name.value, field);
}
}
}
return typeFieldASTMap;
}
function getFieldMergerFromSupergraphSdl(supergraphSdl) {
const supergraphAST = ensureSupergraphSDLAst(supergraphSdl);
const typeFieldASTMap = getTypeFieldMapFromSupergraphAST(supergraphAST);
const defaultMerger = (0, stitch_1.getDefaultFieldConfigMerger)(true);
const memoizedASTPrint = (0, utils_1.memoize1)(graphql_1.print);
const memoizedTypePrint = (0, utils_1.memoize1)((type) => type.toString());
return function (candidates) {
const filteredCandidates = candidates.filter(candidate => {
const fieldASTMap = typeFieldASTMap.get(candidate.type.name);
if (fieldASTMap) {
const fieldAST = fieldASTMap.get(candidate.fieldName);
if (fieldAST) {
const typeNodeInAST = memoizedASTPrint(fieldAST.type);
const typeNodeInCandidate = memoizedTypePrint(candidate.fieldConfig.type);
return typeNodeInAST === typeNodeInCandidate;
}
}
return false;
});
return defaultMerger(filteredCandidates.length ? filteredCandidates : candidates);
};
}
exports.getFieldMergerFromSupergraphSdl = getFieldMergerFromSupergraphSdl;
function getSubschemasFromSupergraphSdl({ supergraphSdl, onExecutor = ({ endpoint }) => (0, executor_http_1.buildHTTPExecutor)({ endpoint }), batch = false, }) {
const supergraphAst = ensureSupergraphSDLAst(supergraphSdl);
const subgraphEndpointMap = new Map();
const subgraphTypesMap = new Map();
const typeNameKeysBySubgraphMap = new Map();
const typeNameFieldsKeyBySubgraphMap = new Map();
const typeNameCanonicalMap = new Map();
const subgraphTypeNameExtraFieldsMap = new Map();
const orphanTypeMap = new Map();
// TODO: Temporary fix to add missing join__type directives to Query
const subgraphNames = [];
(0, graphql_1.visit)(supergraphAst, {
EnumTypeDefinition(node) {
if (node.name.value === 'join__Graph') {
node.values?.forEach(valueNode => {
subgraphNames.push(valueNode.name.value);
});
}
},
});
// END TODO
function TypeWithFieldsVisitor(typeNode) {
// TODO: Temporary fix to add missing join__type directives to Query
if (typeNode.name.value === 'Query' ||
(typeNode.name.value === 'Mutation' &&
!typeNode.directives?.some(directiveNode => directiveNode.name.value === 'join__type'))) {
typeNode.directives = [
...(typeNode.directives || []),
...subgraphNames.map(subgraphName => ({
kind: graphql_1.Kind.DIRECTIVE,
name: {
kind: graphql_1.Kind.NAME,
value: 'join__type',
},
arguments: [
{
kind: graphql_1.Kind.ARGUMENT,
name: {
kind: graphql_1.Kind.NAME,
value: 'graph',
},
value: {
kind: graphql_1.Kind.ENUM,
value: subgraphName,
},
},
],
})),
];
}
let isOrphan = true;
// END TODO
const fieldDefinitionNodesByGraphName = new Map();
typeNode.directives?.forEach(directiveNode => {
if (typeNode.kind === graphql_1.Kind.OBJECT_TYPE_DEFINITION) {
if (directiveNode.name.value === 'join__owner') {
directiveNode.arguments?.forEach(argumentNode => {
if (argumentNode.name.value === 'graph' && argumentNode.value?.kind === graphql_1.Kind.ENUM) {
typeNameCanonicalMap.set(typeNode.name.value, argumentNode.value.value);
}
});
}
}
if (directiveNode.name.value === 'join__type') {
isOrphan = false;
const joinTypeGraphArgNode = directiveNode.arguments?.find(argumentNode => argumentNode.name.value === 'graph');
if (joinTypeGraphArgNode?.value?.kind === graphql_1.Kind.ENUM) {
const graphName = joinTypeGraphArgNode.value.value;
if (typeNode.kind === graphql_1.Kind.OBJECT_TYPE_DEFINITION) {
const keyArgumentNode = directiveNode.arguments?.find(argumentNode => argumentNode.name.value === 'key');
if (keyArgumentNode?.value?.kind === graphql_1.Kind.STRING) {
let typeNameKeysMap = typeNameKeysBySubgraphMap.get(graphName);
if (!typeNameKeysMap) {
typeNameKeysMap = new Map();
typeNameKeysBySubgraphMap.set(graphName, typeNameKeysMap);
}
let keys = typeNameKeysMap.get(typeNode.name.value);
if (!keys) {
keys = [];
typeNameKeysMap.set(typeNode.name.value, keys);
}
keys.push(keyArgumentNode.value.value);
}
}
const fieldDefinitionNodesOfSubgraph = [];
typeNode.fields?.forEach(fieldNode => {
const joinFieldDirectives = fieldNode.directives?.filter(directiveNode => directiveNode.name.value === 'join__field' && directiveNode.arguments?.length);
let notInSubgraph = true;
joinFieldDirectives?.forEach(joinFieldDirectiveNode => {
const joinFieldGraphArgNode = joinFieldDirectiveNode.arguments?.find(argumentNode => argumentNode.name.value === 'graph');
if (joinFieldGraphArgNode?.value?.kind === graphql_1.Kind.ENUM &&
joinFieldGraphArgNode.value.value === graphName) {
notInSubgraph = false;
const isExternal = joinFieldDirectiveNode.arguments?.some(argumentNode => argumentNode.name.value === 'external' &&
argumentNode.value?.kind === graphql_1.Kind.BOOLEAN &&
argumentNode.value.value === true);
if (!isExternal) {
const typeArg = joinFieldDirectiveNode.arguments?.find(argumentNode => argumentNode.name.value === 'type');
const typeNode = typeArg?.value.kind === graphql_1.Kind.STRING
? (0, graphql_1.parseType)(typeArg.value.value)
: fieldNode.type;
fieldDefinitionNodesOfSubgraph.push({
...fieldNode,
type: typeNode,
directives: fieldNode.directives?.filter(directiveNode => directiveNode.name.value !== 'join__field'),
});
}
const providedExtraField = joinFieldDirectiveNode.arguments?.find(argumentNode => argumentNode.name.value === 'provides');
if (providedExtraField?.value?.kind === graphql_1.Kind.STRING) {
let typeNameExtraFieldsMap = subgraphTypeNameExtraFieldsMap.get(graphName);
if (!typeNameExtraFieldsMap) {
typeNameExtraFieldsMap = new Map();
subgraphTypeNameExtraFieldsMap.set(graphName, typeNameExtraFieldsMap);
}
const fieldNodeType = (0, utils_js_1.getNamedTypeNode)(fieldNode.type);
let extraFields = typeNameExtraFieldsMap.get(fieldNodeType.name.value);
if (!extraFields) {
extraFields = [];
typeNameExtraFieldsMap.set(fieldNodeType.name.value, extraFields);
}
const extraFieldTypeNode = supergraphAst.definitions.find(def => 'name' in def && def.name?.value === fieldNodeType.name.value);
providedExtraField.value.value.split(' ').forEach(extraField => {
const extraFieldNodeInType = extraFieldTypeNode.fields?.find(fieldNode => fieldNode.name.value === extraField);
if (extraFieldNodeInType) {
extraFields.push({
...extraFieldNodeInType,
directives: extraFieldNodeInType.directives?.filter(directiveNode => directiveNode.name.value !== 'join__field'),
});
}
});
}
const requiresArgumentNode = joinFieldDirectiveNode.arguments?.find(argumentNode => argumentNode.name.value === 'requires');
if (requiresArgumentNode?.value?.kind === graphql_1.Kind.STRING) {
let typeNameFieldsKeyMap = typeNameFieldsKeyBySubgraphMap.get(graphName);
if (!typeNameFieldsKeyMap) {
typeNameFieldsKeyMap = new Map();
typeNameFieldsKeyBySubgraphMap.set(graphName, typeNameFieldsKeyMap);
}
let fieldsKeyMap = typeNameFieldsKeyMap.get(typeNode.name.value);
if (!fieldsKeyMap) {
fieldsKeyMap = new Map();
typeNameFieldsKeyMap.set(typeNode.name.value, fieldsKeyMap);
}
fieldsKeyMap.set(fieldNode.name.value, requiresArgumentNode.value.value);
}
}
});
// Add if no join__field directive
if (!joinFieldDirectives?.length) {
fieldDefinitionNodesOfSubgraph.push({
...fieldNode,
directives: fieldNode.directives?.filter(directiveNode => directiveNode.name.value !== 'join__field'),
});
}
else if (notInSubgraph &&
typeNameKeysBySubgraphMap
.get(graphName)
?.get(typeNode.name.value)
?.some(key => key.split(' ').includes(fieldNode.name.value))) {
fieldDefinitionNodesOfSubgraph.push({
...fieldNode,
directives: fieldNode.directives?.filter(directiveNode => directiveNode.name.value !== 'join__field'),
});
}
});
if (fieldDefinitionNodesOfSubgraph.length > 0 || typeNode.name.value === 'Query') {
fieldDefinitionNodesByGraphName.set(graphName, fieldDefinitionNodesOfSubgraph);
}
}
}
});
const joinImplementsDirectives = typeNode.directives?.filter(directiveNode => directiveNode.name.value === 'join__implements');
fieldDefinitionNodesByGraphName.forEach((fieldDefinitionNodesOfSubgraph, graphName) => {
const interfaces = [];
typeNode.interfaces?.forEach(interfaceNode => {
const implementedSubgraphs = joinImplementsDirectives?.filter(directiveNode => {
const argumentNode = directiveNode.arguments?.find(argumentNode => argumentNode.name.value === 'interface');
return (argumentNode?.value?.kind === graphql_1.Kind.STRING &&
argumentNode.value.value === interfaceNode.name.value);
});
if (!implementedSubgraphs?.length ||
implementedSubgraphs.some(directiveNode => {
const argumentNode = directiveNode.arguments?.find(argumentNode => argumentNode.name.value === 'graph');
return (argumentNode?.value?.kind === graphql_1.Kind.ENUM && argumentNode.value.value === graphName);
})) {
interfaces.push(interfaceNode);
}
});
if (typeNode.name.value === 'Query') {
fieldDefinitionNodesOfSubgraph.push(entitiesFieldDefinitionNode);
}
const objectTypedDefNodeForSubgraph = {
...typeNode,
interfaces,
fields: fieldDefinitionNodesOfSubgraph,
directives: typeNode.directives?.filter(directiveNode => directiveNode.name.value !== 'join__type' &&
directiveNode.name.value !== 'join__owner' &&
directiveNode.name.value !== 'join__implements'),
};
let subgraphTypes = subgraphTypesMap.get(graphName);
if (!subgraphTypes) {
subgraphTypes = [];
subgraphTypesMap.set(graphName, subgraphTypes);
}
subgraphTypes.push(objectTypedDefNodeForSubgraph);
});
if (isOrphan) {
orphanTypeMap.set(typeNode.name.value, typeNode);
}
}
(0, graphql_1.visit)(supergraphAst, {
ScalarTypeDefinition(node) {
let isOrphan = !node.name.value.startsWith('link__') && !node.name.value.startsWith('join__');
node.directives?.forEach(directiveNode => {
if (directiveNode.name.value === 'join__type') {
directiveNode.arguments?.forEach(argumentNode => {
if (argumentNode.name.value === 'graph' && argumentNode?.value?.kind === graphql_1.Kind.ENUM) {
isOrphan = false;
const graphName = argumentNode.value.value;
let subgraphTypes = subgraphTypesMap.get(graphName);
if (!subgraphTypes) {
subgraphTypes = [];
subgraphTypesMap.set(graphName, subgraphTypes);
}
subgraphTypes.push({
...node,
directives: node.directives?.filter(directiveNode => directiveNode.name.value !== 'join__type'),
});
}
});
}
});
if (isOrphan) {
orphanTypeMap.set(node.name.value, node);
}
},
InputObjectTypeDefinition(node) {
let isOrphan = true;
node.directives?.forEach(directiveNode => {
if (directiveNode.name.value === 'join__type') {
directiveNode.arguments?.forEach(argumentNode => {
if (argumentNode.name.value === 'graph' && argumentNode?.value?.kind === graphql_1.Kind.ENUM) {
isOrphan = false;
const graphName = argumentNode.value.value;
let subgraphTypes = subgraphTypesMap.get(graphName);
if (!subgraphTypes) {
subgraphTypes = [];
subgraphTypesMap.set(graphName, subgraphTypes);
}
subgraphTypes.push({
...node,
directives: node.directives?.filter(directiveNode => directiveNode.name.value !== 'join__type'),
});
}
});
}
});
if (isOrphan) {
orphanTypeMap.set(node.name.value, node);
}
},
InterfaceTypeDefinition: TypeWithFieldsVisitor,
UnionTypeDefinition(node) {
let isOrphan = true;
node.directives?.forEach(directiveNode => {
if (directiveNode.name.value === 'join__type') {
directiveNode.arguments?.forEach(argumentNode => {
if (argumentNode.name.value === 'graph' && argumentNode?.value?.kind === graphql_1.Kind.ENUM) {
isOrphan = false;
const graphName = argumentNode.value.value;
const unionMembers = [];
node.directives?.forEach(directiveNode => {
if (directiveNode.name.value === 'join__unionMember') {
const graphArgumentNode = directiveNode.arguments?.find(argumentNode => argumentNode.name.value === 'graph');
const memberArgumentNode = directiveNode.arguments?.find(argumentNode => argumentNode.name.value === 'member');
if (graphArgumentNode?.value?.kind === graphql_1.Kind.ENUM &&
graphArgumentNode.value.value === graphName &&
memberArgumentNode?.value?.kind === graphql_1.Kind.STRING) {
unionMembers.push({
kind: graphql_1.Kind.NAMED_TYPE,
name: {
kind: graphql_1.Kind.NAME,
value: memberArgumentNode.value.value,
},
});
}
}
});
if (unionMembers.length > 0) {
let subgraphTypes = subgraphTypesMap.get(graphName);
if (!subgraphTypes) {
subgraphTypes = [];
subgraphTypesMap.set(graphName, subgraphTypes);
}
subgraphTypes.push({
...node,
types: unionMembers,
directives: node.directives?.filter(directiveNode => directiveNode.name.value !== 'join__type' &&
directiveNode.name.value !== 'join__unionMember'),
});
}
}
});
}
});
if (isOrphan && node.name.value !== '_Entity') {
orphanTypeMap.set(node.name.value, node);
}
},
EnumTypeDefinition(node) {
let isOrphan = true;
if (node.name.value === 'join__Graph') {
node.values?.forEach(valueNode => {
isOrphan = false;
valueNode.directives?.forEach(directiveNode => {
if (directiveNode.name.value === 'join__graph') {
directiveNode.arguments?.forEach(argumentNode => {
if (argumentNode.name.value === 'url' && argumentNode.value?.kind === graphql_1.Kind.STRING) {
subgraphEndpointMap.set(valueNode.name.value, argumentNode.value.value);
}
});
}
});
});
}
node.directives?.forEach(directiveNode => {
if (directiveNode.name.value === 'join__type') {
isOrphan = false;
directiveNode.arguments?.forEach(argumentNode => {
if (argumentNode.name.value === 'graph' && argumentNode.value?.kind === graphql_1.Kind.ENUM) {
const graphName = argumentNode.value.value;
const enumValueNodes = [];
node.values?.forEach(valueNode => {
const joinEnumValueDirectives = valueNode.directives?.filter(directiveNode => directiveNode.name.value === 'join__enumValue');
if (joinEnumValueDirectives?.length) {
joinEnumValueDirectives.forEach(joinEnumValueDirectiveNode => {
joinEnumValueDirectiveNode.arguments?.forEach(argumentNode => {
if (argumentNode.name.value === 'graph' &&
argumentNode.value?.kind === graphql_1.Kind.ENUM &&
argumentNode.value.value === graphName) {
enumValueNodes.push({
...valueNode,
directives: valueNode.directives?.filter(directiveNode => directiveNode.name.value !== 'join__enumValue'),
});
}
});
});
}
else {
enumValueNodes.push(valueNode);
}
});
const enumTypedDefNodeForSubgraph = {
...node,
directives: node.directives?.filter(directiveNode => directiveNode.name.value !== 'join__type'),
values: enumValueNodes,
};
let subgraphTypes = subgraphTypesMap.get(graphName);
if (!subgraphTypes) {
subgraphTypes = [];
subgraphTypesMap.set(graphName, subgraphTypes);
}
subgraphTypes.push(enumTypedDefNodeForSubgraph);
}
});
}
});
if (isOrphan) {
orphanTypeMap.set(node.name.value, node);
}
},
ObjectTypeDefinition: TypeWithFieldsVisitor,
});
const subschemaMap = new Map();
for (const [subgraphName, endpoint] of subgraphEndpointMap) {
const mergeConfig = {};
const typeNameKeyMap = typeNameKeysBySubgraphMap.get(subgraphName);
const unionTypeNodes = [];
if (typeNameKeyMap) {
const typeNameFieldsKeyMap = typeNameFieldsKeyBySubgraphMap.get(subgraphName);
for (const [typeName, keys] of typeNameKeyMap) {
const mergedTypeConfig = (mergeConfig[typeName] = {});
const fieldsKeyMap = typeNameFieldsKeyMap?.get(typeName);
const extraKeys = [];
if (fieldsKeyMap) {
const fieldsConfig = (mergedTypeConfig.fields = {});
for (const [fieldName, fieldNameKey] of fieldsKeyMap) {
extraKeys.push(fieldNameKey);
fieldsConfig[fieldName] = {
selectionSet: `{ ${fieldNameKey} }`,
computed: true,
};
}
}
if (typeNameCanonicalMap.get(typeName) === subgraphName) {
mergedTypeConfig.canonical = true;
}
mergedTypeConfig.entryPoints = keys.map(key => ({
selectionSet: `{ ${key} }`,
argsFromKeys: utils_js_1.getArgsFromKeysForFederation,
key: (0, utils_js_1.getKeyFnForFederation)(typeName, [key, ...extraKeys]),
fieldName: `_entities`,
dataLoaderOptions: {
cacheKeyFn: (0, utils_js_1.getCacheKeyFnFromKey)(key),
},
}));
unionTypeNodes.push({
kind: graphql_1.Kind.NAMED_TYPE,
name: {
kind: graphql_1.Kind.NAME,
value: typeName,
},
});
}
}
const entitiesUnionTypeDefinitionNode = {
name: {
kind: graphql_1.Kind.NAME,
value: '_Entity',
},
kind: graphql_1.Kind.UNION_TYPE_DEFINITION,
types: unionTypeNodes,
};
const extraOrphanTypesForSubgraph = new Map();
function visitTypeDefinitionsForOrphanTypes(node) {
function visitNamedTypeNode(namedTypeNode) {
const typeName = namedTypeNode.name.value;
if (specifiedTypeNames.includes(typeName)) {
return node;
}
const orphanType = orphanTypeMap.get(typeName);
if (orphanType) {
if (!extraOrphanTypesForSubgraph.has(typeName)) {
extraOrphanTypesForSubgraph.set(typeName, {});
const extraOrphanType = visitTypeDefinitionsForOrphanTypes(orphanType);
extraOrphanTypesForSubgraph.set(typeName, extraOrphanType);
}
}
else if (!subgraphTypes.some(typeNode => typeNode.name.value === typeName)) {
return null;
}
return node;
}
function visitFieldDefs(nodeFields) {
const fields = [];
for (const field of nodeFields || []) {
const isTypeNodeOk = visitNamedTypeNode((0, utils_js_1.getNamedTypeNode)(field.type));
if (!isTypeNodeOk) {
continue;
}
if (field.kind === graphql_1.Kind.FIELD_DEFINITION) {
const args = visitFieldDefs(field.arguments);
fields.push({
...field,
arguments: args,
});
}
else {
fields.push(field);
}
}
return fields;
}
function visitObjectAndInterfaceDefs(node) {
const fields = visitFieldDefs(node.fields);
const interfaces = [];
for (const iface of node.interfaces || []) {
const isTypeNodeOk = visitNamedTypeNode(iface);
if (!isTypeNodeOk) {
continue;
}
interfaces.push(iface);
}
return {
...node,
fields,
interfaces,
};
}
return (0, graphql_1.visit)(node, {
[graphql_1.Kind.OBJECT_TYPE_DEFINITION]: visitObjectAndInterfaceDefs,
[graphql_1.Kind.OBJECT_TYPE_EXTENSION]: visitObjectAndInterfaceDefs,
[graphql_1.Kind.INTERFACE_TYPE_DEFINITION]: visitObjectAndInterfaceDefs,
[graphql_1.Kind.INTERFACE_TYPE_EXTENSION]: visitObjectAndInterfaceDefs,
[graphql_1.Kind.UNION_TYPE_DEFINITION](node) {
const types = [];
for (const type of node.types || []) {
const isTypeNodeOk = visitNamedTypeNode(type);
if (!isTypeNodeOk) {
continue;
}
types.push(type);
}
return {
...node,
types,
};
},
[graphql_1.Kind.UNION_TYPE_EXTENSION](node) {
const types = [];
for (const type of node.types || []) {
const isTypeNodeOk = visitNamedTypeNode(type);
if (!isTypeNodeOk) {
continue;
}
types.push(type);
}
return {
...node,
types,
};
},
[graphql_1.Kind.INPUT_OBJECT_TYPE_DEFINITION](node) {
const fields = visitFieldDefs(node.fields);
return {
...node,
fields,
};
},
[graphql_1.Kind.INPUT_OBJECT_TYPE_EXTENSION](node) {
const fields = visitFieldDefs(node.fields);
return {
...node,
fields,
};
},
});
}
const subgraphTypes = subgraphTypesMap.get(subgraphName) || [];
const typeNameExtraFieldsMap = subgraphTypeNameExtraFieldsMap.get(subgraphName);
subgraphTypes.forEach(typeNode => {
if (typeNameExtraFieldsMap && 'fields' in typeNode) {
const extraFields = typeNameExtraFieldsMap.get(typeNode.name.value);
if (extraFields) {
typeNode.fields.push(...extraFields);
}
}
visitTypeDefinitionsForOrphanTypes(typeNode);
});
let schema;
const schemaAst = {
kind: graphql_1.Kind.DOCUMENT,
definitions: [
...subgraphTypes,
...extraOrphanTypesForSubgraph.values(),
entitiesUnionTypeDefinitionNode,
anyTypeDefinitionNode,
],
};
try {
schema = (0, graphql_1.buildASTSchema)(schemaAst, {
assumeValidSDL: true,
assumeValid: true,
});
}
catch (e) {
throw new Error(`Error building schema for subgraph ${subgraphName}: ${e?.message || e.toString()}`);
}
let executor = onExecutor({ subgraphName, endpoint, subgraphSchema: schema });
if (globalThis.process?.env?.['DEBUG']) {
const origExecutor = executor;
executor = async function debugExecutor(execReq) {
console.log(`Executing ${subgraphName} with args:`, {
document: (0, graphql_1.print)(execReq.document),
variables: JSON.stringify(execReq.variables, null, 2),
});
const res = await origExecutor(execReq);
console.log(`Response from ${subgraphName}:`, JSON.stringify(res, null, 2));
return res;
};
}
subschemaMap.set(subgraphName, {
name: subgraphName,
schema,
executor,
merge: mergeConfig,
batch,
});
}
return subschemaMap;
}
exports.getSubschemasFromSupergraphSdl = getSubschemasFromSupergraphSdl;
function getStitchedSchemaFromSupergraphSdl(opts) {
const subschemaMap = getSubschemasFromSupergraphSdl(opts);
const supergraphSchema = (0, stitch_1.stitchSchemas)({
subschemas: [...subschemaMap.values()],
assumeValid: true,
assumeValidSDL: true,
typeMergingOptions: {
useNonNullableFieldOnConflict: true,
validationSettings: {
validationLevel: stitch_1.ValidationLevel.Off,
},
fieldConfigMerger: getFieldMergerFromSupergraphSdl(opts.supergraphSdl),
},
});
return (0, utils_js_1.filterInternalFieldsAndTypes)(supergraphSchema);
}
exports.getStitchedSchemaFromSupergraphSdl = getStitchedSchemaFromSupergraphSdl;
const anyTypeDefinitionNode = {
name: {
kind: graphql_1.Kind.NAME,
value: '_Any',
},
kind: graphql_1.Kind.SCALAR_TYPE_DEFINITION,
};
const entitiesFieldDefinitionNode = {
kind: graphql_1.Kind.FIELD_DEFINITION,
name: {
kind: graphql_1.Kind.NAME,
value: '_entities',
},
type: {
kind: graphql_1.Kind.NAMED_TYPE,
name: {
kind: graphql_1.Kind.NAME,
value: '_Entity',
},
},
arguments: [
{
kind: graphql_1.Kind.INPUT_VALUE_DEFINITION,
name: {
kind: graphql_1.Kind.NAME,
value: 'representations',
},
type: {
kind: graphql_1.Kind.NON_NULL_TYPE,
type: {
kind: graphql_1.Kind.LIST_TYPE,
type: {
kind: graphql_1.Kind.NON_NULL_TYPE,
type: {
kind: graphql_1.Kind.NAMED_TYPE,
name: {
kind: graphql_1.Kind.NAME,
value: '_Any',
},
},
},
},
},
},
],
};
const specifiedTypeNames = ['ID', 'String', 'Float', 'Int', 'Boolean', '_Any', '_Entity'];