From 01d17fcb390ed1da239f97b91ba53e36ad2ac098 Mon Sep 17 00:00:00 2001 From: rcannon Date: Fri, 10 Nov 2017 23:29:21 -0800 Subject: [PATCH] [hystrixjs] Strengthen type hints This adds type hints for builders, commands and their respective callbacks functions out to seven arity, while leaving the nonspecific versions for backwards compatibility. This allows `commandFactory.getOrCreate()` to create fully type hinted callback signatures, both for the builder and the command. ```js const command = commandFactory. getOrCreate(); ``` I also replaced all references to `Q` with `PromiseLike`, and added the missing `hystrix.promise.implementation` configuration option, which allows changing the underlying promise implementation. This allows things like: ```js const Bluebird = require("bluebird"); HystrixConfig.init({ "hystrix.promise.implementation": Bluebird }); (command.execute() as Bluebird).catch(() => true); ``` ...although I couldn't figure out how to more elegantly express that Bluebird type. Also made the fallback signature match the implementation. --- types/hystrixjs/hystrixjs-tests.ts | 2 +- types/hystrixjs/index.d.ts | 206 ++++++++++++++++++++++++++++- types/hystrixjs/tsconfig.json | 8 +- 3 files changed, 202 insertions(+), 14 deletions(-) diff --git a/types/hystrixjs/hystrixjs-tests.ts b/types/hystrixjs/hystrixjs-tests.ts index 676015be06..7ed7819fb7 100644 --- a/types/hystrixjs/hystrixjs-tests.ts +++ b/types/hystrixjs/hystrixjs-tests.ts @@ -4,7 +4,7 @@ import q = require('q'); var commandFactory = hystrixjs.commandFactory; var command = commandFactory - .getOrCreate('testCommand', 'testGroup') + .getOrCreate('testCommand', 'testGroup') .circuitBreakerSleepWindowInMilliseconds(5000) .errorHandler((error) => { return false; diff --git a/types/hystrixjs/index.d.ts b/types/hystrixjs/index.d.ts index 865f2b3916..b49cd40ba4 100644 --- a/types/hystrixjs/index.d.ts +++ b/types/hystrixjs/index.d.ts @@ -4,7 +4,6 @@ // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.3 -import * as Q from "q"; import * as RX from "rx"; export as namespace hystrixjs; @@ -23,7 +22,8 @@ export interface HystrixProperties { "hystrix.metrics.statistical.window.bucketsNumber"?: number, "hystrix.metrics.percentile.window.timeInMilliseconds"?: number, "hystrix.metrics.percentile.window.bucketsNumber"?: number, - "hystrix.request.volume.rejectionThreshold"?: number + "hystrix.request.volume.rejectionThreshold"?: number, + "hystrix.promise.implementation"?: PromiseConstructorLike, } export interface HystrixConfig { @@ -46,7 +46,39 @@ export interface HystrixConfig { } export interface Command { - execute(...args: any[]): Q.Promise; + execute(...args: any[]): PromiseLike +} + +export interface CommandA0 { + execute(): PromiseLike +} + +export interface CommandA1 { + execute(t: T): PromiseLike +} + +export interface CommandA2 { + execute(t: T, u: U): PromiseLike +} + +export interface CommandA3 { + execute(t: T, u: U, v: V): PromiseLike +} + +export interface CommandA4 { + execute(t: T, u: U, v: V, w: W): PromiseLike +} + +export interface CommandA5 { + execute(t: T, u: U, v: V, w: W, x: X): PromiseLike +} + +export interface CommandA6 { + execute(t: T, u: U, v: V, w: W, x: X, y: Y): PromiseLike +} + +export interface CommandA7 { + execute(t: T, u: U, v: V, w: W, x: X, y: Y, z: Z): PromiseLike } export interface CommandBuilder { @@ -62,14 +94,174 @@ export interface CommandBuilder { percentileWindowNumberOfBuckets(value: number): CommandBuilder; percentileWindowLength(value: number): CommandBuilder; circuitBreakerErrorThresholdPercentage(value: number): CommandBuilder; - run(value: (args: any) => Q.Promise): CommandBuilder; - fallbackTo(value: (...args: any[]) => Q.Promise): CommandBuilder; context(value: any): CommandBuilder; - build(): Command; + run(value: (...args: any[]) => PromiseLike): CommandBuilder; + fallbackTo(value: (error: Error, args ?: any[]) => PromiseLike): CommandBuilder; + build() : Command; +} + +export interface CommandBuilderA0 { + circuitBreakerSleepWindowInMilliseconds(value: number): CommandBuilderA0; + errorHandler(value: (error: any) => boolean): CommandBuilderA0; + timeout(value: number): CommandBuilderA0; + circuitBreakerRequestVolumeThreshold(value: number): CommandBuilderA0; + requestVolumeRejectionThreshold(value: number): CommandBuilderA0; + circuitBreakerForceOpened(value: boolean): CommandBuilderA0; + circuitBreakerForceClosed(value: boolean): CommandBuilderA0; + statisticalWindowNumberOfBuckets(value: number): CommandBuilderA0; + statisticalWindowLength(value: number): CommandBuilderA0; + percentileWindowNumberOfBuckets(value: number): CommandBuilderA0; + percentileWindowLength(value: number): CommandBuilderA0; + circuitBreakerErrorThresholdPercentage(value: number): CommandBuilderA0; + context(value: any): CommandBuilderA0; + run(value: () => PromiseLike): CommandBuilderA0; + fallbackTo(value: (error: Error) => PromiseLike): CommandBuilderA0; + build() : CommandA0; +} + +export interface CommandBuilderA1 { + circuitBreakerSleepWindowInMilliseconds(value: number): CommandBuilderA1; + errorHandler(value: (error: any) => boolean): CommandBuilderA1; + timeout(value: number): CommandBuilderA1; + circuitBreakerRequestVolumeThreshold(value: number): CommandBuilderA1; + requestVolumeRejectionThreshold(value: number): CommandBuilderA1; + circuitBreakerForceOpened(value: boolean): CommandBuilderA1; + circuitBreakerForceClosed(value: boolean): CommandBuilderA1; + statisticalWindowNumberOfBuckets(value: number): CommandBuilderA1; + statisticalWindowLength(value: number): CommandBuilderA1; + percentileWindowNumberOfBuckets(value: number): CommandBuilderA1; + percentileWindowLength(value: number): CommandBuilderA1; + circuitBreakerErrorThresholdPercentage(value: number): CommandBuilderA1; + context(value: any): CommandBuilderA1; + run(value: (t: T) => PromiseLike): CommandBuilderA1; + fallbackTo(value: (error: Error, args : [T]) => PromiseLike): CommandBuilderA1; + build(): CommandA1; +} + +export interface CommandBuilderA2 { + circuitBreakerSleepWindowInMilliseconds(value: number): CommandBuilderA2; + errorHandler(value: (error: any) => boolean): CommandBuilderA2; + timeout(value: number): CommandBuilderA2; + circuitBreakerRequestVolumeThreshold(value: number): CommandBuilderA2; + requestVolumeRejectionThreshold(value: number): CommandBuilderA2; + circuitBreakerForceOpened(value: boolean): CommandBuilderA2; + circuitBreakerForceClosed(value: boolean): CommandBuilderA2; + statisticalWindowNumberOfBuckets(value: number): CommandBuilderA2; + statisticalWindowLength(value: number): CommandBuilderA2; + percentileWindowNumberOfBuckets(value: number): CommandBuilderA2; + percentileWindowLength(value: number): CommandBuilderA2; + circuitBreakerErrorThresholdPercentage(value: number): CommandBuilderA2; + context(value: any): CommandBuilderA2; + run(value: (t: T, u: U) => PromiseLike): CommandBuilderA2; + fallbackTo(value: (error: Error, args: [T, U]) => PromiseLike): CommandBuilderA2; + build(): CommandA2; +} + +export interface CommandBuilderA3 { + circuitBreakerSleepWindowInMilliseconds(value: number): CommandBuilderA3; + errorHandler(value: (error: any) => boolean): CommandBuilderA3; + timeout(value: number): CommandBuilderA3; + circuitBreakerRequestVolumeThreshold(value: number): CommandBuilderA3; + requestVolumeRejectionThreshold(value: number): CommandBuilderA3; + circuitBreakerForceOpened(value: boolean): CommandBuilderA3; + circuitBreakerForceClosed(value: boolean): CommandBuilderA3; + statisticalWindowNumberOfBuckets(value: number): CommandBuilderA3; + statisticalWindowLength(value: number): CommandBuilderA3; + percentileWindowNumberOfBuckets(value: number): CommandBuilderA3; + percentileWindowLength(value: number): CommandBuilderA3; + circuitBreakerErrorThresholdPercentage(value: number): CommandBuilderA3; + context(value: any): CommandBuilderA3; + run(value: (t: T, u: U, v: V) => PromiseLike): CommandBuilderA3; + fallbackTo(value: (error: Error, args: [T, U, V]) => PromiseLike): CommandBuilderA3; + build(): CommandA3; +} + +export interface CommandBuilderA4 { + circuitBreakerSleepWindowInMilliseconds(value: number): CommandBuilderA4; + errorHandler(value: (error: any) => boolean): CommandBuilderA4; + timeout(value: number): CommandBuilderA4; + circuitBreakerRequestVolumeThreshold(value: number): CommandBuilderA4; + requestVolumeRejectionThreshold(value: number): CommandBuilderA4; + circuitBreakerForceOpened(value: boolean): CommandBuilderA4; + circuitBreakerForceClosed(value: boolean): CommandBuilderA4; + statisticalWindowNumberOfBuckets(value: number): CommandBuilderA4; + statisticalWindowLength(value: number): CommandBuilderA4; + percentileWindowNumberOfBuckets(value: number): CommandBuilderA4; + percentileWindowLength(value: number): CommandBuilderA4; + circuitBreakerErrorThresholdPercentage(value: number): CommandBuilderA4; + context(value: any): CommandBuilderA4; + run(value: (t: T, u: U, v: V, w: W) => PromiseLike): CommandBuilderA4; + fallbackTo(value: (error: Error, args: [T, U, V, W]) => PromiseLike): CommandBuilderA4; + build(): CommandA4; +} + +export interface CommandBuilderA5 { + circuitBreakerSleepWindowInMilliseconds(value: number): CommandBuilderA5; + errorHandler(value: (error: any) => boolean): CommandBuilderA5; + timeout(value: number): CommandBuilderA5; + circuitBreakerRequestVolumeThreshold(value: number): CommandBuilderA5; + requestVolumeRejectionThreshold(value: number): CommandBuilderA5; + circuitBreakerForceOpened(value: boolean): CommandBuilderA5; + circuitBreakerForceClosed(value: boolean): CommandBuilderA5; + statisticalWindowNumberOfBuckets(value: number): CommandBuilderA5; + statisticalWindowLength(value: number): CommandBuilderA5; + percentileWindowNumberOfBuckets(value: number): CommandBuilderA5; + percentileWindowLength(value: number): CommandBuilderA5; + circuitBreakerErrorThresholdPercentage(value: number): CommandBuilderA5; + context(value: any): CommandBuilderA5; + run(value: (t: T, u: U, v: V, w: W, x: X) => PromiseLike): CommandBuilderA5; + fallbackTo(value: (error: Error, args: [T, U, V, W, X]) => PromiseLike): CommandBuilderA5; + build(): CommandA5; +} + +export interface CommandBuilderA6 { + circuitBreakerSleepWindowInMilliseconds(value: number): CommandBuilderA6; + errorHandler(value: (error: any) => boolean): CommandBuilderA6; + timeout(value: number): CommandBuilderA6; + circuitBreakerRequestVolumeThreshold(value: number): CommandBuilderA6; + requestVolumeRejectionThreshold(value: number): CommandBuilderA6; + circuitBreakerForceOpened(value: boolean): CommandBuilderA6; + circuitBreakerForceClosed(value: boolean): CommandBuilderA6; + statisticalWindowNumberOfBuckets(value: number): CommandBuilderA6; + statisticalWindowLength(value: number): CommandBuilderA6; + percentileWindowNumberOfBuckets(value: number): CommandBuilderA6; + percentileWindowLength(value: number): CommandBuilderA6; + circuitBreakerErrorThresholdPercentage(value: number): CommandBuilderA6; + context(value: any): CommandBuilderA6; + run(value: (t: T, u: U, v: V, w: W, x: X, y: Y) => PromiseLike): CommandBuilderA6; + fallbackTo(value: (error: Error, args: [T, U, V, W, X, Y]) => PromiseLike): CommandBuilderA6; + build(): CommandA6; +} + +export interface CommandBuilderA7 { + circuitBreakerSleepWindowInMilliseconds(value: number): CommandBuilderA7; + errorHandler(value: (error: any) => boolean): CommandBuilderA7; + timeout(value: number): CommandBuilderA7; + circuitBreakerRequestVolumeThreshold(value: number): CommandBuilderA7; + requestVolumeRejectionThreshold(value: number): CommandBuilderA7; + circuitBreakerForceOpened(value: boolean): CommandBuilderA7; + circuitBreakerForceClosed(value: boolean): CommandBuilderA7; + statisticalWindowNumberOfBuckets(value: number): CommandBuilderA7; + statisticalWindowLength(value: number): CommandBuilderA7; + percentileWindowNumberOfBuckets(value: number): CommandBuilderA7; + percentileWindowLength(value: number): CommandBuilderA7; + circuitBreakerErrorThresholdPercentage(value: number): CommandBuilderA7; + context(value: any): CommandBuilderA7; + run(value: (t: T, u: U, v: V, w: W, x: X, y: Y, z: Z) => PromiseLike): CommandBuilderA7; + fallbackTo(value: (error: Error, args: [T, U, V, W, X, Y, Z]) => PromiseLike): CommandBuilderA7; + build(): CommandA7; } export interface CommandFactory { getOrCreate(commandKey: string, commandGroup?: string): CommandBuilder; + getOrCreate(commandKey: string, commandGroup?: string): CommandBuilderA0; + getOrCreate(commandKey: string, commandGroup?: string): CommandBuilderA1; + getOrCreate(commandKey: string, commandGroup?: string): CommandBuilderA2; + getOrCreate(commandKey: string, commandGroup?: string): CommandBuilderA3; + getOrCreate(commandKey: string, commandGroup?: string): CommandBuilderA4; + getOrCreate(commandKey: string, commandGroup?: string): CommandBuilderA5; + getOrCreate(commandKey: string, commandGroup?: string): CommandBuilderA6; + getOrCreate(commandKey: string, commandGroup?: string): CommandBuilderA7; resetCache(): void; } @@ -141,4 +333,4 @@ export var commandFactory: CommandFactory; export var metricsFactory: MetricsFactory; export var circuitFactory: CircuitFactory; export var hystrixSSEStream: HystrixSSEStream; -export var hystrixConfig: HystrixConfig; \ No newline at end of file +export var hystrixConfig: HystrixConfig; diff --git a/types/hystrixjs/tsconfig.json b/types/hystrixjs/tsconfig.json index 0cf5de7b81..480476e8d1 100644 --- a/types/hystrixjs/tsconfig.json +++ b/types/hystrixjs/tsconfig.json @@ -13,11 +13,7 @@ "typeRoots": [ "../" ], - "paths": { - "q": [ - "q/v0" - ] - }, + "paths": {}, "types": [], "noEmit": true, "forceConsistentCasingInFileNames": true @@ -26,4 +22,4 @@ "index.d.ts", "hystrixjs-tests.ts" ] -} \ No newline at end of file +}