npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@woogie0303/easyfetch

v0.1.4

Published

#### [한국어 버전](./README_KO.md)

Downloads

1

Readme

EasyFetch

한국어 버전

While working on the attraction team project using the Next.js App Router, I encountered some inconveniences, especially being familiar with React and Axios. These issues include:

  • Lack of interceptor functionality in client components.
  • Using res.json, JSON.stringify
  • Handling of errors above status 400 using res.ok.
  • Missing API methods like axios.post in the fetch API.

To address these inconveniences, EasyFetch was created as an extended fetch for Next.js App Router, making it more user-friendly for those accustomed to Axios.

Install

pnpm add @woogie0303/easyfetch
yarn add @woogie0303/easyfetch
npm install @woogie0303/easyfetch

Type

RequestInitWithNextConfig

interface NextFetchRequestConfig {
  revalidate?: number | false;
  tags?: string[];
}

interface RequestInitWithNextConfig extends globalThis.RequestInit {
  next?: NextFetchRequestConfig | undefined;
}

EasyFetchResponse

type EasyFetchResponse<T> = Omit<
  Awaited<ReturnType<typeof fetch>>,
  keyof Body | 'clone' | 'url'
> & {
  body: T;
  config: [string | URL, RequestInit | RequestInitWithNextConfig | undefined];
};

EasyFetchRequestType

type EasyFetchRequestType = [
  string | URL,
  RequestInitWithNextConfig | undefined
];

Feature

You can set default headers and baseUrl.

easyFetch()

const easy = easyFetch(defaultConfig);

Parameter

defaultConfig?: {
  baseUrl?: string | URL;
  headers?: HeadersInit;
}

Use API methods and you can set Request instances as argument.

const easy = easyFetch({
  baseUrl: 'https://attraction/',
  headers: {
    'Content-Type': 'multipart/form-data',
  },
});

const request = new Request('https://hi');

easy.request(request);

easy.get('getUser');
easy.delete('deleteUser');

easy.patch('postUser', { userData: 'kang' });
easy.post('postUser', { userData: 'kang' });
easy.put('postUser', { userData: 'kang' });

Parameter, Return Type

get, delete method
<T>(url: string | URL, reqConfig?: Omit<RequestInitWithNextConfig, 'method'>) =>
  Promise<EasyFetchResponse<T>>;
patch, post, put method
<T>(
  url: string | URL,
  reqBody?: object, // Request Body
  reqConfig?: Omit<RequestInitWithNextConfig, 'method' | 'body'>
) => Promise<EasyFetchResponse<T>>;
request method
<T>(request: RequestInfo | URL, requestInit?: RequestInitWithNextConfig) =>
  Promise<EasyFetchResponse<T>>;

Request Interceptor

This feature allows you to add custom logic before a request is sent.

const easy = easyFetch();

easy.interceptor.request(onFulfilled, onReject);

Parameter, Return Type

 (
  onFulfilled?: (arg: EasyFetchRequestType)
    => | Promise<EasyFetchRequestType>
       | EasyFetchRequestType,
  onRejected?: (err: any) => any
 ): void

Response Interceptor

You can configure logic to handle responses before they are processed. For handling 400-level errors, use the EasyFetchResponse type assertion to handle server errors.

const easy = easyFetch();

easy.interceptor.response(onFulfilled, onReject);

Parameter, Return Type

 (
  onFulfilled?: (arg: EasyFetchResponse<any>)
    => | Promise<EasyFetchResponse<any>>
       | EasyFetchResponse<any>,
  onRejected?: (err: any) => any
 ): void

Handling 400-level Server Errors

const easy = easyFetch();

easy.interceptor.response(
  (res) => res,
  async (err) => {
    const error = err as EasyFetchResponse<ErrorType>;

    if (error.status === 401) {
      const { body } = await easy.get<Token>('https://google.co/getToken', {
        ...error.config[1],
      });

      const headers = new Headers(error.config[1]?.headers);

      headers.set('Authorization', `Bearer ${body.accessToken}`);

      return easy.request(error.config[0], {
        ...error.config[1],
        headers,
      });
    }

    throw err;
  }
);

Note

When handling errors, note that the Interceptor Response feature is not the same as transforming the response data. Returning an error config url as an argument helps maintain type consistency.

// Incorrect usage
const easy = easyFetch();
easy.interceptor.response(
  (res) => res,
  (err) => {
    const serverError = err as EasyFetchResponse<ResponseType>;

    return { data: 'Hi' };
  }
);

const data = await easy.get<ResponseType>('https://sdf'); // return {data: 'Hi'}

// Correct usage
const easy = easyFetch();
easy.interceptor.response(
  (res) => res,
  (err) => {
    const serverError = err as EasyFetchResponse<ResponseType>;
    const [url, requestConfig] = serverError.config;

    return easy.get(url, requestConfig);
  }
);

const data = easy.get<ResponseType>('https://sdf'); // return ResponseType Data

License

MIT © DongWook Kang