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

@swissquote/fetch-filter

v0.10.0

Published

A wrapper around Fetch that allows to manipulate the responses, or have side effects on them

Downloads

7

Readme

Fetch filter

Travis npm (scoped)

Fetch filter is a utility library that replaces the original fetch with itself to allow manipulations on the response before the original requester gets the response.

This allows to implement things like password confirmations without needing to modify the original code in any way.

Fetch filter is a successor to jquery-xhrfilter But because of more recent APIs, I needed to also provide a version that works with fetch.

Both are very similar, except in how rejections are handled, in $.ajax: a 400 or 500 error code results in a rejected promise, but in fetch only a network error ends in a rejected promise.

API

The API surface consists of one method and one interface. The FetchFilter interface has three optional methods before, then and fail that are called respectively before fetch, when the request succeeded and when the request failed.

Implement the functions you need and leave the others unset.

Be careful with the then and fail as you MUST call next() when you're done with your filter or your requests will never end.

Once you've created your filter, call addFetchFilter with it and it is added in the chain of filters.

interface FetchFilter {
    /**
     * Executed before the request is sent, you may add headers or change the options any way you want
     */
    before?(
        settings: RequestInfo, // Original first parameter set to fetch
        options?: RequestInit  // Original second parameter set to fetch
    ): void;

    /**
     * Executed when the request was successful, you can implement any logic here, even asynchronous.
     *
     * You can call reject(reason) if you decide the request should not pass.
     */
    then?(
        response: Response,    // The response given by Fetch
        settings: RequestInfo, // Original first parameter set to fetch
        options: RequestInit,  // Original second parameter set to fetch
        reject: (reason: any) => void, // Pass from resolved to failed for this promise
        next: (newResponse?: Response) => void // The callback to call when you're done with your business, you can optionally provide a new Response object here that will replace the original response
    ): void;

    /**
     * Executed when the request was successful, you can implement any logic here, even asynchronous.
     *
     * You can call resolve(reponse) if you decide the request should pass.
     */
    fail?(
        reason: any,           // The object you receive from the failed promise
        settings: RequestInfo, // Original first parameter set to fetch
        options: RequestInit,  // Original second parameter set to fetch
        resolve: (response: Response) => void, // Pass from failed to resolved for this request
        next: Function         // The callback to call when you're done with your business
    ): void;
}
addFetchFilter(filter: FetchFilter): void;

Examples

In this example, if a request fails with a 403 error and {error: "no_auth_token"} as content, we will request an authentication token to the user and re-send the request to the server with this token.

addFetchFilter({
    then: function(response, settings, options, reject, next) {
        // Only handle 403's
        if (response.status != "403") {
            next();
            return;
        }
        
        response.json().then(function(content) {
            // Only handle "no_auth_token" errors
            // Leave the rest to other filters or
            // the original handler
            if (!content.error || content.error != 'no_auth_token') {
                next();
                return;
            }

            // At this stage, you know your request failed with a "no_auth_token" error
            // You can decide to show a popup that requests a password from the user, do
            // a request to a specific server, or simply retry the initial request with
            // new parameters.

            // `modalValidate()` is a promise that will show a popup to the user 
            // asking if he wants to accept this request or not.
            modalValidate().then(function (authToken) {
                // Deep clone the options and add a header
                // We clone because we don't want to modify the original request
                var newOptions = options && JSON.parse(JSON.stringify(options)) || {};
                newOptions.headers = newOptions.headers || {};
                newOptions.headers['X-Auth-token'] = authToken;
        
                // Now we make a new request with authorization in place
                fetch(settings, newOptions).then(function(response) {

                    // If this request succeeds, we'll send the new
                    // response to the next handler
                    next(response);

                }).catch(reject); // The new request failed, we'll just fail the full request

            }).catch(function () {
                // If the validation is incorrect, go back to the normal cycle of things 
                // and the original requester will see the error
                next();
            });

        }).catch(next) // If the json can't be parsed it's probably not for us, continue with the rest
    }
});

Installing

npm install --save @swissquote/fetch-filter

Because fetch-filter patches window.fetch you should use named import like

import "@swissquote/fetch-filter";

//and then just call addFetchFilter from anywhere to init concrate filter
addFetchFilter({});