Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@alwatr/fetch

Package Overview
Dependencies
Maintainers
1
Versions
79
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@alwatr/fetch - npm Package Compare versions

Comparing version 0.16.0 to 0.17.0

16

CHANGELOG.md

@@ -6,10 +6,22 @@ # Change Log

# [0.16.0](https://github.com/AliMD/alwatr/compare/v0.15.0...v0.16.0) (2022-09-08)
# [0.17.0](https://github.com/AliMD/alwatr/compare/v0.16.1...v0.17.0) (2022-10-21)
**Note:** Version bump only for package @alwatr/fetch
### Bug Fixes
- **fetch:** not ok retry condition ([0da1edd](https://github.com/AliMD/alwatr/commit/0da1edda64ec5abf70a83361d159e207691e368e))
### Features
- **fetch:** docs & pattern ([459ad1c](https://github.com/AliMD/alwatr/commit/459ad1c5996f851769306639136d79c0f7270770))
- **fetch:** logger & jsdocs ([36f652d](https://github.com/AliMD/alwatr/commit/36f652d5dad23b2aeb824af77d1b0e442119c6e8))
- **fetch:** retry pattern ([5350d1a](https://github.com/AliMD/alwatr/commit/5350d1a81b9134d598f46006a1baa880b280ea98))
### Performance Improvements
- **fetch:** syntax ([1fdd02e](https://github.com/AliMD/alwatr/commit/1fdd02ec8b52e32a124b8d7c1d1c7fd7c993e3af))
# [0.16.0](https://github.com/AliMD/alwatr/compare/v0.15.0...v0.16.0) (2022-09-08)
**Note:** Version bump only for package @alwatr/fetch
# [0.15.0](https://github.com/AliMD/alwatr/compare/v0.14.0...v0.15.0) (2022-09-01)

@@ -16,0 +28,0 @@

52

fetch.d.ts

@@ -8,31 +8,47 @@ declare global {

/**
* @default 10_000 ms
* A timeout for the fetch request.
*
* @default 5000 ms
*/
timeout?: number;
bodyObject?: Record<string | number, unknown>;
/**
* If fetch response not acceptable or timed out, it will retry the request.
*
* @default 3
*/
retry?: number;
bodyJson?: Record<string | number, unknown>;
queryParameters?: Record<string, string | number | boolean>;
}
/**
* Enhanced base fetch API.
* @example const response = await fetch(url, {jsonResponse: false});
* It's a wrapper around the browser's `fetch` function that adds retry pattern with timeout
*
* Example:
*
* ```ts
* const response = await fetch(url, {timeout: 5_000, bodyJson: {a: 1, b: 2}});
* ```
*/
export declare function fetch(url: string, options?: FetchOptions): Promise<Response>;
/**
* Enhanced get data.
* @example
* const response = await postData('/api/products', {limit: 10}, {timeout: 5_000});
* It fetches a JSON file from a URL, and returns the JSON data
*
* Example:
*
* ```ts
* const productList = await getJson<ProductResponse>('/api/products', {queryParameters: {limit: 10}, timeout: 5_000});
* ```
*/
export declare function getData(url: string, queryParameters?: Record<string | number, string | number | boolean>, options?: FetchOptions): Promise<Response>;
export declare function getJson<ResponseType extends Record<string | number, unknown>>(url: string, options?: FetchOptions): Promise<ResponseType>;
/**
* Enhanced fetch JSON.
* @example
* const productList = await getJson('/api/products', {limit: 10}, {timeout: 5_000});
* It takes a URL, a JSON object, and an optional FetchOptions object, and returns a Promise of a
* Response object
*
* Example:
*
* ```ts
* const response = await postJson('/api/product/new', {name: 'foo', ...});
* ```
*/
export declare function getJson<ResponseType extends Record<string | number, unknown>>(url: string, queryParameters?: Record<string | number, string | number | boolean>, options?: FetchOptions): Promise<ResponseType>;
/**
* Enhanced post json data.
* @example
* const response = await postData('/api/product/new', {name: 'foo', ...});
*/
export declare function postData(url: string, body: Record<string | number, unknown>, options?: FetchOptions): Promise<Response>;
export declare function postJson(url: string, bodyJson: Record<string | number, unknown>, options?: FetchOptions): Promise<Response>;
//# sourceMappingURL=fetch.d.ts.map

@@ -8,18 +8,21 @@ import { createLogger, alwatrRegisteredList } from '@alwatr/logger';

/**
* Enhanced base fetch API.
* @example const response = await fetch(url, {jsonResponse: false});
* It's a wrapper around the browser's `fetch` function that adds retry pattern with timeout
*
* Example:
*
* ```ts
* const response = await fetch(url, {timeout: 5_000, bodyJson: {a: 1, b: 2}});
* ```
*/
export function fetch(url, options) {
export function fetch(url, options = {}) {
logger.logMethodArgs('fetch', { url, options });
if (!navigator.onLine) {
logger.accident('fetch', 'abort_signal', 'abort signal received', { url });
throw new Error('fetch_offline');
}
options = {
method: 'GET',
timeout: 15000,
window: null,
...options,
};
if (options.queryParameters != null) {
// if (!navigator.onLine) {
// logger.accident('fetch', 'abort_signal', 'abort signal received', {url});
// throw new Error('fetch_offline');
// }
options.method ?? (options.method = 'GET');
options.timeout ?? (options.timeout = 5000);
options.retry ?? (options.retry = 3);
options.window ?? (options.window = null);
if (url.lastIndexOf('?') === -1 && options.queryParameters != null) {
// prettier-ignore

@@ -34,4 +37,4 @@ const queryArray = Object

}
if (options.bodyObject != null) {
options.body = JSON.stringify(options.bodyObject);
if (options.body != null && options.bodyJson != null) {
options.body = JSON.stringify(options.bodyJson);
options.headers = {

@@ -45,2 +48,8 @@ ...options.headers,

const externalAbortSignal = options.signal;
options.signal = abortController.signal;
let timedOut = false;
const timeoutId = setTimeout(() => {
abortController.abort('fetch_timeout');
timedOut = true;
}, options.timeout);
if (externalAbortSignal != null) {

@@ -50,2 +59,3 @@ // Respect external abort signal

abortController.abort(`external abort signal: ${externalAbortSignal.reason}`);
clearTimeout(timeoutId);
});

@@ -59,44 +69,86 @@ }

});
options.signal = abortController.signal;
const timeoutId = setTimeout(() => abortController.abort('fetch_timeout'), options.timeout);
// @TODO: browser fetch polyfill
const response = window.fetch(url, options);
response.then(() => clearTimeout(timeoutId));
return response;
}
/**
* Enhanced get data.
* @example
* const response = await postData('/api/products', {limit: 10}, {timeout: 5_000});
*/
export function getData(url, queryParameters, options) {
logger.logMethodArgs('getData', { url, queryParameters, options });
return fetch(url, {
queryParameters,
...options,
return response
.then((response) => {
clearTimeout(timeoutId);
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
if (response.status >= 502 && response.status <= 504 && options.retry > 1) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
options.retry--;
options.signal = externalAbortSignal;
logger.accident('fetch', 'fetch_nok', 'fetch not ok and retry', {
retry: options.retry,
response,
});
return fetch(url, options);
}
return response;
})
.catch((reason) => {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
if (timedOut && options.retry > 1) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
options.retry--;
options.signal = externalAbortSignal;
logger.accident('fetch', 'fetch_catch', 'fetch catch and retry', {
retry: options.retry,
reason,
});
return fetch(url, options);
}
else {
throw reason;
}
});
}
/**
* Enhanced fetch JSON.
* @example
* const productList = await getJson('/api/products', {limit: 10}, {timeout: 5_000});
* It fetches a JSON file from a URL, and returns the JSON data
*
* Example:
*
* ```ts
* const productList = await getJson<ProductResponse>('/api/products', {queryParameters: {limit: 10}, timeout: 5_000});
* ```
*/
export async function getJson(url, queryParameters, options) {
logger.logMethodArgs('getJson', { url, queryParameters, options });
const response = await getData(url, queryParameters, options);
if (!response.ok) {
throw new Error('fetch_nok');
export async function getJson(url, options = {}) {
logger.logMethodArgs('getJson', { url, options });
const response = await fetch(url, options);
let data;
try {
if (!response.ok) {
throw new Error('fetch_nok');
}
data = (await response.json());
}
return response.json();
catch (err) {
logger.accident('getJson', 'response_json', 'response json error', {
retry: options.retry,
err,
});
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
if (options.retry > 1) {
data = await getJson(url, options);
}
else {
throw err;
}
}
return data;
}
/**
* Enhanced post json data.
* @example
* const response = await postData('/api/product/new', {name: 'foo', ...});
* It takes a URL, a JSON object, and an optional FetchOptions object, and returns a Promise of a
* Response object
*
* Example:
*
* ```ts
* const response = await postJson('/api/product/new', {name: 'foo', ...});
* ```
*/
export function postData(url, body, options) {
logger.logMethodArgs('postData', { url, body, options });
export function postJson(url, bodyJson, options) {
logger.logMethod('postJson');
return fetch(url, {
method: 'POST',
bodyObject: body,
bodyJson,
...options,

@@ -103,0 +155,0 @@ });

{
"name": "@alwatr/fetch",
"version": "0.16.0",
"version": "0.17.0",
"description": "Enhanced fetch api with timeout, helper methods and types written in tiny TypeScript module.",

@@ -35,6 +35,6 @@ "keywords": [

"dependencies": {
"@alwatr/logger": "^0.16.0",
"@alwatr/logger": "^0.17.0",
"tslib": "^2.3.1"
},
"gitHead": "403b42f686edc84c4a3021b40f5b05dce0289f12"
"gitHead": "f531925ca3db1072c0eaea90cb18e00802c93247"
}

@@ -9,13 +9,52 @@ # @alwatr/fetch

Options have two other parameters:
Options have some other parameters:
- `bodyObject`: a JSON object that converts to string and put on the body.
- `queryParameters`: a JSON object that converts to URL query params
- `bodyJson`: a JSON object that converts to string and put on the body.
- `queryParameters`: a JSON object that converts to URL query params.
- `timeout`: A timeout for the fetch request.
- `retry` If fetch response not acceptable or timed out, it will retry the request
## Example usage
```js
```ts
import {getJson} from 'https://esm.run/@alwatr/fetch';
const productList = await getJson('/api/products', {limit: 10}, {timeout: 5_000});
interface ProductInterface {
_id: string;
name: string;
description: string;
image: string;
}
const productList = await getJson<Record<string, ProductInterface>>('/api/products', {
queryParameters: {limit: 10},
timeout: 15_000,
retry: 5,
});
```
## API
### `fetch(url: string, options: FetchOptions = {})`
It's a wrapper around the browser's `fetch` function that adds retry pattern with timeout
```ts
await fetch(url, {timeout: 5_000, bodyJson: {a: 1, b: 2}});
```
### `getJson(url: string, options: FetchOptions = {})`
It fetches a JSON file from a URL, and returns the JSON data
```ts
await getJson('/api/products', {queryParameters: {limit: 10}, timeout: 5_000});
```
### `postJson(url: string, bodyJson: Record<string | number, unknown>, options?: FetchOptions)`
It takes a URL, a JSON object, and an optional FetchOptions object, and returns a Promise of a Response object
```ts
await postJson(url, {first_name: 'foo', last_name: 'bar'});
```

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