New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

use-http

Package Overview
Dependencies
Maintainers
1
Versions
102
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

use-http - npm Package Compare versions

Comparing version 1.0.7 to 1.0.8

11

dist/defaults.js

@@ -17,2 +17,4 @@ "use strict";

exports.useFetchArgsDefaults = {
host: '',
path: undefined,
customOptions: {

@@ -26,3 +28,2 @@ cacheLife: 0,

onTimeout: function () { },
path: '',
perPage: 0,

@@ -36,3 +37,5 @@ persist: false,

timeout: 0,
url: '',
// defaults
data: undefined,
loading: false
},

@@ -44,6 +47,2 @@ requestInit: {

},
defaults: {
data: undefined,
loading: false
},
dependencies: undefined

@@ -50,0 +49,0 @@ };

import { HTTPMethod, Interceptors, ValueOf, DoFetchArgs, Cache } from './types';
export default function doFetchArgs<TData = any>(initialOptions: RequestInit, initialURL: string, path: string, method: HTTPMethod, controller: AbortController, cacheLife: number, cache: Cache, routeOrBody?: string | BodyInit | object, bodyAs2ndParam?: BodyInit | object, requestInterceptor?: ValueOf<Pick<Interceptors, 'request'>>): Promise<DoFetchArgs>;
export default function doFetchArgs<TData = any>(initialOptions: RequestInit, method: HTTPMethod, controller: AbortController, cacheLife: number, cache: Cache, host?: string, path?: string, routeOrBody?: string | BodyInit | object, bodyAs2ndParam?: BodyInit | object, requestInterceptor?: ValueOf<Pick<Interceptors, 'request'>>): Promise<DoFetchArgs>;

@@ -53,3 +53,3 @@ "use strict";

var GET = types_1.HTTPMethod.GET;
function doFetchArgs(initialOptions, initialURL, path, method, controller, cacheLife, cache, routeOrBody, bodyAs2ndParam, requestInterceptor) {
function doFetchArgs(initialOptions, method, controller, cacheLife, cache, host, path, routeOrBody, bodyAs2ndParam, requestInterceptor) {
return __awaiter(this, void 0, void 0, function () {

@@ -71,3 +71,3 @@ var route, url, body, headers, options, responseID, _a, _b;

})();
url = "" + initialURL + path + route;
url = "" + host + utils_1.addSlash(path, host) + utils_1.addSlash(route);
body = (function () {

@@ -121,3 +121,3 @@ // FormData instanceof check should go first, because React Native's FormData implementation

if (!requestInterceptor) return [3 /*break*/, 2];
return [4 /*yield*/, requestInterceptor({ options: opts, url: initialURL, path: path, route: route })];
return [4 /*yield*/, requestInterceptor({ options: opts, url: host, path: path, route: route })];
case 1:

@@ -124,0 +124,0 @@ interceptor = _a.sent();

@@ -73,3 +73,3 @@ import { ReactNode } from 'react';

url: string;
options: Options;
options: IncomingOptions;
graphql?: boolean;

@@ -79,3 +79,3 @@ }

url?: string;
options?: Options;
options?: IncomingOptions;
graphql?: boolean;

@@ -125,3 +125,3 @@ children: ReactNode;

export declare type Req<TData = any> = ReqMethods & ReqBase<TData>;
export declare type UseFetchArgs = [(string | OptionsMaybeURL | OverwriteGlobalOptions)?, (NoUrlOptions | OverwriteGlobalOptions | any[])?, any[]?];
export declare type UseFetchArgs = [(string | IncomingOptions | OverwriteGlobalOptions)?, (IncomingOptions | OverwriteGlobalOptions | any[])?, any[]?];
export declare type UseFetchArrayReturn<TData> = [Req<TData>, Res<TData>, boolean, Error];

@@ -135,7 +135,7 @@ export declare type UseFetchObjectReturn<TData> = ReqBase<TData> & ReqMethods & {

request?: ({ options, url, path, route }: {
options: Options;
url: string;
path: string;
route: string;
}) => Promise<Options> | Options;
options: RequestInit;
url?: string;
path?: string;
route?: string;
}) => Promise<RequestInit> | RequestInit;
response?: ({ response }: {

@@ -153,29 +153,26 @@ response: Res<TData>;

export interface CustomOptions {
cacheLife?: number;
cachePolicy?: CachePolicies;
data?: any;
interceptors?: Interceptors;
loading?: boolean;
onAbort?: () => void;
onError?: OnError;
onNewData?: (currData: any, newData: any) => any;
onTimeout?: () => void;
path?: string;
persist?: boolean;
perPage?: number;
responseType?: ResponseType;
retries?: number;
retryOn?: RetryOn;
retryDelay?: RetryDelay;
suspense?: boolean;
timeout?: number;
url?: string;
cacheLife: number;
cachePolicy: CachePolicies;
data: any;
interceptors: Interceptors;
loading: boolean;
onAbort: () => void;
onError: OnError;
onNewData: (currData: any, newData: any) => any;
onTimeout: () => void;
persist: boolean;
perPage: number;
responseType: ResponseType;
retries: number;
retryOn: RetryOn;
retryDelay: RetryDelay;
suspense: boolean;
timeout: number;
}
export declare type IncomingOptions = Partial<CustomOptions> & Omit<RequestInit, 'body'> & {
body?: BodyInit | object | null;
};
export declare type Options = CustomOptions & Omit<RequestInit, 'body'> & {
body?: BodyInit | object | null;
};
export declare type NoUrlOptions = Omit<Options, 'url'>;
export declare type OptionsMaybeURL = NoUrlOptions & Partial<Pick<Options, 'url'>> & {
url?: string;
};
export declare type OverwriteGlobalOptions = (options: Options) => Options;

@@ -190,2 +187,4 @@ export declare type RetryOn = (<TData = any>({ attempt, error, response }: RetryOpts) => Promise<boolean>) | number[];

export declare type UseFetchArgsReturn = {
host: string;
path?: string;
customOptions: {

@@ -199,3 +198,2 @@ cacheLife: number;

onTimeout: () => void;
path: string;
perPage: number;

@@ -209,9 +207,6 @@ persist: boolean;

timeout: number;
url: string;
};
requestInit: RequestInit;
defaults: {
loading: boolean;
data?: any;
};
requestInit: RequestInit;
dependencies?: any[];

@@ -218,0 +213,0 @@ };

@@ -49,2 +49,13 @@ "use strict";

};
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
var __importDefault = (this && this.__importDefault) || function (mod) {

@@ -69,5 +80,5 @@ return (mod && mod.__esModule) ? mod : { "default": mod };

}
var _a = useFetchArgs_1.default.apply(void 0, args), customOptions = _a.customOptions, requestInit = _a.requestInit, defaults = _a.defaults, dependencies = _a.dependencies;
var _a = useFetchArgs_1.default.apply(void 0, args), host = _a.host, path = _a.path, customOptions = _a.customOptions, requestInit = _a.requestInit, dependencies = _a.dependencies;
var cacheLife = customOptions.cacheLife, cachePolicy = customOptions.cachePolicy, // 'cache-first' by default
interceptors = customOptions.interceptors, onAbort = customOptions.onAbort, onError = customOptions.onError, onNewData = customOptions.onNewData, onTimeout = customOptions.onTimeout, path = customOptions.path, perPage = customOptions.perPage, persist = customOptions.persist, responseType = customOptions.responseType, retries = customOptions.retries, retryDelay = customOptions.retryDelay, retryOn = customOptions.retryOn, suspense = customOptions.suspense, timeout = customOptions.timeout, initialURL = customOptions.url;
interceptors = customOptions.interceptors, onAbort = customOptions.onAbort, onError = customOptions.onError, onNewData = customOptions.onNewData, onTimeout = customOptions.onTimeout, perPage = customOptions.perPage, persist = customOptions.persist, responseType = customOptions.responseType, retries = customOptions.retries, retryDelay = customOptions.retryDelay, retryOn = customOptions.retryOn, suspense = customOptions.suspense, timeout = customOptions.timeout, defaults = __rest(customOptions, ["cacheLife", "cachePolicy", "interceptors", "onAbort", "onError", "onNewData", "onTimeout", "perPage", "persist", "responseType", "retries", "retryDelay", "retryOn", "suspense", "timeout"]);
var cache = useCache_1.default({ persist: persist, cacheLife: cacheLife, cachePolicy: cachePolicy });

@@ -89,5 +100,5 @@ var isServer = use_ssr_1.default().isServer;

var doFetch = function (routeOrBody, body) { return __awaiter(_this, void 0, void 0, function () {
var theController, _a, url, options, response, theData, _b, _c, err_1, timer, newData, newRes, _d, _e, opts, shouldRetry, _f, _g, theData, err_2, opts, shouldRetry, _h, _j, theData;
return __generator(this, function (_k) {
switch (_k.label) {
var theController, _a, url, options, response, timer, newData, newRes, _b, _c, opts, shouldRetry, _d, _e, theData, err_1, opts, shouldRetry, _f, _g, theData;
return __generator(this, function (_h) {
switch (_h.label) {
case 0:

@@ -99,43 +110,11 @@ if (isServer)

theController = controller.current;
return [4 /*yield*/, doFetchArgs_1.default(requestInit, initialURL, path, method, theController, cacheLife, cache, routeOrBody, body, interceptors.request)];
return [4 /*yield*/, doFetchArgs_1.default(requestInit, method, theController, cacheLife, cache, host, path, routeOrBody, body, interceptors.request)];
case 1:
_a = _k.sent(), url = _a.url, options = _a.options, response = _a.response;
_a = _h.sent(), url = _a.url, options = _a.options, response = _a.response;
error.current = undefined;
if (!(response.isCached && cachePolicy === CACHE_FIRST)) return [3 /*break*/, 8];
_k.label = 2;
case 2:
_k.trys.push([2, 7, , 8]);
res.current = response.cached;
return [4 /*yield*/, utils_1.tryGetData(response.cached, defaults.data, responseType)];
case 3:
theData = _k.sent();
res.current.data = theData;
_b = res;
if (!interceptors.response) return [3 /*break*/, 5];
return [4 /*yield*/, interceptors.response({ response: res.current })];
case 4:
_c = _k.sent();
return [3 /*break*/, 6];
case 5:
_c = res.current;
_k.label = 6;
case 6:
_b.current = _c;
utils_1.invariant('data' in res.current, 'You must have `data` field on the Response returned from your `interceptors.response`');
data.current = res.current.data;
if (!suspense && mounted.current)
forceUpdate();
return [2 /*return*/, data.current];
case 7:
err_1 = _k.sent();
error.current = err_1;
if (mounted.current)
forceUpdate();
return [3 /*break*/, 8];
case 8:
if (!suspense)
setLoading(true);
// don't perform the request if there is no more data to fetch (pagination)
if (perPage > 0 && !hasMore.current && !error.current)
return [2 /*return*/, data.current];
if (!suspense)
setLoading(true);
timer = timeout && setTimeout(function () {

@@ -147,24 +126,29 @@ timedout.current = true;

}, timeout);
_k.label = 9;
case 9:
_k.trys.push([9, 22, 28, 29]);
return [4 /*yield*/, fetch(url, options)];
case 10:
newRes = _k.sent();
_h.label = 2;
case 2:
_h.trys.push([2, 17, 23, 24]);
if (!(response.isCached && cachePolicy === CACHE_FIRST)) return [3 /*break*/, 3];
newRes = response.cached;
return [3 /*break*/, 5];
case 3: return [4 /*yield*/, fetch(url, options)];
case 4:
newRes = _h.sent();
_h.label = 5;
case 5:
res.current = newRes.clone();
return [4 /*yield*/, utils_1.tryGetData(newRes, defaults.data, responseType)];
case 11:
newData = _k.sent();
case 6:
newData = _h.sent();
res.current.data = onNewData(data.current, newData);
_d = res;
if (!interceptors.response) return [3 /*break*/, 13];
_b = res;
if (!interceptors.response) return [3 /*break*/, 8];
return [4 /*yield*/, interceptors.response({ response: res.current })];
case 12:
_e = _k.sent();
return [3 /*break*/, 14];
case 13:
_e = res.current;
_k.label = 14;
case 14:
_d.current = _e;
case 7:
_c = _h.sent();
return [3 /*break*/, 9];
case 8:
_c = res.current;
_h.label = 9;
case 9:
_b.current = _c;
utils_1.invariant('data' in res.current, 'You must have `data` field on the Response returned from your `interceptors.response`');

@@ -175,68 +159,68 @@ data.current = res.current.data;

// automatically retry on fail until attempts run out
_f = !utils_1.isFunction(retryOn) && Array.isArray(retryOn) && retryOn.length < 1 && (newRes === null || newRes === void 0 ? void 0 : newRes.ok) === false
_d = !utils_1.isFunction(retryOn) && Array.isArray(retryOn) && retryOn.length < 1 && (newRes === null || newRes === void 0 ? void 0 : newRes.ok) === false
// otherwise only retry when is specified
|| Array.isArray(retryOn) && retryOn.includes(newRes.status);
if (_f)
if (_d)
// if we just have `retries` set with NO `retryOn` then
// automatically retry on fail until attempts run out
return [3 /*break*/, 17];
_g = utils_1.isFunction(retryOn);
if (!_g) return [3 /*break*/, 16];
return [3 /*break*/, 12];
_e = utils_1.isFunction(retryOn);
if (!_e) return [3 /*break*/, 11];
return [4 /*yield*/, retryOn(opts)];
case 15:
_g = (_k.sent());
_k.label = 16;
case 16:
_f = _g;
_k.label = 17;
case 17:
shouldRetry = (_f) && retries > 0 && retries > attempt.current;
if (!shouldRetry) return [3 /*break*/, 19];
case 10:
_e = (_h.sent());
_h.label = 11;
case 11:
_d = _e;
_h.label = 12;
case 12:
shouldRetry = (_d) && retries > 0 && retries > attempt.current;
if (!shouldRetry) return [3 /*break*/, 14];
return [4 /*yield*/, retry(opts, routeOrBody, body)];
case 18:
theData = _k.sent();
case 13:
theData = _h.sent();
return [2 /*return*/, theData];
case 19:
if (!(cachePolicy === CACHE_FIRST)) return [3 /*break*/, 21];
case 14:
if (!(cachePolicy === CACHE_FIRST)) return [3 /*break*/, 16];
return [4 /*yield*/, cache.set(response.id, newRes.clone())];
case 20:
_k.sent();
_k.label = 21;
case 21:
case 15:
_h.sent();
_h.label = 16;
case 16:
if (Array.isArray(data.current) && !!(data.current.length % perPage))
hasMore.current = false;
return [3 /*break*/, 29];
case 22:
err_2 = _k.sent();
return [3 /*break*/, 24];
case 17:
err_1 = _h.sent();
if (attempt.current >= retries && timedout.current)
error.current = utils_1.makeError('AbortError', 'Timeout Error');
opts = { attempt: attempt.current, error: err_2 };
opts = { attempt: attempt.current, error: err_1 };
// if we just have `retries` set with NO `retryOn` then
// automatically retry on fail until attempts run out
_h = !utils_1.isFunction(retryOn) && Array.isArray(retryOn) && retryOn.length < 1;
if (_h)
_f = !utils_1.isFunction(retryOn) && Array.isArray(retryOn) && retryOn.length < 1;
if (_f)
// if we just have `retries` set with NO `retryOn` then
// automatically retry on fail until attempts run out
return [3 /*break*/, 25];
_j = utils_1.isFunction(retryOn);
if (!_j) return [3 /*break*/, 24];
return [3 /*break*/, 20];
_g = utils_1.isFunction(retryOn);
if (!_g) return [3 /*break*/, 19];
return [4 /*yield*/, retryOn(opts)];
case 23:
_j = (_k.sent());
_k.label = 24;
case 24:
_h = _j;
_k.label = 25;
case 25:
shouldRetry = (_h) && retries > 0 && retries > attempt.current;
if (!shouldRetry) return [3 /*break*/, 27];
case 18:
_g = (_h.sent());
_h.label = 19;
case 19:
_f = _g;
_h.label = 20;
case 20:
shouldRetry = (_f) && retries > 0 && retries > attempt.current;
if (!shouldRetry) return [3 /*break*/, 22];
return [4 /*yield*/, retry(opts, routeOrBody, body)];
case 26:
theData = _k.sent();
case 21:
theData = _h.sent();
return [2 /*return*/, theData];
case 27:
if (err_2.name !== 'AbortError')
error.current = utils_1.makeError(err_2.name, err_2.message);
return [3 /*break*/, 29];
case 28:
case 22:
if (err_1.name !== 'AbortError')
error.current = utils_1.makeError(err_1.name, err_1.message);
return [3 /*break*/, 24];
case 23:
timedout.current = false;

@@ -247,3 +231,3 @@ if (timer)

return [7 /*endfinally*/];
case 29:
case 24:
if (newRes && !newRes.ok && !error.current)

@@ -311,3 +295,3 @@ error.current = utils_1.makeError(newRes.status, newRes.statusText);

return doFetch;
}, [isServer, onAbort, requestInit, initialURL, path, interceptors, cachePolicy, perPage, timeout, persist, cacheLife, onTimeout, defaults.data, onNewData, forceUpdate, suspense]);
}, [isServer, onAbort, requestInit, host, path, interceptors, cachePolicy, perPage, timeout, persist, cacheLife, onTimeout, defaults.data, onNewData, forceUpdate, suspense]);
var post = react_1.useCallback(makeFetch(types_1.HTTPMethod.POST), [makeFetch]);

@@ -314,0 +298,0 @@ var del = react_1.useCallback(makeFetch(types_1.HTTPMethod.DELETE), [makeFetch]);

@@ -1,2 +0,2 @@

import { OptionsMaybeURL, NoUrlOptions, OverwriteGlobalOptions, UseFetchArgsReturn } from './types';
export default function useFetchArgs(urlOrOptionsOrOverwriteGlobal?: string | OptionsMaybeURL | OverwriteGlobalOptions, optionsNoURLsOrOverwriteGlobalOrDeps?: NoUrlOptions | OverwriteGlobalOptions | any[], deps?: any[]): UseFetchArgsReturn;
import { OverwriteGlobalOptions, IncomingOptions, UseFetchArgsReturn } from './types';
export default function useFetchArgs(urlOrPathOrOptionsOrOverwriteGlobalOptions?: string | IncomingOptions | OverwriteGlobalOptions, optionsOrOverwriteGlobalOrDeps?: IncomingOptions | OverwriteGlobalOptions | any[], deps?: any[]): UseFetchArgsReturn;

@@ -16,2 +16,9 @@ "use strict";

};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });

@@ -21,126 +28,75 @@ var utils_1 = require("./utils");

var FetchContext_1 = __importDefault(require("./FetchContext"));
var defaults_1 = __importDefault(require("./defaults"));
var useField = function (field, urlOrOptions, optionsNoURLs) {
var defaults_1 = __importStar(require("./defaults"));
function useFetchArgs(urlOrPathOrOptionsOrOverwriteGlobalOptions, optionsOrOverwriteGlobalOrDeps, deps) {
utils_1.invariant(!(utils_1.isObject(urlOrPathOrOptionsOrOverwriteGlobalOptions) && utils_1.isObject(optionsOrOverwriteGlobalOrDeps)), 'You cannot have a 2nd parameter of useFetch as object when your first argument is an object.');
var context = react_1.useContext(FetchContext_1.default);
var contextOptions = context.options || {};
return react_1.useMemo(function () {
if (utils_1.isObject(urlOrOptions) && field in urlOrOptions)
return urlOrOptions[field];
if (utils_1.isObject(optionsNoURLs) && field in optionsNoURLs) {
return optionsNoURLs[field];
}
if (field in contextOptions)
return contextOptions[field];
return defaults_1.default[field];
}, [urlOrOptions, field, optionsNoURLs, contextOptions]);
};
function useFetchArgs(urlOrOptionsOrOverwriteGlobal, optionsNoURLsOrOverwriteGlobalOrDeps, deps) {
var context = react_1.useContext(FetchContext_1.default);
context.options = react_1.useMemo(function () {
var overwriteGlobalOptions = (utils_1.isFunction(urlOrOptionsOrOverwriteGlobal) ? urlOrOptionsOrOverwriteGlobal : utils_1.isFunction(optionsNoURLsOrOverwriteGlobalOrDeps) && optionsNoURLsOrOverwriteGlobalOrDeps);
if (!overwriteGlobalOptions)
return context.options;
// make a copy so we make sure not to modify the original context
return overwriteGlobalOptions(__assign({}, context.options));
}, [context.options, optionsNoURLsOrOverwriteGlobalOrDeps, urlOrOptionsOrOverwriteGlobal]);
var urlOrOptions = urlOrOptionsOrOverwriteGlobal;
var optionsNoURLs = optionsNoURLsOrOverwriteGlobalOrDeps;
utils_1.invariant(!(utils_1.isObject(urlOrOptions) && utils_1.isObject(optionsNoURLs)), 'You cannot have a 2nd parameter of useFetch when your first argument is an object config.');
var url = react_1.useMemo(function () {
if (utils_1.isString(urlOrOptions) && urlOrOptions)
return urlOrOptions;
if (utils_1.isObject(urlOrOptions) && !!urlOrOptions.url)
return urlOrOptions.url;
var host = react_1.useMemo(function () {
var maybeHost = urlOrPathOrOptionsOrOverwriteGlobalOptions;
if (utils_1.isString(maybeHost) && maybeHost.includes('://'))
return maybeHost;
if (context.url)
return context.url;
return defaults_1.default.url;
}, [context.url, urlOrOptions]);
utils_1.invariant(!!url, 'The first argument of useFetch is required unless you have a global url setup like: <Provider url="https://example.com"></Provider>');
return defaults_1.default.host;
}, [context.url, urlOrPathOrOptionsOrOverwriteGlobalOptions]);
var path = react_1.useMemo(function () {
var maybePath = urlOrPathOrOptionsOrOverwriteGlobalOptions;
if (utils_1.isString(maybePath) && !maybePath.includes('://'))
return maybePath;
}, [urlOrPathOrOptionsOrOverwriteGlobalOptions]);
var overwriteGlobalOptions = react_1.useMemo(function () {
if (utils_1.isFunction(urlOrPathOrOptionsOrOverwriteGlobalOptions))
return urlOrPathOrOptionsOrOverwriteGlobalOptions;
if (utils_1.isFunction(optionsOrOverwriteGlobalOrDeps))
return optionsOrOverwriteGlobalOrDeps;
}, []);
var options = react_1.useMemo(function () {
var localOptions = { headers: {} };
if (utils_1.isObject(urlOrPathOrOptionsOrOverwriteGlobalOptions)) {
localOptions = urlOrPathOrOptionsOrOverwriteGlobalOptions;
}
else if (utils_1.isObject(optionsOrOverwriteGlobalOrDeps)) {
localOptions = optionsOrOverwriteGlobalOrDeps;
}
var globalOptions = context.options;
var finalOptions = __assign(__assign(__assign(__assign({}, defaults_1.default), globalOptions), localOptions), { headers: __assign(__assign(__assign({}, defaults_1.default.headers), globalOptions.headers), localOptions.headers) });
if (overwriteGlobalOptions)
return overwriteGlobalOptions(finalOptions);
return finalOptions;
}, [urlOrPathOrOptionsOrOverwriteGlobalOptions, overwriteGlobalOptions, context.options]);
var requestInit = react_1.useMemo(function () { return utils_1.pullOutRequestInit(options); }, [options]);
var dependencies = react_1.useMemo(function () {
if (Array.isArray(optionsNoURLsOrOverwriteGlobalOrDeps))
return optionsNoURLsOrOverwriteGlobalOrDeps;
if (Array.isArray(optionsOrOverwriteGlobalOrDeps))
return optionsOrOverwriteGlobalOrDeps;
if (Array.isArray(deps))
return deps;
return defaults_1.default.dependencies;
}, [optionsNoURLsOrOverwriteGlobalOrDeps, deps]);
var data = useField('data', urlOrOptions, optionsNoURLs);
var cacheLife = useField('cacheLife', urlOrOptions, optionsNoURLs);
}, [optionsOrOverwriteGlobalOrDeps, deps]);
var cacheLife = options.cacheLife, retries = options.retries, retryDelay = options.retryDelay, retryOn = options.retryOn;
utils_1.invariant(Number.isInteger(cacheLife) && cacheLife >= 0, '`cacheLife` must be a number >= 0');
var cachePolicy = useField('cachePolicy', urlOrOptions, optionsNoURLs);
var onAbort = useField('onAbort', urlOrOptions, optionsNoURLs);
var onError = useField('onError', urlOrOptions, optionsNoURLs);
var onNewData = useField('onNewData', urlOrOptions, optionsNoURLs);
var onTimeout = useField('onTimeout', urlOrOptions, optionsNoURLs);
var path = useField('path', urlOrOptions, optionsNoURLs);
var perPage = useField('perPage', urlOrOptions, optionsNoURLs);
var persist = useField('persist', urlOrOptions, optionsNoURLs);
var responseType = useField('responseType', urlOrOptions, optionsNoURLs);
var retries = useField('retries', urlOrOptions, optionsNoURLs);
utils_1.invariant(Number.isInteger(retries) && retries >= 0, '`retries` must be a number >= 0');
var retryDelay = useField('retryDelay', urlOrOptions, optionsNoURLs);
utils_1.invariant(utils_1.isFunction(retryDelay) || Number.isInteger(retryDelay) && retryDelay >= 0, '`retryDelay` must be a positive number or a function returning a positive number.');
var retryOn = useField('retryOn', urlOrOptions, optionsNoURLs);
var isValidRetryOn = utils_1.isFunction(retryOn) || (Array.isArray(retryOn) && retryOn.every(utils_1.isPositiveNumber));
utils_1.invariant(isValidRetryOn, '`retryOn` must be an array of positive numbers or a function returning a boolean.');
var suspense = useField('suspense', urlOrOptions, optionsNoURLs);
var timeout = useField('timeout', urlOrOptions, optionsNoURLs);
var loading = react_1.useMemo(function () {
if (utils_1.isObject(urlOrOptions))
return !!urlOrOptions.loading || Array.isArray(dependencies);
if (utils_1.isObject(optionsNoURLs))
return !!optionsNoURLs.loading || Array.isArray(dependencies);
return defaults_1.default.loading || Array.isArray(dependencies);
}, [urlOrOptions, dependencies, optionsNoURLs]);
var loading = options.loading || Array.isArray(dependencies);
var interceptors = react_1.useMemo(function () {
var contextInterceptors = context.options && (context.options.interceptors || {});
var final = __assign({}, contextInterceptors);
if (utils_1.isObject(urlOrOptions) && utils_1.isObject(urlOrOptions.interceptors)) {
if (urlOrOptions.interceptors.request)
final.request = urlOrOptions.interceptors.request;
if (urlOrOptions.interceptors.response)
final.response = urlOrOptions.interceptors.response;
}
if (utils_1.isObject(optionsNoURLs) && utils_1.isObject(optionsNoURLs.interceptors)) {
if (optionsNoURLs.interceptors.request)
final.request = optionsNoURLs.interceptors.request;
if (optionsNoURLs.interceptors.response)
final.response = optionsNoURLs.interceptors.response;
}
var final = {};
if ('request' in options.interceptors)
final.request = options.interceptors.request;
if ('response' in options.interceptors)
final.response = options.interceptors.response;
return final;
}, [context.options, urlOrOptions, optionsNoURLs]);
var requestInit = react_1.useMemo(function () {
var contextRequestInit = utils_1.pullOutRequestInit(context.options);
var requestInitOptions = utils_1.isObject(urlOrOptions)
? urlOrOptions
: utils_1.isObject(optionsNoURLs)
? optionsNoURLs
: {};
var requestInit = utils_1.pullOutRequestInit(requestInitOptions);
return __assign(__assign(__assign({}, contextRequestInit), requestInit), { headers: __assign(__assign(__assign({}, defaults_1.default.headers), contextRequestInit.headers), requestInit.headers) });
}, [context.options, urlOrOptions, optionsNoURLs]);
}, [options]);
var customOptions = react_1.useMemo(function () {
var customOptionKeys = Object.keys(defaults_1.useFetchArgsDefaults.customOptions); // Array<keyof CustomOptions>
var customOptions = customOptionKeys.reduce(function (opts, key) {
opts[key] = options[key];
return opts;
}, {});
return __assign(__assign({}, customOptions), { interceptors: interceptors, loading: loading });
}, [interceptors, loading]);
return {
customOptions: {
cacheLife: cacheLife,
cachePolicy: cachePolicy,
interceptors: interceptors,
onAbort: onAbort,
onError: onError,
onNewData: onNewData,
onTimeout: onTimeout,
path: path,
persist: persist,
perPage: perPage,
responseType: responseType,
retries: retries,
retryDelay: retryDelay,
retryOn: retryOn,
suspense: suspense,
timeout: timeout,
url: url,
},
host: host,
path: path,
customOptions: customOptions,
requestInit: requestInit,
defaults: {
data: data,
loading: loading
},
dependencies: dependencies

@@ -147,0 +103,0 @@ };

import { MutableRefObject, DependencyList } from 'react';
import { OptionsMaybeURL, Res, HTTPMethod, ResponseType } from './types';
import { Options, Res, HTTPMethod, ResponseType } from './types';
import { FunctionKeys, NonFunctionKeys } from 'utility-types';

@@ -28,3 +28,3 @@ /**

*/
export declare const pullOutRequestInit: (options?: OptionsMaybeURL | undefined) => RequestInit;
export declare const pullOutRequestInit: (options?: Options | undefined) => RequestInit;
export declare const isEmpty: (x: any) => boolean;

@@ -68,2 +68,18 @@ export declare enum Device {

export declare const makeError: (name: string | number, message: string) => Error;
/**
* Determines if we need to add a slash to front
* of a path, and adds it if we do.
* Cases:
* (path = '', url = '' || null | undefined) => ''
* (path = '?foo=bar', url = 'a.com') => '?foo=bar'
* (path = '?foo=bar', url = 'a.com/') => '?foo=bar'
* (path = 'foo', url = 'a.com') => '/foo'
* (path = 'foo', url = 'a.com/') => 'foo'
* (path = '/foo', url = 'a.com') => '/foo'
* (path = '/foo', url = 'a.com/') => 'foo'
* (path = '?foo=bar') => '?foo=bar'
* (path = 'foo') => '/foo'
* (path = '/foo') => '/foo'
*/
export declare const addSlash: (input?: string | undefined, url?: string | undefined) => string;
export {};

@@ -183,15 +183,22 @@ "use strict";

}); };
var tryRetry = function (res, types) { return __awaiter(void 0, void 0, void 0, function () {
return __generator(this, function (_a) {
try {
return [2 /*return*/, res.clone()[types[0]]()];
}
catch (error) {
if (types.length === 1)
throw error;
return [2 /*return*/, tryRetry(res.clone(), types.slice(1))];
}
return [2 /*return*/];
var tryRetry = function (res, types, i) {
if (i === void 0) { i = 0; }
return __awaiter(void 0, void 0, void 0, function () {
var error_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
return [4 /*yield*/, res.clone()[types[i]]()];
case 1: return [2 /*return*/, _a.sent()];
case 2:
error_1 = _a.sent();
if (types.length - 1 === i)
throw error_1;
return [2 /*return*/, tryRetry(res.clone(), types, ++i)];
case 3: return [2 /*return*/];
}
});
});
}); };
};
exports.responseFields = ['headers', 'ok', 'redirected', 'trailer', 'status', 'statusText', 'type', 'url', 'body', 'bodyUsed', 'data'];

@@ -270,1 +277,30 @@ exports.responseMethods = ['clone', 'arrayBuffer', 'blob', 'formData', 'json', 'text'];

};
/**
* Determines if we need to add a slash to front
* of a path, and adds it if we do.
* Cases:
* (path = '', url = '' || null | undefined) => ''
* (path = '?foo=bar', url = 'a.com') => '?foo=bar'
* (path = '?foo=bar', url = 'a.com/') => '?foo=bar'
* (path = 'foo', url = 'a.com') => '/foo'
* (path = 'foo', url = 'a.com/') => 'foo'
* (path = '/foo', url = 'a.com') => '/foo'
* (path = '/foo', url = 'a.com/') => 'foo'
* (path = '?foo=bar') => '?foo=bar'
* (path = 'foo') => '/foo'
* (path = '/foo') => '/foo'
*/
exports.addSlash = function (input, url) {
if (!input)
return '';
if (!url) {
if (input.startsWith('?') || input.startsWith('/'))
return input;
return "/" + input;
}
if (url.endsWith('/') && input.startsWith('/'))
return input.substr(1);
if (!url.endsWith('/') && !input.startsWith('/') && !input.startsWith('?'))
return "/" + input;
return input;
};
{
"name": "use-http",
"version": "1.0.7",
"version": "1.0.8",
"homepage": "https://use-http.com",

@@ -5,0 +5,0 @@ "main": "dist/index.js",

@@ -12,3 +12,3 @@ [![use-http logo][3]][5]

<p align="center">
<a href="https://github.com/ava/use-http/pulls">
<a href="https://github.com/ava/use-http/blob/master/.github/contributing.md">
<img src="https://camo.githubusercontent.com/d4e0f63e9613ee474a7dfdc23c240b9795712c96/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5052732d77656c636f6d652d627269676874677265656e2e737667" />

@@ -93,3 +93,2 @@ </a>

- useFetch - managed state, request, response, etc. [![](https://img.shields.io/badge/example-blue.svg)](https://codesandbox.io/s/usefetch-request-response-managed-state-ruyi3?file=/src/index.js) [![](https://img.shields.io/badge/video-red.svg)](https://www.youtube.com/watch?v=_-GujYZFCKI&list=PLZIwrWkE9rCdUybd8t3tY-mUMvXkCdenW&index=6)
- useFetch - route, path, Provider, etc. [![](https://img.shields.io/badge/example-blue.svg)](https://codesandbox.io/s/usefetch-with-provider-c78w2) [![](https://img.shields.io/badge/video-red.svg)](https://www.youtube.com/watch?v=JWDL_AVOYT0&list=PLZIwrWkE9rCdUybd8t3tY-mUMvXkCdenW&index=10)
- useFetch - request/response interceptors [![](https://img.shields.io/badge/example-blue.svg)](https://codesandbox.io/s/usefetch-provider-requestresponse-interceptors-s1lex) [![](https://img.shields.io/badge/video-red.svg)](https://www.youtube.com/watch?v=3HauoWh0Jts&list=PLZIwrWkE9rCdUybd8t3tY-mUMvXkCdenW&index=8)

@@ -106,3 +105,3 @@ - useFetch - retries, retryOn, retryDelay [![](https://img.shields.io/badge/example-blue.svg)](https://codesandbox.io/s/usefetch-retryon-retrydelay-s74q9) [![](https://img.shields.io/badge/video-red.svg)](https://www.youtube.com/watch?v=grE3AX-Q9ss&list=PLZIwrWkE9rCdUybd8t3tY-mUMvXkCdenW&index=9)

<details open><summary><b>Basic Usage (managed state) <code>useFetch</code></b></summary>
<details open><summary><b>Basic Usage Managed State <code>useFetch</code></b></summary>

@@ -153,5 +152,5 @@ If the last argument of `useFetch` is not a dependency array `[]`, then it will not fire until you call one of the http methods like `get`, `post`, etc.

<details><summary><b>Basic Usage (auto managed state) <code>useFetch</code></b></summary>
<details open><summary><b>Basic Usage Auto-Managed State <code>useFetch</code></b></summary>
This fetch is run `onMount/componentDidMount`. The last argument `[]` means it will run `onMount`. If you pass it a variable like `[someVariable]`, it will run `onMount` and again whenever `someVariable` changes values (aka `onUpdate`). **If no method is specified, GET is the default**
This fetch is run `onMount/componentDidMount`. The last argument `[]` means it will run `onMount`. If you pass it a variable like `[someVariable]`, it will run `onMount` and again whenever `someVariable` changes values (aka `onUpdate`). If no method is specified, GET is the default.

@@ -162,8 +161,6 @@ ```js

function Todos() {
// accepts all `fetch` options
const options = {
data: [], // setting default for `data` as array instead of undefined
}
const { loading, error, data } = useFetch('https://example.com/todos', options, []) // onMount (GET by default)
const { loading, error, data } = useFetch('https://example.com/todos', {
// these options accept all native `fetch` options
data: [] // defaults the `data` to an array instead of `undefined`
}, []) // <- this [] means it will fire onMount (GET by default)

@@ -187,40 +184,4 @@ return (

<details open><summary><b>Suspense Mode<sup>(experimental)</sup> Auto-Managed State</b></summary>
<details open><summary><b>Basic Usage (auto managed state) with <code>Provider</code></b></summary>
```js
import useFetch, { Provider } from 'use-http'
function Todos() {
const { loading, error, data } = useFetch({
path: '/todos',
data: []
}, []) // onMount
return (
<>
{error && 'Error!'}
{loading && 'Loading...'}
{data.map(todo => (
<div key={todo.id}>{todo.title}</div>
)}
</>
)
}
const App = () => (
<Provider url='https://example.com'>
<Todos />
</Provider>
)
```
<!-- TODO: youtube -->
<a target="_blank" rel="noopener noreferrer" href='https://codesandbox.io/s/usefetch-provider-requestresponse-interceptors-s1lex?file=/src/index.js'><img width='150px' height='30px' src='https://codesandbox.io/static/img/play-codesandbox.svg' /></a>
<!-- <a target="_blank" rel="noopener noreferrer" href='XXXXXXX'><img width='150px' height='30px' src='https://github.com/ava/use-http/raw/master/public/watch-youtube-video.png' /></a> -->
</details>
<details open><summary><b>Suspense Mode (auto managed state)</b></summary>
Can put `suspense` in 2 places. Either `useFetch` (A) or `Provider` (B).

@@ -232,4 +193,3 @@

function Todos() {
const { data: todos } = useFetch({
path: '/todos',
const { data: todos } = useFetch('/todos', {
data: [],

@@ -260,5 +220,5 @@ suspense: true // A. can put `suspense: true` here

<details><summary><b>Suspense Mode (managed state)</b></summary>
<details><summary><b>Suspense Mode<sup>(experimental)</sup> Managed State</b></summary>
Can put `suspense` in 2 places. Either `useFetch` (A) or `Provider` (B).
Can put `suspense` in 2 places. Either `useFetch` (A) or `Provider` (B). Suspense mode via managed state is very experimental.

@@ -339,4 +299,3 @@ ```js

const { data, loading } = useFetch({
path: `/todos?page=${page}&amountPerPage=15`,
const { data, loading } = useFetch(`/todos?page=${page}&amountPerPage=15`, {
onNewData: (currTodos, newTodos) => [...currTodos, ...newTodos], // appends newly fetched todos

@@ -442,6 +401,3 @@ perPage: 15, // stops making more requests if last todos fetched < 15

⚠️ `baseUrl` is no longer supported, it is now only `url`
```jsx
var request = useFetch({ url: 'https://example.com' })
// OR
var request = useFetch('https://example.com')

@@ -464,13 +420,11 @@

```jsx
const githubRepos = useFetch({
url: `https://api.github.com/search/repositories?q=`
})
const { get, abort, loading, data: repos } = useFetch('https://api.github.com/search/repositories?q=')
// the line below is not isomorphic, but for simplicity we're using the browsers `encodeURI`
const searchGithubRepos = e => githubRepos.get(encodeURI(e.target.value))
const searchGithubRepos = e => get(encodeURI(e.target.value))
<>
<input onChange={searchGithubRepos} />
<button onClick={githubRepos.abort}>Abort</button>
{githubRepos.loading ? 'Loading...' : githubRepos.data.items.map(repo => (
<button onClick={abort}>Abort</button>
{loading ? 'Loading...' : repos.data.items.map(repo => (
<div key={repo.id}>{repo.name}</div>

@@ -867,3 +821,2 @@ ))}

| `onTimeout` | Called when the request times out. | empty function |
| `path` | When using a global `url` set in the `Provider`, this is useful for adding onto it | `''` |
| `persist` | Persists data for the duration of `cacheLife`. If `cacheLife` is not set it defaults to 24h. Currently only available in Browser. | `false` |

@@ -877,3 +830,2 @@ | `perPage` | Stops making more requests if there is no more data to fetch. (i.e. if we have 25 todos, and the perPage is 10, after fetching 2 times, we will have 20 todos. The last 5 tells us we don't have any more to fetch because it's less than 10) For pagination. | `0` |

| `timeout` | The request will be aborted/cancelled after this amount of time. This is also the interval at which `retries` will be made at. **in milliseconds**. If set to `0`, it will not timeout except for browser defaults. | `0` |
| `url` | Allows you to set a base path so relative paths can be used for each request :) | empty string |

@@ -922,5 +874,2 @@ ```jsx

// if you have a global `url` set up, this is how you can add to it
path: '/path/to/your/api',
// this will tell useFetch not to run the request if the list doesn't haveMore. (pagination)

@@ -974,5 +923,2 @@ // i.e. if the last page fetched was < 15, don't run the request again

timeout: 10000,
// used to be `baseUrl`. You can set your URL this way instead of as the 1st argument
url: 'https://example.com',
}

@@ -1019,2 +965,5 @@

- [ ] prefetching
- [ ] global cache state management
- [ ] optimistic updates
- [ ] `persist` support for React Native

@@ -1021,0 +970,0 @@ - [ ] better loading state management. When using only 1 useFetch in a component and we use

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc