Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: address compatibility issues with axios 1.7.8 (#953) #958

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

ArnaudBuchholz
Copy link

  • Added typescript validation during the unit tests
  • Fixed the issues detected during typescript validation

Copy link

codecov bot commented Dec 18, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 99.60%. Comparing base (4626ec0) to head (7b10ca9).
Report is 27 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #958   +/-   ##
=======================================
  Coverage   99.60%   99.60%           
=======================================
  Files          19       19           
  Lines        2509     2510    +1     
  Branches      223      221    -2     
=======================================
+ Hits         2499     2500    +1     
  Misses         10       10           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

src/cache/axios.ts Outdated Show resolved Hide resolved
@@ -30,7 +30,7 @@ export interface CacheAxiosResponse<R = any, D = any> extends AxiosResponse<R, D
*
* @see https://axios-cache-interceptor.js.org/config/response-object#id
*/
id: string;
id?: string;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will always be present

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here : that is exactly what breaks the compatibility with axios 1.7.8

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By the way, I modified the test to assess this id is present.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but where does it break the compatibility? that's where you need to fix it, an interface cannot block its extension to add new fields.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, the problem appears when using this interface, after removing the optional flag, here is the transpiler message :

The types of 'interceptors.response.use' are incompatible between these types.
    Types of parameters 'onFulfilled' and 'onFulfilled' are incompatible.
      Type 'AxiosResponse<any, any> | Promise<AxiosResponse<any, any>>' is not assignable to type 'CacheAxiosResponse<any, any> | Promise<CacheAxiosResponse<any, any>>'.
        Type 'AxiosResponse<any, any>' is not assignable to type 'CacheAxiosResponse<any, any> | Promise<CacheAxiosResponse<any, any>>'.
          Type 'AxiosResponse<any, any>' is missing the following properties from type 'CacheAxiosResponse<any, any>': id, cached

because of the following :

export interface AxiosCacheInstance extends CacheInstance, AxiosInstance {
  /* ... */
  interceptors: {
    request: AxiosInterceptorManager<InternalCacheRequestConfig>;
    response: AxiosInterceptorManager<CacheAxiosResponse>;
  };

I noticed that in the InternalCacheRequestConfig, id and cache were optional, I assumed it was to solve the same issue.

But I get your point : if anybody relies on the CacheAxiosResponse interface, this represents a breaking change. However, since it is not explicitly documented, I assumed it was OK.

Copy link
Owner

@arthurfiorette arthurfiorette Dec 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a dedicated doc page just for these 2 fields: https://axios-cache-interceptor.js.org/config/response-object.

Isn't there another way to fix it?

Probably just as I did with InternalCacheRequestConfig

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, reviewing the implementation, theCacheRequestConfig uses optional on id and cache as documented here : https://axios-cache-interceptor.js.org/config/request-specifics

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pushed a new version that keeps backward compatibility but it requires many changes across the code. The most important is to ensure that, in the end, the onFulfilled receives the CacheAxiosResponse response... which is the case.

I am not able to evaluate if this change can break anybody implementation (do people rely on the AxiosCacheInstance interface ?), but it works on my use.

test/storage/storages.ts Outdated Show resolved Hide resolved
test/interceptors/response.test.ts Outdated Show resolved Hide resolved
test/interceptors/request.test.ts Outdated Show resolved Hide resolved
[symbol]: true
});
} as CacheRequestConfig);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having a single ts-expect-error comment covering a single field is safer than casting the whole object into the shape you want.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, proposing a different approach to remove TypeScript error without special handling

test/storage/storages.test.ts Outdated Show resolved Hide resolved
@@ -321,7 +321,7 @@ export interface CacheInstance {
* @default defaultResponseInterceptor
* @see https://axios-cache-interceptor.js.org/config#responseinterceptor
*/
responseInterceptor: AxiosInterceptor<CacheAxiosResponse<unknown, unknown>>;
responseInterceptor: AxiosInterceptor<AxiosResponse<unknown, unknown>>;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be great if you could keep the CacheAxiosResponse type here.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately changing this cascades up to the initial problem : the definition of AxiosCacheInstance.
Can you elaborate on why you want this responseInterceptor type to be using CacheAxiosResponse, it may help me understand what are my options ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants