@expo/entity 0.31.1 → 0.32.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/ComposedEntityCacheAdapter.d.ts +4 -6
- package/build/ComposedEntityCacheAdapter.js +3 -6
- package/build/ComposedEntityCacheAdapter.js.map +1 -1
- package/build/EnforcingEntityLoader.d.ts +1 -1
- package/build/Entity.d.ts +20 -10
- package/build/Entity.js +2 -2
- package/build/Entity.js.map +1 -1
- package/build/EntityAssociationLoader.d.ts +9 -9
- package/build/EntityCompanion.d.ts +6 -5
- package/build/EntityCompanion.js +6 -4
- package/build/EntityCompanion.js.map +1 -1
- package/build/EntityCompanionProvider.d.ts +28 -36
- package/build/EntityCompanionProvider.js +4 -19
- package/build/EntityCompanionProvider.js.map +1 -1
- package/build/EntityConfiguration.d.ts +3 -3
- package/build/EntityConfiguration.js +2 -2
- package/build/EntityConfiguration.js.map +1 -1
- package/build/EntityDatabaseAdapter.d.ts +1 -1
- package/build/EntityDatabaseAdapter.js +1 -1
- package/build/EntityDatabaseAdapter.js.map +1 -1
- package/build/EntityFieldDefinition.d.ts +2 -2
- package/build/EntityFieldDefinition.js +1 -1
- package/build/EntityFieldDefinition.js.map +1 -1
- package/build/EntityLoader.d.ts +4 -2
- package/build/EntityLoader.js +21 -7
- package/build/EntityLoader.js.map +1 -1
- package/build/EntityLoaderFactory.d.ts +4 -7
- package/build/EntityLoaderFactory.js +3 -5
- package/build/EntityLoaderFactory.js.map +1 -1
- package/build/EntityMutationInfo.d.ts +3 -3
- package/build/EntityMutationInfo.js +1 -1
- package/build/EntityMutationInfo.js.map +1 -1
- package/build/EntityMutationTriggerConfiguration.d.ts +3 -3
- package/build/EntityMutationValidator.d.ts +1 -1
- package/build/EntityMutator.d.ts +9 -7
- package/build/EntityMutator.js +21 -21
- package/build/EntityMutator.js.map +1 -1
- package/build/EntityMutatorFactory.d.ts +4 -2
- package/build/EntityMutatorFactory.js +5 -4
- package/build/EntityMutatorFactory.js.map +1 -1
- package/build/EntityPrivacyPolicy.d.ts +3 -3
- package/build/EntityPrivacyPolicy.js +2 -2
- package/build/EntityPrivacyPolicy.js.map +1 -1
- package/build/EntityQueryContext.d.ts +13 -5
- package/build/EntityQueryContext.js +11 -4
- package/build/EntityQueryContext.js.map +1 -1
- package/build/EntityQueryContextProvider.d.ts +3 -3
- package/build/EntityQueryContextProvider.js +2 -2
- package/build/EntityQueryContextProvider.js.map +1 -1
- package/build/EntitySecondaryCacheLoader.d.ts +1 -1
- package/build/EntitySecondaryCacheLoader.js +1 -1
- package/build/EntitySecondaryCacheLoader.js.map +1 -1
- package/build/GenericEntityCacheAdapter.d.ts +14 -0
- package/build/GenericEntityCacheAdapter.js +38 -0
- package/build/GenericEntityCacheAdapter.js.map +1 -0
- package/build/{EntityCacheAdapter.d.ts → IEntityCacheAdapter.d.ts} +5 -8
- package/build/IEntityCacheAdapter.js +3 -0
- package/build/IEntityCacheAdapter.js.map +1 -0
- package/build/IEntityCacheAdapterProvider.d.ts +2 -2
- package/build/IEntityGenericCacher.d.ts +31 -2
- package/build/ReadonlyEntity.d.ts +19 -7
- package/build/ReadonlyEntity.js +15 -13
- package/build/ReadonlyEntity.js.map +1 -1
- package/build/ViewerContext.d.ts +3 -3
- package/build/ViewerContext.js +3 -3
- package/build/ViewerContext.js.map +1 -1
- package/build/ViewerScopedEntityCompanion.d.ts +2 -2
- package/build/ViewerScopedEntityCompanion.js.map +1 -1
- package/build/ViewerScopedEntityCompanionProvider.d.ts +3 -3
- package/build/ViewerScopedEntityCompanionProvider.js +3 -3
- package/build/ViewerScopedEntityCompanionProvider.js.map +1 -1
- package/build/ViewerScopedEntityLoaderFactory.d.ts +1 -1
- package/build/ViewerScopedEntityMutatorFactory.d.ts +1 -1
- package/build/__tests__/ComposedCacheAdapter-test.js +4 -8
- package/build/__tests__/ComposedCacheAdapter-test.js.map +1 -1
- package/build/__tests__/EnforcingEntityLoader-test.js +1 -0
- package/build/__tests__/EnforcingEntityLoader-test.js.map +1 -1
- package/build/__tests__/Entity-test.js +42 -20
- package/build/__tests__/Entity-test.js.map +1 -1
- package/build/__tests__/EntityAssociationLoader-test.js +6 -6
- package/build/__tests__/EntityAssociationLoader-test.js.map +1 -1
- package/build/__tests__/EntityCommonUseCases-test.js +20 -22
- package/build/__tests__/EntityCommonUseCases-test.js.map +1 -1
- package/build/__tests__/EntityCompanion-test.js +2 -1
- package/build/__tests__/EntityCompanion-test.js.map +1 -1
- package/build/__tests__/EntityCompanionProvider-test.js +15 -40
- package/build/__tests__/EntityCompanionProvider-test.js.map +1 -1
- package/build/__tests__/EntityEdges-test.js +48 -54
- package/build/__tests__/EntityEdges-test.js.map +1 -1
- package/build/__tests__/EntityLoader-constructor-test.d.ts +9 -5
- package/build/__tests__/EntityLoader-constructor-test.js +13 -14
- 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.js +20 -22
- package/build/__tests__/EntityMutator-MutationCacheConsistency-test.js.map +1 -1
- package/build/__tests__/EntityMutator-test.js +67 -14
- package/build/__tests__/EntityMutator-test.js.map +1 -1
- package/build/__tests__/EntityPrivacyPolicy-test.js +82 -29
- package/build/__tests__/EntityPrivacyPolicy-test.js.map +1 -1
- package/build/__tests__/EntityQueryContext-test.js +12 -0
- package/build/__tests__/EntityQueryContext-test.js.map +1 -1
- package/build/__tests__/EntitySecondaryCacheLoader-test.js +1 -2
- package/build/__tests__/EntitySecondaryCacheLoader-test.js.map +1 -1
- package/build/__tests__/EntitySelfReferentialEdges-test.js +16 -20
- package/build/__tests__/EntitySelfReferentialEdges-test.js.map +1 -1
- package/build/__tests__/GenericEntityCacheAdapter-test.d.ts +1 -0
- package/build/__tests__/GenericEntityCacheAdapter-test.js +80 -0
- package/build/__tests__/GenericEntityCacheAdapter-test.js.map +1 -0
- package/build/__tests__/ReadonlyEntity-test.js +79 -13
- package/build/__tests__/ReadonlyEntity-test.js.map +1 -1
- package/build/__tests__/ViewerScopedEntityCompanionProvider-test.js +2 -25
- package/build/__tests__/ViewerScopedEntityCompanionProvider-test.js.map +1 -1
- package/build/__tests__/cases/TwoEntitySameTableDisjointRows-test.js +20 -23
- package/build/__tests__/cases/TwoEntitySameTableDisjointRows-test.js.map +1 -1
- package/build/__tests__/cases/TwoEntitySameTableOverlappingRows-test.js +17 -20
- package/build/__tests__/cases/TwoEntitySameTableOverlappingRows-test.js.map +1 -1
- package/build/errors/EntityError.js +2 -2
- package/build/errors/EntityError.js.map +1 -1
- package/build/errors/EntityInvalidFieldValueError.d.ts +2 -2
- package/build/errors/EntityInvalidFieldValueError.js.map +1 -1
- package/build/errors/EntityNotAuthorizedError.d.ts +2 -2
- package/build/errors/EntityNotAuthorizedError.js +1 -1
- package/build/errors/EntityNotAuthorizedError.js.map +1 -1
- package/build/errors/EntityNotFoundError.d.ts +2 -2
- package/build/errors/EntityNotFoundError.js.map +1 -1
- package/build/index.d.ts +2 -1
- package/build/index.js +3 -3
- package/build/index.js.map +1 -1
- package/build/internal/EntityDataManager.d.ts +1 -1
- package/build/internal/EntityDataManager.js +1 -1
- package/build/internal/EntityDataManager.js.map +1 -1
- package/build/internal/EntityFieldTransformationUtils.d.ts +1 -1
- package/build/internal/EntityFieldTransformationUtils.js +4 -4
- package/build/internal/EntityFieldTransformationUtils.js.map +1 -1
- package/build/internal/EntityTableDataCoordinator.d.ts +3 -3
- package/build/internal/EntityTableDataCoordinator.js.map +1 -1
- package/build/internal/ReadThroughEntityCache.d.ts +3 -3
- package/build/internal/ReadThroughEntityCache.js +1 -1
- package/build/internal/ReadThroughEntityCache.js.map +1 -1
- package/build/internal/__tests__/EntityDataManager-test.js +1 -1
- package/build/internal/__tests__/EntityDataManager-test.js.map +1 -1
- package/build/internal/__tests__/ReadThroughEntityCache-test.js.map +1 -1
- package/build/metrics/EntityMetricsUtils.js.map +1 -1
- package/build/metrics/IEntityMetricsAdapter.js +4 -4
- package/build/metrics/IEntityMetricsAdapter.js.map +1 -1
- package/build/rules/AlwaysAllowPrivacyPolicyRule.d.ts +2 -2
- package/build/rules/AlwaysAllowPrivacyPolicyRule.js.map +1 -1
- package/build/rules/AlwaysDenyPrivacyPolicyRule.d.ts +2 -2
- package/build/rules/AlwaysDenyPrivacyPolicyRule.js.map +1 -1
- package/build/rules/AlwaysSkipPrivacyPolicyRule.d.ts +2 -2
- package/build/rules/AlwaysSkipPrivacyPolicyRule.js.map +1 -1
- package/build/rules/PrivacyPolicyRule.d.ts +1 -1
- package/build/rules/PrivacyPolicyRule.js +1 -1
- package/build/rules/PrivacyPolicyRule.js.map +1 -1
- package/build/testfixtures/DateIDTestEntity.d.ts +2 -3
- package/build/testfixtures/DateIDTestEntity.js +7 -9
- package/build/testfixtures/DateIDTestEntity.js.map +1 -1
- package/build/testfixtures/SimpleTestEntity.d.ts +3 -4
- package/build/testfixtures/SimpleTestEntity.js +7 -9
- package/build/testfixtures/SimpleTestEntity.js.map +1 -1
- package/build/testfixtures/TestEntity.d.ts +2 -3
- package/build/testfixtures/TestEntity.js +14 -10
- package/build/testfixtures/TestEntity.js.map +1 -1
- package/build/testfixtures/TestEntity2.d.ts +2 -3
- package/build/testfixtures/TestEntity2.js +7 -9
- package/build/testfixtures/TestEntity2.js.map +1 -1
- package/build/testfixtures/TestEntityNumberKey.d.ts +2 -3
- package/build/testfixtures/TestEntityNumberKey.js +7 -9
- package/build/testfixtures/TestEntityNumberKey.js.map +1 -1
- package/build/utils/testing/PrivacyPolicyRuleTestUtils.d.ts +4 -4
- package/build/utils/testing/StubCacheAdapter.d.ts +6 -5
- package/build/utils/testing/StubCacheAdapter.js +5 -6
- package/build/utils/testing/StubCacheAdapter.js.map +1 -1
- package/build/utils/testing/StubDatabaseAdapterProvider.js.map +1 -1
- package/build/utils/testing/StubQueryContextProvider.d.ts +2 -1
- package/build/utils/testing/StubQueryContextProvider.js +1 -1
- package/build/utils/testing/StubQueryContextProvider.js.map +1 -1
- package/build/utils/testing/createUnitTestEntityCompanionProvider.js +2 -2
- package/build/utils/testing/createUnitTestEntityCompanionProvider.js.map +1 -1
- package/package.json +3 -3
- package/src/ComposedEntityCacheAdapter.ts +4 -11
- package/src/EnforcingEntityLoader.ts +1 -1
- package/src/Entity.ts +23 -12
- package/src/EntityAssociationLoader.ts +12 -12
- package/src/EntityCompanion.ts +13 -32
- package/src/EntityCompanionProvider.ts +41 -80
- package/src/EntityConfiguration.ts +4 -5
- package/src/EntityFieldDefinition.ts +2 -2
- package/src/EntityLoader.ts +19 -2
- package/src/EntityLoaderFactory.ts +7 -9
- package/src/EntityMutationInfo.ts +2 -2
- package/src/EntityMutationTriggerConfiguration.ts +3 -3
- package/src/EntityMutationValidator.ts +1 -1
- package/src/EntityMutator.ts +38 -31
- package/src/EntityMutatorFactory.ts +6 -1
- package/src/EntityPrivacyPolicy.ts +2 -2
- package/src/EntityQueryContext.ts +24 -4
- package/src/EntityQueryContextProvider.ts +7 -5
- package/src/EntitySecondaryCacheLoader.ts +1 -1
- package/src/GenericEntityCacheAdapter.ts +65 -0
- package/src/{EntityCacheAdapter.ts → IEntityCacheAdapter.ts} +5 -8
- package/src/IEntityCacheAdapterProvider.ts +2 -2
- package/src/IEntityGenericCacher.ts +32 -2
- package/src/ReadonlyEntity.ts +32 -32
- package/src/ViewerContext.ts +10 -8
- package/src/ViewerScopedEntityCompanion.ts +2 -2
- package/src/ViewerScopedEntityCompanionProvider.ts +4 -12
- package/src/ViewerScopedEntityLoaderFactory.ts +1 -1
- package/src/ViewerScopedEntityMutatorFactory.ts +1 -1
- package/src/__tests__/ComposedCacheAdapter-test.ts +6 -11
- package/src/__tests__/EnforcingEntityLoader-test.ts +1 -0
- package/src/__tests__/Entity-test.ts +42 -21
- package/src/__tests__/EntityCommonUseCases-test.ts +20 -22
- package/src/__tests__/EntityCompanion-test.ts +6 -9
- package/src/__tests__/EntityCompanionProvider-test.ts +14 -26
- package/src/__tests__/EntityEdges-test.ts +43 -49
- package/src/__tests__/EntityLoader-constructor-test.ts +16 -12
- package/src/__tests__/EntityLoader-test.ts +9 -0
- package/src/__tests__/EntityMutator-MutationCacheConsistency-test.ts +20 -22
- package/src/__tests__/EntityMutator-test.ts +119 -19
- package/src/__tests__/EntityPrivacyPolicy-test.ts +82 -29
- package/src/__tests__/EntityQueryContext-test.ts +23 -1
- package/src/__tests__/EntitySelfReferentialEdges-test.ts +8 -10
- package/src/__tests__/GenericEntityCacheAdapter-test.ts +102 -0
- package/src/__tests__/ReadonlyEntity-test.ts +79 -13
- package/src/__tests__/ViewerScopedEntityCompanionProvider-test.ts +2 -5
- package/src/__tests__/cases/TwoEntitySameTableDisjointRows-test.ts +30 -24
- package/src/__tests__/cases/TwoEntitySameTableOverlappingRows-test.ts +14 -18
- package/src/errors/EntityInvalidFieldValueError.ts +2 -2
- package/src/errors/EntityNotAuthorizedError.ts +2 -2
- package/src/errors/EntityNotFoundError.ts +2 -2
- package/src/index.ts +2 -1
- package/src/internal/EntityDataManager.ts +1 -1
- package/src/internal/EntityTableDataCoordinator.ts +4 -4
- package/src/internal/ReadThroughEntityCache.ts +2 -2
- package/src/internal/__tests__/EntityDataManager-test.ts +2 -1
- package/src/internal/__tests__/ReadThroughEntityCache-test.ts +8 -8
- package/src/metrics/EntityMetricsUtils.ts +1 -1
- package/src/rules/AlwaysAllowPrivacyPolicyRule.ts +2 -2
- package/src/rules/AlwaysDenyPrivacyPolicyRule.ts +2 -2
- package/src/rules/AlwaysSkipPrivacyPolicyRule.ts +2 -2
- package/src/rules/PrivacyPolicyRule.ts +1 -1
- package/src/testfixtures/DateIDTestEntity.ts +6 -8
- package/src/testfixtures/SimpleTestEntity.ts +6 -8
- package/src/testfixtures/TestEntity.ts +19 -15
- package/src/testfixtures/TestEntity2.ts +6 -8
- package/src/testfixtures/TestEntityNumberKey.ts +6 -8
- package/src/utils/testing/PrivacyPolicyRuleTestUtils.ts +4 -4
- package/src/utils/testing/StubCacheAdapter.ts +9 -11
- package/src/utils/testing/StubDatabaseAdapterProvider.ts +1 -1
- package/src/utils/testing/StubQueryContextProvider.ts +4 -3
- package/src/utils/testing/createUnitTestEntityCompanionProvider.ts +3 -3
- package/build/EntityCacheAdapter.js +0 -13
- package/build/EntityCacheAdapter.js.map +0 -1
package/src/EntityCompanion.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import EntityCompanionProvider, { EntityCompanionDefinition } from './EntityCompanionProvider';
|
|
2
2
|
import EntityLoaderFactory from './EntityLoaderFactory';
|
|
3
|
-
import EntityMutationTriggerConfiguration from './EntityMutationTriggerConfiguration';
|
|
4
|
-
import EntityMutationValidator from './EntityMutationValidator';
|
|
5
3
|
import EntityMutatorFactory from './EntityMutatorFactory';
|
|
6
4
|
import EntityPrivacyPolicy from './EntityPrivacyPolicy';
|
|
7
5
|
import EntityQueryContextProvider from './EntityQueryContextProvider';
|
|
@@ -18,7 +16,7 @@ export interface IPrivacyPolicyClass<TPrivacyPolicy> {
|
|
|
18
16
|
* Composition root responsible for orchestrating setup of Entity mutators and loaders.
|
|
19
17
|
*/
|
|
20
18
|
export default class EntityCompanion<
|
|
21
|
-
TFields,
|
|
19
|
+
TFields extends object,
|
|
22
20
|
TID extends NonNullable<TFields[TSelectedFields]>,
|
|
23
21
|
TViewerContext extends ViewerContext,
|
|
24
22
|
TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>,
|
|
@@ -31,6 +29,8 @@ export default class EntityCompanion<
|
|
|
31
29
|
>,
|
|
32
30
|
TSelectedFields extends keyof TFields
|
|
33
31
|
> {
|
|
32
|
+
public readonly privacyPolicy: TPrivacyPolicy;
|
|
33
|
+
|
|
34
34
|
private readonly entityLoaderFactory: EntityLoaderFactory<
|
|
35
35
|
TFields,
|
|
36
36
|
TID,
|
|
@@ -49,7 +49,8 @@ export default class EntityCompanion<
|
|
|
49
49
|
>;
|
|
50
50
|
|
|
51
51
|
constructor(
|
|
52
|
-
|
|
52
|
+
public readonly entityCompanionProvider: EntityCompanionProvider,
|
|
53
|
+
public readonly entityCompanionDefinition: EntityCompanionDefinition<
|
|
53
54
|
TFields,
|
|
54
55
|
TID,
|
|
55
56
|
TViewerContext,
|
|
@@ -58,24 +59,9 @@ export default class EntityCompanion<
|
|
|
58
59
|
TSelectedFields
|
|
59
60
|
>,
|
|
60
61
|
private readonly tableDataCoordinator: EntityTableDataCoordinator<TFields>,
|
|
61
|
-
PrivacyPolicyClass: IPrivacyPolicyClass<TPrivacyPolicy>,
|
|
62
|
-
mutationValidators: EntityMutationValidator<
|
|
63
|
-
TFields,
|
|
64
|
-
TID,
|
|
65
|
-
TViewerContext,
|
|
66
|
-
TEntity,
|
|
67
|
-
TSelectedFields
|
|
68
|
-
>[],
|
|
69
|
-
mutationTriggers: EntityMutationTriggerConfiguration<
|
|
70
|
-
TFields,
|
|
71
|
-
TID,
|
|
72
|
-
TViewerContext,
|
|
73
|
-
TEntity,
|
|
74
|
-
TSelectedFields
|
|
75
|
-
>,
|
|
76
62
|
private readonly metricsAdapter: IEntityMetricsAdapter
|
|
77
63
|
) {
|
|
78
|
-
|
|
64
|
+
this.privacyPolicy = new entityCompanionDefinition.privacyPolicyClass();
|
|
79
65
|
this.entityLoaderFactory = new EntityLoaderFactory<
|
|
80
66
|
TFields,
|
|
81
67
|
TID,
|
|
@@ -83,19 +69,14 @@ export default class EntityCompanion<
|
|
|
83
69
|
TEntity,
|
|
84
70
|
TPrivacyPolicy,
|
|
85
71
|
TSelectedFields
|
|
86
|
-
>(
|
|
87
|
-
tableDataCoordinator.entityConfiguration,
|
|
88
|
-
entityClass,
|
|
89
|
-
privacyPolicy,
|
|
90
|
-
tableDataCoordinator.dataManager,
|
|
91
|
-
metricsAdapter
|
|
92
|
-
);
|
|
72
|
+
>(this, tableDataCoordinator.dataManager, metricsAdapter);
|
|
93
73
|
this.entityMutatorFactory = new EntityMutatorFactory(
|
|
74
|
+
entityCompanionProvider,
|
|
94
75
|
tableDataCoordinator.entityConfiguration,
|
|
95
|
-
entityClass,
|
|
96
|
-
privacyPolicy,
|
|
97
|
-
mutationValidators,
|
|
98
|
-
mutationTriggers,
|
|
76
|
+
entityCompanionDefinition.entityClass,
|
|
77
|
+
this.privacyPolicy,
|
|
78
|
+
entityCompanionDefinition.mutationValidators ?? [],
|
|
79
|
+
entityCompanionDefinition.mutationTriggers ?? {},
|
|
99
80
|
this.entityLoaderFactory,
|
|
100
81
|
tableDataCoordinator.databaseAdapter,
|
|
101
82
|
metricsAdapter
|
|
@@ -49,8 +49,8 @@ export interface CacheAdapterFlavorDefinition {
|
|
|
49
49
|
* Definition for constructing a companion for an entity. Defines the core set of objects
|
|
50
50
|
* used to power the entity framework for a particular type of entity.
|
|
51
51
|
*/
|
|
52
|
-
export
|
|
53
|
-
TFields,
|
|
52
|
+
export interface EntityCompanionDefinition<
|
|
53
|
+
TFields extends object,
|
|
54
54
|
TID extends NonNullable<TFields[TSelectedFields]>,
|
|
55
55
|
TViewerContext extends ViewerContext,
|
|
56
56
|
TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>,
|
|
@@ -63,6 +63,9 @@ export class EntityCompanionDefinition<
|
|
|
63
63
|
>,
|
|
64
64
|
TSelectedFields extends keyof TFields = keyof TFields
|
|
65
65
|
> {
|
|
66
|
+
/**
|
|
67
|
+
* The concrete Entity class for which this is the definition.
|
|
68
|
+
*/
|
|
66
69
|
readonly entityClass: IEntityClass<
|
|
67
70
|
TFields,
|
|
68
71
|
TID,
|
|
@@ -71,85 +74,45 @@ export class EntityCompanionDefinition<
|
|
|
71
74
|
TPrivacyPolicy,
|
|
72
75
|
TSelectedFields
|
|
73
76
|
>;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* The EntityConfiguration for this entity.
|
|
80
|
+
*/
|
|
74
81
|
readonly entityConfiguration: EntityConfiguration<TFields>;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* The EntityPrivacyPolicy class for this entity.
|
|
85
|
+
*/
|
|
75
86
|
readonly privacyPolicyClass: IPrivacyPolicyClass<TPrivacyPolicy>;
|
|
76
|
-
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* An optional list of EntityMutationValidator for this entity.
|
|
90
|
+
*/
|
|
91
|
+
readonly mutationValidators?: EntityMutationValidator<
|
|
77
92
|
TFields,
|
|
78
93
|
TID,
|
|
79
94
|
TViewerContext,
|
|
80
95
|
TEntity,
|
|
81
96
|
TSelectedFields
|
|
82
97
|
>[];
|
|
83
|
-
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* An optional list of EntityMutationTrigger for this entity.
|
|
101
|
+
*/
|
|
102
|
+
readonly mutationTriggers?: EntityMutationTriggerConfiguration<
|
|
84
103
|
TFields,
|
|
85
104
|
TID,
|
|
86
105
|
TViewerContext,
|
|
87
106
|
TEntity,
|
|
88
107
|
TSelectedFields
|
|
89
108
|
>;
|
|
90
|
-
readonly entitySelectedFields: TSelectedFields[];
|
|
91
109
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
entitySelectedFields = Array.from(entityConfiguration.schema.keys()) as TSelectedFields[],
|
|
99
|
-
}: {
|
|
100
|
-
/**
|
|
101
|
-
* The concrete Entity class for which this is the definition.
|
|
102
|
-
*/
|
|
103
|
-
entityClass: IEntityClass<
|
|
104
|
-
TFields,
|
|
105
|
-
TID,
|
|
106
|
-
TViewerContext,
|
|
107
|
-
TEntity,
|
|
108
|
-
TPrivacyPolicy,
|
|
109
|
-
TSelectedFields
|
|
110
|
-
>;
|
|
111
|
-
/**
|
|
112
|
-
* The EntityConfiguration for this entity.
|
|
113
|
-
*/
|
|
114
|
-
entityConfiguration: EntityConfiguration<TFields>;
|
|
115
|
-
/**
|
|
116
|
-
* The EntityPrivacyPolicy class for this entity.
|
|
117
|
-
*/
|
|
118
|
-
privacyPolicyClass: IPrivacyPolicyClass<TPrivacyPolicy>;
|
|
119
|
-
/**
|
|
120
|
-
* An optional list of EntityMutationValidator for this entity.
|
|
121
|
-
*/
|
|
122
|
-
mutationValidators?: () => EntityMutationValidator<
|
|
123
|
-
TFields,
|
|
124
|
-
TID,
|
|
125
|
-
TViewerContext,
|
|
126
|
-
TEntity,
|
|
127
|
-
TSelectedFields
|
|
128
|
-
>[];
|
|
129
|
-
/**
|
|
130
|
-
* An optional list of EntityMutationTrigger for this entity.
|
|
131
|
-
*/
|
|
132
|
-
mutationTriggers?: () => EntityMutationTriggerConfiguration<
|
|
133
|
-
TFields,
|
|
134
|
-
TID,
|
|
135
|
-
TViewerContext,
|
|
136
|
-
TEntity,
|
|
137
|
-
TSelectedFields
|
|
138
|
-
>;
|
|
139
|
-
/**
|
|
140
|
-
* An optional subset of fields defined in the EntityConfiguration which belong to this entity.
|
|
141
|
-
* For use when multiple types of entities are backed by a single table (EntityConfiguration) yet
|
|
142
|
-
* only expose a subset of the fields.
|
|
143
|
-
*/
|
|
144
|
-
entitySelectedFields?: TSelectedFields[];
|
|
145
|
-
}) {
|
|
146
|
-
this.entityClass = entityClass;
|
|
147
|
-
this.entityConfiguration = entityConfiguration;
|
|
148
|
-
this.privacyPolicyClass = privacyPolicyClass;
|
|
149
|
-
this.mutationValidators = mutationValidators;
|
|
150
|
-
this.mutationTriggers = mutationTriggers;
|
|
151
|
-
this.entitySelectedFields = entitySelectedFields;
|
|
152
|
-
}
|
|
110
|
+
/**
|
|
111
|
+
* An optional subset of fields defined in the EntityConfiguration which belong to this entity.
|
|
112
|
+
* For use when multiple types of entities are backed by a single table (EntityConfiguration) yet
|
|
113
|
+
* only expose a subset of the fields.
|
|
114
|
+
*/
|
|
115
|
+
readonly entitySelectedFields?: TSelectedFields[];
|
|
153
116
|
}
|
|
154
117
|
|
|
155
118
|
/**
|
|
@@ -162,6 +125,10 @@ export class EntityCompanionDefinition<
|
|
|
162
125
|
* EntityCompanion for each type of Entity.
|
|
163
126
|
*/
|
|
164
127
|
export default class EntityCompanionProvider {
|
|
128
|
+
private readonly companionDefinitionMap: Map<
|
|
129
|
+
string,
|
|
130
|
+
EntityCompanionDefinition<any, any, any, any, any, any>
|
|
131
|
+
> = new Map();
|
|
165
132
|
private readonly companionMap: Map<string, EntityCompanion<any, any, any, any, any, any>> =
|
|
166
133
|
new Map();
|
|
167
134
|
private readonly tableDataCoordinatorMap: Map<string, EntityTableDataCoordinator<any>> =
|
|
@@ -187,10 +154,9 @@ export default class EntityCompanionProvider {
|
|
|
187
154
|
* companion is constructed using the configuration provided by the factory.
|
|
188
155
|
*
|
|
189
156
|
* @param entityClass - entity class to load
|
|
190
|
-
* @param factory - entity companion factory
|
|
191
157
|
*/
|
|
192
158
|
getCompanionForEntity<
|
|
193
|
-
TFields,
|
|
159
|
+
TFields extends object,
|
|
194
160
|
TID extends NonNullable<TFields[TSelectedFields]>,
|
|
195
161
|
TViewerContext extends ViewerContext,
|
|
196
162
|
TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>,
|
|
@@ -210,27 +176,22 @@ export default class EntityCompanionProvider {
|
|
|
210
176
|
TEntity,
|
|
211
177
|
TPrivacyPolicy,
|
|
212
178
|
TSelectedFields
|
|
213
|
-
>,
|
|
214
|
-
entityCompanionDefinition: EntityCompanionDefinition<
|
|
215
|
-
TFields,
|
|
216
|
-
TID,
|
|
217
|
-
TViewerContext,
|
|
218
|
-
TEntity,
|
|
219
|
-
TPrivacyPolicy,
|
|
220
|
-
TSelectedFields
|
|
221
179
|
>
|
|
222
180
|
): EntityCompanion<TFields, TID, TViewerContext, TEntity, TPrivacyPolicy, TSelectedFields> {
|
|
181
|
+
const entityCompanionDefinition = computeIfAbsent(
|
|
182
|
+
this.companionDefinitionMap,
|
|
183
|
+
entityClass.name,
|
|
184
|
+
() => entityClass.defineCompanionDefinition()
|
|
185
|
+
);
|
|
223
186
|
const tableDataCoordinator = this.getTableDataCoordinatorForEntity(
|
|
224
187
|
entityCompanionDefinition.entityConfiguration,
|
|
225
188
|
entityClass.name
|
|
226
189
|
);
|
|
227
190
|
return computeIfAbsent(this.companionMap, entityClass.name, () => {
|
|
228
191
|
return new EntityCompanion(
|
|
229
|
-
|
|
192
|
+
this,
|
|
193
|
+
entityCompanionDefinition,
|
|
230
194
|
tableDataCoordinator,
|
|
231
|
-
entityCompanionDefinition.privacyPolicyClass,
|
|
232
|
-
entityCompanionDefinition.mutationValidators(),
|
|
233
|
-
entityCompanionDefinition.mutationTriggers(),
|
|
234
195
|
this.metricsAdapter
|
|
235
196
|
);
|
|
236
197
|
});
|
|
@@ -13,7 +13,7 @@ export default class EntityConfiguration<TFields> {
|
|
|
13
13
|
readonly cacheableKeys: ReadonlySet<keyof TFields>;
|
|
14
14
|
readonly cacheKeyVersion: number;
|
|
15
15
|
|
|
16
|
-
readonly
|
|
16
|
+
readonly inboundEdges: IEntityClass<any, any, any, any, any, any>[];
|
|
17
17
|
readonly schema: ReadonlyMap<keyof TFields, EntityFieldDefinition<any>>;
|
|
18
18
|
readonly entityToDBFieldsKeyMapping: ReadonlyMap<keyof TFields, string>;
|
|
19
19
|
readonly dbToEntityFieldsKeyMapping: ReadonlyMap<string, keyof TFields>;
|
|
@@ -25,7 +25,7 @@ export default class EntityConfiguration<TFields> {
|
|
|
25
25
|
idField,
|
|
26
26
|
tableName,
|
|
27
27
|
schema,
|
|
28
|
-
|
|
28
|
+
inboundEdges = [],
|
|
29
29
|
cacheKeyVersion = 0,
|
|
30
30
|
databaseAdapterFlavor,
|
|
31
31
|
cacheAdapterFlavor,
|
|
@@ -48,7 +48,7 @@ export default class EntityConfiguration<TFields> {
|
|
|
48
48
|
/**
|
|
49
49
|
* List of other entity types that reference this type in EntityFieldDefinition associations.
|
|
50
50
|
*/
|
|
51
|
-
|
|
51
|
+
inboundEdges?: IEntityClass<any, any, any, any, any, any>[];
|
|
52
52
|
|
|
53
53
|
/**
|
|
54
54
|
* Cache key version for this entity type. Should be bumped when a field is added to, removed from, or changed
|
|
@@ -71,8 +71,7 @@ export default class EntityConfiguration<TFields> {
|
|
|
71
71
|
this.cacheKeyVersion = cacheKeyVersion;
|
|
72
72
|
this.databaseAdapterFlavor = databaseAdapterFlavor;
|
|
73
73
|
this.cacheAdapterFlavor = cacheAdapterFlavor;
|
|
74
|
-
|
|
75
|
-
this.getInboundEdges = getInboundEdges;
|
|
74
|
+
this.inboundEdges = inboundEdges;
|
|
76
75
|
|
|
77
76
|
// external schema is a Record to typecheck that all fields have FieldDefinitions,
|
|
78
77
|
// but internally the most useful representation is a map for lookups
|
|
@@ -41,7 +41,7 @@ export enum EntityEdgeDeletionBehavior {
|
|
|
41
41
|
*/
|
|
42
42
|
export interface EntityAssociationDefinition<
|
|
43
43
|
TViewerContext extends ViewerContext,
|
|
44
|
-
TAssociatedFields,
|
|
44
|
+
TAssociatedFields extends object,
|
|
45
45
|
TAssociatedID extends NonNullable<TAssociatedFields[TAssociatedSelectedFields]>,
|
|
46
46
|
TAssociatedEntity extends ReadonlyEntity<
|
|
47
47
|
TAssociatedFields,
|
|
@@ -61,7 +61,7 @@ export interface EntityAssociationDefinition<
|
|
|
61
61
|
/**
|
|
62
62
|
* Class of entity on the other end of this edge.
|
|
63
63
|
*/
|
|
64
|
-
|
|
64
|
+
associatedEntityClass: IEntityClass<
|
|
65
65
|
TAssociatedFields,
|
|
66
66
|
TAssociatedID,
|
|
67
67
|
TViewerContext,
|
package/src/EntityLoader.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Result, asyncResult, result } from '@expo/results';
|
|
2
2
|
import invariant from 'invariant';
|
|
3
|
+
import nullthrows from 'nullthrows';
|
|
3
4
|
|
|
4
5
|
import EnforcingEntityLoader from './EnforcingEntityLoader';
|
|
5
6
|
import { IEntityClass } from './Entity';
|
|
@@ -14,6 +15,7 @@ import EntityPrivacyPolicy, { EntityPrivacyPolicyEvaluationContext } from './Ent
|
|
|
14
15
|
import { EntityQueryContext } from './EntityQueryContext';
|
|
15
16
|
import ReadonlyEntity from './ReadonlyEntity';
|
|
16
17
|
import ViewerContext from './ViewerContext';
|
|
18
|
+
import { pick } from './entityUtils';
|
|
17
19
|
import EntityInvalidFieldValueError from './errors/EntityInvalidFieldValueError';
|
|
18
20
|
import EntityNotFoundError from './errors/EntityNotFoundError';
|
|
19
21
|
import EntityDataManager from './internal/EntityDataManager';
|
|
@@ -25,7 +27,7 @@ import { mapMap, mapMapAsync } from './utils/collections/maps';
|
|
|
25
27
|
* cached, and authorized against the entity's EntityPrivacyPolicy.
|
|
26
28
|
*/
|
|
27
29
|
export default class EntityLoader<
|
|
28
|
-
TFields,
|
|
30
|
+
TFields extends object,
|
|
29
31
|
TID extends NonNullable<TFields[TSelectedFields]>,
|
|
30
32
|
TViewerContext extends ViewerContext,
|
|
31
33
|
TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>,
|
|
@@ -51,6 +53,7 @@ export default class EntityLoader<
|
|
|
51
53
|
TPrivacyPolicy,
|
|
52
54
|
TSelectedFields
|
|
53
55
|
>,
|
|
56
|
+
private readonly entitySelectedFields: TSelectedFields[] | undefined,
|
|
54
57
|
private readonly privacyPolicy: TPrivacyPolicy,
|
|
55
58
|
private readonly dataManager: EntityDataManager<TFields>,
|
|
56
59
|
protected readonly metricsAdapter: IEntityMetricsAdapter
|
|
@@ -332,7 +335,7 @@ export default class EntityLoader<
|
|
|
332
335
|
private tryConstructEntities(fieldsObjects: readonly TFields[]): readonly Result<TEntity>[] {
|
|
333
336
|
return fieldsObjects.map((fieldsObject) => {
|
|
334
337
|
try {
|
|
335
|
-
return result(
|
|
338
|
+
return result(this.constructEntity(fieldsObject));
|
|
336
339
|
} catch (e) {
|
|
337
340
|
if (!(e instanceof Error)) {
|
|
338
341
|
throw e;
|
|
@@ -342,6 +345,20 @@ export default class EntityLoader<
|
|
|
342
345
|
});
|
|
343
346
|
}
|
|
344
347
|
|
|
348
|
+
public constructEntity(fieldsObject: TFields): TEntity {
|
|
349
|
+
const idField = this.entityConfiguration.idField;
|
|
350
|
+
const id = nullthrows(fieldsObject[idField], 'must provide ID to create an entity');
|
|
351
|
+
const entitySelectedFields =
|
|
352
|
+
this.entitySelectedFields ?? Array.from(this.entityConfiguration.schema.keys());
|
|
353
|
+
const selectedFields = pick(fieldsObject, entitySelectedFields);
|
|
354
|
+
return new this.entityClass({
|
|
355
|
+
viewerContext: this.viewerContext,
|
|
356
|
+
id: id as TID,
|
|
357
|
+
databaseFields: fieldsObject,
|
|
358
|
+
selectedFields,
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
|
|
345
362
|
/**
|
|
346
363
|
* Construct and authorize entities from fields map, returning error results for entities that fail
|
|
347
364
|
* to construct or fail to authorize.
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import EntityConfiguration from './EntityConfiguration';
|
|
1
|
+
import EntityCompanion from './EntityCompanion';
|
|
3
2
|
import EntityLoader from './EntityLoader';
|
|
4
3
|
import EntityPrivacyPolicy, { EntityPrivacyPolicyEvaluationContext } from './EntityPrivacyPolicy';
|
|
5
4
|
import { EntityQueryContext } from './EntityQueryContext';
|
|
@@ -12,7 +11,7 @@ import IEntityMetricsAdapter from './metrics/IEntityMetricsAdapter';
|
|
|
12
11
|
* The primary entry point for loading entities.
|
|
13
12
|
*/
|
|
14
13
|
export default class EntityLoaderFactory<
|
|
15
|
-
TFields,
|
|
14
|
+
TFields extends object,
|
|
16
15
|
TID extends NonNullable<TFields[TSelectedFields]>,
|
|
17
16
|
TViewerContext extends ViewerContext,
|
|
18
17
|
TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>,
|
|
@@ -26,8 +25,7 @@ export default class EntityLoaderFactory<
|
|
|
26
25
|
TSelectedFields extends keyof TFields
|
|
27
26
|
> {
|
|
28
27
|
constructor(
|
|
29
|
-
private readonly
|
|
30
|
-
private readonly entityClass: IEntityClass<
|
|
28
|
+
private readonly entityCompanion: EntityCompanion<
|
|
31
29
|
TFields,
|
|
32
30
|
TID,
|
|
33
31
|
TViewerContext,
|
|
@@ -35,7 +33,6 @@ export default class EntityLoaderFactory<
|
|
|
35
33
|
TPrivacyPolicy,
|
|
36
34
|
TSelectedFields
|
|
37
35
|
>,
|
|
38
|
-
private readonly privacyPolicyClass: TPrivacyPolicy,
|
|
39
36
|
private readonly dataManager: EntityDataManager<TFields>,
|
|
40
37
|
protected readonly metricsAdapter: IEntityMetricsAdapter
|
|
41
38
|
) {}
|
|
@@ -54,9 +51,10 @@ export default class EntityLoaderFactory<
|
|
|
54
51
|
viewerContext,
|
|
55
52
|
queryContext,
|
|
56
53
|
privacyPolicyEvaluationContext,
|
|
57
|
-
this.entityConfiguration,
|
|
58
|
-
this.entityClass,
|
|
59
|
-
this.
|
|
54
|
+
this.entityCompanion.entityCompanionDefinition.entityConfiguration,
|
|
55
|
+
this.entityCompanion.entityCompanionDefinition.entityClass,
|
|
56
|
+
this.entityCompanion.entityCompanionDefinition.entitySelectedFields,
|
|
57
|
+
this.entityCompanion.privacyPolicy,
|
|
60
58
|
this.dataManager,
|
|
61
59
|
this.metricsAdapter
|
|
62
60
|
);
|
|
@@ -8,7 +8,7 @@ export enum EntityMutationType {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
export type EntityValidatorMutationInfo<
|
|
11
|
-
TFields,
|
|
11
|
+
TFields extends object,
|
|
12
12
|
TID extends NonNullable<TFields[TSelectedFields]>,
|
|
13
13
|
TViewerContext extends ViewerContext,
|
|
14
14
|
TEntity extends Entity<TFields, TID, TViewerContext, TSelectedFields>,
|
|
@@ -39,7 +39,7 @@ export type EntityCascadingDeletionInfo = {
|
|
|
39
39
|
};
|
|
40
40
|
|
|
41
41
|
export type EntityTriggerMutationInfo<
|
|
42
|
-
TFields,
|
|
42
|
+
TFields extends object,
|
|
43
43
|
TID extends NonNullable<TFields[TSelectedFields]>,
|
|
44
44
|
TViewerContext extends ViewerContext,
|
|
45
45
|
TEntity extends Entity<TFields, TID, TViewerContext, TSelectedFields>,
|
|
@@ -7,7 +7,7 @@ import ViewerContext from './ViewerContext';
|
|
|
7
7
|
* Interface to define trigger behavior for entities.
|
|
8
8
|
*/
|
|
9
9
|
export default interface EntityMutationTriggerConfiguration<
|
|
10
|
-
TFields,
|
|
10
|
+
TFields extends object,
|
|
11
11
|
TID extends NonNullable<TFields[TSelectedFields]>,
|
|
12
12
|
TViewerContext extends ViewerContext,
|
|
13
13
|
TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>,
|
|
@@ -70,7 +70,7 @@ export default interface EntityMutationTriggerConfiguration<
|
|
|
70
70
|
* the transaction if a transaction is supplied.
|
|
71
71
|
*/
|
|
72
72
|
export abstract class EntityMutationTrigger<
|
|
73
|
-
TFields,
|
|
73
|
+
TFields extends object,
|
|
74
74
|
TID extends NonNullable<TFields[TSelectedFields]>,
|
|
75
75
|
TViewerContext extends ViewerContext,
|
|
76
76
|
TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>,
|
|
@@ -89,7 +89,7 @@ export abstract class EntityMutationTrigger<
|
|
|
89
89
|
* since they explicitly occur outside of the transaction.
|
|
90
90
|
*/
|
|
91
91
|
export abstract class EntityNonTransactionalMutationTrigger<
|
|
92
|
-
TFields,
|
|
92
|
+
TFields extends object,
|
|
93
93
|
TID extends NonNullable<TFields[TSelectedFields]>,
|
|
94
94
|
TViewerContext extends ViewerContext,
|
|
95
95
|
TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>,
|
|
@@ -8,7 +8,7 @@ import ViewerContext from './ViewerContext';
|
|
|
8
8
|
* same transaction as the mutation itself before creating or updating an entity.
|
|
9
9
|
*/
|
|
10
10
|
export default abstract class EntityMutationValidator<
|
|
11
|
-
TFields,
|
|
11
|
+
TFields extends object,
|
|
12
12
|
TID extends NonNullable<TFields[TSelectedFields]>,
|
|
13
13
|
TViewerContext extends ViewerContext,
|
|
14
14
|
TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>,
|
package/src/EntityMutator.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Result, asyncResult, result, enforceAsyncResult } from '@expo/results';
|
|
|
2
2
|
import invariant from 'invariant';
|
|
3
3
|
|
|
4
4
|
import Entity, { IEntityClass } from './Entity';
|
|
5
|
-
import
|
|
5
|
+
import EntityCompanionProvider from './EntityCompanionProvider';
|
|
6
6
|
import EntityConfiguration from './EntityConfiguration';
|
|
7
7
|
import EntityDatabaseAdapter from './EntityDatabaseAdapter';
|
|
8
8
|
import { EntityEdgeDeletionBehavior } from './EntityFieldDefinition';
|
|
@@ -28,7 +28,7 @@ import IEntityMetricsAdapter, { EntityMetricsMutationType } from './metrics/IEnt
|
|
|
28
28
|
import { mapMapAsync } from './utils/collections/maps';
|
|
29
29
|
|
|
30
30
|
abstract class BaseMutator<
|
|
31
|
-
TFields,
|
|
31
|
+
TFields extends object,
|
|
32
32
|
TID extends NonNullable<TFields[TSelectedFields]>,
|
|
33
33
|
TViewerContext extends ViewerContext,
|
|
34
34
|
TEntity extends Entity<TFields, TID, TViewerContext, TSelectedFields>,
|
|
@@ -42,6 +42,7 @@ abstract class BaseMutator<
|
|
|
42
42
|
TSelectedFields extends keyof TFields
|
|
43
43
|
> {
|
|
44
44
|
constructor(
|
|
45
|
+
protected readonly companionProvider: EntityCompanionProvider,
|
|
45
46
|
protected readonly viewerContext: TViewerContext,
|
|
46
47
|
protected readonly queryContext: EntityQueryContext,
|
|
47
48
|
protected readonly entityConfiguration: EntityConfiguration<TFields>,
|
|
@@ -155,7 +156,7 @@ abstract class BaseMutator<
|
|
|
155
156
|
* Mutator for creating a new entity.
|
|
156
157
|
*/
|
|
157
158
|
export class CreateMutator<
|
|
158
|
-
TFields,
|
|
159
|
+
TFields extends object,
|
|
159
160
|
TID extends NonNullable<TFields[TSelectedFields]>,
|
|
160
161
|
TViewerContext extends ViewerContext,
|
|
161
162
|
TEntity extends Entity<TFields, TID, TViewerContext, TSelectedFields>,
|
|
@@ -211,7 +212,11 @@ export class CreateMutator<
|
|
|
211
212
|
): Promise<Result<TEntity>> {
|
|
212
213
|
this.validateFields(this.fieldsForEntity);
|
|
213
214
|
|
|
214
|
-
const
|
|
215
|
+
const entityLoader = this.entityLoaderFactory.forLoad(this.viewerContext, queryContext, {
|
|
216
|
+
cascadingDeleteCause: null,
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
const temporaryEntityForPrivacyCheck = entityLoader.constructEntity({
|
|
215
220
|
[this.entityConfiguration.idField]: '00000000-0000-0000-0000-000000000000', // zero UUID
|
|
216
221
|
...this.fieldsForEntity,
|
|
217
222
|
} as unknown as TFields);
|
|
@@ -250,14 +255,11 @@ export class CreateMutator<
|
|
|
250
255
|
|
|
251
256
|
const insertResult = await this.databaseAdapter.insertAsync(queryContext, this.fieldsForEntity);
|
|
252
257
|
|
|
253
|
-
const entityLoader = this.entityLoaderFactory.forLoad(this.viewerContext, queryContext, {
|
|
254
|
-
cascadingDeleteCause: null,
|
|
255
|
-
});
|
|
256
258
|
queryContext.appendPostCommitInvalidationCallback(
|
|
257
259
|
entityLoader.invalidateFieldsAsync.bind(entityLoader, insertResult)
|
|
258
260
|
);
|
|
259
261
|
|
|
260
|
-
const unauthorizedEntityAfterInsert =
|
|
262
|
+
const unauthorizedEntityAfterInsert = entityLoader.constructEntity(insertResult);
|
|
261
263
|
const newEntity = await entityLoader
|
|
262
264
|
.enforcing()
|
|
263
265
|
.loadByIDAsync(unauthorizedEntityAfterInsert.getID());
|
|
@@ -292,7 +294,7 @@ export class CreateMutator<
|
|
|
292
294
|
* Mutator for updating an existing entity.
|
|
293
295
|
*/
|
|
294
296
|
export class UpdateMutator<
|
|
295
|
-
TFields,
|
|
297
|
+
TFields extends object,
|
|
296
298
|
TID extends NonNullable<TFields[TSelectedFields]>,
|
|
297
299
|
TViewerContext extends ViewerContext,
|
|
298
300
|
TEntity extends Entity<TFields, TID, TViewerContext, TSelectedFields>,
|
|
@@ -310,6 +312,7 @@ export class UpdateMutator<
|
|
|
310
312
|
private readonly updatedFields: Partial<TFields> = {};
|
|
311
313
|
|
|
312
314
|
constructor(
|
|
315
|
+
companionProvider: EntityCompanionProvider,
|
|
313
316
|
viewerContext: TViewerContext,
|
|
314
317
|
queryContext: EntityQueryContext,
|
|
315
318
|
entityConfiguration: EntityConfiguration<TFields>,
|
|
@@ -349,6 +352,7 @@ export class UpdateMutator<
|
|
|
349
352
|
originalEntity: TEntity
|
|
350
353
|
) {
|
|
351
354
|
super(
|
|
355
|
+
companionProvider,
|
|
352
356
|
viewerContext,
|
|
353
357
|
queryContext,
|
|
354
358
|
entityConfiguration,
|
|
@@ -419,7 +423,11 @@ export class UpdateMutator<
|
|
|
419
423
|
): Promise<Result<TEntity>> {
|
|
420
424
|
this.validateFields(this.updatedFields);
|
|
421
425
|
|
|
422
|
-
const
|
|
426
|
+
const entityLoader = this.entityLoaderFactory.forLoad(this.viewerContext, queryContext, {
|
|
427
|
+
cascadingDeleteCause,
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
const entityAboutToBeUpdated = entityLoader.constructEntity(this.fieldsForEntity);
|
|
423
431
|
const authorizeUpdateResult = await asyncResult(
|
|
424
432
|
this.privacyPolicy.authorizeUpdateAsync(
|
|
425
433
|
this.viewerContext,
|
|
@@ -462,10 +470,6 @@ export class UpdateMutator<
|
|
|
462
470
|
this.updatedFields
|
|
463
471
|
);
|
|
464
472
|
|
|
465
|
-
const entityLoader = this.entityLoaderFactory.forLoad(this.viewerContext, queryContext, {
|
|
466
|
-
cascadingDeleteCause,
|
|
467
|
-
});
|
|
468
|
-
|
|
469
473
|
queryContext.appendPostCommitInvalidationCallback(
|
|
470
474
|
entityLoader.invalidateFieldsAsync.bind(
|
|
471
475
|
entityLoader,
|
|
@@ -481,7 +485,7 @@ export class UpdateMutator<
|
|
|
481
485
|
const updatedEntity = updateResult
|
|
482
486
|
? await entityLoader
|
|
483
487
|
.enforcing()
|
|
484
|
-
.loadByIDAsync(
|
|
488
|
+
.loadByIDAsync(entityLoader.constructEntity(updateResult).getID())
|
|
485
489
|
: entityAboutToBeUpdated;
|
|
486
490
|
|
|
487
491
|
await this.executeMutationTriggersAsync(
|
|
@@ -518,7 +522,7 @@ export class UpdateMutator<
|
|
|
518
522
|
* Mutator for deleting an existing entity.
|
|
519
523
|
*/
|
|
520
524
|
export class DeleteMutator<
|
|
521
|
-
TFields,
|
|
525
|
+
TFields extends object,
|
|
522
526
|
TID extends NonNullable<TFields[TSelectedFields]>,
|
|
523
527
|
TViewerContext extends ViewerContext,
|
|
524
528
|
TEntity extends Entity<TFields, TID, TViewerContext, TSelectedFields>,
|
|
@@ -532,6 +536,7 @@ export class DeleteMutator<
|
|
|
532
536
|
TSelectedFields extends keyof TFields
|
|
533
537
|
> extends BaseMutator<TFields, TID, TViewerContext, TEntity, TPrivacyPolicy, TSelectedFields> {
|
|
534
538
|
constructor(
|
|
539
|
+
companionProvider: EntityCompanionProvider,
|
|
535
540
|
viewerContext: TViewerContext,
|
|
536
541
|
queryContext: EntityQueryContext,
|
|
537
542
|
entityConfiguration: EntityConfiguration<TFields>,
|
|
@@ -571,6 +576,7 @@ export class DeleteMutator<
|
|
|
571
576
|
private readonly entity: TEntity
|
|
572
577
|
) {
|
|
573
578
|
super(
|
|
579
|
+
companionProvider,
|
|
574
580
|
viewerContext,
|
|
575
581
|
queryContext,
|
|
576
582
|
entityConfiguration,
|
|
@@ -723,31 +729,32 @@ export class DeleteMutator<
|
|
|
723
729
|
}
|
|
724
730
|
processedEntityIdentifiers.add(entity.getUniqueIdentifier());
|
|
725
731
|
|
|
726
|
-
const companionDefinition = (
|
|
727
|
-
entity.constructor as
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
732
|
+
const companionDefinition = this.companionProvider.getCompanionForEntity(
|
|
733
|
+
entity.constructor as IEntityClass<
|
|
734
|
+
TFields,
|
|
735
|
+
TID,
|
|
736
|
+
TViewerContext,
|
|
737
|
+
TEntity,
|
|
738
|
+
TPrivacyPolicy,
|
|
739
|
+
TSelectedFields
|
|
740
|
+
>
|
|
741
|
+
).entityCompanionDefinition;
|
|
736
742
|
const entityConfiguration = companionDefinition.entityConfiguration;
|
|
737
|
-
const inboundEdges = entityConfiguration.
|
|
743
|
+
const inboundEdges = entityConfiguration.inboundEdges;
|
|
738
744
|
await Promise.all(
|
|
739
745
|
inboundEdges.map(async (entityClass) => {
|
|
740
746
|
return await mapMapAsync(
|
|
741
|
-
|
|
747
|
+
this.companionProvider.getCompanionForEntity(entityClass).entityCompanionDefinition
|
|
748
|
+
.entityConfiguration.schema,
|
|
742
749
|
async (fieldDefinition, fieldName) => {
|
|
743
750
|
const association = fieldDefinition.association;
|
|
744
751
|
if (!association) {
|
|
745
752
|
return;
|
|
746
753
|
}
|
|
747
754
|
|
|
748
|
-
const associatedConfiguration =
|
|
749
|
-
.
|
|
750
|
-
|
|
755
|
+
const associatedConfiguration = this.companionProvider.getCompanionForEntity(
|
|
756
|
+
association.associatedEntityClass
|
|
757
|
+
).entityCompanionDefinition.entityConfiguration;
|
|
751
758
|
if (associatedConfiguration !== entityConfiguration) {
|
|
752
759
|
return;
|
|
753
760
|
}
|