Narcissistic Passion Minified
    Have ideas to improve npm?Join in the discussion! »

    @tkrotoff/fetch
    TypeScript icon, indicating that this package has built-in type declarations

    0.12.0 • Public • Published

    @tkrotoff/fetch

    npm version Node.js CI Codecov Bundle size Prettier Airbnb Code Style

    A Fetch wrapper.

    • Simplifies the use of Fetch
    • Tiny
    • No dependencies
    • Fully tested
    • Written in TypeScript
    • Comes with test utilities

    Why?

    When using Fetch, you must write some boilerplate:

    const url = 'https://example.com/profile';
    const data = { username: 'example' };
    
    try {
      const response = await fetch(url, {
        method: 'POST',
        body: JSON.stringify(data),
        headers: {
          'content-type': 'application/json'
        }
      });
      if (!response.ok) {
        throw new Error('Network response was not ok');
      }
      const json = await response.json();
      console.log('Success:', json);
    } catch (e) {
      console.error('Error:', e);
    }

    With @tkrotoff/fetch it becomes:

    try {
      const response = await postJSON(url, data).json();
      console.log('Success:', response);
    } catch (e /* HttpError | TypeError | DOMException */) {
      console.error('Error:', e);
    }

    You don't have to worry about:

    • HTTP headers: Accept and Content-Type are already set
    • stringifying the request body
    • One await instead of two
    • No need to manually throw an exception on HTTP error status (like 404 or 500)

    Usage

    Examples:

    npm install @tkrotoff/fetch

    import { defaults, postJSON } from '@tkrotoff/fetch';
    
    defaults.init = { /* ... */ };
    
    const response = await postJSON(
      'https://jsonplaceholder.typicode.com/posts',
      {
        title: 'foo',
        body: 'bar',
        userId: 1
      }
    ).json();
    console.log(response);

    Fetch is not supported by old browsers (IE), use whatwg-fetch polyfill + core-js for other modern JS features like async/await.

    With Node.js use node-fetch polyfill.

    API

    • get(input: RequestInfo, init?: RequestInit): ResponsePromiseWithBodyMethods

    • post(input: RequestInfo, body: BodyInit, init?: RequestInit): ResponsePromiseWithBodyMethods

    • postJSON(input: RequestInfo, body: object, init?: RequestInit): ResponsePromiseWithBodyMethods

    • put(input: RequestInfo, body: BodyInit, init?: Init): ResponsePromiseWithBodyMethods

    • putJSON(input: RequestInfo, body: object, init?: RequestInit): ResponsePromiseWithBodyMethods

    • patch(input: RequestInfo, body: BodyInit, init?: Init): ResponsePromiseWithBodyMethods

    • patchJSON(input: RequestInfo, body: object, init?: RequestInit): ResponsePromiseWithBodyMethods

    • del(input: RequestInfo, init?: RequestInit): ResponsePromiseWithBodyMethods

    • isJSONResponse(response: Response): boolean

    ResponsePromiseWithBodyMethods being Promise<Response> with added methods from Body.

    HttpError

    @tkrotoff/fetch throws HttpError with a response property when the HTTP status code is < 200 or >= 300.

    Test utilities

    • createResponsePromise(body?: BodyInit, init?: ResponseInit): ResponsePromiseWithBodyMethods

    • createJSONResponsePromise(body: object, init?: ResponseInit): ResponsePromiseWithBodyMethods

    • createHttpError(body?: BodyInit, status = 0, statusText?: string): HttpError

    • createJSONHttpError(body: object, status = 0, statusText?: string): HttpError

    HttpStatus

    Instead of writing HTTP statuses as numbers 201, 403, 503... you can replace them with HttpStatus and write more explicit code:

    import { HttpStatus } from '@tkrotoff/fetch';
    
    console.log(HttpStatus._201_Created);
    console.log(HttpStatus._403_Forbidden);
    console.log(HttpStatus._503_ServiceUnavailable);

    Configuration

    @tkrotoff/fetch exposes defaults.init that will be applied to every request.

    import { defaults } from '@tkrotoff/fetch';
    
    defaults.init.mode = 'cors';
    defaults.init.credentials = 'include';

    Testing

    When testing your code, use createResponsePromise() and createJSONResponsePromise():

    import * as Http from '@tkrotoff/fetch';
    
    test('OK', async () => {
      const getSpy = jest.spyOn(Http, 'get').mockImplementation(() =>
        Http.createResponsePromise('test')
      );
    
      const response = await Http.get(url).text();
      expect(response).toEqual('test');
    
      expect(getSpy).toHaveBeenNthCalledWith(1, url);
    
      getSpy.mockRestore();
    });
    
    test('fail', async () => {
      const getSpy = jest.spyOn(Http, 'get').mockImplementation(() =>
        Http.createResponsePromise('<!DOCTYPE html><title>404</title>', {
          status: 404,
          statusText: 'Not Found'
        })
      );
    
      await expect(Http.get(url).text()).rejects.toThrow('Not Found');
    
      expect(getSpy).toHaveBeenNthCalledWith(1, url);
    
      getSpy.mockRestore();
    });

    Check examples/node and examples/web.

    Install

    npm i @tkrotoff/fetch

    DownloadsWeekly Downloads

    58

    Version

    0.12.0

    License

    MIT

    Unpacked Size

    59.6 kB

    Total Files

    22

    Last publish

    Collaborators

    • avatar