newsiberian / apollo-link-token-refresh

Apollo Link that performs access tokens (JWT) renew
MIT License
337 stars 45 forks source link

fetchAccessToken tightly couple to Fetch API #5

Open amacleay opened 6 years ago

amacleay commented 6 years ago

I am trying to use apollo-link-token-refresh in a typescript project. In this project, we are using a library function to make the access token refresh request, and that library function does not expose the Fetch API underneath:

interface RefreshedSession {
  accessToken: string;
  expirationTimestamp: number;
}
async function refreshSession: Promise<RefreshedSession> {
  const resp = await fetch(...);
  ...
  return {
    accessToken,
    expirationTimestamp;
  };
}

I believe I should be able to use apollo-link-token-refresh without casting to any or using any other type hacks. Perhaps TokenRefreshLink should have an optional type parameter.

new TokenRefreshLink<RefreshedSession>({
  fetchAccessToken: refreshSession,
  handleResponse: (_, __) => response => response.accessToken,
  handleFetch: saveToken,
  handleError: console.error,
  },
});

Workaround: force my session response to be of a modified Response type:

new TokenRefreshLink({
  fetchAccessToken: async () => {
    const refreshedSession = await refreshSession();
    const fakeReq = new Request('uri://fake');
    return Object.assign(fakeReq, refreshedSession);
  },
  handleResponse: (_, __) => (response: Response & RefreshedSession) => response.accessToken,
  handleFetch: saveToken,
  handleError: console.error,
  },
});
newsiberian commented 6 years ago

Hi, @amacleay, did you try to do something like this?:

accessTokenField: 'refreshedSession', // Your object name with `accessToken` and 
// `expirationTimestamp` that returned by fetch
fetchAccessToken: fetch(...),
handleResponse: (_, __) => (response: typeYouNeed) => {
  ...
  return {
    accessToken,
    expirationTimestamp
  };
},
handleFetch: ({ accessToken, expirationTimestamp }) => saveToken
amacleay commented 6 years ago

That would certainly work as I've laid out the issue.

In actual fact, though, I need to use a function in fetchAccessToken that doesn't expose the fetch API at all: my refreshSession function is actually wrapping a call to apollo-client

newsiberian commented 6 years ago

Can you make a PR that allows to avoid cases like yours?