@nestjs/graphql
Version:
Nest - modern, fast, powerful node.js web framework (@graphql)
175 lines (174 loc) • 8.32 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.GraphQLFederationFactory = void 0;
const tslib_1 = require("tslib");
const common_1 = require("@nestjs/common");
const load_package_util_1 = require("@nestjs/common/utils/load-package.util");
const shared_utils_1 = require("@nestjs/common/utils/shared.utils");
const apollo_server_core_1 = require("apollo-server-core");
const graphql_1 = require("graphql");
const merge_1 = require("@graphql-tools/merge");
const lodash_1 = require("lodash");
const graphql_schema_builder_1 = require("../graphql-schema.builder");
const services_1 = require("../services");
const utils_1 = require("../utils");
const transform_schema_util_1 = require("../utils/transform-schema.util");
const graphql_schema_host_1 = require("../graphql-schema.host");
let GraphQLFederationFactory = class GraphQLFederationFactory {
constructor(resolversExplorerService, scalarsExplorerService, pluginsExplorerService, gqlSchemaBuilder, gqlSchemaHost) {
this.resolversExplorerService = resolversExplorerService;
this.scalarsExplorerService = scalarsExplorerService;
this.pluginsExplorerService = pluginsExplorerService;
this.gqlSchemaBuilder = gqlSchemaBuilder;
this.gqlSchemaHost = gqlSchemaHost;
}
async mergeOptions(options = {}) {
const transformSchema = async (schema) => options.transformSchema ? options.transformSchema(schema) : schema;
options.plugins = (0, utils_1.extend)(options.plugins || [], this.pluginsExplorerService.explore());
let schema;
if (options.autoSchemaFile) {
schema = await this.generateSchema(options);
}
else if ((0, lodash_1.isEmpty)(options.typeDefs)) {
schema = options.schema;
}
else {
schema = this.buildSchemaFromTypeDefs(options);
}
this.gqlSchemaHost.schema = schema;
return {
...options,
schema: await transformSchema(schema),
typeDefs: undefined,
};
}
buildSchemaFromTypeDefs(options) {
const { buildFederatedSchema } = (0, load_package_util_1.loadPackage)('@apollo/federation', 'ApolloFederation', () => require('@apollo/federation'));
return buildFederatedSchema([
{
typeDefs: (0, apollo_server_core_1.gql) `
${options.typeDefs}
`,
resolvers: this.getResolvers(options.resolvers),
},
]);
}
async generateSchema(options) {
const { buildFederatedSchema, printSchema, } = (0, load_package_util_1.loadPackage)('@apollo/federation', 'ApolloFederation', () => require('@apollo/federation'));
const autoGeneratedSchema = await this.gqlSchemaBuilder.buildFederatedSchema(options.autoSchemaFile, options, this.resolversExplorerService.getAllCtors());
let executableSchema = buildFederatedSchema({
typeDefs: (0, apollo_server_core_1.gql)(printSchema(autoGeneratedSchema)),
resolvers: this.getResolvers(options.resolvers),
});
executableSchema = this.overrideOrExtendResolvers(executableSchema, autoGeneratedSchema);
const schema = options.schema
? (0, merge_1.mergeSchemas)({
schemas: [options.schema, executableSchema],
})
: executableSchema;
return schema;
}
getResolvers(optionResolvers) {
optionResolvers = Array.isArray(optionResolvers)
? optionResolvers
: [optionResolvers];
return this.extendResolvers([
this.resolversExplorerService.explore(),
...this.scalarsExplorerService.explore(),
...optionResolvers,
]);
}
extendResolvers(resolvers) {
return resolvers.reduce((prev, curr) => (0, utils_1.extend)(prev, curr), {});
}
overrideOrExtendResolvers(executableSchema, autoGeneratedSchema) {
return (0, transform_schema_util_1.transformSchema)(executableSchema, (type) => {
if ((0, graphql_1.isUnionType)(type) && type.name !== '_Entity') {
return this.overrideFederatedResolveType(type, autoGeneratedSchema);
}
else if ((0, graphql_1.isInterfaceType)(type)) {
return this.overrideFederatedResolveType(type, autoGeneratedSchema);
}
else if ((0, graphql_1.isEnumType)(type)) {
return autoGeneratedSchema.getType(type.name);
}
else if ((0, graphql_1.isInputObjectType)(type)) {
const autoGeneratedInputType = autoGeneratedSchema.getType(type.name);
if (!autoGeneratedInputType) {
return type;
}
const fields = type.getFields();
(0, lodash_1.forEach)(fields, (value, key) => {
const field = autoGeneratedInputType.getFields()[key];
if (!field) {
return;
}
value.extensions = field.extensions;
value.astNode = field.astNode;
});
type.extensions = autoGeneratedInputType.extensions;
return type;
}
else if ((0, graphql_1.isObjectType)(type)) {
const autoGeneratedObjectType = autoGeneratedSchema.getType(type.name);
if (!autoGeneratedObjectType) {
return type;
}
const fields = type.getFields();
(0, lodash_1.forEach)(fields, (value, key) => {
const field = autoGeneratedObjectType.getFields()[key];
if (!field) {
return;
}
value.extensions = field.extensions;
value.astNode = field.astNode;
if (!value.resolve) {
value.resolve = field.resolve;
}
});
type.extensions = autoGeneratedObjectType.extensions;
return type;
}
else if ((0, graphql_1.isScalarType)(type) && type.name === 'DateTime') {
const autoGeneratedScalar = autoGeneratedSchema.getType(type.name);
if (!autoGeneratedScalar) {
return type;
}
type.parseLiteral = autoGeneratedScalar.parseLiteral;
type.parseValue = autoGeneratedScalar.parseValue;
return type;
}
return type;
});
}
overrideFederatedResolveType(typeInFederatedSchema, autoGeneratedSchema) {
const autoGeneratedType = autoGeneratedSchema.getType(typeInFederatedSchema.name);
if (!autoGeneratedType ||
!(autoGeneratedType instanceof graphql_1.GraphQLUnionType || autoGeneratedType instanceof graphql_1.GraphQLInterfaceType) ||
!autoGeneratedType.resolveType) {
return typeInFederatedSchema;
}
typeInFederatedSchema.resolveType = async (value, context, info, abstractType) => {
const resultFromAutogenSchema = await autoGeneratedType.resolveType(value, context, info, abstractType);
if (!resultFromAutogenSchema || (0, shared_utils_1.isString)(resultFromAutogenSchema)) {
return resultFromAutogenSchema;
}
const resultFromFederatedSchema = info.schema.getType(resultFromAutogenSchema.name);
if (resultFromFederatedSchema &&
resultFromFederatedSchema instanceof graphql_1.GraphQLObjectType) {
return resultFromFederatedSchema;
}
return resultFromAutogenSchema.name;
};
return typeInFederatedSchema;
}
};
GraphQLFederationFactory = (0, tslib_1.__decorate)([
(0, common_1.Injectable)(),
(0, tslib_1.__metadata)("design:paramtypes", [services_1.ResolversExplorerService,
services_1.ScalarsExplorerService,
services_1.PluginsExplorerService,
graphql_schema_builder_1.GraphQLSchemaBuilder,
graphql_schema_host_1.GraphQLSchemaHost])
], GraphQLFederationFactory);
exports.GraphQLFederationFactory = GraphQLFederationFactory;