diff --git a/.gitignore b/.gitignore index 720a2b6..a895aff 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ .vagrant node_modules *.log -.ts-node \ No newline at end of file +.ts-node +.idea diff --git a/README.md b/README.md index d69238d..e708374 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ tsnd --respawn server.ts - `--clear` (`--cls`) Will clear screen on restart - `--watch` - Explicitly add files or folders to watch and restart on change (list separated by commas) - `--exit-child` - Adds 'SIGTERM' exit handler in a child process. +- `--notifyLevel` - `error` or `info` (default). The level for which OS level notifications should be sent **Caveats and points of notice:** diff --git a/bin/ts-node-dev b/bin/ts-node-dev index 7575ede..bc4f101 100644 --- a/bin/ts-node-dev +++ b/bin/ts-node-dev @@ -53,6 +53,7 @@ var opts = minimist(devArgs, { 'ignore-watch', 'interval', 'debounce', + 'notifyLevel', 'watch' ], alias: { diff --git a/lib/cfg.js b/lib/cfg.js index c6a5e9e..efac5f2 100644 --- a/lib/cfg.js +++ b/lib/cfg.js @@ -28,6 +28,7 @@ module.exports = function (main, opts) { if (opts.respawn) c.respawn = true; if (opts.notify === false) c.notify = false; if (opts.clear || opts.cls) c.clear = true; + if (opts.notifyLevel) c.notifyLevel = opts.notifyLevel } var ignoreWatch = ([]).concat(opts && opts['ignore-watch'] || []).concat(c.ignore || []); @@ -37,6 +38,7 @@ module.exports = function (main, opts) { vm: c.vm !== false, fork: c.fork !== false, notify: c.notify !== false, + notifyLevel: c.notifyLevel || 'DEBUG', deps: c.deps, timestamp: c.timestamp || (c.timestamp !== false && 'HH:MM:ss'), clear: !!(c.clear), diff --git a/lib/child-require-hook.js b/lib/child-require-hook.js index 36515e4..3b97c1e 100644 --- a/lib/child-require-hook.js +++ b/lib/child-require-hook.js @@ -2,6 +2,7 @@ var fs = require('fs') var getCompiledPath = require('./get-compiled-path') var sep = require('path').sep var join = require('path').join +var notify = require(join(__dirname, './notify')) var execSync = require('child_process').execSync var compilationId var timeThreshold = 0 @@ -13,6 +14,7 @@ var readyFile var execCheck = false var exitChild = false var sourceMapSupportPath +var cfg = {} var checkFileScript = join(__dirname, 'check-file-exists.js') @@ -113,6 +115,12 @@ if (readyFile) { } } +process.on('uncaughtException', err => { + notify(cfg, null, err)('Error', err.message || err.stack, 'error') + process.exitCode = 1 + process.kill(process.pid, 'SIGTERM') +}) + if (exitChild) { process.on('SIGTERM', function() { console.log('Child got SIGTERM, exiting.') diff --git a/lib/compiler.js b/lib/compiler.js index 08a2bc3..99721e8 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -24,6 +24,10 @@ var compilationInstanceStamp = Math.random() var compiler = { allowJs: false, tsConfigPath: '', + cfg: {}, + setConfig(cfg) { + this.cfg = cfg + }, getCompilationId: function() { return compilationInstanceStamp }, @@ -117,6 +121,10 @@ var compiler = { /__dirname/, '"' + __dirname.replace(/\\/g, '/') + '"' ) + fileData = fileData.replace( + 'var cfg = {}', + 'var cfg = ' + JSON.stringify(this.cfg) + ) fs.writeFileSync(compiler.getChildHookPath(), fileData) }, init: function(options) { diff --git a/lib/index.js b/lib/index.js index 3f44013..ba95a80 100755 --- a/lib/index.js +++ b/lib/index.js @@ -31,6 +31,7 @@ module.exports = function(script, scriptArgs, nodeArgs, opts) { var log = require('./log')(cfg) var notify = require('./notify')(cfg, log) opts.log = log + compiler.setConfig(cfg) compiler.init(opts) compiler.notify = notify diff --git a/lib/notify.js b/lib/notify.js index 204ba71..ccc2ab7 100644 --- a/lib/notify.js +++ b/lib/notify.js @@ -5,14 +5,25 @@ function icon(level) { return path.resolve(__dirname, '../icons/node_' + level + '.png'); } +function levelToInt(strLevel) { + if (!strLevel) return 0; + switch (strLevel.toLowerCase()) { + case 'info': return 1; + case 'error': return 3; + default: return 0; + } +} + /** * Displays a desktop notification and writes a message to the console. */ module.exports = function (cfg, log) { return function (title, msg, level) { level = level || 'info'; - log([title, msg].filter(_ => _).join(': '), level); - if (cfg.notify) { + if (log) { + log([title, msg].filter(_ => _).join(': '), level); + } + if (cfg.notify && levelToInt(cfg.notifyLevel) <= levelToInt(level)) { notifier.notify({ title: title || 'node.js', icon: icon(level),