@expo/entity 0.38.0 → 0.40.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 (206) hide show
  1. package/build/AuthorizationResultBasedEntityAssociationLoader.d.ts +99 -0
  2. package/build/AuthorizationResultBasedEntityAssociationLoader.js +124 -0
  3. package/build/AuthorizationResultBasedEntityAssociationLoader.js.map +1 -0
  4. package/build/AuthorizationResultBasedEntityLoader.d.ts +1 -1
  5. package/build/AuthorizationResultBasedEntityLoader.js.map +1 -1
  6. package/build/{EntityMutator.d.ts → AuthorizationResultBasedEntityMutator.d.ts} +5 -17
  7. package/build/{EntityMutator.js → AuthorizationResultBasedEntityMutator.js} +22 -48
  8. package/build/AuthorizationResultBasedEntityMutator.js.map +1 -0
  9. package/build/EnforcingEntityAssociationLoader.d.ts +79 -0
  10. package/build/EnforcingEntityAssociationLoader.js +62 -0
  11. package/build/EnforcingEntityAssociationLoader.js.map +1 -0
  12. package/build/EnforcingEntityCreator.d.ts +24 -0
  13. package/build/EnforcingEntityCreator.js +32 -0
  14. package/build/EnforcingEntityCreator.js.map +1 -0
  15. package/build/EnforcingEntityDeleter.d.ts +17 -0
  16. package/build/EnforcingEntityDeleter.js +22 -0
  17. package/build/EnforcingEntityDeleter.js.map +1 -0
  18. package/build/EnforcingEntityUpdater.d.ts +24 -0
  19. package/build/EnforcingEntityUpdater.js +32 -0
  20. package/build/EnforcingEntityUpdater.js.map +1 -0
  21. package/build/Entity.d.ts +8 -12
  22. package/build/Entity.js +9 -34
  23. package/build/Entity.js.map +1 -1
  24. package/build/EntityAssociationLoader.d.ts +12 -91
  25. package/build/EntityAssociationLoader.js +20 -126
  26. package/build/EntityAssociationLoader.js.map +1 -1
  27. package/build/EntityCompanionProvider.d.ts +2 -2
  28. package/build/EntityCompanionProvider.js.map +1 -1
  29. package/build/EntityCreator.d.ts +27 -0
  30. package/build/EntityCreator.js +39 -0
  31. package/build/EntityCreator.js.map +1 -0
  32. package/build/EntityDatabaseAdapter.js +2 -2
  33. package/build/EntityDatabaseAdapter.js.map +1 -1
  34. package/build/EntityDeleter.d.ts +27 -0
  35. package/build/EntityDeleter.js +40 -0
  36. package/build/EntityDeleter.js.map +1 -0
  37. package/build/EntityLoader.d.ts +4 -14
  38. package/build/EntityLoader.js +7 -20
  39. package/build/EntityLoader.js.map +1 -1
  40. package/build/EntityLoaderFactory.d.ts +2 -2
  41. package/build/EntityLoaderFactory.js +4 -2
  42. package/build/EntityLoaderFactory.js.map +1 -1
  43. package/build/EntityMutatorFactory.d.ts +4 -4
  44. package/build/EntityMutatorFactory.js +4 -4
  45. package/build/EntityMutatorFactory.js.map +1 -1
  46. package/build/EntitySecondaryCacheLoader.d.ts +3 -3
  47. package/build/EntitySecondaryCacheLoader.js +1 -3
  48. package/build/EntitySecondaryCacheLoader.js.map +1 -1
  49. package/build/EntityUpdater.d.ts +27 -0
  50. package/build/EntityUpdater.js +40 -0
  51. package/build/EntityUpdater.js.map +1 -0
  52. package/build/ReadonlyEntity.d.ts +2 -2
  53. package/build/ReadonlyEntity.js +4 -6
  54. package/build/ReadonlyEntity.js.map +1 -1
  55. package/build/ViewerScopedEntityLoaderFactory.d.ts +2 -2
  56. package/build/ViewerScopedEntityLoaderFactory.js.map +1 -1
  57. package/build/ViewerScopedEntityMutatorFactory.d.ts +4 -4
  58. package/build/ViewerScopedEntityMutatorFactory.js.map +1 -1
  59. package/build/__tests__/AuthorizationResultBasedEntityAssociationLoader-test.d.ts +1 -0
  60. package/build/__tests__/AuthorizationResultBasedEntityAssociationLoader-test.js +273 -0
  61. package/build/__tests__/AuthorizationResultBasedEntityAssociationLoader-test.js.map +1 -0
  62. package/build/__tests__/{EntityLoader-constructor-test.js → AuthorizationResultBasedEntityLoader-constructor-test.js} +11 -11
  63. package/build/__tests__/AuthorizationResultBasedEntityLoader-constructor-test.js.map +1 -0
  64. package/build/__tests__/AuthorizationResultBasedEntityLoader-test.d.ts +1 -0
  65. package/build/__tests__/AuthorizationResultBasedEntityLoader-test.js +401 -0
  66. package/build/__tests__/AuthorizationResultBasedEntityLoader-test.js.map +1 -0
  67. package/build/__tests__/EnforcingEntityAssociationLoader-test.d.ts +1 -0
  68. package/build/__tests__/EnforcingEntityAssociationLoader-test.js +115 -0
  69. package/build/__tests__/EnforcingEntityAssociationLoader-test.js.map +1 -0
  70. package/build/__tests__/Entity-test.js +23 -5
  71. package/build/__tests__/Entity-test.js.map +1 -1
  72. package/build/__tests__/EntityAssociationLoader-test.js +14 -184
  73. package/build/__tests__/EntityAssociationLoader-test.js.map +1 -1
  74. package/build/__tests__/EntityCommonUseCases-test.js +34 -12
  75. package/build/__tests__/EntityCommonUseCases-test.js.map +1 -1
  76. package/build/__tests__/EntityCompanion-test.js +17 -7
  77. package/build/__tests__/EntityCompanion-test.js.map +1 -1
  78. package/build/__tests__/EntityDatabaseAdapter-test.js.map +1 -1
  79. package/build/__tests__/EntityEdges-test.js +41 -23
  80. package/build/__tests__/EntityEdges-test.js.map +1 -1
  81. package/build/__tests__/EntityLoader-test.js +22 -386
  82. package/build/__tests__/EntityLoader-test.js.map +1 -1
  83. package/build/__tests__/EntityMutator-MutationCacheConsistency-test.js +4 -3
  84. package/build/__tests__/EntityMutator-MutationCacheConsistency-test.js.map +1 -1
  85. package/build/__tests__/EntityMutator-test.js +67 -70
  86. package/build/__tests__/EntityMutator-test.js.map +1 -1
  87. package/build/__tests__/EntityPrivacyPolicy-test.js +17 -7
  88. package/build/__tests__/EntityPrivacyPolicy-test.js.map +1 -1
  89. package/build/__tests__/EntitySecondaryCacheLoader-test.js +7 -7
  90. package/build/__tests__/EntitySecondaryCacheLoader-test.js.map +1 -1
  91. package/build/__tests__/EntitySelfReferentialEdges-test.js +36 -24
  92. package/build/__tests__/EntitySelfReferentialEdges-test.js.map +1 -1
  93. package/build/__tests__/ReadonlyEntity-test.js +1 -1
  94. package/build/__tests__/ReadonlyEntity-test.js.map +1 -1
  95. package/build/__tests__/cases/TwoEntitySameTableDisjointRows-test.js +4 -2
  96. package/build/__tests__/cases/TwoEntitySameTableDisjointRows-test.js.map +1 -1
  97. package/build/__tests__/cases/TwoEntitySameTableOverlappingRows-test.js +7 -4
  98. package/build/__tests__/cases/TwoEntitySameTableOverlappingRows-test.js.map +1 -1
  99. package/build/__tests__/entityUtils-test.js +8 -0
  100. package/build/__tests__/entityUtils-test.js.map +1 -1
  101. package/build/entityUtils.d.ts +7 -0
  102. package/build/entityUtils.js +20 -10
  103. package/build/entityUtils.js.map +1 -1
  104. package/build/errors/EntityCacheAdapterError.js +17 -7
  105. package/build/errors/EntityCacheAdapterError.js.map +1 -1
  106. package/build/errors/EntityDatabaseAdapterError.js +17 -7
  107. package/build/errors/EntityDatabaseAdapterError.js.map +1 -1
  108. package/build/errors/EntityInvalidFieldValueError.js +17 -7
  109. package/build/errors/EntityInvalidFieldValueError.js.map +1 -1
  110. package/build/errors/EntityNotAuthorizedError.js +17 -7
  111. package/build/errors/EntityNotAuthorizedError.js.map +1 -1
  112. package/build/errors/EntityNotFoundError.js +17 -7
  113. package/build/errors/EntityNotFoundError.js.map +1 -1
  114. package/build/index.d.ts +19 -11
  115. package/build/index.js +24 -7
  116. package/build/index.js.map +1 -1
  117. package/build/internal/EntityFieldTransformationUtils.js.map +1 -1
  118. package/build/internal/__tests__/EntityDataManager-test.js +42 -32
  119. package/build/internal/__tests__/EntityDataManager-test.js.map +1 -1
  120. package/build/internal/__tests__/ReadThroughEntityCache-test.js +17 -7
  121. package/build/internal/__tests__/ReadThroughEntityCache-test.js.map +1 -1
  122. package/build/rules/AlwaysAllowPrivacyPolicyRule.js +17 -7
  123. package/build/rules/AlwaysAllowPrivacyPolicyRule.js.map +1 -1
  124. package/build/rules/AlwaysDenyPrivacyPolicyRule.js +17 -7
  125. package/build/rules/AlwaysDenyPrivacyPolicyRule.js.map +1 -1
  126. package/build/rules/AlwaysSkipPrivacyPolicyRule.js +17 -7
  127. package/build/rules/AlwaysSkipPrivacyPolicyRule.js.map +1 -1
  128. package/build/utils/EntityPrivacyUtils.d.ts +32 -4
  129. package/build/utils/EntityPrivacyUtils.js +68 -24
  130. package/build/utils/EntityPrivacyUtils.js.map +1 -1
  131. package/build/utils/__tests__/EntityPrivacyUtils-test.js +148 -23
  132. package/build/utils/__tests__/EntityPrivacyUtils-test.js.map +1 -1
  133. package/build/utils/__tests__/canViewerDeleteAsync-edgeDeletionPermissionInferenceBehavior-test.js +8 -5
  134. package/build/utils/__tests__/canViewerDeleteAsync-edgeDeletionPermissionInferenceBehavior-test.js.map +1 -1
  135. package/build/utils/collections/__tests__/maps-test.js +1 -1
  136. package/build/utils/collections/__tests__/maps-test.js.map +1 -1
  137. package/build/utils/collections/maps.js +2 -2
  138. package/build/utils/collections/maps.js.map +1 -1
  139. package/build/utils/mergeEntityMutationTriggerConfigurations.js +1 -2
  140. package/build/utils/mergeEntityMutationTriggerConfigurations.js.map +1 -1
  141. package/build/utils/testing/PrivacyPolicyRuleTestUtils.js +1 -1
  142. package/build/utils/testing/PrivacyPolicyRuleTestUtils.js.map +1 -1
  143. package/build/utils/testing/StubDatabaseAdapter.js +17 -7
  144. package/build/utils/testing/StubDatabaseAdapter.js.map +1 -1
  145. package/build/utils/testing/StubQueryContextProvider.d.ts +1 -3
  146. package/build/utils/testing/StubQueryContextProvider.js +1 -3
  147. package/build/utils/testing/StubQueryContextProvider.js.map +1 -1
  148. package/build/utils/testing/createUnitTestEntityCompanionProvider.js +2 -1
  149. package/build/utils/testing/createUnitTestEntityCompanionProvider.js.map +1 -1
  150. package/build/utils/testing/describeFieldTestCase.js +1 -1
  151. package/build/utils/testing/describeFieldTestCase.js.map +1 -1
  152. package/package.json +19 -3
  153. package/src/AuthorizationResultBasedEntityAssociationLoader.ts +492 -0
  154. package/src/AuthorizationResultBasedEntityLoader.ts +2 -2
  155. package/src/{EntityMutator.ts → AuthorizationResultBasedEntityMutator.ts} +62 -58
  156. package/src/EnforcingEntityAssociationLoader.ts +390 -0
  157. package/src/EnforcingEntityCreator.ts +55 -0
  158. package/src/EnforcingEntityDeleter.ts +44 -0
  159. package/src/EnforcingEntityUpdater.ts +55 -0
  160. package/src/Entity.ts +20 -65
  161. package/src/EntityAssociationLoader.ts +38 -495
  162. package/src/EntityCompanionProvider.ts +5 -2
  163. package/src/EntityCreator.ts +73 -0
  164. package/src/EntityDeleter.ts +73 -0
  165. package/src/EntityLoader.ts +10 -49
  166. package/src/EntityLoaderFactory.ts +20 -3
  167. package/src/EntityMutatorFactory.ts +32 -7
  168. package/src/EntitySecondaryCacheLoader.ts +5 -7
  169. package/src/EntityUpdater.ts +73 -0
  170. package/src/ReadonlyEntity.ts +14 -13
  171. package/src/ViewerScopedEntityLoaderFactory.ts +9 -2
  172. package/src/ViewerScopedEntityMutatorFactory.ts +29 -4
  173. package/src/__tests__/AuthorizationResultBasedEntityAssociationLoader-test.ts +354 -0
  174. package/src/__tests__/{EntityLoader-constructor-test.ts → AuthorizationResultBasedEntityLoader-constructor-test.ts} +17 -10
  175. package/src/__tests__/AuthorizationResultBasedEntityLoader-test.ts +730 -0
  176. package/src/__tests__/EnforcingEntityAssociationLoader-test.ts +253 -0
  177. package/src/__tests__/Entity-test.ts +24 -5
  178. package/src/__tests__/EntityAssociationLoader-test.ts +16 -259
  179. package/src/__tests__/EntityCommonUseCases-test.ts +20 -8
  180. package/src/__tests__/EntityCompanion-test.ts +1 -1
  181. package/src/__tests__/EntityDatabaseAdapter-test.ts +6 -6
  182. package/src/__tests__/EntityEdges-test.ts +24 -16
  183. package/src/__tests__/EntityLoader-test.ts +25 -675
  184. package/src/__tests__/EntityMutator-MutationCacheConsistency-test.ts +4 -3
  185. package/src/__tests__/EntityMutator-test.ts +116 -103
  186. package/src/__tests__/EntitySecondaryCacheLoader-test.ts +7 -7
  187. package/src/__tests__/EntitySelfReferentialEdges-test.ts +36 -24
  188. package/src/__tests__/ReadonlyEntity-test.ts +1 -1
  189. package/src/__tests__/cases/TwoEntitySameTableDisjointRows-test.ts +4 -2
  190. package/src/__tests__/cases/TwoEntitySameTableOverlappingRows-test.ts +7 -4
  191. package/src/__tests__/entityUtils-test.ts +12 -0
  192. package/src/entityUtils.ts +24 -9
  193. package/src/index.ts +19 -11
  194. package/src/internal/EntityFieldTransformationUtils.ts +2 -2
  195. package/src/internal/__tests__/EntityDataManager-test.ts +29 -29
  196. package/src/utils/EntityPrivacyUtils.ts +188 -107
  197. package/src/utils/__tests__/EntityPrivacyUtils-test.ts +169 -29
  198. package/src/utils/__tests__/canViewerDeleteAsync-edgeDeletionPermissionInferenceBehavior-test.ts +8 -5
  199. package/src/utils/collections/__tests__/maps-test.ts +1 -1
  200. package/src/utils/testing/PrivacyPolicyRuleTestUtils.ts +1 -1
  201. package/src/utils/testing/StubDatabaseAdapter.ts +1 -1
  202. package/src/utils/testing/StubQueryContextProvider.ts +1 -3
  203. package/src/utils/testing/createUnitTestEntityCompanionProvider.ts +3 -1
  204. package/build/EntityMutator.js.map +0 -1
  205. package/build/__tests__/EntityLoader-constructor-test.js.map +0 -1
  206. /package/build/__tests__/{EntityLoader-constructor-test.d.ts → AuthorizationResultBasedEntityLoader-constructor-test.d.ts} +0 -0
@@ -0,0 +1,73 @@
1
+ import { AuthorizationResultBasedDeleteMutator } from './AuthorizationResultBasedEntityMutator';
2
+ import EnforcingEntityDeleter from './EnforcingEntityDeleter';
3
+ import { IEntityClass } from './Entity';
4
+ import EntityPrivacyPolicy from './EntityPrivacyPolicy';
5
+ import { EntityQueryContext } from './EntityQueryContext';
6
+ import ReadonlyEntity from './ReadonlyEntity';
7
+ import ViewerContext from './ViewerContext';
8
+
9
+ /**
10
+ * The primary interface for deleting entities.
11
+ */
12
+ export default class EntityDeleter<
13
+ TFields extends object,
14
+ TID extends NonNullable<TFields[TSelectedFields]>,
15
+ TViewerContext extends ViewerContext,
16
+ TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>,
17
+ TPrivacyPolicy extends EntityPrivacyPolicy<
18
+ TFields,
19
+ TID,
20
+ TViewerContext,
21
+ TEntity,
22
+ TSelectedFields
23
+ >,
24
+ TSelectedFields extends keyof TFields,
25
+ > {
26
+ constructor(
27
+ private readonly existingEntity: TEntity,
28
+ private readonly queryContext: EntityQueryContext,
29
+ private readonly entityClass: IEntityClass<
30
+ TFields,
31
+ TID,
32
+ TViewerContext,
33
+ TEntity,
34
+ TPrivacyPolicy,
35
+ TSelectedFields
36
+ >,
37
+ ) {}
38
+
39
+ /**
40
+ * Enforcing entity deleter. All deletes through this deleter are
41
+ * guaranteed to be successful and will throw otherwise.
42
+ */
43
+ enforcing(): EnforcingEntityDeleter<
44
+ TFields,
45
+ TID,
46
+ TViewerContext,
47
+ TEntity,
48
+ TPrivacyPolicy,
49
+ TSelectedFields
50
+ > {
51
+ return new EnforcingEntityDeleter(this.withAuthorizationResults());
52
+ }
53
+
54
+ /**
55
+ * Authorization-result-based entity deleter. All deletes through this
56
+ * deleter are results, where an unsuccessful result means an authorization
57
+ * error or entity construction error occurred. Other errors are thrown.
58
+ */
59
+ withAuthorizationResults(): AuthorizationResultBasedDeleteMutator<
60
+ TFields,
61
+ TID,
62
+ TViewerContext,
63
+ TEntity,
64
+ TPrivacyPolicy,
65
+ TSelectedFields
66
+ > {
67
+ return this.existingEntity
68
+ .getViewerContext()
69
+ .getViewerScopedEntityCompanionForClass(this.entityClass)
70
+ .getMutatorFactory()
71
+ .forDelete(this.existingEntity, this.queryContext);
72
+ }
73
+ }
@@ -1,14 +1,11 @@
1
1
  import AuthorizationResultBasedEntityLoader from './AuthorizationResultBasedEntityLoader';
2
2
  import EnforcingEntityLoader from './EnforcingEntityLoader';
3
3
  import { IEntityClass } from './Entity';
4
- import EntityConfiguration from './EntityConfiguration';
5
4
  import EntityLoaderUtils from './EntityLoaderUtils';
6
- import EntityPrivacyPolicy, { EntityPrivacyPolicyEvaluationContext } from './EntityPrivacyPolicy';
5
+ import EntityPrivacyPolicy from './EntityPrivacyPolicy';
7
6
  import { EntityQueryContext } from './EntityQueryContext';
8
7
  import ReadonlyEntity from './ReadonlyEntity';
9
8
  import ViewerContext from './ViewerContext';
10
- import EntityDataManager from './internal/EntityDataManager';
11
- import IEntityMetricsAdapter from './metrics/IEntityMetricsAdapter';
12
9
 
13
10
  /**
14
11
  * The primary interface for loading entities. All normal loads are batched,
@@ -18,6 +15,7 @@ export default class EntityLoader<
18
15
  TFields extends object,
19
16
  TID extends NonNullable<TFields[TSelectedFields]>,
20
17
  TViewerContext extends ViewerContext,
18
+ TViewerContext2 extends TViewerContext,
21
19
  TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>,
22
20
  TPrivacyPolicy extends EntityPrivacyPolicy<
23
21
  TFields,
@@ -28,26 +26,9 @@ export default class EntityLoader<
28
26
  >,
29
27
  TSelectedFields extends keyof TFields,
30
28
  > {
31
- private readonly utilsPrivate: EntityLoaderUtils<
32
- TFields,
33
- TID,
34
- TViewerContext,
35
- TEntity,
36
- TPrivacyPolicy,
37
- TSelectedFields
38
- >;
39
-
40
29
  constructor(
41
- private readonly viewerContext: TViewerContext,
30
+ private readonly viewerContext: TViewerContext2,
42
31
  private readonly queryContext: EntityQueryContext,
43
- private readonly privacyPolicyEvaluationContext: EntityPrivacyPolicyEvaluationContext<
44
- TFields,
45
- TID,
46
- TViewerContext,
47
- TEntity,
48
- TSelectedFields
49
- >,
50
- private readonly entityConfiguration: EntityConfiguration<TFields>,
51
32
  private readonly entityClass: IEntityClass<
52
33
  TFields,
53
34
  TID,
@@ -56,23 +37,7 @@ export default class EntityLoader<
56
37
  TPrivacyPolicy,
57
38
  TSelectedFields
58
39
  >,
59
- private readonly entitySelectedFields: TSelectedFields[] | undefined,
60
- private readonly privacyPolicy: TPrivacyPolicy,
61
- private readonly dataManager: EntityDataManager<TFields>,
62
- protected readonly metricsAdapter: IEntityMetricsAdapter,
63
- ) {
64
- this.utilsPrivate = new EntityLoaderUtils(
65
- this.viewerContext,
66
- this.queryContext,
67
- this.privacyPolicyEvaluationContext,
68
- this.entityConfiguration,
69
- this.entityClass,
70
- this.entitySelectedFields,
71
- this.privacyPolicy,
72
- this.dataManager,
73
- this.metricsAdapter,
74
- );
75
- }
40
+ ) {}
76
41
 
77
42
  /**
78
43
  * Enforcing entity loader. All loads through this loader are
@@ -92,7 +57,7 @@ export default class EntityLoader<
92
57
 
93
58
  /**
94
59
  * Authorization-result-based entity loader. All loads through this
95
- * loader are are results (or null for some loader methods), where an unsuccessful result
60
+ * loader are results (or null for some loader methods), where an unsuccessful result
96
61
  * means an authorization error or entity construction error occurred. Other errors are thrown.
97
62
  */
98
63
  withAuthorizationResults(): AuthorizationResultBasedEntityLoader<
@@ -103,14 +68,10 @@ export default class EntityLoader<
103
68
  TPrivacyPolicy,
104
69
  TSelectedFields
105
70
  > {
106
- return new AuthorizationResultBasedEntityLoader(
107
- this.queryContext,
108
- this.entityConfiguration,
109
- this.entityClass,
110
- this.dataManager,
111
- this.metricsAdapter,
112
- this.utilsPrivate,
113
- );
71
+ return this.viewerContext
72
+ .getViewerScopedEntityCompanionForClass(this.entityClass)
73
+ .getLoaderFactory()
74
+ .forLoad(this.queryContext, { previousValue: null, cascadingDeleteCause: null });
114
75
  }
115
76
 
116
77
  /**
@@ -125,6 +86,6 @@ export default class EntityLoader<
125
86
  TPrivacyPolicy,
126
87
  TSelectedFields
127
88
  > {
128
- return this.utilsPrivate;
89
+ return this.withAuthorizationResults().utils;
129
90
  }
130
91
  }
@@ -1,5 +1,6 @@
1
+ import AuthorizationResultBasedEntityLoader from './AuthorizationResultBasedEntityLoader';
1
2
  import EntityCompanion from './EntityCompanion';
2
- import EntityLoader from './EntityLoader';
3
+ import EntityLoaderUtils from './EntityLoaderUtils';
3
4
  import EntityPrivacyPolicy, { EntityPrivacyPolicyEvaluationContext } from './EntityPrivacyPolicy';
4
5
  import { EntityQueryContext } from './EntityQueryContext';
5
6
  import ReadonlyEntity from './ReadonlyEntity';
@@ -52,8 +53,15 @@ export default class EntityLoaderFactory<
52
53
  TEntity,
53
54
  TSelectedFields
54
55
  >,
55
- ): EntityLoader<TFields, TID, TViewerContext, TEntity, TPrivacyPolicy, TSelectedFields> {
56
- return new EntityLoader(
56
+ ): AuthorizationResultBasedEntityLoader<
57
+ TFields,
58
+ TID,
59
+ TViewerContext,
60
+ TEntity,
61
+ TPrivacyPolicy,
62
+ TSelectedFields
63
+ > {
64
+ const utils = new EntityLoaderUtils(
57
65
  viewerContext,
58
66
  queryContext,
59
67
  privacyPolicyEvaluationContext,
@@ -64,5 +72,14 @@ export default class EntityLoaderFactory<
64
72
  this.dataManager,
65
73
  this.metricsAdapter,
66
74
  );
75
+
76
+ return new AuthorizationResultBasedEntityLoader(
77
+ queryContext,
78
+ this.entityCompanion.entityCompanionDefinition.entityConfiguration,
79
+ this.entityCompanion.entityCompanionDefinition.entityClass,
80
+ this.dataManager,
81
+ this.metricsAdapter,
82
+ utils,
83
+ );
67
84
  }
68
85
  }
@@ -1,3 +1,8 @@
1
+ import {
2
+ AuthorizationResultBasedCreateMutator,
3
+ AuthorizationResultBasedUpdateMutator,
4
+ AuthorizationResultBasedDeleteMutator,
5
+ } from './AuthorizationResultBasedEntityMutator';
1
6
  import Entity, { IEntityClass } from './Entity';
2
7
  import EntityCompanionProvider from './EntityCompanionProvider';
3
8
  import EntityConfiguration from './EntityConfiguration';
@@ -5,7 +10,6 @@ import EntityDatabaseAdapter from './EntityDatabaseAdapter';
5
10
  import EntityLoaderFactory from './EntityLoaderFactory';
6
11
  import EntityMutationTriggerConfiguration from './EntityMutationTriggerConfiguration';
7
12
  import EntityMutationValidator from './EntityMutationValidator';
8
- import { CreateMutator, UpdateMutator, DeleteMutator } from './EntityMutator';
9
13
  import EntityPrivacyPolicy from './EntityPrivacyPolicy';
10
14
  import { EntityQueryContext } from './EntityQueryContext';
11
15
  import ViewerContext from './ViewerContext';
@@ -75,8 +79,15 @@ export default class EntityMutatorFactory<
75
79
  forCreate(
76
80
  viewerContext: TViewerContext,
77
81
  queryContext: EntityQueryContext,
78
- ): CreateMutator<TFields, TID, TViewerContext, TEntity, TPrivacyPolicy, TSelectedFields> {
79
- return new CreateMutator(
82
+ ): AuthorizationResultBasedCreateMutator<
83
+ TFields,
84
+ TID,
85
+ TViewerContext,
86
+ TEntity,
87
+ TPrivacyPolicy,
88
+ TSelectedFields
89
+ > {
90
+ return new AuthorizationResultBasedCreateMutator(
80
91
  this.entityCompanionProvider,
81
92
  viewerContext,
82
93
  queryContext,
@@ -100,8 +111,15 @@ export default class EntityMutatorFactory<
100
111
  forUpdate(
101
112
  existingEntity: TEntity,
102
113
  queryContext: EntityQueryContext,
103
- ): UpdateMutator<TFields, TID, TViewerContext, TEntity, TPrivacyPolicy, TSelectedFields> {
104
- return new UpdateMutator(
114
+ ): AuthorizationResultBasedUpdateMutator<
115
+ TFields,
116
+ TID,
117
+ TViewerContext,
118
+ TEntity,
119
+ TPrivacyPolicy,
120
+ TSelectedFields
121
+ > {
122
+ return new AuthorizationResultBasedUpdateMutator(
105
123
  this.entityCompanionProvider,
106
124
  existingEntity.getViewerContext(),
107
125
  queryContext,
@@ -125,8 +143,15 @@ export default class EntityMutatorFactory<
125
143
  forDelete(
126
144
  existingEntity: TEntity,
127
145
  queryContext: EntityQueryContext,
128
- ): DeleteMutator<TFields, TID, TViewerContext, TEntity, TPrivacyPolicy, TSelectedFields> {
129
- return new DeleteMutator(
146
+ ): AuthorizationResultBasedDeleteMutator<
147
+ TFields,
148
+ TID,
149
+ TViewerContext,
150
+ TEntity,
151
+ TPrivacyPolicy,
152
+ TSelectedFields
153
+ > {
154
+ return new AuthorizationResultBasedDeleteMutator(
130
155
  this.entityCompanionProvider,
131
156
  existingEntity.getViewerContext(),
132
157
  queryContext,
@@ -1,6 +1,6 @@
1
1
  import { Result } from '@expo/results';
2
2
 
3
- import EntityLoader from './EntityLoader';
3
+ import AuthorizationResultBasedEntityLoader from './AuthorizationResultBasedEntityLoader';
4
4
  import EntityPrivacyPolicy from './EntityPrivacyPolicy';
5
5
  import ReadonlyEntity from './ReadonlyEntity';
6
6
  import ViewerContext from './ViewerContext';
@@ -60,7 +60,7 @@ export default abstract class EntitySecondaryCacheLoader<
60
60
  > {
61
61
  constructor(
62
62
  private readonly secondaryEntityCache: ISecondaryEntityCache<TFields, TLoadParams>,
63
- protected readonly entityLoader: EntityLoader<
63
+ protected readonly entityLoader: AuthorizationResultBasedEntityLoader<
64
64
  TFields,
65
65
  TID,
66
66
  TViewerContext,
@@ -84,11 +84,9 @@ export default abstract class EntitySecondaryCacheLoader<
84
84
  );
85
85
 
86
86
  // convert value to and from array to reuse complex code
87
- const entitiesMap = await this.entityLoader
88
- .utils()
89
- .constructAndAuthorizeEntitiesAsync(
90
- mapMap(loadParamsToFieldObjects, (fieldObject) => (fieldObject ? [fieldObject] : [])),
91
- );
87
+ const entitiesMap = await this.entityLoader.utils.constructAndAuthorizeEntitiesAsync(
88
+ mapMap(loadParamsToFieldObjects, (fieldObject) => (fieldObject ? [fieldObject] : [])),
89
+ );
92
90
  return mapMap(entitiesMap, (fieldObjects) => fieldObjects[0] ?? null);
93
91
  }
94
92
 
@@ -0,0 +1,73 @@
1
+ import { AuthorizationResultBasedUpdateMutator } from './AuthorizationResultBasedEntityMutator';
2
+ import EnforcingEntityUpdater from './EnforcingEntityUpdater';
3
+ import { IEntityClass } from './Entity';
4
+ import EntityPrivacyPolicy from './EntityPrivacyPolicy';
5
+ import { EntityQueryContext } from './EntityQueryContext';
6
+ import ReadonlyEntity from './ReadonlyEntity';
7
+ import ViewerContext from './ViewerContext';
8
+
9
+ /**
10
+ * The primary interface for updating entities.
11
+ */
12
+ export default class EntityUpdater<
13
+ TFields extends object,
14
+ TID extends NonNullable<TFields[TSelectedFields]>,
15
+ TViewerContext extends ViewerContext,
16
+ TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>,
17
+ TPrivacyPolicy extends EntityPrivacyPolicy<
18
+ TFields,
19
+ TID,
20
+ TViewerContext,
21
+ TEntity,
22
+ TSelectedFields
23
+ >,
24
+ TSelectedFields extends keyof TFields,
25
+ > {
26
+ constructor(
27
+ private readonly existingEntity: TEntity,
28
+ private readonly queryContext: EntityQueryContext,
29
+ private readonly entityClass: IEntityClass<
30
+ TFields,
31
+ TID,
32
+ TViewerContext,
33
+ TEntity,
34
+ TPrivacyPolicy,
35
+ TSelectedFields
36
+ >,
37
+ ) {}
38
+
39
+ /**
40
+ * Enforcing entity updater. All updates through this updater are
41
+ * guaranteed to be successful and will throw otherwise.
42
+ */
43
+ enforcing(): EnforcingEntityUpdater<
44
+ TFields,
45
+ TID,
46
+ TViewerContext,
47
+ TEntity,
48
+ TPrivacyPolicy,
49
+ TSelectedFields
50
+ > {
51
+ return new EnforcingEntityUpdater(this.withAuthorizationResults());
52
+ }
53
+
54
+ /**
55
+ * Authorization-result-based entity updater. All updates through this
56
+ * updater are results, where an unsuccessful result means an authorization
57
+ * error or entity construction error occurred. Other errors are thrown.
58
+ */
59
+ withAuthorizationResults(): AuthorizationResultBasedUpdateMutator<
60
+ TFields,
61
+ TID,
62
+ TViewerContext,
63
+ TEntity,
64
+ TPrivacyPolicy,
65
+ TSelectedFields
66
+ > {
67
+ return this.existingEntity
68
+ .getViewerContext()
69
+ .getViewerScopedEntityCompanionForClass(this.entityClass)
70
+ .getMutatorFactory()
71
+ .forUpdate(this.existingEntity, this.queryContext);
72
+ }
73
+ }
@@ -84,14 +84,10 @@ export default abstract class ReadonlyEntity<
84
84
  /**
85
85
  * @returns EntityAssociationLoader for this entity
86
86
  */
87
- associationLoader(): EntityAssociationLoader<
88
- TFields,
89
- TID,
90
- TViewerContext,
91
- this,
92
- TSelectedFields
93
- > {
94
- return new EntityAssociationLoader(this);
87
+ associationLoader(
88
+ queryContext?: EntityQueryContext,
89
+ ): EntityAssociationLoader<TFields, TID, TViewerContext, this, TSelectedFields> {
90
+ return new EntityAssociationLoader(this, queryContext);
95
91
  }
96
92
 
97
93
  /**
@@ -152,10 +148,15 @@ export default abstract class ReadonlyEntity<
152
148
  .getViewerScopedEntityCompanionForClass(this)
153
149
  .getQueryContextProvider()
154
150
  .getQueryContext(),
155
- ): EntityLoader<TMFields, TMID, TMViewerContext, TMEntity, TMPrivacyPolicy, TMSelectedFields> {
156
- return viewerContext
157
- .getViewerScopedEntityCompanionForClass(this)
158
- .getLoaderFactory()
159
- .forLoad(queryContext, { previousValue: null, cascadingDeleteCause: null });
151
+ ): EntityLoader<
152
+ TMFields,
153
+ TMID,
154
+ TMViewerContext,
155
+ TMViewerContext2,
156
+ TMEntity,
157
+ TMPrivacyPolicy,
158
+ TMSelectedFields
159
+ > {
160
+ return new EntityLoader(viewerContext, queryContext, this);
160
161
  }
161
162
  }
@@ -1,4 +1,4 @@
1
- import EntityLoader from './EntityLoader';
1
+ import AuthorizationResultBasedEntityLoader from './AuthorizationResultBasedEntityLoader';
2
2
  import EntityLoaderFactory from './EntityLoaderFactory';
3
3
  import EntityPrivacyPolicy, { EntityPrivacyPolicyEvaluationContext } from './EntityPrivacyPolicy';
4
4
  import { EntityQueryContext } from './EntityQueryContext';
@@ -43,7 +43,14 @@ export default class ViewerScopedEntityLoaderFactory<
43
43
  TEntity,
44
44
  TSelectedFields
45
45
  >,
46
- ): EntityLoader<TFields, TID, TViewerContext, TEntity, TPrivacyPolicy, TSelectedFields> {
46
+ ): AuthorizationResultBasedEntityLoader<
47
+ TFields,
48
+ TID,
49
+ TViewerContext,
50
+ TEntity,
51
+ TPrivacyPolicy,
52
+ TSelectedFields
53
+ > {
47
54
  return this.entityLoaderFactory.forLoad(
48
55
  this.viewerContext,
49
56
  queryContext,
@@ -1,4 +1,8 @@
1
- import { CreateMutator, UpdateMutator, DeleteMutator } from './EntityMutator';
1
+ import {
2
+ AuthorizationResultBasedCreateMutator,
3
+ AuthorizationResultBasedUpdateMutator,
4
+ AuthorizationResultBasedDeleteMutator,
5
+ } from './AuthorizationResultBasedEntityMutator';
2
6
  import EntityMutatorFactory from './EntityMutatorFactory';
3
7
  import EntityPrivacyPolicy from './EntityPrivacyPolicy';
4
8
  import { EntityQueryContext } from './EntityQueryContext';
@@ -36,21 +40,42 @@ export default class ViewerScopedEntityMutatorFactory<
36
40
 
37
41
  forCreate(
38
42
  queryContext: EntityQueryContext,
39
- ): CreateMutator<TFields, TID, TViewerContext, TEntity, TPrivacyPolicy, TSelectedFields> {
43
+ ): AuthorizationResultBasedCreateMutator<
44
+ TFields,
45
+ TID,
46
+ TViewerContext,
47
+ TEntity,
48
+ TPrivacyPolicy,
49
+ TSelectedFields
50
+ > {
40
51
  return this.entityMutatorFactory.forCreate(this.viewerContext, queryContext);
41
52
  }
42
53
 
43
54
  forUpdate(
44
55
  existingEntity: TEntity,
45
56
  queryContext: EntityQueryContext,
46
- ): UpdateMutator<TFields, TID, TViewerContext, TEntity, TPrivacyPolicy, TSelectedFields> {
57
+ ): AuthorizationResultBasedUpdateMutator<
58
+ TFields,
59
+ TID,
60
+ TViewerContext,
61
+ TEntity,
62
+ TPrivacyPolicy,
63
+ TSelectedFields
64
+ > {
47
65
  return this.entityMutatorFactory.forUpdate(existingEntity, queryContext);
48
66
  }
49
67
 
50
68
  forDelete(
51
69
  existingEntity: TEntity,
52
70
  queryContext: EntityQueryContext,
53
- ): DeleteMutator<TFields, TID, TViewerContext, TEntity, TPrivacyPolicy, TSelectedFields> {
71
+ ): AuthorizationResultBasedDeleteMutator<
72
+ TFields,
73
+ TID,
74
+ TViewerContext,
75
+ TEntity,
76
+ TPrivacyPolicy,
77
+ TSelectedFields
78
+ > {
54
79
  return this.entityMutatorFactory.forDelete(existingEntity, queryContext);
55
80
  }
56
81
  }