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 0.1.82 to 0.1.83

4

dist/makeRouteAndOptions.d.ts

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

import { HTTPMethod } from './types';
import { HTTPMethod, Interceptors, ValueOf } from './types';
import { MutableRefObject } from 'react';

@@ -7,3 +7,3 @@ interface RouteAndOptions {

}
export default function makeRouteAndOptions(initialOptions: RequestInit, method: HTTPMethod, controller: MutableRefObject<AbortController | null | undefined>, routeOrBody?: string | BodyInit | object, bodyAs2ndParam?: BodyInit | object): RouteAndOptions;
export default function makeRouteAndOptions(initialOptions: RequestInit, method: HTTPMethod, controller: MutableRefObject<AbortController | null | undefined>, routeOrBody?: string | BodyInit | object, bodyAs2ndParam?: BodyInit | object, requestInterceptor?: ValueOf<Pick<Interceptors, 'request'>>): Promise<RouteAndOptions>;
export {};
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });

@@ -6,46 +15,50 @@ const types_1 = require("./types");

const { GET, OPTIONS } = types_1.HTTPMethod;
function makeRouteAndOptions(initialOptions, method, controller, routeOrBody, bodyAs2ndParam) {
utils_1.invariant(!(utils_1.isObject(routeOrBody) && utils_1.isObject(bodyAs2ndParam)), `If first argument of ${method.toLowerCase()}() is an object, you cannot have a 2nd argument. 😜`);
utils_1.invariant(!(method === GET && utils_1.isObject(routeOrBody)), `You can only have query params as 1st argument of request.get()`);
utils_1.invariant(!(method === GET && bodyAs2ndParam !== undefined), `You can only have query params as 1st argument of request.get()`);
const route = (() => {
if (utils_1.isBrowser && routeOrBody instanceof URLSearchParams)
return `?${routeOrBody}`;
if (utils_1.isString(routeOrBody))
return routeOrBody;
return '';
})();
const body = (() => {
if (utils_1.isObject(routeOrBody))
return JSON.stringify(routeOrBody);
if (utils_1.isObject(bodyAs2ndParam))
return JSON.stringify(bodyAs2ndParam);
if (utils_1.isBrowser &&
(bodyAs2ndParam instanceof FormData ||
bodyAs2ndParam instanceof URLSearchParams))
return bodyAs2ndParam;
return JSON.stringify({});
})();
const options = (() => {
const opts = Object.assign(Object.assign({}, initialOptions), { body,
method, signal: controller.current ? controller.current.signal : null, headers: Object.assign({
// default content types http://bit.ly/2N2ovOZ
// Accept: 'application/json',
'Content-Type': 'application/json' }, initialOptions.headers) });
if (utils_1.isBrowser &&
(routeOrBody instanceof URLSearchParams ||
routeOrBody instanceof FormData ||
bodyAs2ndParam instanceof FormData)) {
delete opts.headers['Content-Type'];
}
if (method === GET || method === OPTIONS)
delete opts.body;
return opts;
})();
return {
route,
options,
};
function makeRouteAndOptions(initialOptions, method, controller, routeOrBody, bodyAs2ndParam, requestInterceptor) {
return __awaiter(this, void 0, void 0, function* () {
utils_1.invariant(!(utils_1.isObject(routeOrBody) && utils_1.isObject(bodyAs2ndParam)), `If first argument of ${method.toLowerCase()}() is an object, you cannot have a 2nd argument. 😜`);
utils_1.invariant(!(method === GET && utils_1.isObject(routeOrBody)), `You can only have query params as 1st argument of request.get()`);
utils_1.invariant(!(method === GET && bodyAs2ndParam !== undefined), `You can only have query params as 1st argument of request.get()`);
const route = (() => {
if (utils_1.isBrowser && routeOrBody instanceof URLSearchParams)
return `?${routeOrBody}`;
if (utils_1.isString(routeOrBody))
return routeOrBody;
return '';
})();
const body = (() => {
if (utils_1.isObject(routeOrBody))
return JSON.stringify(routeOrBody);
if (utils_1.isObject(bodyAs2ndParam))
return JSON.stringify(bodyAs2ndParam);
if (utils_1.isBrowser &&
(bodyAs2ndParam instanceof FormData ||
bodyAs2ndParam instanceof URLSearchParams))
return bodyAs2ndParam;
return JSON.stringify({});
})();
const options = yield (() => __awaiter(this, void 0, void 0, function* () {
const opts = Object.assign(Object.assign({}, initialOptions), { body,
method, signal: controller.current ? controller.current.signal : null, headers: Object.assign({
// default content types http://bit.ly/2N2ovOZ
// Accept: 'application/json',
'Content-Type': 'application/json' }, initialOptions.headers) });
if (utils_1.isBrowser &&
(routeOrBody instanceof URLSearchParams ||
routeOrBody instanceof FormData ||
bodyAs2ndParam instanceof FormData)) {
delete opts.headers['Content-Type'];
}
if (method === GET || method === OPTIONS)
delete opts.body;
if (requestInterceptor)
return yield requestInterceptor(opts);
return opts;
}))();
return {
route,
options,
};
});
}
exports.default = makeRouteAndOptions;
//# sourceMappingURL=makeRouteAndOptions.js.map

@@ -12,3 +12,3 @@ export declare enum HTTPMethod {

url?: string;
options?: RequestInit | undefined;
options?: Options | undefined;
graphql?: boolean;

@@ -56,2 +56,6 @@ }

export declare type UseFetch<TData> = UseFetchArrayReturn<TData> & UseFetchObjectReturn<TData>;
export declare type Interceptors = {
request?: (options: Options) => Options;
response?: (response: Res<any>) => any;
};
export interface CustomOptions {

@@ -61,5 +65,6 @@ onMount?: boolean;

path?: string;
url: string;
url?: string;
loading?: boolean;
data?: any;
interceptors?: Interceptors;
}

@@ -74,1 +79,2 @@ export declare type Options = CustomOptions & Omit<RequestInit, 'body'> & {

export declare type OptionsOverwriteWithContext = (options: Options) => Options;
export declare type ValueOf<T> = T[keyof T];

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

import { OptionsMaybeURL, NoUrlOptions, CustomOptions } from './types';
import { OptionsMaybeURL, NoUrlOptions, Interceptors } from './types';
declare type UseCustomOptions = {
onMount: boolean;
path: string;
url: string;
loading: boolean;
data?: any;
interceptors: Interceptors;
};
/**

@@ -11,2 +19,3 @@ * Handles all special options.

*/
export default function useCustomOptions(urlOrOptions?: string | OptionsMaybeURL, optionsNoURLs?: NoUrlOptions): CustomOptions;
export default function useCustomOptions(urlOrOptions?: string | OptionsMaybeURL, optionsNoURLs?: NoUrlOptions): UseCustomOptions;
export {};

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

const FetchContext_1 = __importDefault(require("./FetchContext"));
// Provider ex: useFetch({ url: 'https://url.com' }) -- (overwrites global url)
// TODO - Provider: arg1 = oldGlobalOptions => ({ my: 'new local options'}) (overwrite all global options for this instance of useFetch)
/**

@@ -24,2 +22,3 @@ * Handles all special options.

const context = react_1.useContext(FetchContext_1.default);
const contextInterceptors = context.options && context.options.interceptors || {};
const { isServer } = use_ssr_1.default();

@@ -66,5 +65,21 @@ 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.');

}, [urlOrOptions, optionsNoURLs]);
return { url, onMount, loading, data, path };
const interceptors = react_1.useMemo(() => {
const final = Object.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;
}
return final;
}, [urlOrOptions, optionsNoURLs]);
return { url, onMount, loading, data, path, interceptors };
}
exports.default = useCustomOptions;
//# sourceMappingURL=useCustomOptions.js.map

@@ -32,2 +32,3 @@ "use strict";

const makeRouteAndOptions_1 = __importDefault(require("./makeRouteAndOptions"));
const utils_1 = require("./utils");
// No <Provider url='example.com' />

@@ -42,3 +43,3 @@ // function useFetch<TData = any>(url: string, options?: NoUrlOptions): UseFetch<TData>

function useFetch(...args) {
const _a = useCustomOptions_1.default(...args), { url, onMount, path } = _a, defaults = __rest(_a, ["url", "onMount", "path"]);
const _a = useCustomOptions_1.default(...args), { url, onMount, path, interceptors } = _a, defaults = __rest(_a, ["url", "onMount", "path", "interceptors"]);
const requestInit = useRequestInit_1.default(...args);

@@ -54,7 +55,8 @@ const { isBrowser, isServer } = use_ssr_1.default();

controller.current = isBrowser ? new AbortController() : null;
const { route, options } = makeRouteAndOptions_1.default(requestInit, method, controller, routeOrBody, body);
setLoading(true);
if (error)
setError(undefined);
let { route, options } = yield makeRouteAndOptions_1.default(requestInit, method, controller, routeOrBody, body, interceptors.request);
let theData;
try {
setLoading(true);
if (error)
setError(undefined);
if (isServer)

@@ -64,6 +66,6 @@ return; // TODO: for now, we don't do anything on the server

try {
data.current = yield res.current.json();
theData = yield res.current.json();
}
catch (err) {
data.current = (yield res.current.text()); // FIXME: should not be `any` type
theData = (yield res.current.text()); // FIXME: should not be `any` type
}

@@ -76,2 +78,3 @@ }

finally {
data.current = (defaults.data && utils_1.isEmpty(theData)) ? defaults.data : theData;
controller.current = null;

@@ -101,3 +104,4 @@ setLoading(false);

};
const response = Object.assign({ data: data.current }, res.current);
const responseObj = Object.assign({ data: data.current }, res.current);
const response = interceptors.response ? interceptors.response(responseObj) : responseObj;
// handling onMount

@@ -104,0 +108,0 @@ const mounted = react_1.useRef(false);

@@ -11,2 +11,3 @@ "use strict";

const context = react_1.useContext(FetchContext_1.default);
const contextRequestInit = utils_1.pullOutRequestInit(context.options);
const requestInitOptions = utils_1.isObject(urlOrOptions)

@@ -18,8 +19,8 @@ ? urlOrOptions

const requestInit = utils_1.pullOutRequestInit(requestInitOptions);
return Object.assign(Object.assign(Object.assign({}, context.options), requestInit), { headers: Object.assign(Object.assign({
return Object.assign(Object.assign(Object.assign({}, contextRequestInit), requestInit), { headers: Object.assign(Object.assign({
// default content types http://bit.ly/2N2ovOZ
// Accept: 'application/json',
'Content-Type': 'application/json' }, (context.options || {}).headers), requestInit.headers) });
'Content-Type': 'application/json' }, contextRequestInit.headers), requestInit.headers) });
}
exports.default = useRequestInit;
//# sourceMappingURL=useRequestInit.js.map

@@ -19,3 +19,4 @@ import { OptionsMaybeURL } from './types';

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

@@ -82,2 +82,3 @@ "use strict";

};
exports.isEmpty = (x) => x === undefined || x === null;
exports.isBrowser = !!(typeof window !== 'undefined' &&

@@ -84,0 +85,0 @@ window.document &&

{
"name": "use-http",
"version": "0.1.82",
"version": "0.1.83",
"homepage": "http://use-http.com",

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

@@ -74,2 +74,3 @@ <a href="http://use-http.com">

- Provider to set default `url` and `options`
- Request/response interceptors <!--https://github.com/alex-cory/use-http#user-content-interceptors-->

@@ -157,3 +158,3 @@ Usage

<details open><summary>Basic Usage with <code>Provider</code></summary>
<details open><summary><b>Basic Usage with <code>Provider</code></b></summary>

@@ -430,2 +431,36 @@ ```js

<details id='interceptors'><summary><b>Request/Response Interceptors</b></summary>
This example shows how we can do authentication in the `request` interceptor and how we can camelCase the results in the `response` interceptor
```jsx
import { Provider } from 'use-http'
import camelCase from 'camelcase-keys-recursive'
function App() {
let [token] = useLocalStorage('token')
const options = {
interceptors: {
// every time we make an http request, this will run 1st before the request is made
request: async (options) => {
if (isExpired(token)) token = await getNewToken()
options.headers.Authorization = `Bearer ${token}`
return options
},
// every time we make an http request, before getting the response back, this will run
response: (response) => camelCase(response)
}
}
return (
<Provider url='http://example.com' options={options}>
<SomeComponent />
<Provider/>
)
}
```
</details>
Overview

@@ -455,2 +490,4 @@ --------

| `loading` | Allows you to set default value for `loading` | `false` unless `onMount === true` |
| `interceptors.request` | Allows you to do something before an http request is sent out. Useful for authentication if you need to refresh tokens a lot. | `undefined` |
| `interceptors.response` | Allows you to do something after an http response is recieved. Useful for something like camelCasing the keys of the response. | `undefined` |

@@ -460,6 +497,14 @@ ```jsx

// accepts all `fetch` options such as headers, method, etc.
url: 'https://example.com', // used to be `baseUrl`
url: 'https://example.com', // used to be `baseUrl`
onMount: true,
data: [], // default for `data` field
loading: false, // default for `loading` field
data: [], // default for `data` field
loading: false, // default for `loading` field
interceptors: { // typically, `interceptors` would be added as an option to the `<Provider />`
request: async (options) => { // `async` is not required
return options // returning the `options` is important
},
response: (response) => {
return response // returning the `response` is important
}
}
})

@@ -487,46 +532,2 @@ ```

- [ ] show comparison with Apollo
- [ ] Interceptors (potential syntax example) this shows how to get access tokens on each request if an access token or refresh token is expired
```jsx
const App = () => {
const { get } = useFetch('https://example.com')
const [accessToken, setAccessToken] = useLocalStorage('access-token')
const [refreshToken, setRefreshToken] = useLocalStorage('refresh-token')
const { history } = useReactRouter()
const options = {
interceptors: {
async request(opts) {
let headers = {}
// refresh token expires in 1 day, used to get access token
if (!refreshToken || isExpired(refreshToken)) {
return history.push('/login')
}
// access token expires every 15 minutes, use refresh token to get new access token
if (!accessToken || isExpired(accessToken)) {
const access = await get(`/access-token?refreshToken=${refreshToken}`)
setAccessToken(access)
headers = {
Authorization: `Bearer ${access}`,
}
}
const finalOptions = {
...opts,
headers: {
...opts.headers,
...headers,
},
}
return finalOptions
},
},
headers: {
Authorization: `Bearer ${accessToken}`
}
}
return (
<Provider url='https://example.com' options={options}>
<App />
</Provider>
)
}
```
- [ ] Dedupe requests done to the same endpoint. Only one request to the same endpoint will be initiated. [ref](https://www.npmjs.com/package/@bjornagh/use-fetch)

@@ -556,3 +557,2 @@ - [ ] Cache responses to improve speed and reduce amount of requests

onUpdate: [props.id] // everytime props.id is updated, it will re-run the request GET in this case
path: '/todos' // this would allow you to POST and GET to the same path onMount and on demand if you had a url in context
retry: 3, // amount of times it should retry before erroring out

@@ -564,10 +564,2 @@ retryDuration: 1000, // amount of time for each retry before timing out?

mutation: `some graphql mutation` // if you would prefer to pass the mutation in the config
interceptors: {
request(opts) { // i.e. if you need to do some kind of authentication before a request
return opts
}
response(res) { // i.e. if you want to camelCase all fields in a response everytime
return res
}
}
})

@@ -574,0 +566,0 @@ ```

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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