UNPKG

@netlify/content-engine

Version:
136 lines 5.53 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.startServer = startServer; const express_1 = __importDefault(require("express")); const compression_1 = __importDefault(require("compression")); const express_2 = require("graphql-http/lib/use/express"); const content_engine_graphiql_explorer_1 = __importDefault(require("@netlify/content-engine-graphiql-explorer")); const graphql_1 = require("graphql"); const uuid_1 = require("../core-utils/uuid"); const http_1 = __importDefault(require("http")); const https_1 = __importDefault(require("https")); const cors_1 = __importDefault(require("cors")); // import telemetry from "gatsby-telemetry" const redux_1 = require("../redux"); const context_1 = __importDefault(require("../schema/context")); const api_runner_node_1 = __importDefault(require("./api-runner-node")); const polyfill_remote_file_1 = require("../plugin-utils/polyfill-remote-file"); async function startServer(program, app) { /** * Set up the express app. **/ app.use((0, compression_1.default)()); // app.use(telemetry.expressMiddleware(`DEVELOP`)) app.use((0, cors_1.default)()); /** * Pattern matching all endpoints with graphql or graphiql with 1 or more leading underscores */ const graphqlEndpoint = `/_+graphi?ql`; (0, content_engine_graphiql_explorer_1.default)(app, { graphqlEndpoint, getFragments: function getFragments() { const fragments = []; for (const def of redux_1.store.getState().definitions.values()) { if (def.def.kind === graphql_1.Kind.FRAGMENT_DEFINITION) { fragments.push(def.def); } } return fragments; }, }); app.use(graphqlEndpoint, (0, express_2.createHandler)({ schema() { return redux_1.store.getState().schema; }, context() { return (0, context_1.default)({ schema: redux_1.store.getState().schema, schemaComposer: redux_1.store.getState().schemaCustomization.composer, context: { cacheTags: new Set() }, customContext: redux_1.store.getState().schemaCustomization.context, }); }, onOperation(_req, args, result) { if (result.errors) { result.errors = result.errors.map((err) => ({ ...err.toJSON(), extensions: { stack: err.stack ? err.stack.split(`\n`) : [], }, })); } result.extensions = { enableRefresh: process.env.ENABLE_GATSBY_REFRESH_ENDPOINT, refreshToken: process.env.GATSBY_REFRESH_TOKEN, }; // this is for the dev/preview gql API if (process.env.DEBUG_CACHE_TAGS) { result.extensions.cacheTags = Array.from( // TODO: why does TS think contextValue can be a string? args.contextValue?.cacheTags); } return result; }, })); /** * Refresh external data sources. * If no GATSBY_REFRESH_TOKEN env var is available, then no Authorization header is required **/ const REFRESH_ENDPOINT = `/__refresh`; const refresh = async (req, pluginName) => { global.__GATSBY.buildId = uuid_1.uuid.v4(); redux_1.emitter.emit(`WEBHOOK_RECEIVED`, { webhookBody: req.body, pluginName, }); }; app.post(`${REFRESH_ENDPOINT}/:plugin_name?`, express_1.default.json(), (req, res) => { const pluginName = req.params[`plugin_name`]; const refreshToken = process.env.GATSBY_REFRESH_TOKEN; const authorizedRefresh = !refreshToken || req.headers.authorization === refreshToken; if (authorizedRefresh) { refresh(req, pluginName); res.status(200); res.setHeader(`content-type`, `application/json`); } else { res.status(authorizedRefresh ? 404 : 403); res.json({ error: `Authorization failed. Make sure you add authorization header to your refresh requests`, }); } res.end(); }); (0, polyfill_remote_file_1.addImageRoutes)(app, // @ts-ignore todo should this be Store or GatsbyStore? redux_1.store); // Expose access to app for advanced use cases const { developMiddleware } = redux_1.store.getState().config; if (developMiddleware) { developMiddleware(app, program); } await (0, api_runner_node_1.default)(`onCreateDevServer`, { app, deferNodeMutation: true }); app.use(async (req, res) => { // in this catch-all block we don't support POST so we should 404 if (req.method === `POST`) { res.status(404).end(); return; } res.sendStatus(404); }); return new Promise((res) => { /** * Set up the HTTP server and socket.io. **/ const server = program.ssl ? new https_1.default.Server(program.ssl, app) : new http_1.default.Server(app); const listener = server.listen(program.port, program.host, () => { res({ listener }); }); }); } //# sourceMappingURL=start-server.js.map