UNPKG

@graphql-codegen/cli

Version:

<p align="center"> <img src="https://github.com/dotansimha/graphql-code-generator/blob/master/logo.png?raw=true" /> </p>

141 lines (140 loc) • 6.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createWatcher = void 0; const tslib_1 = require("tslib"); const codegen_js_1 = require("../codegen.js"); const plugin_helpers_1 = require("@graphql-codegen/plugin-helpers"); const is_glob_1 = tslib_1.__importDefault(require("is-glob")); const debounce_1 = tslib_1.__importDefault(require("debounce")); const log_symbols_1 = tslib_1.__importDefault(require("log-symbols")); const debugging_js_1 = require("./debugging.js"); const logger_js_1 = require("./logger.js"); const path_1 = require("path"); const hooks_js_1 = require("../hooks.js"); const config_js_1 = require("../config.js"); const utils_1 = require("@graphql-tools/utils"); function log(msg) { // double spaces to inline the message with Listr (0, logger_js_1.getLogger)().info(` ${msg}`); } function emitWatching() { log(`${log_symbols_1.default.info} Watching for changes...`); } const createWatcher = (initalContext, onNext) => { (0, debugging_js_1.debugLog)(`[Watcher] Starting watcher...`); let config = initalContext.getConfig(); const files = [initalContext.filepath].filter(a => a); const documents = (0, plugin_helpers_1.normalizeInstanceOrArray)(config.documents); const schemas = (0, plugin_helpers_1.normalizeInstanceOrArray)(config.schema); // Add schemas and documents from "generates" Object.keys(config.generates) .map(filename => (0, plugin_helpers_1.normalizeOutputParam)(config.generates[filename])) .forEach(conf => { schemas.push(...(0, plugin_helpers_1.normalizeInstanceOrArray)(conf.schema)); documents.push(...(0, plugin_helpers_1.normalizeInstanceOrArray)(conf.documents)); }); if (documents) { documents.forEach(doc => { if (typeof doc === 'string') { files.push(doc); } else { files.push(...Object.keys(doc)); } }); } schemas.forEach((schema) => { if ((0, is_glob_1.default)(schema) || (0, utils_1.isValidPath)(schema)) { files.push(schema); } }); if (typeof config.watch !== 'boolean') { files.push(...(0, plugin_helpers_1.normalizeInstanceOrArray)(config.watch)); } let watcher; const runWatcher = async () => { var _a, _b; const chokidar = await Promise.resolve().then(() => tslib_1.__importStar(require('chokidar'))); let isShutdown = false; const debouncedExec = (0, debounce_1.default)(() => { if (!isShutdown) { (0, codegen_js_1.executeCodegen)(initalContext) .then(onNext, () => Promise.resolve()) .then(() => emitWatching()); } }, 100); emitWatching(); const ignored = []; Object.keys(config.generates) .map(filename => ({ filename, config: (0, plugin_helpers_1.normalizeOutputParam)(config.generates[filename]) })) .forEach(entry => { if (entry.config.preset) { const extension = entry.config.presetConfig && entry.config.presetConfig.extension; if (extension) { ignored.push((0, path_1.join)(entry.filename, '**', '*' + extension)); } } else { ignored.push(entry.filename); } }); watcher = chokidar.watch(files, { persistent: true, ignoreInitial: true, followSymlinks: true, cwd: process.cwd(), disableGlobbing: false, usePolling: (_a = config.watchConfig) === null || _a === void 0 ? void 0 : _a.usePolling, interval: (_b = config.watchConfig) === null || _b === void 0 ? void 0 : _b.interval, depth: 99, awaitWriteFinish: true, ignorePermissionErrors: false, atomic: true, ignored, }); (0, debugging_js_1.debugLog)(`[Watcher] Started`); const shutdown = () => { isShutdown = true; (0, debugging_js_1.debugLog)(`[Watcher] Shutting down`); log(`Shutting down watch...`); watcher.close(); (0, hooks_js_1.lifecycleHooks)(config.hooks).beforeDone(); }; // it doesn't matter what has changed, need to run whole process anyway watcher.on('all', async (eventName, path) => { (0, hooks_js_1.lifecycleHooks)(config.hooks).onWatchTriggered(eventName, path); (0, debugging_js_1.debugLog)(`[Watcher] triggered due to a file ${eventName} event: ${path}`); const fullPath = (0, path_1.join)(process.cwd(), path); // In ESM require is not defined try { delete require.cache[fullPath]; } catch (err) { } if (eventName === 'change' && config.configFilePath && fullPath === config.configFilePath) { log(`${log_symbols_1.default.info} Config file has changed, reloading...`); const context = await (0, config_js_1.loadContext)(config.configFilePath); const newParsedConfig = context.getConfig(); newParsedConfig.watch = config.watch; newParsedConfig.silent = config.silent; newParsedConfig.overwrite = config.overwrite; newParsedConfig.configFilePath = config.configFilePath; config = newParsedConfig; initalContext.updateConfig(config); } debouncedExec(); }); process.once('SIGINT', shutdown); process.once('SIGTERM', shutdown); }; // the promise never resolves to keep process running return new Promise((resolve, reject) => { (0, codegen_js_1.executeCodegen)(initalContext) .then(onNext, () => Promise.resolve()) .then(runWatcher) .catch(err => { watcher.close(); reject(err); }); }); }; exports.createWatcher = createWatcher;