From e0dd752b9a912a051266a1b850b51e80e863b6a4 Mon Sep 17 00:00:00 2001 From: Dmitriy Pleshevskiy Date: Sun, 20 Dec 2020 12:26:50 +0300 Subject: [PATCH 1/6] chore: bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0bbfa0f..407f7f7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-rest-request", - "version": "0.4.1", + "version": "0.5.0", "description": "Minimalistic REST API client for React inspired by Apollo", "readme": "README.md", "main": "./target/index.js", From 83605adee130164bb65cfcd6ddf44272e1e1d071 Mon Sep 17 00:00:00 2001 From: Dmitriy Pleshevskiy Date: Sun, 20 Dec 2020 16:16:56 +0300 Subject: [PATCH 2/6] chore: move react to peer dependencies --- package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 407f7f7..a0e8c5c 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,6 @@ "homepage": "https://github.com/pleshevskiy/react-rest-request#readme", "dependencies": { "lodash.isequal": "^4.5.0", - "react": "^17.0.1", "tiny-invariant": "^1.1.0" }, "devDependencies": { @@ -52,5 +51,8 @@ "node-fetch": "^2.6.1", "ts-jest": "^26.4.3", "typescript": "^4.0.5" + }, + "peerDependencies": { + "react": "^16.3.0 || ^17.0.0" } } From 79b404cd28523885ad52290ba9c11893ebed2cc1 Mon Sep 17 00:00:00 2001 From: Dmitriy Pleshevskiy Date: Sun, 20 Dec 2020 16:18:41 +0300 Subject: [PATCH 3/6] chore: bump version --- package-lock.json | 25 +++++-------------------- package.json | 2 +- 2 files changed, 6 insertions(+), 21 deletions(-) diff --git a/package-lock.json b/package-lock.json index c71c4e0..893670a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "react-rest-request", - "version": "0.4.1", + "version": "0.5.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -5083,7 +5083,8 @@ "js-tokens": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true }, "js-yaml": { "version": "3.13.1", @@ -5340,14 +5341,6 @@ "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", "dev": true }, - "loose-envify": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", - "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", - "requires": { - "js-tokens": "^3.0.0" - } - }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -5624,7 +5617,8 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true }, "object-copy": { "version": "0.1.0", @@ -6256,15 +6250,6 @@ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "dev": true }, - "react": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/react/-/react-17.0.1.tgz", - "integrity": "sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, "react-is": { "version": "17.0.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", diff --git a/package.json b/package.json index a0e8c5c..4a1c36a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-rest-request", - "version": "0.5.0", + "version": "0.5.1", "description": "Minimalistic REST API client for React inspired by Apollo", "readme": "README.md", "main": "./target/index.js", From beba6445a2a4f258af97f1b1fcc8f5ee034f52bb Mon Sep 17 00:00:00 2001 From: Dmitriy Pleshevskiy Date: Wed, 23 Dec 2020 00:03:45 +0300 Subject: [PATCH 4/6] fix: extracting type conflicts --- package-lock.json | 2 +- src/endpoint.ts | 5 ++++- src/lazy-request-hook.ts | 48 ++++++++++++++++++++++------------------ src/reducer.ts | 2 ++ src/request-hook.ts | 17 +++++--------- 5 files changed, 39 insertions(+), 35 deletions(-) diff --git a/package-lock.json b/package-lock.json index 893670a..64d6bfd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "react-rest-request", - "version": "0.5.0", + "version": "0.5.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/src/endpoint.ts b/src/endpoint.ts index 70568b0..16570a5 100644 --- a/src/endpoint.ts +++ b/src/endpoint.ts @@ -8,13 +8,16 @@ export enum Method { DELETE = 'DELETE', } -export type Endpoint = Readonly<{ +export type Endpoint = Readonly<{ + _?: V; // Temporary hack to extract the type of variables. Do not use it in real endpoints. method: Method; url: string | ((params: P) => string); headers?: Record; transformResponseData?: (data: any) => R; }> +export type AnyEndpoint = Endpoint; + export type ExtractEndpointResponse = E extends Endpoint ? R : E extends Endpoint ? R : never; export type ExtractEndpointVariables = E extends Endpoint ? V : E extends Endpoint ? V : never; export type ExtractEndpointParams = E extends Endpoint ? P : never; diff --git a/src/lazy-request-hook.ts b/src/lazy-request-hook.ts index c9c807d..53e7cb4 100644 --- a/src/lazy-request-hook.ts +++ b/src/lazy-request-hook.ts @@ -2,13 +2,13 @@ import React from 'react'; import invariant from 'tiny-invariant'; import isEqual from 'lodash.isequal'; import { useClient } from './client-hook'; -import { Endpoint, ExtractEndpointParams, ExtractEndpointResponse, ExtractEndpointVariables } from './endpoint'; -import { PublicRequestState, RequestAction, requestReducer, RequestState } from './reducer'; +import { AnyEndpoint, ExtractEndpointParams, ExtractEndpointResponse, ExtractEndpointVariables } from './endpoint'; +import { PublicRequestState, RequestReducer, requestReducer } from './reducer'; import { useRequestContext } from './request-context'; import { ClientResponse } from './client'; import { isFunction } from './misc'; -export type LazyRequestConfig = Readonly<{ +export type LazyRequestConfig = Readonly<{ variables?: V; params?: P; headers?: Record; @@ -16,29 +16,33 @@ export type LazyRequestConfig = Readonly<{ onFailure?: (res: ClientResponse) => unknown; }> -export type LazyRequestHandlerConfig = Readonly< - LazyRequestConfig +export type LazyRequestConfigFromEndpoint = LazyRequestConfig< + ExtractEndpointResponse, + ExtractEndpointVariables, + ExtractEndpointParams +>; + +export type LazyRequestHandlerConfig = Readonly< + LazyRequestConfigFromEndpoint & { force?: boolean } > -export type RequestHandler = (config?: LazyRequestHandlerConfig) => Promise; +export type RequestHandler = + (config?: LazyRequestHandlerConfig) => Promise | null>; export type RefetchRequestHandler = () => void; -export type PublicRequestStateWithRefetch = PublicRequestState & { refetch: RefetchRequestHandler }; +export type PublicRequestStateWithRefetch = + PublicRequestState> + & { refetch: RefetchRequestHandler }; -export function useLazyRequest< - E extends Endpoint, - R = ExtractEndpointResponse, - V = ExtractEndpointVariables, - P = ExtractEndpointParams ->( +export function useLazyRequest( endpoint: E, - config?: LazyRequestConfig, -): [RequestHandler, PublicRequestStateWithRefetch] { + config?: LazyRequestConfigFromEndpoint, +): [RequestHandler, PublicRequestStateWithRefetch] { const [client] = useClient(); const { defaultHeaders } = useRequestContext(); - const [state, dispatch] = React.useReducer, RequestAction>>( + const [state, dispatch] = React.useReducer>>( requestReducer, { data: null, @@ -46,24 +50,24 @@ export function useLazyRequest< isCalled: false, } ); - const [prevHandlerConfig, setPrevHandlerConfig] = React.useState | null>(null); + const [prevHandlerConfig, setPrevHandlerConfig] = React.useState | null>(null); const transformResponseData = React.useCallback( - (data: unknown): R => { + (data: unknown): ExtractEndpointResponse => { return isFunction(endpoint.transformResponseData) ? endpoint.transformResponseData(data) - : data as R; + : data as ExtractEndpointResponse; }, [endpoint] ); const handler = React.useCallback( - (handlerConfig?: LazyRequestHandlerConfig) => { + (handlerConfig?: LazyRequestHandlerConfig) => { if (state?.loading) { return Promise.resolve(null); } - let params: P | undefined; + let params: ExtractEndpointParams | undefined; let endpointUrl: string; let isSameRequest = true; if (isFunction(endpoint.url)) { @@ -106,7 +110,7 @@ export function useLazyRequest< setPrevHandlerConfig(handlerConfig ?? {}); return client - .request({ + .request>({ ...endpoint, url: endpointUrl, headers, diff --git a/src/reducer.ts b/src/reducer.ts index 5607fcf..409ef63 100644 --- a/src/reducer.ts +++ b/src/reducer.ts @@ -28,6 +28,8 @@ export type RequestAction = response: ClientResponse } +export type RequestReducer = React.Reducer, RequestAction> + export function requestReducer(state: RequestState, action: RequestAction) { switch (action.type) { case 'call': { diff --git a/src/request-hook.ts b/src/request-hook.ts index 376e529..a66ed8a 100644 --- a/src/request-hook.ts +++ b/src/request-hook.ts @@ -1,23 +1,18 @@ import React from 'react'; import invariant from 'tiny-invariant'; -import { Endpoint, ExtractEndpointParams, ExtractEndpointResponse, ExtractEndpointVariables, Method } from './endpoint'; -import { LazyRequestConfig, useLazyRequest } from './lazy-request-hook'; +import { AnyEndpoint, Method } from './endpoint'; +import { LazyRequestConfigFromEndpoint, useLazyRequest } from './lazy-request-hook'; -export type RequestConfig = Readonly< - LazyRequestConfig +export type RequestConfigFromEndpoint = Readonly< + LazyRequestConfigFromEndpoint & { skip?: boolean, } > -export function useRequest< - E extends Endpoint, - R = ExtractEndpointResponse, - V = ExtractEndpointVariables, - P = ExtractEndpointParams ->( +export function useRequest( endpoint: E, - config?: RequestConfig, + config?: RequestConfigFromEndpoint, ) { invariant( endpoint.method !== Method.DELETE, From e762303d040041af6f3912b447e7adb48fa1cd36 Mon Sep 17 00:00:00 2001 From: Dmitriy Pleshevskiy Date: Wed, 23 Dec 2020 00:06:25 +0300 Subject: [PATCH 5/6] chore: bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4a1c36a..03295e1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-rest-request", - "version": "0.5.1", + "version": "0.5.2", "description": "Minimalistic REST API client for React inspired by Apollo", "readme": "README.md", "main": "./target/index.js", From edc88a64ff64ddb8cc368bdb5a75128f37ec1fa6 Mon Sep 17 00:00:00 2001 From: Dmitriy Pleshevskiy Date: Wed, 23 Dec 2020 00:18:55 +0300 Subject: [PATCH 6/6] fix: change default params type to unknown --- package.json | 2 +- src/endpoint.ts | 4 ++-- target/endpoint.d.ts | 4 +++- target/lazy-request-hook.d.ts | 13 +++++++------ target/reducer.d.ts | 2 ++ target/request-hook.d.ts | 8 ++++---- 6 files changed, 19 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index 03295e1..b1d0cd7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-rest-request", - "version": "0.5.2", + "version": "0.5.3", "description": "Minimalistic REST API client for React inspired by Apollo", "readme": "README.md", "main": "./target/index.js", diff --git a/src/endpoint.ts b/src/endpoint.ts index 16570a5..520cf9f 100644 --- a/src/endpoint.ts +++ b/src/endpoint.ts @@ -8,7 +8,7 @@ export enum Method { DELETE = 'DELETE', } -export type Endpoint = Readonly<{ +export type Endpoint = Readonly<{ _?: V; // Temporary hack to extract the type of variables. Do not use it in real endpoints. method: Method; url: string | ((params: P) => string); @@ -16,7 +16,7 @@ export type Endpoint = Readonly<{ transformResponseData?: (data: any) => R; }> -export type AnyEndpoint = Endpoint; +export type AnyEndpoint = Endpoint export type ExtractEndpointResponse = E extends Endpoint ? R : E extends Endpoint ? R : never; export type ExtractEndpointVariables = E extends Endpoint ? V : E extends Endpoint ? V : never; diff --git a/target/endpoint.d.ts b/target/endpoint.d.ts index 3fb8732..54e2b09 100644 --- a/target/endpoint.d.ts +++ b/target/endpoint.d.ts @@ -6,12 +6,14 @@ export declare enum Method { PATCH = "PATCH", DELETE = "DELETE" } -export declare type Endpoint = Readonly<{ +export declare type Endpoint = Readonly<{ + _?: V; method: Method; url: string | ((params: P) => string); headers?: Record; transformResponseData?: (data: any) => R; }>; +export declare type AnyEndpoint = Endpoint; export declare type ExtractEndpointResponse = E extends Endpoint ? R : E extends Endpoint ? R : never; export declare type ExtractEndpointVariables = E extends Endpoint ? V : E extends Endpoint ? V : never; export declare type ExtractEndpointParams = E extends Endpoint ? P : never; diff --git a/target/lazy-request-hook.d.ts b/target/lazy-request-hook.d.ts index 34e8248..85eb71d 100644 --- a/target/lazy-request-hook.d.ts +++ b/target/lazy-request-hook.d.ts @@ -1,19 +1,20 @@ -import { Endpoint, ExtractEndpointParams, ExtractEndpointResponse, ExtractEndpointVariables } from './endpoint'; +import { AnyEndpoint, ExtractEndpointParams, ExtractEndpointResponse, ExtractEndpointVariables } from './endpoint'; import { PublicRequestState } from './reducer'; import { ClientResponse } from './client'; -export declare type LazyRequestConfig = Readonly<{ +export declare type LazyRequestConfig = Readonly<{ variables?: V; params?: P; headers?: Record; onComplete?: (data: R) => unknown; onFailure?: (res: ClientResponse) => unknown; }>; -export declare type LazyRequestHandlerConfig = Readonly & { +export declare type LazyRequestConfigFromEndpoint = LazyRequestConfig, ExtractEndpointVariables, ExtractEndpointParams>; +export declare type LazyRequestHandlerConfig = Readonly & { force?: boolean; }>; -export declare type RequestHandler = (config?: LazyRequestHandlerConfig) => Promise; +export declare type RequestHandler = (config?: LazyRequestHandlerConfig) => Promise | null>; export declare type RefetchRequestHandler = () => void; -export declare type PublicRequestStateWithRefetch = PublicRequestState & { +export declare type PublicRequestStateWithRefetch = PublicRequestState> & { refetch: RefetchRequestHandler; }; -export declare function useLazyRequest, R = ExtractEndpointResponse, V = ExtractEndpointVariables, P = ExtractEndpointParams>(endpoint: E, config?: LazyRequestConfig): [RequestHandler, PublicRequestStateWithRefetch]; +export declare function useLazyRequest(endpoint: E, config?: LazyRequestConfigFromEndpoint): [RequestHandler, PublicRequestStateWithRefetch]; diff --git a/target/reducer.d.ts b/target/reducer.d.ts index 0b0892f..bf94a2c 100644 --- a/target/reducer.d.ts +++ b/target/reducer.d.ts @@ -1,3 +1,4 @@ +/// import { ClientResponse } from './client'; export declare type PublicRequestState = Readonly<{ data: R | null; @@ -21,6 +22,7 @@ export declare type RequestAction = { type: 'failure'; response: ClientResponse; }; +export declare type RequestReducer = React.Reducer, RequestAction>; export declare function requestReducer(state: RequestState, action: RequestAction): { loading: boolean; isCalled: boolean; diff --git a/target/request-hook.d.ts b/target/request-hook.d.ts index 0644b01..23106ca 100644 --- a/target/request-hook.d.ts +++ b/target/request-hook.d.ts @@ -1,6 +1,6 @@ -import { Endpoint, ExtractEndpointParams, ExtractEndpointResponse, ExtractEndpointVariables } from './endpoint'; -import { LazyRequestConfig } from './lazy-request-hook'; -export declare type RequestConfig = Readonly & { +import { AnyEndpoint } from './endpoint'; +import { LazyRequestConfigFromEndpoint } from './lazy-request-hook'; +export declare type RequestConfigFromEndpoint = Readonly & { skip?: boolean; }>; -export declare function useRequest, R = ExtractEndpointResponse, V = ExtractEndpointVariables, P = ExtractEndpointParams>(endpoint: E, config?: RequestConfig): import("./lazy-request-hook").PublicRequestStateWithRefetch; +export declare function useRequest(endpoint: E, config?: RequestConfigFromEndpoint): import("./lazy-request-hook").PublicRequestStateWithRefetch;