@coko/server
Version:
Reusable server for use by Coko's projects
102 lines • 4.3 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const ws_1 = require("graphql-ws/lib/use/ws");
const ws_2 = require("ws");
const express5_1 = require("@as-integrations/express5");
const server_1 = require("@apollo/server");
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
const graphqlUploadExpress_mjs_1 = __importDefault(require("graphql-upload/graphqlUploadExpress.mjs"));
const drainHttpServer_1 = require("@apollo/server/plugin/drainHttpServer");
const default_1 = require("@apollo/server/plugin/landingPage/default");
const sentryPlugin_1 = __importDefault(require("./sentryPlugin"));
const AuthenticationError_1 = __importDefault(require("../errors/AuthenticationError"));
const config_1 = __importDefault(require("../configManager/config"));
const logger_1 = __importDefault(require("../logger"));
const loaders_1 = __importDefault(require("./loaders"));
const generateSchema_1 = __importDefault(require("./generateSchema"));
const setup = async (httpServer, app, passport) => {
const sentryDsn = config_1.default.get('sentry.dsn');
// it is important that this runs before generateSchema (applyMiddleware specifically),
// otherwise uploads will not work, showing a POST body empty error
app.use((0, graphqlUploadExpress_mjs_1.default)());
const schema = await (0, generateSchema_1.default)();
/* SUBSCRIPTION SERVER */
const wsServer = new ws_2.WebSocketServer({
server: httpServer,
path: '/subscriptions',
});
const getDynamicContext = (ctx) => {
const context = { userId: null };
if (ctx.connectionParams.authToken) {
try {
const decodedToken = jsonwebtoken_1.default.verify(ctx.connectionParams.authToken, config_1.default.get('secret'));
context.userId = decodedToken.id;
}
catch (_e) {
throw new AuthenticationError_1.default('Subscription authentication token invalid');
}
}
return context;
};
// store it in a variable so it can be cleaned up on shutdown
const subscriptionServerCleanup = (0, ws_1.useServer)({
schema,
context: (ctx, _msg, _args) => {
return getDynamicContext(ctx);
},
}, wsServer);
/* APOLLO SERVER */
const apolloServer = new server_1.ApolloServer({
schema,
plugins: [
sentryDsn && (0, sentryPlugin_1.default)(),
// Proper shutdown for the HTTP server
/* eslint-disable-next-line new-cap */
(0, drainHttpServer_1.ApolloServerPluginDrainHttpServer)({ httpServer }),
// Proper shutdown for the WebSocket server
{
async serverWillStart() {
return {
async drainServer() {
await subscriptionServerCleanup.dispose();
},
};
},
},
// Embed apollo explorer
process.env.NODE_ENV === 'development' &&
/* eslint-disable-next-line new-cap */
(0, default_1.ApolloServerPluginLandingPageLocalDefault)({
embed: {
endpointIsEditable: true,
},
}),
].filter(Boolean),
introspection: process.env.NODE_ENV === 'development',
csrfPrevention: true,
formatError: (error) => {
logger_1.default.error(error);
return error;
},
});
await apolloServer.start();
/* APOLLO EXPRESS */
const createdLoaders = await (0, loaders_1.default)();
app.use('/graphql', passport.authenticate(['bearer', 'anonymous'], {
session: false,
}), (0, express5_1.expressMiddleware)(apolloServer, {
context: async ({ req, res }) => {
return {
userId: req.user, // req.user is set by passport
loaders: createdLoaders,
req,
res,
};
},
}));
};
exports.default = setup;
//# sourceMappingURL=setup.js.map