diff --git a/types/redux-api-middleware/index.d.ts b/types/redux-api-middleware/index.d.ts new file mode 100644 index 0000000000..7c79fe9c9c --- /dev/null +++ b/types/redux-api-middleware/index.d.ts @@ -0,0 +1,104 @@ +// Type definitions for redux-api-middleware 3.0 +// Project: https://github.com/agraboso/redux-api-middleware +// Definitions by: Andrew Luca +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.8 + +import { + Middleware, + MiddlewareAPI, + Dispatch, + AnyAction, + applyMiddleware +} from 'redux'; + +/** + * This module is also a UMD module that exposes a global variable 'ReduxApiMiddleware' + * when loaded outside a module loader environment. + */ +export as namespace ReduxApiMiddleware; + +export type RSAA = '@@redux-api-middleware/RSAA'; +export const RSAA = '@@redux-api-middleware/RSAA'; + +export function isRSAA(action: object): boolean; +export function validateRSAA(action: object): string[]; +export function isValidRSAA(action: object): boolean; + +export class InvalidRSAA extends Error { + name: 'InvalidRSAA'; + message: 'Invalid RSAA'; + validationErrors: string[]; + constructor(validationErrors: string[]); +} + +export class InternalError extends Error { + name: 'InternalError'; + message: string; + constructor(message: string); +} + +export class RequestError extends Error { + name: 'RequestError'; + message: string; + constructor(message: string); +} + +export class ApiError extends Error { + name: 'ApiError'; + status: number; + statusText: string; + response: T; + message: string; + constructor(status: number, statusText: string, response: T); +} + +export function getJSON(res: Response): Promise | Promise; + +export const apiMiddleware: Middleware; + +export interface CreateMiddlewareOptions { + ok?: (res: Response) => boolean; + fetch?: typeof fetch; +} + +export function createMiddleware(options?: CreateMiddlewareOptions): Middleware; + +export interface RSAARequestTypeDescriptor { + type: string | symbol; + payload?: (action: RSAAAction, state: S) => P | P; + meta?: (action: RSAAAction, state: S) => M | M; +} + +export interface RSAASuccessTypeDescriptor { + type: string | symbol; + payload?: (action: RSAAAction, state: S, res: any) => P | P; + meta?: (action: RSAAAction, state: S, res: any) => M | M; +} + +export interface RSAAFailureTypeDescriptor { + type: string | symbol; + payload?: (action: RSAAAction, state: S) => P | P; + meta?: (action: RSAAAction, state: S, res: any) => M | M; +} + +export interface RSAACall { + endpoint: (state: S) => string | string; + method: string; + types: [ + string | symbol | RSAARequestTypeDescriptor, + string | symbol | RSAASuccessTypeDescriptor, + string | symbol | RSAAFailureTypeDescriptor + ]; + body?: ((state: S) => BodyInit | null) | BodyInit | null; + headers?: (state: S) => HeadersInit | HeadersInit; + options?: (state: S) => RequestInit | RequestInit; + credentials?: RequestCredentials; + bailout?: (state: S) => boolean | boolean; + fetch?: typeof fetch; + ok?: (res: Response) => boolean; +} + +export interface RSAAAction { + [RSAA]: RSAACall; +} diff --git a/types/redux-api-middleware/package.json b/types/redux-api-middleware/package.json new file mode 100644 index 0000000000..7cc600c266 --- /dev/null +++ b/types/redux-api-middleware/package.json @@ -0,0 +1,6 @@ +{ + "private": true, + "dependencies": { + "redux": "^4.0.1" + } +} diff --git a/types/redux-api-middleware/redux-api-middleware-tests.ts b/types/redux-api-middleware/redux-api-middleware-tests.ts new file mode 100644 index 0000000000..ad9b7ef34b --- /dev/null +++ b/types/redux-api-middleware/redux-api-middleware-tests.ts @@ -0,0 +1,105 @@ +import { + RSAA, + isRSAA, + validateRSAA, + isValidRSAA, + InvalidRSAA, + InternalError, + RequestError, + ApiError, + getJSON, + createMiddleware, + apiMiddleware, +} from 'redux-api-middleware'; + +{ + // RSAA + const passRSAA: RSAA = '@@redux-api-middleware/RSAA'; + const failRSAA: RSAA = '@@redux-api-middleware/RSAA-fail'; // $ExpectError +} + +{ + // isRSAA + isRSAA({}); // $ExpectType boolean + isRSAA(); // $ExpectError +} + +{ + // validateRSAA + validateRSAA({}); // $ExpectType string[] + validateRSAA(); // $ExpectError +} + +{ + // isValidRSAA + isValidRSAA({}); // $ExpectType boolean + isValidRSAA(); // $ExpectError +} + +{ + // InvalidRSAA + new InvalidRSAA([]); // $ExpectType InvalidRSAA + new InvalidRSAA([]).message; // $ExpectType "Invalid RSAA" + new InvalidRSAA([]).name; // $ExpectType "InvalidRSAA" + new InvalidRSAA([]).validationErrors; // $ExpectType string[] + new InvalidRSAA(['']); + new InvalidRSAA(); // $ExpectError + new InvalidRSAA([0]); // $ExpectError +} + +{ + // InternalError + new InternalError(''); // $ExpectType InternalError + new InternalError('').name; // $ExpectType "InternalError" + new InternalError(); // $ExpectError + new InternalError(0); // $ExpectError +} + +{ + // RequestError + new RequestError(''); // $ExpectType RequestError + new RequestError('').name; // $ExpectType "RequestError" + new RequestError(); // $ExpectError + new RequestError(0); // $ExpectError +} + +{ + // ApiError + new ApiError(200, 'OK', {}); // $ExpectType ApiError<{}> + new ApiError(200, 'OK', {}).name; // $ExpectType "ApiError" + new ApiError(200, 'OK', {}).status; // $ExpectType number + new ApiError(200, 'OK', {}).statusText; // $ExpectType string + new ApiError(200, 'OK', {}).response; // $ExpectType {} + new ApiError(); // $ExpectError + + interface Response { data: number; } + new ApiError(200, 'OK', { data: 0 }); // $ExpectType ApiError + new ApiError(200, 'OK', { data: 0 }).name; // $ExpectType "ApiError" + new ApiError(200, 'OK', { data: 0 }).status; // $ExpectType number + new ApiError(200, 'OK', { data: 0 }).statusText; // $ExpectType string + new ApiError(200, 'OK', { data: 0 }).response; // $ExpectType Response + new ApiError(200, 'OK', {}); // $ExpectError +} + +{ + // getJSON + getJSON(new Response()); // $ExpectType Promise | Promise + getJSON(); // $ExpectError + getJSON(0); // $ExpectError +} + +{ + // createMiddleware + createMiddleware(); // $ExpectType Middleware<{}, any, Dispatch> + createMiddleware({}); // $ExpectType Middleware<{}, any, Dispatch> + createMiddleware({ fetch }); // $ExpectType Middleware<{}, any, Dispatch> + createMiddleware({ ok: res => res.ok }); // $ExpectType Middleware<{}, any, Dispatch> + createMiddleware({ fetch, ok: res => res.ok }); // $ExpectType Middleware<{}, any, Dispatch> +} + +{ + // apiMiddleware + // $ExpectType (next: Dispatch) => (action: any) => any + apiMiddleware({ getState: () => undefined, dispatch: (action: any) => action }); + apiMiddleware(); // $ExpectError +} diff --git a/types/redux-api-middleware/tsconfig.json b/types/redux-api-middleware/tsconfig.json new file mode 100644 index 0000000000..f875313961 --- /dev/null +++ b/types/redux-api-middleware/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6", + "dom" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictFunctionTypes": true, + "strictNullChecks": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "redux-api-middleware-tests.ts" + ] +} diff --git a/types/redux-api-middleware/tslint.json b/types/redux-api-middleware/tslint.json new file mode 100644 index 0000000000..f93cf8562a --- /dev/null +++ b/types/redux-api-middleware/tslint.json @@ -0,0 +1,3 @@ +{ + "extends": "dtslint/dt.json" +}