valeriangalliat / fetch-cookie

Decorator for a `fetch` function to support automatic cookie storage and population. 🍪
The Unlicense
135 stars 29 forks source link

Is it possible to make abstract interface for this library functionality? #79

Closed krutoo closed 1 year ago

krutoo commented 1 year ago

Hi, i develop some library for fetch function - fetch-tools: https://github.com/krutoo/fetch-tools

Currently it provides a way to add middleware for fetching process.

Middleware is just a function that receives:

Middleware should return Response | Promise<Response>

In fetch-tools package there is a simple middleware for collect cookie on the server. But recently I realized that I did not implement it quite correctly.

I see that fetch-cookie makes a lot of work to collect/pass cookie according to spec and browser behavior

Can i create properly worked solution based on fetch-cookie as middleware?

krutoo commented 1 year ago

i think it can be look like this:

import { Middleware } from '@krutoo/fetch-tools';

interface CookieStore {
  // ...
}

export function cookieMiddleware(store: CookieStore): Middleware {
  return async (request, next) => {
    const nextHeaders = new Headers(request.headers);

    // here we get cookies from the storage that are needed only for this request
    nextHeaders.append('cookie', store.getCookies(request));

    // copy original request with add cookie
    const nextRequest = new Request(request, { headers: nextHeaders })

    // make fetch
    const response = await next(nextRequest);

    // handle set-cookie headers
    if (response.headers.has('set-cookie')) {
      response.headers.forEach((headerValue, headerName) => {
        if (headerName === 'set-cookie') {
          store.setCookie(headerValue);
        }
      });
    }

    return response;
  };
}
valeriangalliat commented 1 year ago

Hey!

Because fetch-cookie takes a fetch instance to call next, it's essentially a middleware :)

You should be able to wrap it like this:

import fetchCookie from 'fetch-cookie'

export function cookieMiddleware(store: CookieStore): Middleware {
  return async (request, next) => {
    return await fetchCookie(next, store)(request)
  }
}