@yeskiy/federation-with-subscriptions
Version:
Apollo Federation with subscriptions support
119 lines (117 loc) • 6.01 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createExpressMicroservice = void 0;
const schema_1 = require("@graphql-tools/schema");
const stitching_directives_1 = require("@graphql-tools/stitching-directives");
const ws_1 = require("graphql-ws/lib/use/ws");
const ws_2 = require("ws");
const extended_apollo_server_1 = require("./extended-apollo-server");
const createExecutableSchema = ({ typeDefs, resolvers, }) => {
const config = (0, stitching_directives_1.stitchingDirectives)();
const stitchingSDL = `
${(0, stitching_directives_1.federationToStitchingSDL)(typeDefs, config)}
extend type Query {
_sdl: String!
}
`;
const hasEntities = Boolean(stitchingSDL.match(/\n\s+_entities\(/));
return (0, schema_1.makeExecutableSchema)({
typeDefs: stitchingSDL,
resolvers: [
resolvers,
// add the SDL are queryable field so the gateway can have access to the full schema
{ Query: { _sdl: () => stitchingSDL } },
// this will be the result of converting federation SDL to stitching SDL
// (see https://www.graphql-tools.com/docs/schema-stitching/stitch-federation)
hasEntities
? {
Query: {
_entities: (root, { representations }) => representations.map((representation) => representation),
},
_Entity: {
__resolveType: ({ __typename }) => __typename,
},
}
: {},
],
});
};
const createExpressMicroservice = (_a) => __awaiter(void 0, void 0, void 0, function* () {
var { typeDefs, resolvers, context, subscriptionContext, host, plugins } = _a, rest = __rest(_a, ["typeDefs", "resolvers", "context", "subscriptionContext", "host", "plugins"]);
const schema = createExecutableSchema({
typeDefs: typeof typeDefs === "function" ? yield typeDefs({}) : typeDefs,
resolvers: typeof resolvers === "function" ? yield resolvers({}) : resolvers,
});
const apolloExpressServer = new extended_apollo_server_1.ExtendedApolloServer(Object.assign({ schema,
plugins,
context, schemaCallback: typeof typeDefs === "function" || typeof resolvers === "function"
? (expressContext) => __awaiter(void 0, void 0, void 0, function* () {
const dynamicContext = (context === null || context === void 0 ? void 0 : context(expressContext.res)) || {};
const dynamicTypeDefs = typeof typeDefs === "function"
? yield typeDefs(dynamicContext)
: typeDefs;
const dynamicResolvers = typeof resolvers === "function"
? yield (resolvers === null || resolvers === void 0 ? void 0 : resolvers(expressContext.res))
: resolvers;
return createExecutableSchema({
typeDefs: dynamicTypeDefs,
resolvers: dynamicResolvers,
});
})
: undefined }, rest));
return {
schema,
start: () => __awaiter(void 0, void 0, void 0, function* () {
yield apolloExpressServer.start();
}),
applyMiddleware: (_a) => {
var { app, path = "/graphql" } = _a, restData = __rest(_a, ["app", "path"]);
apolloExpressServer.applyMiddleware(Object.assign({ app,
path }, restData));
return {
listen: (port) => new Promise((resolve) => {
const server = app.listen(port, host, () => {
const wsServer = new ws_2.WebSocketServer({
host,
server,
path,
});
(0, ws_1.useServer)({
schema,
context: (ctx, message, args) => {
var _a;
return subscriptionContext === null || subscriptionContext === void 0 ? void 0 : subscriptionContext(ctx, message, args, Object.assign({}, (_a = message.payload.variables) === null || _a === void 0 ? void 0 : _a.__headers));
},
}, wsServer);
resolve({
url: `http://${host}:${port}${path}`,
server,
wsServer,
});
});
}),
};
},
};
});
exports.createExpressMicroservice = createExpressMicroservice;