@expo/entity 0.35.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 (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 +1 -0
  132. package/build/index.js +1 -0
  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 +4 -3
  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 +1 -0
  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
@@ -69,7 +69,7 @@ class AlwaysDenyPolicy extends EntityPrivacyPolicy<BlahFields, string, ViewerCon
69
69
  class DryRunAlwaysDenyPolicy extends AlwaysDenyPolicy {
70
70
  // public method for test spying
71
71
  public denyHandler(
72
- _error: EntityNotAuthorizedError<BlahFields, string, ViewerContext, BlahEntity>
72
+ _error: EntityNotAuthorizedError<BlahFields, string, ViewerContext, BlahEntity>,
73
73
  ): void {}
74
74
 
75
75
  protected override getPrivacyPolicyEvaluator(): EntityPrivacyPolicyEvaluator<
@@ -88,7 +88,7 @@ class DryRunAlwaysDenyPolicy extends AlwaysDenyPolicy {
88
88
  class LoggingEnforceAlwaysDenyPolicy extends AlwaysDenyPolicy {
89
89
  // public method for test spying
90
90
  public denyHandler(
91
- _error: EntityNotAuthorizedError<BlahFields, string, ViewerContext, BlahEntity>
91
+ _error: EntityNotAuthorizedError<BlahFields, string, ViewerContext, BlahEntity>,
92
92
  ): void {}
93
93
 
94
94
  protected override getPrivacyPolicyEvaluator(): EntityPrivacyPolicyEvaluator<
@@ -122,7 +122,7 @@ class AlwaysAllowPolicy extends EntityPrivacyPolicy<BlahFields, string, ViewerCo
122
122
  class DryRunAlwaysAllowPolicy extends AlwaysAllowPolicy {
123
123
  // public method for test spying
124
124
  public denyHandler(
125
- _error: EntityNotAuthorizedError<BlahFields, string, ViewerContext, BlahEntity>
125
+ _error: EntityNotAuthorizedError<BlahFields, string, ViewerContext, BlahEntity>,
126
126
  ): void {}
127
127
 
128
128
  protected override getPrivacyPolicyEvaluator(): EntityPrivacyPolicyEvaluator<
@@ -141,7 +141,7 @@ class DryRunAlwaysAllowPolicy extends AlwaysAllowPolicy {
141
141
  class LoggingEnforceAlwaysAllowPolicy extends AlwaysAllowPolicy {
142
142
  // public method for test spying
143
143
  public denyHandler(
144
- _error: EntityNotAuthorizedError<BlahFields, string, ViewerContext, BlahEntity>
144
+ _error: EntityNotAuthorizedError<BlahFields, string, ViewerContext, BlahEntity>,
145
145
  ): void {}
146
146
 
147
147
  protected override getPrivacyPolicyEvaluator(): EntityPrivacyPolicyEvaluator<
@@ -172,6 +172,30 @@ class SkipAllPolicy extends EntityPrivacyPolicy<BlahFields, string, ViewerContex
172
172
  ];
173
173
  }
174
174
 
175
+ class InvalidCreateRuleResultPolicy extends EntityPrivacyPolicy<
176
+ BlahFields,
177
+ string,
178
+ ViewerContext,
179
+ BlahEntity
180
+ > {
181
+ protected override readonly createRules = [
182
+ {
183
+ async evaluateAsync(): Promise<RuleEvaluationResult> {
184
+ return 2 as any;
185
+ },
186
+ },
187
+ ];
188
+ protected override readonly readRules = [
189
+ new AlwaysSkipPrivacyPolicyRule<BlahFields, string, ViewerContext, BlahEntity>(),
190
+ ];
191
+ protected override readonly updateRules = [
192
+ new AlwaysSkipPrivacyPolicyRule<BlahFields, string, ViewerContext, BlahEntity>(),
193
+ ];
194
+ protected override readonly deleteRules = [
195
+ new AlwaysSkipPrivacyPolicyRule<BlahFields, string, ViewerContext, BlahEntity>(),
196
+ ];
197
+ }
198
+
175
199
  class AlwaysThrowPrivacyPolicyRule extends PrivacyPolicyRule<
176
200
  BlahFields,
177
201
  string,
@@ -181,8 +205,13 @@ class AlwaysThrowPrivacyPolicyRule extends PrivacyPolicyRule<
181
205
  evaluateAsync(
182
206
  _viewerContext: ViewerContext,
183
207
  _queryContext: EntityQueryContext,
184
- _evaluationContext: EntityPrivacyPolicyEvaluationContext,
185
- _entity: BlahEntity
208
+ _evaluationContext: EntityPrivacyPolicyEvaluationContext<
209
+ BlahFields,
210
+ string,
211
+ ViewerContext,
212
+ BlahEntity
213
+ >,
214
+ _entity: BlahEntity,
186
215
  ): Promise<RuleEvaluationResult> {
187
216
  throw new Error('WooHoo!');
188
217
  }
@@ -198,7 +227,7 @@ class ThrowAllPolicy extends EntityPrivacyPolicy<BlahFields, string, ViewerConte
198
227
  class DryRunThrowAllPolicy extends ThrowAllPolicy {
199
228
  // public method for test spying
200
229
  public denyHandler(
201
- _error: EntityNotAuthorizedError<BlahFields, string, ViewerContext, BlahEntity>
230
+ _error: EntityNotAuthorizedError<BlahFields, string, ViewerContext, BlahEntity>,
202
231
  ): void {}
203
232
 
204
233
  protected override getPrivacyPolicyEvaluator(): EntityPrivacyPolicyEvaluator<
@@ -217,7 +246,7 @@ class DryRunThrowAllPolicy extends ThrowAllPolicy {
217
246
  class LoggingEnforceThrowAllPolicy extends ThrowAllPolicy {
218
247
  // public method for test spying
219
248
  public denyHandler(
220
- _error: EntityNotAuthorizedError<BlahFields, string, ViewerContext, BlahEntity>
249
+ _error: EntityNotAuthorizedError<BlahFields, string, ViewerContext, BlahEntity>,
221
250
  ): void {}
222
251
 
223
252
  protected override getPrivacyPolicyEvaluator(): EntityPrivacyPolicyEvaluator<
@@ -245,7 +274,12 @@ describe(EntityPrivacyPolicy, () => {
245
274
  it('throws EntityNotAuthorizedError when deny', async () => {
246
275
  const viewerContext = instance(mock(ViewerContext));
247
276
  const queryContext = instance(mock(EntityQueryContext));
248
- const privacyPolicyEvaluationContext = instance(mock<EntityPrivacyPolicyEvaluationContext>());
277
+ const privacyPolicyEvaluationContext =
278
+ instance(
279
+ mock<
280
+ EntityPrivacyPolicyEvaluationContext<BlahFields, string, ViewerContext, BlahEntity>
281
+ >(),
282
+ );
249
283
  const metricsAdapterMock = mock<IEntityMetricsAdapter>();
250
284
  const metricsAdapter = instance(metricsAdapterMock);
251
285
  const entity = new BlahEntity({
@@ -261,8 +295,8 @@ describe(EntityPrivacyPolicy, () => {
261
295
  queryContext,
262
296
  privacyPolicyEvaluationContext,
263
297
  entity,
264
- metricsAdapter
265
- )
298
+ metricsAdapter,
299
+ ),
266
300
  ).rejects.toBeInstanceOf(EntityNotAuthorizedError);
267
301
  verify(
268
302
  metricsAdapterMock.logAuthorizationEvent(
@@ -271,15 +305,20 @@ describe(EntityPrivacyPolicy, () => {
271
305
  action: EntityAuthorizationAction.CREATE,
272
306
  evaluationResult: EntityMetricsAuthorizationResult.DENY,
273
307
  privacyPolicyEvaluationMode: EntityPrivacyPolicyEvaluationMode.ENFORCE,
274
- })
275
- )
308
+ }),
309
+ ),
276
310
  ).once();
277
311
  });
278
312
 
279
313
  it('returns entity when allowed', async () => {
280
314
  const viewerContext = instance(mock(ViewerContext));
281
315
  const queryContext = instance(mock(EntityQueryContext));
282
- const privacyPolicyEvaluationContext = instance(mock<EntityPrivacyPolicyEvaluationContext>());
316
+ const privacyPolicyEvaluationContext =
317
+ instance(
318
+ mock<
319
+ EntityPrivacyPolicyEvaluationContext<BlahFields, string, ViewerContext, BlahEntity>
320
+ >(),
321
+ );
283
322
  const metricsAdapterMock = mock<IEntityMetricsAdapter>();
284
323
  const metricsAdapter = instance(metricsAdapterMock);
285
324
  const entity = new BlahEntity({
@@ -294,7 +333,7 @@ describe(EntityPrivacyPolicy, () => {
294
333
  queryContext,
295
334
  privacyPolicyEvaluationContext,
296
335
  entity,
297
- metricsAdapter
336
+ metricsAdapter,
298
337
  );
299
338
  expect(approvedEntity).toEqual(entity);
300
339
  verify(
@@ -304,15 +343,20 @@ describe(EntityPrivacyPolicy, () => {
304
343
  action: EntityAuthorizationAction.CREATE,
305
344
  evaluationResult: EntityMetricsAuthorizationResult.ALLOW,
306
345
  privacyPolicyEvaluationMode: EntityPrivacyPolicyEvaluationMode.ENFORCE,
307
- })
308
- )
346
+ }),
347
+ ),
309
348
  ).once();
310
349
  });
311
350
 
312
351
  it('throws EntityNotAuthorizedError when all skipped', async () => {
313
352
  const viewerContext = instance(mock(ViewerContext));
314
353
  const queryContext = instance(mock(EntityQueryContext));
315
- const privacyPolicyEvaluationContext = instance(mock<EntityPrivacyPolicyEvaluationContext>());
354
+ const privacyPolicyEvaluationContext =
355
+ instance(
356
+ mock<
357
+ EntityPrivacyPolicyEvaluationContext<BlahFields, string, ViewerContext, BlahEntity>
358
+ >(),
359
+ );
316
360
  const metricsAdapterMock = mock<IEntityMetricsAdapter>();
317
361
  const metricsAdapter = instance(metricsAdapterMock);
318
362
  const entity = new BlahEntity({
@@ -328,8 +372,8 @@ describe(EntityPrivacyPolicy, () => {
328
372
  queryContext,
329
373
  privacyPolicyEvaluationContext,
330
374
  entity,
331
- metricsAdapter
332
- )
375
+ metricsAdapter,
376
+ ),
333
377
  ).rejects.toBeInstanceOf(EntityNotAuthorizedError);
334
378
  verify(
335
379
  metricsAdapterMock.logAuthorizationEvent(
@@ -338,15 +382,49 @@ describe(EntityPrivacyPolicy, () => {
338
382
  action: EntityAuthorizationAction.CREATE,
339
383
  evaluationResult: EntityMetricsAuthorizationResult.DENY,
340
384
  privacyPolicyEvaluationMode: EntityPrivacyPolicyEvaluationMode.ENFORCE,
341
- })
342
- )
385
+ }),
386
+ ),
343
387
  ).once();
344
388
  });
345
389
 
390
+ it('throws when an invalid result is returned', async () => {
391
+ const viewerContext = instance(mock(ViewerContext));
392
+ const queryContext = instance(mock(EntityQueryContext));
393
+ const privacyPolicyEvaluationContext =
394
+ instance(
395
+ mock<
396
+ EntityPrivacyPolicyEvaluationContext<BlahFields, string, ViewerContext, BlahEntity>
397
+ >(),
398
+ );
399
+ const metricsAdapterMock = mock<IEntityMetricsAdapter>();
400
+ const metricsAdapter = instance(metricsAdapterMock);
401
+ const entity = new BlahEntity({
402
+ viewerContext,
403
+ id: '1',
404
+ databaseFields: { id: '1' },
405
+ selectedFields: { id: '1' },
406
+ });
407
+ const policy = new InvalidCreateRuleResultPolicy();
408
+ await expect(
409
+ policy.authorizeCreateAsync(
410
+ viewerContext,
411
+ queryContext,
412
+ privacyPolicyEvaluationContext,
413
+ entity,
414
+ metricsAdapter,
415
+ ),
416
+ ).rejects.toThrow('Invalid RuleEvaluationResult returned from rule');
417
+ });
418
+
346
419
  it('throws EntityNotAuthorizedError when empty policy', async () => {
347
420
  const viewerContext = instance(mock(ViewerContext));
348
421
  const queryContext = instance(mock(EntityQueryContext));
349
- const privacyPolicyEvaluationContext = instance(mock<EntityPrivacyPolicyEvaluationContext>());
422
+ const privacyPolicyEvaluationContext =
423
+ instance(
424
+ mock<
425
+ EntityPrivacyPolicyEvaluationContext<BlahFields, string, ViewerContext, BlahEntity>
426
+ >(),
427
+ );
350
428
  const metricsAdapterMock = mock<IEntityMetricsAdapter>();
351
429
  const metricsAdapter = instance(metricsAdapterMock);
352
430
  const entity = new BlahEntity({
@@ -362,8 +440,8 @@ describe(EntityPrivacyPolicy, () => {
362
440
  queryContext,
363
441
  privacyPolicyEvaluationContext,
364
442
  entity,
365
- metricsAdapter
366
- )
443
+ metricsAdapter,
444
+ ),
367
445
  ).rejects.toBeInstanceOf(EntityNotAuthorizedError);
368
446
  verify(
369
447
  metricsAdapterMock.logAuthorizationEvent(
@@ -372,15 +450,20 @@ describe(EntityPrivacyPolicy, () => {
372
450
  action: EntityAuthorizationAction.CREATE,
373
451
  evaluationResult: EntityMetricsAuthorizationResult.DENY,
374
452
  privacyPolicyEvaluationMode: EntityPrivacyPolicyEvaluationMode.ENFORCE,
375
- })
376
- )
453
+ }),
454
+ ),
377
455
  ).once();
378
456
  });
379
457
 
380
458
  it('throws when rule throws', async () => {
381
459
  const viewerContext = instance(mock(ViewerContext));
382
460
  const queryContext = instance(mock(EntityQueryContext));
383
- const privacyPolicyEvaluationContext = instance(mock<EntityPrivacyPolicyEvaluationContext>());
461
+ const privacyPolicyEvaluationContext =
462
+ instance(
463
+ mock<
464
+ EntityPrivacyPolicyEvaluationContext<BlahFields, string, ViewerContext, BlahEntity>
465
+ >(),
466
+ );
384
467
  const metricsAdapterMock = mock<IEntityMetricsAdapter>();
385
468
  const metricsAdapter = instance(metricsAdapterMock);
386
469
  const entity = new BlahEntity({
@@ -396,8 +479,8 @@ describe(EntityPrivacyPolicy, () => {
396
479
  queryContext,
397
480
  privacyPolicyEvaluationContext,
398
481
  entity,
399
- metricsAdapter
400
- )
482
+ metricsAdapter,
483
+ ),
401
484
  ).rejects.toThrowError('WooHoo!');
402
485
  verify(metricsAdapterMock.logAuthorizationEvent(anything())).never();
403
486
  });
@@ -407,7 +490,12 @@ describe(EntityPrivacyPolicy, () => {
407
490
  it('returns entity when denied but calls denialHandler', async () => {
408
491
  const viewerContext = instance(mock(ViewerContext));
409
492
  const queryContext = instance(mock(EntityQueryContext));
410
- const privacyPolicyEvaluationContext = instance(mock<EntityPrivacyPolicyEvaluationContext>());
493
+ const privacyPolicyEvaluationContext =
494
+ instance(
495
+ mock<
496
+ EntityPrivacyPolicyEvaluationContext<BlahFields, string, ViewerContext, BlahEntity>
497
+ >(),
498
+ );
411
499
  const metricsAdapterMock = mock<IEntityMetricsAdapter>();
412
500
  const metricsAdapter = instance(metricsAdapterMock);
413
501
  const entity = new BlahEntity({
@@ -425,7 +513,7 @@ describe(EntityPrivacyPolicy, () => {
425
513
  queryContext,
426
514
  privacyPolicyEvaluationContext,
427
515
  entity,
428
- metricsAdapter
516
+ metricsAdapter,
429
517
  );
430
518
  expect(approvedEntity).toEqual(entity);
431
519
 
@@ -438,15 +526,20 @@ describe(EntityPrivacyPolicy, () => {
438
526
  action: EntityAuthorizationAction.CREATE,
439
527
  evaluationResult: EntityMetricsAuthorizationResult.DENY,
440
528
  privacyPolicyEvaluationMode: EntityPrivacyPolicyEvaluationMode.DRY_RUN,
441
- })
442
- )
529
+ }),
530
+ ),
443
531
  ).once();
444
532
  });
445
533
 
446
534
  it('does not log when not denied', async () => {
447
535
  const viewerContext = instance(mock(ViewerContext));
448
536
  const queryContext = instance(mock(EntityQueryContext));
449
- const privacyPolicyEvaluationContext = instance(mock<EntityPrivacyPolicyEvaluationContext>());
537
+ const privacyPolicyEvaluationContext =
538
+ instance(
539
+ mock<
540
+ EntityPrivacyPolicyEvaluationContext<BlahFields, string, ViewerContext, BlahEntity>
541
+ >(),
542
+ );
450
543
  const metricsAdapterMock = mock<IEntityMetricsAdapter>();
451
544
  const metricsAdapter = instance(metricsAdapterMock);
452
545
  const entity = new BlahEntity({
@@ -464,7 +557,7 @@ describe(EntityPrivacyPolicy, () => {
464
557
  queryContext,
465
558
  privacyPolicyEvaluationContext,
466
559
  entity,
467
- metricsAdapter
560
+ metricsAdapter,
468
561
  );
469
562
  expect(approvedEntity).toEqual(entity);
470
563
 
@@ -477,15 +570,20 @@ describe(EntityPrivacyPolicy, () => {
477
570
  action: EntityAuthorizationAction.CREATE,
478
571
  evaluationResult: EntityMetricsAuthorizationResult.ALLOW,
479
572
  privacyPolicyEvaluationMode: EntityPrivacyPolicyEvaluationMode.DRY_RUN,
480
- })
481
- )
573
+ }),
574
+ ),
482
575
  ).once();
483
576
  });
484
577
 
485
578
  it('passes through other errors', async () => {
486
579
  const viewerContext = instance(mock(ViewerContext));
487
580
  const queryContext = instance(mock(EntityQueryContext));
488
- const privacyPolicyEvaluationContext = instance(mock<EntityPrivacyPolicyEvaluationContext>());
581
+ const privacyPolicyEvaluationContext =
582
+ instance(
583
+ mock<
584
+ EntityPrivacyPolicyEvaluationContext<BlahFields, string, ViewerContext, BlahEntity>
585
+ >(),
586
+ );
489
587
  const metricsAdapterMock = mock<IEntityMetricsAdapter>();
490
588
  const metricsAdapter = instance(metricsAdapterMock);
491
589
  const entity = new BlahEntity({
@@ -504,8 +602,8 @@ describe(EntityPrivacyPolicy, () => {
504
602
  queryContext,
505
603
  privacyPolicyEvaluationContext,
506
604
  entity,
507
- metricsAdapter
508
- )
605
+ metricsAdapter,
606
+ ),
509
607
  ).rejects.toThrowError('WooHoo!');
510
608
 
511
609
  verify(policySpy.denyHandler(anyOfClass(EntityNotAuthorizedError))).never();
@@ -518,7 +616,12 @@ describe(EntityPrivacyPolicy, () => {
518
616
  it('denies when denied but calls denialHandler', async () => {
519
617
  const viewerContext = instance(mock(ViewerContext));
520
618
  const queryContext = instance(mock(EntityQueryContext));
521
- const privacyPolicyEvaluationContext = instance(mock<EntityPrivacyPolicyEvaluationContext>());
619
+ const privacyPolicyEvaluationContext =
620
+ instance(
621
+ mock<
622
+ EntityPrivacyPolicyEvaluationContext<BlahFields, string, ViewerContext, BlahEntity>
623
+ >(),
624
+ );
522
625
  const metricsAdapterMock = mock<IEntityMetricsAdapter>();
523
626
  const metricsAdapter = instance(metricsAdapterMock);
524
627
  const entity = new BlahEntity({
@@ -537,8 +640,8 @@ describe(EntityPrivacyPolicy, () => {
537
640
  queryContext,
538
641
  privacyPolicyEvaluationContext,
539
642
  entity,
540
- metricsAdapter
541
- )
643
+ metricsAdapter,
644
+ ),
542
645
  ).rejects.toBeInstanceOf(EntityNotAuthorizedError);
543
646
 
544
647
  verify(policySpy.denyHandler(anyOfClass(EntityNotAuthorizedError))).once();
@@ -550,15 +653,20 @@ describe(EntityPrivacyPolicy, () => {
550
653
  action: EntityAuthorizationAction.CREATE,
551
654
  evaluationResult: EntityMetricsAuthorizationResult.DENY,
552
655
  privacyPolicyEvaluationMode: EntityPrivacyPolicyEvaluationMode.ENFORCE_AND_LOG,
553
- })
554
- )
656
+ }),
657
+ ),
555
658
  ).once();
556
659
  });
557
660
 
558
661
  it('does not log when not denied', async () => {
559
662
  const viewerContext = instance(mock(ViewerContext));
560
663
  const queryContext = instance(mock(EntityQueryContext));
561
- const privacyPolicyEvaluationContext = instance(mock<EntityPrivacyPolicyEvaluationContext>());
664
+ const privacyPolicyEvaluationContext =
665
+ instance(
666
+ mock<
667
+ EntityPrivacyPolicyEvaluationContext<BlahFields, string, ViewerContext, BlahEntity>
668
+ >(),
669
+ );
562
670
  const metricsAdapterMock = mock<IEntityMetricsAdapter>();
563
671
  const metricsAdapter = instance(metricsAdapterMock);
564
672
  const entity = new BlahEntity({
@@ -576,7 +684,7 @@ describe(EntityPrivacyPolicy, () => {
576
684
  queryContext,
577
685
  privacyPolicyEvaluationContext,
578
686
  entity,
579
- metricsAdapter
687
+ metricsAdapter,
580
688
  );
581
689
  expect(approvedEntity).toEqual(entity);
582
690
 
@@ -589,15 +697,20 @@ describe(EntityPrivacyPolicy, () => {
589
697
  action: EntityAuthorizationAction.CREATE,
590
698
  evaluationResult: EntityMetricsAuthorizationResult.ALLOW,
591
699
  privacyPolicyEvaluationMode: EntityPrivacyPolicyEvaluationMode.ENFORCE_AND_LOG,
592
- })
593
- )
700
+ }),
701
+ ),
594
702
  ).once();
595
703
  });
596
704
 
597
705
  it('passes through other errors', async () => {
598
706
  const viewerContext = instance(mock(ViewerContext));
599
707
  const queryContext = instance(mock(EntityQueryContext));
600
- const privacyPolicyEvaluationContext = instance(mock<EntityPrivacyPolicyEvaluationContext>());
708
+ const privacyPolicyEvaluationContext =
709
+ instance(
710
+ mock<
711
+ EntityPrivacyPolicyEvaluationContext<BlahFields, string, ViewerContext, BlahEntity>
712
+ >(),
713
+ );
601
714
  const metricsAdapterMock = mock<IEntityMetricsAdapter>();
602
715
  const metricsAdapter = instance(metricsAdapterMock);
603
716
  const entity = new BlahEntity({
@@ -616,8 +729,8 @@ describe(EntityPrivacyPolicy, () => {
616
729
  queryContext,
617
730
  privacyPolicyEvaluationContext,
618
731
  entity,
619
- metricsAdapter
620
- )
732
+ metricsAdapter,
733
+ ),
621
734
  ).rejects.toThrowError('WooHoo!');
622
735
 
623
736
  verify(policySpy.denyHandler(anyOfClass(EntityNotAuthorizedError))).never();
@@ -15,25 +15,25 @@ describe(EntityQueryContext, () => {
15
15
  const postCommitInvalidationCallback = jest.fn(async (): Promise<void> => {
16
16
  invariant(
17
17
  preCommitFirstCallback.mock.calls.length === 1,
18
- 'preCommit should be called before postCommitInvalidation'
18
+ 'preCommit should be called before postCommitInvalidation',
19
19
  );
20
20
  invariant(
21
21
  preCommitSecondCallback.mock.calls.length === 1,
22
- 'preCommit should be called before postCommitInvalidation'
22
+ 'preCommit should be called before postCommitInvalidation',
23
23
  );
24
24
  });
25
25
  const postCommitCallback = jest.fn(async (): Promise<void> => {
26
26
  invariant(
27
27
  preCommitFirstCallback.mock.calls.length === 1,
28
- 'preCommit should be called before postCommit'
28
+ 'preCommit should be called before postCommit',
29
29
  );
30
30
  invariant(
31
31
  preCommitSecondCallback.mock.calls.length === 1,
32
- 'preCommit should be called before postCommit'
32
+ 'preCommit should be called before postCommit',
33
33
  );
34
34
  invariant(
35
35
  postCommitInvalidationCallback.mock.calls.length === 1,
36
- 'postCommitInvalidation should be called before postCommit'
36
+ 'postCommitInvalidation should be called before postCommit',
37
37
  );
38
38
  });
39
39
 
@@ -44,7 +44,7 @@ describe(EntityQueryContext, () => {
44
44
  queryContext.appendPostCommitInvalidationCallback(postCommitInvalidationCallback);
45
45
  queryContext.appendPreCommitCallback(preCommitSecondCallback, 2);
46
46
  queryContext.appendPreCommitCallback(preCommitFirstCallback, 1);
47
- }
47
+ },
48
48
  );
49
49
 
50
50
  expect(preCommitFirstCallback).toHaveBeenCalledTimes(1);
@@ -70,8 +70,8 @@ describe(EntityQueryContext, () => {
70
70
  queryContext.appendPostCommitCallback(postCommitCallback);
71
71
  queryContext.appendPostCommitInvalidationCallback(postCommitInvalidationCallback);
72
72
  queryContext.appendPreCommitCallback(preCommitCallback, 0);
73
- }
74
- )
73
+ },
74
+ ),
75
75
  ).rejects.toThrowError('wat');
76
76
 
77
77
  expect(preCommitCallback).toHaveBeenCalledTimes(1);
@@ -102,7 +102,7 @@ describe(EntityQueryContext, () => {
102
102
  queryContext.runInNestedTransactionAsync(async (innerQueryContext) => {
103
103
  innerQueryContext.appendPostCommitCallback(postCommitCallback);
104
104
  innerQueryContext.appendPostCommitInvalidationCallback(
105
- postCommitInvalidationCallback
105
+ postCommitInvalidationCallback,
106
106
  );
107
107
  innerQueryContext.appendPreCommitCallback(preCommitNestedCallback, 0);
108
108
  }),
@@ -112,14 +112,14 @@ describe(EntityQueryContext, () => {
112
112
  // these two shouldn't be called
113
113
  innerQueryContext.appendPostCommitCallback(postCommitCallback);
114
114
  innerQueryContext.appendPostCommitInvalidationCallback(
115
- postCommitInvalidationCallback
115
+ postCommitInvalidationCallback,
116
116
  );
117
117
  innerQueryContext.appendPreCommitCallback(preCommitNestedCallbackThrow, 0);
118
118
  });
119
119
  } catch {}
120
120
  })(),
121
121
  ]);
122
- }
122
+ },
123
123
  );
124
124
 
125
125
  expect(preCommitCallback).toHaveBeenCalledTimes(1);
@@ -128,6 +128,24 @@ describe(EntityQueryContext, () => {
128
128
  expect(postCommitCallback).toHaveBeenCalledTimes(2);
129
129
  expect(postCommitInvalidationCallback).toHaveBeenCalledTimes(2);
130
130
  });
131
+
132
+ it('does not support calling runPostCommitCallbacksAsync on nested transaction', async () => {
133
+ const companionProvider = createUnitTestEntityCompanionProvider();
134
+ const viewerContext = new ViewerContext(companionProvider);
135
+
136
+ await expect(
137
+ viewerContext.runInTransactionForDatabaseAdaptorFlavorAsync(
138
+ 'postgres',
139
+ async (queryContext) => {
140
+ await queryContext.runInNestedTransactionAsync(async (innerQueryContext) => {
141
+ await innerQueryContext.runPostCommitCallbacksAsync();
142
+ });
143
+ },
144
+ ),
145
+ ).rejects.toThrowError(
146
+ 'Must not call runPostCommitCallbacksAsync on EntityNestedTransactionalQueryContext',
147
+ );
148
+ });
131
149
  });
132
150
 
133
151
  describe('transaction config', () => {
@@ -145,7 +163,7 @@ describe(EntityQueryContext, () => {
145
163
  await viewerContext.runInTransactionForDatabaseAdaptorFlavorAsync(
146
164
  'postgres',
147
165
  transactionScopeFn,
148
- transactionConfig
166
+ transactionConfig,
149
167
  );
150
168
 
151
169
  expect(queryContextProviderSpy).toHaveBeenCalledWith(transactionScopeFn, transactionConfig);
@@ -20,7 +20,7 @@ class TestSecondaryRedisCacheLoader extends EntitySecondaryCacheLoader<
20
20
  SimpleTestEntityPrivacyPolicy
21
21
  > {
22
22
  protected async fetchObjectsFromDatabaseAsync(
23
- _loadParamsArray: readonly Readonly<TestLoadParams>[]
23
+ _loadParamsArray: readonly Readonly<TestLoadParams>[],
24
24
  ): Promise<ReadonlyMap<Readonly<TestLoadParams>, Readonly<SimpleTestFields>>> {
25
25
  // unused
26
26
  return new Map();
@@ -38,19 +38,19 @@ describe(EntitySecondaryCacheLoader, () => {
38
38
  const secondaryEntityCacheMock =
39
39
  mock<ISecondaryEntityCache<SimpleTestFields, TestLoadParams>>();
40
40
  when(
41
- secondaryEntityCacheMock.loadManyThroughAsync(deepEqual([loadParams]), anything())
41
+ secondaryEntityCacheMock.loadManyThroughAsync(deepEqual([loadParams]), anything()),
42
42
  ).thenResolve(new Map());
43
43
  const secondaryEntityCache = instance(secondaryEntityCacheMock);
44
44
 
45
45
  const secondaryCacheLoader = new TestSecondaryRedisCacheLoader(
46
46
  secondaryEntityCache,
47
- SimpleTestEntity.loader(vc1)
47
+ SimpleTestEntity.loader(vc1),
48
48
  );
49
49
 
50
50
  await secondaryCacheLoader.loadManyAsync([loadParams]);
51
51
 
52
52
  verify(
53
- secondaryEntityCacheMock.loadManyThroughAsync(deepEqual([loadParams]), anything())
53
+ secondaryEntityCacheMock.loadManyThroughAsync(deepEqual([loadParams]), anything()),
54
54
  ).once();
55
55
  });
56
56
 
@@ -63,7 +63,7 @@ describe(EntitySecondaryCacheLoader, () => {
63
63
  const secondaryEntityCacheMock =
64
64
  mock<ISecondaryEntityCache<SimpleTestFields, TestLoadParams>>();
65
65
  when(
66
- secondaryEntityCacheMock.loadManyThroughAsync(deepEqual([loadParams]), anything())
66
+ secondaryEntityCacheMock.loadManyThroughAsync(deepEqual([loadParams]), anything()),
67
67
  ).thenResolve(new Map([[loadParams, createdEntity.getAllFields()]]));
68
68
  const secondaryEntityCache = instance(secondaryEntityCacheMock);
69
69
 
@@ -80,8 +80,8 @@ describe(EntitySecondaryCacheLoader, () => {
80
80
  anyOfClass(EntityNonTransactionalQueryContext),
81
81
  anything(),
82
82
  anything(),
83
- anything()
84
- )
83
+ anything(),
84
+ ),
85
85
  ).once();
86
86
  });
87
87
  });