@graphql-box/cache-manager 5.3.3 → 5.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/dist/cjs/index.cjs +1 -1
  2. package/dist/cjs/index.cjs.map +1 -1
  3. package/dist/esm/index.mjs +1 -1
  4. package/dist/esm/index.mjs.map +1 -1
  5. package/dist/production.analysis.txt +148 -148
  6. package/dist/types/cjs/constants.d.cts +5 -5
  7. package/dist/types/cjs/constants.d.cts.map +1 -1
  8. package/dist/types/cjs/debug/logCacheEntry.d.cts.map +1 -1
  9. package/dist/types/cjs/debug/logCacheQuery.d.cts.map +1 -1
  10. package/dist/types/cjs/debug/logPartialCompiled.d.cts.map +1 -1
  11. package/dist/types/cjs/helpers/createEntityDataKey.d.cts.map +1 -1
  12. package/dist/types/cjs/helpers/filterField.d.cts.map +1 -1
  13. package/dist/types/cjs/helpers/filterFragmentDefinitions.d.cts.map +1 -1
  14. package/dist/types/cjs/helpers/filterOutPropsWithEntityArgsOrDirectives.d.cts.map +1 -1
  15. package/dist/types/cjs/helpers/filterOutPropsWithEntityOrArgs.d.cts.map +1 -1
  16. package/dist/types/cjs/helpers/filterQuery.d.cts.map +1 -1
  17. package/dist/types/cjs/helpers/getDataValue.d.cts.map +1 -1
  18. package/dist/types/cjs/helpers/hasTypename.d.cts.map +1 -1
  19. package/dist/types/cjs/helpers/isFieldEntity.d.cts.map +1 -1
  20. package/dist/types/cjs/helpers/mergeObjects.d.cts.map +1 -1
  21. package/dist/types/cjs/helpers/normalizePatchResponseData.d.cts +4 -4
  22. package/dist/types/cjs/helpers/validTypeIdValue.d.cts.map +1 -1
  23. package/dist/types/cjs/main.d.cts +6 -6
  24. package/dist/types/cjs/main.d.cts.map +1 -1
  25. package/dist/types/cjs/types.d.cts +2 -2
  26. package/dist/types/esm/constants.d.ts +5 -5
  27. package/dist/types/esm/constants.d.ts.map +1 -1
  28. package/dist/types/esm/debug/logCacheEntry.d.ts.map +1 -1
  29. package/dist/types/esm/debug/logCacheQuery.d.ts.map +1 -1
  30. package/dist/types/esm/debug/logPartialCompiled.d.ts.map +1 -1
  31. package/dist/types/esm/helpers/createEntityDataKey.d.ts.map +1 -1
  32. package/dist/types/esm/helpers/filterField.d.ts.map +1 -1
  33. package/dist/types/esm/helpers/filterFragmentDefinitions.d.ts.map +1 -1
  34. package/dist/types/esm/helpers/filterOutPropsWithEntityArgsOrDirectives.d.ts.map +1 -1
  35. package/dist/types/esm/helpers/filterOutPropsWithEntityOrArgs.d.ts.map +1 -1
  36. package/dist/types/esm/helpers/filterQuery.d.ts.map +1 -1
  37. package/dist/types/esm/helpers/getDataValue.d.ts.map +1 -1
  38. package/dist/types/esm/helpers/hasTypename.d.ts.map +1 -1
  39. package/dist/types/esm/helpers/isFieldEntity.d.ts.map +1 -1
  40. package/dist/types/esm/helpers/mergeObjects.d.ts.map +1 -1
  41. package/dist/types/esm/helpers/normalizePatchResponseData.d.ts +4 -4
  42. package/dist/types/esm/helpers/validTypeIdValue.d.ts.map +1 -1
  43. package/dist/types/esm/main.d.ts +6 -6
  44. package/dist/types/esm/main.d.ts.map +1 -1
  45. package/dist/types/esm/types.d.ts +2 -2
  46. package/dist/types/tsconfig.build.tsbuildinfo +1 -1
  47. package/package.json +17 -19
  48. package/src/__snapshots__/index.test.ts.snap +2592 -2592
  49. package/src/constants.ts +5 -5
  50. package/src/debug/logCacheEntry.ts +5 -3
  51. package/src/debug/logCacheQuery.ts +14 -4
  52. package/src/debug/logPartialCompiled.ts +1 -1
  53. package/src/helpers/checkFieldPathChecklist.ts +1 -1
  54. package/src/helpers/createEntityDataKey.ts +3 -1
  55. package/src/helpers/filterField.ts +3 -3
  56. package/src/helpers/filterFragmentDefinitions.ts +4 -2
  57. package/src/helpers/filterFragmentSpreads.ts +3 -3
  58. package/src/helpers/filterIDsAndTypeNames.ts +4 -4
  59. package/src/helpers/filterInlineFragments.ts +1 -1
  60. package/src/helpers/filterOperationAndFragmentDefinitions.ts +2 -2
  61. package/src/helpers/filterOutPropsWithEntityArgsOrDirectives.ts +4 -1
  62. package/src/helpers/filterOutPropsWithEntityOrArgs.ts +7 -3
  63. package/src/helpers/filterQuery.ts +4 -2
  64. package/src/helpers/getDataValue.ts +4 -0
  65. package/src/helpers/isFieldEntity.ts +1 -1
  66. package/src/helpers/isFirstResponseChunk.ts +1 -1
  67. package/src/helpers/isLastResponseChunk.ts +1 -1
  68. package/src/helpers/isNotLastResponseChunk.ts +1 -1
  69. package/src/helpers/isNotResponseChunk.ts +1 -1
  70. package/src/helpers/mergeObjects.ts +2 -0
  71. package/src/helpers/mergeResponseDataSets.ts +1 -1
  72. package/src/helpers/normalizePatchResponseData.ts +1 -1
  73. package/src/helpers/validTypeIdValue.ts +3 -1
  74. package/src/index.test.ts +57 -57
  75. package/src/main.ts +133 -104
  76. package/src/types.ts +7 -7
package/src/main.ts CHANGED
@@ -120,7 +120,7 @@ export class CacheManager implements CacheManagerDef {
120
120
  }
121
121
 
122
122
  const { isEntity, possibleTypes } = fieldTypeInfo;
123
- return isEntity || possibleTypes.some(type => !!type.isEntity);
123
+ return isEntity || possibleTypes.some(type => type.isEntity);
124
124
  }
125
125
 
126
126
  private static _isNodeRequestFieldPath(fieldTypeInfo?: FieldTypeInfo): boolean {
@@ -137,7 +137,7 @@ export class CacheManager implements CacheManagerDef {
137
137
 
138
138
  private static _mergeResponseCacheMetadata(
139
139
  cacheMetadata: CacheMetadata,
140
- partialQueryResponse?: PartialQueryResponse
140
+ partialQueryResponse?: PartialQueryResponse,
141
141
  ): CacheMetadata {
142
142
  if (!partialQueryResponse) {
143
143
  return cacheMetadata;
@@ -149,7 +149,7 @@ export class CacheManager implements CacheManagerDef {
149
149
  private static _setCachedData(
150
150
  responseData: unknown,
151
151
  { data }: MergedCachedFieldData,
152
- propNameOrIndex: string | number
152
+ propNameOrIndex: string | number,
153
153
  ): void {
154
154
  const setData = (value: unknown) => {
155
155
  if (isArray(responseData) && isNumber(propNameOrIndex)) {
@@ -174,7 +174,7 @@ export class CacheManager implements CacheManagerDef {
174
174
  { propNameOrIndex, requestFieldPath }: KeysAndPaths,
175
175
  typeNamesAndKind: TypenamesAndKind,
176
176
  _options: RequestOptions,
177
- { operation }: CacheManagerContext
177
+ { operation }: CacheManagerContext,
178
178
  ) {
179
179
  CacheManager._setCacheMetadata(cacheMetadata, cachedFieldData.cacheability, requestFieldPath, operation);
180
180
  CacheManager._setFieldPathChecklist(fieldPathChecklist, cachedFieldData, requestFieldPath, typeNamesAndKind);
@@ -185,7 +185,7 @@ export class CacheManager implements CacheManagerDef {
185
185
  cacheMetadata: CacheMetadata,
186
186
  cacheability: Cacheability | undefined,
187
187
  requestFieldPath: string,
188
- operation: string
188
+ operation: string,
189
189
  ): void {
190
190
  if (!cacheability) {
191
191
  return;
@@ -203,7 +203,7 @@ export class CacheManager implements CacheManagerDef {
203
203
  fieldPathChecklist: FieldPathChecklist,
204
204
  { data }: MergedCachedFieldData,
205
205
  requestFieldPath: string,
206
- { dataTypename: dataTypeName, fieldTypename: fieldTypeName, fragmentKind, fragmentName }: TypenamesAndKind
206
+ { dataTypename: dataTypeName, fieldTypename: fieldTypeName, fragmentKind, fragmentName }: TypenamesAndKind,
207
207
  ): void {
208
208
  if (isUndefined(fieldTypeName) || fragmentKind === Kind.FRAGMENT_SPREAD) {
209
209
  if (fieldPathChecklist.has(requestFieldPath)) {
@@ -231,14 +231,14 @@ export class CacheManager implements CacheManagerDef {
231
231
  ]);
232
232
  }
233
233
 
234
- private _cache: Core;
235
- private _cacheTiersEnabled: CacheTiersEnabled = { entity: false, queryResponse: true, requestPath: false };
236
- private _cascadeCacheControl: boolean;
237
- private _fallbackOperationCacheability: string;
234
+ private readonly _cache: Core;
235
+ private readonly _cacheTiersEnabled: CacheTiersEnabled = { entity: false, queryResponse: true, requestPath: false };
236
+ private readonly _cascadeCacheControl: boolean;
237
+ private readonly _fallbackOperationCacheability: string;
238
238
  private _partialQueryResponses: PartialQueryResponses = new Map();
239
239
  private _responseChunksAwaitingCaching = new Map<string, RawResponseDataWithMaybeCacheMetadata[]>();
240
- private _typeCacheDirectives: Record<string, string>;
241
- private _typeIDKey: string;
240
+ private readonly _typeCacheDirectives: Record<string, string>;
241
+ private readonly _typeIDKey: string;
242
242
 
243
243
  constructor(options: UserOptions) {
244
244
  const errors: ArgsError[] = [];
@@ -267,7 +267,7 @@ export class CacheManager implements CacheManagerDef {
267
267
  public async analyzeQuery(
268
268
  requestData: RequestData,
269
269
  options: RequestOptions,
270
- context: RequestContext
270
+ context: RequestContext,
271
271
  ): Promise<AnalyzeQueryResult> {
272
272
  // the client has already checked the query response cache with
273
273
  // `checkQueryResponseCacheEntry`, so at this point the entity and
@@ -290,7 +290,7 @@ export class CacheManager implements CacheManagerDef {
290
290
  /**
291
291
  * Second half of check is required for the scenario where the only matching data is
292
292
  * the typeIDKey field, i.e. "id", in which case there is no point settings a partial
293
- * query reponse because we request the typeIDKey field with every request.
293
+ * query response because we request the typeIDKey field with every request.
294
294
  */
295
295
  if (fieldCount.missing === fieldCount.total || areOnlyPopulatedFieldsTypeIdKeys(data, this._typeIDKey)) {
296
296
  return { updated: requestData };
@@ -330,7 +330,7 @@ export class CacheManager implements CacheManagerDef {
330
330
  updatedRequestData: RequestData | undefined,
331
331
  rawResponseData: RawResponseDataWithMaybeCacheMetadata,
332
332
  options: RequestOptions,
333
- context: RequestContext
333
+ context: RequestContext,
334
334
  ): Promise<ResponseData> {
335
335
  const cacheManagerContext: CacheManagerContext = {
336
336
  ...context,
@@ -345,7 +345,7 @@ export class CacheManager implements CacheManagerDef {
345
345
  requestData: RequestData,
346
346
  rawResponseData: RawResponseDataWithMaybeCacheMetadata,
347
347
  options: RequestOptions,
348
- context: RequestContext
348
+ context: RequestContext,
349
349
  ): Promise<ResponseData> {
350
350
  const cacheManagerContext: CacheManagerContext = {
351
351
  ...context,
@@ -360,7 +360,7 @@ export class CacheManager implements CacheManagerDef {
360
360
  cacheType: CacheTypes,
361
361
  hash: string,
362
362
  options: RequestOptions,
363
- context: RequestContext & { requestFieldCacheKey?: string }
363
+ context: RequestContext & { requestFieldCacheKey?: string },
364
364
  ): Promise<CheckCacheEntryResult | false> {
365
365
  if (allCacheTiersDisabled(this._cacheTiersEnabled)) {
366
366
  return false;
@@ -372,19 +372,19 @@ export class CacheManager implements CacheManagerDef {
372
372
  public async checkQueryResponseCacheEntry(
373
373
  hash: string,
374
374
  options: RequestOptions,
375
- context: RequestContext
375
+ context: RequestContext,
376
376
  ): Promise<ResponseData | false> {
377
377
  if (!queryResponseCacheTierEnabled(this._cacheTiersEnabled)) {
378
378
  return false;
379
379
  }
380
380
 
381
- const result = await this._checkCacheEntry(QUERY_RESPONSES, hash, options, context);
381
+ const result = await this._checkCacheEntry<QueryResponseCacheEntry>(QUERY_RESPONSES, hash, options, context);
382
382
 
383
383
  if (!result) {
384
384
  return false;
385
385
  }
386
386
 
387
- const { cacheMetadata, data } = result.entry as QueryResponseCacheEntry;
387
+ const { cacheMetadata, data } = result.entry;
388
388
 
389
389
  return {
390
390
  cacheMetadata: rehydrateCacheMetadata(cacheMetadata),
@@ -402,7 +402,7 @@ export class CacheManager implements CacheManagerDef {
402
402
  requestData: RequestData,
403
403
  responseData: ResponseData,
404
404
  options: RequestOptions,
405
- context: CacheManagerContext
405
+ context: CacheManagerContext,
406
406
  ): Promise<void> {
407
407
  if (queryResponseCacheTierEnabled(this._cacheTiersEnabled)) {
408
408
  return this._setQueryResponseCacheEntry(requestData.hash, responseData, options, context);
@@ -414,7 +414,7 @@ export class CacheManager implements CacheManagerDef {
414
414
  cachedAncestorFieldData: CachedAncestorFieldData,
415
415
  cachedResponseData: CachedResponseData & { data: unknown },
416
416
  options: RequestOptions,
417
- context: CacheManagerContext
417
+ context: CacheManagerContext,
418
418
  ): Promise<void> {
419
419
  await (hasChildFields(fieldNode, { fragmentDefinitions: context.fragmentDefinitions })
420
420
  ? this._analyzeParentFieldNode(fieldNode, cachedAncestorFieldData, cachedResponseData, options, context)
@@ -426,7 +426,7 @@ export class CacheManager implements CacheManagerDef {
426
426
  cachedAncestorFieldData: CachedAncestorFieldData,
427
427
  cachedResponseData: CachedResponseData & { data: unknown },
428
428
  options: RequestOptions,
429
- context: CacheManagerContext
429
+ context: CacheManagerContext,
430
430
  ): Promise<void> {
431
431
  const keysAndPaths = buildFieldKeysAndPaths(fieldNode, cachedAncestorFieldData, context);
432
432
  const { hashedRequestFieldCacheKey, propNameOrIndex, requestFieldCacheKey, requestFieldPath } = keysAndPaths;
@@ -436,8 +436,8 @@ export class CacheManager implements CacheManagerDef {
436
436
  const dataTypename = hasTypename(entityData)
437
437
  ? entityData.__typename
438
438
  : hasTypename(requestFieldPathData)
439
- ? requestFieldPathData.__typename
440
- : undefined;
439
+ ? requestFieldPathData.__typename
440
+ : undefined;
441
441
 
442
442
  const typenamesAndKind = {
443
443
  dataTypename,
@@ -455,7 +455,7 @@ export class CacheManager implements CacheManagerDef {
455
455
  cachedResponseData.fieldPathChecklist,
456
456
  { data: cachedFieldData },
457
457
  requestFieldPath,
458
- typenamesAndKind
458
+ typenamesAndKind,
459
459
  );
460
460
 
461
461
  CacheManager._setCachedData(cachedResponseData.data, { data: cachedFieldData }, propNameOrIndex);
@@ -464,7 +464,7 @@ export class CacheManager implements CacheManagerDef {
464
464
  hashedRequestFieldCacheKey,
465
465
  requestFieldCacheKey,
466
466
  options,
467
- context
467
+ context,
468
468
  );
469
469
 
470
470
  CacheManager._setCachedResponseSlice(
@@ -473,7 +473,7 @@ export class CacheManager implements CacheManagerDef {
473
473
  keysAndPaths,
474
474
  typenamesAndKind,
475
475
  options,
476
- context
476
+ context,
477
477
  );
478
478
  }
479
479
  }
@@ -483,29 +483,42 @@ export class CacheManager implements CacheManagerDef {
483
483
  cachedAncestorFieldData: CachedAncestorFieldData,
484
484
  cachedResponseData: CachedResponseData,
485
485
  options: RequestOptions,
486
- context: CacheManagerContext
486
+ context: CacheManagerContext,
487
487
  ): Promise<void> {
488
488
  const keysAndPaths = buildFieldKeysAndPaths(fieldNode, cachedAncestorFieldData, context);
489
489
  const { propNameOrIndex, requestFieldCacheKey, requestFieldPath } = keysAndPaths;
490
- const fieldTypeInfo = context.fieldTypeMap.get(requestFieldPath)!;
490
+ const fieldTypeInfo = context.fieldTypeMap.get(requestFieldPath);
491
+
492
+ if (!fieldTypeInfo) {
493
+ return;
494
+ }
491
495
 
492
496
  const { cacheability, data, entityData, requestFieldPathData } = await this._retrieveCachedParentNodeData(
493
497
  cachedAncestorFieldData,
494
498
  keysAndPaths,
495
499
  fieldTypeInfo,
496
500
  options,
497
- context
501
+ context,
498
502
  );
499
503
 
500
504
  const { fragmentKind, fragmentName, typeName } = cachedAncestorFieldData;
505
+ // Don't get this one, need to look into it more
506
+ // eslint-disable-next-line @typescript-eslint/no-confusing-void-expression
507
+ const dataTypename = get(data, TYPE_NAME_KEY);
501
508
 
502
509
  CacheManager._setCachedResponseSlice(
503
510
  { cacheability, data },
504
511
  cachedResponseData,
505
512
  keysAndPaths,
506
- { dataTypename: get(data, TYPE_NAME_KEY), fieldTypename: typeName, fragmentKind, fragmentName },
513
+
514
+ {
515
+ dataTypename,
516
+ fieldTypename: typeName,
517
+ fragmentKind,
518
+ fragmentName,
519
+ },
507
520
  options,
508
- context
521
+ context,
509
522
  );
510
523
 
511
524
  if (!isObjectLike(data)) {
@@ -523,7 +536,7 @@ export class CacheManager implements CacheManagerDef {
523
536
  childTypeName: string | undefined,
524
537
  childFragmentKind: string | undefined,
525
538
  childFragmentName: string | undefined,
526
- childIndex?: number
539
+ childIndex?: number,
527
540
  ) => {
528
541
  promises.push(
529
542
  this._analyzeFieldNode(
@@ -541,19 +554,18 @@ export class CacheManager implements CacheManagerDef {
541
554
  },
542
555
  {
543
556
  ...cachedResponseData,
544
- /**
545
- * `cachedResponseData.data[propNameOrIndex]` will always be either an empty array
546
- * or an empty object at this point as based on whether `data` is object-like
547
- * `cachedResponseData.data[propNameOrIndex]` is set accordingly in
548
- * _setCachedResponseData > _setCachedData
549
- */
557
+ // `cachedResponseData.data[propNameOrIndex]` will always be either an empty array
558
+ // or an empty object at this point as based on whether `data` is object-like
559
+ // `cachedResponseData.data[propNameOrIndex]` is set accordingly in
560
+ // _setCachedResponseData > _setCachedData
561
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
550
562
  data: getDataValue<PlainData>(cachedResponseData.data, propNameOrIndex)!,
551
563
  },
552
564
  options,
553
- context
554
- )
565
+ context,
566
+ ),
555
567
  );
556
- }
568
+ },
557
569
  );
558
570
 
559
571
  await Promise.all(promises);
@@ -563,7 +575,7 @@ export class CacheManager implements CacheManagerDef {
563
575
  { ast }: RequestData,
564
576
  { data, ...otherProps }: RawResponseDataWithMaybeCacheMetadata,
565
577
  options: RequestOptions,
566
- context: CacheManagerContext
578
+ context: CacheManagerContext,
567
579
  ): CacheMetadata {
568
580
  const cacheMetadata = this._createCacheMetadata({ data, ...otherProps }, context);
569
581
  const queryNode = getOperationDefinitions(ast, context.operation)[0];
@@ -584,7 +596,7 @@ export class CacheManager implements CacheManagerDef {
584
596
  { requestFieldPath: context.operation },
585
597
  { cacheMetadata, data },
586
598
  options,
587
- context
599
+ context,
588
600
  );
589
601
 
590
602
  return cacheMetadata;
@@ -595,7 +607,7 @@ export class CacheManager implements CacheManagerDef {
595
607
  updatedRequestData: RequestData | undefined,
596
608
  rawResponseData: RawResponseDataWithMaybeCacheMetadata,
597
609
  options: RequestOptions,
598
- context: CacheManagerContext
610
+ context: CacheManagerContext,
599
611
  ): Promise<ResponseData> {
600
612
  const normalizedResponseData = normalizePatchResponseData(rawResponseData, context);
601
613
  let responseDataForCaching: RawResponseDataWithMaybeCacheMetadata | undefined = normalizedResponseData;
@@ -625,8 +637,8 @@ export class CacheManager implements CacheManagerDef {
625
637
  requestFieldPathData: structuredClone(data),
626
638
  },
627
639
  options,
628
- context
629
- )
640
+ context,
641
+ ),
630
642
  );
631
643
  }
632
644
 
@@ -638,7 +650,7 @@ export class CacheManager implements CacheManagerDef {
638
650
 
639
651
  if (context.queryFiltered && updatedRequestData) {
640
652
  dataCaching.push(
641
- this._setQueryResponseCacheEntry(updatedRequestData.hash, { cacheMetadata, data }, options, context)
653
+ this._setQueryResponseCacheEntry(updatedRequestData.hash, { cacheMetadata, data }, options, context),
642
654
  );
643
655
 
644
656
  partialQueryResponse = this._getPartialQueryResponse(requestData.hash);
@@ -652,8 +664,8 @@ export class CacheManager implements CacheManagerDef {
652
664
  requestData.hash,
653
665
  { cacheMetadata: queryCacheMetadata, data: queryData },
654
666
  options,
655
- context
656
- )
667
+ context,
668
+ ),
657
669
  );
658
670
  }
659
671
 
@@ -683,7 +695,7 @@ export class CacheManager implements CacheManagerDef {
683
695
  cacheType: CacheTypes,
684
696
  hash: string,
685
697
  options: RequestOptions,
686
- context: CacheManagerContext & { requestFieldCacheKey?: string }
698
+ context: CacheManagerContext & { requestFieldCacheKey?: string },
687
699
  ): Promise<CheckCacheEntryResult<T> | false> {
688
700
  try {
689
701
  const cacheability = await this._hasCacheEntry(cacheType, hash);
@@ -706,7 +718,7 @@ export class CacheManager implements CacheManagerDef {
706
718
 
707
719
  private _createCacheMetadata(
708
720
  { _cacheMetadata, headers }: RawResponseDataWithMaybeCacheMetadata,
709
- { operation }: CacheManagerContext
721
+ { operation }: CacheManagerContext,
710
722
  ): CacheMetadata {
711
723
  const cacheMetadata = new Map<string, Cacheability>();
712
724
 
@@ -730,7 +742,7 @@ export class CacheManager implements CacheManagerDef {
730
742
  cacheType: CacheTypes,
731
743
  hash: string,
732
744
  _options: RequestOptions,
733
- _context: CacheManagerContext & { requestFieldCacheKey?: string }
745
+ _context: CacheManagerContext & { requestFieldCacheKey?: string },
734
746
  ): Promise<T | undefined> {
735
747
  return this._cache.get<T>(`${cacheType}::${hash}`);
736
748
  }
@@ -762,10 +774,12 @@ export class CacheManager implements CacheManagerDef {
762
774
  ancestorKeysAndPaths: AncestorKeysAndPaths,
763
775
  { cacheMetadata, entityData, requestFieldPathData }: ResponseDataForCaching,
764
776
  options: RequestOptions,
765
- context: CacheManagerContext
777
+ context: CacheManagerContext,
766
778
  ): Promise<void> {
767
779
  const keysAndPaths = buildFieldKeysAndPaths(field, ancestorKeysAndPaths, context);
768
780
  const { hashedRequestFieldCacheKey, requestFieldCacheKey, requestFieldPath, responseDataPath } = keysAndPaths;
781
+ // get has rubbish return typing
782
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
769
783
  const fieldData = get(requestFieldPathData, responseDataPath) as unknown;
770
784
  const fieldTypeInfo = context.fieldTypeMap.get(requestFieldPath);
771
785
  const cacheability = cacheMetadata.get(requestFieldPath);
@@ -786,7 +800,7 @@ export class CacheManager implements CacheManagerDef {
786
800
  _typeName: string | undefined,
787
801
  _fragmentKind: string | undefined,
788
802
  _fragmentName: string | undefined,
789
- childIndex?: number
803
+ childIndex?: number,
790
804
  ) => {
791
805
  promises.push(
792
806
  this._parseEntityAndRequestFieldPathCacheEntryData(
@@ -794,10 +808,10 @@ export class CacheManager implements CacheManagerDef {
794
808
  { index: childIndex, requestFieldCacheKey, requestFieldPath, responseDataPath },
795
809
  { cacheMetadata, entityData, requestFieldPathData },
796
810
  options,
797
- context
798
- )
811
+ context,
812
+ ),
799
813
  );
800
- }
814
+ },
801
815
  );
802
816
 
803
817
  await Promise.all(promises);
@@ -808,7 +822,7 @@ export class CacheManager implements CacheManagerDef {
808
822
  }
809
823
 
810
824
  const isEntity = isFieldEntity(fieldData, fieldTypeInfo, this._typeIDKey);
811
- const hasArgsOrDirectives = !!fieldTypeInfo.hasArguments || !!fieldTypeInfo.hasDirectives;
825
+ const hasArgsOrDirectives = fieldTypeInfo.hasArguments || fieldTypeInfo.hasDirectives;
812
826
 
813
827
  if (
814
828
  context.operation === OperationTypeNode.QUERY &&
@@ -823,7 +837,7 @@ export class CacheManager implements CacheManagerDef {
823
837
  fieldTypeInfo,
824
838
  },
825
839
  options,
826
- context
840
+ context,
827
841
  );
828
842
 
829
843
  if (hasChildFields(field, { fragmentDefinitions: context.fragmentDefinitions })) {
@@ -842,15 +856,17 @@ export class CacheManager implements CacheManagerDef {
842
856
  {
843
857
  cacheability,
844
858
  fieldData: filterOutPropsWithEntityOrArgs(
845
- structuredClone(get(entityData, responseDataPath)) as EntityData,
859
+ // Casting here for ease of typing
860
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
861
+ structuredClone(get(entityData, responseDataPath) as EntityData),
846
862
  field,
847
863
  keysAndPaths,
848
- context
864
+ context,
849
865
  ),
850
866
  fieldTypeInfo,
851
867
  },
852
868
  options,
853
- context
869
+ context,
854
870
  );
855
871
 
856
872
  set(entityData, responseDataPath, {
@@ -863,17 +879,17 @@ export class CacheManager implements CacheManagerDef {
863
879
  validTypeIDValue: string | number,
864
880
  { possibleTypes, typeName }: FieldTypeInfo,
865
881
  options: RequestOptions,
866
- context: CacheManagerContext
882
+ context: CacheManagerContext,
867
883
  ): Promise<Partial<CheckCacheEntryResult<EntityData>>> {
868
884
  const typeNames = [...possibleTypes.map(type => type.typeName), typeName];
869
885
 
870
886
  const checkResults = await Promise.all(
871
887
  typeNames.map(name =>
872
- this._checkCacheEntry<EntityData>(DATA_ENTITIES, `${name}::${validTypeIDValue}`, options, context)
873
- )
888
+ this._checkCacheEntry<EntityData>(DATA_ENTITIES, `${name}::${String(validTypeIDValue)}`, options, context),
889
+ ),
874
890
  );
875
891
 
876
- const validResults = checkResults.filter(result => !!result) as CheckCacheEntryResult<EntityData>[];
892
+ const validResults = checkResults.filter(result => !!result);
877
893
  let validResult: CheckCacheEntryResult<EntityData> | undefined;
878
894
 
879
895
  if (validResults.length === 1) {
@@ -881,13 +897,19 @@ export class CacheManager implements CacheManagerDef {
881
897
  } else if (validResults.length > 1) {
882
898
  validResults.sort(({ cacheability: a }, { cacheability: b }) => a.metadata.ttl - b.metadata.ttl);
883
899
 
884
- validResult = {
885
- cacheability: validResults[0]!.cacheability,
886
- entry: validResults.reduce<Partial<EntityData>>(
887
- (obj, { entry }) => mergeDataSets(obj, entry, this._typeIDKey),
888
- {}
889
- ) as EntityData,
890
- };
900
+ const firstResult = validResults[0];
901
+
902
+ if (firstResult) {
903
+ validResult = {
904
+ cacheability: firstResult.cacheability,
905
+ // By the time the merge has happened, the type is EntityData
906
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
907
+ entry: validResults.reduce<Partial<EntityData>>(
908
+ (obj, { entry }) => mergeDataSets(obj, entry, this._typeIDKey),
909
+ {},
910
+ ) as EntityData,
911
+ };
912
+ }
891
913
  }
892
914
 
893
915
  return validResult ?? {};
@@ -898,7 +920,7 @@ export class CacheManager implements CacheManagerDef {
898
920
  { hashedRequestFieldCacheKey, propNameOrIndex, requestFieldCacheKey }: KeysAndPaths,
899
921
  fieldTypeInfo: FieldTypeInfo,
900
922
  options: RequestOptions,
901
- context: CacheManagerContext
923
+ context: CacheManagerContext,
902
924
  ) {
903
925
  let entityData = CacheManager._getFieldDataFromAncestor(ancestorEntityData, propNameOrIndex);
904
926
  let requestFieldPathData = CacheManager._getFieldDataFromAncestor(ancestorRequestFieldPathData, propNameOrIndex);
@@ -909,7 +931,7 @@ export class CacheManager implements CacheManagerDef {
909
931
  hashedRequestFieldCacheKey,
910
932
  requestFieldCacheKey,
911
933
  options,
912
- context
934
+ context,
913
935
  );
914
936
 
915
937
  requestFieldPathData = combineDataSets(requestFieldPathData, entry, this._typeIDKey);
@@ -930,7 +952,7 @@ export class CacheManager implements CacheManagerDef {
930
952
  validTypeIDValue,
931
953
  fieldTypeInfo,
932
954
  options,
933
- context
955
+ context,
934
956
  );
935
957
 
936
958
  entityData = combineDataSets(entityData, entry, this._typeIDKey);
@@ -956,7 +978,7 @@ export class CacheManager implements CacheManagerDef {
956
978
  hash: string,
957
979
  requestFieldCacheKey: string,
958
980
  options: RequestOptions,
959
- context: CacheManagerContext
981
+ context: CacheManagerContext,
960
982
  ): Promise<Partial<CheckCacheEntryResult>> {
961
983
  return (
962
984
  (await this._checkCacheEntry(REQUEST_FIELD_PATHS, hash, options, { ...context, requestFieldCacheKey })) || {}
@@ -966,7 +988,7 @@ export class CacheManager implements CacheManagerDef {
966
988
  private async _retrieveCachedResponseData(
967
989
  { ast }: RequestData,
968
990
  options: RequestOptions,
969
- context: CacheManagerContext
991
+ context: CacheManagerContext,
970
992
  ): Promise<CachedResponseData> {
971
993
  const cachedResponseData: CachedResponseData = {
972
994
  cacheMetadata: new Map(),
@@ -989,8 +1011,14 @@ export class CacheManager implements CacheManagerDef {
989
1011
 
990
1012
  await Promise.all(
991
1013
  fieldsAndTypeNames.map(({ fieldNode }) =>
992
- this._analyzeFieldNode(fieldNode, { requestFieldPath: context.operation }, cachedResponseData, options, context)
993
- )
1014
+ this._analyzeFieldNode(
1015
+ fieldNode,
1016
+ { requestFieldPath: context.operation },
1017
+ cachedResponseData,
1018
+ options,
1019
+ context,
1020
+ ),
1021
+ ),
994
1022
  );
995
1023
 
996
1024
  cachedResponseData.fieldCount = CacheManager._countFieldPathChecklist(cachedResponseData.fieldPathChecklist);
@@ -999,12 +1027,11 @@ export class CacheManager implements CacheManagerDef {
999
1027
 
1000
1028
  private _retrieveResponseDataForCaching(
1001
1029
  normalizedResponseData: RawResponseDataWithMaybeCacheMetadata,
1002
- context: CacheManagerContext
1030
+ context: CacheManagerContext,
1003
1031
  ) {
1004
- const responseChunks = this._responseChunksAwaitingCaching.get(context.requestID)!;
1005
-
1032
+ const responseChunks = this._responseChunksAwaitingCaching.get(context.requestID);
1006
1033
  this._responseChunksAwaitingCaching.delete(context.requestID);
1007
- return mergeResponseDataSets([...responseChunks, normalizedResponseData]);
1034
+ return mergeResponseDataSets([...(responseChunks ?? []), normalizedResponseData]);
1008
1035
  }
1009
1036
 
1010
1037
  @logCacheEntry()
@@ -1014,7 +1041,7 @@ export class CacheManager implements CacheManagerDef {
1014
1041
  value: unknown,
1015
1042
  cachemapOptions: CachemapOptions,
1016
1043
  _options: RequestOptions,
1017
- _context: CacheManagerContext & { requestFieldCacheKey?: string }
1044
+ _context: CacheManagerContext & { requestFieldCacheKey?: string },
1018
1045
  ): Promise<void> {
1019
1046
  try {
1020
1047
  await this._cache.set(`${cacheType}::${hash}`, structuredClone(value), cachemapOptions);
@@ -1027,7 +1054,7 @@ export class CacheManager implements CacheManagerDef {
1027
1054
  requestData: RequestData,
1028
1055
  responseData: ResponseDataForCaching,
1029
1056
  options: RequestOptions,
1030
- context: CacheManagerContext
1057
+ context: CacheManagerContext,
1031
1058
  ): Promise<void> {
1032
1059
  const operationNode = getOperationDefinitions(requestData.ast, context.operation)[0];
1033
1060
 
@@ -1048,16 +1075,16 @@ export class CacheManager implements CacheManagerDef {
1048
1075
  { requestFieldPath: context.operation },
1049
1076
  responseData,
1050
1077
  options,
1051
- context
1078
+ context,
1052
1079
  );
1053
- })
1080
+ }),
1054
1081
  );
1055
1082
  }
1056
1083
 
1057
1084
  private async _setEntityCacheEntry(
1058
1085
  { cacheability, fieldData, fieldTypeInfo }: DataForCachingEntry<EntityData>,
1059
1086
  options: RequestOptions,
1060
- context: CacheManagerContext
1087
+ context: CacheManagerContext,
1061
1088
  ) {
1062
1089
  const fieldTypeName = fieldTypeInfo.isEntity ? fieldTypeInfo.typeName : fieldData.__typename;
1063
1090
  const entityDataKey = `${fieldTypeName}::${String(fieldData[this._typeIDKey])}`;
@@ -1073,7 +1100,7 @@ export class CacheManager implements CacheManagerDef {
1073
1100
  fieldData,
1074
1101
  { cacheHeaders: { cacheControl: cacheability.printCacheControl() }, tag: options.tag },
1075
1102
  options,
1076
- context
1103
+ context,
1077
1104
  );
1078
1105
  }
1079
1106
 
@@ -1082,7 +1109,7 @@ export class CacheManager implements CacheManagerDef {
1082
1109
  ancestorKeysAndPaths: AncestorKeysAndPaths,
1083
1110
  { cacheMetadata, data }: ResponseData,
1084
1111
  options: RequestOptions,
1085
- context: CacheManagerContext
1112
+ context: CacheManagerContext,
1086
1113
  ): void {
1087
1114
  const { requestFieldPath: ancestorRequestFieldPath } = ancestorKeysAndPaths;
1088
1115
  const keysAndPaths = buildFieldKeysAndPaths(field, ancestorKeysAndPaths, context);
@@ -1092,6 +1119,8 @@ export class CacheManager implements CacheManagerDef {
1092
1119
  return;
1093
1120
  }
1094
1121
 
1122
+ // get return type annotation is rubbish
1123
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
1095
1124
  const fieldData = get(data, responseDataPath) as unknown;
1096
1125
  const fieldTypeInfo = context.fieldTypeMap.get(requestFieldPath);
1097
1126
 
@@ -1111,16 +1140,16 @@ export class CacheManager implements CacheManagerDef {
1111
1140
  _typeName: string | undefined,
1112
1141
  _fragmentKind: string | undefined,
1113
1142
  _fragmentName: string | undefined,
1114
- childIndex?: number
1143
+ childIndex?: number,
1115
1144
  ) => {
1116
1145
  this._setFieldCacheability(
1117
1146
  childField,
1118
1147
  { index: childIndex, requestFieldPath, responseDataPath },
1119
1148
  { cacheMetadata, data },
1120
1149
  options,
1121
- context
1150
+ context,
1122
1151
  );
1123
- }
1152
+ },
1124
1153
  );
1125
1154
  }
1126
1155
  }
@@ -1128,7 +1157,7 @@ export class CacheManager implements CacheManagerDef {
1128
1157
  private _setFieldTypeCacheDirective(
1129
1158
  cacheMetadata: CacheMetadata,
1130
1159
  { ancestorRequestFieldPath, requestFieldPath }: { ancestorRequestFieldPath?: string; requestFieldPath: string },
1131
- { fieldTypeMap, operation }: CacheManagerContext
1160
+ { fieldTypeMap, operation }: CacheManagerContext,
1132
1161
  ): void {
1133
1162
  if (cacheMetadata.has(requestFieldPath)) {
1134
1163
  return;
@@ -1144,7 +1173,7 @@ export class CacheManager implements CacheManagerDef {
1144
1173
  cacheMetadata,
1145
1174
  cacheMetadata.get(ancestorRequestFieldPath),
1146
1175
  requestFieldPath,
1147
- operation
1176
+ operation,
1148
1177
  );
1149
1178
  }
1150
1179
  }
@@ -1154,7 +1183,7 @@ export class CacheManager implements CacheManagerDef {
1154
1183
  hash: string,
1155
1184
  partialQueryResponse: PartialQueryResponse,
1156
1185
  _options: RequestOptions,
1157
- _context: CacheManagerContext
1186
+ _context: CacheManagerContext,
1158
1187
  ): void {
1159
1188
  this._partialQueryResponses.set(hash, partialQueryResponse);
1160
1189
  }
@@ -1163,7 +1192,7 @@ export class CacheManager implements CacheManagerDef {
1163
1192
  hash: string,
1164
1193
  { cacheMetadata, data }: ResponseData,
1165
1194
  options: RequestOptions,
1166
- context: CacheManagerContext
1195
+ context: CacheManagerContext,
1167
1196
  ): Promise<void> {
1168
1197
  const dehydratedCacheMetadata = dehydrateCacheMetadata(cacheMetadata);
1169
1198
  const cacheControl = CacheManager._getOperationCacheControl(cacheMetadata, context.operation);
@@ -1174,7 +1203,7 @@ export class CacheManager implements CacheManagerDef {
1174
1203
  { cacheMetadata: dehydratedCacheMetadata, data },
1175
1204
  { cacheHeaders: { cacheControl }, tag: options.tag },
1176
1205
  options,
1177
- context
1206
+ context,
1178
1207
  );
1179
1208
  }
1180
1209
 
@@ -1182,7 +1211,7 @@ export class CacheManager implements CacheManagerDef {
1182
1211
  keysAndPaths: KeysAndPaths,
1183
1212
  { cacheability, fieldData }: DataForCachingEntry,
1184
1213
  options: RequestOptions,
1185
- context: CacheManagerContext
1214
+ context: CacheManagerContext,
1186
1215
  ): Promise<void> {
1187
1216
  const { hashedRequestFieldCacheKey, requestFieldCacheKey } = keysAndPaths;
1188
1217
 
@@ -1201,13 +1230,13 @@ export class CacheManager implements CacheManagerDef {
1201
1230
  fieldData,
1202
1231
  { cacheHeaders: { cacheControl: cacheability.printCacheControl() }, tag: options.tag },
1203
1232
  options,
1204
- { ...context, requestFieldCacheKey }
1233
+ { ...context, requestFieldCacheKey },
1205
1234
  );
1206
1235
  }
1207
1236
 
1208
1237
  private _setResponseChunksAwaitingCaching(
1209
1238
  normalizedResponseData: RawResponseDataWithMaybeCacheMetadata,
1210
- context: CacheManagerContext
1239
+ context: CacheManagerContext,
1211
1240
  ) {
1212
1241
  const responseChunks = this._responseChunksAwaitingCaching.get(context.requestID);
1213
1242