@expo/entity 0.17.0 → 0.21.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 (215) hide show
  1. package/build/EnforcingEntityLoader.js +2 -2
  2. package/build/EnforcingEntityLoader.js.map +1 -1
  3. package/build/Entity.js +8 -2
  4. package/build/Entity.js.map +1 -1
  5. package/build/EntityAssociationLoader.js +3 -3
  6. package/build/EntityAssociationLoader.js.map +1 -1
  7. package/build/EntityCompanion.d.ts +5 -0
  8. package/build/EntityCompanion.js +8 -1
  9. package/build/EntityCompanion.js.map +1 -1
  10. package/build/EntityCompanionProvider.d.ts +1 -1
  11. package/build/EntityCompanionProvider.js +5 -5
  12. package/build/EntityCompanionProvider.js.map +1 -1
  13. package/build/EntityConfiguration.d.ts +1 -1
  14. package/build/EntityConfiguration.js +3 -3
  15. package/build/EntityConfiguration.js.map +1 -1
  16. package/build/EntityDatabaseAdapter.d.ts +4 -4
  17. package/build/EntityDatabaseAdapter.js +13 -13
  18. package/build/EntityDatabaseAdapter.js.map +1 -1
  19. package/build/EntityFieldDefinition.d.ts +77 -0
  20. package/build/EntityFieldDefinition.js +53 -0
  21. package/build/EntityFieldDefinition.js.map +1 -0
  22. package/build/EntityFields.d.ts +1 -77
  23. package/build/EntityFields.js +13 -61
  24. package/build/EntityFields.js.map +1 -1
  25. package/build/EntityLoader.d.ts +3 -1
  26. package/build/EntityLoader.js +19 -15
  27. package/build/EntityLoader.js.map +1 -1
  28. package/build/EntityLoaderFactory.d.ts +3 -1
  29. package/build/EntityLoaderFactory.js +3 -2
  30. package/build/EntityLoaderFactory.js.map +1 -1
  31. package/build/EntityMutationInfo.d.ts +26 -0
  32. package/build/EntityMutationInfo.js +10 -0
  33. package/build/EntityMutationInfo.js.map +1 -0
  34. package/build/EntityMutationTriggerConfiguration.d.ts +4 -4
  35. package/build/EntityMutationValidator.d.ts +3 -3
  36. package/build/EntityMutationValidator.js.map +1 -1
  37. package/build/EntityMutator.d.ts +5 -16
  38. package/build/EntityMutator.js +62 -58
  39. package/build/EntityMutator.js.map +1 -1
  40. package/build/EntityPrivacyPolicy.d.ts +5 -4
  41. package/build/EntityPrivacyPolicy.js +60 -12
  42. package/build/EntityPrivacyPolicy.js.map +1 -1
  43. package/build/EntityQueryContext.d.ts +24 -0
  44. package/build/EntityQueryContext.js +43 -0
  45. package/build/EntityQueryContext.js.map +1 -1
  46. package/build/EntityQueryContextProvider.js +1 -0
  47. package/build/EntityQueryContextProvider.js.map +1 -1
  48. package/build/EntitySecondaryCacheLoader.js +2 -2
  49. package/build/EntitySecondaryCacheLoader.js.map +1 -1
  50. package/build/ReadonlyEntity.js +3 -4
  51. package/build/ReadonlyEntity.js.map +1 -1
  52. package/build/ViewerScopedEntityCompanion.d.ts +5 -0
  53. package/build/ViewerScopedEntityCompanion.js +6 -0
  54. package/build/ViewerScopedEntityCompanion.js.map +1 -1
  55. package/build/__tests__/EnforcingEntityLoader-test.js +82 -82
  56. package/build/__tests__/EnforcingEntityLoader-test.js.map +1 -1
  57. package/build/__tests__/Entity-test.js +6 -6
  58. package/build/__tests__/Entity-test.js.map +1 -1
  59. package/build/__tests__/EntityAssociationLoader-test.js +40 -40
  60. package/build/__tests__/EntityAssociationLoader-test.js.map +1 -1
  61. package/build/__tests__/EntityCommonUseCases-test.js +11 -11
  62. package/build/__tests__/EntityCommonUseCases-test.js.map +1 -1
  63. package/build/__tests__/EntityCompanion-test.js +3 -3
  64. package/build/__tests__/EntityCompanion-test.js.map +1 -1
  65. package/build/__tests__/EntityCompanionProvider-test.js +1 -1
  66. package/build/__tests__/EntityCompanionProvider-test.js.map +1 -1
  67. package/build/__tests__/EntityDatabaseAdapter-test.js +12 -12
  68. package/build/__tests__/EntityDatabaseAdapter-test.js.map +1 -1
  69. package/build/__tests__/EntityEdges-test.js +103 -6
  70. package/build/__tests__/EntityEdges-test.js.map +1 -1
  71. package/build/__tests__/EntityFields-test.js +18 -27
  72. package/build/__tests__/EntityFields-test.js.map +1 -1
  73. package/build/__tests__/EntityLoader-constructor-test.d.ts +22 -0
  74. package/build/__tests__/EntityLoader-constructor-test.js +111 -0
  75. package/build/__tests__/EntityLoader-constructor-test.js.map +1 -0
  76. package/build/__tests__/EntityLoader-test.js +72 -64
  77. package/build/__tests__/EntityLoader-test.js.map +1 -1
  78. package/build/__tests__/EntityMutator-MutationCacheConsistency-test.d.ts +1 -0
  79. package/build/__tests__/EntityMutator-MutationCacheConsistency-test.js +81 -0
  80. package/build/__tests__/EntityMutator-MutationCacheConsistency-test.js.map +1 -0
  81. package/build/__tests__/EntityMutator-test.js +116 -114
  82. package/build/__tests__/EntityMutator-test.js.map +1 -1
  83. package/build/__tests__/EntityPrivacyPolicy-test.js +143 -67
  84. package/build/__tests__/EntityPrivacyPolicy-test.js.map +1 -1
  85. package/build/__tests__/EntityQueryContext-test.d.ts +1 -0
  86. package/build/__tests__/EntityQueryContext-test.js +56 -0
  87. package/build/__tests__/EntityQueryContext-test.js.map +1 -0
  88. package/build/__tests__/EntitySecondaryCacheLoader-test.js +15 -15
  89. package/build/__tests__/EntitySecondaryCacheLoader-test.js.map +1 -1
  90. package/build/__tests__/EntitySelfReferentialEdges-test.js +13 -12
  91. package/build/__tests__/EntitySelfReferentialEdges-test.js.map +1 -1
  92. package/build/__tests__/ReadonlyEntity-test.js +11 -11
  93. package/build/__tests__/ReadonlyEntity-test.js.map +1 -1
  94. package/build/__tests__/ViewerContext-test.js +2 -2
  95. package/build/__tests__/ViewerContext-test.js.map +1 -1
  96. package/build/__tests__/ViewerScopedEntityCompanion-test.js +2 -2
  97. package/build/__tests__/ViewerScopedEntityCompanion-test.js.map +1 -1
  98. package/build/__tests__/ViewerScopedEntityCompanionProvider-test.js +2 -2
  99. package/build/__tests__/ViewerScopedEntityCompanionProvider-test.js.map +1 -1
  100. package/build/__tests__/ViewerScopedEntityLoaderFactory-test.js +5 -5
  101. package/build/__tests__/ViewerScopedEntityLoaderFactory-test.js.map +1 -1
  102. package/build/__tests__/ViewerScopedEntityMutatorFactory-test.js +5 -5
  103. package/build/__tests__/ViewerScopedEntityMutatorFactory-test.js.map +1 -1
  104. package/build/__tests__/cases/TwoEntitySameTableDisjointRows-test.js +5 -5
  105. package/build/__tests__/cases/TwoEntitySameTableDisjointRows-test.js.map +1 -1
  106. package/build/__tests__/cases/TwoEntitySameTableOverlappingRows-test.js +2 -2
  107. package/build/__tests__/cases/TwoEntitySameTableOverlappingRows-test.js.map +1 -1
  108. package/build/__tests__/entityUtils-test.js +21 -21
  109. package/build/__tests__/entityUtils-test.js.map +1 -1
  110. package/build/index.d.ts +3 -0
  111. package/build/index.js +5 -1
  112. package/build/index.js.map +1 -1
  113. package/build/internal/EntityDataManager.js +8 -7
  114. package/build/internal/EntityDataManager.js.map +1 -1
  115. package/build/internal/EntityFieldTransformationUtils.js +2 -2
  116. package/build/internal/EntityFieldTransformationUtils.js.map +1 -1
  117. package/build/internal/ReadThroughEntityCache.js +4 -4
  118. package/build/internal/ReadThroughEntityCache.js.map +1 -1
  119. package/build/internal/__tests__/EntityDataManager-test.js +17 -17
  120. package/build/internal/__tests__/EntityDataManager-test.js.map +1 -1
  121. package/build/internal/__tests__/EntityFieldTransformationUtils-test.js +8 -8
  122. package/build/internal/__tests__/EntityFieldTransformationUtils-test.js.map +1 -1
  123. package/build/internal/__tests__/ReadThroughEntityCache-test.js +48 -48
  124. package/build/internal/__tests__/ReadThroughEntityCache-test.js.map +1 -1
  125. package/build/metrics/EntityMetricsUtils.js +1 -1
  126. package/build/metrics/EntityMetricsUtils.js.map +1 -1
  127. package/build/metrics/IEntityMetricsAdapter.d.ts +16 -0
  128. package/build/metrics/IEntityMetricsAdapter.js +6 -1
  129. package/build/metrics/IEntityMetricsAdapter.js.map +1 -1
  130. package/build/metrics/NoOpEntityMetricsAdapter.d.ts +2 -1
  131. package/build/metrics/NoOpEntityMetricsAdapter.js +1 -0
  132. package/build/metrics/NoOpEntityMetricsAdapter.js.map +1 -1
  133. package/build/rules/__tests__/AlwaysAllowPrivacyPolicyRule-test.js +4 -4
  134. package/build/rules/__tests__/AlwaysAllowPrivacyPolicyRule-test.js.map +1 -1
  135. package/build/rules/__tests__/AlwaysDenyPrivacyPolicyRule-test.js +4 -4
  136. package/build/rules/__tests__/AlwaysDenyPrivacyPolicyRule-test.js.map +1 -1
  137. package/build/rules/__tests__/AlwaysSkipPrivacyPolicyRule-test.js +4 -4
  138. package/build/rules/__tests__/AlwaysSkipPrivacyPolicyRule-test.js.map +1 -1
  139. package/build/testfixtures/DateIDTestEntity.js.map +1 -1
  140. package/build/testfixtures/SimpleTestEntity.js.map +1 -1
  141. package/build/testfixtures/TestEntity.d.ts +5 -5
  142. package/build/testfixtures/TestEntity.js +2 -2
  143. package/build/testfixtures/TestEntity.js.map +1 -1
  144. package/build/testfixtures/TestEntity2.d.ts +5 -5
  145. package/build/testfixtures/TestEntity2.js.map +1 -1
  146. package/build/testfixtures/TestEntityNumberKey.js.map +1 -1
  147. package/build/utils/collections/__tests__/maps-test.js +13 -13
  148. package/build/utils/collections/__tests__/maps-test.js.map +1 -1
  149. package/build/utils/collections/maps.js +1 -1
  150. package/build/utils/collections/maps.js.map +1 -1
  151. package/build/utils/testing/PrivacyPolicyRuleTestUtils.d.ts +6 -6
  152. package/build/utils/testing/PrivacyPolicyRuleTestUtils.js +1 -1
  153. package/build/utils/testing/PrivacyPolicyRuleTestUtils.js.map +1 -1
  154. package/build/utils/testing/StubCacheAdapter.js +1 -1
  155. package/build/utils/testing/StubCacheAdapter.js.map +1 -1
  156. package/build/utils/testing/StubDatabaseAdapter.js +6 -6
  157. package/build/utils/testing/StubDatabaseAdapter.js.map +1 -1
  158. package/build/utils/testing/__tests__/StubDatabaseAdapter-test.js +9 -9
  159. package/build/utils/testing/__tests__/StubDatabaseAdapter-test.js.map +1 -1
  160. package/build/utils/testing/describeFieldTestCase.d.ts +2 -0
  161. package/build/utils/testing/describeFieldTestCase.js +18 -0
  162. package/build/utils/testing/describeFieldTestCase.js.map +1 -0
  163. package/package.json +2 -1
  164. package/src/Entity.ts +10 -2
  165. package/src/EntityAssociationLoader.ts +1 -1
  166. package/src/EntityCompanion.ts +10 -2
  167. package/src/EntityCompanionProvider.ts +5 -9
  168. package/src/EntityConfiguration.ts +1 -1
  169. package/src/EntityDatabaseAdapter.ts +10 -8
  170. package/src/EntityFieldDefinition.ts +124 -0
  171. package/src/EntityFields.ts +2 -125
  172. package/src/EntityLoader.ts +12 -4
  173. package/src/EntityLoaderFactory.ts +5 -2
  174. package/src/EntityMutationInfo.ts +47 -0
  175. package/src/EntityMutationTriggerConfiguration.ts +5 -5
  176. package/src/EntityMutationValidator.ts +10 -4
  177. package/src/EntityMutator.ts +98 -76
  178. package/src/EntityPrivacyPolicy.ts +77 -19
  179. package/src/EntityQueryContext.ts +54 -0
  180. package/src/EntityQueryContextProvider.ts +1 -0
  181. package/src/ReadonlyEntity.ts +3 -2
  182. package/src/ViewerScopedEntityCompanion.ts +8 -0
  183. package/src/__tests__/Entity-test.ts +8 -8
  184. package/src/__tests__/EntityCommonUseCases-test.ts +4 -4
  185. package/src/__tests__/EntityEdges-test.ts +169 -14
  186. package/src/__tests__/EntityFields-test.ts +2 -21
  187. package/src/__tests__/EntityLoader-constructor-test.ts +177 -0
  188. package/src/__tests__/EntityLoader-test.ts +39 -11
  189. package/src/__tests__/EntityMutator-MutationCacheConsistency-test.ts +105 -0
  190. package/src/__tests__/EntityMutator-test.ts +140 -133
  191. package/src/__tests__/EntityPrivacyPolicy-test.ts +215 -78
  192. package/src/__tests__/EntityQueryContext-test.ts +82 -0
  193. package/src/__tests__/EntitySecondaryCacheLoader-test.ts +7 -9
  194. package/src/__tests__/EntitySelfReferentialEdges-test.ts +6 -5
  195. package/src/__tests__/ViewerContext-test.ts +7 -6
  196. package/src/__tests__/ViewerScopedEntityCompanion-test.ts +11 -10
  197. package/src/__tests__/ViewerScopedEntityMutatorFactory-test.ts +4 -3
  198. package/src/__tests__/cases/TwoEntitySameTableDisjointRows-test.ts +6 -6
  199. package/src/__tests__/cases/TwoEntitySameTableOverlappingRows-test.ts +4 -4
  200. package/src/index.ts +3 -0
  201. package/src/internal/EntityDataManager.ts +2 -1
  202. package/src/internal/__tests__/EntityDataManager-test.ts +2 -2
  203. package/src/internal/__tests__/ReadThroughEntityCache-test.ts +15 -13
  204. package/src/metrics/EntityMetricsUtils.ts +56 -50
  205. package/src/metrics/IEntityMetricsAdapter.ts +23 -0
  206. package/src/metrics/NoOpEntityMetricsAdapter.ts +2 -0
  207. package/src/testfixtures/DateIDTestEntity.ts +4 -4
  208. package/src/testfixtures/SimpleTestEntity.ts +4 -4
  209. package/src/testfixtures/TestEntity.ts +4 -4
  210. package/src/testfixtures/TestEntity2.ts +4 -4
  211. package/src/testfixtures/TestEntityNumberKey.ts +4 -4
  212. package/src/utils/testing/StubDatabaseAdapter.ts +2 -2
  213. package/src/utils/testing/__tests__/StubDatabaseAdapter-test.ts +1 -1
  214. package/src/utils/testing/describeFieldTestCase.ts +21 -0
  215. package/CHANGELOG.md +0 -252
@@ -6,6 +6,7 @@ import { EntityQueryContext } from './EntityQueryContext';
6
6
  import ReadonlyEntity from './ReadonlyEntity';
7
7
  import ViewerContext from './ViewerContext';
8
8
  import EntityDataManager from './internal/EntityDataManager';
9
+ import IEntityMetricsAdapter from './metrics/IEntityMetricsAdapter';
9
10
 
10
11
  /**
11
12
  * The primary entry point for loading entities.
@@ -35,7 +36,8 @@ export default class EntityLoaderFactory<
35
36
  TSelectedFields
36
37
  >,
37
38
  private readonly privacyPolicyClass: TPrivacyPolicy,
38
- private readonly dataManager: EntityDataManager<TFields>
39
+ private readonly dataManager: EntityDataManager<TFields>,
40
+ protected readonly metricsAdapter: IEntityMetricsAdapter
39
41
  ) {}
40
42
 
41
43
  /**
@@ -53,7 +55,8 @@ export default class EntityLoaderFactory<
53
55
  this.entityConfiguration,
54
56
  this.entityClass,
55
57
  this.privacyPolicyClass,
56
- this.dataManager
58
+ this.dataManager,
59
+ this.metricsAdapter
57
60
  );
58
61
  }
59
62
  }
@@ -0,0 +1,47 @@
1
+ import Entity from './Entity';
2
+ import ViewerContext from './ViewerContext';
3
+
4
+ export enum EntityMutationType {
5
+ CREATE,
6
+ UPDATE,
7
+ DELETE,
8
+ }
9
+
10
+ export type EntityValidatorMutationInfo<
11
+ TFields,
12
+ TID extends NonNullable<TFields[TSelectedFields]>,
13
+ TViewerContext extends ViewerContext,
14
+ TEntity extends Entity<TFields, TID, TViewerContext, TSelectedFields>,
15
+ TSelectedFields extends keyof TFields = keyof TFields
16
+ > =
17
+ | {
18
+ type: EntityMutationType.CREATE;
19
+ }
20
+ | {
21
+ type: EntityMutationType.UPDATE;
22
+ previousValue: TEntity;
23
+ };
24
+
25
+ export type EntityMutationTriggerDeleteCascadeInfo<> = {
26
+ entity: Entity<any, any, any, any>;
27
+ cascadingDeleteCause: EntityMutationTriggerDeleteCascadeInfo | null;
28
+ };
29
+
30
+ export type EntityTriggerMutationInfo<
31
+ TFields,
32
+ TID extends NonNullable<TFields[TSelectedFields]>,
33
+ TViewerContext extends ViewerContext,
34
+ TEntity extends Entity<TFields, TID, TViewerContext, TSelectedFields>,
35
+ TSelectedFields extends keyof TFields = keyof TFields
36
+ > =
37
+ | {
38
+ type: EntityMutationType.CREATE;
39
+ }
40
+ | {
41
+ type: EntityMutationType.UPDATE;
42
+ previousValue: TEntity;
43
+ }
44
+ | {
45
+ type: EntityMutationType.DELETE;
46
+ cascadingDeleteCause: EntityMutationTriggerDeleteCascadeInfo | null;
47
+ };
@@ -1,5 +1,5 @@
1
- import { EntityMutationInfo } from './EntityMutator';
2
- import { EntityQueryContext } from './EntityQueryContext';
1
+ import { EntityTriggerMutationInfo } from './EntityMutationInfo';
2
+ import { EntityTransactionalQueryContext } from './EntityQueryContext';
3
3
  import ReadonlyEntity from './ReadonlyEntity';
4
4
  import ViewerContext from './ViewerContext';
5
5
 
@@ -78,9 +78,9 @@ export abstract class EntityMutationTrigger<
78
78
  > {
79
79
  abstract executeAsync(
80
80
  viewerContext: TViewerContext,
81
- queryContext: EntityQueryContext,
81
+ queryContext: EntityTransactionalQueryContext,
82
82
  entity: TEntity,
83
- mutationInfo: EntityMutationInfo<TFields, TID, TViewerContext, TEntity, TSelectedFields>
83
+ mutationInfo: EntityTriggerMutationInfo<TFields, TID, TViewerContext, TEntity, TSelectedFields>
84
84
  ): Promise<void>;
85
85
  }
86
86
 
@@ -98,6 +98,6 @@ export abstract class EntityNonTransactionalMutationTrigger<
98
98
  abstract executeAsync(
99
99
  viewerContext: TViewerContext,
100
100
  entity: TEntity,
101
- mutationInfo: EntityMutationInfo<TFields, TID, TViewerContext, TEntity, TSelectedFields>
101
+ mutationInfo: EntityTriggerMutationInfo<TFields, TID, TViewerContext, TEntity, TSelectedFields>
102
102
  ): Promise<void>;
103
103
  }
@@ -1,5 +1,5 @@
1
- import { EntityMutationInfo } from './EntityMutator';
2
- import { EntityQueryContext } from './EntityQueryContext';
1
+ import { EntityValidatorMutationInfo } from './EntityMutationInfo';
2
+ import { EntityTransactionalQueryContext } from './EntityQueryContext';
3
3
  import ReadonlyEntity from './ReadonlyEntity';
4
4
  import ViewerContext from './ViewerContext';
5
5
 
@@ -16,8 +16,14 @@ export default abstract class EntityMutationValidator<
16
16
  > {
17
17
  abstract executeAsync(
18
18
  viewerContext: TViewerContext,
19
- queryContext: EntityQueryContext,
19
+ queryContext: EntityTransactionalQueryContext,
20
20
  entity: TEntity,
21
- mutationInfo: EntityMutationInfo<TFields, TID, TViewerContext, TEntity, TSelectedFields>
21
+ mutationInfo: EntityValidatorMutationInfo<
22
+ TFields,
23
+ TID,
24
+ TViewerContext,
25
+ TEntity,
26
+ TSelectedFields
27
+ >
22
28
  ): Promise<void>;
23
29
  }
@@ -5,8 +5,14 @@ import Entity, { IEntityClass } from './Entity';
5
5
  import { EntityCompanionDefinition } from './EntityCompanionProvider';
6
6
  import EntityConfiguration from './EntityConfiguration';
7
7
  import EntityDatabaseAdapter from './EntityDatabaseAdapter';
8
- import { EntityEdgeDeletionBehavior } from './EntityFields';
8
+ import { EntityEdgeDeletionBehavior } from './EntityFieldDefinition';
9
9
  import EntityLoaderFactory from './EntityLoaderFactory';
10
+ import {
11
+ EntityValidatorMutationInfo,
12
+ EntityMutationType,
13
+ EntityTriggerMutationInfo,
14
+ EntityMutationTriggerDeleteCascadeInfo,
15
+ } from './EntityMutationInfo';
10
16
  import EntityMutationTriggerConfiguration, {
11
17
  EntityMutationTrigger,
12
18
  EntityNonTransactionalMutationTrigger,
@@ -21,30 +27,6 @@ import { timeAndLogMutationEventAsync } from './metrics/EntityMetricsUtils';
21
27
  import IEntityMetricsAdapter, { EntityMetricsMutationType } from './metrics/IEntityMetricsAdapter';
22
28
  import { mapMapAsync } from './utils/collections/maps';
23
29
 
24
- export enum EntityMutationType {
25
- CREATE,
26
- UPDATE,
27
- DELETE,
28
- }
29
-
30
- export type EntityMutationInfo<
31
- TFields,
32
- TID extends NonNullable<TFields[TSelectedFields]>,
33
- TViewerContext extends ViewerContext,
34
- TEntity extends Entity<TFields, TID, TViewerContext, TSelectedFields>,
35
- TSelectedFields extends keyof TFields = keyof TFields
36
- > =
37
- | {
38
- type: EntityMutationType.CREATE;
39
- }
40
- | {
41
- type: EntityMutationType.UPDATE;
42
- previousValue: TEntity;
43
- }
44
- | {
45
- type: EntityMutationType.DELETE;
46
- };
47
-
48
30
  abstract class BaseMutator<
49
31
  TFields,
50
32
  TID extends NonNullable<TFields[TSelectedFields]>,
@@ -110,26 +92,44 @@ abstract class BaseMutator<
110
92
  }
111
93
  }
112
94
 
113
- protected async executeMutationTriggersOrValidatorsAsync(
114
- triggersOrValidators:
95
+ protected async executeMutationValidatorsAsync(
96
+ validators: EntityMutationValidator<TFields, TID, TViewerContext, TEntity, TSelectedFields>[],
97
+ queryContext: EntityTransactionalQueryContext,
98
+ entity: TEntity,
99
+ mutationInfo: EntityValidatorMutationInfo<
100
+ TFields,
101
+ TID,
102
+ TViewerContext,
103
+ TEntity,
104
+ TSelectedFields
105
+ >
106
+ ): Promise<void> {
107
+ await Promise.all(
108
+ validators.map((validator) =>
109
+ validator.executeAsync(this.viewerContext, queryContext, entity, mutationInfo)
110
+ )
111
+ );
112
+ }
113
+
114
+ protected async executeMutationTriggersAsync(
115
+ triggers:
115
116
  | EntityMutationTrigger<TFields, TID, TViewerContext, TEntity, TSelectedFields>[]
116
- | EntityMutationValidator<TFields, TID, TViewerContext, TEntity, TSelectedFields>[]
117
117
  | undefined,
118
- queryContext: EntityQueryContext,
118
+ queryContext: EntityTransactionalQueryContext,
119
119
  entity: TEntity,
120
- mutationInfo: EntityMutationInfo<TFields, TID, TViewerContext, TEntity, TSelectedFields>
120
+ mutationInfo: EntityTriggerMutationInfo<TFields, TID, TViewerContext, TEntity, TSelectedFields>
121
121
  ): Promise<void> {
122
- if (!triggersOrValidators) {
122
+ if (!triggers) {
123
123
  return;
124
124
  }
125
125
  await Promise.all(
126
- triggersOrValidators.map((triggerOrValidator) =>
127
- triggerOrValidator.executeAsync(this.viewerContext, queryContext, entity, mutationInfo)
126
+ triggers.map((trigger) =>
127
+ trigger.executeAsync(this.viewerContext, queryContext, entity, mutationInfo)
128
128
  )
129
129
  );
130
130
  }
131
131
 
132
- protected async executeNonTransactionalMutationTriggersOrValidatorsAsync(
132
+ protected async executeNonTransactionalMutationTriggersAsync(
133
133
  triggers:
134
134
  | EntityNonTransactionalMutationTrigger<
135
135
  TFields,
@@ -140,7 +140,7 @@ abstract class BaseMutator<
140
140
  >[]
141
141
  | undefined,
142
142
  entity: TEntity,
143
- mutationInfo: EntityMutationInfo<TFields, TID, TViewerContext, TEntity, TSelectedFields>
143
+ mutationInfo: EntityTriggerMutationInfo<TFields, TID, TViewerContext, TEntity, TSelectedFields>
144
144
  ): Promise<void> {
145
145
  if (!triggers) {
146
146
  return;
@@ -211,35 +211,36 @@ export class CreateMutator<
211
211
  ): Promise<Result<TEntity>> {
212
212
  this.validateFields(this.fieldsForEntity);
213
213
 
214
- const temporaryEntityForPrivacyCheck = new this.entityClass(this.viewerContext, ({
214
+ const temporaryEntityForPrivacyCheck = new this.entityClass(this.viewerContext, {
215
215
  [this.entityConfiguration.idField]: '00000000-0000-0000-0000-000000000000', // zero UUID
216
216
  ...this.fieldsForEntity,
217
- } as unknown) as TFields);
217
+ } as unknown as TFields);
218
218
 
219
219
  const authorizeCreateResult = await asyncResult(
220
220
  this.privacyPolicy.authorizeCreateAsync(
221
221
  this.viewerContext,
222
222
  queryContext,
223
- temporaryEntityForPrivacyCheck
223
+ temporaryEntityForPrivacyCheck,
224
+ this.metricsAdapter
224
225
  )
225
226
  );
226
227
  if (!authorizeCreateResult.ok) {
227
228
  return authorizeCreateResult;
228
229
  }
229
230
 
230
- await this.executeMutationTriggersOrValidatorsAsync(
231
+ await this.executeMutationValidatorsAsync(
231
232
  this.mutationValidators,
232
233
  queryContext,
233
234
  temporaryEntityForPrivacyCheck,
234
235
  { type: EntityMutationType.CREATE }
235
236
  );
236
- await this.executeMutationTriggersOrValidatorsAsync(
237
+ await this.executeMutationTriggersAsync(
237
238
  this.mutationTriggers.beforeAll,
238
239
  queryContext,
239
240
  temporaryEntityForPrivacyCheck,
240
241
  { type: EntityMutationType.CREATE }
241
242
  );
242
- await this.executeMutationTriggersOrValidatorsAsync(
243
+ await this.executeMutationTriggersAsync(
243
244
  this.mutationTriggers.beforeCreate,
244
245
  queryContext,
245
246
  temporaryEntityForPrivacyCheck,
@@ -249,7 +250,7 @@ export class CreateMutator<
249
250
  const insertResult = await this.databaseAdapter.insertAsync(queryContext, this.fieldsForEntity);
250
251
 
251
252
  const entityLoader = this.entityLoaderFactory.forLoad(this.viewerContext, queryContext);
252
- queryContext.appendPostCommitCallback(
253
+ queryContext.appendPostCommitInvalidationCallback(
253
254
  entityLoader.invalidateFieldsAsync.bind(entityLoader, insertResult)
254
255
  );
255
256
 
@@ -258,13 +259,13 @@ export class CreateMutator<
258
259
  .enforcing()
259
260
  .loadByIDAsync(unauthorizedEntityAfterInsert.getID());
260
261
 
261
- await this.executeMutationTriggersOrValidatorsAsync(
262
+ await this.executeMutationTriggersAsync(
262
263
  this.mutationTriggers.afterCreate,
263
264
  queryContext,
264
265
  newEntity,
265
266
  { type: EntityMutationType.CREATE }
266
267
  );
267
- await this.executeMutationTriggersOrValidatorsAsync(
268
+ await this.executeMutationTriggersAsync(
268
269
  this.mutationTriggers.afterAll,
269
270
  queryContext,
270
271
  newEntity,
@@ -272,7 +273,7 @@ export class CreateMutator<
272
273
  );
273
274
 
274
275
  queryContext.appendPostCommitCallback(
275
- this.executeNonTransactionalMutationTriggersOrValidatorsAsync.bind(
276
+ this.executeNonTransactionalMutationTriggersAsync.bind(
276
277
  this,
277
278
  this.mutationTriggers.afterCommit,
278
279
  newEntity,
@@ -408,26 +409,27 @@ export class UpdateMutator<
408
409
  this.privacyPolicy.authorizeUpdateAsync(
409
410
  this.viewerContext,
410
411
  queryContext,
411
- entityAboutToBeUpdated
412
+ entityAboutToBeUpdated,
413
+ this.metricsAdapter
412
414
  )
413
415
  );
414
416
  if (!authorizeUpdateResult.ok) {
415
417
  return authorizeUpdateResult;
416
418
  }
417
419
 
418
- await this.executeMutationTriggersOrValidatorsAsync(
420
+ await this.executeMutationValidatorsAsync(
419
421
  this.mutationValidators,
420
422
  queryContext,
421
423
  entityAboutToBeUpdated,
422
424
  { type: EntityMutationType.UPDATE, previousValue: this.originalEntity }
423
425
  );
424
- await this.executeMutationTriggersOrValidatorsAsync(
426
+ await this.executeMutationTriggersAsync(
425
427
  this.mutationTriggers.beforeAll,
426
428
  queryContext,
427
429
  entityAboutToBeUpdated,
428
430
  { type: EntityMutationType.UPDATE, previousValue: this.originalEntity }
429
431
  );
430
- await this.executeMutationTriggersOrValidatorsAsync(
432
+ await this.executeMutationTriggersAsync(
431
433
  this.mutationTriggers.beforeUpdate,
432
434
  queryContext,
433
435
  entityAboutToBeUpdated,
@@ -443,13 +445,13 @@ export class UpdateMutator<
443
445
 
444
446
  const entityLoader = this.entityLoaderFactory.forLoad(this.viewerContext, queryContext);
445
447
 
446
- queryContext.appendPostCommitCallback(
448
+ queryContext.appendPostCommitInvalidationCallback(
447
449
  entityLoader.invalidateFieldsAsync.bind(
448
450
  entityLoader,
449
451
  this.originalEntity.getAllDatabaseFields()
450
452
  )
451
453
  );
452
- queryContext.appendPostCommitCallback(
454
+ queryContext.appendPostCommitInvalidationCallback(
453
455
  entityLoader.invalidateFieldsAsync.bind(entityLoader, this.fieldsForEntity)
454
456
  );
455
457
 
@@ -458,13 +460,13 @@ export class UpdateMutator<
458
460
  .enforcing()
459
461
  .loadByIDAsync(unauthorizedEntityAfterUpdate.getID());
460
462
 
461
- await this.executeMutationTriggersOrValidatorsAsync(
463
+ await this.executeMutationTriggersAsync(
462
464
  this.mutationTriggers.afterUpdate,
463
465
  queryContext,
464
466
  updatedEntity,
465
467
  { type: EntityMutationType.UPDATE, previousValue: this.originalEntity }
466
468
  );
467
- await this.executeMutationTriggersOrValidatorsAsync(
469
+ await this.executeMutationTriggersAsync(
468
470
  this.mutationTriggers.afterAll,
469
471
  queryContext,
470
472
  updatedEntity,
@@ -472,7 +474,7 @@ export class UpdateMutator<
472
474
  );
473
475
 
474
476
  queryContext.appendPostCommitCallback(
475
- this.executeNonTransactionalMutationTriggersOrValidatorsAsync.bind(
477
+ this.executeNonTransactionalMutationTriggersAsync.bind(
476
478
  this,
477
479
  this.mutationTriggers.afterCommit,
478
480
  updatedEntity,
@@ -563,7 +565,7 @@ export class DeleteMutator<
563
565
  this.metricsAdapter,
564
566
  EntityMetricsMutationType.DELETE,
565
567
  this.entityClass.name
566
- )(this.deleteInTransactionAsync());
568
+ )(this.deleteInTransactionAsync(new Set(), false, null));
567
569
  }
568
570
 
569
571
  /**
@@ -574,14 +576,16 @@ export class DeleteMutator<
574
576
  }
575
577
 
576
578
  private async deleteInTransactionAsync(
577
- processedEntityIdentifiersFromTransitiveDeletions: Set<string> = new Set(),
578
- skipDatabaseDeletion: boolean = false
579
+ processedEntityIdentifiersFromTransitiveDeletions: Set<string>,
580
+ skipDatabaseDeletion: boolean,
581
+ cascadingDeleteCause: EntityMutationTriggerDeleteCascadeInfo | null
579
582
  ): Promise<Result<void>> {
580
583
  return await this.queryContext.runInTransactionIfNotInTransactionAsync((innerQueryContext) =>
581
584
  this.deleteInternalAsync(
582
585
  innerQueryContext,
583
586
  processedEntityIdentifiersFromTransitiveDeletions,
584
- skipDatabaseDeletion
587
+ skipDatabaseDeletion,
588
+ cascadingDeleteCause
585
589
  )
586
590
  );
587
591
  }
@@ -589,10 +593,16 @@ export class DeleteMutator<
589
593
  private async deleteInternalAsync(
590
594
  queryContext: EntityTransactionalQueryContext,
591
595
  processedEntityIdentifiersFromTransitiveDeletions: Set<string>,
592
- skipDatabaseDeletion: boolean
596
+ skipDatabaseDeletion: boolean,
597
+ cascadingDeleteCause: EntityMutationTriggerDeleteCascadeInfo | null
593
598
  ): Promise<Result<void>> {
594
599
  const authorizeDeleteResult = await asyncResult(
595
- this.privacyPolicy.authorizeDeleteAsync(this.viewerContext, queryContext, this.entity)
600
+ this.privacyPolicy.authorizeDeleteAsync(
601
+ this.viewerContext,
602
+ queryContext,
603
+ this.entity,
604
+ this.metricsAdapter
605
+ )
596
606
  );
597
607
  if (!authorizeDeleteResult.ok) {
598
608
  return authorizeDeleteResult;
@@ -601,20 +611,21 @@ export class DeleteMutator<
601
611
  await this.processEntityDeletionForInboundEdgesAsync(
602
612
  this.entity,
603
613
  queryContext,
604
- processedEntityIdentifiersFromTransitiveDeletions
614
+ processedEntityIdentifiersFromTransitiveDeletions,
615
+ cascadingDeleteCause
605
616
  );
606
617
 
607
- await this.executeMutationTriggersOrValidatorsAsync(
618
+ await this.executeMutationTriggersAsync(
608
619
  this.mutationTriggers.beforeAll,
609
620
  queryContext,
610
621
  this.entity,
611
- { type: EntityMutationType.DELETE }
622
+ { type: EntityMutationType.DELETE, cascadingDeleteCause }
612
623
  );
613
- await this.executeMutationTriggersOrValidatorsAsync(
624
+ await this.executeMutationTriggersAsync(
614
625
  this.mutationTriggers.beforeDelete,
615
626
  queryContext,
616
627
  this.entity,
617
- { type: EntityMutationType.DELETE }
628
+ { type: EntityMutationType.DELETE, cascadingDeleteCause }
618
629
  );
619
630
 
620
631
  if (!skipDatabaseDeletion) {
@@ -626,29 +637,29 @@ export class DeleteMutator<
626
637
  }
627
638
 
628
639
  const entityLoader = this.entityLoaderFactory.forLoad(this.viewerContext, queryContext);
629
- queryContext.appendPostCommitCallback(
640
+ queryContext.appendPostCommitInvalidationCallback(
630
641
  entityLoader.invalidateFieldsAsync.bind(entityLoader, this.entity.getAllDatabaseFields())
631
642
  );
632
643
 
633
- await this.executeMutationTriggersOrValidatorsAsync(
644
+ await this.executeMutationTriggersAsync(
634
645
  this.mutationTriggers.afterDelete,
635
646
  queryContext,
636
647
  this.entity,
637
- { type: EntityMutationType.DELETE }
648
+ { type: EntityMutationType.DELETE, cascadingDeleteCause }
638
649
  );
639
- await this.executeMutationTriggersOrValidatorsAsync(
650
+ await this.executeMutationTriggersAsync(
640
651
  this.mutationTriggers.afterAll,
641
652
  queryContext,
642
653
  this.entity,
643
- { type: EntityMutationType.DELETE }
654
+ { type: EntityMutationType.DELETE, cascadingDeleteCause }
644
655
  );
645
656
 
646
657
  queryContext.appendPostCommitCallback(
647
- this.executeNonTransactionalMutationTriggersOrValidatorsAsync.bind(
658
+ this.executeNonTransactionalMutationTriggersAsync.bind(
648
659
  this,
649
660
  this.mutationTriggers.afterCommit,
650
661
  this.entity,
651
- { type: EntityMutationType.DELETE }
662
+ { type: EntityMutationType.DELETE, cascadingDeleteCause }
652
663
  )
653
664
  );
654
665
 
@@ -672,7 +683,8 @@ export class DeleteMutator<
672
683
  private async processEntityDeletionForInboundEdgesAsync(
673
684
  entity: TEntity,
674
685
  queryContext: EntityTransactionalQueryContext,
675
- processedEntityIdentifiers: Set<string>
686
+ processedEntityIdentifiers: Set<string>,
687
+ cascadingDeleteCause: EntityMutationTriggerDeleteCascadeInfo | null
676
688
  ): Promise<void> {
677
689
  // prevent infinite reference cycles by keeping track of entities already processed
678
690
  if (processedEntityIdentifiers.has(entity.getUniqueIdentifier())) {
@@ -680,7 +692,9 @@ export class DeleteMutator<
680
692
  }
681
693
  processedEntityIdentifiers.add(entity.getUniqueIdentifier());
682
694
 
683
- const companionDefinition = (entity.constructor as any).getCompanionDefinition() as EntityCompanionDefinition<
695
+ const companionDefinition = (
696
+ entity.constructor as any
697
+ ).getCompanionDefinition() as EntityCompanionDefinition<
684
698
  TFields,
685
699
  TID,
686
700
  TViewerContext,
@@ -743,7 +757,11 @@ export class DeleteMutator<
743
757
  .forDelete(inboundReferenceEntity, queryContext)
744
758
  .deleteInTransactionAsync(
745
759
  processedEntityIdentifiers,
746
- /* skipDatabaseDeletion */ true // deletion is handled by DB
760
+ /* skipDatabaseDeletion */ true, // deletion is handled by DB
761
+ {
762
+ entity,
763
+ cascadingDeleteCause,
764
+ }
747
765
  )
748
766
  )
749
767
  );
@@ -767,7 +785,11 @@ export class DeleteMutator<
767
785
  .forDelete(inboundReferenceEntity, queryContext)
768
786
  .deleteInTransactionAsync(
769
787
  processedEntityIdentifiers,
770
- /* skipDatabaseDeletion */ false
788
+ /* skipDatabaseDeletion */ false,
789
+ {
790
+ entity,
791
+ cascadingDeleteCause,
792
+ }
771
793
  )
772
794
  )
773
795
  );