Skip to content

Commit 870ba80

Browse files
authored
fix: [GH-267] Fix CacheOptions Related Types (#268)
* Fix RequestOptions.cacheOptions function return type to also return a non-promise value. * Fix propagation of the cache options generic type RequestOptions and AugmentedRequest. Fixes #267
1 parent aed01be commit 870ba80

File tree

3 files changed

+30
-23
lines changed

3 files changed

+30
-23
lines changed

.changeset/perfect-experts-sell.md

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@apollo/datasource-rest': patch
3+
---
4+
5+
* Fix RequestOptions.cacheOptions function return type to also return a non-promise value.
6+
* Fix propagation of the cache options generic type `RequestOptions` and `AugmentedRequest`.

src/HTTPCache.ts

+10-11
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,7 @@ import nodeFetch, {
55
} from 'node-fetch';
66
import CachePolicy from 'http-cache-semantics';
77
import type { Options as HttpCacheSemanticsOptions } from 'http-cache-semantics';
8-
import type {
9-
Fetcher,
10-
FetcherResponse,
11-
FetcherRequestInit,
12-
} from '@apollo/utils.fetcher';
8+
import type { Fetcher, FetcherResponse } from '@apollo/utils.fetcher';
139
import {
1410
type KeyValueCache,
1511
InMemoryLRUCache,
@@ -53,15 +49,15 @@ export class HTTPCache<CO extends CacheOptions = CacheOptions> {
5349

5450
async fetch(
5551
url: URL,
56-
requestOpts: FetcherRequestInit = {},
52+
requestOpts: RequestOptions<CO> = {},
5753
cache?: {
5854
cacheKey?: string;
5955
cacheOptions?:
6056
| CO
6157
| ((
6258
url: string,
6359
response: FetcherResponse,
64-
request: RequestOptions,
60+
request: RequestOptions<CO>,
6561
) => ValueOrPromise<CO | undefined>);
6662
httpCacheSemanticsCachePolicyOptions?: HttpCacheSemanticsOptions;
6763
},
@@ -148,7 +144,7 @@ export class HTTPCache<CO extends CacheOptions = CacheOptions> {
148144
const revalidationHeaders = policy.revalidationHeaders(
149145
policyRequestFrom(urlString, requestOpts),
150146
);
151-
const revalidationRequest: RequestOptions = {
147+
const revalidationRequest = {
152148
...requestOpts,
153149
headers: cachePolicyHeadersToFetcherHeadersInit(revalidationHeaders),
154150
};
@@ -185,15 +181,15 @@ export class HTTPCache<CO extends CacheOptions = CacheOptions> {
185181
private async storeResponseAndReturnClone(
186182
url: string,
187183
response: FetcherResponse,
188-
request: RequestOptions,
184+
request: RequestOptions<CO>,
189185
policy: SneakyCachePolicy,
190186
cacheKey: string,
191187
cacheOptions?:
192188
| CO
193189
| ((
194190
url: string,
195191
response: FetcherResponse,
196-
request: RequestOptions,
192+
request: RequestOptions<CO>,
197193
) => ValueOrPromise<CO | undefined>),
198194
): Promise<ResponseWithCacheWritePromise> {
199195
if (typeof cacheOptions === 'function') {
@@ -288,7 +284,10 @@ function canBeRevalidated(response: FetcherResponse): boolean {
288284
return response.headers.has('ETag') || response.headers.has('Last-Modified');
289285
}
290286

291-
function policyRequestFrom(url: string, request: RequestOptions) {
287+
function policyRequestFrom<CO extends CacheOptions = CacheOptions>(
288+
url: string,
289+
request: RequestOptions<CO>,
290+
) {
292291
return {
293292
url,
294293
method: request.method ?? 'GET',

src/RESTDataSource.ts

+14-12
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ export type RequestOptions<CO extends CacheOptions = CacheOptions> =
4343
| ((
4444
url: string,
4545
response: FetcherResponse,
46-
request: RequestOptions,
47-
) => Promise<CO | undefined>);
46+
request: RequestOptions<CO>,
47+
) => ValueOrPromise<CO | undefined>);
4848
/**
4949
* If provided, this is passed through as the third argument to `new
5050
* CachePolicy()` from the `http-cache-semantics` npm package as part of the
@@ -205,7 +205,7 @@ export abstract class RESTDataSource<CO extends CacheOptions = CacheOptions> {
205205
// won't return a cache entry whose Vary-ed header field doesn't match, new
206206
// responses can overwrite old ones with different Vary-ed header fields if
207207
// you don't take the header into account in the cache key.
208-
protected cacheKeyFor(url: URL, request: RequestOptions): string {
208+
protected cacheKeyFor(url: URL, request: RequestOptions<CO>): string {
209209
return request.cacheKey ?? `${request.method ?? 'GET'} ${url}`;
210210
}
211211

@@ -227,7 +227,7 @@ export abstract class RESTDataSource<CO extends CacheOptions = CacheOptions> {
227227
*/
228228
protected requestDeduplicationPolicyFor(
229229
url: URL,
230-
request: RequestOptions,
230+
request: RequestOptions<CO>,
231231
): RequestDeduplicationPolicy {
232232
const method = request.method ?? 'GET';
233233
// Start with the cache key that is used for the shared header-sensitive
@@ -258,12 +258,12 @@ export abstract class RESTDataSource<CO extends CacheOptions = CacheOptions> {
258258

259259
protected willSendRequest?(
260260
path: string,
261-
requestOpts: AugmentedRequest,
261+
requestOpts: AugmentedRequest<CO>,
262262
): ValueOrPromise<void>;
263263

264264
protected resolveURL(
265265
path: string,
266-
_request: AugmentedRequest,
266+
_request: AugmentedRequest<CO>,
267267
): ValueOrPromise<URL> {
268268
return new URL(path, this.baseURL);
269269
}
@@ -276,7 +276,7 @@ export abstract class RESTDataSource<CO extends CacheOptions = CacheOptions> {
276276

277277
protected didEncounterError(
278278
_error: Error,
279-
_request: RequestOptions,
279+
_request: RequestOptions<CO>,
280280
// TODO(v7): this shouldn't be optional in a future major version
281281
_url?: URL,
282282
) {
@@ -331,7 +331,9 @@ export abstract class RESTDataSource<CO extends CacheOptions = CacheOptions> {
331331
return cloneDeep(parsedBody);
332332
}
333333

334-
protected shouldJSONSerializeBody(body: RequestWithBody['body']): boolean {
334+
protected shouldJSONSerializeBody(
335+
body: RequestWithBody<CO>['body'],
336+
): boolean {
335337
return !!(
336338
// We accept arbitrary objects and arrays as body and serialize them as JSON.
337339
(
@@ -352,7 +354,7 @@ export abstract class RESTDataSource<CO extends CacheOptions = CacheOptions> {
352354

353355
protected async throwIfResponseIsError(options: {
354356
url: URL;
355-
request: RequestOptions;
357+
request: RequestOptions<CO>;
356358
response: FetcherResponse;
357359
parsedBody: unknown;
358360
}) {
@@ -367,7 +369,7 @@ export abstract class RESTDataSource<CO extends CacheOptions = CacheOptions> {
367369
parsedBody,
368370
}: {
369371
url?: URL;
370-
request?: RequestOptions;
372+
request?: RequestOptions<CO>;
371373
response: FetcherResponse;
372374
parsedBody: unknown;
373375
}) {
@@ -483,7 +485,7 @@ export abstract class RESTDataSource<CO extends CacheOptions = CacheOptions> {
483485
});
484486
}
485487

486-
const augmentedRequest: AugmentedRequest = {
488+
const augmentedRequest: AugmentedRequest<CO> = {
487489
...incomingRequest,
488490
// guarantee params and headers objects before calling `willSendRequest` for convenience
489491
params:
@@ -632,7 +634,7 @@ export abstract class RESTDataSource<CO extends CacheOptions = CacheOptions> {
632634

633635
protected async trace<TResult>(
634636
url: URL,
635-
request: RequestOptions,
637+
request: RequestOptions<CO>,
636638
fn: () => Promise<TResult>,
637639
): Promise<TResult> {
638640
if (NODE_ENV === 'development') {

0 commit comments

Comments
 (0)