diff --git a/.travis.yml b/.travis.yml index e09347d2..7c934c23 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,4 +10,5 @@ script: - npm run test after_script: - npm run coveralls + - npm run dtslint sudo: false diff --git a/package.json b/package.json index 6218ad14..b86c152e 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "file", "fsevents" ], + "types": "./types/index.d.ts", "homepage": "https://github.com/paulmillr/chokidar", "author": "Paul Miller (https://paulmillr.com), Elan Shanker", "repository": { @@ -23,11 +24,13 @@ "license": "MIT", "scripts": { "test": "nyc mocha --exit", - "coveralls": "nyc report --reporter=text-lcov | coveralls" + "coveralls": "nyc report --reporter=text-lcov | coveralls", + "dtslint": "dtslint types" }, "files": [ "index.js", - "lib/" + "lib/", + "types/index.d.ts" ], "dependencies": { "anymatch": "^2.0.0", @@ -46,8 +49,10 @@ "fsevents": "^1.2.7" }, "devDependencies": { + "@types/node": "^11.9.4", "chai": "^3.2.0", "coveralls": "^3.0.1", + "dtslint": "0.4.1", "graceful-fs": "4.1.4", "mocha": "^5.2.0", "nyc": "^11.8.0", diff --git a/types/index.d.ts b/types/index.d.ts new file mode 100644 index 00000000..40bc4f75 --- /dev/null +++ b/types/index.d.ts @@ -0,0 +1,168 @@ +// TypeScript Version: 3.0 + +/// + +import * as fs from "fs"; +import { EventEmitter } from "events"; + +/** + * The object's keys are all the directories (using absolute paths unless the `cwd` option was + * used), and the values are arrays of the names of the items contained in each directory. + */ +export interface WatchedPaths { + [directory: string]: string[]; +} + +export class FSWatcher extends EventEmitter implements fs.FSWatcher { + /** + * Constructs a new FSWatcher instance with optional WatchOptions parameter. + */ + constructor(options?: WatchOptions); + + /** + * Add files, directories, or glob patterns for tracking. Takes an array of strings or just one + * string. + */ + add(paths: string | string[]): void; + + /** + * Stop watching files, directories, or glob patterns. Takes an array of strings or just one + * string. + */ + unwatch(paths: string | string[]): void; + + /** + * Returns an object representing all the paths on the file system being watched by this + * `FSWatcher` instance. The object's keys are all the directories (using absolute paths unless + * the `cwd` option was used), and the values are arrays of the names of the items contained in + * each directory. + */ + getWatched(): WatchedPaths; + + /** + * Removes all listeners from watched files. + */ + close(): void; +} + +export interface WatchOptions { + /** + * Indicates whether the process should continue to run as long as files are being watched. If + * set to `false` when using `fsevents` to watch, no more events will be emitted after `ready`, + * even if the process continues to run. + */ + persistent?: boolean; + + /** + * ([anymatch](https://github.com/es128/anymatch)-compatible definition) Defines files/paths to + * be ignored. The whole relative or absolute path is tested, not just filename. If a function + * with two arguments is provided, it gets called twice per path - once with a single argument + * (the path), second time with two arguments (the path and the + * [`fs.Stats`](http://nodejs.org/api/fs.html#fs_class_fs_stats) object of that path). + */ + ignored?: any; + + /** + * If set to `false` then `add`/`addDir` events are also emitted for matching paths while + * instantiating the watching as chokidar discovers these file paths (before the `ready` event). + */ + ignoreInitial?: boolean; + + /** + * When `false`, only the symlinks themselves will be watched for changes instead of following + * the link references and bubbling events through the link's path. + */ + followSymlinks?: boolean; + + /** + * The base directory from which watch `paths` are to be derived. Paths emitted with events will + * be relative to this. + */ + cwd?: string; + + /** + * If set to true then the strings passed to .watch() and .add() are treated as literal path + * names, even if they look like globs. Default: false. + */ + disableGlobbing?: boolean; + + /** + * Whether to use fs.watchFile (backed by polling), or fs.watch. If polling leads to high CPU + * utilization, consider setting this to `false`. It is typically necessary to **set this to + * `true` to successfully watch files over a network**, and it may be necessary to successfully + * watch files in other non-standard situations. Setting to `true` explicitly on OS X overrides + * the `useFsEvents` default. + */ + usePolling?: boolean; + + /** + * Whether to use the `fsevents` watching interface if available. When set to `true` explicitly + * and `fsevents` is available this supercedes the `usePolling` setting. When set to `false` on + * OS X, `usePolling: true` becomes the default. + */ + useFsEvents?: boolean; + + /** + * If relying upon the [`fs.Stats`](http://nodejs.org/api/fs.html#fs_class_fs_stats) object that + * may get passed with `add`, `addDir`, and `change` events, set this to `true` to ensure it is + * provided even in cases where it wasn't already available from the underlying watch events. + */ + alwaysStat?: boolean; + + /** + * If set, limits how many levels of subdirectories will be traversed. + */ + depth?: number; + + /** + * Interval of file system polling. + */ + interval?: number; + + /** + * Interval of file system polling for binary files. ([see list of binary extensions](https://gi + * thub.com/sindresorhus/binary-extensions/blob/master/binary-extensions.json)) + */ + binaryInterval?: number; + + /** + * Indicates whether to watch files that don't have read permissions if possible. If watching + * fails due to `EPERM` or `EACCES` with this set to `true`, the errors will be suppressed + * silently. + */ + ignorePermissionErrors?: boolean; + + /** + * `true` if `useFsEvents` and `usePolling` are `false`). Automatically filters out artifacts + * that occur when using editors that use "atomic writes" instead of writing directly to the + * source file. If a file is re-added within 100 ms of being deleted, Chokidar emits a `change` + * event rather than `unlink` then `add`. If the default of 100 ms does not work well for you, + * you can override it by setting `atomic` to a custom value, in milliseconds. + */ + atomic?: boolean | number; + + /** + * can be set to an object in order to adjust timing params: + */ + awaitWriteFinish?: AwaitWriteFinishOptions | boolean; +} + +export interface AwaitWriteFinishOptions { + /** + * Amount of time in milliseconds for a file size to remain constant before emitting its event. + */ + stabilityThreshold?: number; + + /** + * File size polling interval. + */ + pollInterval?: number; +} + +/** + * produces an instance of `FSWatcher`. + */ +export function watch( + paths: string | string[], + options?: WatchOptions +): FSWatcher; diff --git a/types/test.ts b/types/test.ts new file mode 100644 index 00000000..f57f8331 --- /dev/null +++ b/types/test.ts @@ -0,0 +1,60 @@ +import * as fs from "fs"; +import chokidar from "chokidar"; + +const watcher = chokidar.watch("file, dir, or glob", { + ignored: /[\/\\]\./, + persistent: true +}); + +const log = console.log.bind(console); + +watcher + .on("add", (path: string) => { + log("File", path, "has been added"); + }) + .on("addDir", (path: string) => { + log("Directory", path, "has been added"); + }) + .on("change", (path: string) => { + log("File", path, "has been changed"); + }) + .on("unlink", (path: string) => { + log("File", path, "has been removed"); + }) + .on("unlinkDir", (path: string) => { + log("Directory", path, "has been removed"); + }) + .on("error", (error: any) => { + log("Error happened", error); + }) + .on("ready", () => { + log("Initial scan complete. Ready for changes."); + }) + .on("raw", (event: string, path: string, details: any) => { + log("Raw event info:", event, path, details); + }); + +// 'add', 'addDir' and 'change' events also receive stat() results as second +// argument when available: http://nodejs.org/api/fs.html#fs_class_fs_stats +watcher.on("change", (path: string, stats: fs.Stats) => { + if (stats) { + console.log("File", path, "changed size to", stats.size); + } +}); + +// Watch new files. +watcher.add("new-file"); +watcher.add(["new-file-2", "new-file-3", "**/other-file*"]); + +// Un-watch some files. +watcher.unwatch("new-file*"); + +// Only needed if watching is `persistent: true`. +watcher.close(); + +// One-liner +chokidar + .watch(".", { ignored: /[\/\\]\./ }) + .on("all", (event: string, path: string) => { + console.log(event, path); + }); diff --git a/types/tsconfig.json b/types/tsconfig.json new file mode 100644 index 00000000..375b0cef --- /dev/null +++ b/types/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": ["es6"], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "noEmit": true, + "esModuleInterop": true, + "baseUrl": ".", + "paths": { "chokidar": ["."] } + } +}