Skip to content

Commit

Permalink
Add TypeScript type definitions (#801)
Browse files Browse the repository at this point in the history
* Add dtslint and @types/node

Adding dtslint to test (lint) the type definitions and @types/node since they're a depedency of these types

* Assert the types are valid in CI

* Create the tsconfig for validating types

* Port (copy/paste) existing types from DefinitelyTyped

* Add the types key and include in the package
  • Loading branch information
skovy authored and paulmillr committed Feb 18, 2019
1 parent 24f13bb commit 75e6043
Show file tree
Hide file tree
Showing 5 changed files with 250 additions and 2 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Expand Up @@ -10,4 +10,5 @@ script:
- npm run test
after_script:
- npm run coveralls
- npm run dtslint
sudo: false
9 changes: 7 additions & 2 deletions package.json
Expand Up @@ -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": {
Expand All @@ -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",
Expand All @@ -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",
Expand Down
168 changes: 168 additions & 0 deletions types/index.d.ts
@@ -0,0 +1,168 @@
// TypeScript Version: 3.0

/// <reference types="node" />

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;
60 changes: 60 additions & 0 deletions 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);
});
14 changes: 14 additions & 0 deletions 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": ["."] }
}
}

0 comments on commit 75e6043

Please sign in to comment.