@expo/entity 0.18.0 → 0.22.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.
- package/build/Entity.js +8 -2
- package/build/Entity.js.map +1 -1
- package/build/EntityCompanion.d.ts +5 -0
- package/build/EntityCompanion.js +8 -1
- package/build/EntityCompanion.js.map +1 -1
- package/build/EntityCompanionProvider.d.ts +1 -1
- package/build/EntityCompanionProvider.js.map +1 -1
- package/build/EntityLoader.d.ts +3 -1
- package/build/EntityLoader.js +5 -4
- package/build/EntityLoader.js.map +1 -1
- package/build/EntityLoaderFactory.d.ts +3 -1
- package/build/EntityLoaderFactory.js +3 -2
- package/build/EntityLoaderFactory.js.map +1 -1
- package/build/EntityMutationInfo.d.ts +26 -0
- package/build/EntityMutationInfo.js +10 -0
- package/build/EntityMutationInfo.js.map +1 -0
- package/build/EntityMutationTriggerConfiguration.d.ts +3 -3
- package/build/EntityMutationValidator.d.ts +2 -2
- package/build/EntityMutationValidator.js.map +1 -1
- package/build/EntityMutator.d.ts +4 -15
- package/build/EntityMutator.js +48 -44
- package/build/EntityMutator.js.map +1 -1
- package/build/EntityPrivacyPolicy.d.ts +5 -4
- package/build/EntityPrivacyPolicy.js +60 -12
- package/build/EntityPrivacyPolicy.js.map +1 -1
- package/build/EntityQueryContext.d.ts +24 -0
- package/build/EntityQueryContext.js +43 -0
- package/build/EntityQueryContext.js.map +1 -1
- package/build/EntityQueryContextProvider.js +1 -0
- package/build/EntityQueryContextProvider.js.map +1 -1
- package/build/ViewerScopedEntityCompanion.d.ts +5 -0
- package/build/ViewerScopedEntityCompanion.js +6 -0
- package/build/ViewerScopedEntityCompanion.js.map +1 -1
- package/build/__tests__/EntityEdges-test.js +99 -3
- package/build/__tests__/EntityEdges-test.js.map +1 -1
- package/build/__tests__/EntityLoader-constructor-test.js +3 -2
- package/build/__tests__/EntityLoader-constructor-test.js.map +1 -1
- package/build/__tests__/EntityLoader-test.js +19 -11
- package/build/__tests__/EntityLoader-test.js.map +1 -1
- package/build/__tests__/EntityMutator-MutationCacheConsistency-test.d.ts +1 -0
- package/build/__tests__/EntityMutator-MutationCacheConsistency-test.js +81 -0
- package/build/__tests__/EntityMutator-MutationCacheConsistency-test.js.map +1 -0
- package/build/__tests__/EntityMutator-test.js +16 -14
- package/build/__tests__/EntityMutator-test.js.map +1 -1
- package/build/__tests__/EntityPrivacyPolicy-test.js +119 -43
- package/build/__tests__/EntityPrivacyPolicy-test.js.map +1 -1
- package/build/__tests__/EntityQueryContext-test.d.ts +1 -0
- package/build/__tests__/EntityQueryContext-test.js +56 -0
- package/build/__tests__/EntityQueryContext-test.js.map +1 -0
- package/build/__tests__/EntitySecondaryCacheLoader-test.js +1 -1
- package/build/__tests__/EntitySecondaryCacheLoader-test.js.map +1 -1
- package/build/index.d.ts +1 -0
- package/build/index.js +1 -0
- package/build/index.js.map +1 -1
- package/build/metrics/IEntityMetricsAdapter.d.ts +16 -0
- package/build/metrics/IEntityMetricsAdapter.js +6 -1
- package/build/metrics/IEntityMetricsAdapter.js.map +1 -1
- package/build/metrics/NoOpEntityMetricsAdapter.d.ts +2 -1
- package/build/metrics/NoOpEntityMetricsAdapter.js +1 -0
- package/build/metrics/NoOpEntityMetricsAdapter.js.map +1 -1
- package/package.json +1 -1
- package/src/Entity.ts +10 -2
- package/src/EntityCompanion.ts +10 -2
- package/src/EntityCompanionProvider.ts +1 -1
- package/src/EntityLoader.ts +9 -4
- package/src/EntityLoaderFactory.ts +5 -2
- package/src/EntityMutationInfo.ts +47 -0
- package/src/EntityMutationTriggerConfiguration.ts +3 -3
- package/src/EntityMutationValidator.ts +8 -2
- package/src/EntityMutator.ts +91 -71
- package/src/EntityPrivacyPolicy.ts +76 -18
- package/src/EntityQueryContext.ts +54 -0
- package/src/EntityQueryContextProvider.ts +1 -0
- package/src/ViewerScopedEntityCompanion.ts +8 -0
- package/src/__tests__/EntityEdges-test.ts +163 -9
- package/src/__tests__/EntityLoader-constructor-test.ts +4 -2
- package/src/__tests__/EntityLoader-test.ts +39 -11
- package/src/__tests__/EntityMutator-MutationCacheConsistency-test.ts +105 -0
- package/src/__tests__/EntityMutator-test.ts +38 -13
- package/src/__tests__/EntityPrivacyPolicy-test.ts +189 -52
- package/src/__tests__/EntityQueryContext-test.ts +82 -0
- package/src/__tests__/EntitySecondaryCacheLoader-test.ts +1 -0
- package/src/index.ts +1 -0
- package/src/metrics/IEntityMetricsAdapter.ts +23 -0
- package/src/metrics/NoOpEntityMetricsAdapter.ts +2 -0
package/src/EntityLoader.ts
CHANGED
|
@@ -16,6 +16,7 @@ import ViewerContext from './ViewerContext';
|
|
|
16
16
|
import EntityInvalidFieldValueError from './errors/EntityInvalidFieldValueError';
|
|
17
17
|
import EntityNotFoundError from './errors/EntityNotFoundError';
|
|
18
18
|
import EntityDataManager from './internal/EntityDataManager';
|
|
19
|
+
import IEntityMetricsAdapter from './metrics/IEntityMetricsAdapter';
|
|
19
20
|
import { mapMap, mapMapAsync } from './utils/collections/maps';
|
|
20
21
|
|
|
21
22
|
/**
|
|
@@ -49,7 +50,8 @@ export default class EntityLoader<
|
|
|
49
50
|
TSelectedFields
|
|
50
51
|
>,
|
|
51
52
|
private readonly privacyPolicy: TPrivacyPolicy,
|
|
52
|
-
private readonly dataManager: EntityDataManager<TFields
|
|
53
|
+
private readonly dataManager: EntityDataManager<TFields>,
|
|
54
|
+
protected readonly metricsAdapter: IEntityMetricsAdapter
|
|
53
55
|
) {}
|
|
54
56
|
|
|
55
57
|
/**
|
|
@@ -216,7 +218,8 @@ export default class EntityLoader<
|
|
|
216
218
|
this.privacyPolicy.authorizeReadAsync(
|
|
217
219
|
this.viewerContext,
|
|
218
220
|
this.queryContext,
|
|
219
|
-
uncheckedEntityResult.value
|
|
221
|
+
uncheckedEntityResult.value,
|
|
222
|
+
this.metricsAdapter
|
|
220
223
|
)
|
|
221
224
|
);
|
|
222
225
|
})
|
|
@@ -269,7 +272,8 @@ export default class EntityLoader<
|
|
|
269
272
|
this.privacyPolicy.authorizeReadAsync(
|
|
270
273
|
this.viewerContext,
|
|
271
274
|
this.queryContext,
|
|
272
|
-
uncheckedEntityResult.value
|
|
275
|
+
uncheckedEntityResult.value,
|
|
276
|
+
this.metricsAdapter
|
|
273
277
|
)
|
|
274
278
|
);
|
|
275
279
|
})
|
|
@@ -328,7 +332,8 @@ export default class EntityLoader<
|
|
|
328
332
|
this.privacyPolicy.authorizeReadAsync(
|
|
329
333
|
this.viewerContext,
|
|
330
334
|
this.queryContext,
|
|
331
|
-
uncheckedEntityResult.value
|
|
335
|
+
uncheckedEntityResult.value,
|
|
336
|
+
this.metricsAdapter
|
|
332
337
|
)
|
|
333
338
|
);
|
|
334
339
|
})
|
|
@@ -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,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EntityTriggerMutationInfo } from './EntityMutationInfo';
|
|
2
2
|
import { EntityTransactionalQueryContext } from './EntityQueryContext';
|
|
3
3
|
import ReadonlyEntity from './ReadonlyEntity';
|
|
4
4
|
import ViewerContext from './ViewerContext';
|
|
@@ -80,7 +80,7 @@ export abstract class EntityMutationTrigger<
|
|
|
80
80
|
viewerContext: TViewerContext,
|
|
81
81
|
queryContext: EntityTransactionalQueryContext,
|
|
82
82
|
entity: TEntity,
|
|
83
|
-
mutationInfo:
|
|
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:
|
|
101
|
+
mutationInfo: EntityTriggerMutationInfo<TFields, TID, TViewerContext, TEntity, TSelectedFields>
|
|
102
102
|
): Promise<void>;
|
|
103
103
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EntityValidatorMutationInfo } from './EntityMutationInfo';
|
|
2
2
|
import { EntityTransactionalQueryContext } from './EntityQueryContext';
|
|
3
3
|
import ReadonlyEntity from './ReadonlyEntity';
|
|
4
4
|
import ViewerContext from './ViewerContext';
|
|
@@ -18,6 +18,12 @@ export default abstract class EntityMutationValidator<
|
|
|
18
18
|
viewerContext: TViewerContext,
|
|
19
19
|
queryContext: EntityTransactionalQueryContext,
|
|
20
20
|
entity: TEntity,
|
|
21
|
-
mutationInfo:
|
|
21
|
+
mutationInfo: EntityValidatorMutationInfo<
|
|
22
|
+
TFields,
|
|
23
|
+
TID,
|
|
24
|
+
TViewerContext,
|
|
25
|
+
TEntity,
|
|
26
|
+
TSelectedFields
|
|
27
|
+
>
|
|
22
28
|
): Promise<void>;
|
|
23
29
|
}
|
package/src/EntityMutator.ts
CHANGED
|
@@ -7,6 +7,12 @@ import EntityConfiguration from './EntityConfiguration';
|
|
|
7
7
|
import EntityDatabaseAdapter from './EntityDatabaseAdapter';
|
|
8
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
|
|
114
|
-
|
|
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
118
|
queryContext: EntityTransactionalQueryContext,
|
|
119
119
|
entity: TEntity,
|
|
120
|
-
mutationInfo:
|
|
120
|
+
mutationInfo: EntityTriggerMutationInfo<TFields, TID, TViewerContext, TEntity, TSelectedFields>
|
|
121
121
|
): Promise<void> {
|
|
122
|
-
if (!
|
|
122
|
+
if (!triggers) {
|
|
123
123
|
return;
|
|
124
124
|
}
|
|
125
125
|
await Promise.all(
|
|
126
|
-
|
|
127
|
-
|
|
126
|
+
triggers.map((trigger) =>
|
|
127
|
+
trigger.executeAsync(this.viewerContext, queryContext, entity, mutationInfo)
|
|
128
128
|
)
|
|
129
129
|
);
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
-
protected async
|
|
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:
|
|
143
|
+
mutationInfo: EntityTriggerMutationInfo<TFields, TID, TViewerContext, TEntity, TSelectedFields>
|
|
144
144
|
): Promise<void> {
|
|
145
145
|
if (!triggers) {
|
|
146
146
|
return;
|
|
@@ -220,26 +220,27 @@ export class CreateMutator<
|
|
|
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.
|
|
231
|
+
await this.executeMutationValidatorsAsync(
|
|
231
232
|
this.mutationValidators,
|
|
232
233
|
queryContext,
|
|
233
234
|
temporaryEntityForPrivacyCheck,
|
|
234
235
|
{ type: EntityMutationType.CREATE }
|
|
235
236
|
);
|
|
236
|
-
await this.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
448
|
+
queryContext.appendPostCommitInvalidationCallback(
|
|
447
449
|
entityLoader.invalidateFieldsAsync.bind(
|
|
448
450
|
entityLoader,
|
|
449
451
|
this.originalEntity.getAllDatabaseFields()
|
|
450
452
|
)
|
|
451
453
|
);
|
|
452
|
-
queryContext.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
578
|
-
skipDatabaseDeletion: boolean
|
|
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(
|
|
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.
|
|
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.
|
|
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.
|
|
640
|
+
queryContext.appendPostCommitInvalidationCallback(
|
|
630
641
|
entityLoader.invalidateFieldsAsync.bind(entityLoader, this.entity.getAllDatabaseFields())
|
|
631
642
|
);
|
|
632
643
|
|
|
633
|
-
await this.
|
|
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.
|
|
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.
|
|
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())) {
|
|
@@ -745,7 +757,11 @@ export class DeleteMutator<
|
|
|
745
757
|
.forDelete(inboundReferenceEntity, queryContext)
|
|
746
758
|
.deleteInTransactionAsync(
|
|
747
759
|
processedEntityIdentifiers,
|
|
748
|
-
/* skipDatabaseDeletion */ true // deletion is handled by DB
|
|
760
|
+
/* skipDatabaseDeletion */ true, // deletion is handled by DB
|
|
761
|
+
{
|
|
762
|
+
entity,
|
|
763
|
+
cascadingDeleteCause,
|
|
764
|
+
}
|
|
749
765
|
)
|
|
750
766
|
)
|
|
751
767
|
);
|
|
@@ -769,7 +785,11 @@ export class DeleteMutator<
|
|
|
769
785
|
.forDelete(inboundReferenceEntity, queryContext)
|
|
770
786
|
.deleteInTransactionAsync(
|
|
771
787
|
processedEntityIdentifiers,
|
|
772
|
-
/* skipDatabaseDeletion */ false
|
|
788
|
+
/* skipDatabaseDeletion */ false,
|
|
789
|
+
{
|
|
790
|
+
entity,
|
|
791
|
+
cascadingDeleteCause,
|
|
792
|
+
}
|
|
773
793
|
)
|
|
774
794
|
)
|
|
775
795
|
);
|