UNPKG

@apollo/subgraph

Version:
152 lines 7.26 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isFederationType = exports.federationTypes = exports.serviceField = exports.entitiesField = exports.entitiesResolver = exports.LinkImportType = exports.AnyType = exports.ServiceType = exports.EntityType = void 0; const graphql_1 = require("graphql"); const cache_control_types_1 = require("@apollo/cache-control-types"); const util_1 = require("util"); exports.EntityType = new graphql_1.GraphQLUnionType({ name: '_Entity', types: [], }); exports.ServiceType = new graphql_1.GraphQLObjectType({ name: '_Service', fields: { sdl: { type: graphql_1.GraphQLString, description: 'The sdl representing the federated service capabilities. Includes federation directives, removes federation types, and includes rest of full schema after schema directives have been applied', }, }, }); exports.AnyType = new graphql_1.GraphQLScalarType({ name: '_Any', serialize(value) { return value; }, }); exports.LinkImportType = new graphql_1.GraphQLScalarType({ name: 'link__Import', specifiedByURL: null }); function isPromise(value) { return typeof (value === null || value === void 0 ? void 0 : value.then) === 'function'; } async function maybeAddTypeNameToPossibleReturn(maybeObject, typename) { const objectOrNull = await maybeObject; if (objectOrNull !== null && typeof objectOrNull === 'object') { if ('__typename' in objectOrNull && objectOrNull.__typename !== typename) { return { ...objectOrNull, __typename: typename, }; } Object.defineProperty(objectOrNull, '__typename', { value: typename, }); } return objectOrNull; } function ensureValidRuntimeType(runtimeTypeName, schema, returnType, result) { if (runtimeTypeName == null) { throw new graphql_1.GraphQLError(`Abstract type "${returnType.name}" \`__resolveReference\` method must resolve to an Object type at runtime. Either the object returned by "${returnType}.__resolveReference" must include a valid \`__typename\` field, or the "${returnType.name}" type should provide a "resolveType" function or each possible type should provide an "isTypeOf" function.`); } if (typeof runtimeTypeName !== 'string') { throw new graphql_1.GraphQLError(`Abstract type "${returnType.name}" \`__resolveReference\` method must resolve to an Object type at runtime with ` + `value ${(0, util_1.inspect)(result)}, received "${(0, util_1.inspect)(runtimeTypeName)}".`); } const runtimeType = schema.getType(runtimeTypeName); if (runtimeType == null) { throw new graphql_1.GraphQLError(`Abstract type "${returnType.name}" \`__resolveReference\` method resolved to a type "${runtimeTypeName}" that does not exist inside the schema.`); } if (!(0, graphql_1.isObjectType)(runtimeType)) { throw new graphql_1.GraphQLError(`Abstract type "${returnType.name}" \`__resolveReference\` method resolved to a non-object type "${runtimeTypeName}".`); } if (!schema.isSubType(returnType, runtimeType)) { throw new graphql_1.GraphQLError(`Runtime Object type "${runtimeType.name}" \`__resolveReference\` method is not a possible type for "${returnType.name}".`); } return runtimeType; } async function withResolvedType({ type, value, context, info, callback, }) { var _a; const resolvedValue = await value; if (resolvedValue === null) { return resolvedValue; } const resolveTypeFn = (_a = type.resolveType) !== null && _a !== void 0 ? _a : graphql_1.defaultTypeResolver; const runtimeType = resolveTypeFn(resolvedValue, context, info, type); if (isPromise(runtimeType)) { return runtimeType.then((name) => (callback(ensureValidRuntimeType(name, info.schema, type, resolvedValue)))); } return callback(ensureValidRuntimeType(runtimeType, info.schema, type, resolvedValue)); } function definedResolveReference(type) { var _a, _b; const extensions = type.extensions; return (_b = (_a = extensions.apollo) === null || _a === void 0 ? void 0 : _a.subgraph) === null || _b === void 0 ? void 0 : _b.resolveReference; } function entitiesResolver({ representations, context, info }) { return representations.map((reference) => { const { __typename } = reference; const type = info.schema.getType(__typename); if (!type || !((0, graphql_1.isObjectType)(type) || (0, graphql_1.isInterfaceType)(type))) { throw new Error(`The _entities resolver tried to load an entity for type "${__typename}", but no object or interface type of that name was found in the schema`); } const cacheControl = (0, cache_control_types_1.maybeCacheControlFromInfo)(info); if (cacheControl) { const cacheHint = cacheControl.cacheHintFromType(type); if (cacheHint) { cacheControl.cacheHint.restrict(cacheHint); } } const resolveReference = definedResolveReference(type); const result = resolveReference ? resolveReference(reference, context, info) : reference; if ((0, graphql_1.isInterfaceType)(type)) { return withResolvedType({ type, value: result, context, info, callback: (runtimeType) => { let finalResult = maybeAddTypeNameToPossibleReturn(result, runtimeType.name); if (!resolveReference) { const runtimeResolveReference = definedResolveReference(runtimeType); if (runtimeResolveReference) { finalResult = isPromise(finalResult) ? finalResult.then((r) => runtimeResolveReference(r, context, info)) : runtimeResolveReference(finalResult, context, info); finalResult = maybeAddTypeNameToPossibleReturn(finalResult, runtimeType.name); } } return finalResult; }, }); } return maybeAddTypeNameToPossibleReturn(result, __typename); }); } exports.entitiesResolver = entitiesResolver; exports.entitiesField = { type: new graphql_1.GraphQLNonNull(new graphql_1.GraphQLList(exports.EntityType)), args: { representations: { type: new graphql_1.GraphQLNonNull(new graphql_1.GraphQLList(new graphql_1.GraphQLNonNull(exports.AnyType))), }, }, resolve(_source, { representations }, context, info) { return entitiesResolver({ representations, context, info }); }, }; exports.serviceField = { type: new graphql_1.GraphQLNonNull(exports.ServiceType), }; exports.federationTypes = [ exports.ServiceType, exports.AnyType, exports.EntityType, exports.LinkImportType, ]; function isFederationType(type) { return ((0, graphql_1.isNamedType)(type) && exports.federationTypes.some(({ name }) => name === type.name)); } exports.isFederationType = isFederationType; //# sourceMappingURL=types.js.map