Skip to content

Commit

Permalink
feat(types): Add TypeScript support for reduxful (#9)
Browse files Browse the repository at this point in the history
* Add basic typescript starter files

* Add basic typescript around reduxful package

* Refactor Map types based on review

* Refactor types based on review

* Update RequestDescription method doc/type
  • Loading branch information
shawnkoon authored and agerard-godaddy committed Sep 17, 2019
1 parent 67d2059 commit e75420c
Show file tree
Hide file tree
Showing 9 changed files with 167 additions and 6 deletions.
4 changes: 2 additions & 2 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ Create new RESTful configuration for Redux.
| --- | --- | --- |
| apiName | <code>String</code> | Name of the REST API |
| apiDesc | [<code>ApiDescription</code>](#ApiDescription) | Description object of target REST API |
| [config] | <code>Object</code> | Optional configuration settings |
| [config] | [<code>ApiConfig</code>](#ApiConfig) | Optional configuration settings |
| [config.requestAdapter] | [<code>RequestAdapter</code>](#RequestAdapter) | Request adapter to use |
| [config.options] | <code>Object</code> \| [<code>OptionsFn</code>](#OptionsFn) | Options to be passed to the request adapter |

Expand Down Expand Up @@ -353,7 +353,7 @@ Request Description object
| Name | Type | Description |
| --- | --- | --- |
| url | <code>String</code> \| [<code>UrlTemplateFn</code>](#UrlTemplateFn) | URL template of the REST endpoint. Placeholders can be set, with final URL built by [transform-url](https://github.com/godaddy/transform-url#readme). |
| method | <code>String</code> | HTTP method to use |
| [method] | <code>String</code> | HTTP method to use |
| [resourceAlias] | <code>String</code> | Resource name alias |
| [resourceData] | <code>Object</code> \| <code>Array</code> \| <code>\*</code> | Optional initial resource data |
| [dataTransform] | [<code>TransformFn</code>](#TransformFn) | Function to fixup request response |
Expand Down
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"main": "./lib",
"browser": "./lib",
"module": "./src",
"types": "./typings/index.d.ts",
"license": "MIT",
"author": "GoDaddy Operating Company, LLC",
"contributors": [
Expand All @@ -30,7 +31,9 @@
"lint:fix": "yarn lint --fix",
"prepublish": "yarn build",
"pretest": "yarn lint",
"test": "jest",
"test": "yarn test:jest && yarn test:types",
"test:jest": "jest",
"test:types": "tsc --lib es2015,dom --noEmit ./typings/*.ts",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",
"coveralls": "jest --coverage --coverageReporters=text-lcov | coveralls",
Expand All @@ -57,6 +60,7 @@
"eslint-plugin-json": "^1.2.0",
"eslint-plugin-mocha": "^5.0.0",
"jest": "^23.5.0",
"jsdoc-to-markdown": "^4.0.1"
"jsdoc-to-markdown": "^4.0.1",
"typescript": "^3.6.2"
}
}
2 changes: 1 addition & 1 deletion src/reduxful.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ Reduxful.setRequestAdapter = setRequestAdapter;
*
* @param {String} apiName - Name of the REST API
* @param {ApiDescription} apiDesc - Description object of target REST API
* @param {Object} [config] - Optional configuration settings
* @param {ApiConfig} [config] - Optional configuration settings
* @param {RequestAdapter} [config.requestAdapter] - Request adapter to use
* @param {Object|OptionsFn} [config.options] - Options to be passed to the request adapter
* @returns {Reduxful} instance
Expand Down
2 changes: 1 addition & 1 deletion src/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
*
* @property {String|UrlTemplateFn} url - URL template of the REST endpoint.
* Placeholders can be set, with final URL built by [transform-url](https://github.com/godaddy/transform-url#readme).
* @property {String} method - HTTP method to use
* @property {String} [method] - HTTP method to use
* @property {String} [resourceAlias] - Resource name alias
* @property {Object|Array|*} [resourceData] - Optional initial resource data
* @property {TransformFn} [dataTransform] - Function to fixup request response
Expand Down
5 changes: 5 additions & 0 deletions typings/fetchUtils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { makeFetchAdapter } from 'reduxful';

makeFetchAdapter(fetch, {});

export default makeFetchAdapter(fetch);
108 changes: 108 additions & 0 deletions typings/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
declare module 'reduxful' {
// fetchUtils
export interface RequestAdapterOptions {
method: string;
url: string;
headers: { [key: string]: string };
withCredentials: boolean;
body: any;
}

export type RequestAdapter = (options: RequestAdapterOptions) => Promise<any>;

export function makeFetchAdapter(
fetcher: typeof fetch,
defaultOptions?: Object
): RequestAdapter;

// utils
export interface Resource {
isLoaded?: boolean;
isUpdating?: boolean;
hasError?: boolean;
}

export function isLoaded(resource?: Resource): boolean;

export function isUpdating(resource?: Resource): boolean;

export function hasError(resource?: Resource): boolean;

export function getResourceKey(
reqName: string,
params?: { [key: string]: string | number }
): string;

// reduxful
export type TransformFn = (data: any, context?: { params?: Object }) => any;

export type UrlTemplateFn = (getState: () => any) => string;

export type OptionsFn<Options = Object> = (getState: () => any) => Options;

export interface RequestDescription<Options = Object> {
url: string | UrlTemplateFn;
method?: string;
resourceAlias?: string;
resourceData?: any;
dataTransform?: TransformFn;
errorTransform?: TransformFn;
repeatRequestDelay?: number;
options?: Options | OptionsFn<Options>;
}

export interface ApiDescription {
[key: string]: RequestDescription;
}

export interface ApiConfig<Options = Object> {
requestAdapter?: RequestAdapter;
options?: Options | OptionsFn<Options>;
}

export interface Action {
type: string;
payload: string;
meta: { key: string };
error?: boolean;
}

export type ActionCreatorThunkFn = (
dispatch: () => any,
getState: () => any
) => Promise<Action>;

export type ActionCreatorFn<Options = Object> = (
params: { [paramName: string]: any },
options?: Options | OptionsFn<Options>
) => ActionCreatorThunkFn;

export type ReducerFn<S = any> = (state: S, action: Object) => S;

export type SelectorFn = (state: Object, params: Object) => Resource;

export interface ReduxfulProps {
actionCreators: { [key: string]: ActionCreatorFn };
actions: { [key: string]: ActionCreatorFn };
reducers: { [key: string]: ReducerFn };
reducerMap: { [key: string]: ReducerFn };
selectors: { [key: string]: SelectorFn };
}

class Reduxful implements ReduxfulProps {
public actionCreators: { [key: string]: ActionCreatorFn };
public actions: { [key: string]: ActionCreatorFn };
public reducers: { [key: string]: ReducerFn };
public reducerMap: { [key: string]: ReducerFn };
public selectors: { [key: string]: SelectorFn };
constructor(apiName: string, apiDesc: ApiDescription, apiConfig?: ApiConfig);
}

export function setupApi(
apiName: string,
apiDesc: ApiDescription,
config?: ApiConfig
): Reduxful;

export default Reduxful;
}
18 changes: 18 additions & 0 deletions typings/reduxful.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import Reduxful, { setupApi } from 'reduxful';
import requestAdapter from './fetchUtils.test';

const apiDesc = {
getDoodad: {
url: 'http://api.my-service.com/doodads/:id',
},
getDoodadList: {
url: 'http://api.my-service.com/doodads',
},
};

const apiConfig = { requestAdapter };
const doodadApi = new Reduxful('doodadApi', apiDesc, apiConfig);

export const reduxFul = setupApi('test-name', {});

export default doodadApi;
21 changes: 21 additions & 0 deletions typings/utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { isLoaded, isUpdating, hasError, getResourceKey } from 'reduxful';

isLoaded();
isLoaded(null);
isLoaded({ isLoaded: false });

isUpdating();
isUpdating(null);
isUpdating({ isUpdating: false });

hasError();
hasError(null);
hasError({ hasError: false });

const params = {
id: 'user123',
count: 777,
};

getResourceKey('test', params);
getResourceKey('test');
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4740,6 +4740,11 @@ type-check@~0.3.2:
dependencies:
prelude-ls "~1.1.2"

typescript@^3.6.2:
version "3.6.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.6.2.tgz#105b0f1934119dde543ac8eb71af3a91009efe54"
integrity sha512-lmQ4L+J6mnu3xweP8+rOrUwzmN+MRAj7TgtJtDaXE5PMyX2kCrklhg3rvOsOIfNeAWMQWO2F1GPc1kMD2vLAfw==

typical@^2.4.2, typical@^2.6.0, typical@^2.6.1:
version "2.6.1"
resolved "https://registry.yarnpkg.com/typical/-/typical-2.6.1.tgz#5c080e5d661cbbe38259d2e70a3c7253e873881d"
Expand Down

0 comments on commit e75420c

Please sign in to comment.