Comparing version 1.0.10 to 1.0.11
150
index.js
@@ -1,149 +0,1 @@ | ||
#!/usr/bin/env node | ||
'use strict'; | ||
const chalk = require('chalk'); | ||
const spawn = require('cross-spawn'); | ||
const killer = require('./killer'); | ||
const compilationStartedRegex = /Starting incremental compilation/; | ||
const compilationCompleteRegex = / Compilation complete\. Watching for file changes\./; | ||
const typescriptSuccessRegex = /Compilation complete/; | ||
const typescriptWatchCommandRegex = /Watch input files\./; | ||
const typescriptErrorRegex = /\(\d+,\d+\): error TS\d+:/; | ||
const onSuccessCommandSyntax = ' --onSuccess COMMAND Run the COMMAND on each successful compilation'; | ||
const onFirstSuccessCommandSyntax = ' --onFirstSuccess COMMAND Run the COMMAND on the first successful compilation (Will not run the onSuccess)'; | ||
const newAdditionToSyntax = ['Watch input files. [always on]', onSuccessCommandSyntax, onFirstSuccessCommandSyntax].join('\n'); | ||
let hadErrors = false; | ||
let firstTime = true; | ||
let firstSuccessProcess = null; | ||
let firstSuccessProcessExited = null; | ||
let successProcess = null; | ||
let successProcessExited = null; | ||
function color(line) { | ||
if (typescriptErrorRegex.test(line)) { | ||
return chalk.red(line); | ||
} | ||
if (typescriptSuccessRegex.test(line) || typescriptWatchCommandRegex.test(line)) { | ||
return chalk.green(line); | ||
} | ||
return chalk.white(line); | ||
} | ||
function print(lines) { | ||
return lines.forEach(line => console.log(color(line))); | ||
} | ||
function cleanArgs(inputArgs) { | ||
return inputArgs | ||
.splice(2) | ||
.filter(arg => arg.toLowerCase() !== '-w') | ||
.filter(arg => arg.toLowerCase() !== '--watch') | ||
.filter(arg => arg.toLowerCase() !== '--onsuccess') | ||
.filter(arg => arg.toLowerCase() !== '--onfirstsuccess'); | ||
} | ||
function getCommandIdx(inputArgs, command) { | ||
const idx = inputArgs.indexOf(command); | ||
if (idx > -1 && idx + 1 < inputArgs.length) { | ||
return idx; | ||
} else { | ||
return -1; | ||
} | ||
} | ||
function runCommand(fullCommand) { | ||
if (fullCommand) { | ||
const parts = fullCommand.split(' ').filter(a => a.length > 0); | ||
return spawn(parts[0], parts.slice(1), {stdio: 'inherit'}) | ||
} | ||
} | ||
function killAllProcesses() { | ||
const promises = []; | ||
if (firstSuccessProcess) { | ||
promises.push(killer(firstSuccessProcess).then(() => firstSuccessProcess = null)); | ||
promises.push(firstSuccessProcessExited.then(() => firstSuccessProcessExited = null)); | ||
} | ||
if (successProcess) { | ||
promises.push(killer(successProcess).then(() => successProcess = null)); | ||
promises.push(successProcessExited.then(() => successProcessExited = null)); | ||
} | ||
return Promise.all(promises); | ||
} | ||
let allArgs = process.argv; | ||
// onSuccess | ||
let onSuccessCommandIdx = getCommandIdx(allArgs, '--onSuccess'); | ||
let onSuccessCommand = null; | ||
if (onSuccessCommandIdx > -1) { | ||
onSuccessCommand = allArgs[onSuccessCommandIdx + 1]; | ||
allArgs.splice(onSuccessCommandIdx, 2) | ||
} | ||
// onFirstSuccess | ||
let onFirstSuccessCommandIdx = getCommandIdx(allArgs, '--onFirstSuccess'); | ||
let onFirstSuccessCommand = null; | ||
if (onFirstSuccessCommandIdx > -1) { | ||
onFirstSuccessCommand = allArgs[onFirstSuccessCommandIdx + 1]; | ||
allArgs.splice(onFirstSuccessCommandIdx, 2) | ||
} | ||
let args = cleanArgs(allArgs); | ||
args.push('--watch'); // force watch | ||
const bin = require.resolve('typescript/bin/tsc'); | ||
const tscProcess = spawn(bin, [...args]); | ||
tscProcess.stdout.on('data', buffer => { | ||
const lines = buffer.toString() | ||
.split('\n') | ||
.filter(a => a.length > 0) | ||
// .filter(a => a !== '\r') | ||
.map(a => a.replace(typescriptWatchCommandRegex, newAdditionToSyntax)); | ||
print(lines); | ||
const newCompilation = lines.some(line => compilationStartedRegex.test(line)); | ||
if (newCompilation) { | ||
hadErrors = false; | ||
} | ||
const error = lines.some(line => typescriptErrorRegex.test(line)); | ||
if (error) { | ||
hadErrors = true; | ||
} | ||
const compilationComplete = lines.some(line => compilationCompleteRegex.test(line)); | ||
if (compilationComplete) { | ||
if (hadErrors) { | ||
console.log('Had errors, not spawning'); | ||
} else { | ||
killAllProcesses().then(() => { | ||
if (firstTime && onFirstSuccessCommand) { | ||
firstTime = false; | ||
firstSuccessProcess = runCommand(onFirstSuccessCommand); | ||
firstSuccessProcessExited = new Promise(resolve => { | ||
firstSuccessProcess.on('exit', code => { | ||
resolve(code); | ||
}); | ||
}); | ||
} else if (onSuccessCommand) { | ||
successProcess = runCommand(onSuccessCommand); | ||
successProcessExited = new Promise(resolve => { | ||
successProcess.on('exit', code => { | ||
resolve(code); | ||
}); | ||
}); | ||
} | ||
}); | ||
} | ||
} | ||
}); | ||
tscProcess.on('exit', killAllProcesses); | ||
require('./lib/tsc-watch'); |
{ | ||
"name": "tsc-watch", | ||
"version": "1.0.10", | ||
"version": "1.0.11", | ||
"description": "The TypeScript compiler with onSuccess command", | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1" | ||
"test": "mocha test/**/*.js" | ||
}, | ||
@@ -29,3 +29,10 @@ "bin": { | ||
"typescript": "*" | ||
}, | ||
"devDependencies": { | ||
"chai": "^4.1.2", | ||
"fs-extra": "^5.0.0", | ||
"mocha": "^4.0.1", | ||
"mocha-eventually": "^1.1.0", | ||
"sinon": "^4.1.3" | ||
} | ||
} |
@@ -12,2 +12,4 @@ # The TypeScript compiler with `--watch` and a new onSuccess argument | ||
### From Command-Line | ||
```sh | ||
@@ -17,3 +19,40 @@ tsc-watch server.ts --outDir ./dist --onSuccess "node ./dist/server.ts" | ||
### From Code | ||
The client is implemented as an instance of `Node.JS`'s `EventEmitter`, with the following events: | ||
- `first_success` - Emitted upon first successful compilation. | ||
- `subsequent_success` - Emitted upon every subsequent successful compilation. | ||
- `compile_errors` - Emitted upon every failing compilation. | ||
Once subscribed to the relevant events, start the client by running `watch.start()` | ||
To kill the client, run `watch.kill()` | ||
Example usage: | ||
```javascript | ||
const watch = require('tsc-watch/client'); | ||
watch.on('first_success', () => { | ||
console.log('First success!'); | ||
}); | ||
watch.on('subsequent_success', () => { | ||
// Your code goes here... | ||
}); | ||
watch.on('compile_errors', () => { | ||
// Your code goes here... | ||
}); | ||
watch.start(); | ||
try { | ||
// do something... | ||
} catch (e) { | ||
watch.kill(); // Fatal error, kill the compiler instance. | ||
} | ||
``` | ||
Notes: | ||
@@ -20,0 +59,0 @@ * The `COMMAND` will not run if the compilation failed. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 2 instances in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No tests
QualityPackage does not have any tests. This is a strong signal of a poorly maintained or low quality package.
Found 1 instance in 1 package
14616
17
314
0
62
5
2
4