UNPKG

@graphql-tools/federation

Version:

Useful tools to create and manipulate GraphQL schemas.

89 lines (83 loc) 3.44 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.buildSubgraphSchema = exports.SubgraphBaseSDL = void 0; const graphql_1 = require("graphql"); const value_or_promise_1 = require("value-or-promise"); const merge_1 = require("@graphql-tools/merge"); const schema_1 = require("@graphql-tools/schema"); const utils_1 = require("@graphql-tools/utils"); exports.SubgraphBaseSDL = ` scalar _Any scalar _FieldSet scalar link__Import enum link__Purpose { SECURITY EXECUTION } type _Service { sdl: String! } type Query { _entities(representations: [_Any!]!): [_Entity]! _service: _Service! } directive @external on FIELD_DEFINITION | OBJECT directive @requires(fields: _FieldSet!) on FIELD_DEFINITION directive @provides(fields: _FieldSet!) on FIELD_DEFINITION directive @key(fields: _FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE directive @link( url: String! as: String for: link__Purpose import: [link__Import] ) repeatable on SCHEMA directive @shareable repeatable on OBJECT | FIELD_DEFINITION directive @inaccessible on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION directive @tag( name: String! ) repeatable on FIELD_DEFINITION | INTERFACE | OBJECT | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION directive @override(from: String!) on FIELD_DEFINITION directive @composeDirective(name: String!) repeatable on SCHEMA directive @extends on OBJECT | INTERFACE `; function buildSubgraphSchema(opts) { const typeDefs = (0, merge_1.mergeTypeDefs)([exports.SubgraphBaseSDL, opts.typeDefs]); const entityTypeNames = []; (0, graphql_1.visit)(typeDefs, { ObjectTypeDefinition: node => { if (node.directives?.some(directive => directive.name.value === 'key')) { entityTypeNames.push(node.name.value); } }, }); const entityTypeDefinition = `union _Entity = ${entityTypeNames.join(' | ')}`; const givenResolvers = (0, merge_1.mergeResolvers)(opts.resolvers); const subgraphResolvers = { _Entity: { __resolveType: (obj) => obj.__typename, }, Query: { _entities: (_root, args, context, info) => value_or_promise_1.ValueOrPromise.all(args.representations.map(representation => new value_or_promise_1.ValueOrPromise(() => givenResolvers[representation.__typename]?.__resolveReference?.(representation, context, info)).then(resolvedEntity => { if (!resolvedEntity) { return representation; } if (!resolvedEntity.__typename) { resolvedEntity.__typename = representation.__typename; } return resolvedEntity; }))).resolve(), _service: () => ({}), }, _Service: { sdl: (_root, _args, _context, info) => (0, utils_1.printSchemaWithDirectives)(info.schema), }, }; return (0, schema_1.makeExecutableSchema)({ assumeValid: true, assumeValidSDL: true, ...opts, typeDefs: [entityTypeDefinition, typeDefs], resolvers: [subgraphResolvers, givenResolvers], }); } exports.buildSubgraphSchema = buildSubgraphSchema;