@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
@@ -14,19 +14,19 @@ export default class ComposedSecondaryEntityCache<TLoadParams, TFields>
14
14
  * Typically, caches closer to the application should be ordered before caches closer to the database.
15
15
  */
16
16
  constructor(
17
- private readonly secondaryEntityCaches: ISecondaryEntityCache<TFields, TLoadParams>[]
17
+ private readonly secondaryEntityCaches: ISecondaryEntityCache<TFields, TLoadParams>[],
18
18
  ) {}
19
19
 
20
20
  async 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
  return await ComposedSecondaryEntityCache.loadManyThroughRecursivelyAsync(
27
27
  this.secondaryEntityCaches,
28
28
  loadParamsArray,
29
- fetcher
29
+ fetcher,
30
30
  );
31
31
  }
32
32
 
@@ -34,8 +34,8 @@ export default class ComposedSecondaryEntityCache<TLoadParams, TFields>
34
34
  secondaryEntityCaches: ISecondaryEntityCache<TFields, TLoadParams>[],
35
35
  loadParamsArray: readonly Readonly<TLoadParams>[],
36
36
  fetcher: (
37
- fetcherLoadParamsArray: readonly Readonly<TLoadParams>[]
38
- ) => Promise<ReadonlyMap<Readonly<TLoadParams>, Readonly<TFields> | null>>
37
+ fetcherLoadParamsArray: readonly Readonly<TLoadParams>[],
38
+ ) => Promise<ReadonlyMap<Readonly<TLoadParams>, Readonly<TFields> | null>>,
39
39
  ): Promise<ReadonlyMap<Readonly<TLoadParams>, Readonly<TFields> | null>> {
40
40
  if (secondaryEntityCaches.length === 0) {
41
41
  return await fetcher(loadParamsArray);
@@ -49,8 +49,8 @@ export default class ComposedSecondaryEntityCache<TLoadParams, TFields>
49
49
  ComposedSecondaryEntityCache.loadManyThroughRecursivelyAsync(
50
50
  restCaches,
51
51
  fetcherLoadParamsArray,
52
- fetcher
53
- )
52
+ fetcher,
53
+ ),
54
54
  );
55
55
  }
56
56
 
@@ -1,17 +1,18 @@
1
+ import AuthorizationResultBasedEntityLoader from './AuthorizationResultBasedEntityLoader';
1
2
  import {
2
3
  FieldEqualityCondition,
3
4
  QuerySelectionModifiers,
4
5
  QuerySelectionModifiersWithOrderByRaw,
5
6
  } from './EntityDatabaseAdapter';
6
- import EntityLoader from './EntityLoader';
7
7
  import EntityPrivacyPolicy from './EntityPrivacyPolicy';
8
8
  import ReadonlyEntity from './ReadonlyEntity';
9
9
  import ViewerContext from './ViewerContext';
10
10
  import { mapMap } from './utils/collections/maps';
11
11
 
12
12
  /**
13
- * Enforcing view on an entity loader. All loads through this loader will throw
14
- * if the loads are not successful.
13
+ * Enforcing entity loader. All normal loads are batched,
14
+ * cached, and authorized against the entity's EntityPrivacyPolicy. All loads
15
+ * through this loader will throw if the load is not successful.
15
16
  */
16
17
  export default class EnforcingEntityLoader<
17
18
  TFields extends object,
@@ -25,17 +26,17 @@ export default class EnforcingEntityLoader<
25
26
  TEntity,
26
27
  TSelectedFields
27
28
  >,
28
- TSelectedFields extends keyof TFields
29
+ TSelectedFields extends keyof TFields,
29
30
  > {
30
31
  constructor(
31
- private readonly entityLoader: EntityLoader<
32
+ private readonly entityLoader: AuthorizationResultBasedEntityLoader<
32
33
  TFields,
33
34
  TID,
34
35
  TViewerContext,
35
36
  TEntity,
36
37
  TPrivacyPolicy,
37
38
  TSelectedFields
38
- >
39
+ >,
39
40
  ) {}
40
41
 
41
42
  /**
@@ -44,14 +45,14 @@ export default class EnforcingEntityLoader<
44
45
  */
45
46
  async loadManyByFieldEqualingManyAsync<N extends keyof Pick<TFields, TSelectedFields>>(
46
47
  fieldName: N,
47
- fieldValues: readonly NonNullable<TFields[N]>[]
48
+ fieldValues: readonly NonNullable<TFields[N]>[],
48
49
  ): Promise<ReadonlyMap<NonNullable<TFields[N]>, readonly TEntity[]>> {
49
50
  const fieldValuesToResults = await this.entityLoader.loadManyByFieldEqualingManyAsync(
50
51
  fieldName,
51
- fieldValues
52
+ fieldValues,
52
53
  );
53
54
  return mapMap(fieldValuesToResults, (results) =>
54
- results.map((result) => result.enforceValue())
55
+ results.map((result) => result.enforceValue()),
55
56
  );
56
57
  }
57
58
 
@@ -61,11 +62,11 @@ export default class EnforcingEntityLoader<
61
62
  */
62
63
  async loadManyByFieldEqualingAsync<N extends keyof Pick<TFields, TSelectedFields>>(
63
64
  fieldName: N,
64
- fieldValue: NonNullable<TFields[N]>
65
+ fieldValue: NonNullable<TFields[N]>,
65
66
  ): Promise<readonly TEntity[]> {
66
67
  const entityResults = await this.entityLoader.loadManyByFieldEqualingAsync(
67
68
  fieldName,
68
- fieldValue
69
+ fieldValue,
69
70
  );
70
71
  return entityResults.map((result) => result.enforceValue());
71
72
  }
@@ -77,11 +78,11 @@ export default class EnforcingEntityLoader<
77
78
  */
78
79
  async loadByFieldEqualingAsync<N extends keyof Pick<TFields, TSelectedFields>>(
79
80
  uniqueFieldName: N,
80
- fieldValue: NonNullable<TFields[N]>
81
+ fieldValue: NonNullable<TFields[N]>,
81
82
  ): Promise<TEntity | null> {
82
83
  const entityResult = await this.entityLoader.loadByFieldEqualingAsync(
83
84
  uniqueFieldName,
84
- fieldValue
85
+ fieldValue,
85
86
  );
86
87
  return entityResult ? entityResult.enforceValue() : null;
87
88
  }
@@ -130,11 +131,11 @@ export default class EnforcingEntityLoader<
130
131
  async loadFirstByFieldEqualityConjunctionAsync<N extends keyof Pick<TFields, TSelectedFields>>(
131
132
  fieldEqualityOperands: FieldEqualityCondition<TFields, N>[],
132
133
  querySelectionModifiers: Omit<QuerySelectionModifiers<TFields>, 'limit'> &
133
- Required<Pick<QuerySelectionModifiers<TFields>, 'orderBy'>>
134
+ Required<Pick<QuerySelectionModifiers<TFields>, 'orderBy'>>,
134
135
  ): Promise<TEntity | null> {
135
136
  const entityResult = await this.entityLoader.loadFirstByFieldEqualityConjunctionAsync(
136
137
  fieldEqualityOperands,
137
- querySelectionModifiers
138
+ querySelectionModifiers,
138
139
  );
139
140
  return entityResult ? entityResult.enforceValue() : null;
140
141
  }
@@ -145,11 +146,11 @@ export default class EnforcingEntityLoader<
145
146
  */
146
147
  async loadManyByFieldEqualityConjunctionAsync<N extends keyof Pick<TFields, TSelectedFields>>(
147
148
  fieldEqualityOperands: FieldEqualityCondition<TFields, N>[],
148
- querySelectionModifiers: QuerySelectionModifiers<TFields> = {}
149
+ querySelectionModifiers: QuerySelectionModifiers<TFields> = {},
149
150
  ): Promise<readonly TEntity[]> {
150
151
  const entityResults = await this.entityLoader.loadManyByFieldEqualityConjunctionAsync(
151
152
  fieldEqualityOperands,
152
- querySelectionModifiers
153
+ querySelectionModifiers,
153
154
  );
154
155
  return entityResults.map((result) => result.enforceValue());
155
156
  }
@@ -161,12 +162,12 @@ export default class EnforcingEntityLoader<
161
162
  async loadManyByRawWhereClauseAsync(
162
163
  rawWhereClause: string,
163
164
  bindings: any[] | object,
164
- querySelectionModifiers: QuerySelectionModifiersWithOrderByRaw<TFields> = {}
165
+ querySelectionModifiers: QuerySelectionModifiersWithOrderByRaw<TFields> = {},
165
166
  ): Promise<readonly TEntity[]> {
166
167
  const entityResults = await this.entityLoader.loadManyByRawWhereClauseAsync(
167
168
  rawWhereClause,
168
169
  bindings,
169
- querySelectionModifiers
170
+ querySelectionModifiers,
170
171
  );
171
172
  return entityResults.map((result) => result.enforceValue());
172
173
  }
package/src/Entity.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Result, asyncResult } from '@expo/results';
1
+ import { Result } from '@expo/results';
2
2
 
3
3
  import { EntityCompanionDefinition } from './EntityCompanionProvider';
4
4
  import { CreateMutator, UpdateMutator } from './EntityMutator';
@@ -29,7 +29,7 @@ export default abstract class Entity<
29
29
  TFields extends object,
30
30
  TID extends NonNullable<TFields[TSelectedFields]>,
31
31
  TViewerContext extends ViewerContext,
32
- TSelectedFields extends keyof TFields = keyof TFields
32
+ TSelectedFields extends keyof TFields = keyof TFields,
33
33
  > extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields> {
34
34
  /**
35
35
  * Vend mutator for creating a new entity in given query context.
@@ -50,7 +50,7 @@ export default abstract class Entity<
50
50
  TMEntity,
51
51
  TMSelectedFields
52
52
  >,
53
- TMSelectedFields extends keyof TMFields = keyof TMFields
53
+ TMSelectedFields extends keyof TMFields = keyof TMFields,
54
54
  >(
55
55
  this: IEntityClass<
56
56
  TMFields,
@@ -64,7 +64,7 @@ export default abstract class Entity<
64
64
  queryContext: EntityQueryContext = viewerContext
65
65
  .getViewerScopedEntityCompanionForClass(this)
66
66
  .getQueryContextProvider()
67
- .getQueryContext()
67
+ .getQueryContext(),
68
68
  ): CreateMutator<TMFields, TMID, TMViewerContext, TMEntity, TMPrivacyPolicy, TMSelectedFields> {
69
69
  return viewerContext
70
70
  .getViewerScopedEntityCompanionForClass(this)
@@ -90,7 +90,7 @@ export default abstract class Entity<
90
90
  TMEntity,
91
91
  TMSelectedFields
92
92
  >,
93
- TMSelectedFields extends keyof TMFields = keyof TMFields
93
+ TMSelectedFields extends keyof TMFields = keyof TMFields,
94
94
  >(
95
95
  this: IEntityClass<
96
96
  TMFields,
@@ -105,7 +105,7 @@ export default abstract class Entity<
105
105
  .getViewerContext()
106
106
  .getViewerScopedEntityCompanionForClass(this)
107
107
  .getQueryContextProvider()
108
- .getQueryContext()
108
+ .getQueryContext(),
109
109
  ): UpdateMutator<TMFields, TMID, TMViewerContext, TMEntity, TMPrivacyPolicy, TMSelectedFields> {
110
110
  return existingEntity
111
111
  .getViewerContext()
@@ -131,7 +131,7 @@ export default abstract class Entity<
131
131
  TMEntity,
132
132
  TMSelectedFields
133
133
  >,
134
- TMSelectedFields extends keyof TMFields = keyof TMFields
134
+ TMSelectedFields extends keyof TMFields = keyof TMFields,
135
135
  >(
136
136
  this: IEntityClass<
137
137
  TMFields,
@@ -146,7 +146,7 @@ export default abstract class Entity<
146
146
  .getViewerContext()
147
147
  .getViewerScopedEntityCompanionForClass(this)
148
148
  .getQueryContextProvider()
149
- .getQueryContext()
149
+ .getQueryContext(),
150
150
  ): Promise<Result<void>> {
151
151
  return existingEntity
152
152
  .getViewerContext()
@@ -173,7 +173,7 @@ export default abstract class Entity<
173
173
  TMEntity,
174
174
  TMSelectedFields
175
175
  >,
176
- TMSelectedFields extends keyof TMFields = keyof TMFields
176
+ TMSelectedFields extends keyof TMFields = keyof TMFields,
177
177
  >(
178
178
  this: IEntityClass<
179
179
  TMFields,
@@ -188,7 +188,7 @@ export default abstract class Entity<
188
188
  .getViewerContext()
189
189
  .getViewerScopedEntityCompanionForClass(this)
190
190
  .getQueryContextProvider()
191
- .getQueryContext()
191
+ .getQueryContext(),
192
192
  ): Promise<void> {
193
193
  return existingEntity
194
194
  .getViewerContext()
@@ -197,121 +197,6 @@ export default abstract class Entity<
197
197
  .forDelete(existingEntity, queryContext)
198
198
  .enforceDeleteAsync();
199
199
  }
200
-
201
- /**
202
- * Check whether an entity loaded by a viewer can be updated by that same viewer.
203
- *
204
- * @remarks
205
- *
206
- * This may be useful in situations relying upon the thrown privacy policy thrown authorization error
207
- * is insufficient for the task at hand. When dealing with purely a sequence of mutations it is easy
208
- * to roll back all mutations given a single authorization error by wrapping them in a single transaction.
209
- * When certain portions of a mutation cannot be rolled back transactionally (third pary calls,
210
- * legacy code, etc), using this method can help decide whether the sequence of mutations will fail before
211
- * attempting them. Note that if any privacy policy rules use a piece of data being updated in the mutations
212
- * the result of this method and the update mutation itself may differ.
213
- *
214
- * @param existingEntity - entity loaded by viewer
215
- * @param queryContext - query context in which to perform the check
216
- */
217
- static async canViewerUpdateAsync<
218
- TMFields extends object,
219
- TMID extends NonNullable<TMFields[TMSelectedFields]>,
220
- TMViewerContext extends ViewerContext,
221
- TMEntity extends Entity<TMFields, TMID, TMViewerContext, TMSelectedFields>,
222
- TMPrivacyPolicy extends EntityPrivacyPolicy<
223
- TMFields,
224
- TMID,
225
- TMViewerContext,
226
- TMEntity,
227
- TMSelectedFields
228
- >,
229
- TMSelectedFields extends keyof TMFields = keyof TMFields
230
- >(
231
- this: IEntityClass<
232
- TMFields,
233
- TMID,
234
- TMViewerContext,
235
- TMEntity,
236
- TMPrivacyPolicy,
237
- TMSelectedFields
238
- >,
239
- existingEntity: TMEntity,
240
- queryContext: EntityQueryContext = existingEntity
241
- .getViewerContext()
242
- .getViewerScopedEntityCompanionForClass(this)
243
- .getQueryContextProvider()
244
- .getQueryContext()
245
- ): Promise<boolean> {
246
- const companion = existingEntity
247
- .getViewerContext()
248
- .getViewerScopedEntityCompanionForClass(this);
249
- const privacyPolicy = companion.entityCompanion.privacyPolicy;
250
- const evaluationResult = await asyncResult(
251
- privacyPolicy.authorizeUpdateAsync(
252
- existingEntity.getViewerContext(),
253
- queryContext,
254
- { cascadingDeleteCause: null },
255
- existingEntity,
256
- companion.getMetricsAdapter()
257
- )
258
- );
259
- return evaluationResult.ok;
260
- }
261
-
262
- /**
263
- * Check whether an entity loaded by a viewer can be deleted by that same viewer.
264
- *
265
- * @remarks
266
- * See remarks for canViewerUpdate.
267
- *
268
- * @param existingEntity - entity loaded by viewer
269
- * @param queryContext - query context in which to perform the check
270
- */
271
- static async canViewerDeleteAsync<
272
- TMFields extends object,
273
- TMID extends NonNullable<TMFields[TMSelectedFields]>,
274
- TMViewerContext extends ViewerContext,
275
- TMEntity extends Entity<TMFields, TMID, TMViewerContext, TMSelectedFields>,
276
- TMPrivacyPolicy extends EntityPrivacyPolicy<
277
- TMFields,
278
- TMID,
279
- TMViewerContext,
280
- TMEntity,
281
- TMSelectedFields
282
- >,
283
- TMSelectedFields extends keyof TMFields = keyof TMFields
284
- >(
285
- this: IEntityClass<
286
- TMFields,
287
- TMID,
288
- TMViewerContext,
289
- TMEntity,
290
- TMPrivacyPolicy,
291
- TMSelectedFields
292
- >,
293
- existingEntity: TMEntity,
294
- queryContext: EntityQueryContext = existingEntity
295
- .getViewerContext()
296
- .getViewerScopedEntityCompanionForClass(this)
297
- .getQueryContextProvider()
298
- .getQueryContext()
299
- ): Promise<boolean> {
300
- const companion = existingEntity
301
- .getViewerContext()
302
- .getViewerScopedEntityCompanionForClass(this);
303
- const privacyPolicy = companion.entityCompanion.privacyPolicy;
304
- const evaluationResult = await asyncResult(
305
- privacyPolicy.authorizeDeleteAsync(
306
- existingEntity.getViewerContext(),
307
- queryContext,
308
- { cascadingDeleteCause: null },
309
- existingEntity,
310
- companion.getMetricsAdapter()
311
- )
312
- );
313
- return evaluationResult.ok;
314
- }
315
200
  }
316
201
 
317
202
  /**
@@ -329,7 +214,7 @@ export interface IEntityClass<
329
214
  TEntity,
330
215
  TSelectedFields
331
216
  >,
332
- TSelectedFields extends keyof TFields = keyof TFields
217
+ TSelectedFields extends keyof TFields = keyof TFields,
333
218
  > {
334
219
  new (constructorParam: {
335
220
  viewerContext: TViewerContext;
@@ -16,7 +16,7 @@ export default class EntityAssociationLoader<
16
16
  TID extends NonNullable<TFields[TSelectedFields]>,
17
17
  TViewerContext extends ViewerContext,
18
18
  TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>,
19
- TSelectedFields extends keyof TFields
19
+ TSelectedFields extends keyof TFields,
20
20
  > {
21
21
  constructor(private readonly entity: TEntity) {}
22
22
 
@@ -44,7 +44,7 @@ export default class EntityAssociationLoader<
44
44
  TAssociatedEntity,
45
45
  TAssociatedSelectedFields
46
46
  >,
47
- TAssociatedSelectedFields extends keyof TAssociatedFields = keyof TAssociatedFields
47
+ TAssociatedSelectedFields extends keyof TAssociatedFields = keyof TAssociatedFields,
48
48
  >(
49
49
  fieldIdentifyingAssociatedEntity: TIdentifyingField,
50
50
  associatedEntityClass: IEntityClass<
@@ -59,7 +59,7 @@ export default class EntityAssociationLoader<
59
59
  .getViewerContext()
60
60
  .getViewerScopedEntityCompanionForClass(associatedEntityClass)
61
61
  .getQueryContextProvider()
62
- .getQueryContext()
62
+ .getQueryContext(),
63
63
  ): Promise<
64
64
  Result<null extends TFields[TIdentifyingField] ? TAssociatedEntity | null : TAssociatedEntity>
65
65
  > {
@@ -74,9 +74,11 @@ export default class EntityAssociationLoader<
74
74
  .getViewerContext()
75
75
  .getViewerScopedEntityCompanionForClass(associatedEntityClass)
76
76
  .getLoaderFactory()
77
- .forLoad(queryContext, { cascadingDeleteCause: null });
77
+ .forLoad(queryContext, { previousValue: null, cascadingDeleteCause: null });
78
78
 
79
- return (await loader.loadByIDAsync(associatedEntityID as unknown as TAssociatedID)) as Result<
79
+ return (await loader
80
+ .withAuthorizationResults()
81
+ .loadByIDAsync(associatedEntityID as unknown as TAssociatedID)) as Result<
80
82
  null extends TFields[TIdentifyingField] ? TAssociatedEntity | null : TAssociatedEntity
81
83
  >;
82
84
  }
@@ -106,7 +108,7 @@ export default class EntityAssociationLoader<
106
108
  TAssociatedEntity,
107
109
  TAssociatedSelectedFields
108
110
  >,
109
- TAssociatedSelectedFields extends keyof TAssociatedFields = keyof TAssociatedFields
111
+ TAssociatedSelectedFields extends keyof TAssociatedFields = keyof TAssociatedFields,
110
112
  >(
111
113
  associatedEntityClass: IEntityClass<
112
114
  TAssociatedFields,
@@ -121,18 +123,17 @@ export default class EntityAssociationLoader<
121
123
  .getViewerContext()
122
124
  .getViewerScopedEntityCompanionForClass(associatedEntityClass)
123
125
  .getQueryContextProvider()
124
- .getQueryContext()
126
+ .getQueryContext(),
125
127
  ): Promise<readonly Result<TAssociatedEntity>[]> {
126
128
  const thisID = this.entity.getID();
127
129
  const loader = this.entity
128
130
  .getViewerContext()
129
131
  .getViewerScopedEntityCompanionForClass(associatedEntityClass)
130
132
  .getLoaderFactory()
131
- .forLoad(queryContext, { cascadingDeleteCause: null });
132
- return await loader.loadManyByFieldEqualingAsync(
133
- associatedEntityFieldContainingThisID,
134
- thisID as any
135
- );
133
+ .forLoad(queryContext, { previousValue: null, cascadingDeleteCause: null });
134
+ return await loader
135
+ .withAuthorizationResults()
136
+ .loadManyByFieldEqualingAsync(associatedEntityFieldContainingThisID, thisID as any);
136
137
  }
137
138
 
138
139
  /**
@@ -159,7 +160,7 @@ export default class EntityAssociationLoader<
159
160
  TAssociatedEntity,
160
161
  TAssociatedSelectedFields
161
162
  >,
162
- TAssociatedSelectedFields extends keyof TAssociatedFields = keyof TAssociatedFields
163
+ TAssociatedSelectedFields extends keyof TAssociatedFields = keyof TAssociatedFields,
163
164
  >(
164
165
  fieldIdentifyingAssociatedEntity: keyof Pick<TFields, TSelectedFields>,
165
166
  associatedEntityClass: IEntityClass<
@@ -175,7 +176,7 @@ export default class EntityAssociationLoader<
175
176
  .getViewerContext()
176
177
  .getViewerScopedEntityCompanionForClass(associatedEntityClass)
177
178
  .getQueryContextProvider()
178
- .getQueryContext()
179
+ .getQueryContext(),
179
180
  ): Promise<Result<TAssociatedEntity> | null> {
180
181
  const associatedFieldValue = this.entity.getField(fieldIdentifyingAssociatedEntity);
181
182
  if (!associatedFieldValue) {
@@ -185,11 +186,10 @@ export default class EntityAssociationLoader<
185
186
  .getViewerContext()
186
187
  .getViewerScopedEntityCompanionForClass(associatedEntityClass)
187
188
  .getLoaderFactory()
188
- .forLoad(queryContext, { cascadingDeleteCause: null });
189
- return await loader.loadByFieldEqualingAsync(
190
- associatedEntityLookupByField,
191
- associatedFieldValue as any
192
- );
189
+ .forLoad(queryContext, { previousValue: null, cascadingDeleteCause: null });
190
+ return await loader
191
+ .withAuthorizationResults()
192
+ .loadByFieldEqualingAsync(associatedEntityLookupByField, associatedFieldValue as any);
193
193
  }
194
194
 
195
195
  /**
@@ -216,7 +216,7 @@ export default class EntityAssociationLoader<
216
216
  TAssociatedEntity,
217
217
  TAssociatedSelectedFields
218
218
  >,
219
- TAssociatedSelectedFields extends keyof TAssociatedFields = keyof TAssociatedFields
219
+ TAssociatedSelectedFields extends keyof TAssociatedFields = keyof TAssociatedFields,
220
220
  >(
221
221
  fieldIdentifyingAssociatedEntity: keyof Pick<TFields, TSelectedFields>,
222
222
  associatedEntityClass: IEntityClass<
@@ -232,7 +232,7 @@ export default class EntityAssociationLoader<
232
232
  .getViewerContext()
233
233
  .getViewerScopedEntityCompanionForClass(associatedEntityClass)
234
234
  .getQueryContextProvider()
235
- .getQueryContext()
235
+ .getQueryContext(),
236
236
  ): Promise<readonly Result<TAssociatedEntity>[]> {
237
237
  const associatedFieldValue = this.entity.getField(fieldIdentifyingAssociatedEntity);
238
238
  if (!associatedFieldValue) {
@@ -243,11 +243,10 @@ export default class EntityAssociationLoader<
243
243
  .getViewerContext()
244
244
  .getViewerScopedEntityCompanionForClass(associatedEntityClass)
245
245
  .getLoaderFactory()
246
- .forLoad(queryContext, { cascadingDeleteCause: null });
247
- return await loader.loadManyByFieldEqualingAsync(
248
- associatedEntityLookupByField,
249
- associatedFieldValue as any
250
- );
246
+ .forLoad(queryContext, { previousValue: null, cascadingDeleteCause: null });
247
+ return await loader
248
+ .withAuthorizationResults()
249
+ .loadManyByFieldEqualingAsync(associatedEntityLookupByField, associatedFieldValue as any);
251
250
  }
252
251
 
253
252
  /**
@@ -267,7 +266,7 @@ export default class EntityAssociationLoader<
267
266
  TEntity2,
268
267
  TSelectedFields2
269
268
  >,
270
- TSelectedFields2 extends keyof TFields2 = keyof TFields2
269
+ TSelectedFields2 extends keyof TFields2 = keyof TFields2,
271
270
  >(
272
271
  loadDirectives: [
273
272
  EntityLoadThroughDirective<
@@ -279,9 +278,9 @@ export default class EntityAssociationLoader<
279
278
  TPrivacyPolicy2,
280
279
  TSelectedFields,
281
280
  TSelectedFields2
282
- >
281
+ >,
283
282
  ],
284
- queryContext?: EntityQueryContext
283
+ queryContext?: EntityQueryContext,
285
284
  ): Promise<Result<TEntity2> | null>;
286
285
 
287
286
  /**
@@ -312,7 +311,7 @@ export default class EntityAssociationLoader<
312
311
  TSelectedFields3
313
312
  >,
314
313
  TSelectedFields2 extends keyof TFields2 = keyof TFields2,
315
- TSelectedFields3 extends keyof TFields3 = keyof TFields3
314
+ TSelectedFields3 extends keyof TFields3 = keyof TFields3,
316
315
  >(
317
316
  loadDirectives: [
318
317
  EntityLoadThroughDirective<
@@ -334,9 +333,9 @@ export default class EntityAssociationLoader<
334
333
  TPrivacyPolicy3,
335
334
  TSelectedFields2,
336
335
  TSelectedFields3
337
- >
336
+ >,
338
337
  ],
339
- queryContext?: EntityQueryContext
338
+ queryContext?: EntityQueryContext,
340
339
  ): Promise<Result<TEntity3> | null>;
341
340
 
342
341
  /**
@@ -378,9 +377,9 @@ export default class EntityAssociationLoader<
378
377
  >,
379
378
  TSelectedFields2 extends keyof TFields2 = keyof TFields2,
380
379
  TSelectedFields3 extends keyof TFields3 = keyof TFields3,
381
- TSelectedFields4 extends keyof TFields4 = keyof TFields4
380
+ TSelectedFields4 extends keyof TFields4 = keyof TFields4,
382
381
  >(
383
- loadDirective: [
382
+ loadDirectives: [
384
383
  EntityLoadThroughDirective<
385
384
  TViewerContext,
386
385
  TFields,
@@ -410,9 +409,9 @@ export default class EntityAssociationLoader<
410
409
  TPrivacyPolicy4,
411
410
  TSelectedFields3,
412
411
  TSelectedFields4
413
- >
412
+ >,
414
413
  ],
415
- queryContext?: EntityQueryContext
414
+ queryContext?: EntityQueryContext,
416
415
  ): Promise<Result<TEntity4> | null>;
417
416
 
418
417
  /**
@@ -423,12 +422,12 @@ export default class EntityAssociationLoader<
423
422
  */
424
423
  async loadAssociatedEntityThroughAsync(
425
424
  loadDirectives: EntityLoadThroughDirective<TViewerContext, any, any, any, any, any, any, any>[],
426
- queryContext?: EntityQueryContext
425
+ queryContext?: EntityQueryContext,
427
426
  ): Promise<Result<ReadonlyEntity<any, any, any, any>> | null>;
428
427
 
429
428
  async loadAssociatedEntityThroughAsync(
430
429
  loadDirectives: EntityLoadThroughDirective<TViewerContext, any, any, any, any, any, any, any>[],
431
- queryContext?: EntityQueryContext
430
+ queryContext?: EntityQueryContext,
432
431
  ): Promise<Result<ReadonlyEntity<any, any, any, any>> | null> {
433
432
  let currentEntity: ReadonlyEntity<any, any, any, any> = this.entity;
434
433
  for (const loadDirective of loadDirectives) {
@@ -445,7 +444,7 @@ export default class EntityAssociationLoader<
445
444
  fieldIdentifyingAssociatedEntity,
446
445
  associatedEntityClass,
447
446
  associatedEntityLookupByField,
448
- queryContext
447
+ queryContext,
449
448
  );
450
449
  } else {
451
450
  const associatedEntityResultLocal = await currentEntity
@@ -453,7 +452,7 @@ export default class EntityAssociationLoader<
453
452
  .loadAssociatedEntityAsync(
454
453
  fieldIdentifyingAssociatedEntity,
455
454
  associatedEntityClass,
456
- queryContext
455
+ queryContext,
457
456
  );
458
457
 
459
458
  if (associatedEntityResultLocal.ok && associatedEntityResultLocal.value === null) {
@@ -498,7 +497,7 @@ export interface EntityLoadThroughDirective<
498
497
  TAssociatedSelectedFields
499
498
  >,
500
499
  TSelectedFields extends keyof TFields = keyof TFields,
501
- TAssociatedSelectedFields extends keyof TAssociatedFields = keyof TAssociatedFields
500
+ TAssociatedSelectedFields extends keyof TAssociatedFields = keyof TAssociatedFields,
502
501
  > {
503
502
  /**
504
503
  * Class of entity to load at this step.
@@ -7,6 +7,7 @@ import ReadonlyEntity from './ReadonlyEntity';
7
7
  import ViewerContext from './ViewerContext';
8
8
  import EntityTableDataCoordinator from './internal/EntityTableDataCoordinator';
9
9
  import IEntityMetricsAdapter from './metrics/IEntityMetricsAdapter';
10
+ import { mergeEntityMutationTriggerConfigurations } from './utils/mergeEntityMutationTriggerConfigurations';
10
11
 
11
12
  export interface IPrivacyPolicyClass<TPrivacyPolicy> {
12
13
  new (): TPrivacyPolicy;
@@ -27,7 +28,7 @@ export default class EntityCompanion<
27
28
  TEntity,
28
29
  TSelectedFields
29
30
  >,
30
- TSelectedFields extends keyof TFields
31
+ TSelectedFields extends keyof TFields,
31
32
  > {
32
33
  public readonly privacyPolicy: TPrivacyPolicy;
33
34
 
@@ -59,7 +60,7 @@ export default class EntityCompanion<
59
60
  TSelectedFields
60
61
  >,
61
62
  private readonly tableDataCoordinator: EntityTableDataCoordinator<TFields>,
62
- private readonly metricsAdapter: IEntityMetricsAdapter
63
+ private readonly metricsAdapter: IEntityMetricsAdapter,
63
64
  ) {
64
65
  this.privacyPolicy = new entityCompanionDefinition.privacyPolicyClass();
65
66
  this.entityLoaderFactory = new EntityLoaderFactory<
@@ -76,10 +77,13 @@ export default class EntityCompanion<
76
77
  entityCompanionDefinition.entityClass,
77
78
  this.privacyPolicy,
78
79
  entityCompanionDefinition.mutationValidators ?? [],
79
- entityCompanionDefinition.mutationTriggers ?? {},
80
+ mergeEntityMutationTriggerConfigurations(
81
+ entityCompanionDefinition.mutationTriggers ?? {},
82
+ entityCompanionProvider.globalMutationTriggers ?? {},
83
+ ),
80
84
  this.entityLoaderFactory,
81
85
  tableDataCoordinator.databaseAdapter,
82
- metricsAdapter
86
+ metricsAdapter,
83
87
  );
84
88
  }
85
89