@expo/entity 0.34.0 → 0.36.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 (333) 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 +4 -31
  12. package/build/Entity.js +19 -46
  13. package/build/Entity.js.map +1 -1
  14. package/build/EntityAssociationLoader.d.ts +9 -9
  15. package/build/EntityAssociationLoader.js +37 -12
  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/EntityQueryContextProvider.d.ts +1 -1
  55. package/build/EntityQueryContextProvider.js +1 -1
  56. package/build/EntityQueryContextProvider.js.map +1 -1
  57. package/build/EntitySecondaryCacheLoader.js +5 -1
  58. package/build/EntitySecondaryCacheLoader.js.map +1 -1
  59. package/build/GenericEntityCacheAdapter.js +1 -0
  60. package/build/GenericEntityCacheAdapter.js.map +1 -1
  61. package/build/GenericSecondaryEntityCache.js +2 -0
  62. package/build/GenericSecondaryEntityCache.js.map +1 -1
  63. package/build/IEntityCacheAdapterProvider.d.ts +1 -1
  64. package/build/IEntityDatabaseAdapterProvider.d.ts +1 -1
  65. package/build/ReadonlyEntity.d.ts +1 -1
  66. package/build/ReadonlyEntity.js +9 -2
  67. package/build/ReadonlyEntity.js.map +1 -1
  68. package/build/ViewerContext.d.ts +2 -2
  69. package/build/ViewerContext.js +5 -3
  70. package/build/ViewerContext.js.map +1 -1
  71. package/build/ViewerScopedEntityCompanion.js +2 -0
  72. package/build/ViewerScopedEntityCompanion.js.map +1 -1
  73. package/build/ViewerScopedEntityCompanionProvider.d.ts +0 -1
  74. package/build/ViewerScopedEntityCompanionProvider.js +2 -1
  75. package/build/ViewerScopedEntityCompanionProvider.js.map +1 -1
  76. package/build/ViewerScopedEntityLoaderFactory.d.ts +1 -1
  77. package/build/ViewerScopedEntityLoaderFactory.js +2 -0
  78. package/build/ViewerScopedEntityLoaderFactory.js.map +1 -1
  79. package/build/ViewerScopedEntityMutatorFactory.js +2 -0
  80. package/build/ViewerScopedEntityMutatorFactory.js.map +1 -1
  81. package/build/__tests__/ComposedCacheAdapter-test.js +2 -0
  82. package/build/__tests__/ComposedCacheAdapter-test.js.map +1 -1
  83. package/build/__tests__/ComposedSecondaryEntityCache-test.js +1 -0
  84. package/build/__tests__/ComposedSecondaryEntityCache-test.js.map +1 -1
  85. package/build/__tests__/EnforcingEntityLoader-test.js +101 -113
  86. package/build/__tests__/EnforcingEntityLoader-test.js.map +1 -1
  87. package/build/__tests__/Entity-test.js +5 -137
  88. package/build/__tests__/Entity-test.js.map +1 -1
  89. package/build/__tests__/EntityAssociationLoader-test.js +37 -65
  90. package/build/__tests__/EntityAssociationLoader-test.js.map +1 -1
  91. package/build/__tests__/EntityCommonUseCases-test.js +31 -37
  92. package/build/__tests__/EntityCommonUseCases-test.js.map +1 -1
  93. package/build/__tests__/EntityCompanion-test.js +26 -3
  94. package/build/__tests__/EntityCompanion-test.js.map +1 -1
  95. package/build/__tests__/EntityConfiguration-test.js +103 -0
  96. package/build/__tests__/EntityConfiguration-test.js.map +1 -0
  97. package/build/__tests__/EntityDatabaseAdapter-test.js +6 -0
  98. package/build/__tests__/EntityDatabaseAdapter-test.js.map +1 -1
  99. package/build/__tests__/EntityEdges-test.js +89 -80
  100. package/build/__tests__/EntityEdges-test.js.map +1 -1
  101. package/build/__tests__/EntityFields-test.js +6 -0
  102. package/build/__tests__/EntityFields-test.js.map +1 -1
  103. package/build/__tests__/EntityLoader-constructor-test.js +17 -18
  104. package/build/__tests__/EntityLoader-constructor-test.js.map +1 -1
  105. package/build/__tests__/EntityLoader-test.js +93 -41
  106. package/build/__tests__/EntityLoader-test.js.map +1 -1
  107. package/build/__tests__/EntityMutator-MutationCacheConsistency-test.js +18 -21
  108. package/build/__tests__/EntityMutator-MutationCacheConsistency-test.js.map +1 -1
  109. package/build/__tests__/EntityMutator-test.js +74 -29
  110. package/build/__tests__/EntityMutator-test.js.map +1 -1
  111. package/build/__tests__/EntityPrivacyPolicy-test.js +77 -59
  112. package/build/__tests__/EntityPrivacyPolicy-test.js.map +1 -1
  113. package/build/__tests__/EntityQueryContext-test.js +9 -0
  114. package/build/__tests__/EntityQueryContext-test.js.map +1 -1
  115. package/build/__tests__/EntitySecondaryCacheLoader-test.js +10 -10
  116. package/build/__tests__/EntitySecondaryCacheLoader-test.js.map +1 -1
  117. package/build/__tests__/EntitySelfReferentialEdges-test.js +59 -74
  118. package/build/__tests__/EntitySelfReferentialEdges-test.js.map +1 -1
  119. package/build/__tests__/ReadonlyEntity-test.js +13 -13
  120. package/build/__tests__/ReadonlyEntity-test.js.map +1 -1
  121. package/build/__tests__/ViewerContext-test.js +2 -2
  122. package/build/__tests__/ViewerContext-test.js.map +1 -1
  123. package/build/__tests__/ViewerScopedEntityLoaderFactory-test.js.map +1 -1
  124. package/build/__tests__/cases/TwoEntitySameTableDisjointRows-test.js +26 -28
  125. package/build/__tests__/cases/TwoEntitySameTableDisjointRows-test.js.map +1 -1
  126. package/build/__tests__/cases/TwoEntitySameTableOverlappingRows-test.js +25 -30
  127. package/build/__tests__/cases/TwoEntitySameTableOverlappingRows-test.js.map +1 -1
  128. package/build/entityUtils.d.ts +1 -1
  129. package/build/entityUtils.js.map +1 -1
  130. package/build/errors/EntityCacheAdapterError.js +2 -5
  131. package/build/errors/EntityCacheAdapterError.js.map +1 -1
  132. package/build/errors/EntityDatabaseAdapterError.js +14 -35
  133. package/build/errors/EntityDatabaseAdapterError.js.map +1 -1
  134. package/build/errors/EntityError.js +1 -0
  135. package/build/errors/EntityError.js.map +1 -1
  136. package/build/errors/EntityInvalidFieldValueError.js +2 -2
  137. package/build/errors/EntityInvalidFieldValueError.js.map +1 -1
  138. package/build/errors/EntityNotAuthorizedError.js +3 -2
  139. package/build/errors/EntityNotAuthorizedError.js.map +1 -1
  140. package/build/errors/EntityNotFoundError.js +2 -2
  141. package/build/errors/EntityNotFoundError.js.map +1 -1
  142. package/build/index.d.ts +1 -0
  143. package/build/index.js +1 -0
  144. package/build/index.js.map +1 -1
  145. package/build/internal/EntityDataManager.d.ts +1 -1
  146. package/build/internal/EntityDataManager.js +7 -2
  147. package/build/internal/EntityDataManager.js.map +1 -1
  148. package/build/internal/EntityFieldTransformationUtils.d.ts +5 -5
  149. package/build/internal/EntityFieldTransformationUtils.js +5 -8
  150. package/build/internal/EntityFieldTransformationUtils.js.map +1 -1
  151. package/build/internal/EntityTableDataCoordinator.d.ts +1 -1
  152. package/build/internal/EntityTableDataCoordinator.js +5 -0
  153. package/build/internal/EntityTableDataCoordinator.js.map +1 -1
  154. package/build/internal/ReadThroughEntityCache.d.ts +1 -1
  155. package/build/internal/ReadThroughEntityCache.js +2 -0
  156. package/build/internal/ReadThroughEntityCache.js.map +1 -1
  157. package/build/internal/__tests__/EntityDataManager-test.js +11 -11
  158. package/build/internal/__tests__/EntityDataManager-test.js.map +1 -1
  159. package/build/internal/__tests__/EntityFieldTransformationUtils-test.js +6 -2
  160. package/build/internal/__tests__/EntityFieldTransformationUtils-test.js.map +1 -1
  161. package/build/internal/__tests__/ReadThroughEntityCache-test.js +33 -0
  162. package/build/internal/__tests__/ReadThroughEntityCache-test.js.map +1 -1
  163. package/build/metrics/IEntityMetricsAdapter.d.ts +1 -1
  164. package/build/rules/AlwaysAllowPrivacyPolicyRule.d.ts +1 -1
  165. package/build/rules/AlwaysAllowPrivacyPolicyRule.js.map +1 -1
  166. package/build/rules/AlwaysDenyPrivacyPolicyRule.d.ts +1 -1
  167. package/build/rules/AlwaysDenyPrivacyPolicyRule.js.map +1 -1
  168. package/build/rules/AlwaysSkipPrivacyPolicyRule.d.ts +1 -1
  169. package/build/rules/AlwaysSkipPrivacyPolicyRule.js.map +1 -1
  170. package/build/rules/PrivacyPolicyRule.d.ts +1 -1
  171. package/build/rules/PrivacyPolicyRule.js.map +1 -1
  172. package/build/rules/__tests__/AlwaysAllowPrivacyPolicyRule-test.js.map +1 -1
  173. package/build/rules/__tests__/AlwaysDenyPrivacyPolicyRule-test.js.map +1 -1
  174. package/build/rules/__tests__/AlwaysSkipPrivacyPolicyRule-test.js.map +1 -1
  175. package/build/testfixtures/DateIDTestEntity.js +12 -15
  176. package/build/testfixtures/DateIDTestEntity.js.map +1 -1
  177. package/build/testfixtures/SimpleTestEntity.d.ts +8 -8
  178. package/build/testfixtures/SimpleTestEntity.js +12 -15
  179. package/build/testfixtures/SimpleTestEntity.js.map +1 -1
  180. package/build/testfixtures/TestEntity.d.ts +12 -12
  181. package/build/testfixtures/TestEntity.js +12 -15
  182. package/build/testfixtures/TestEntity.js.map +1 -1
  183. package/build/testfixtures/TestEntity2.d.ts +8 -8
  184. package/build/testfixtures/TestEntity2.js +12 -15
  185. package/build/testfixtures/TestEntity2.js.map +1 -1
  186. package/build/testfixtures/TestEntityNumberKey.js +12 -15
  187. package/build/testfixtures/TestEntityNumberKey.js.map +1 -1
  188. package/build/testfixtures/TestEntityWithMutationTriggers.d.ts +36 -0
  189. package/build/testfixtures/TestEntityWithMutationTriggers.js +82 -0
  190. package/build/testfixtures/TestEntityWithMutationTriggers.js.map +1 -0
  191. package/build/testfixtures/TestViewerContext.d.ts +0 -3
  192. package/build/testfixtures/TestViewerContext.js +0 -6
  193. package/build/testfixtures/TestViewerContext.js.map +1 -1
  194. package/build/utils/EntityPrivacyUtils.d.ts +34 -0
  195. package/build/utils/EntityPrivacyUtils.js +160 -0
  196. package/build/utils/EntityPrivacyUtils.js.map +1 -0
  197. package/build/utils/__tests__/EntityPrivacyUtils-test.d.ts +1 -0
  198. package/build/utils/__tests__/EntityPrivacyUtils-test.js +395 -0
  199. package/build/utils/__tests__/EntityPrivacyUtils-test.js.map +1 -0
  200. package/build/utils/__tests__/mergeEntityMutationTriggerConfigurations-test.d.ts +1 -0
  201. package/build/utils/__tests__/mergeEntityMutationTriggerConfigurations-test.js +26 -0
  202. package/build/utils/__tests__/mergeEntityMutationTriggerConfigurations-test.js.map +1 -0
  203. package/build/utils/collections/maps.js.map +1 -1
  204. package/build/utils/mergeEntityMutationTriggerConfigurations.d.ts +4 -0
  205. package/build/utils/mergeEntityMutationTriggerConfigurations.js +28 -0
  206. package/build/utils/mergeEntityMutationTriggerConfigurations.js.map +1 -0
  207. package/build/utils/testing/PrivacyPolicyRuleTestUtils.d.ts +1 -1
  208. package/build/utils/testing/PrivacyPolicyRuleTestUtils.js.map +1 -1
  209. package/build/utils/testing/StubCacheAdapter.d.ts +3 -3
  210. package/build/utils/testing/StubCacheAdapter.js +3 -3
  211. package/build/utils/testing/StubCacheAdapter.js.map +1 -1
  212. package/build/utils/testing/StubDatabaseAdapter.d.ts +2 -2
  213. package/build/utils/testing/StubDatabaseAdapter.js +4 -2
  214. package/build/utils/testing/StubDatabaseAdapter.js.map +1 -1
  215. package/build/utils/testing/StubDatabaseAdapterProvider.d.ts +1 -1
  216. package/build/utils/testing/StubDatabaseAdapterProvider.js +1 -3
  217. package/build/utils/testing/StubDatabaseAdapterProvider.js.map +1 -1
  218. package/build/utils/testing/__tests__/PrivacyPolicyRuleTestUtils-test.d.ts +1 -0
  219. package/build/utils/testing/__tests__/PrivacyPolicyRuleTestUtils-test.js +42 -0
  220. package/build/utils/testing/__tests__/PrivacyPolicyRuleTestUtils-test.js.map +1 -0
  221. package/build/utils/testing/__tests__/StubDatabaseAdapter-test.js +53 -0
  222. package/build/utils/testing/__tests__/StubDatabaseAdapter-test.js.map +1 -1
  223. package/build/utils/testing/describeFieldTestCase.js.map +1 -1
  224. package/package.json +4 -3
  225. package/src/AuthorizationResultBasedEntityLoader.ts +297 -0
  226. package/src/ComposedEntityCacheAdapter.ts +6 -6
  227. package/src/ComposedSecondaryEntityCache.ts +8 -8
  228. package/src/EnforcingEntityLoader.ts +20 -19
  229. package/src/Entity.ts +26 -118
  230. package/src/EntityAssociationLoader.ts +56 -41
  231. package/src/EntityCompanion.ts +8 -4
  232. package/src/EntityCompanionProvider.ts +24 -16
  233. package/src/EntityConfiguration.ts +18 -7
  234. package/src/EntityDatabaseAdapter.ts +41 -41
  235. package/src/EntityFieldDefinition.ts +28 -18
  236. package/src/EntityFields.ts +15 -0
  237. package/src/EntityLoader.ts +63 -357
  238. package/src/EntityLoaderFactory.ts +10 -4
  239. package/src/EntityLoaderUtils.ts +149 -0
  240. package/src/EntityMutationInfo.ts +2 -2
  241. package/src/EntityMutationTriggerConfiguration.ts +5 -5
  242. package/src/EntityMutationValidator.ts +2 -2
  243. package/src/EntityMutator.ts +146 -144
  244. package/src/EntityMutatorFactory.ts +8 -8
  245. package/src/EntityPrivacyPolicy.ts +78 -28
  246. package/src/EntityQueryContext.ts +14 -13
  247. package/src/EntityQueryContextProvider.ts +6 -6
  248. package/src/EntitySecondaryCacheLoader.ts +13 -11
  249. package/src/GenericEntityCacheAdapter.ts +10 -10
  250. package/src/GenericSecondaryEntityCache.ts +6 -6
  251. package/src/IEntityCacheAdapter.ts +4 -4
  252. package/src/IEntityCacheAdapterProvider.ts +2 -2
  253. package/src/IEntityDatabaseAdapterProvider.ts +2 -2
  254. package/src/ReadonlyEntity.ts +8 -5
  255. package/src/ViewerContext.ts +10 -10
  256. package/src/ViewerScopedEntityCompanion.ts +4 -4
  257. package/src/ViewerScopedEntityCompanionProvider.ts +4 -5
  258. package/src/ViewerScopedEntityLoaderFactory.ts +10 -4
  259. package/src/ViewerScopedEntityMutatorFactory.ts +5 -5
  260. package/src/__tests__/ComposedCacheAdapter-test.ts +12 -10
  261. package/src/__tests__/ComposedSecondaryEntityCache-test.ts +8 -8
  262. package/src/__tests__/EnforcingEntityLoader-test.ts +236 -159
  263. package/src/__tests__/Entity-test.ts +5 -223
  264. package/src/__tests__/EntityAssociationLoader-test.ts +91 -169
  265. package/src/__tests__/EntityCommonUseCases-test.ts +36 -38
  266. package/src/__tests__/EntityCompanion-test.ts +57 -5
  267. package/src/__tests__/EntityConfiguration-test.ts +118 -0
  268. package/src/__tests__/EntityDatabaseAdapter-test.ts +11 -11
  269. package/src/__tests__/EntityEdges-test.ts +128 -118
  270. package/src/__tests__/EntityFields-test.ts +14 -2
  271. package/src/__tests__/EntityLoader-constructor-test.ts +21 -8
  272. package/src/__tests__/EntityLoader-test.ts +233 -105
  273. package/src/__tests__/EntityMutator-MutationCacheConsistency-test.ts +17 -20
  274. package/src/__tests__/EntityMutator-test.ts +342 -163
  275. package/src/__tests__/EntityPrivacyPolicy-test.ts +166 -53
  276. package/src/__tests__/EntityQueryContext-test.ts +30 -12
  277. package/src/__tests__/EntitySecondaryCacheLoader-test.ts +17 -26
  278. package/src/__tests__/EntitySelfReferentialEdges-test.ts +67 -115
  279. package/src/__tests__/GenericEntityCacheAdapter-test.ts +2 -2
  280. package/src/__tests__/ReadonlyEntity-test.ts +13 -15
  281. package/src/__tests__/ViewerContext-test.ts +3 -4
  282. package/src/__tests__/ViewerScopedEntityCompanion-test.ts +2 -2
  283. package/src/__tests__/ViewerScopedEntityCompanionProvider-test.ts +2 -2
  284. package/src/__tests__/ViewerScopedEntityLoaderFactory-test.ts +2 -1
  285. package/src/__tests__/cases/TwoEntitySameTableDisjointRows-test.ts +34 -45
  286. package/src/__tests__/cases/TwoEntitySameTableOverlappingRows-test.ts +22 -30
  287. package/src/__tests__/entityUtils-test.ts +2 -2
  288. package/src/entityUtils.ts +4 -4
  289. package/src/errors/EntityError.ts +4 -1
  290. package/src/errors/EntityInvalidFieldValueError.ts +2 -2
  291. package/src/errors/EntityNotAuthorizedError.ts +3 -3
  292. package/src/errors/EntityNotFoundError.ts +2 -2
  293. package/src/index.ts +1 -0
  294. package/src/internal/EntityDataManager.ts +25 -25
  295. package/src/internal/EntityFieldTransformationUtils.ts +39 -32
  296. package/src/internal/EntityTableDataCoordinator.ts +3 -3
  297. package/src/internal/ReadThroughEntityCache.ts +9 -9
  298. package/src/internal/__tests__/EntityDataManager-test.ts +62 -62
  299. package/src/internal/__tests__/EntityFieldTransformationUtils-test.ts +14 -10
  300. package/src/internal/__tests__/ReadThroughEntityCache-test.ts +74 -18
  301. package/src/metrics/EntityMetricsUtils.ts +4 -4
  302. package/src/metrics/IEntityMetricsAdapter.ts +1 -1
  303. package/src/rules/AlwaysAllowPrivacyPolicyRule.ts +9 -3
  304. package/src/rules/AlwaysDenyPrivacyPolicyRule.ts +9 -3
  305. package/src/rules/AlwaysSkipPrivacyPolicyRule.ts +9 -3
  306. package/src/rules/PrivacyPolicyRule.ts +9 -3
  307. package/src/rules/__tests__/AlwaysAllowPrivacyPolicyRule-test.ts +2 -1
  308. package/src/rules/__tests__/AlwaysDenyPrivacyPolicyRule-test.ts +2 -1
  309. package/src/rules/__tests__/AlwaysSkipPrivacyPolicyRule-test.ts +2 -1
  310. package/src/testfixtures/SimpleTestEntity.ts +8 -8
  311. package/src/testfixtures/TestEntity.ts +13 -16
  312. package/src/testfixtures/TestEntity2.ts +8 -8
  313. package/src/testfixtures/TestEntityWithMutationTriggers.ts +156 -0
  314. package/src/testfixtures/TestViewerContext.ts +1 -12
  315. package/src/utils/EntityPrivacyUtils.ts +325 -0
  316. package/src/utils/__tests__/EntityPrivacyUtils-test.ts +570 -0
  317. package/src/utils/__tests__/mergeEntityMutationTriggerConfigurations-test.ts +29 -0
  318. package/src/utils/collections/__tests__/maps-test.ts +2 -2
  319. package/src/utils/collections/maps.ts +11 -11
  320. package/src/utils/mergeEntityMutationTriggerConfigurations.ts +44 -0
  321. package/src/utils/testing/PrivacyPolicyRuleTestUtils.ts +25 -22
  322. package/src/utils/testing/StubCacheAdapter.ts +17 -15
  323. package/src/utils/testing/StubDatabaseAdapter.ts +35 -30
  324. package/src/utils/testing/StubDatabaseAdapterProvider.ts +2 -2
  325. package/src/utils/testing/StubQueryContextProvider.ts +2 -2
  326. package/src/utils/testing/__tests__/PrivacyPolicyRuleTestUtils-test.ts +42 -0
  327. package/src/utils/testing/__tests__/StubDatabaseAdapter-test.ts +111 -29
  328. package/src/utils/testing/createUnitTestEntityCompanionProvider.ts +2 -2
  329. package/src/utils/testing/describeFieldTestCase.ts +1 -1
  330. package/build/__tests__/EntityDataConfiguration-test.js +0 -68
  331. package/build/__tests__/EntityDataConfiguration-test.js.map +0 -1
  332. package/src/__tests__/EntityDataConfiguration-test.ts +0 -77
  333. /package/build/__tests__/{EntityDataConfiguration-test.d.ts → EntityConfiguration-test.d.ts} +0 -0
@@ -26,7 +26,7 @@ export default class EntityMutatorFactory<
26
26
  TEntity,
27
27
  TSelectedFields
28
28
  >,
29
- TSelectedFields extends keyof TFields = keyof TFields
29
+ TSelectedFields extends keyof TFields = keyof TFields,
30
30
  > {
31
31
  constructor(
32
32
  private readonly entityCompanionProvider: EntityCompanionProvider,
@@ -63,7 +63,7 @@ export default class EntityMutatorFactory<
63
63
  TSelectedFields
64
64
  >,
65
65
  private readonly databaseAdapter: EntityDatabaseAdapter<TFields>,
66
- private readonly metricsAdapter: IEntityMetricsAdapter
66
+ private readonly metricsAdapter: IEntityMetricsAdapter,
67
67
  ) {}
68
68
 
69
69
  /**
@@ -74,7 +74,7 @@ export default class EntityMutatorFactory<
74
74
  */
75
75
  forCreate(
76
76
  viewerContext: TViewerContext,
77
- queryContext: EntityQueryContext
77
+ queryContext: EntityQueryContext,
78
78
  ): CreateMutator<TFields, TID, TViewerContext, TEntity, TPrivacyPolicy, TSelectedFields> {
79
79
  return new CreateMutator(
80
80
  this.entityCompanionProvider,
@@ -87,7 +87,7 @@ export default class EntityMutatorFactory<
87
87
  this.mutationTriggers,
88
88
  this.entityLoaderFactory,
89
89
  this.databaseAdapter,
90
- this.metricsAdapter
90
+ this.metricsAdapter,
91
91
  );
92
92
  }
93
93
 
@@ -99,7 +99,7 @@ export default class EntityMutatorFactory<
99
99
  */
100
100
  forUpdate(
101
101
  existingEntity: TEntity,
102
- queryContext: EntityQueryContext
102
+ queryContext: EntityQueryContext,
103
103
  ): UpdateMutator<TFields, TID, TViewerContext, TEntity, TPrivacyPolicy, TSelectedFields> {
104
104
  return new UpdateMutator(
105
105
  this.entityCompanionProvider,
@@ -113,7 +113,7 @@ export default class EntityMutatorFactory<
113
113
  this.entityLoaderFactory,
114
114
  this.databaseAdapter,
115
115
  this.metricsAdapter,
116
- existingEntity
116
+ existingEntity,
117
117
  );
118
118
  }
119
119
 
@@ -124,7 +124,7 @@ export default class EntityMutatorFactory<
124
124
  */
125
125
  forDelete(
126
126
  existingEntity: TEntity,
127
- queryContext: EntityQueryContext
127
+ queryContext: EntityQueryContext,
128
128
  ): DeleteMutator<TFields, TID, TViewerContext, TEntity, TPrivacyPolicy, TSelectedFields> {
129
129
  return new DeleteMutator(
130
130
  this.entityCompanionProvider,
@@ -138,7 +138,7 @@ export default class EntityMutatorFactory<
138
138
  this.entityLoaderFactory,
139
139
  this.databaseAdapter,
140
140
  this.metricsAdapter,
141
- existingEntity
141
+ existingEntity,
142
142
  );
143
143
  }
144
144
  }
@@ -11,7 +11,19 @@ import PrivacyPolicyRule, { RuleEvaluationResult } from './rules/PrivacyPolicyRu
11
11
  /**
12
12
  * Information about the reason this privacy policy is being evaluated.
13
13
  */
14
- export type EntityPrivacyPolicyEvaluationContext = {
14
+ export type EntityPrivacyPolicyEvaluationContext<
15
+ TFields extends object,
16
+ TID extends NonNullable<TFields[TSelectedFields]>,
17
+ TViewerContext extends ViewerContext,
18
+ TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>,
19
+ TSelectedFields extends keyof TFields = keyof TFields,
20
+ > = {
21
+ /**
22
+ * When this privacy policy is being evaluated as a result of an update, this will be populated with the value
23
+ * of the entity before the update. Note that this doesn't only apply to UPDATE authorization actions though:
24
+ * when an entity is updated it is re-LOADed after the update completes.
25
+ */
26
+ previousValue: TEntity | null;
15
27
  /**
16
28
  * When this privacy policy is being evaluated as a result of a cascading deletion, this will be populated
17
29
  * with information on the cascading delete.
@@ -45,7 +57,7 @@ export type EntityPrivacyPolicyEvaluator<
45
57
  TID extends NonNullable<TFields[TSelectedFields]>,
46
58
  TViewerContext extends ViewerContext,
47
59
  TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>,
48
- TSelectedFields extends keyof TFields = keyof TFields
60
+ TSelectedFields extends keyof TFields = keyof TFields,
49
61
  > =
50
62
  | {
51
63
  mode: EntityPrivacyPolicyEvaluationMode.ENFORCE;
@@ -53,13 +65,13 @@ export type EntityPrivacyPolicyEvaluator<
53
65
  | {
54
66
  mode: EntityPrivacyPolicyEvaluationMode.DRY_RUN;
55
67
  denyHandler: (
56
- error: EntityNotAuthorizedError<TFields, TID, TViewerContext, TEntity, TSelectedFields>
68
+ error: EntityNotAuthorizedError<TFields, TID, TViewerContext, TEntity, TSelectedFields>,
57
69
  ) => void;
58
70
  }
59
71
  | {
60
72
  mode: EntityPrivacyPolicyEvaluationMode.ENFORCE_AND_LOG;
61
73
  denyHandler: (
62
- error: EntityNotAuthorizedError<TFields, TID, TViewerContext, TEntity, TSelectedFields>
74
+ error: EntityNotAuthorizedError<TFields, TID, TViewerContext, TEntity, TSelectedFields>,
63
75
  ) => void;
64
76
  };
65
77
 
@@ -96,7 +108,7 @@ export default abstract class EntityPrivacyPolicy<
96
108
  TID extends NonNullable<TFields[TSelectedFields]>,
97
109
  TViewerContext extends ViewerContext,
98
110
  TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>,
99
- TSelectedFields extends keyof TFields = keyof TFields
111
+ TSelectedFields extends keyof TFields = keyof TFields,
100
112
  > {
101
113
  protected readonly createRules: readonly PrivacyPolicyRule<
102
114
  TFields,
@@ -136,7 +148,7 @@ export default abstract class EntityPrivacyPolicy<
136
148
  * Override to enable dry run evaluation of the policy.
137
149
  */
138
150
  protected getPrivacyPolicyEvaluator(
139
- _viewerContext: TViewerContext
151
+ _viewerContext: TViewerContext,
140
152
  ): EntityPrivacyPolicyEvaluator<TFields, TID, TViewerContext, TEntity, TSelectedFields> {
141
153
  return {
142
154
  mode: EntityPrivacyPolicyEvaluationMode.ENFORCE,
@@ -154,9 +166,15 @@ export default abstract class EntityPrivacyPolicy<
154
166
  async authorizeCreateAsync(
155
167
  viewerContext: TViewerContext,
156
168
  queryContext: EntityQueryContext,
157
- evaluationContext: EntityPrivacyPolicyEvaluationContext,
169
+ evaluationContext: EntityPrivacyPolicyEvaluationContext<
170
+ TFields,
171
+ TID,
172
+ TViewerContext,
173
+ TEntity,
174
+ TSelectedFields
175
+ >,
158
176
  entity: TEntity,
159
- metricsAdapter: IEntityMetricsAdapter
177
+ metricsAdapter: IEntityMetricsAdapter,
160
178
  ): Promise<TEntity> {
161
179
  return await this.authorizeForRulesetAsync(
162
180
  this.createRules,
@@ -165,7 +183,7 @@ export default abstract class EntityPrivacyPolicy<
165
183
  evaluationContext,
166
184
  entity,
167
185
  EntityAuthorizationAction.CREATE,
168
- metricsAdapter
186
+ metricsAdapter,
169
187
  );
170
188
  }
171
189
 
@@ -180,9 +198,15 @@ export default abstract class EntityPrivacyPolicy<
180
198
  async authorizeReadAsync(
181
199
  viewerContext: TViewerContext,
182
200
  queryContext: EntityQueryContext,
183
- evaluationContext: EntityPrivacyPolicyEvaluationContext,
201
+ evaluationContext: EntityPrivacyPolicyEvaluationContext<
202
+ TFields,
203
+ TID,
204
+ TViewerContext,
205
+ TEntity,
206
+ TSelectedFields
207
+ >,
184
208
  entity: TEntity,
185
- metricsAdapter: IEntityMetricsAdapter
209
+ metricsAdapter: IEntityMetricsAdapter,
186
210
  ): Promise<TEntity> {
187
211
  return await this.authorizeForRulesetAsync(
188
212
  this.readRules,
@@ -191,7 +215,7 @@ export default abstract class EntityPrivacyPolicy<
191
215
  evaluationContext,
192
216
  entity,
193
217
  EntityAuthorizationAction.READ,
194
- metricsAdapter
218
+ metricsAdapter,
195
219
  );
196
220
  }
197
221
 
@@ -206,9 +230,15 @@ export default abstract class EntityPrivacyPolicy<
206
230
  async authorizeUpdateAsync(
207
231
  viewerContext: TViewerContext,
208
232
  queryContext: EntityQueryContext,
209
- evaluationContext: EntityPrivacyPolicyEvaluationContext,
233
+ evaluationContext: EntityPrivacyPolicyEvaluationContext<
234
+ TFields,
235
+ TID,
236
+ TViewerContext,
237
+ TEntity,
238
+ TSelectedFields
239
+ >,
210
240
  entity: TEntity,
211
- metricsAdapter: IEntityMetricsAdapter
241
+ metricsAdapter: IEntityMetricsAdapter,
212
242
  ): Promise<TEntity> {
213
243
  return await this.authorizeForRulesetAsync(
214
244
  this.updateRules,
@@ -217,7 +247,7 @@ export default abstract class EntityPrivacyPolicy<
217
247
  evaluationContext,
218
248
  entity,
219
249
  EntityAuthorizationAction.UPDATE,
220
- metricsAdapter
250
+ metricsAdapter,
221
251
  );
222
252
  }
223
253
 
@@ -232,9 +262,15 @@ export default abstract class EntityPrivacyPolicy<
232
262
  async authorizeDeleteAsync(
233
263
  viewerContext: TViewerContext,
234
264
  queryContext: EntityQueryContext,
235
- evaluationContext: EntityPrivacyPolicyEvaluationContext,
265
+ evaluationContext: EntityPrivacyPolicyEvaluationContext<
266
+ TFields,
267
+ TID,
268
+ TViewerContext,
269
+ TEntity,
270
+ TSelectedFields
271
+ >,
236
272
  entity: TEntity,
237
- metricsAdapter: IEntityMetricsAdapter
273
+ metricsAdapter: IEntityMetricsAdapter,
238
274
  ): Promise<TEntity> {
239
275
  return await this.authorizeForRulesetAsync(
240
276
  this.deleteRules,
@@ -243,7 +279,7 @@ export default abstract class EntityPrivacyPolicy<
243
279
  evaluationContext,
244
280
  entity,
245
281
  EntityAuthorizationAction.DELETE,
246
- metricsAdapter
282
+ metricsAdapter,
247
283
  );
248
284
  }
249
285
 
@@ -251,10 +287,16 @@ export default abstract class EntityPrivacyPolicy<
251
287
  ruleset: readonly PrivacyPolicyRule<TFields, TID, TViewerContext, TEntity, TSelectedFields>[],
252
288
  viewerContext: TViewerContext,
253
289
  queryContext: EntityQueryContext,
254
- evaluationContext: EntityPrivacyPolicyEvaluationContext,
290
+ evaluationContext: EntityPrivacyPolicyEvaluationContext<
291
+ TFields,
292
+ TID,
293
+ TViewerContext,
294
+ TEntity,
295
+ TSelectedFields
296
+ >,
255
297
  entity: TEntity,
256
298
  action: EntityAuthorizationAction,
257
- metricsAdapter: IEntityMetricsAdapter
299
+ metricsAdapter: IEntityMetricsAdapter,
258
300
  ): Promise<TEntity> {
259
301
  const privacyPolicyEvaluator = this.getPrivacyPolicyEvaluator(viewerContext);
260
302
  switch (privacyPolicyEvaluator.mode) {
@@ -266,7 +308,7 @@ export default abstract class EntityPrivacyPolicy<
266
308
  queryContext,
267
309
  evaluationContext,
268
310
  entity,
269
- action
311
+ action,
270
312
  );
271
313
  metricsAdapter.logAuthorizationEvent({
272
314
  entityClassName: entity.constructor.name,
@@ -295,7 +337,7 @@ export default abstract class EntityPrivacyPolicy<
295
337
  queryContext,
296
338
  evaluationContext,
297
339
  entity,
298
- action
340
+ action,
299
341
  );
300
342
  metricsAdapter.logAuthorizationEvent({
301
343
  entityClassName: entity.constructor.name,
@@ -325,7 +367,7 @@ export default abstract class EntityPrivacyPolicy<
325
367
  queryContext,
326
368
  evaluationContext,
327
369
  entity,
328
- action
370
+ action,
329
371
  );
330
372
  metricsAdapter.logAuthorizationEvent({
331
373
  entityClassName: entity.constructor.name,
@@ -354,9 +396,15 @@ export default abstract class EntityPrivacyPolicy<
354
396
  ruleset: readonly PrivacyPolicyRule<TFields, TID, TViewerContext, TEntity, TSelectedFields>[],
355
397
  viewerContext: TViewerContext,
356
398
  queryContext: EntityQueryContext,
357
- evaluationContext: EntityPrivacyPolicyEvaluationContext,
399
+ evaluationContext: EntityPrivacyPolicyEvaluationContext<
400
+ TFields,
401
+ TID,
402
+ TViewerContext,
403
+ TEntity,
404
+ TSelectedFields
405
+ >,
358
406
  entity: TEntity,
359
- action: EntityAuthorizationAction
407
+ action: EntityAuthorizationAction,
360
408
  ): Promise<TEntity> {
361
409
  for (let i = 0; i < ruleset.length; i++) {
362
410
  const rule = ruleset[i]!;
@@ -364,7 +412,7 @@ export default abstract class EntityPrivacyPolicy<
364
412
  viewerContext,
365
413
  queryContext,
366
414
  evaluationContext,
367
- entity
415
+ entity,
368
416
  );
369
417
  switch (ruleEvaluationResult) {
370
418
  case RuleEvaluationResult.DENY:
@@ -380,7 +428,9 @@ export default abstract class EntityPrivacyPolicy<
380
428
  case RuleEvaluationResult.ALLOW:
381
429
  return entity;
382
430
  default:
383
- throw new Error('should not be a fourth type of rule evaluation result');
431
+ throw new Error(
432
+ `Invalid RuleEvaluationResult returned from rule: ${entity} (viewer = ${viewerContext}, action = ${EntityAuthorizationAction[action]}, ruleIndex = ${i})`,
433
+ );
384
434
  }
385
435
  }
386
436
 
@@ -388,7 +438,7 @@ export default abstract class EntityPrivacyPolicy<
388
438
  entity,
389
439
  viewerContext,
390
440
  action,
391
- -1
441
+ -1,
392
442
  );
393
443
  }
394
444
  }
@@ -36,7 +36,7 @@ export abstract class EntityQueryContext {
36
36
 
37
37
  abstract runInTransactionIfNotInTransactionAsync<T>(
38
38
  transactionScope: (queryContext: EntityTransactionalQueryContext) => Promise<T>,
39
- transactionConfig?: TransactionConfig
39
+ transactionConfig?: TransactionConfig,
40
40
  ): Promise<T>;
41
41
  }
42
42
 
@@ -49,7 +49,7 @@ export abstract class EntityQueryContext {
49
49
  export class EntityNonTransactionalQueryContext extends EntityQueryContext {
50
50
  constructor(
51
51
  queryInterface: any,
52
- private readonly entityQueryContextProvider: EntityQueryContextProvider
52
+ private readonly entityQueryContextProvider: EntityQueryContextProvider,
53
53
  ) {
54
54
  super(queryInterface);
55
55
  }
@@ -60,11 +60,11 @@ export class EntityNonTransactionalQueryContext extends EntityQueryContext {
60
60
 
61
61
  async runInTransactionIfNotInTransactionAsync<T>(
62
62
  transactionScope: (queryContext: EntityTransactionalQueryContext) => Promise<T>,
63
- transactionConfig?: TransactionConfig
63
+ transactionConfig?: TransactionConfig,
64
64
  ): Promise<T> {
65
65
  return await this.entityQueryContextProvider.runInTransactionAsync(
66
66
  transactionScope,
67
- transactionConfig
67
+ transactionConfig,
68
68
  );
69
69
  }
70
70
  }
@@ -82,7 +82,7 @@ export class EntityTransactionalQueryContext extends EntityQueryContext {
82
82
 
83
83
  constructor(
84
84
  queryInterface: any,
85
- private readonly entityQueryContextProvider: EntityQueryContextProvider
85
+ private readonly entityQueryContextProvider: EntityQueryContextProvider,
86
86
  ) {
87
87
  super(queryInterface);
88
88
  }
@@ -98,7 +98,7 @@ export class EntityTransactionalQueryContext extends EntityQueryContext {
98
98
  public appendPreCommitCallback(callback: PreCommitCallback, order: number): void {
99
99
  assert(
100
100
  order >= Number.MIN_SAFE_INTEGER && order <= Number.MAX_SAFE_INTEGER,
101
- `Invalid order specified: ${order}`
101
+ `Invalid order specified: ${order}`,
102
102
  );
103
103
  this.preCommitCallbacks.push({ callback, order });
104
104
  }
@@ -148,21 +148,21 @@ export class EntityTransactionalQueryContext extends EntityQueryContext {
148
148
 
149
149
  async runInTransactionIfNotInTransactionAsync<T>(
150
150
  transactionScope: (queryContext: EntityTransactionalQueryContext) => Promise<T>,
151
- transactionConfig?: TransactionConfig
151
+ transactionConfig?: TransactionConfig,
152
152
  ): Promise<T> {
153
153
  assert(
154
154
  transactionConfig === undefined,
155
- 'Should not pass transactionConfig to a nested transaction'
155
+ 'Should not pass transactionConfig to a nested transaction',
156
156
  );
157
157
  return await transactionScope(this);
158
158
  }
159
159
 
160
160
  async runInNestedTransactionAsync<T>(
161
- transactionScope: (innerQueryContext: EntityTransactionalQueryContext) => Promise<T>
161
+ transactionScope: (innerQueryContext: EntityTransactionalQueryContext) => Promise<T>,
162
162
  ): Promise<T> {
163
163
  return await this.entityQueryContextProvider.runInNestedTransactionAsync(
164
164
  this,
165
- transactionScope
165
+ transactionScope,
166
166
  );
167
167
  }
168
168
  }
@@ -172,7 +172,8 @@ export class EntityTransactionalQueryContext extends EntityQueryContext {
172
172
  * to EntityMutator and EntityLoader methods, those methods and their
173
173
  * dependent triggers and validators will run within the nested transaction.
174
174
  *
175
- * This exists to forward post-commit callbacks to the parent query context.
175
+ * This exists to forward post-commit callbacks to the parent query context but only after
176
+ * successful commit of the nested transaction.
176
177
  */
177
178
  export class EntityNestedTransactionalQueryContext extends EntityTransactionalQueryContext {
178
179
  private readonly postCommitInvalidationCallbacksToTransfer: PostCommitCallback[] = [];
@@ -181,7 +182,7 @@ export class EntityNestedTransactionalQueryContext extends EntityTransactionalQu
181
182
  constructor(
182
183
  queryInterface: any,
183
184
  private readonly parentQueryContext: EntityTransactionalQueryContext,
184
- entityQueryContextProvider: EntityQueryContextProvider
185
+ entityQueryContextProvider: EntityQueryContextProvider,
185
186
  ) {
186
187
  super(queryInterface, entityQueryContextProvider);
187
188
  }
@@ -196,7 +197,7 @@ export class EntityNestedTransactionalQueryContext extends EntityTransactionalQu
196
197
 
197
198
  public override runPostCommitCallbacksAsync(): Promise<void> {
198
199
  throw new Error(
199
- 'Must not call runPostCommitCallbacksAsync on EntityNestedTransactionalQueryContext'
200
+ 'Must not call runPostCommitCallbacksAsync on EntityNestedTransactionalQueryContext',
200
201
  );
201
202
  }
202
203
 
@@ -12,7 +12,7 @@ export default abstract class EntityQueryContextProvider {
12
12
  /**
13
13
  * Vend a regular (non-transactional) entity query context.
14
14
  */
15
- public getNonTransactionalQueryContext(): EntityNonTransactionalQueryContext {
15
+ public getQueryContext(): EntityNonTransactionalQueryContext {
16
16
  return new EntityNonTransactionalQueryContext(this.getQueryInterface(), this);
17
17
  }
18
18
 
@@ -25,11 +25,11 @@ export default abstract class EntityQueryContextProvider {
25
25
  * Vend a transaction runner for use in runInTransactionAsync.
26
26
  */
27
27
  protected abstract createTransactionRunner<T>(
28
- transactionConfig?: TransactionConfig
28
+ transactionConfig?: TransactionConfig,
29
29
  ): (transactionScope: (queryInterface: any) => Promise<T>) => Promise<T>;
30
30
 
31
31
  protected abstract createNestedTransactionRunner<T>(
32
- outerQueryInterface: any
32
+ outerQueryInterface: any,
33
33
  ): (transactionScope: (queryInterface: any) => Promise<T>) => Promise<T>;
34
34
 
35
35
  /**
@@ -38,7 +38,7 @@ export default abstract class EntityQueryContextProvider {
38
38
  */
39
39
  async runInTransactionAsync<T>(
40
40
  transactionScope: (queryContext: EntityTransactionalQueryContext) => Promise<T>,
41
- transactionConfig?: TransactionConfig
41
+ transactionConfig?: TransactionConfig,
42
42
  ): Promise<T> {
43
43
  const [returnedValue, queryContext] = await this.createTransactionRunner<
44
44
  [T, EntityTransactionalQueryContext]
@@ -60,7 +60,7 @@ export default abstract class EntityQueryContextProvider {
60
60
  */
61
61
  async runInNestedTransactionAsync<T>(
62
62
  outerQueryContext: EntityTransactionalQueryContext,
63
- transactionScope: (innerQueryContext: EntityNestedTransactionalQueryContext) => Promise<T>
63
+ transactionScope: (innerQueryContext: EntityNestedTransactionalQueryContext) => Promise<T>,
64
64
  ): Promise<T> {
65
65
  const [returnedValue, innerQueryContext] = await this.createNestedTransactionRunner<
66
66
  [T, EntityNestedTransactionalQueryContext]
@@ -68,7 +68,7 @@ export default abstract class EntityQueryContextProvider {
68
68
  const innerQueryContext = new EntityNestedTransactionalQueryContext(
69
69
  innerQueryInterface,
70
70
  outerQueryContext,
71
- this
71
+ this,
72
72
  );
73
73
  const result = await transactionScope(innerQueryContext);
74
74
  await innerQueryContext.runPreCommitCallbacksAsync();
@@ -20,8 +20,8 @@ export interface ISecondaryEntityCache<TFields, TLoadParams> {
20
20
  loadManyThroughAsync(
21
21
  loadParamsArray: readonly Readonly<TLoadParams>[],
22
22
  fetcher: (
23
- fetcherLoadParamsArray: readonly Readonly<TLoadParams>[]
24
- ) => Promise<ReadonlyMap<Readonly<TLoadParams>, Readonly<TFields> | null>>
23
+ fetcherLoadParamsArray: readonly Readonly<TLoadParams>[],
24
+ ) => Promise<ReadonlyMap<Readonly<TLoadParams>, Readonly<TFields> | null>>,
25
25
  ): Promise<ReadonlyMap<Readonly<TLoadParams>, Readonly<TFields> | null>>;
26
26
 
27
27
  /**
@@ -56,7 +56,7 @@ export default abstract class EntitySecondaryCacheLoader<
56
56
  TEntity,
57
57
  TSelectedFields
58
58
  >,
59
- TSelectedFields extends keyof TFields = keyof TFields
59
+ TSelectedFields extends keyof TFields = keyof TFields,
60
60
  > {
61
61
  constructor(
62
62
  private readonly secondaryEntityCache: ISecondaryEntityCache<TFields, TLoadParams>,
@@ -67,7 +67,7 @@ export default abstract class EntitySecondaryCacheLoader<
67
67
  TEntity,
68
68
  TPrivacyPolicy,
69
69
  TSelectedFields
70
- >
70
+ >,
71
71
  ) {}
72
72
 
73
73
  /**
@@ -76,17 +76,19 @@ export default abstract class EntitySecondaryCacheLoader<
76
76
  * @param loadParamsArray - array of loadParams to load through the cache
77
77
  */
78
78
  public async loadManyAsync(
79
- loadParamsArray: readonly Readonly<TLoadParams>[]
79
+ loadParamsArray: readonly Readonly<TLoadParams>[],
80
80
  ): Promise<ReadonlyMap<Readonly<TLoadParams>, Result<TEntity> | null>> {
81
81
  const loadParamsToFieldObjects = await this.secondaryEntityCache.loadManyThroughAsync(
82
82
  loadParamsArray,
83
- this.fetchObjectsFromDatabaseAsync.bind(this)
83
+ this.fetchObjectsFromDatabaseAsync.bind(this),
84
84
  );
85
85
 
86
86
  // convert value to and from array to reuse complex code
87
- const entitiesMap = await this.entityLoader.constructAndAuthorizeEntitiesAsync(
88
- mapMap(loadParamsToFieldObjects, (fieldObject) => (fieldObject ? [fieldObject] : []))
89
- );
87
+ const entitiesMap = await this.entityLoader
88
+ .utils()
89
+ .constructAndAuthorizeEntitiesAsync(
90
+ mapMap(loadParamsToFieldObjects, (fieldObject) => (fieldObject ? [fieldObject] : [])),
91
+ );
90
92
  return mapMap(entitiesMap, (fieldObjects) => fieldObjects[0] ?? null);
91
93
  }
92
94
 
@@ -96,7 +98,7 @@ export default abstract class EntitySecondaryCacheLoader<
96
98
  * @param loadParamsArray - array of load params objects to invalidate
97
99
  */
98
100
  public async invalidateManyAsync(
99
- loadParamsArray: readonly Readonly<TLoadParams>[]
101
+ loadParamsArray: readonly Readonly<TLoadParams>[],
100
102
  ): Promise<void> {
101
103
  await this.secondaryEntityCache.invalidateManyAsync(loadParamsArray);
102
104
  }
@@ -107,6 +109,6 @@ export default abstract class EntitySecondaryCacheLoader<
107
109
  * @param loadParamsArray - array of load params objects to load
108
110
  */
109
111
  protected abstract fetchObjectsFromDatabaseAsync(
110
- loadParamsArray: readonly Readonly<TLoadParams>[]
112
+ loadParamsArray: readonly Readonly<TLoadParams>[],
111
113
  ): Promise<ReadonlyMap<Readonly<Readonly<TLoadParams>>, Readonly<TFields> | null>>;
112
114
  }
@@ -13,16 +13,16 @@ export default class GenericEntityCacheAdapter<TFields> implements IEntityCacheA
13
13
 
14
14
  public async loadManyAsync<N extends keyof TFields>(
15
15
  fieldName: N,
16
- fieldValues: readonly NonNullable<TFields[N]>[]
16
+ fieldValues: readonly NonNullable<TFields[N]>[],
17
17
  ): Promise<ReadonlyMap<NonNullable<TFields[N]>, CacheLoadResult<TFields>>> {
18
18
  const redisCacheKeyToFieldValueMapping = new Map(
19
19
  fieldValues.map((fieldValue) => [
20
20
  this.genericCacher.makeCacheKey(fieldName, fieldValue),
21
21
  fieldValue,
22
- ])
22
+ ]),
23
23
  );
24
24
  const cacheResults = await this.genericCacher.loadManyAsync(
25
- Array.from(redisCacheKeyToFieldValueMapping.keys())
25
+ Array.from(redisCacheKeyToFieldValueMapping.keys()),
26
26
  );
27
27
 
28
28
  return mapKeys(cacheResults, (redisCacheKey) => {
@@ -30,7 +30,7 @@ export default class GenericEntityCacheAdapter<TFields> implements IEntityCacheA
30
30
  invariant(
31
31
  fieldValue !== undefined,
32
32
  'Unspecified cache key %s returned from generic cacher',
33
- redisCacheKey
33
+ redisCacheKey,
34
34
  );
35
35
  return fieldValue;
36
36
  });
@@ -38,28 +38,28 @@ export default class GenericEntityCacheAdapter<TFields> implements IEntityCacheA
38
38
 
39
39
  public async cacheManyAsync<N extends keyof TFields>(
40
40
  fieldName: N,
41
- objectMap: ReadonlyMap<NonNullable<TFields[N]>, Readonly<TFields>>
41
+ objectMap: ReadonlyMap<NonNullable<TFields[N]>, Readonly<TFields>>,
42
42
  ): Promise<void> {
43
43
  await this.genericCacher.cacheManyAsync(
44
- mapKeys(objectMap, (fieldValue) => this.genericCacher.makeCacheKey(fieldName, fieldValue))
44
+ mapKeys(objectMap, (fieldValue) => this.genericCacher.makeCacheKey(fieldName, fieldValue)),
45
45
  );
46
46
  }
47
47
 
48
48
  public async cacheDBMissesAsync<N extends keyof TFields>(
49
49
  fieldName: N,
50
- fieldValues: readonly NonNullable<TFields[N]>[]
50
+ fieldValues: readonly NonNullable<TFields[N]>[],
51
51
  ): Promise<void> {
52
52
  await this.genericCacher.cacheDBMissesAsync(
53
- fieldValues.map((fieldValue) => this.genericCacher.makeCacheKey(fieldName, fieldValue))
53
+ fieldValues.map((fieldValue) => this.genericCacher.makeCacheKey(fieldName, fieldValue)),
54
54
  );
55
55
  }
56
56
 
57
57
  public async invalidateManyAsync<N extends keyof TFields>(
58
58
  fieldName: N,
59
- fieldValues: readonly NonNullable<TFields[N]>[]
59
+ fieldValues: readonly NonNullable<TFields[N]>[],
60
60
  ): Promise<void> {
61
61
  await this.genericCacher.invalidateManyAsync(
62
- fieldValues.map((fieldValue) => this.genericCacher.makeCacheKey(fieldName, fieldValue))
62
+ fieldValues.map((fieldValue) => this.genericCacher.makeCacheKey(fieldName, fieldValue)),
63
63
  );
64
64
  }
65
65
  }
@@ -15,14 +15,14 @@ export default abstract class GenericSecondaryEntityCache<TFields, TLoadParams>
15
15
  {
16
16
  constructor(
17
17
  protected readonly cacher: IEntityGenericCacher<TFields>,
18
- protected readonly constructCacheKey: (params: Readonly<TLoadParams>) => string
18
+ protected readonly constructCacheKey: (params: Readonly<TLoadParams>) => string,
19
19
  ) {}
20
20
 
21
21
  public async loadManyThroughAsync(
22
22
  loadParamsArray: readonly Readonly<TLoadParams>[],
23
23
  fetcher: (
24
- fetcherLoadParamsArray: readonly Readonly<TLoadParams>[]
25
- ) => Promise<ReadonlyMap<Readonly<TLoadParams>, Readonly<TFields> | null>>
24
+ fetcherLoadParamsArray: readonly Readonly<TLoadParams>[],
25
+ ) => Promise<ReadonlyMap<Readonly<TLoadParams>, Readonly<TFields> | null>>,
26
26
  ): Promise<ReadonlyMap<Readonly<TLoadParams>, Readonly<TFields> | null>> {
27
27
  const cacheKeys = loadParamsArray.map(this.constructCacheKey);
28
28
  const cacheKeyToLoadParamsMap = zipToMap(cacheKeys, loadParamsArray);
@@ -31,14 +31,14 @@ export default abstract class GenericSecondaryEntityCache<TFields, TLoadParams>
31
31
 
32
32
  invariant(
33
33
  cacheLoadResults.size === loadParamsArray.length,
34
- `${this.constructor.name} loadMany should return a result for each key`
34
+ `${this.constructor.name} loadMany should return a result for each key`,
35
35
  );
36
36
 
37
37
  const cacheKeysToFetch = Array.from(
38
38
  filterMap(
39
39
  cacheLoadResults,
40
- (cacheLoadResult) => cacheLoadResult.status === CacheStatus.MISS
41
- ).keys()
40
+ (cacheLoadResult) => cacheLoadResult.status === CacheStatus.MISS,
41
+ ).keys(),
42
42
  );
43
43
 
44
44
  // put cache hits in result map
@@ -13,7 +13,7 @@ export default interface IEntityCacheAdapter<TFields> {
13
13
  */
14
14
  loadManyAsync<N extends keyof TFields>(
15
15
  fieldName: N,
16
- fieldValues: readonly NonNullable<TFields[N]>[]
16
+ fieldValues: readonly NonNullable<TFields[N]>[],
17
17
  ): Promise<ReadonlyMap<NonNullable<TFields[N]>, CacheLoadResult<TFields>>>;
18
18
 
19
19
  /**
@@ -23,7 +23,7 @@ export default interface IEntityCacheAdapter<TFields> {
23
23
  */
24
24
  cacheManyAsync<N extends keyof TFields>(
25
25
  fieldName: N,
26
- objectMap: ReadonlyMap<NonNullable<TFields[N]>, Readonly<TFields>>
26
+ objectMap: ReadonlyMap<NonNullable<TFields[N]>, Readonly<TFields>>,
27
27
  ): Promise<void>;
28
28
 
29
29
  /**
@@ -34,7 +34,7 @@ export default interface IEntityCacheAdapter<TFields> {
34
34
  */
35
35
  cacheDBMissesAsync<N extends keyof TFields>(
36
36
  fieldName: N,
37
- fieldValues: readonly NonNullable<TFields[N]>[]
37
+ fieldValues: readonly NonNullable<TFields[N]>[],
38
38
  ): Promise<void>;
39
39
 
40
40
  /**
@@ -44,6 +44,6 @@ export default interface IEntityCacheAdapter<TFields> {
44
44
  */
45
45
  invalidateManyAsync<N extends keyof TFields>(
46
46
  fieldName: N,
47
- fieldValues: readonly NonNullable<TFields[N]>[]
47
+ fieldValues: readonly NonNullable<TFields[N]>[],
48
48
  ): Promise<void>;
49
49
  }