@expo/entity 0.35.0 → 0.37.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 (309) hide show
  1. package/build/AuthorizationResultBasedEntityLoader.d.ts +128 -0
  2. package/build/AuthorizationResultBasedEntityLoader.js +196 -0
  3. package/build/AuthorizationResultBasedEntityLoader.js.map +1 -0
  4. package/build/ComposedEntityCacheAdapter.js +1 -0
  5. package/build/ComposedEntityCacheAdapter.js.map +1 -1
  6. package/build/ComposedSecondaryEntityCache.js +1 -0
  7. package/build/ComposedSecondaryEntityCache.js.map +1 -1
  8. package/build/EnforcingEntityLoader.d.ts +5 -4
  9. package/build/EnforcingEntityLoader.js +4 -2
  10. package/build/EnforcingEntityLoader.js.map +1 -1
  11. package/build/Entity.d.ts +0 -27
  12. package/build/Entity.js +0 -50
  13. package/build/Entity.js.map +1 -1
  14. package/build/EntityAssociationLoader.d.ts +1 -1
  15. package/build/EntityAssociationLoader.js +17 -8
  16. package/build/EntityAssociationLoader.js.map +1 -1
  17. package/build/EntityCompanion.js +9 -1
  18. package/build/EntityCompanion.js.map +1 -1
  19. package/build/EntityCompanionProvider.d.ts +3 -1
  20. package/build/EntityCompanionProvider.js +10 -4
  21. package/build/EntityCompanionProvider.js.map +1 -1
  22. package/build/EntityConfiguration.d.ts +2 -1
  23. package/build/EntityConfiguration.js +19 -1
  24. package/build/EntityConfiguration.js.map +1 -1
  25. package/build/EntityDatabaseAdapter.d.ts +2 -2
  26. package/build/EntityDatabaseAdapter.js +5 -3
  27. package/build/EntityDatabaseAdapter.js.map +1 -1
  28. package/build/EntityFieldDefinition.d.ts +21 -10
  29. package/build/EntityFieldDefinition.js +8 -9
  30. package/build/EntityFieldDefinition.js.map +1 -1
  31. package/build/EntityFields.d.ts +10 -0
  32. package/build/EntityFields.js +15 -1
  33. package/build/EntityFields.js.map +1 -1
  34. package/build/EntityLoader.d.ts +12 -125
  35. package/build/EntityLoader.js +24 -239
  36. package/build/EntityLoader.js.map +1 -1
  37. package/build/EntityLoaderFactory.d.ts +1 -1
  38. package/build/EntityLoaderFactory.js +3 -0
  39. package/build/EntityLoaderFactory.js.map +1 -1
  40. package/build/EntityLoaderUtils.d.ts +58 -0
  41. package/build/EntityLoaderUtils.js +109 -0
  42. package/build/EntityLoaderUtils.js.map +1 -0
  43. package/build/EntityMutator.d.ts +1 -0
  44. package/build/EntityMutator.js +71 -56
  45. package/build/EntityMutator.js.map +1 -1
  46. package/build/EntityMutatorFactory.js +9 -0
  47. package/build/EntityMutatorFactory.js.map +1 -1
  48. package/build/EntityPrivacyPolicy.d.ts +11 -5
  49. package/build/EntityPrivacyPolicy.js +5 -7
  50. package/build/EntityPrivacyPolicy.js.map +1 -1
  51. package/build/EntityQueryContext.d.ts +2 -1
  52. package/build/EntityQueryContext.js +11 -6
  53. package/build/EntityQueryContext.js.map +1 -1
  54. package/build/EntitySecondaryCacheLoader.js +5 -1
  55. package/build/EntitySecondaryCacheLoader.js.map +1 -1
  56. package/build/GenericEntityCacheAdapter.js +1 -0
  57. package/build/GenericEntityCacheAdapter.js.map +1 -1
  58. package/build/GenericSecondaryEntityCache.js +2 -0
  59. package/build/GenericSecondaryEntityCache.js.map +1 -1
  60. package/build/IEntityCacheAdapterProvider.d.ts +1 -1
  61. package/build/IEntityDatabaseAdapterProvider.d.ts +1 -1
  62. package/build/ReadonlyEntity.js +5 -1
  63. package/build/ReadonlyEntity.js.map +1 -1
  64. package/build/ViewerContext.js +2 -0
  65. package/build/ViewerContext.js.map +1 -1
  66. package/build/ViewerScopedEntityCompanion.js +2 -0
  67. package/build/ViewerScopedEntityCompanion.js.map +1 -1
  68. package/build/ViewerScopedEntityCompanionProvider.d.ts +0 -1
  69. package/build/ViewerScopedEntityCompanionProvider.js +2 -1
  70. package/build/ViewerScopedEntityCompanionProvider.js.map +1 -1
  71. package/build/ViewerScopedEntityLoaderFactory.d.ts +1 -1
  72. package/build/ViewerScopedEntityLoaderFactory.js +2 -0
  73. package/build/ViewerScopedEntityLoaderFactory.js.map +1 -1
  74. package/build/ViewerScopedEntityMutatorFactory.js +2 -0
  75. package/build/ViewerScopedEntityMutatorFactory.js.map +1 -1
  76. package/build/__tests__/ComposedCacheAdapter-test.js +2 -0
  77. package/build/__tests__/ComposedCacheAdapter-test.js.map +1 -1
  78. package/build/__tests__/ComposedSecondaryEntityCache-test.js +1 -0
  79. package/build/__tests__/ComposedSecondaryEntityCache-test.js.map +1 -1
  80. package/build/__tests__/EnforcingEntityLoader-test.js +101 -113
  81. package/build/__tests__/EnforcingEntityLoader-test.js.map +1 -1
  82. package/build/__tests__/Entity-test.js +0 -132
  83. package/build/__tests__/Entity-test.js.map +1 -1
  84. package/build/__tests__/EntityAssociationLoader-test.js +6 -2
  85. package/build/__tests__/EntityAssociationLoader-test.js.map +1 -1
  86. package/build/__tests__/EntityCommonUseCases-test.js +24 -22
  87. package/build/__tests__/EntityCommonUseCases-test.js.map +1 -1
  88. package/build/__tests__/EntityCompanion-test.js +26 -3
  89. package/build/__tests__/EntityCompanion-test.js.map +1 -1
  90. package/build/__tests__/EntityConfiguration-test.js +103 -0
  91. package/build/__tests__/EntityConfiguration-test.js.map +1 -0
  92. package/build/__tests__/EntityDatabaseAdapter-test.js +6 -0
  93. package/build/__tests__/EntityDatabaseAdapter-test.js.map +1 -1
  94. package/build/__tests__/EntityEdges-test.js +61 -20
  95. package/build/__tests__/EntityEdges-test.js.map +1 -1
  96. package/build/__tests__/EntityFields-test.js +6 -0
  97. package/build/__tests__/EntityFields-test.js.map +1 -1
  98. package/build/__tests__/EntityLoader-constructor-test.js +16 -17
  99. package/build/__tests__/EntityLoader-constructor-test.js.map +1 -1
  100. package/build/__tests__/EntityLoader-test.js +74 -22
  101. package/build/__tests__/EntityLoader-test.js.map +1 -1
  102. package/build/__tests__/EntityMutator-MutationCacheConsistency-test.js +12 -15
  103. package/build/__tests__/EntityMutator-MutationCacheConsistency-test.js.map +1 -1
  104. package/build/__tests__/EntityMutator-test.js +54 -9
  105. package/build/__tests__/EntityMutator-test.js.map +1 -1
  106. package/build/__tests__/EntityPrivacyPolicy-test.js +77 -59
  107. package/build/__tests__/EntityPrivacyPolicy-test.js.map +1 -1
  108. package/build/__tests__/EntityQueryContext-test.js +9 -0
  109. package/build/__tests__/EntityQueryContext-test.js.map +1 -1
  110. package/build/__tests__/EntitySelfReferentialEdges-test.js +42 -25
  111. package/build/__tests__/EntitySelfReferentialEdges-test.js.map +1 -1
  112. package/build/__tests__/ViewerScopedEntityLoaderFactory-test.js.map +1 -1
  113. package/build/__tests__/cases/TwoEntitySameTableDisjointRows-test.js +20 -18
  114. package/build/__tests__/cases/TwoEntitySameTableDisjointRows-test.js.map +1 -1
  115. package/build/__tests__/cases/TwoEntitySameTableOverlappingRows-test.js +12 -15
  116. package/build/__tests__/cases/TwoEntitySameTableOverlappingRows-test.js.map +1 -1
  117. package/build/entityUtils.d.ts +1 -1
  118. package/build/entityUtils.js.map +1 -1
  119. package/build/errors/EntityCacheAdapterError.js +2 -5
  120. package/build/errors/EntityCacheAdapterError.js.map +1 -1
  121. package/build/errors/EntityDatabaseAdapterError.js +14 -35
  122. package/build/errors/EntityDatabaseAdapterError.js.map +1 -1
  123. package/build/errors/EntityError.js +1 -0
  124. package/build/errors/EntityError.js.map +1 -1
  125. package/build/errors/EntityInvalidFieldValueError.js +2 -2
  126. package/build/errors/EntityInvalidFieldValueError.js.map +1 -1
  127. package/build/errors/EntityNotAuthorizedError.js +3 -2
  128. package/build/errors/EntityNotAuthorizedError.js.map +1 -1
  129. package/build/errors/EntityNotFoundError.js +2 -2
  130. package/build/errors/EntityNotFoundError.js.map +1 -1
  131. package/build/index.d.ts +26 -20
  132. package/build/index.js +38 -28
  133. package/build/index.js.map +1 -1
  134. package/build/internal/EntityDataManager.d.ts +1 -1
  135. package/build/internal/EntityDataManager.js +6 -1
  136. package/build/internal/EntityDataManager.js.map +1 -1
  137. package/build/internal/EntityFieldTransformationUtils.d.ts +5 -5
  138. package/build/internal/EntityFieldTransformationUtils.js +5 -8
  139. package/build/internal/EntityFieldTransformationUtils.js.map +1 -1
  140. package/build/internal/EntityTableDataCoordinator.d.ts +1 -1
  141. package/build/internal/EntityTableDataCoordinator.js +5 -0
  142. package/build/internal/EntityTableDataCoordinator.js.map +1 -1
  143. package/build/internal/ReadThroughEntityCache.d.ts +1 -1
  144. package/build/internal/ReadThroughEntityCache.js +2 -0
  145. package/build/internal/ReadThroughEntityCache.js.map +1 -1
  146. package/build/internal/__tests__/EntityFieldTransformationUtils-test.js +6 -2
  147. package/build/internal/__tests__/EntityFieldTransformationUtils-test.js.map +1 -1
  148. package/build/internal/__tests__/ReadThroughEntityCache-test.js +33 -0
  149. package/build/internal/__tests__/ReadThroughEntityCache-test.js.map +1 -1
  150. package/build/metrics/IEntityMetricsAdapter.d.ts +1 -1
  151. package/build/rules/AlwaysAllowPrivacyPolicyRule.d.ts +1 -1
  152. package/build/rules/AlwaysAllowPrivacyPolicyRule.js.map +1 -1
  153. package/build/rules/AlwaysDenyPrivacyPolicyRule.d.ts +1 -1
  154. package/build/rules/AlwaysDenyPrivacyPolicyRule.js.map +1 -1
  155. package/build/rules/AlwaysSkipPrivacyPolicyRule.d.ts +1 -1
  156. package/build/rules/AlwaysSkipPrivacyPolicyRule.js.map +1 -1
  157. package/build/rules/PrivacyPolicyRule.d.ts +1 -1
  158. package/build/rules/PrivacyPolicyRule.js.map +1 -1
  159. package/build/rules/__tests__/AlwaysAllowPrivacyPolicyRule-test.js.map +1 -1
  160. package/build/rules/__tests__/AlwaysDenyPrivacyPolicyRule-test.js.map +1 -1
  161. package/build/rules/__tests__/AlwaysSkipPrivacyPolicyRule-test.js.map +1 -1
  162. package/build/testfixtures/DateIDTestEntity.js +12 -15
  163. package/build/testfixtures/DateIDTestEntity.js.map +1 -1
  164. package/build/testfixtures/SimpleTestEntity.js +12 -15
  165. package/build/testfixtures/SimpleTestEntity.js.map +1 -1
  166. package/build/testfixtures/TestEntity.js +12 -15
  167. package/build/testfixtures/TestEntity.js.map +1 -1
  168. package/build/testfixtures/TestEntity2.js +12 -15
  169. package/build/testfixtures/TestEntity2.js.map +1 -1
  170. package/build/testfixtures/TestEntityNumberKey.js +12 -15
  171. package/build/testfixtures/TestEntityNumberKey.js.map +1 -1
  172. package/build/testfixtures/TestEntityWithMutationTriggers.d.ts +36 -0
  173. package/build/testfixtures/TestEntityWithMutationTriggers.js +82 -0
  174. package/build/testfixtures/TestEntityWithMutationTriggers.js.map +1 -0
  175. package/build/utils/EntityPrivacyUtils.d.ts +34 -0
  176. package/build/utils/EntityPrivacyUtils.js +160 -0
  177. package/build/utils/EntityPrivacyUtils.js.map +1 -0
  178. package/build/utils/__tests__/EntityPrivacyUtils-test.d.ts +1 -0
  179. package/build/utils/__tests__/EntityPrivacyUtils-test.js +395 -0
  180. package/build/utils/__tests__/EntityPrivacyUtils-test.js.map +1 -0
  181. package/build/utils/__tests__/mergeEntityMutationTriggerConfigurations-test.d.ts +1 -0
  182. package/build/utils/__tests__/mergeEntityMutationTriggerConfigurations-test.js +26 -0
  183. package/build/utils/__tests__/mergeEntityMutationTriggerConfigurations-test.js.map +1 -0
  184. package/build/utils/collections/maps.js.map +1 -1
  185. package/build/utils/mergeEntityMutationTriggerConfigurations.d.ts +4 -0
  186. package/build/utils/mergeEntityMutationTriggerConfigurations.js +28 -0
  187. package/build/utils/mergeEntityMutationTriggerConfigurations.js.map +1 -0
  188. package/build/utils/testing/PrivacyPolicyRuleTestUtils.d.ts +1 -1
  189. package/build/utils/testing/PrivacyPolicyRuleTestUtils.js.map +1 -1
  190. package/build/utils/testing/StubCacheAdapter.d.ts +3 -3
  191. package/build/utils/testing/StubCacheAdapter.js +3 -3
  192. package/build/utils/testing/StubCacheAdapter.js.map +1 -1
  193. package/build/utils/testing/StubDatabaseAdapter.d.ts +2 -2
  194. package/build/utils/testing/StubDatabaseAdapter.js +4 -2
  195. package/build/utils/testing/StubDatabaseAdapter.js.map +1 -1
  196. package/build/utils/testing/StubDatabaseAdapterProvider.d.ts +1 -1
  197. package/build/utils/testing/StubDatabaseAdapterProvider.js +1 -3
  198. package/build/utils/testing/StubDatabaseAdapterProvider.js.map +1 -1
  199. package/build/utils/testing/__tests__/PrivacyPolicyRuleTestUtils-test.d.ts +1 -0
  200. package/build/utils/testing/__tests__/PrivacyPolicyRuleTestUtils-test.js +42 -0
  201. package/build/utils/testing/__tests__/PrivacyPolicyRuleTestUtils-test.js.map +1 -0
  202. package/build/utils/testing/__tests__/StubDatabaseAdapter-test.js +53 -0
  203. package/build/utils/testing/__tests__/StubDatabaseAdapter-test.js.map +1 -1
  204. package/build/utils/testing/describeFieldTestCase.js.map +1 -1
  205. package/package.json +5 -4
  206. package/src/AuthorizationResultBasedEntityLoader.ts +297 -0
  207. package/src/ComposedEntityCacheAdapter.ts +6 -6
  208. package/src/ComposedSecondaryEntityCache.ts +8 -8
  209. package/src/EnforcingEntityLoader.ts +20 -19
  210. package/src/Entity.ts +11 -126
  211. package/src/EntityAssociationLoader.ts +40 -41
  212. package/src/EntityCompanion.ts +8 -4
  213. package/src/EntityCompanionProvider.ts +24 -16
  214. package/src/EntityConfiguration.ts +18 -7
  215. package/src/EntityDatabaseAdapter.ts +41 -41
  216. package/src/EntityFieldDefinition.ts +28 -18
  217. package/src/EntityFields.ts +15 -0
  218. package/src/EntityLoader.ts +63 -357
  219. package/src/EntityLoaderFactory.ts +10 -4
  220. package/src/EntityLoaderUtils.ts +149 -0
  221. package/src/EntityMutationInfo.ts +2 -2
  222. package/src/EntityMutationTriggerConfiguration.ts +5 -5
  223. package/src/EntityMutationValidator.ts +2 -2
  224. package/src/EntityMutator.ts +146 -144
  225. package/src/EntityMutatorFactory.ts +8 -8
  226. package/src/EntityPrivacyPolicy.ts +78 -28
  227. package/src/EntityQueryContext.ts +14 -13
  228. package/src/EntityQueryContextProvider.ts +5 -5
  229. package/src/EntitySecondaryCacheLoader.ts +13 -11
  230. package/src/GenericEntityCacheAdapter.ts +10 -10
  231. package/src/GenericSecondaryEntityCache.ts +6 -6
  232. package/src/IEntityCacheAdapter.ts +4 -4
  233. package/src/IEntityCacheAdapterProvider.ts +2 -2
  234. package/src/IEntityDatabaseAdapterProvider.ts +2 -2
  235. package/src/ReadonlyEntity.ts +5 -5
  236. package/src/ViewerContext.ts +5 -5
  237. package/src/ViewerScopedEntityCompanion.ts +4 -4
  238. package/src/ViewerScopedEntityCompanionProvider.ts +4 -5
  239. package/src/ViewerScopedEntityLoaderFactory.ts +10 -4
  240. package/src/ViewerScopedEntityMutatorFactory.ts +5 -5
  241. package/src/__tests__/ComposedCacheAdapter-test.ts +12 -10
  242. package/src/__tests__/ComposedSecondaryEntityCache-test.ts +8 -8
  243. package/src/__tests__/EnforcingEntityLoader-test.ts +236 -159
  244. package/src/__tests__/Entity-test.ts +0 -202
  245. package/src/__tests__/EntityAssociationLoader-test.ts +29 -25
  246. package/src/__tests__/EntityCommonUseCases-test.ts +29 -13
  247. package/src/__tests__/EntityCompanion-test.ts +57 -5
  248. package/src/__tests__/EntityConfiguration-test.ts +118 -0
  249. package/src/__tests__/EntityDatabaseAdapter-test.ts +11 -11
  250. package/src/__tests__/EntityEdges-test.ts +108 -36
  251. package/src/__tests__/EntityFields-test.ts +14 -2
  252. package/src/__tests__/EntityLoader-constructor-test.ts +20 -7
  253. package/src/__tests__/EntityLoader-test.ts +214 -86
  254. package/src/__tests__/EntityMutator-MutationCacheConsistency-test.ts +2 -2
  255. package/src/__tests__/EntityMutator-test.ts +281 -96
  256. package/src/__tests__/EntityPrivacyPolicy-test.ts +166 -53
  257. package/src/__tests__/EntityQueryContext-test.ts +30 -12
  258. package/src/__tests__/EntitySecondaryCacheLoader-test.ts +7 -7
  259. package/src/__tests__/EntitySelfReferentialEdges-test.ts +46 -26
  260. package/src/__tests__/GenericEntityCacheAdapter-test.ts +2 -2
  261. package/src/__tests__/ViewerContext-test.ts +1 -1
  262. package/src/__tests__/ViewerScopedEntityCompanion-test.ts +2 -2
  263. package/src/__tests__/ViewerScopedEntityCompanionProvider-test.ts +2 -2
  264. package/src/__tests__/ViewerScopedEntityLoaderFactory-test.ts +2 -1
  265. package/src/__tests__/cases/TwoEntitySameTableDisjointRows-test.ts +19 -19
  266. package/src/__tests__/entityUtils-test.ts +2 -2
  267. package/src/entityUtils.ts +4 -4
  268. package/src/errors/EntityError.ts +4 -1
  269. package/src/errors/EntityInvalidFieldValueError.ts +2 -2
  270. package/src/errors/EntityNotAuthorizedError.ts +3 -3
  271. package/src/errors/EntityNotFoundError.ts +2 -2
  272. package/src/index.ts +26 -20
  273. package/src/internal/EntityDataManager.ts +24 -24
  274. package/src/internal/EntityFieldTransformationUtils.ts +39 -32
  275. package/src/internal/EntityTableDataCoordinator.ts +3 -3
  276. package/src/internal/ReadThroughEntityCache.ts +9 -9
  277. package/src/internal/__tests__/EntityDataManager-test.ts +51 -51
  278. package/src/internal/__tests__/EntityFieldTransformationUtils-test.ts +14 -10
  279. package/src/internal/__tests__/ReadThroughEntityCache-test.ts +74 -18
  280. package/src/metrics/EntityMetricsUtils.ts +4 -4
  281. package/src/metrics/IEntityMetricsAdapter.ts +1 -1
  282. package/src/rules/AlwaysAllowPrivacyPolicyRule.ts +9 -3
  283. package/src/rules/AlwaysDenyPrivacyPolicyRule.ts +9 -3
  284. package/src/rules/AlwaysSkipPrivacyPolicyRule.ts +9 -3
  285. package/src/rules/PrivacyPolicyRule.ts +9 -3
  286. package/src/rules/__tests__/AlwaysAllowPrivacyPolicyRule-test.ts +2 -1
  287. package/src/rules/__tests__/AlwaysDenyPrivacyPolicyRule-test.ts +2 -1
  288. package/src/rules/__tests__/AlwaysSkipPrivacyPolicyRule-test.ts +2 -1
  289. package/src/testfixtures/TestEntity.ts +1 -1
  290. package/src/testfixtures/TestEntityWithMutationTriggers.ts +156 -0
  291. package/src/utils/EntityPrivacyUtils.ts +325 -0
  292. package/src/utils/__tests__/EntityPrivacyUtils-test.ts +570 -0
  293. package/src/utils/__tests__/mergeEntityMutationTriggerConfigurations-test.ts +29 -0
  294. package/src/utils/collections/__tests__/maps-test.ts +2 -2
  295. package/src/utils/collections/maps.ts +11 -11
  296. package/src/utils/mergeEntityMutationTriggerConfigurations.ts +44 -0
  297. package/src/utils/testing/PrivacyPolicyRuleTestUtils.ts +25 -22
  298. package/src/utils/testing/StubCacheAdapter.ts +17 -15
  299. package/src/utils/testing/StubDatabaseAdapter.ts +35 -30
  300. package/src/utils/testing/StubDatabaseAdapterProvider.ts +2 -2
  301. package/src/utils/testing/StubQueryContextProvider.ts +2 -2
  302. package/src/utils/testing/__tests__/PrivacyPolicyRuleTestUtils-test.ts +42 -0
  303. package/src/utils/testing/__tests__/StubDatabaseAdapter-test.ts +111 -29
  304. package/src/utils/testing/createUnitTestEntityCompanionProvider.ts +2 -2
  305. package/src/utils/testing/describeFieldTestCase.ts +1 -1
  306. package/build/__tests__/EntityDataConfiguration-test.js +0 -68
  307. package/build/__tests__/EntityDataConfiguration-test.js.map +0 -1
  308. package/src/__tests__/EntityDataConfiguration-test.ts +0 -77
  309. /package/build/__tests__/{EntityDataConfiguration-test.d.ts → EntityConfiguration-test.d.ts} +0 -0
@@ -25,7 +25,7 @@ import { computeIfAbsent, zipToMap } from '../utils/collections/maps';
25
25
  *
26
26
  * It is also responsible for invalidating all sources of data when mutated using EntityMutator.
27
27
  */
28
- export default class EntityDataManager<TFields> {
28
+ export default class EntityDataManager<TFields extends Record<string, any>> {
29
29
  private readonly fieldDataLoaders: Map<
30
30
  keyof TFields,
31
31
  DataLoader<NonNullable<TFields[keyof TFields]>, readonly Readonly<TFields>[]>
@@ -36,30 +36,30 @@ export default class EntityDataManager<TFields> {
36
36
  private readonly entityCache: ReadThroughEntityCache<TFields>,
37
37
  private readonly queryContextProvider: EntityQueryContextProvider,
38
38
  private readonly metricsAdapter: IEntityMetricsAdapter,
39
- private readonly entityClassName: string
39
+ private readonly entityClassName: string,
40
40
  ) {}
41
41
 
42
42
  private getFieldDataLoaderForFieldName<N extends keyof TFields>(
43
- fieldName: N
43
+ fieldName: N,
44
44
  ): DataLoader<NonNullable<TFields[N]>, readonly Readonly<TFields>[]> {
45
45
  return computeIfAbsent(this.fieldDataLoaders, fieldName, () => {
46
46
  return new DataLoader(
47
47
  async (
48
- fieldValues: readonly NonNullable<TFields[N]>[]
48
+ fieldValues: readonly NonNullable<TFields[N]>[],
49
49
  ): Promise<readonly (readonly TFields[])[]> => {
50
50
  const objectMap = await this.loadManyForDataLoaderByFieldEqualingAsync(
51
51
  fieldName,
52
- fieldValues
52
+ fieldValues,
53
53
  );
54
54
  return fieldValues.map((fv) => objectMap.get(fv) ?? []);
55
- }
55
+ },
56
56
  );
57
57
  });
58
58
  }
59
59
 
60
60
  private async loadManyForDataLoaderByFieldEqualingAsync<N extends keyof TFields>(
61
61
  fieldName: N,
62
- fieldValues: readonly NonNullable<TFields[N]>[]
62
+ fieldValues: readonly NonNullable<TFields[N]>[],
63
63
  ): Promise<ReadonlyMap<NonNullable<TFields[N]>, readonly Readonly<TFields>[]>> {
64
64
  this.metricsAdapter.incrementDataManagerLoadCount({
65
65
  type: IncrementLoadCountEventType.CACHE,
@@ -78,9 +78,9 @@ export default class EntityDataManager<TFields> {
78
78
  return await this.databaseAdapter.fetchManyWhereAsync(
79
79
  this.queryContextProvider.getQueryContext(),
80
80
  fieldName,
81
- fetcherValues
81
+ fetcherValues,
82
82
  );
83
- }
83
+ },
84
84
  );
85
85
  }
86
86
 
@@ -95,28 +95,28 @@ export default class EntityDataManager<TFields> {
95
95
  async loadManyByFieldEqualingAsync<N extends keyof TFields>(
96
96
  queryContext: EntityQueryContext,
97
97
  fieldName: N,
98
- fieldValues: readonly NonNullable<TFields[N]>[]
98
+ fieldValues: readonly NonNullable<TFields[N]>[],
99
99
  ): Promise<ReadonlyMap<NonNullable<TFields[N]>, readonly Readonly<TFields>[]>> {
100
100
  return await timeAndLogLoadMapEventAsync(
101
101
  this.metricsAdapter,
102
102
  EntityMetricsLoadType.LOAD_MANY,
103
- this.entityClassName
103
+ this.entityClassName,
104
104
  )(this.loadManyByFieldEqualingInternalAsync(queryContext, fieldName, fieldValues));
105
105
  }
106
106
 
107
107
  private async loadManyByFieldEqualingInternalAsync<N extends keyof TFields>(
108
108
  queryContext: EntityQueryContext,
109
109
  fieldName: N,
110
- fieldValues: readonly NonNullable<TFields[N]>[]
110
+ fieldValues: readonly NonNullable<TFields[N]>[],
111
111
  ): Promise<ReadonlyMap<NonNullable<TFields[N]>, readonly Readonly<TFields>[]>> {
112
112
  const nullOrUndefinedValueIndex = fieldValues.findIndex(
113
- (value) => value === null || value === undefined
113
+ (value) => value === null || value === undefined,
114
114
  );
115
115
  if (nullOrUndefinedValueIndex >= 0) {
116
116
  throw new Error(
117
117
  `Invalid load: ${this.entityClassName} (${String(fieldName)} = ${
118
118
  fieldValues[nullOrUndefinedValueIndex]
119
- })`
119
+ })`,
120
120
  );
121
121
  }
122
122
 
@@ -153,18 +153,18 @@ export default class EntityDataManager<TFields> {
153
153
  async loadManyByFieldEqualityConjunctionAsync<N extends keyof TFields>(
154
154
  queryContext: EntityQueryContext,
155
155
  fieldEqualityOperands: FieldEqualityCondition<TFields, N>[],
156
- querySelectionModifiers: QuerySelectionModifiers<TFields>
156
+ querySelectionModifiers: QuerySelectionModifiers<TFields>,
157
157
  ): Promise<readonly Readonly<TFields>[]> {
158
158
  return await timeAndLogLoadEventAsync(
159
159
  this.metricsAdapter,
160
160
  EntityMetricsLoadType.LOAD_MANY_EQUALITY_CONJUNCTION,
161
- this.entityClassName
161
+ this.entityClassName,
162
162
  )(
163
163
  this.databaseAdapter.fetchManyByFieldEqualityConjunctionAsync(
164
164
  queryContext,
165
165
  fieldEqualityOperands,
166
- querySelectionModifiers
167
- )
166
+ querySelectionModifiers,
167
+ ),
168
168
  );
169
169
  }
170
170
 
@@ -181,25 +181,25 @@ export default class EntityDataManager<TFields> {
181
181
  queryContext: EntityQueryContext,
182
182
  rawWhereClause: string,
183
183
  bindings: any[] | object,
184
- querySelectionModifiers: QuerySelectionModifiersWithOrderByRaw<TFields>
184
+ querySelectionModifiers: QuerySelectionModifiersWithOrderByRaw<TFields>,
185
185
  ): Promise<readonly Readonly<TFields>[]> {
186
186
  return await timeAndLogLoadEventAsync(
187
187
  this.metricsAdapter,
188
188
  EntityMetricsLoadType.LOAD_MANY_RAW,
189
- this.entityClassName
189
+ this.entityClassName,
190
190
  )(
191
191
  this.databaseAdapter.fetchManyByRawWhereClauseAsync(
192
192
  queryContext,
193
193
  rawWhereClause,
194
194
  bindings,
195
- querySelectionModifiers
196
- )
195
+ querySelectionModifiers,
196
+ ),
197
197
  );
198
198
  }
199
199
 
200
200
  private async invalidateManyByFieldEqualingAsync<N extends keyof TFields>(
201
201
  fieldName: N,
202
- fieldValues: readonly NonNullable<TFields[N]>[]
202
+ fieldValues: readonly NonNullable<TFields[N]>[],
203
203
  ): Promise<void> {
204
204
  await this.entityCache.invalidateManyAsync(fieldName, fieldValues);
205
205
  const dataLoader = this.getFieldDataLoaderForFieldName(fieldName);
@@ -222,7 +222,7 @@ export default class EntityDataManager<TFields> {
222
222
  value as NonNullable<TFields[keyof TFields]>,
223
223
  ]);
224
224
  }
225
- })
225
+ }),
226
226
  );
227
227
  }
228
228
  }
@@ -1,4 +1,5 @@
1
1
  import invariant from 'invariant';
2
+ import nullthrows from 'nullthrows';
2
3
 
3
4
  import EntityConfiguration from '../EntityConfiguration';
4
5
 
@@ -19,19 +20,19 @@ export interface FieldTransformer<T> {
19
20
  */
20
21
  export type FieldTransformerMap = Map<string, FieldTransformer<any>>;
21
22
 
22
- export const getDatabaseFieldForEntityField = <TFields>(
23
+ export const getDatabaseFieldForEntityField = <TFields extends Record<string, any>>(
23
24
  entityConfiguration: EntityConfiguration<TFields>,
24
- entityField: keyof TFields
25
+ entityField: keyof TFields,
25
26
  ): string => {
26
27
  const databaseField = entityConfiguration.entityToDBFieldsKeyMapping.get(entityField);
27
28
  invariant(databaseField, `database field mapping missing for ${String(entityField)}`);
28
29
  return databaseField!;
29
30
  };
30
31
 
31
- export const transformDatabaseObjectToFields = <TFields>(
32
+ export const transformDatabaseObjectToFields = <TFields extends Record<string, any>>(
32
33
  entityConfiguration: EntityConfiguration<TFields>,
33
34
  fieldTransformerMap: FieldTransformerMap,
34
- databaseObject: { [key: string]: any }
35
+ databaseObject: { [key: string]: any },
35
36
  ): Readonly<TFields> => {
36
37
  const fields: TFields = {} as any;
37
38
  for (const k in databaseObject) {
@@ -42,17 +43,17 @@ export const transformDatabaseObjectToFields = <TFields>(
42
43
  entityConfiguration,
43
44
  fieldTransformerMap,
44
45
  fieldsKey,
45
- val
46
+ val,
46
47
  );
47
48
  }
48
49
  }
49
50
  return fields;
50
51
  };
51
52
 
52
- export const transformFieldsToDatabaseObject = <TFields>(
53
+ export const transformFieldsToDatabaseObject = <TFields extends Record<string, any>>(
53
54
  entityConfiguration: EntityConfiguration<TFields>,
54
55
  fieldTransformerMap: FieldTransformerMap,
55
- fields: Readonly<Partial<TFields>>
56
+ fields: Readonly<Partial<TFields>>,
56
57
  ): object => {
57
58
  const databaseObject: { [key: string]: any } = {};
58
59
  for (const k in fields) {
@@ -63,16 +64,16 @@ export const transformFieldsToDatabaseObject = <TFields>(
63
64
  entityConfiguration,
64
65
  fieldTransformerMap,
65
66
  k,
66
- val
67
+ val,
67
68
  );
68
69
  }
69
70
  return databaseObject;
70
71
  };
71
72
 
72
- export const transformCacheObjectToFields = <TFields>(
73
+ export const transformCacheObjectToFields = <TFields extends Record<string, any>>(
73
74
  entityConfiguration: EntityConfiguration<TFields>,
74
75
  fieldTransformerMap: FieldTransformerMap,
75
- cacheObject: { [key: string]: any }
76
+ cacheObject: { [key: string]: any },
76
77
  ): Readonly<TFields> => {
77
78
  const fields: TFields = {} as any;
78
79
  for (const fieldsKey in cacheObject) {
@@ -81,16 +82,16 @@ export const transformCacheObjectToFields = <TFields>(
81
82
  entityConfiguration,
82
83
  fieldTransformerMap,
83
84
  fieldsKey as keyof TFields,
84
- val
85
+ val,
85
86
  );
86
87
  }
87
88
  return fields;
88
89
  };
89
90
 
90
- export const transformFieldsToCacheObject = <TFields>(
91
+ export const transformFieldsToCacheObject = <TFields extends Record<string, any>>(
91
92
  entityConfiguration: EntityConfiguration<TFields>,
92
93
  fieldTransformerMap: FieldTransformerMap,
93
- fields: Readonly<Partial<TFields>>
94
+ fields: Readonly<Partial<TFields>>,
94
95
  ): object => {
95
96
  const cacheObject: { [key: string]: any } = {};
96
97
  for (const fieldsKey in fields) {
@@ -99,49 +100,52 @@ export const transformFieldsToCacheObject = <TFields>(
99
100
  entityConfiguration,
100
101
  fieldTransformerMap,
101
102
  fieldsKey,
102
- val
103
+ val,
103
104
  );
104
105
  }
105
106
  return cacheObject;
106
107
  };
107
108
 
108
- const maybeTransformDatabaseValueToFieldValue = <TFields, N extends keyof TFields>(
109
+ const maybeTransformDatabaseValueToFieldValue = <
110
+ TFields extends Record<string, any>,
111
+ N extends keyof TFields,
112
+ >(
109
113
  entityConfiguration: EntityConfiguration<TFields>,
110
114
  fieldTransformerMap: FieldTransformerMap,
111
115
  fieldName: N,
112
- value: any
116
+ value: any,
113
117
  ): TFields[N] => {
114
- const fieldDefinition = entityConfiguration.schema.get(fieldName);
115
- if (!fieldDefinition) {
116
- return value;
117
- }
118
-
118
+ // this will always be non-null due to the way the dbToEntityFieldsKeyMapping is computed and this
119
+ // function is called conditionally
120
+ const fieldDefinition = nullthrows(entityConfiguration.schema.get(fieldName));
119
121
  const transformer = fieldTransformerMap.get(fieldDefinition.constructor.name);
120
122
  const readTransformer = transformer?.read;
121
123
  return readTransformer ? readTransformer(value) : value;
122
124
  };
123
125
 
124
- const maybeTransformFieldValueToDatabaseValue = <TFields, N extends keyof TFields>(
126
+ const maybeTransformFieldValueToDatabaseValue = <
127
+ TFields extends Record<string, any>,
128
+ N extends keyof TFields,
129
+ >(
125
130
  entityConfiguration: EntityConfiguration<TFields>,
126
131
  fieldTransformerMap: FieldTransformerMap,
127
132
  fieldName: N,
128
- value: TFields[N]
133
+ value: TFields[N],
129
134
  ): any => {
130
- const fieldDefinition = entityConfiguration.schema.get(fieldName);
131
- if (!fieldDefinition) {
132
- return value;
133
- }
134
-
135
+ const fieldDefinition = nullthrows(entityConfiguration.schema.get(fieldName));
135
136
  const transformer = fieldTransformerMap.get(fieldDefinition.constructor.name);
136
137
  const writeTransformer = transformer?.write;
137
138
  return writeTransformer ? writeTransformer(value) : value;
138
139
  };
139
140
 
140
- const maybeTransformCacheValueToFieldValue = <TFields, N extends keyof TFields>(
141
+ const maybeTransformCacheValueToFieldValue = <
142
+ TFields extends Record<string, any>,
143
+ N extends keyof TFields,
144
+ >(
141
145
  entityConfiguration: EntityConfiguration<TFields>,
142
146
  fieldTransformerMap: FieldTransformerMap,
143
147
  fieldName: N,
144
- value: any
148
+ value: any,
145
149
  ): TFields[N] => {
146
150
  const fieldDefinition = entityConfiguration.schema.get(fieldName);
147
151
  if (!fieldDefinition) {
@@ -153,11 +157,14 @@ const maybeTransformCacheValueToFieldValue = <TFields, N extends keyof TFields>(
153
157
  return readTransformer ? readTransformer(value) : value;
154
158
  };
155
159
 
156
- const maybeTransformFieldValueToCacheValue = <TFields, N extends keyof TFields>(
160
+ const maybeTransformFieldValueToCacheValue = <
161
+ TFields extends Record<string, any>,
162
+ N extends keyof TFields,
163
+ >(
157
164
  entityConfiguration: EntityConfiguration<TFields>,
158
165
  fieldTransformerMap: FieldTransformerMap,
159
166
  fieldName: N,
160
- value: TFields[N]
167
+ value: TFields[N],
161
168
  ): any => {
162
169
  const fieldDefinition = entityConfiguration.schema.get(fieldName);
163
170
  if (!fieldDefinition) {
@@ -13,7 +13,7 @@ import IEntityMetricsAdapter from '../metrics/IEntityMetricsAdapter';
13
13
  * table. Note that one instance is shared amongst all entities that read from
14
14
  * the table to ensure cross-entity data consistency.
15
15
  */
16
- export default class EntityTableDataCoordinator<TFields> {
16
+ export default class EntityTableDataCoordinator<TFields extends Record<string, any>> {
17
17
  readonly databaseAdapter: EntityDatabaseAdapter<TFields>;
18
18
  readonly cacheAdapter: IEntityCacheAdapter<TFields>;
19
19
  readonly dataManager: EntityDataManager<TFields>;
@@ -24,7 +24,7 @@ export default class EntityTableDataCoordinator<TFields> {
24
24
  cacheAdapterProvider: IEntityCacheAdapterProvider,
25
25
  private readonly queryContextProvider: EntityQueryContextProvider,
26
26
  metricsAdapter: IEntityMetricsAdapter,
27
- entityClassName: string
27
+ entityClassName: string,
28
28
  ) {
29
29
  this.databaseAdapter = databaseAdapterProvider.getDatabaseAdapter(entityConfiguration);
30
30
  this.cacheAdapter = cacheAdapterProvider.getCacheAdapter(entityConfiguration);
@@ -33,7 +33,7 @@ export default class EntityTableDataCoordinator<TFields> {
33
33
  new ReadThroughEntityCache(entityConfiguration, this.cacheAdapter),
34
34
  queryContextProvider,
35
35
  metricsAdapter,
36
- entityClassName
36
+ entityClassName,
37
37
  );
38
38
  }
39
39
 
@@ -26,10 +26,10 @@ export type CacheLoadResult<TFields> =
26
26
  * A read-through entity cache is responsible for coordinating EntityDatabaseAdapter and
27
27
  * EntityCacheAdapter within the EntityDataManager.
28
28
  */
29
- export default class ReadThroughEntityCache<TFields> {
29
+ export default class ReadThroughEntityCache<TFields extends Record<string, any>> {
30
30
  constructor(
31
31
  private readonly entityConfiguration: EntityConfiguration<TFields>,
32
- private readonly entityCacheAdapter: IEntityCacheAdapter<TFields>
32
+ private readonly entityCacheAdapter: IEntityCacheAdapter<TFields>,
33
33
  ) {}
34
34
 
35
35
  private isFieldCacheable<N extends keyof TFields>(fieldName: N): boolean {
@@ -56,8 +56,8 @@ export default class ReadThroughEntityCache<TFields> {
56
56
  fieldName: N,
57
57
  fieldValues: readonly NonNullable<TFields[N]>[],
58
58
  fetcher: (
59
- fetcherFieldValues: readonly NonNullable<TFields[N]>[]
60
- ) => Promise<ReadonlyMap<NonNullable<TFields[N]>, readonly Readonly<TFields>[]>>
59
+ fetcherFieldValues: readonly NonNullable<TFields[N]>[],
60
+ ) => Promise<ReadonlyMap<NonNullable<TFields[N]>, readonly Readonly<TFields>[]>>,
61
61
  ): Promise<ReadonlyMap<NonNullable<TFields[N]>, readonly Readonly<TFields>[]>> {
62
62
  // return normal fetch when cache by fieldName not supported
63
63
  if (!this.isFieldCacheable(fieldName)) {
@@ -68,14 +68,14 @@ export default class ReadThroughEntityCache<TFields> {
68
68
 
69
69
  invariant(
70
70
  cacheLoadResults.size === fieldValues.length,
71
- `${this.constructor.name} loadMany should return a result for each fieldValue`
71
+ `${this.constructor.name} loadMany should return a result for each fieldValue`,
72
72
  );
73
73
 
74
74
  const fieldValuesToFetchFromDB = Array.from(
75
75
  filterMap(
76
76
  cacheLoadResults,
77
- (cacheLoadResult) => cacheLoadResult.status === CacheStatus.MISS
78
- ).keys()
77
+ (cacheLoadResult) => cacheLoadResult.status === CacheStatus.MISS,
78
+ ).keys(),
79
79
  );
80
80
 
81
81
  // put transformed cache hits in result map
@@ -104,7 +104,7 @@ export default class ReadThroughEntityCache<TFields> {
104
104
  console.warn(
105
105
  `unique key ${String(fieldName)} in ${
106
106
  this.entityConfiguration.tableName
107
- } returned multiple rows for ${fieldValue}`
107
+ } returned multiple rows for ${fieldValue}`,
108
108
  );
109
109
  continue;
110
110
  }
@@ -132,7 +132,7 @@ export default class ReadThroughEntityCache<TFields> {
132
132
  */
133
133
  public async invalidateManyAsync<N extends keyof TFields>(
134
134
  fieldName: N,
135
- fieldValues: readonly NonNullable<TFields[N]>[]
135
+ fieldValues: readonly NonNullable<TFields[N]>[],
136
136
  ): Promise<void> {
137
137
  // no-op when cache by fieldName not supported
138
138
  if (!this.isFieldCacheable(fieldName)) {