diff --git a/index.d.ts b/index.d.ts index 12e1b4d1..c8e4ec24 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,3 +1,5 @@ +import type { WatchOptions } from 'chokidar' + export type NodemonEventHandler = | 'start' | 'crash' @@ -16,77 +18,34 @@ export type NodemonEventListener = { on(event: 'stdout' | 'stderr', listener: (e: string) => void): Nodemon; on(event: 'restart', listener: (e?: NodemonEventRestart) => void): Nodemon; on(event: 'quit', listener: (e?: NodemonEventQuit) => void): Nodemon; - on(event: 'exit', listener: (e?: NodemonEventExit) => void): Nodemon; - on( - event: 'config:update', - listener: (e?: NodemonEventConfig) => void - ): Nodemon; + on(event: 'exit', listener: (e?: number) => void): Nodemon; + on(event: 'config:update', listener: (e?: NodemonEventConfig) => void): Nodemon; }; export type Nodemon = { - (options?: NodemonSettings): Nodemon; - on(event: 'start' | 'crash', listener: () => void): Nodemon; - on(event: 'log', listener: (e: NodemonEventLog) => void): Nodemon; - on(event: 'restart', listener: (e?: NodemonEventRestart) => void): Nodemon; - on(event: 'quit', listener: (e?: NodemonEventQuit) => void): Nodemon; - on(event: 'exit', listener: (e?: NodemonEventExit) => void): Nodemon; - on( - event: 'config:update', - listener: (e?: NodemonEventConfig) => void - ): Nodemon; - - // this is repeated because VS Code doesn't autocomplete otherwise - addEventListener(event: 'start' | 'crash', listener: () => void): Nodemon; - addEventListener( - event: 'log', - listener: (e: NodemonEventLog) => void - ): Nodemon; - addEventListener( - event: 'restart', - listener: (e?: NodemonEventRestart) => void - ): Nodemon; - addEventListener( - event: 'quit', - listener: (e?: NodemonEventQuit) => void - ): Nodemon; - addEventListener( - event: 'exit', - listener: (e?: NodemonEventExit) => void - ): Nodemon; - addEventListener( - event: 'config:update', - listener: (e?: NodemonEventConfig) => void - ): Nodemon; - - once(event: 'start' | 'crash', listener: () => void): Nodemon; - once(event: 'log', listener: (e: NodemonEventLog) => void): Nodemon; - once(event: 'restart', listener: (e?: NodemonEventRestart) => void): Nodemon; - once(event: 'quit', listener: (e?: NodemonEventQuit) => void): Nodemon; - once(event: 'exit', listener: (e?: NodemonEventExit) => void): Nodemon; - once( - event: 'config:update', - listener: (e?: NodemonEventConfig) => void - ): Nodemon; - removeAllListeners(event: NodemonEventHandler): Nodemon; emit(type: NodemonEventHandler, event?: any): Nodemon; reset(callback: Function): Nodemon; restart(): Nodemon; config: NodemonSettings; +} & NodemonEventListener & { + [K in keyof NodemonEventListener as "addListener"]: NodemonEventListener[K]; +} & { + [K in keyof NodemonEventListener as "once"]: NodemonEventListener[K]; }; export type NodemonEventLog = { /** - detail*: what you get with nodemon --verbose. - status: subprocess starting, restarting. - fail: is the subprocess crashing. - error: is a nodemon system error. + - detail: what you get with nodemon --verbose. + - status: subprocess starting, restarting. + - fail: is the subprocess crashing. + - error: is a nodemon system error. */ type: 'detail' | 'log' | 'status' | 'error' | 'fail'; /** the plain text message */ - message: String; + message: string; /** contains the terminal escape codes to add colour, plus the "[nodemon]" prefix */ - colour: String; + colour: string; }; export interface NodemonEventRestart { @@ -97,15 +56,36 @@ export interface NodemonEventRestart { } export type NodemonEventQuit = 143 | 130; -export type NodemonEventExit = number; -// TODO: Define the type of NodemonEventConfig -export type NodemonEventConfig = any; +export type NodemonEventConfig = { + run: boolean; + system: { + cwd: string; + }; + required: boolean; + dirs: string[]; + timeout: number; + options: NodemonConfig; + lastStarted: number + loaded: string[] + load: (settings: NodemonSettings, ready: (config: NodemonEventConfig) => void) => void + reset: () => void +}; + +export interface NodemonExecOptions { + script: string; + scriptPosition?: number; + args?: string[] + ext?: string; // "js,mjs" etc (should really support an array of strings, but I don't think it does right now) + exec?: string; // node, python, etc + execArgs?: string[]; // args passed to node, etc, + nodeArgs?: string[]; // args passed to node, etc, +} export interface NodemonConfig { - /* restartable defaults to "rs" as a string the user enters */ - restartable?: false | String; - colours?: Boolean; + /** restartable defaults to "rs" as a string the user enters */ + restartable?: false | string; + colours?: boolean; execMap?: { [key: string]: string }; ignoreRoot?: string[]; watch?: string[]; @@ -116,25 +96,28 @@ export interface NodemonConfig { signal?: string; stdout?: boolean; watchOptions?: WatchOptions; + help?: string + version?: boolean + cwd?: string + dump?: boolean + ignore?: string[] + watch?: string[] + monitor?: string[] + spawn?: boolean + noUpdateNotifier?: boolean + legacyWatch?: boolean + pollingInterval?: number + /** @deprecated as this is "on" by default */ + js?: boolean + quiet?: boolean + configFile?: string + exitCrash?: boolean + execOptions?: NodemonExecOptions } -export interface NodemonSettings extends NodemonConfig { - script: string; - ext?: string; // "js,mjs" etc (should really support an array of strings, but I don't think it does right now) +export interface NodemonSettings extends NodemonConfig, NodemonExecOptions { events?: { [key: string]: string }; env?: { [key: string]: string }; - exec?: string; // node, python, etc - execArgs?: string[]; // args passed to node, etc, - nodeArgs?: string[]; // args passed to node, etc, - delay?: number; -} - -export interface WatchOptions { - ignorePermissionErrors: boolean; - ignored: string; - persistent: boolean; - usePolling: boolean; - interval: number; } const nodemon: Nodemon = (settings: NodemonSettings): Nodemon => {}; diff --git a/lib/cli/parse.js b/lib/cli/parse.js index ad740038..560cc715 100644 --- a/lib/cli/parse.js +++ b/lib/cli/parse.js @@ -25,7 +25,7 @@ module.exports = parse; * Parses the command line arguments `process.argv` and returns the * nodemon options, the user script and the executable script. * - * @param {Array} full process arguments, including `node` leading arg + * @param {Array | string} argv full process arguments, including `node` leading arg * @return {Object} { options, script, args } */ function parse(argv) { @@ -97,9 +97,9 @@ function parse(argv) { * Given an argument (ie. from process.argv), sets nodemon * options and can eat up the argument value * - * @param {Object} options object that will be updated - * @param {Sting} current argument from argv - * @param {Function} the callback to eat up the next argument in argv + * @param {import('../..').NodemonSettings} options object that will be updated + * @param {String} arg current argument from argv + * @param {Function} eatNext the callback to eat up the next argument in argv * @return {Boolean} false if argument was not a nodemon arg */ function nodemonOption(options, arg, eatNext) { @@ -161,7 +161,7 @@ function nodemonOption(options, arg, eatNext) { } else if (arg === '--exitcrash') { - options.exitcrash = true; + options.exitCrash = true; } else if (arg === '--delay' || arg === '-d') { @@ -210,7 +210,7 @@ function nodemonOption(options, arg, eatNext) { * Given an argument (ie. from nodemonOption()), will parse and return the * equivalent millisecond value or 0 if the argument cannot be parsed * - * @param {String} argument value given to the --delay option + * @param {String} value argument value given to the --delay option * @return {Number} millisecond equivalent of the argument */ function parseDelay(value) { diff --git a/lib/config/load.js b/lib/config/load.js index 75d8443f..7c57d323 100644 --- a/lib/config/load.js +++ b/lib/config/load.js @@ -30,8 +30,10 @@ function findAppScript() { * the local nodemon.json to the exec and then overwriting using any user * specified settings (i.e. from the cli) * - * @param {Object} settings user defined settings - * @param {Function} ready callback that receives complete config + * @param {Object} settings user defined settings + * @param {Object} options global options + * @param {Object} config the config object to be updated + * @param {Function} callback that receives complete config */ function load(settings, options, config, callback) { config.loaded = []; diff --git a/lib/monitor/run.js b/lib/monitor/run.js index 52442033..4314226a 100644 --- a/lib/monitor/run.js +++ b/lib/monitor/run.js @@ -249,7 +249,7 @@ function run(options) { } } else { bus.emit('crash'); - if (options.exitcrash) { + if (options.exitCrash) { utils.log.fail('app crashed'); if (!config.required) { process.exit(1); diff --git a/lib/nodemon.js b/lib/nodemon.js index 278ea658..75619ba4 100644 --- a/lib/nodemon.js +++ b/lib/nodemon.js @@ -7,6 +7,7 @@ var util = require('util'); var utils = require('./utils'); var bus = utils.bus; var help = require('./help'); +/** @type {import('..').NodemonEventConfig} */ var config = require('./config'); var spawn = require('./spawn'); const defaults = require('./config/defaults') @@ -17,12 +18,15 @@ var eventHandlers = {}; config.required = utils.isRequired; /** - * @param {NodemonSettings} settings - * @returns {Nodemon} + * @param {import('..').NodemonSettings | string} settings + * @returns {import('..').Nodemon} */ function nodemon(settings) { bus.emit('boot'); nodemon.reset(); + + /** @type {import('..').NodemonSettings} */ + let options // allow the cli string as the argument to nodemon, and allow for // `node nodemon -V app.js` or just `-V app.js` @@ -34,25 +38,25 @@ function nodemon(settings) { } settings = 'node ' + settings; } - settings = cli.parse(settings); - } + options = cli.parse(settings); + } else options = settings; // set the debug flag as early as possible to get all the detailed logging - if (settings.verbose) { + if (options.verbose) { utils.debug = true; } - if (settings.help) { + if (options.help) { if (process.stdout.isTTY) { process.stdout._handle.setBlocking(true); // nodejs/node#6456 } - console.log(help(settings.help)); + console.log(help(options.help)); if (!config.required) { process.exit(0); } } - if (settings.version) { + if (options.version) { version().then(function (v) { console.log(v); if (!config.required) { @@ -65,17 +69,15 @@ function nodemon(settings) { // nodemon tools like grunt-nodemon. This affects where // the script is being run from, and will affect where // nodemon looks for the nodemon.json files - if (settings.cwd) { + if (options.cwd) { // this is protection to make sure we haven't dont the chdir already... // say like in cli/parse.js (which is where we do this once already!) - if (process.cwd() !== path.resolve(config.system.cwd, settings.cwd)) { - process.chdir(settings.cwd); + if (process.cwd() !== path.resolve(config.system.cwd, options.cwd)) { + process.chdir(options.cwd); } } - const cwd = process.cwd(); - - config.load(settings, function (config) { + config.load(options, function (config) { if (!config.options.dump && !config.options.execOptions.script && config.options.execOptions.exec === 'node') { if (!config.required) { @@ -175,7 +177,7 @@ function nodemon(settings) { // don't notify of default ignores if (defaults.ignoreRoot.indexOf(rule) !== -1) { return false; - return rule.slice(3).slice(0, -3); + // return rule.slice(3).slice(0, -3); } if (rule.startsWith(cwd)) { diff --git a/lib/rules/add.js b/lib/rules/add.js index de85bb7f..11f1fd71 100644 --- a/lib/rules/add.js +++ b/lib/rules/add.js @@ -28,7 +28,7 @@ module.exports = add; * @param {Object} rules containing `watch` and `ignore`. Also updated during * execution * @param {String} which must be either "watch" or "ignore" - * @param {String|RegExp} the actual rule. + * @param {String|RegExp} rule the actual rule. */ function add(rules, which, rule) { if (!{ ignore: 1, watch: 1}[which]) { diff --git a/test/cli/parse.test.js b/test/cli/parse.test.js index b2b63131..2b79971f 100644 --- a/test/cli/parse.test.js +++ b/test/cli/parse.test.js @@ -251,7 +251,7 @@ describe('nodemon argument parser', function () { assert(settings.exec === 'java', 'exec'); assert(settings.quiet, 'quiet'); assert(settings.stdin === false, 'read stdin'); - assert(settings.exitcrash, 'exit if crash'); + assert(settings.exitCrash, 'exit if crash'); assert(settings.watch[0] === 'fixtures', 'watch'); assert(settings.ignore[0] === 'fixtures', 'ignore'); assert(settings.delay === 5000, 'delay 5 seconds');