Coder Social home page Coder Social logo

fetch-cookie's Introduction

๐Ÿช fetch-cookie npm version Build status

Decorator for a fetch function to support automatic cookie storage and population.

Migrating from v1

Description

fetch-cookie wraps around a fetch function and intercepts request options and response objects to store received cookies and populate request with the appropriate cookies.

This library is developed with Node.js and fetch polyfill libraries such as node-fetch in mind, since the browser version is supposed to let a way to include cookies in requests. Compatibility may not be guaranteed but as long as your library implements the Fetch standard you should be fine. In case of incompatibilities, please create a new issue.

Internally the plugin uses a cookie jar. You can insert your own (details below) but tough-cookie is preferred.

Usage

With Node.js 18.3.0 and greater, using the native global fetch function:

import makeFetchCookie from 'fetch-cookie'

const fetchCookie = makeFetchCookie(fetch)

Or with node-fetch:

import nodeFetch from 'node-fetch'
import fetchCookie from 'fetch-cookie'

const fetch = fetchCookie(nodeFetch)

Custom cookie jar

If you want to customize the internal cookie jar instance (for example, with a custom store), you can inject it as a second argument:

import makeFetchCookie from 'fetch-cookie'

const fetchCookie = makeFetchCookie(fetch, new makeFetchCookie.toughCookie.CookieJar())

Here, we expose the tough-cookie version that we depend on internally so you can just reuse it and don't end up accidentally bundling two different versions. That being said you can use any version of tough-cookie here, or even any compatible cookie jar.

This enables you to create multiple fetch-cookie instances that use different cookie jars, essentially two different HTTP clients with different login sessions on you backend (for example).

All calls to fetch will store and send back cookies according to the URL.

If you use a cookie jar that is not tough-cookie, keep in mind that it must implement this interface to be compatible:

interface CookieJar {
  getCookieString(currentUrl: string): Promise<string>
  setCookie(cookieString: string, currentUrl: string, opts: { ignoreError: boolean }): Promise
}

Custom cookie jar with options

If you don't want a custom store and just want to pass tough-cookie options, e.g. to allow cookies on localhost:

import makeFetchCookie from 'fetch-cookie'

const fetchCookie = makeFetchCookie(fetch, new makeFetchCookie.toughCookie.CookieJar(undefined, {
  allowSpecialUseDomain: true
}))

Or with a custom store as well:

import makeFetchCookie from 'fetch-cookie'
import FileCookieStore from 'file-cookie-store'

const store = new FileCookieStore('cookies.txt')

const fetchCookie = makeFetchCookie(fetch, new makeFetchCookie.toughCookie.CookieJar(store, {
  allowSpecialUseDomain: true
}))

Ignoring errors

All errors when setting cookies are ignored by default. You can make it throw errors in cookies by passing a third argument ignoreError (defaulting to true).

import makeFetchCookie from 'fetch-cookie'

const fetchCookie = makeFetchCookie(fetch, new makeFetchCookie.toughCookie.CookieJar(), false)

When set to false, fetch-cookie will throw when an error occurs in setting cookies and breaks the request and execution.

Otherwise, it silently ignores errors and continues to make requests/redirections.

Max redirects

Because we need to do our own redirect implementation, the way to configure the max redirects is not going to be that of your chosen fetch implementation, but custom to fetch-cookie.

We read a maxRedirect parameter for that. The default is 20.

import makeFetchCookie from 'fetch-cookie'

const fetchCookie = makeFetchCookie(fetch)

await fetchCookie(url, { maxRedirect: 10 })

Cookies on redirects

In order to handle cookies on redirects, we force the redirect parameter to manual, and handle the redirections internally (according to the original redirect value) instead of leaving it to the upstream fetch implementation.

This allows us to hook into the redirect logic in order to store and forward cookies accordingly.

This is useful for example when a login page sets a session cookie and redirects to another page.

Migrating from v1

The only breaking change with v2 is that the node-fetch wrapper (that was handling redirects only with node-fetch nonstandard APIs) was dropped and the redirects are now always handled by the main export.

// If you were doing
const fetchCookie = require('fetch-cookie/node-fetch')

// Change it to
const fetchCookie = require('fetch-cookie')

// Or
import fetchCookie from 'fetch-cookie'

This also means that if you were not using the node-fetch wrapper and were happy about cookies not being included in redirects, cookies are now going to be stored and sent in redirects as well like they would in the browser.

Development

# Install dependencies
npm ci

# Allows to test node-fetch v2 as well as node-fetch v3
npm --prefix test/node_modules/node-fetch-2 ci

# Allows to test against Undici by removing the blacklisting of `Set-Cookie` headers
npm run patch-undici

npm run lint
npm run type-check

# Generates code in `esm` and `cjs` directories
npm run build

# Run tests (depends on the built code)
npm test

# Generate type declarations in the `types` directory
npm run type-declarations

Credits

  • ๐Ÿฅฐ All the contributors to fetch-cookie!
  • ๐Ÿ˜ node-fetch for the redirect logic that we carefully mimic (sadly reimplementing this code was the only way to support cookies in redirects).

fetch-cookie's People

Contributors

ahmadalhallak avatar caub avatar cheeseandcereal avatar devanshj avatar ebdrup avatar ewoerner avatar fabiante avatar gajus avatar heyitsaamir avatar hubertmalkowski avatar jackymancs4 avatar jimmywarting avatar juicetan avatar krushiraj avatar leonelv avatar mvindahl avatar nlang avatar omgimalexis avatar piwonskp avatar qw-in avatar riftlurker avatar teidesu avatar valeriangalliat avatar wrumsby avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fetch-cookie's Issues

Stable ?

Hi everyone, like many people, I've ended up here.

I am not sure if I should give a try, is this completely stable ?

I have just had a try and configured my entrypoint with :

require('es6-promise').polyfill();
require('isomorphic-fetch');

global.fetch = require('fetch-cookie')(fetch);
global.API_URL = 'http://api-test.com:8080';
global.localStorage = window.localStorage || require('localStorage');

There are no cookie set in the request, it also remove and disable them.

Does this actually work?

I am doing requests like this:

var fetch = require('fetch-cookie')(require('node-fetch'))
var qs = require('qs')

var headers = {
    'Accept': 'application/json',
    'Accept-Charset': 'utf-8',
    'Keep-Alive': 'true',
    'X-Requested-By': 'hb_android_app',
    'User-Agent': 'Apache-HttpClient/UNAVAILABLE (java 1.4)'
}

// login, set coookies
function login(email, password){
    return fetch('https://www.humblebundle.com/login', {
        method: 'POST',
        credentials: 'include',
        headers: headers,
        body: qs.stringify({
            username: email,
            password: password
        })
    })
    .then(function(res){
        if (res.status !== 200){
            throw new Error('Could not login.')
        }
       // res.headers._headers['set-cookie'].join(';') is cookies.
        return res
    })
}

// get library
function library(){
    return fetch('https://www.humblebundle.com/home/library', {
        credentials: 'include',
        headers: headers
    })
    .then(function(res){
        return res.text()
    })
    .then(function(body){
        // ERR: I get login page because cookies aren't set.
        var m = /var gamekeys =  \[(".+")+\];/.exec(body)
        if (m){
            return JSON.parse('[' + m[0] + ']')
        }
    })
}

// test
login(process.env.HUMBLE_EMAIL, process.env.HUMBLE_PASSWORD)
    .then(library)

and no subsequent requests are using the cookies. I also tried passing an instance of tough-cookie CookieJar as second param to require('fetch-cookie')(). Am I doing something wrong?

I hit an error: Cookie failed to parse

I checked the request on Postman that's normal with two cookies but it failed on fetch() with error:
Error: Cookie failed to parse
That's really confused. Any hint will be appreciated.

node-fetch version 2 incompatibility

This package is not compatible with node-fetch version 2.

This causes a bunch of issues:

#22 - Broken using node-fetch v2
#23 - I hit an error: Cookie failed to parse
#17 - Doesn't work if using headers object

The fixes should be minor and I'll try to implement them this week in my fork.

It could work on browser?

I see window.fetch in source, but tough-cookie is node-only, how would this be used for a client platform (supporting or not cookies)?

Travis CI

@valeriangalliat

I'd like to include the Travis CI I used in my fork to ensure better stability.
If you are okay with it I'd need you to enable it, my access rights are not enough to do that.
In my fork you can find the Travis YAML configuration file.

Post-install script prevents installation

I just leave this log here, but the type definitions prevent installation in my environment. TS config also included:

โžœ  fp-ra-client git:(main) โœ— yarn add https://github.com/leehambley/fetch-cookie --ignore-scripts

yarn add v1.22.19
[1/4] ๐Ÿ”  Resolving packages...
[2/4] ๐Ÿšš  Fetching packages...
info No lockfile found.
warning package-lock.json found. Your project contains lock files generated by tools other than Yarn. It is advised not to mix package managers in order to avoid resolution inconsistencies caused by unsynchronized lock files. To clear this warning, remove package-lock.json.
[1/4] ๐Ÿ”  Resolving packages...
[2/4] ๐Ÿšš  Fetching packages...
[3/4] ๐Ÿ”—  Linking dependencies...
warning "ts-standard > @typescript-eslint/[email protected]" has unmet peer dependency "@typescript-eslint/parser@^4.0.0".
[4/4] ๐Ÿ”จ  Building fresh packages...
success Saved lockfile.
$ npm run build && npm run type-declarations

> [email protected] build
> esbuild src/*.ts --format=esm --outdir=esm && esbuild src/*.ts --format=cjs --outdir=cjs


  esm/index.js  7.3kb


  cjs/index.js  8.4kb


> [email protected] type-declarations
> tsc --project tsconfig.build.json --declaration --emitDeclarationOnly --outDir esm && cat esm/index.d.ts | sed 's/^export default /export = /' > cjs/index.d.ts

src/index.ts:284:33 - error TS2345: Argument of type '{ (input: RequestInfo, init?: FetchCookieInit<RequestInit> | undefined): Promise<Response>; toughCookie: typeof import("/Users/leehambley/Library/Caches/Yarn/v6/.tmp/c81626f186160b75360efa5a0bd19eb6.f90f607aeb4918327abc84fc675b337482b2abb6.prepare/node_modules/@types/tough-cookie/index"); }' is not assignable to parameter of type '(input: URL | RequestInfo, init?: RequestInit | undefined) => Promise<Response>'.
  Types of parameters 'input' and 'input' are incompatible.
    Type 'URL | RequestInfo' is not assignable to type 'RequestInfo'.
      Type 'URL' is not assignable to type 'RequestInfo'.

284     return await handleRedirect(fetchCookieWrapper, originalInit, response)
                                    ~~~~~~~~~~~~~~~~~~


Found 1 error in src/index.ts:284

error Command failed with exit code 2.
info Visit https://yarnpkg.com/en/docs/cli/add for documentation about this command.
{
  "compilerOptions": {
    "esModuleInterop": true
  }
}

Not passing options further in redirects

Hi,

in the node-fetch decorator fetch-cookie/node-fetch the options provided by user are not passed further through redirects, is it intentional? In some authentications (e.g. google) they require to have user-agent in every redirect, otherwise it forwards to inappropriate url. I think this line:

const optsForGet = Object.assign({}, {

should be changed into:

const optsForGet = Object.assign({}, userOptions, {

Br,
hh

Clear Cookies?

Is there any way to clear cookies ?

like

const fetchCookies = ....
fetchCookies.clearAll(); 

or something..?

why!!!!

code:

    this.cookieJar = new tough.CookieJar())
    this.fetchCookie = makeFetchCookie(fetch, this.cookieJar)

"AlteonP=BGqtJSF9EKy4atdnbv0jWQ$$; isTopbarhw=true; JSESSIONID=mvJxypY_yN6dZ6VXIB5GZo_d9rfe8ujRx1Dc_TsVBPvnwlX1Ef68!1873756866; languageId=001; txtReSzTypehw=large; tree1Selected=; tree1State=; userType=2; Requestid=T19AAX%2FjQbRRcWB7Q6dp6CkT9Nsc1U9UjhcSIdQDtSc%3D"

    await this.cookieJar.setCookie(cookie, url)
    let bbb = await this.cookieJar.getCookieString(url)
    console.info(bbb)

 'AlteonP=BGqtJSF9EKy4atdnbv0jWQ$$'

Excuse me, why?

Error when using node-fetch decorator without options object

var fetch = require('fetch-cookie/node-fetch')(require('node-fetch'));
fetch('http://google.de', {}).catch(console.error); // works
fetch('http://google.de').catch(console.error); // doesn't work

The latter version throws an error:

TypeError: Cannot read property 'method' of undefined
    at โ€ฆ/node_modules/fetch-cookie/node-fetch.js:8:100
    at process._tickCallback (internal/process/next_tick.js:103:7)

Doesn't work if using headers object

Hello,

One of my projects takes advantage of the Headers() class quite extensively. fetch-cookie tries to modify the instance, resulting in cookies not being sent.

Adjusting line 16 to the following resolves the issue:

                if (opts.headers instanceof Headers) {
                    opts.headers.append("cookie", cookie);
                } else {
                    opts.headers = Object.assign(
                        opts.headers || {},
                        cookie ? { cookie: cookie } : {},
                    );
                }

Should I make a merge request?

Typescript type definitions are incorrect

The current types in index.d.ts do not allow importing the node-fetch submodule (fetch-cookie/node-fetch)

Additionally, while the module supports custom cookie jar implementations, the types now restrict it to be ONLY the tough-cookie cookie jar implementation, which breaks typescript usage which was previously using a custom cookie jar since the v0.9.0 release.

Cookies are not set during node-fetch redirect

This is due to redirects happening internally in node-fetch, and not returning to the wrapping fetch-cookie until redirection has ended. There is some discussion on this in the node-fetch issue tracker (See: node-fetch/node-fetch#94). It seems like their solution has been to add the "redirect: 'manual'" option, allowing wrapping libraries such as node-fetch to handle redirects on their own.

This also points to how it could be made to work.

I have two ideas:

  1. I could extend fetch-cookie to take advantage of this option. It's certainly doable but it would also make the code less succinct and it would couple the library tightly to node-fetch instead of being a more generic fetch wrapper. Thus, it may pollute the design and goals of fetch-cookie. And, no matter how careful I am, there is always the risk of breaking stuff.
  2. I could create a separate project node-fetch-cookie as an additional wrapper. It would require fetch-cookie, and it would take a node-fetch instance in its constructor in the same way that fetch-cookie does. As the name might hint, it could be a drop-in replacement for fetch-cookie, but specifically tailored to wrap node-fetch, and without the cookie-and-redirect issue.

I kind of like the second one better as it seems to be more in line with the "do one thing well" philosophy.

I would, however, appreciate any thoughts on the matter.

How to include cookie on cookie jar?

Hi, how can I add a specific cookie to the cookie jar?

I'm currently using the wrapper.

const nodeFetch = require('node-fetch');
const fetch = require('fetch-cookie/node-fetch')(nodeFetch); //NODE FETCH 2.6.7 //FETCH-COOKIE 1.00

I'm using puppeteer to login on a website that has a captcha and on successful log in I'm getting that puppeteer browser cookies and wanted to pass it on the cookie jar.

Thank you!

Support 307 / POST

Right now this library supports 301, 302, and 303 redirect and changes the method to GET

There is also a 307 which has the unique property of retaining the method and body, so a POST will be redirected as a POST with the same body and options.

We have an auth server that returns 307s and I have modified the code and it works fine.

  • add a condition for 307
  • if 307, use the original userOptions with decremented follow instead of optsForGet

Maintainer?

PING @valeriangalliat

If you're looking for someone to maintain this project I'd be more than happy to step up as I've seen a few issues open from last year without any replies.

fetch-cookie fails at startup for react-native app

Hi!

I am attempting to use fetch-cookie in a react native application. I get the following runtime error after I only added the import

Android Bundling failed 1662ms 
While trying to resolve module 'fetch-cookie' from file 'C:\Git\mobski\App.js', 
the package 'C:\Git\mobski\node_modules\fetch-cookie\package.json' was successfully found. 
However, this package itself specifies a 'main' module field that 
could not be resolved ('C:\Git\mobski\node_modules\fetch-cookie\index'. Indeed, none of these files exist:

C:\Git\mobski\node_modules\fetch-cookie\index(.native|.android.ts|.native.ts|.ts|.android.tsx|.native.tsx|.tsx|.android.js|.native.js|.js|.android.jsx|.native.jsx|.jsx|.android.json|.native.json|.json)
C:\Git\mobski\node_modules\fetch-cookie\index\index(.native|.android.ts|.native.ts|.ts|.android.tsx|.native.tsx|.tsx|.android.js|.native.js|.js|.android.jsx|.native.jsx|.jsx|.android.json|.native.json|.json)

I tried running npm install in node_modules/fetch_cookie and got the following error, but im not sure if this is relevant?

> for format in esm cjs; do esbuild src/*.ts --format=$format --outdir=$format; done

format was unexpected at this time.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] build: `for format in esm cjs; do esbuild src/*.ts --format=$format --outdir=$format; done`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\yoste\AppData\Roaming\npm-cache\_logs\2022-03-15T22_56_22_810Z-debug.log
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] prepare: `npm run build && npm run type-declarations`
npm ERR! Exit status 1

package.json looks like this:


{
  "name": "mobski",
  "version": "1.0.0",
  "main": "node_modules/expo/AppEntry.js",
  "scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "expo start --web",
    "eject": "expo eject"
  },
  "dependencies": {
    "crypto-js": "3.1.9-1",
    "expo": "~44.0.0",
    "expo-status-bar": "~1.2.0",
    "fetch-cookie": "^2.0.1",
    "node-fetch": "^3.2.3",
    "react": "17.0.1",
    "react-dom": "17.0.1",
    "react-native": "0.64.3",
    "react-native-crypto": "^2.2.0",
    "react-native-randombytes": "^3.6.1",
    "react-native-web": "0.17.1",
    "request": "^2.88.0"
  },
  "devDependencies": {
    "@babel/core": "^7.12.9",
    "rn-nodeify": "github:tradle/rn-nodeify"
  },
  "private": true
}

I have also attempted to make a metro.config.js as described in https://stackoverflow.com/questions/60124435/however-this-package-itself-specifies-a-main-module-field-that-could-not-be-r, but still same error.

I am using React-Native and Expo, developing on Windows. Running on Android emulator using Android Studio. Npm version 6.14.15 and node version 14.17.6.

Any ideas what I can attempt to solve this? Any help would be greatly appreciated

Any exaples

Hi! I can't find any examples, maybe somebody can help me?
I need to make a GET request to a login page, take a token from hidden input, then make a POS login request with a cookie from a previous request, then another request also should be with same session
Something like that:

const loginRequest = await fetch(loginPageUrl, {method: 'GET'}).then(resp => resp.text())

const token = parseToken(loginRequest) // own parser function

const doLogin = await fetch(loginPageUrl, {method: 'POST', body: formData}).then(resp => resp.text()) 

if(doLogin == 'success'){
 const someAnotherRequest = await fetch(actionUrl, {method: 'POST', body: someData}).then(resp => resp.text())  

 this request available only if user is logged in
}

Type definition not working under Node.js ESM support in TypeScript 4.7

As TypeScript 4.7 are introducing ESM support on Node.js, they also introduce a new way for reading type definition per CJS / ESM, which will be enabled if moduleResolution is Node16 or Nodenext (If module is Node16 or Nodenext, by default moduleResolution will be changed to match it).

You can see the example on the second snippets of this section:
https://devblogs.microsoft.com/typescript/announcing-typescript-4-7/#package-json-exports-imports-and-self-referencing

As a result, if module=Node16 is enabled, TypeScript cannot find the typing definition on either CommonJS or ESM.
I am making a minimal Gist to reproduce it:
https://gist.github.com/littlebtc/ef5b27f0c2d90c80c8c76e4a7dfb2176

Redirect with Location partial URL doesn't work

Hey guys,

I'm working on an internal tool so I can't share a test case unfortunately (since I don't know of another server that creates this behavior). However, I thought I would toss my discovery and solution towards the project in case anyone else also discovers this issue and can provide a test case.

My Problem

Basically the server was sending a redirect request back to my app with headers that looked like this instead of a full URL:

{
.
.
.
location: /foobar/
.
.
.
}

then when node-fetch would try to create the request, Node would throw the error:
TypeError [ERR_INVALID_URL]: Invalid URL

My Solution

I wrote a little function that will return a full url using the protocol provided by the request agent and the host url provided in the request headers and then use that for the redirect URL instead of just the location header.

  /**
   * formats the URL by adding the host and protocol to the url string if the first character of the location url is '/'
   * @param {String} url 
   * @param {*} opts 
   * @returns {String}
   */
  function getRedirectUrl(url, opts){
    const firstCharacterIsSlash = url.slice(0,1) === '/';
    if(!firstCharacterIsSlash) return url;
    
    const host = opts.headers.Host;
    const protocol = opts.agent.protocol;
    return `${protocol}//${host}${url}`
  }

I can create a pull request if desired but, honestly I am unsure if this is actually the best solution since I'm not exactly an expert in this area. This just solved my problem.

[Edit] I made these updates to the node-fetch.js file

Error: Cookie not in this host's domain.

The decorator throws an exception on this line if the server returned cookies that are outside of its domain. While such cookies certainly do not belong in the jar, I would still like to get the fetched response.

await Promise.all(cookies.map((cookie) => setCookie(cookie, res.url)))

Failed to load configuration of your project('./package.json' is not defined by "exports")

I am getting this error with the latest version or react-native 0.69

[react-native] error Failed to load configuration of your project.
[react-native] Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './package.json' is not defined by "exports" in ../node_modules/fetch-cookie/package.json
[react-native]     at throwExportsNotFound (internal/modules/esm/resolve.js:299:9)
[react-native]     at packageExportsResolve (internal/modules/esm/resolve.js:522:3)
[react-native]     at resolveExports (internal/modules/cjs/loader.js:449:36)
[react-native]     at Function.Module._findPath (internal/modules/cjs/loader.js:489:31)
[react-native]     at Function.Module._resolveFilename (internal/modules/cjs/loader.js:875:27)
[react-native]     at Function.resolve (internal/modules/cjs/helpers.js:98:19)
[react-native]     at resolveNodeModuleDir (../node_modules/@react-native-community/cli-tools/build/resolveNodeModuleDir.js:24:42)
[react-native]     at ../node_modules/@react-native-community/cli-config/build/loadConfig.js:93:76
[react-native]     at Array.reduce (<anonymous>)
[react-native]     at loadConfig (../node_modules/@react-native-community/cli-config/build/loadConfig.js:91:134)
[react-native] info Run CLI with --verbose flag for more details.
error Command failed with exit code 1.

node-fetch decorator does not reject if redirection count exceeds limit

Behaviour should be the same as with the undecorated function:

const fetch = require('node-fetch');
const decorated = require('fetch-cookie/node-fetch')(fetch);

fetch('https://tests.eckhart-woerner.de/redirect.html', {follow: 2}); // rejects
decorated('https://tests.eckhart-woerner.de/redirect.html', {follow: 2}); // resolves

Cookies are set for wrong domain

This is closely related to #6:
When a request gets redirected from domain A to domain B, and domain B sets some cookies, those cookies are incorrectly stored for domain A.

Typescript error

Code:

import nodeFetch from 'node-fetch';
const fetch = fetchCookie(nodeFetch);
error TS2345: Argument of type 'typeof fetch' is not assignable to parameter of type 'GenericFetch<GenericRequestInfo, RequestInit, Response>'.
  Types of parameters 'url' and 'input' are incompatible.
    Type 'GenericRequestInfo' is not assignable to type 'RequestInfo'.
      Type 'GenericRequest' is not assignable to type 'RequestInfo'.
        Type 'GenericRequest' is missing the following properties from type 'Request': clone, context, headers, method, and 17 more.


versions in package.json

    "@types/node-fetch": "^2.6.1",
    "node-fetch": "^2.6.1",

Example in documentation doesn't works with fetch-cookie v2 e

The typescript definition doesn't works.
See https://codesandbox.io/s/jolly-cookies-8nfzz3?file=/index.ts

  • First issue
    image

  • After adding compilerOptions.esModuleInterop to true, 2nd issue because jar parameter is not declared as optional (while there is a provided default value see

    jar = jar || new tough.CookieJar()

    image

  • After adding manually tough.cookieJar, 3rd issue regarding missing properties size and buffer in Request type
    image

Add a license

Hi,

As an open source project that is used by several other projects, I would suggest adding a permissive license.

Thanks

Set-Cookie typings are incorrect

setCookie(cookieString: string, currentUrl: string, cb: (err: any) => void, opts: { ignoreError: boolean }): void;

Please correct me if I'm wrong --
The current set-cookie typings don't have the callback as the final arg, and the package promisifies that function (which needs that callback to the the final argument). Should opts and cb be swapped?

undici and native Node.js `fetch` support

Since Node.js 17.5, we can pass --experimental-fetch to use the built-in undici fetch implementation.

Sadly even if fetch-cookie now theoretically supports WHATWG fetch standard (through response.headers.get('set-cookie') and splitCookieString), undici in most cases drop the set-cookie header, most likely because the spec says it's a forbidden header, and fetch-cookie cannot work with it.

As pointed out by @justingrant in whatwg/fetch#1384 (comment) (I'm following up here because this discussion is off topic for the linked issue), undici do expose the set-cookie header in some cases.

I confirmed on Node 17.5 and I am able to read the Set-Cookie header:

(await fetch('https://wikipedia.com/')).headers.get('set-cookie')
'WMF-Last-Access=26-Feb-2022;Path=/;HttpOnly;secure;Expires=Wed, 30 Mar 2022 12:00:00 GMT, WMF-Last-Access-Global=26-Feb-2022;Path=/;Domain=.wikipedia.org;HttpOnly;secure;Expires=Wed, 30 Mar 2022 12:00:00 GMT, GeoIP=...; Path=/; secure; Domain=.wikipedia.org'

That's a good news but from my testing, the set-cookie header is not always returned. It seem to be related to responseTainting and the CORS implementation of undici but I couldn't figure precisely in what conditions undici will or will not drop the set-cookie header.

Typically in the earlier URL https://wikipedia.com/, it issues a redirect to https://www.wikipedia.org/ which is the actual response setting the cookie, as shown by:

curl 'https://www.wikipedia.org/' -H 'User-Agent:' -v 2>&1 | grep -i set-cookie
< set-cookie: WMF-Last-Access=26-Feb-2022;Path=/;HttpOnly;secure;Expires=Wed, 30 Mar 2022 12:00:00 GMT
< set-cookie: WMF-Last-Access-Global=26-Feb-2022;Path=/;Domain=.wikipedia.org;HttpOnly;secure;Expires=Wed, 30 Mar 2022 12:00:00 GMT
< set-cookie: GeoIP=...; Path=/; secure; Domain=.wikipedia.org

But fetching that URL with undici returns null for the set-cookie header:

(await fetch('https://www.wikipedia.org/')).headers.get('set-cookie')
null

Also every test I've done on a http://localhost URL failed to return a set-cookie header with undici:

http.createServer((req, res) => res.setHeader('set-cookie', 'foo=bar').end()).listen(8080)
<ref *1> Server
(await fetch('http://localhost:8080/')).headers.get('set-cookie')
null
http.request('http://localhost:8080/', res => console.log(res.headers['set-cookie'])).end()
[ 'foo=bar' ]

And the same goes for every request I've done with redirect: 'manual', which is a requirement for fetch-cookie to do its job.


I'd love fetch-cookie to eventually work with the native Node.js fetch implementation but until we can reliably get access to the set-cookie response header this will not be possible.

Broken support for WebPack's `enhanced-resolve` due to incorrect order of "default" condition in `package.json` "exports"

Culprit:

"type": "module",
"main": "./cjs/index-wrapper.js",
"module": "./esm/index.js",
"exports": {
"import": {
"default": "./esm/index.js",
"types": "./esm/index.d.ts"
},
"require": {
"default": "./cjs/index-wrapper.js",
"types": "./cjs/index.d.ts"
}
},
"types": "esm/index.d.ts",

Error:
"[webpack-cli] ModuleNotFoundError: Module not found: Error: Default condition should be last one"

Origin:
https://github.com/webpack/enhanced-resolve/blob/ddc96f8e738690166e7de77ea09c9e5aff52bb1b/lib/util/entrypoints.js#L453-L457

			if (i !== last) {
				if (condition === "default") {
					throw new Error("Default condition should be last one");
				}
			} 

Unable to use import syntax

Hi,

I am unfamiliar with how to use the new import syntax with this package so I was thinking it might not play nicely with the way the export was defined.

I would be happy to create a PR if this is an issue and we can decide on the correct approach since I cannot think of one that would not be a breaking change to the existing API.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.