Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
@jalik/fetch-client
Advanced tools
HTTP client based on Fetch API with error handling and other DX improvements.
Requires Fetch support in Browser or Node (>=18), use a polyfill to support other environments.
Play with the lib here: https://codesandbox.io/s/jalik-fetch-client-demo-8rolt2?file=/src/index.js
import { FetchClient } from '@jalik/fetch-client'
const client = new FetchClient()
The method .fetch(url, options)
is a generic method to execute a request.
It's like calling fetch()
directly, but with all the benefits of using FetchClient
(error handling, body transformations...).
Usually, you would prefer to use a shortcut method (described after) like .get()
or .post()
instead of .fetch()
.
import { FetchClient } from '@jalik/fetch-client'
const client = new FetchClient()
client.fetch('https://jsonplaceholder.typicode.com/todos/1', {
method: 'GET',
responseType: 'json'
})
.then((resp) => {
console.log(resp.body)
})
The request options are the same as Fetch options with extra options.
type FetchOptions = RequestInit & {
/**
* The type of response to expect.
* Pass undefined to ignore response body.
*/
responseType?: ResponseType
}
The response object returned by all request methods follows the declaration below.
type FetchClientResponse<T = any> = {
/**
* Response body.
*/
body: T
/**
* Response headers.
*/
headers: Record<string, string>
/**
* The original Fetch Response.
*/
original: Response
/**
* Tells if the request has been redirected.
*/
redirected: boolean
/**
* Response status code (ex: 200).
*/
status: number
/**
* Response status text (ex: "OK").
*/
statusText: string
/**
* Contains the response type.
*/
type: globalThis.ResponseType
}
import { FetchClient } from '@jalik/fetch-client'
const client = new FetchClient()
client.delete('https://jsonplaceholder.typicode.com/posts/1')
import { FetchClient } from '@jalik/fetch-client'
const client = new FetchClient()
client.get('https://jsonplaceholder.typicode.com/todos/1', {
// Convert response body to JSON.
// It can be done per request, or for all requests when passed to FetchClient options.
responseType: 'json',
})
.then((resp) => {
console.log(resp.body)
})
import { FetchClient } from '@jalik/fetch-client'
const client = new FetchClient()
client.head('https://jsonplaceholder.typicode.com/todos/1')
.then((resp) => {
// Access response headers
console.log(resp.headers)
})
import { FetchClient } from '@jalik/fetch-client'
const client = new FetchClient()
client.options('https://jsonplaceholder.typicode.com/todos')
.then((resp) => {
// Access response headers
console.log(resp.headers)
})
When body
is an object and Content-Type
is not defined in headers:
body
is serialized to JSONContent-Type: application/json
is added to headersimport { FetchClient } from '@jalik/fetch-client'
const client = new FetchClient()
client.patch(
'https://jsonplaceholder.typicode.com/todos/1',
{ completed: true },
{ responseType: 'json' }
)
.then((resp) => {
console.log(resp.body)
})
When body
is an object and Content-Type
is not defined in headers:
body
is serialized to JSONContent-Type: application/json
is added to headersimport { FetchClient } from '@jalik/fetch-client'
const client = new FetchClient()
client.post(
'https://jsonplaceholder.typicode.com/todos',
{ title: 'test' },
{ responseType: 'json' }
)
.then((resp) => {
console.log(resp.body)
})
When body
is an object and Content-Type
is not defined in headers:
body
is serialized to JSONContent-Type: application/json
is added to headersimport { FetchClient } from '@jalik/fetch-client'
const client = new FetchClient()
client.put(
'https://jsonplaceholder.typicode.com/todos/1',
{ title: 'test' },
{ responseType: 'json' }
)
.then((resp) => {
console.log(resp.body)
})
When the server returns an error code (4xx, 5xx...), the client throws an error.
If the server returned a body (containing error details), it can be found in error.response.body
.
However be aware that the body is only available when responseType
is defined in FetchClient
options or in request options.
import { FetchClient } from '@jalik/fetch-client'
const client = new FetchClient()
const invalidObject = {}
client.post('https://jsonplaceholder.typicode.com/todos', invalidObject, {
// Setting the responseType is important to convert error response body.
responseType: 'json',
})
.catch((error: FetchResponseError) => {
console.error(
// the status error
error.message,
// the server response
error.response.body
)
})
By default, the error contains a basic message (status text like "Bad Request"). You can use the error returned by the server like below (this will be applied to all client responses).
import { FetchClient } from '@jalik/fetch-client'
const client = new FetchClient({
transformError: (error: FetchResponseError, response: FetchClientResponse) => {
// Return custom server error.
if (error.response.body?.message) {
return new FetchResponseError(error.response.body.message, response)
}
return error
},
})
client.post('https://jsonplaceholder.typicode.com/todos', invalidObject, {
// Setting the responseType is important to convert error response body.
responseType: 'json',
})
.catch((error: FetchResponseError) => {
// the error message has the same value as "error.response.body.error"
console.error(error.message)
})
import { FetchClient } from '@jalik/fetch-client'
const client = new FetchClient({
// Do something async after each successful request (200 >= code < 400).
afterEach: async (url, resp) => {
return resp
},
// Prefix all relative URL with the base URL (does nothing on absolute URL).
baseUrl: 'http://localhost',
// Do something async before each request.
beforeEach: async (url, options) => {
return options
},
// Set default headers for all requests (empty by default).
headers: {
'authorization': '...',
'x-xsrf-token': '...',
},
// Set default Fetch options for all requests.
options: {
mode: 'cors',
},
// Enable conversion of body response.
// Use one of "arrayBuffer", "blob", "formData", "json", "stream", "text", or
// undefined to ignore response body.
responseType: 'json',
// Transform response error before returning.
transformError: (error: FetchResponseError, response: FetchClientResponse) => {
// Return custom server error.
if (error.response.body?.message) {
return new FetchResponseError(error.response.body.message, response)
}
return error
},
// Transform request options and headers before sending.
// Several functions can be passed (all executed sequentially).
transformRequest: [
(url, options) => ({
...options,
headers: {
...options.headers,
// Add request date to each request
'x-request-date': Date.now().toString(),
},
}),
],
// Transform response Body before returning.
// Several functions can be passed (all executed sequentially).
transformResponse: [
(body, response) => ({
...body,
// Add response date to each response
receivedAt: Date.now(),
}),
],
})
History of releases is in the changelog on GitHub.
The code is released under the MIT License.
FAQs
Fetch wrapper to manage requests/responses more easier
The npm package @jalik/fetch-client receives a total of 34 weekly downloads. As such, @jalik/fetch-client popularity was classified as not popular.
We found that @jalik/fetch-client demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.