diff --git a/index.d.ts b/index.d.ts new file mode 100644 index 0000000..e7bbe78 --- /dev/null +++ b/index.d.ts @@ -0,0 +1,113 @@ +declare namespace PluginError { + export interface Constructor { + /** + * @param options Options with plugin name and message + */ + new(options: Options & {plugin: string, message: string}): PluginError; + + /** + * @param plugin Plugin name + * @param message Error message + * @param options Error options + */ + new (plugin: string, message: string, options?: Options): PluginError; + + /** + * @param plugin Plugin name + * @param error Base error + * @param options Error options + */ + new (plugin: string, error: E, options?: Options): PluginError; + + /** + * @param plugin Plugin name + * @param options Options with message + */ + new(plugin: string, options: Options & {message: string}): PluginError; + } + + interface Options { + /** + * Error name + */ + name?: string; + + /** + * Error message + */ + message?: any; + + /** + * File name where the error occurred + */ + fileName?: string; + + + /** + * Line number where the error occurred + */ + lineNumber?: number; + + /** + * Error properties will be included in err.toString(). Can be omitted by + * setting this to false. + * + * Default: `true` + */ + showProperties?: boolean; + + /** + * By default the stack will not be shown. Set this to true if you think the + * stack is important for your error. + * + * Default: `false` + */ + showStack?: boolean; + + /** + * Error stack to use for `err.toString()` if `showStack` is `true`. + * By default it uses the `stack` of the original error if you used one, otherwise it captures a new stack. + */ + stack?: string; + } + + + /** + * The `Base` interface defines the properties available on all the the instances of `PluginError`. + */ + export interface Base extends Error { + /** + * Plugin name + */ + plugin: string; + + /** + * Boolean controlling if the stack will be shown in `err.toString()`. + */ + showStack: boolean; + + /** + * Boolean controlling if properties will be shown in `err.toString()`. + */ + showProperties: boolean; + + /** + * File name where the error occurred + */ + fileName?: string; + + /** + * Line number where the error occurred + */ + lineNumber?: number; + } +} + +/** + * Abstraction for error handling for Vinyl plugins + */ +type PluginError = PluginError.Base & T; + +declare const PluginError: PluginError.Constructor; + +export = PluginError; diff --git a/package.json b/package.json index a0588b1..af12db1 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ }, "license": "MIT", "files": [ + "index.d.ts", "index.js" ], "main": "index.js", @@ -23,7 +24,7 @@ "node": ">=0.10.0" }, "scripts": { - "test": "mocha" + "test": "mocha test.js && tsc -p test/types" }, "dependencies": { "ansi-cyan": "^0.1.1", @@ -33,8 +34,9 @@ "extend-shallow": "^1.1.2" }, "devDependencies": { - "mocha": "*", - "should": "*" + "mocha": "^2.5.3", + "should": "^13.2.0", + "typescript": "^2.6.2" }, "keywords": [ "error", diff --git a/test/types/test.ts b/test/types/test.ts new file mode 100644 index 0000000..1ff1b38 --- /dev/null +++ b/test/types/test.ts @@ -0,0 +1,53 @@ +import PluginError = require("plugin-error"); + +{ + // Check constructor signatures + // See: https://github.com/gulpjs/gulp-util#new-pluginerrorpluginname-message-options + { + const err = new PluginError("test", { + message: "something broke", + }); + } + + { + const err = new PluginError({ + plugin: "test", + message: "something broke", + }); + } + + { + const err = new PluginError("test", "something broke"); + } + + { + const err = new PluginError("test", "something broke", {showStack: true}); + } + + { + const existingError = new Error("OMG"); + const err = new PluginError("test", existingError, {showStack: true}); + } +} + +{ + { + // Check available properties + const realErr = Object.assign(new Error("something broke"), {fileName: "original.js"}); + const err = new PluginError("test", realErr, {showStack: true, fileName: "override.js"}); + const plugin: string = err.plugin; + const message: string = err.message; + const fileName: string = err.fileName; + const showStack: boolean = err.showStack; + const showProperties: boolean = err.showProperties; + } + { + // Inference of custom properties from `error` argument, + const realErr = Object.assign(new Error("something broke"), {abstractProperty: "abstract"}); + const err = new PluginError("test", realErr, realErr); + const plugin: string = err.plugin; + const message: string = err.message; + const abstractProperty: string = err.abstractProperty; + } +} + diff --git a/test/types/tsconfig.json b/test/types/tsconfig.json new file mode 100644 index 0000000..24ac961 --- /dev/null +++ b/test/types/tsconfig.json @@ -0,0 +1,63 @@ +{ + "compilerOptions": { + "allowJs": false, + "allowSyntheticDefaultImports": false, + "allowUnreachableCode": false, + "allowUnusedLabels": false, + "alwaysStrict": true, + "baseUrl": "../..", + "charset": "utf8", + "checkJs": false, + "declaration": true, + "disableSizeLimit": false, + "downlevelIteration": false, + "emitBOM": false, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "forceConsistentCasingInFileNames": true, + "importHelpers": false, + "inlineSourceMap": false, + "inlineSources": false, + "isolatedModules": false, + "lib": [ + "es2017" + ], + "locale": "en-us", + "module": "commonjs", + "moduleResolution": "node", + "newLine": "lf", + "noEmit": true, + "noEmitHelpers": false, + "noEmitOnError": true, + "noErrorTruncation": true, + "noFallthroughCasesInSwitch": true, + "noImplicitAny": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "noStrictGenericChecks": false, + "noUnusedLocals": false, + "noUnusedParameters": false, + "noLib": false, + "noResolve": false, + "paths": { + "plugin-error": [ + "index.d.ts" + ] + }, + "preserveConstEnums": true, + "removeComments": false, + "rootDir": "", + "skipLibCheck": false, + "sourceMap": true, + "strict": true, + "strictNullChecks": true, + "suppressExcessPropertyErrors": false, + "suppressImplicitAnyIndexErrors": false, + "target": "es2017", + "traceResolution": false + }, + "include": [ + "./**/*.ts" + ], + "exclude": [] +}