@graphql-mesh/cli
Version:
137 lines (136 loc) • 5.69 kB
JavaScript
/* 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;
}
;