@expo/entity 0.31.1 → 0.32.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 (255) hide show
  1. package/build/ComposedEntityCacheAdapter.d.ts +4 -6
  2. package/build/ComposedEntityCacheAdapter.js +3 -6
  3. package/build/ComposedEntityCacheAdapter.js.map +1 -1
  4. package/build/EnforcingEntityLoader.d.ts +1 -1
  5. package/build/Entity.d.ts +20 -10
  6. package/build/Entity.js +2 -2
  7. package/build/Entity.js.map +1 -1
  8. package/build/EntityAssociationLoader.d.ts +9 -9
  9. package/build/EntityCompanion.d.ts +6 -5
  10. package/build/EntityCompanion.js +6 -4
  11. package/build/EntityCompanion.js.map +1 -1
  12. package/build/EntityCompanionProvider.d.ts +28 -36
  13. package/build/EntityCompanionProvider.js +4 -19
  14. package/build/EntityCompanionProvider.js.map +1 -1
  15. package/build/EntityConfiguration.d.ts +3 -3
  16. package/build/EntityConfiguration.js +2 -2
  17. package/build/EntityConfiguration.js.map +1 -1
  18. package/build/EntityDatabaseAdapter.d.ts +1 -1
  19. package/build/EntityDatabaseAdapter.js +1 -1
  20. package/build/EntityDatabaseAdapter.js.map +1 -1
  21. package/build/EntityFieldDefinition.d.ts +2 -2
  22. package/build/EntityFieldDefinition.js +1 -1
  23. package/build/EntityFieldDefinition.js.map +1 -1
  24. package/build/EntityLoader.d.ts +4 -2
  25. package/build/EntityLoader.js +21 -7
  26. package/build/EntityLoader.js.map +1 -1
  27. package/build/EntityLoaderFactory.d.ts +4 -7
  28. package/build/EntityLoaderFactory.js +3 -5
  29. package/build/EntityLoaderFactory.js.map +1 -1
  30. package/build/EntityMutationInfo.d.ts +3 -3
  31. package/build/EntityMutationInfo.js +1 -1
  32. package/build/EntityMutationInfo.js.map +1 -1
  33. package/build/EntityMutationTriggerConfiguration.d.ts +3 -3
  34. package/build/EntityMutationValidator.d.ts +1 -1
  35. package/build/EntityMutator.d.ts +9 -7
  36. package/build/EntityMutator.js +21 -21
  37. package/build/EntityMutator.js.map +1 -1
  38. package/build/EntityMutatorFactory.d.ts +4 -2
  39. package/build/EntityMutatorFactory.js +5 -4
  40. package/build/EntityMutatorFactory.js.map +1 -1
  41. package/build/EntityPrivacyPolicy.d.ts +3 -3
  42. package/build/EntityPrivacyPolicy.js +2 -2
  43. package/build/EntityPrivacyPolicy.js.map +1 -1
  44. package/build/EntityQueryContext.d.ts +13 -5
  45. package/build/EntityQueryContext.js +11 -4
  46. package/build/EntityQueryContext.js.map +1 -1
  47. package/build/EntityQueryContextProvider.d.ts +3 -3
  48. package/build/EntityQueryContextProvider.js +2 -2
  49. package/build/EntityQueryContextProvider.js.map +1 -1
  50. package/build/EntitySecondaryCacheLoader.d.ts +1 -1
  51. package/build/EntitySecondaryCacheLoader.js +1 -1
  52. package/build/EntitySecondaryCacheLoader.js.map +1 -1
  53. package/build/GenericEntityCacheAdapter.d.ts +14 -0
  54. package/build/GenericEntityCacheAdapter.js +38 -0
  55. package/build/GenericEntityCacheAdapter.js.map +1 -0
  56. package/build/{EntityCacheAdapter.d.ts → IEntityCacheAdapter.d.ts} +5 -8
  57. package/build/IEntityCacheAdapter.js +3 -0
  58. package/build/IEntityCacheAdapter.js.map +1 -0
  59. package/build/IEntityCacheAdapterProvider.d.ts +2 -2
  60. package/build/IEntityGenericCacher.d.ts +31 -2
  61. package/build/ReadonlyEntity.d.ts +19 -7
  62. package/build/ReadonlyEntity.js +15 -13
  63. package/build/ReadonlyEntity.js.map +1 -1
  64. package/build/ViewerContext.d.ts +3 -3
  65. package/build/ViewerContext.js +3 -3
  66. package/build/ViewerContext.js.map +1 -1
  67. package/build/ViewerScopedEntityCompanion.d.ts +2 -2
  68. package/build/ViewerScopedEntityCompanion.js.map +1 -1
  69. package/build/ViewerScopedEntityCompanionProvider.d.ts +3 -3
  70. package/build/ViewerScopedEntityCompanionProvider.js +3 -3
  71. package/build/ViewerScopedEntityCompanionProvider.js.map +1 -1
  72. package/build/ViewerScopedEntityLoaderFactory.d.ts +1 -1
  73. package/build/ViewerScopedEntityMutatorFactory.d.ts +1 -1
  74. package/build/__tests__/ComposedCacheAdapter-test.js +4 -8
  75. package/build/__tests__/ComposedCacheAdapter-test.js.map +1 -1
  76. package/build/__tests__/EnforcingEntityLoader-test.js +1 -0
  77. package/build/__tests__/EnforcingEntityLoader-test.js.map +1 -1
  78. package/build/__tests__/Entity-test.js +42 -20
  79. package/build/__tests__/Entity-test.js.map +1 -1
  80. package/build/__tests__/EntityAssociationLoader-test.js +6 -6
  81. package/build/__tests__/EntityAssociationLoader-test.js.map +1 -1
  82. package/build/__tests__/EntityCommonUseCases-test.js +20 -22
  83. package/build/__tests__/EntityCommonUseCases-test.js.map +1 -1
  84. package/build/__tests__/EntityCompanion-test.js +2 -1
  85. package/build/__tests__/EntityCompanion-test.js.map +1 -1
  86. package/build/__tests__/EntityCompanionProvider-test.js +15 -40
  87. package/build/__tests__/EntityCompanionProvider-test.js.map +1 -1
  88. package/build/__tests__/EntityEdges-test.js +48 -54
  89. package/build/__tests__/EntityEdges-test.js.map +1 -1
  90. package/build/__tests__/EntityLoader-constructor-test.d.ts +9 -5
  91. package/build/__tests__/EntityLoader-constructor-test.js +13 -14
  92. package/build/__tests__/EntityLoader-constructor-test.js.map +1 -1
  93. package/build/__tests__/EntityLoader-test.js +19 -11
  94. package/build/__tests__/EntityLoader-test.js.map +1 -1
  95. package/build/__tests__/EntityMutator-MutationCacheConsistency-test.js +20 -22
  96. package/build/__tests__/EntityMutator-MutationCacheConsistency-test.js.map +1 -1
  97. package/build/__tests__/EntityMutator-test.js +67 -14
  98. package/build/__tests__/EntityMutator-test.js.map +1 -1
  99. package/build/__tests__/EntityPrivacyPolicy-test.js +82 -29
  100. package/build/__tests__/EntityPrivacyPolicy-test.js.map +1 -1
  101. package/build/__tests__/EntityQueryContext-test.js +12 -0
  102. package/build/__tests__/EntityQueryContext-test.js.map +1 -1
  103. package/build/__tests__/EntitySecondaryCacheLoader-test.js +1 -2
  104. package/build/__tests__/EntitySecondaryCacheLoader-test.js.map +1 -1
  105. package/build/__tests__/EntitySelfReferentialEdges-test.js +16 -20
  106. package/build/__tests__/EntitySelfReferentialEdges-test.js.map +1 -1
  107. package/build/__tests__/GenericEntityCacheAdapter-test.d.ts +1 -0
  108. package/build/__tests__/GenericEntityCacheAdapter-test.js +80 -0
  109. package/build/__tests__/GenericEntityCacheAdapter-test.js.map +1 -0
  110. package/build/__tests__/ReadonlyEntity-test.js +79 -13
  111. package/build/__tests__/ReadonlyEntity-test.js.map +1 -1
  112. package/build/__tests__/ViewerScopedEntityCompanionProvider-test.js +2 -25
  113. package/build/__tests__/ViewerScopedEntityCompanionProvider-test.js.map +1 -1
  114. package/build/__tests__/cases/TwoEntitySameTableDisjointRows-test.js +20 -23
  115. package/build/__tests__/cases/TwoEntitySameTableDisjointRows-test.js.map +1 -1
  116. package/build/__tests__/cases/TwoEntitySameTableOverlappingRows-test.js +17 -20
  117. package/build/__tests__/cases/TwoEntitySameTableOverlappingRows-test.js.map +1 -1
  118. package/build/errors/EntityError.js +2 -2
  119. package/build/errors/EntityError.js.map +1 -1
  120. package/build/errors/EntityInvalidFieldValueError.d.ts +2 -2
  121. package/build/errors/EntityInvalidFieldValueError.js.map +1 -1
  122. package/build/errors/EntityNotAuthorizedError.d.ts +2 -2
  123. package/build/errors/EntityNotAuthorizedError.js +1 -1
  124. package/build/errors/EntityNotAuthorizedError.js.map +1 -1
  125. package/build/errors/EntityNotFoundError.d.ts +2 -2
  126. package/build/errors/EntityNotFoundError.js.map +1 -1
  127. package/build/index.d.ts +2 -1
  128. package/build/index.js +3 -3
  129. package/build/index.js.map +1 -1
  130. package/build/internal/EntityDataManager.d.ts +1 -1
  131. package/build/internal/EntityDataManager.js +1 -1
  132. package/build/internal/EntityDataManager.js.map +1 -1
  133. package/build/internal/EntityFieldTransformationUtils.d.ts +1 -1
  134. package/build/internal/EntityFieldTransformationUtils.js +4 -4
  135. package/build/internal/EntityFieldTransformationUtils.js.map +1 -1
  136. package/build/internal/EntityTableDataCoordinator.d.ts +3 -3
  137. package/build/internal/EntityTableDataCoordinator.js.map +1 -1
  138. package/build/internal/ReadThroughEntityCache.d.ts +3 -3
  139. package/build/internal/ReadThroughEntityCache.js +1 -1
  140. package/build/internal/ReadThroughEntityCache.js.map +1 -1
  141. package/build/internal/__tests__/EntityDataManager-test.js +1 -1
  142. package/build/internal/__tests__/EntityDataManager-test.js.map +1 -1
  143. package/build/internal/__tests__/ReadThroughEntityCache-test.js.map +1 -1
  144. package/build/metrics/EntityMetricsUtils.js.map +1 -1
  145. package/build/metrics/IEntityMetricsAdapter.js +4 -4
  146. package/build/metrics/IEntityMetricsAdapter.js.map +1 -1
  147. package/build/rules/AlwaysAllowPrivacyPolicyRule.d.ts +2 -2
  148. package/build/rules/AlwaysAllowPrivacyPolicyRule.js.map +1 -1
  149. package/build/rules/AlwaysDenyPrivacyPolicyRule.d.ts +2 -2
  150. package/build/rules/AlwaysDenyPrivacyPolicyRule.js.map +1 -1
  151. package/build/rules/AlwaysSkipPrivacyPolicyRule.d.ts +2 -2
  152. package/build/rules/AlwaysSkipPrivacyPolicyRule.js.map +1 -1
  153. package/build/rules/PrivacyPolicyRule.d.ts +1 -1
  154. package/build/rules/PrivacyPolicyRule.js +1 -1
  155. package/build/rules/PrivacyPolicyRule.js.map +1 -1
  156. package/build/testfixtures/DateIDTestEntity.d.ts +2 -3
  157. package/build/testfixtures/DateIDTestEntity.js +7 -9
  158. package/build/testfixtures/DateIDTestEntity.js.map +1 -1
  159. package/build/testfixtures/SimpleTestEntity.d.ts +3 -4
  160. package/build/testfixtures/SimpleTestEntity.js +7 -9
  161. package/build/testfixtures/SimpleTestEntity.js.map +1 -1
  162. package/build/testfixtures/TestEntity.d.ts +2 -3
  163. package/build/testfixtures/TestEntity.js +14 -10
  164. package/build/testfixtures/TestEntity.js.map +1 -1
  165. package/build/testfixtures/TestEntity2.d.ts +2 -3
  166. package/build/testfixtures/TestEntity2.js +7 -9
  167. package/build/testfixtures/TestEntity2.js.map +1 -1
  168. package/build/testfixtures/TestEntityNumberKey.d.ts +2 -3
  169. package/build/testfixtures/TestEntityNumberKey.js +7 -9
  170. package/build/testfixtures/TestEntityNumberKey.js.map +1 -1
  171. package/build/utils/testing/PrivacyPolicyRuleTestUtils.d.ts +4 -4
  172. package/build/utils/testing/StubCacheAdapter.d.ts +6 -5
  173. package/build/utils/testing/StubCacheAdapter.js +5 -6
  174. package/build/utils/testing/StubCacheAdapter.js.map +1 -1
  175. package/build/utils/testing/StubDatabaseAdapterProvider.js.map +1 -1
  176. package/build/utils/testing/StubQueryContextProvider.d.ts +2 -1
  177. package/build/utils/testing/StubQueryContextProvider.js +1 -1
  178. package/build/utils/testing/StubQueryContextProvider.js.map +1 -1
  179. package/build/utils/testing/createUnitTestEntityCompanionProvider.js +2 -2
  180. package/build/utils/testing/createUnitTestEntityCompanionProvider.js.map +1 -1
  181. package/package.json +3 -3
  182. package/src/ComposedEntityCacheAdapter.ts +4 -11
  183. package/src/EnforcingEntityLoader.ts +1 -1
  184. package/src/Entity.ts +23 -12
  185. package/src/EntityAssociationLoader.ts +12 -12
  186. package/src/EntityCompanion.ts +13 -32
  187. package/src/EntityCompanionProvider.ts +41 -80
  188. package/src/EntityConfiguration.ts +4 -5
  189. package/src/EntityFieldDefinition.ts +2 -2
  190. package/src/EntityLoader.ts +19 -2
  191. package/src/EntityLoaderFactory.ts +7 -9
  192. package/src/EntityMutationInfo.ts +2 -2
  193. package/src/EntityMutationTriggerConfiguration.ts +3 -3
  194. package/src/EntityMutationValidator.ts +1 -1
  195. package/src/EntityMutator.ts +38 -31
  196. package/src/EntityMutatorFactory.ts +6 -1
  197. package/src/EntityPrivacyPolicy.ts +2 -2
  198. package/src/EntityQueryContext.ts +24 -4
  199. package/src/EntityQueryContextProvider.ts +7 -5
  200. package/src/EntitySecondaryCacheLoader.ts +1 -1
  201. package/src/GenericEntityCacheAdapter.ts +65 -0
  202. package/src/{EntityCacheAdapter.ts → IEntityCacheAdapter.ts} +5 -8
  203. package/src/IEntityCacheAdapterProvider.ts +2 -2
  204. package/src/IEntityGenericCacher.ts +32 -2
  205. package/src/ReadonlyEntity.ts +32 -32
  206. package/src/ViewerContext.ts +10 -8
  207. package/src/ViewerScopedEntityCompanion.ts +2 -2
  208. package/src/ViewerScopedEntityCompanionProvider.ts +4 -12
  209. package/src/ViewerScopedEntityLoaderFactory.ts +1 -1
  210. package/src/ViewerScopedEntityMutatorFactory.ts +1 -1
  211. package/src/__tests__/ComposedCacheAdapter-test.ts +6 -11
  212. package/src/__tests__/EnforcingEntityLoader-test.ts +1 -0
  213. package/src/__tests__/Entity-test.ts +42 -21
  214. package/src/__tests__/EntityCommonUseCases-test.ts +20 -22
  215. package/src/__tests__/EntityCompanion-test.ts +6 -9
  216. package/src/__tests__/EntityCompanionProvider-test.ts +14 -26
  217. package/src/__tests__/EntityEdges-test.ts +43 -49
  218. package/src/__tests__/EntityLoader-constructor-test.ts +16 -12
  219. package/src/__tests__/EntityLoader-test.ts +9 -0
  220. package/src/__tests__/EntityMutator-MutationCacheConsistency-test.ts +20 -22
  221. package/src/__tests__/EntityMutator-test.ts +119 -19
  222. package/src/__tests__/EntityPrivacyPolicy-test.ts +82 -29
  223. package/src/__tests__/EntityQueryContext-test.ts +23 -1
  224. package/src/__tests__/EntitySelfReferentialEdges-test.ts +8 -10
  225. package/src/__tests__/GenericEntityCacheAdapter-test.ts +102 -0
  226. package/src/__tests__/ReadonlyEntity-test.ts +79 -13
  227. package/src/__tests__/ViewerScopedEntityCompanionProvider-test.ts +2 -5
  228. package/src/__tests__/cases/TwoEntitySameTableDisjointRows-test.ts +30 -24
  229. package/src/__tests__/cases/TwoEntitySameTableOverlappingRows-test.ts +14 -18
  230. package/src/errors/EntityInvalidFieldValueError.ts +2 -2
  231. package/src/errors/EntityNotAuthorizedError.ts +2 -2
  232. package/src/errors/EntityNotFoundError.ts +2 -2
  233. package/src/index.ts +2 -1
  234. package/src/internal/EntityDataManager.ts +1 -1
  235. package/src/internal/EntityTableDataCoordinator.ts +4 -4
  236. package/src/internal/ReadThroughEntityCache.ts +2 -2
  237. package/src/internal/__tests__/EntityDataManager-test.ts +2 -1
  238. package/src/internal/__tests__/ReadThroughEntityCache-test.ts +8 -8
  239. package/src/metrics/EntityMetricsUtils.ts +1 -1
  240. package/src/rules/AlwaysAllowPrivacyPolicyRule.ts +2 -2
  241. package/src/rules/AlwaysDenyPrivacyPolicyRule.ts +2 -2
  242. package/src/rules/AlwaysSkipPrivacyPolicyRule.ts +2 -2
  243. package/src/rules/PrivacyPolicyRule.ts +1 -1
  244. package/src/testfixtures/DateIDTestEntity.ts +6 -8
  245. package/src/testfixtures/SimpleTestEntity.ts +6 -8
  246. package/src/testfixtures/TestEntity.ts +19 -15
  247. package/src/testfixtures/TestEntity2.ts +6 -8
  248. package/src/testfixtures/TestEntityNumberKey.ts +6 -8
  249. package/src/utils/testing/PrivacyPolicyRuleTestUtils.ts +4 -4
  250. package/src/utils/testing/StubCacheAdapter.ts +9 -11
  251. package/src/utils/testing/StubDatabaseAdapterProvider.ts +1 -1
  252. package/src/utils/testing/StubQueryContextProvider.ts +4 -3
  253. package/src/utils/testing/createUnitTestEntityCompanionProvider.ts +3 -3
  254. package/build/EntityCacheAdapter.js +0 -13
  255. package/build/EntityCacheAdapter.js.map +0 -1
@@ -1,4 +1,5 @@
1
1
  import Entity, { IEntityClass } from './Entity';
2
+ import EntityCompanionProvider from './EntityCompanionProvider';
2
3
  import EntityConfiguration from './EntityConfiguration';
3
4
  import EntityDatabaseAdapter from './EntityDatabaseAdapter';
4
5
  import EntityLoaderFactory from './EntityLoaderFactory';
@@ -14,7 +15,7 @@ import IEntityMetricsAdapter from './metrics/IEntityMetricsAdapter';
14
15
  * The primary interface for creating, mutating, and deleting entities.
15
16
  */
16
17
  export default class EntityMutatorFactory<
17
- TFields,
18
+ TFields extends object,
18
19
  TID extends NonNullable<TFields[TSelectedFields]>,
19
20
  TViewerContext extends ViewerContext,
20
21
  TEntity extends Entity<TFields, TID, TViewerContext, TSelectedFields>,
@@ -28,6 +29,7 @@ export default class EntityMutatorFactory<
28
29
  TSelectedFields extends keyof TFields = keyof TFields
29
30
  > {
30
31
  constructor(
32
+ private readonly entityCompanionProvider: EntityCompanionProvider,
31
33
  private readonly entityConfiguration: EntityConfiguration<TFields>,
32
34
  private readonly entityClass: IEntityClass<
33
35
  TFields,
@@ -75,6 +77,7 @@ export default class EntityMutatorFactory<
75
77
  queryContext: EntityQueryContext
76
78
  ): CreateMutator<TFields, TID, TViewerContext, TEntity, TPrivacyPolicy, TSelectedFields> {
77
79
  return new CreateMutator(
80
+ this.entityCompanionProvider,
78
81
  viewerContext,
79
82
  queryContext,
80
83
  this.entityConfiguration,
@@ -99,6 +102,7 @@ export default class EntityMutatorFactory<
99
102
  queryContext: EntityQueryContext
100
103
  ): UpdateMutator<TFields, TID, TViewerContext, TEntity, TPrivacyPolicy, TSelectedFields> {
101
104
  return new UpdateMutator(
105
+ this.entityCompanionProvider,
102
106
  existingEntity.getViewerContext(),
103
107
  queryContext,
104
108
  this.entityConfiguration,
@@ -123,6 +127,7 @@ export default class EntityMutatorFactory<
123
127
  queryContext: EntityQueryContext
124
128
  ): DeleteMutator<TFields, TID, TViewerContext, TEntity, TPrivacyPolicy, TSelectedFields> {
125
129
  return new DeleteMutator(
130
+ this.entityCompanionProvider,
126
131
  existingEntity.getViewerContext(),
127
132
  queryContext,
128
133
  this.entityConfiguration,
@@ -41,7 +41,7 @@ export enum EntityPrivacyPolicyEvaluationMode {
41
41
  }
42
42
 
43
43
  export type EntityPrivacyPolicyEvaluator<
44
- TFields,
44
+ TFields extends object,
45
45
  TID extends NonNullable<TFields[TSelectedFields]>,
46
46
  TViewerContext extends ViewerContext,
47
47
  TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>,
@@ -92,7 +92,7 @@ export enum EntityAuthorizationAction {
92
92
  * ```
93
93
  */
94
94
  export default abstract class EntityPrivacyPolicy<
95
- TFields,
95
+ TFields extends object,
96
96
  TID extends NonNullable<TFields[TSelectedFields]>,
97
97
  TViewerContext extends ViewerContext,
98
98
  TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>,
@@ -8,6 +8,16 @@ export type PreCommitCallback = (
8
8
  ...args: any
9
9
  ) => Promise<any>;
10
10
 
11
+ export enum TransactionIsolationLevel {
12
+ READ_COMMITTED = 'READ_COMMITTED',
13
+ REPEATABLE_READ = 'REPEATABLE_READ',
14
+ SERIALIZABLE = 'SERIALIZABLE',
15
+ }
16
+
17
+ export type TransactionConfig = {
18
+ isolationLevel?: TransactionIsolationLevel;
19
+ };
20
+
11
21
  /**
12
22
  * Entity framework representation of transactional and non-transactional database
13
23
  * query execution units.
@@ -25,7 +35,8 @@ export abstract class EntityQueryContext {
25
35
  }
26
36
 
27
37
  abstract runInTransactionIfNotInTransactionAsync<T>(
28
- transactionScope: (queryContext: EntityTransactionalQueryContext) => Promise<T>
38
+ transactionScope: (queryContext: EntityTransactionalQueryContext) => Promise<T>,
39
+ transactionConfig?: TransactionConfig
29
40
  ): Promise<T>;
30
41
  }
31
42
 
@@ -48,9 +59,13 @@ export class EntityNonTransactionalQueryContext extends EntityQueryContext {
48
59
  }
49
60
 
50
61
  async runInTransactionIfNotInTransactionAsync<T>(
51
- transactionScope: (queryContext: EntityTransactionalQueryContext) => Promise<T>
62
+ transactionScope: (queryContext: EntityTransactionalQueryContext) => Promise<T>,
63
+ transactionConfig?: TransactionConfig
52
64
  ): Promise<T> {
53
- return await this.entityQueryContextProvider.runInTransactionAsync(transactionScope);
65
+ return await this.entityQueryContextProvider.runInTransactionAsync(
66
+ transactionScope,
67
+ transactionConfig
68
+ );
54
69
  }
55
70
  }
56
71
 
@@ -132,8 +147,13 @@ export class EntityTransactionalQueryContext extends EntityQueryContext {
132
147
  }
133
148
 
134
149
  async runInTransactionIfNotInTransactionAsync<T>(
135
- transactionScope: (queryContext: EntityTransactionalQueryContext) => Promise<T>
150
+ transactionScope: (queryContext: EntityTransactionalQueryContext) => Promise<T>,
151
+ transactionConfig?: TransactionConfig
136
152
  ): Promise<T> {
153
+ assert(
154
+ transactionConfig === undefined,
155
+ 'Should not pass transactionConfig to a nested transaction'
156
+ );
137
157
  return await transactionScope(this);
138
158
  }
139
159
 
@@ -2,6 +2,7 @@ import {
2
2
  EntityTransactionalQueryContext,
3
3
  EntityNonTransactionalQueryContext,
4
4
  EntityNestedTransactionalQueryContext,
5
+ TransactionConfig,
5
6
  } from './EntityQueryContext';
6
7
 
7
8
  /**
@@ -23,9 +24,9 @@ export default abstract class EntityQueryContextProvider {
23
24
  /**
24
25
  * Vend a transaction runner for use in runInTransactionAsync.
25
26
  */
26
- protected abstract createTransactionRunner<T>(): (
27
- transactionScope: (queryInterface: any) => Promise<T>
28
- ) => Promise<T>;
27
+ protected abstract createTransactionRunner<T>(
28
+ transactionConfig?: TransactionConfig
29
+ ): (transactionScope: (queryInterface: any) => Promise<T>) => Promise<T>;
29
30
 
30
31
  protected abstract createNestedTransactionRunner<T>(
31
32
  outerQueryInterface: any
@@ -36,11 +37,12 @@ export default abstract class EntityQueryContextProvider {
36
37
  * @param transactionScope - async callback to execute within the transaction
37
38
  */
38
39
  async runInTransactionAsync<T>(
39
- transactionScope: (queryContext: EntityTransactionalQueryContext) => Promise<T>
40
+ transactionScope: (queryContext: EntityTransactionalQueryContext) => Promise<T>,
41
+ transactionConfig?: TransactionConfig
40
42
  ): Promise<T> {
41
43
  const [returnedValue, queryContext] = await this.createTransactionRunner<
42
44
  [T, EntityTransactionalQueryContext]
43
- >()(async (queryInterface) => {
45
+ >(transactionConfig)(async (queryInterface) => {
44
46
  const queryContext = new EntityTransactionalQueryContext(queryInterface, this);
45
47
  const result = await transactionScope(queryContext);
46
48
  await queryContext.runPreCommitCallbacksAsync();
@@ -45,7 +45,7 @@ export interface ISecondaryEntityCache<TFields, TLoadParams> {
45
45
  */
46
46
  export default abstract class EntitySecondaryCacheLoader<
47
47
  TLoadParams,
48
- TFields,
48
+ TFields extends object,
49
49
  TID extends NonNullable<TFields[TSelectedFields]>,
50
50
  TViewerContext extends ViewerContext,
51
51
  TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>,
@@ -0,0 +1,65 @@
1
+ import invariant from 'invariant';
2
+
3
+ import IEntityCacheAdapter from './IEntityCacheAdapter';
4
+ import IEntityGenericCacher from './IEntityGenericCacher';
5
+ import { CacheLoadResult } from './internal/ReadThroughEntityCache';
6
+ import { mapKeys } from './utils/collections/maps';
7
+
8
+ /**
9
+ * A standard IEntityCacheAdapter that coordinates caching through an IEntityGenericCacher.
10
+ */
11
+ export default class GenericEntityCacheAdapter<TFields> implements IEntityCacheAdapter<TFields> {
12
+ constructor(private readonly genericCacher: IEntityGenericCacher<TFields>) {}
13
+
14
+ public async loadManyAsync<N extends keyof TFields>(
15
+ fieldName: N,
16
+ fieldValues: readonly NonNullable<TFields[N]>[]
17
+ ): Promise<ReadonlyMap<NonNullable<TFields[N]>, CacheLoadResult<TFields>>> {
18
+ const redisCacheKeyToFieldValueMapping = new Map(
19
+ fieldValues.map((fieldValue) => [
20
+ this.genericCacher.makeCacheKey(fieldName, fieldValue),
21
+ fieldValue,
22
+ ])
23
+ );
24
+ const cacheResults = await this.genericCacher.loadManyAsync(
25
+ Array.from(redisCacheKeyToFieldValueMapping.keys())
26
+ );
27
+
28
+ return mapKeys(cacheResults, (redisCacheKey) => {
29
+ const fieldValue = redisCacheKeyToFieldValueMapping.get(redisCacheKey);
30
+ invariant(
31
+ fieldValue !== undefined,
32
+ 'Unspecified cache key %s returned from generic cacher',
33
+ redisCacheKey
34
+ );
35
+ return fieldValue;
36
+ });
37
+ }
38
+
39
+ public async cacheManyAsync<N extends keyof TFields>(
40
+ fieldName: N,
41
+ objectMap: ReadonlyMap<NonNullable<TFields[N]>, Readonly<TFields>>
42
+ ): Promise<void> {
43
+ await this.genericCacher.cacheManyAsync(
44
+ mapKeys(objectMap, (fieldValue) => this.genericCacher.makeCacheKey(fieldName, fieldValue))
45
+ );
46
+ }
47
+
48
+ public async cacheDBMissesAsync<N extends keyof TFields>(
49
+ fieldName: N,
50
+ fieldValues: readonly NonNullable<TFields[N]>[]
51
+ ): Promise<void> {
52
+ await this.genericCacher.cacheDBMissesAsync(
53
+ fieldValues.map((fieldValue) => this.genericCacher.makeCacheKey(fieldName, fieldValue))
54
+ );
55
+ }
56
+
57
+ public async invalidateManyAsync<N extends keyof TFields>(
58
+ fieldName: N,
59
+ fieldValues: readonly NonNullable<TFields[N]>[]
60
+ ): Promise<void> {
61
+ await this.genericCacher.invalidateManyAsync(
62
+ fieldValues.map((fieldValue) => this.genericCacher.makeCacheKey(fieldName, fieldValue))
63
+ );
64
+ }
65
+ }
@@ -1,20 +1,17 @@
1
- import EntityConfiguration from './EntityConfiguration';
2
1
  import { CacheLoadResult } from './internal/ReadThroughEntityCache';
3
2
 
4
3
  /**
5
4
  * A cache adapter is an interface by which objects can be
6
5
  * cached, fetched from cache, and removed from cache (invalidated).
7
6
  */
8
- export default abstract class EntityCacheAdapter<TFields> {
9
- constructor(protected readonly entityConfiguration: EntityConfiguration<TFields>) {}
10
-
7
+ export default interface IEntityCacheAdapter<TFields> {
11
8
  /**
12
9
  * Load many objects from cache.
13
10
  * @param fieldName - object field being queried
14
11
  * @param fieldValues - fieldName field values being queried
15
12
  * @returns map from all field values to a CacheLoadResult for each input value
16
13
  */
17
- public abstract loadManyAsync<N extends keyof TFields>(
14
+ loadManyAsync<N extends keyof TFields>(
18
15
  fieldName: N,
19
16
  fieldValues: readonly NonNullable<TFields[N]>[]
20
17
  ): Promise<ReadonlyMap<NonNullable<TFields[N]>, CacheLoadResult<TFields>>>;
@@ -24,7 +21,7 @@ export default abstract class EntityCacheAdapter<TFields> {
24
21
  * @param fieldName - object field being queried
25
22
  * @param objectMap - map from field value to object to cache
26
23
  */
27
- public abstract cacheManyAsync<N extends keyof TFields>(
24
+ cacheManyAsync<N extends keyof TFields>(
28
25
  fieldName: N,
29
26
  objectMap: ReadonlyMap<NonNullable<TFields[N]>, Readonly<TFields>>
30
27
  ): Promise<void>;
@@ -35,7 +32,7 @@ export default abstract class EntityCacheAdapter<TFields> {
35
32
  * @param fieldValues - fieldValues for objects reported as CacheStatus.NEGATIVE
36
33
  * in the cache and not found in the DB.
37
34
  */
38
- public abstract cacheDBMissesAsync<N extends keyof TFields>(
35
+ cacheDBMissesAsync<N extends keyof TFields>(
39
36
  fieldName: N,
40
37
  fieldValues: readonly NonNullable<TFields[N]>[]
41
38
  ): Promise<void>;
@@ -45,7 +42,7 @@ export default abstract class EntityCacheAdapter<TFields> {
45
42
  * @param fieldName - object field being queried
46
43
  * @param fieldValues - fieldName field values to be invalidated
47
44
  */
48
- public abstract invalidateManyAsync<N extends keyof TFields>(
45
+ invalidateManyAsync<N extends keyof TFields>(
49
46
  fieldName: N,
50
47
  fieldValues: readonly NonNullable<TFields[N]>[]
51
48
  ): Promise<void>;
@@ -1,5 +1,5 @@
1
- import EntityCacheAdapter from './EntityCacheAdapter';
2
1
  import EntityConfiguration from './EntityConfiguration';
2
+ import IEntityCacheAdapter from './IEntityCacheAdapter';
3
3
 
4
4
  /**
5
5
  * A cache adapter provider vends cache adapters for a particular cache adapter type.
@@ -11,5 +11,5 @@ export default interface IEntityCacheAdapterProvider {
11
11
  */
12
12
  getCacheAdapter<TFields>(
13
13
  entityConfiguration: EntityConfiguration<TFields>
14
- ): EntityCacheAdapter<TFields>;
14
+ ): IEntityCacheAdapter<TFields>;
15
15
  }
@@ -1,15 +1,45 @@
1
1
  import { CacheLoadResult } from './internal/ReadThroughEntityCache';
2
2
 
3
3
  /**
4
- * A cacher stores and loads key-value pairs. It also supports negative caching - it stores the absence
5
- * of keys that don't exist in the backing datastore.
4
+ * A generic cacher stores and loads key-value pairs. It also supports negative caching - it stores the absence
5
+ * of keys that don't exist in the backing datastore. It is also responsible for cache key creation.
6
6
  */
7
7
  export default interface IEntityGenericCacher<TFields> {
8
+ /**
9
+ * Load many keys from the cache. Return info in a format that is useful for read-through caching and
10
+ * negative caching.
11
+ *
12
+ * @param keys - cache keys to load
13
+ */
8
14
  loadManyAsync(keys: readonly string[]): Promise<ReadonlyMap<string, CacheLoadResult<TFields>>>;
9
15
 
16
+ /**
17
+ * Cache many objects for specified keys.
18
+ *
19
+ * @param objectMap - map from cache key to object to cache for key
20
+ */
10
21
  cacheManyAsync(objectMap: ReadonlyMap<string, Readonly<TFields>>): Promise<void>;
11
22
 
23
+ /**
24
+ * Negatively-cache specified keys. Subsequent loads for these keys (without calling invalidate) may
25
+ * return a negative CacheLoadResult
26
+ *
27
+ * @param keys - keys to cache negatively
28
+ */
12
29
  cacheDBMissesAsync(keys: readonly string[]): Promise<void>;
13
30
 
31
+ /**
32
+ * Invalidate specified keys in cache. Subsequent loads for these keys may return a cache miss.
33
+ *
34
+ * @param keys - keys to invalidate
35
+ */
14
36
  invalidateManyAsync(keys: readonly string[]): Promise<void>;
37
+
38
+ /**
39
+ * Create a cache key for a field and value of a object being cached or invalidated.
40
+ *
41
+ * @param fieldName - name of the object field for this cache key
42
+ * @param fieldValue - value of the obejct field for this cache key
43
+ */
44
+ makeCacheKey<N extends keyof TFields>(fieldName: N, fieldValue: NonNullable<TFields[N]>): string;
15
45
  }
@@ -2,12 +2,10 @@ import invariant from 'invariant';
2
2
 
3
3
  import { IEntityClass } from './Entity';
4
4
  import EntityAssociationLoader from './EntityAssociationLoader';
5
- import { EntityCompanionDefinition } from './EntityCompanionProvider';
6
5
  import EntityLoader from './EntityLoader';
7
6
  import EntityPrivacyPolicy from './EntityPrivacyPolicy';
8
7
  import { EntityQueryContext } from './EntityQueryContext';
9
8
  import ViewerContext from './ViewerContext';
10
- import { pick } from './entityUtils';
11
9
 
12
10
  /**
13
11
  * A readonly entity exposes only the read functionality of an Entity. Used as the base
@@ -18,45 +16,47 @@ import { pick } from './entityUtils';
18
16
  * - Entities representing immutable tables.
19
17
  */
20
18
  export default abstract class ReadonlyEntity<
21
- TFields,
19
+ TFields extends object,
22
20
  TID extends NonNullable<TFields[TSelectedFields]>,
23
21
  TViewerContext extends ViewerContext,
24
22
  TSelectedFields extends keyof TFields = keyof TFields
25
23
  > {
24
+ private readonly viewerContext: TViewerContext;
26
25
  private readonly id: TID;
27
- private readonly rawFields: Readonly<Pick<TFields, TSelectedFields>>;
26
+ private readonly databaseFields: Readonly<TFields>;
27
+ private readonly selectedFields: Readonly<Pick<TFields, TSelectedFields>>;
28
28
 
29
29
  /**
30
30
  * Constructs an instance of an Entity.
31
- * @param viewerContext - the ViewerContext reading this entity
32
- * @param rawFields - all underlying fields for this entity's data
31
+ *
32
+ * @param constructorParam - data needed to construct an instance of an entity
33
+ * viewerContext - the ViewerContext reading this entity
34
+ * id - the ID of this entity
35
+ * databaseFields - all underlying fields for this entity's data
36
+ * selectedFields - selected fields for this entity from TSelectedFields type
37
+ *
38
+ * This should only be overridden in cases where additional data validation is needed.
39
+ * The params should not be modified when calling super during constructions.
33
40
  *
34
41
  * @internal
35
42
  */
36
- constructor(
37
- private readonly viewerContext: TViewerContext,
38
- private readonly databaseFields: Readonly<TFields>
39
- ) {
40
- const companionDefinition = (
41
- this.constructor as any
42
- ).getCompanionDefinition() as EntityCompanionDefinition<
43
- TFields,
44
- TID,
45
- TViewerContext,
46
- this,
47
- EntityPrivacyPolicy<TFields, TID, TViewerContext, this, TSelectedFields>,
48
- TSelectedFields
49
- >;
50
- const idField = companionDefinition.entityConfiguration.idField as keyof Pick<
51
- TFields,
52
- TSelectedFields
53
- >;
54
- const id = databaseFields[idField];
55
- invariant(id, 'must provide ID to create an entity');
56
- this.id = id as any;
43
+ constructor({
44
+ viewerContext,
45
+ id,
46
+ databaseFields,
47
+ selectedFields,
48
+ }: {
49
+ viewerContext: TViewerContext;
50
+ id: TID;
51
+ databaseFields: Readonly<TFields>;
52
+ selectedFields: Readonly<Pick<TFields, TSelectedFields>>;
53
+ }) {
54
+ invariant(id !== null && id !== undefined, 'id must be non-null');
57
55
 
58
- const entitySelectedFields = companionDefinition.entitySelectedFields as (keyof TFields)[];
59
- this.rawFields = pick(databaseFields, entitySelectedFields);
56
+ this.viewerContext = viewerContext;
57
+ this.id = id;
58
+ this.databaseFields = databaseFields;
59
+ this.selectedFields = selectedFields;
60
60
  }
61
61
 
62
62
  toString(): string {
@@ -102,14 +102,14 @@ export default abstract class ReadonlyEntity<
102
102
  getField<K extends keyof Pick<TFields, TSelectedFields>>(
103
103
  fieldName: K
104
104
  ): Pick<TFields, TSelectedFields>[K] {
105
- return this.rawFields[fieldName];
105
+ return this.selectedFields[fieldName];
106
106
  }
107
107
 
108
108
  /**
109
109
  * @returns all underlying fields from this entity's data
110
110
  */
111
111
  getAllFields(): Readonly<Pick<TFields, TSelectedFields>> {
112
- return { ...this.rawFields };
112
+ return { ...this.selectedFields };
113
113
  }
114
114
 
115
115
  /**
@@ -125,7 +125,7 @@ export default abstract class ReadonlyEntity<
125
125
  * @param queryContext - query context in which to perform the load
126
126
  */
127
127
  static loader<
128
- TMFields,
128
+ TMFields extends object,
129
129
  TMID extends NonNullable<TMFields[TMSelectedFields]>,
130
130
  TMViewerContext extends ViewerContext,
131
131
  TMViewerContext2 extends TMViewerContext,
@@ -1,7 +1,11 @@
1
1
  import { IEntityClass } from './Entity';
2
2
  import EntityCompanionProvider, { DatabaseAdapterFlavor } from './EntityCompanionProvider';
3
3
  import EntityPrivacyPolicy from './EntityPrivacyPolicy';
4
- import { EntityQueryContext, EntityTransactionalQueryContext } from './EntityQueryContext';
4
+ import {
5
+ EntityQueryContext,
6
+ EntityTransactionalQueryContext,
7
+ TransactionConfig,
8
+ } from './EntityQueryContext';
5
9
  import ReadonlyEntity from './ReadonlyEntity';
6
10
  import ViewerScopedEntityCompanion from './ViewerScopedEntityCompanion';
7
11
  import ViewerScopedEntityCompanionProvider from './ViewerScopedEntityCompanionProvider';
@@ -27,7 +31,7 @@ export default class ViewerContext {
27
31
  }
28
32
 
29
33
  getViewerScopedEntityCompanionForClass<
30
- TMFields,
34
+ TMFields extends object,
31
35
  TMID extends NonNullable<TMFields[TMSelectedFields]>,
32
36
  TMViewerContext extends ViewerContext,
33
37
  TMEntity extends ReadonlyEntity<TMFields, TMID, TMViewerContext, TMSelectedFields>,
@@ -56,10 +60,7 @@ export default class ViewerContext {
56
60
  TMPrivacyPolicy,
57
61
  TMSelectedFields
58
62
  > {
59
- return this.viewerScopedEntityCompanionProvider.getViewerScopedCompanionForEntity(
60
- entityClass,
61
- entityClass.getCompanionDefinition()
62
- );
63
+ return this.viewerScopedEntityCompanionProvider.getViewerScopedCompanionForEntity(entityClass);
63
64
  }
64
65
 
65
66
  /**
@@ -82,11 +83,12 @@ export default class ViewerContext {
82
83
  */
83
84
  async runInTransactionForDatabaseAdaptorFlavorAsync<TResult>(
84
85
  databaseAdaptorFlavor: DatabaseAdapterFlavor,
85
- transactionScope: (queryContext: EntityTransactionalQueryContext) => Promise<TResult>
86
+ transactionScope: (queryContext: EntityTransactionalQueryContext) => Promise<TResult>,
87
+ transactionConfig?: TransactionConfig
86
88
  ): Promise<TResult> {
87
89
  return await this.entityCompanionProvider
88
90
  .getQueryContextProviderForDatabaseAdaptorFlavor(databaseAdaptorFlavor)
89
91
  .getQueryContext()
90
- .runInTransactionIfNotInTransactionAsync(transactionScope);
92
+ .runInTransactionIfNotInTransactionAsync(transactionScope, transactionConfig);
91
93
  }
92
94
  }
@@ -12,7 +12,7 @@ import IEntityMetricsAdapter from './metrics/IEntityMetricsAdapter';
12
12
  * from the viewer-scoped entity companion provider.
13
13
  */
14
14
  export default class ViewerScopedEntityCompanion<
15
- TFields,
15
+ TFields extends object,
16
16
  TID extends NonNullable<TFields[TSelectedFields]>,
17
17
  TViewerContext extends ViewerContext,
18
18
  TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>,
@@ -26,7 +26,7 @@ export default class ViewerScopedEntityCompanion<
26
26
  TSelectedFields extends keyof TFields
27
27
  > {
28
28
  constructor(
29
- private readonly entityCompanion: EntityCompanion<
29
+ public readonly entityCompanion: EntityCompanion<
30
30
  TFields,
31
31
  TID,
32
32
  TViewerContext,
@@ -1,5 +1,5 @@
1
1
  import { IEntityClass } from './Entity';
2
- import EntityCompanionProvider, { EntityCompanionDefinition } from './EntityCompanionProvider';
2
+ import EntityCompanionProvider from './EntityCompanionProvider';
3
3
  import EntityPrivacyPolicy from './EntityPrivacyPolicy';
4
4
  import ReadonlyEntity from './ReadonlyEntity';
5
5
  import ViewerContext from './ViewerContext';
@@ -19,10 +19,10 @@ export default class ViewerScopedEntityCompanionProvider {
19
19
  * companion is constructed using the configuration provided by the factory.
20
20
  *
21
21
  * @param entityClass - entity class to load
22
- * @param factory - entity companion factory
22
+ * @param entityCompanionDefinitionFn - function defining entity companion definition
23
23
  */
24
24
  getViewerScopedCompanionForEntity<
25
- TFields,
25
+ TFields extends object,
26
26
  TID extends NonNullable<TFields[TSelectedFields]>,
27
27
  TViewerContext extends ViewerContext,
28
28
  TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>,
@@ -42,14 +42,6 @@ export default class ViewerScopedEntityCompanionProvider {
42
42
  TEntity,
43
43
  TPrivacyPolicy,
44
44
  TSelectedFields
45
- >,
46
- entityCompanionDefinition: EntityCompanionDefinition<
47
- TFields,
48
- TID,
49
- TViewerContext,
50
- TEntity,
51
- TPrivacyPolicy,
52
- TSelectedFields
53
45
  >
54
46
  ): ViewerScopedEntityCompanion<
55
47
  TFields,
@@ -60,7 +52,7 @@ export default class ViewerScopedEntityCompanionProvider {
60
52
  TSelectedFields
61
53
  > {
62
54
  return new ViewerScopedEntityCompanion(
63
- this.entityCompanionProvider.getCompanionForEntity(entityClass, entityCompanionDefinition),
55
+ this.entityCompanionProvider.getCompanionForEntity(entityClass),
64
56
  this.viewerContext as TViewerContext
65
57
  );
66
58
  }
@@ -9,7 +9,7 @@ import ViewerContext from './ViewerContext';
9
9
  * Provides a cleaner API for loading entities by passing through the ViewerContext.
10
10
  */
11
11
  export default class ViewerScopedEntityLoaderFactory<
12
- TFields,
12
+ TFields extends object,
13
13
  TID extends NonNullable<TFields[TSelectedFields]>,
14
14
  TViewerContext extends ViewerContext,
15
15
  TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>,
@@ -9,7 +9,7 @@ import ViewerContext from './ViewerContext';
9
9
  * Provides a cleaner API for mutating entities by passing through the ViewerContext.
10
10
  */
11
11
  export default class ViewerScopedEntityMutatorFactory<
12
- TFields,
12
+ TFields extends object,
13
13
  TID extends NonNullable<TFields[TSelectedFields]>,
14
14
  TViewerContext extends ViewerContext,
15
15
  TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>,
@@ -1,9 +1,9 @@
1
1
  import invariant from 'invariant';
2
2
 
3
3
  import ComposedEntityCacheAdapter from '../ComposedEntityCacheAdapter';
4
- import EntityCacheAdapter from '../EntityCacheAdapter';
5
4
  import EntityConfiguration from '../EntityConfiguration';
6
5
  import { UUIDField } from '../EntityFields';
6
+ import IEntityCacheAdapter from '../IEntityCacheAdapter';
7
7
  import { CacheLoadResult, CacheStatus } from '../internal/ReadThroughEntityCache';
8
8
 
9
9
  type BlahFields = {
@@ -23,13 +23,11 @@ const entityConfiguration = new EntityConfiguration<BlahFields>({
23
23
  export const DOES_NOT_EXIST_LOCAL_MEMORY_CACHE = Symbol('doesNotExist');
24
24
  type LocalMemoryCacheValue<TFields> = Readonly<TFields> | typeof DOES_NOT_EXIST_LOCAL_MEMORY_CACHE;
25
25
 
26
- class TestLocalCacheAdapter<TFields> extends EntityCacheAdapter<TFields> {
26
+ class TestLocalCacheAdapter<TFields> implements IEntityCacheAdapter<TFields> {
27
27
  constructor(
28
- entityConfiguration: EntityConfiguration<TFields>,
28
+ private readonly entityConfiguration: EntityConfiguration<TFields>,
29
29
  private readonly cache: Map<string, LocalMemoryCacheValue<TFields>>
30
- ) {
31
- super(entityConfiguration);
32
- }
30
+ ) {}
33
31
 
34
32
  public async loadManyAsync<N extends keyof TFields>(
35
33
  fieldName: N,
@@ -123,10 +121,7 @@ function makeTestCacheAdapters(): {
123
121
  const fallbackCache = new Map();
124
122
  const fallbackCacheAdapter = new TestLocalCacheAdapter(entityConfiguration, fallbackCache);
125
123
 
126
- const cacheAdapter = new ComposedEntityCacheAdapter(entityConfiguration, [
127
- primaryCacheAdapter,
128
- fallbackCacheAdapter,
129
- ]);
124
+ const cacheAdapter = new ComposedEntityCacheAdapter([primaryCacheAdapter, fallbackCacheAdapter]);
130
125
 
131
126
  return {
132
127
  primaryCache,
@@ -229,7 +224,7 @@ describe(ComposedEntityCacheAdapter, () => {
229
224
  });
230
225
 
231
226
  it('handles 0 cache adapter compose case', async () => {
232
- const cacheAdapter = new ComposedEntityCacheAdapter(entityConfiguration, []);
227
+ const cacheAdapter = new ComposedEntityCacheAdapter<any>([]);
233
228
  const results = await cacheAdapter.loadManyAsync('id', []);
234
229
  expect(results).toEqual(new Map());
235
230
  });
@@ -330,6 +330,7 @@ describe(EnforcingEntityLoader, () => {
330
330
  'tryConstructEntities',
331
331
  'validateFieldValues',
332
332
  'constructAndAuthorizeEntitiesAsync',
333
+ 'constructEntity',
333
334
  ];
334
335
  expect(loaderProperties).toEqual(expect.arrayContaining(knownLoaderOnlyDifferences));
335
336