UNPKG

@graphql-mesh/cli

Version:
137 lines (136 loc) 5.69 kB
"use strict"; /* eslint-disable import/no-nodejs-modules */ Object.defineProperty(exports, "__esModule", { value: true }); exports.serveMesh = serveMesh; const tslib_1 = require("tslib"); /* eslint-disable dot-notation */ const cluster_1 = tslib_1.__importDefault(require("cluster")); const os_1 = tslib_1.__importDefault(require("os")); const open_1 = tslib_1.__importDefault(require("open")); const cross_helpers_1 = require("@graphql-mesh/cross-helpers"); const http_1 = require("@graphql-mesh/http"); const utils_1 = require("@graphql-tools/utils"); const getMaxConcurency_js_1 = require("./getMaxConcurency.js"); const node_http_js_1 = require("./node-http.js"); function portSelectorFn(sources, logger) { const port = sources.find(source => Boolean(source)) || 4000; if (sources.filter(source => Boolean(source)).length > 1) { const activeSources = []; if (sources[0]) { activeSources.push('CLI'); } if (sources[1]) { activeSources.push('serve configuration'); } if (sources[2]) { activeSources.push('environment variable'); } logger.warn(`Multiple ports specified (${activeSources.join(', ')}), using ${port}`); } return port; } async function serveMesh({ baseDir, argsPort, getBuiltMesh, logger, rawServeConfig = {}, playgroundTitle, registerTerminateHandler, }, cliParams) { const { fork: configFork = cross_helpers_1.process.env.NODE_ENV?.toLowerCase() === 'production', port: configPort, hostname = os_1.default.platform().toLowerCase() === 'win32' || // is WSL? os_1.default.release().toLowerCase().includes('microsoft') ? '127.0.0.1' : '0.0.0.0', sslCredentials, endpoint: graphqlPath = '/graphql', browser = cross_helpers_1.process.env.NODE_ENV?.toLowerCase() !== 'production', } = rawServeConfig; const port = portSelectorFn([argsPort, parseInt(configPort?.toString()), parseInt(cross_helpers_1.process.env.PORT)], logger); let forkNum; const envFork = cross_helpers_1.process.env.FORK; let defaultForkNum = 0; defaultForkNum = (0, getMaxConcurency_js_1.getMaxConcurrency)(); if (envFork != null) { if (envFork === 'false' || envFork === '0') { forkNum = 0; } else if (envFork === 'true') { forkNum = defaultForkNum; } else { forkNum = parseInt(envFork); } } else if (configFork != null) { if (typeof configFork === 'boolean') { forkNum = configFork ? defaultForkNum : 0; } else { forkNum = configFork; } } const protocol = sslCredentials ? 'https' : 'http'; const serverUrl = `${protocol}://${hostname}:${port}`; if (!playgroundTitle) { playgroundTitle = rawServeConfig?.playgroundTitle || cliParams.playgroundTitle; } if (!cluster_1.default.isWorker && forkNum > 1) { let mainProcessKilled = false; registerTerminateHandler(eventName => { mainProcessKilled = true; }); for (let i = 0; i < forkNum; i++) { const worker = cluster_1.default.fork(); registerTerminateHandler(eventName => worker.kill(eventName)); } logger.info(`${cliParams.serveMessage}: ${serverUrl} in ${forkNum} forks`); let diedWorkers = 0; cluster_1.default.on('exit', (worker, code, signal) => { if (!mainProcessKilled) { logger.child(`Worker ${worker.id}`).error(`died with ${signal || code}. Restarting...`); diedWorkers++; if (diedWorkers === forkNum) { logger.error('All workers died. Exiting...'); cross_helpers_1.process.exit(1); } else { setTimeout(() => { const newWorker = cluster_1.default.fork(); registerTerminateHandler(eventName => newWorker.kill(eventName)); }, 1000); } } }); } else { if (cluster_1.default.isWorker) { logger.addPrefix?.(`Worker ${cluster_1.default.worker?.id}`); } logger.info(`Starting GraphQL Mesh...`); logger.info(`${cliParams.serveMessage}: ${serverUrl}`); registerTerminateHandler(eventName => { const eventLogger = logger.child(`${eventName} 💀`); eventLogger.info(`Destroying GraphQL Mesh...`); getBuiltMesh() .then(mesh => mesh.destroy()) .catch(e => eventLogger.error(e)); }); const meshHTTPHandler = (0, http_1.createMeshHTTPHandler)({ baseDir, getBuiltMesh, rawServeConfig, playgroundTitle, }); const { stop } = await (0, node_http_js_1.startNodeHttpServer)({ meshHTTPHandler, getBuiltMesh, sslCredentials, graphqlPath, hostname, port, }); registerTerminateHandler(eventName => { const eventLogger = logger.child(`${eventName} 💀`); eventLogger.debug(`Stopping HTTP Server`); (0, utils_1.mapMaybePromise)(stop(), () => { eventLogger.debug(`HTTP Server has been stopped`); }); }); if (browser) { (0, open_1.default)(serverUrl.replace('0.0.0.0', 'localhost'), typeof browser === 'string' ? { app: browser } : undefined).catch(() => { logger.warn(`Failed to open browser for ${serverUrl}`); }); } } return null; }