@expo/entity 0.34.0 → 0.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/AuthorizationResultBasedEntityLoader.d.ts +128 -0
- package/build/AuthorizationResultBasedEntityLoader.js +196 -0
- package/build/AuthorizationResultBasedEntityLoader.js.map +1 -0
- package/build/ComposedEntityCacheAdapter.js +1 -0
- package/build/ComposedEntityCacheAdapter.js.map +1 -1
- package/build/ComposedSecondaryEntityCache.js +1 -0
- package/build/ComposedSecondaryEntityCache.js.map +1 -1
- package/build/EnforcingEntityLoader.d.ts +5 -4
- package/build/EnforcingEntityLoader.js +4 -2
- package/build/EnforcingEntityLoader.js.map +1 -1
- package/build/Entity.d.ts +4 -31
- package/build/Entity.js +19 -46
- package/build/Entity.js.map +1 -1
- package/build/EntityAssociationLoader.d.ts +9 -9
- package/build/EntityAssociationLoader.js +37 -12
- package/build/EntityAssociationLoader.js.map +1 -1
- package/build/EntityCompanion.js +9 -1
- package/build/EntityCompanion.js.map +1 -1
- package/build/EntityCompanionProvider.d.ts +3 -1
- package/build/EntityCompanionProvider.js +10 -4
- package/build/EntityCompanionProvider.js.map +1 -1
- package/build/EntityConfiguration.d.ts +2 -1
- package/build/EntityConfiguration.js +19 -1
- package/build/EntityConfiguration.js.map +1 -1
- package/build/EntityDatabaseAdapter.d.ts +2 -2
- package/build/EntityDatabaseAdapter.js +5 -3
- package/build/EntityDatabaseAdapter.js.map +1 -1
- package/build/EntityFieldDefinition.d.ts +21 -10
- package/build/EntityFieldDefinition.js +8 -9
- package/build/EntityFieldDefinition.js.map +1 -1
- package/build/EntityFields.d.ts +10 -0
- package/build/EntityFields.js +15 -1
- package/build/EntityFields.js.map +1 -1
- package/build/EntityLoader.d.ts +12 -125
- package/build/EntityLoader.js +24 -239
- package/build/EntityLoader.js.map +1 -1
- package/build/EntityLoaderFactory.d.ts +1 -1
- package/build/EntityLoaderFactory.js +3 -0
- package/build/EntityLoaderFactory.js.map +1 -1
- package/build/EntityLoaderUtils.d.ts +58 -0
- package/build/EntityLoaderUtils.js +109 -0
- package/build/EntityLoaderUtils.js.map +1 -0
- package/build/EntityMutator.d.ts +1 -0
- package/build/EntityMutator.js +71 -56
- package/build/EntityMutator.js.map +1 -1
- package/build/EntityMutatorFactory.js +9 -0
- package/build/EntityMutatorFactory.js.map +1 -1
- package/build/EntityPrivacyPolicy.d.ts +11 -5
- package/build/EntityPrivacyPolicy.js +5 -7
- package/build/EntityPrivacyPolicy.js.map +1 -1
- package/build/EntityQueryContext.d.ts +2 -1
- package/build/EntityQueryContext.js +11 -6
- package/build/EntityQueryContext.js.map +1 -1
- package/build/EntityQueryContextProvider.d.ts +1 -1
- package/build/EntityQueryContextProvider.js +1 -1
- package/build/EntityQueryContextProvider.js.map +1 -1
- package/build/EntitySecondaryCacheLoader.js +5 -1
- package/build/EntitySecondaryCacheLoader.js.map +1 -1
- package/build/GenericEntityCacheAdapter.js +1 -0
- package/build/GenericEntityCacheAdapter.js.map +1 -1
- package/build/GenericSecondaryEntityCache.js +2 -0
- package/build/GenericSecondaryEntityCache.js.map +1 -1
- package/build/IEntityCacheAdapterProvider.d.ts +1 -1
- package/build/IEntityDatabaseAdapterProvider.d.ts +1 -1
- package/build/ReadonlyEntity.d.ts +1 -1
- package/build/ReadonlyEntity.js +9 -2
- package/build/ReadonlyEntity.js.map +1 -1
- package/build/ViewerContext.d.ts +2 -2
- package/build/ViewerContext.js +5 -3
- package/build/ViewerContext.js.map +1 -1
- package/build/ViewerScopedEntityCompanion.js +2 -0
- package/build/ViewerScopedEntityCompanion.js.map +1 -1
- package/build/ViewerScopedEntityCompanionProvider.d.ts +0 -1
- package/build/ViewerScopedEntityCompanionProvider.js +2 -1
- package/build/ViewerScopedEntityCompanionProvider.js.map +1 -1
- package/build/ViewerScopedEntityLoaderFactory.d.ts +1 -1
- package/build/ViewerScopedEntityLoaderFactory.js +2 -0
- package/build/ViewerScopedEntityLoaderFactory.js.map +1 -1
- package/build/ViewerScopedEntityMutatorFactory.js +2 -0
- package/build/ViewerScopedEntityMutatorFactory.js.map +1 -1
- package/build/__tests__/ComposedCacheAdapter-test.js +2 -0
- package/build/__tests__/ComposedCacheAdapter-test.js.map +1 -1
- package/build/__tests__/ComposedSecondaryEntityCache-test.js +1 -0
- package/build/__tests__/ComposedSecondaryEntityCache-test.js.map +1 -1
- package/build/__tests__/EnforcingEntityLoader-test.js +101 -113
- package/build/__tests__/EnforcingEntityLoader-test.js.map +1 -1
- package/build/__tests__/Entity-test.js +5 -137
- package/build/__tests__/Entity-test.js.map +1 -1
- package/build/__tests__/EntityAssociationLoader-test.js +37 -65
- package/build/__tests__/EntityAssociationLoader-test.js.map +1 -1
- package/build/__tests__/EntityCommonUseCases-test.js +31 -37
- package/build/__tests__/EntityCommonUseCases-test.js.map +1 -1
- package/build/__tests__/EntityCompanion-test.js +26 -3
- package/build/__tests__/EntityCompanion-test.js.map +1 -1
- package/build/__tests__/EntityConfiguration-test.js +103 -0
- package/build/__tests__/EntityConfiguration-test.js.map +1 -0
- package/build/__tests__/EntityDatabaseAdapter-test.js +6 -0
- package/build/__tests__/EntityDatabaseAdapter-test.js.map +1 -1
- package/build/__tests__/EntityEdges-test.js +89 -80
- package/build/__tests__/EntityEdges-test.js.map +1 -1
- package/build/__tests__/EntityFields-test.js +6 -0
- package/build/__tests__/EntityFields-test.js.map +1 -1
- package/build/__tests__/EntityLoader-constructor-test.js +17 -18
- package/build/__tests__/EntityLoader-constructor-test.js.map +1 -1
- package/build/__tests__/EntityLoader-test.js +93 -41
- package/build/__tests__/EntityLoader-test.js.map +1 -1
- package/build/__tests__/EntityMutator-MutationCacheConsistency-test.js +18 -21
- package/build/__tests__/EntityMutator-MutationCacheConsistency-test.js.map +1 -1
- package/build/__tests__/EntityMutator-test.js +74 -29
- package/build/__tests__/EntityMutator-test.js.map +1 -1
- package/build/__tests__/EntityPrivacyPolicy-test.js +77 -59
- package/build/__tests__/EntityPrivacyPolicy-test.js.map +1 -1
- package/build/__tests__/EntityQueryContext-test.js +9 -0
- package/build/__tests__/EntityQueryContext-test.js.map +1 -1
- package/build/__tests__/EntitySecondaryCacheLoader-test.js +10 -10
- package/build/__tests__/EntitySecondaryCacheLoader-test.js.map +1 -1
- package/build/__tests__/EntitySelfReferentialEdges-test.js +59 -74
- package/build/__tests__/EntitySelfReferentialEdges-test.js.map +1 -1
- package/build/__tests__/ReadonlyEntity-test.js +13 -13
- package/build/__tests__/ReadonlyEntity-test.js.map +1 -1
- package/build/__tests__/ViewerContext-test.js +2 -2
- package/build/__tests__/ViewerContext-test.js.map +1 -1
- package/build/__tests__/ViewerScopedEntityLoaderFactory-test.js.map +1 -1
- package/build/__tests__/cases/TwoEntitySameTableDisjointRows-test.js +26 -28
- package/build/__tests__/cases/TwoEntitySameTableDisjointRows-test.js.map +1 -1
- package/build/__tests__/cases/TwoEntitySameTableOverlappingRows-test.js +25 -30
- package/build/__tests__/cases/TwoEntitySameTableOverlappingRows-test.js.map +1 -1
- package/build/entityUtils.d.ts +1 -1
- package/build/entityUtils.js.map +1 -1
- package/build/errors/EntityCacheAdapterError.js +2 -5
- package/build/errors/EntityCacheAdapterError.js.map +1 -1
- package/build/errors/EntityDatabaseAdapterError.js +14 -35
- package/build/errors/EntityDatabaseAdapterError.js.map +1 -1
- package/build/errors/EntityError.js +1 -0
- package/build/errors/EntityError.js.map +1 -1
- package/build/errors/EntityInvalidFieldValueError.js +2 -2
- package/build/errors/EntityInvalidFieldValueError.js.map +1 -1
- package/build/errors/EntityNotAuthorizedError.js +3 -2
- package/build/errors/EntityNotAuthorizedError.js.map +1 -1
- package/build/errors/EntityNotFoundError.js +2 -2
- package/build/errors/EntityNotFoundError.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/internal/EntityDataManager.d.ts +1 -1
- package/build/internal/EntityDataManager.js +7 -2
- package/build/internal/EntityDataManager.js.map +1 -1
- package/build/internal/EntityFieldTransformationUtils.d.ts +5 -5
- package/build/internal/EntityFieldTransformationUtils.js +5 -8
- package/build/internal/EntityFieldTransformationUtils.js.map +1 -1
- package/build/internal/EntityTableDataCoordinator.d.ts +1 -1
- package/build/internal/EntityTableDataCoordinator.js +5 -0
- package/build/internal/EntityTableDataCoordinator.js.map +1 -1
- package/build/internal/ReadThroughEntityCache.d.ts +1 -1
- package/build/internal/ReadThroughEntityCache.js +2 -0
- package/build/internal/ReadThroughEntityCache.js.map +1 -1
- package/build/internal/__tests__/EntityDataManager-test.js +11 -11
- package/build/internal/__tests__/EntityDataManager-test.js.map +1 -1
- package/build/internal/__tests__/EntityFieldTransformationUtils-test.js +6 -2
- package/build/internal/__tests__/EntityFieldTransformationUtils-test.js.map +1 -1
- package/build/internal/__tests__/ReadThroughEntityCache-test.js +33 -0
- package/build/internal/__tests__/ReadThroughEntityCache-test.js.map +1 -1
- package/build/metrics/IEntityMetricsAdapter.d.ts +1 -1
- package/build/rules/AlwaysAllowPrivacyPolicyRule.d.ts +1 -1
- package/build/rules/AlwaysAllowPrivacyPolicyRule.js.map +1 -1
- package/build/rules/AlwaysDenyPrivacyPolicyRule.d.ts +1 -1
- package/build/rules/AlwaysDenyPrivacyPolicyRule.js.map +1 -1
- package/build/rules/AlwaysSkipPrivacyPolicyRule.d.ts +1 -1
- package/build/rules/AlwaysSkipPrivacyPolicyRule.js.map +1 -1
- package/build/rules/PrivacyPolicyRule.d.ts +1 -1
- package/build/rules/PrivacyPolicyRule.js.map +1 -1
- package/build/rules/__tests__/AlwaysAllowPrivacyPolicyRule-test.js.map +1 -1
- package/build/rules/__tests__/AlwaysDenyPrivacyPolicyRule-test.js.map +1 -1
- package/build/rules/__tests__/AlwaysSkipPrivacyPolicyRule-test.js.map +1 -1
- package/build/testfixtures/DateIDTestEntity.js +12 -15
- package/build/testfixtures/DateIDTestEntity.js.map +1 -1
- package/build/testfixtures/SimpleTestEntity.d.ts +8 -8
- package/build/testfixtures/SimpleTestEntity.js +12 -15
- package/build/testfixtures/SimpleTestEntity.js.map +1 -1
- package/build/testfixtures/TestEntity.d.ts +12 -12
- package/build/testfixtures/TestEntity.js +12 -15
- package/build/testfixtures/TestEntity.js.map +1 -1
- package/build/testfixtures/TestEntity2.d.ts +8 -8
- package/build/testfixtures/TestEntity2.js +12 -15
- package/build/testfixtures/TestEntity2.js.map +1 -1
- package/build/testfixtures/TestEntityNumberKey.js +12 -15
- package/build/testfixtures/TestEntityNumberKey.js.map +1 -1
- package/build/testfixtures/TestEntityWithMutationTriggers.d.ts +36 -0
- package/build/testfixtures/TestEntityWithMutationTriggers.js +82 -0
- package/build/testfixtures/TestEntityWithMutationTriggers.js.map +1 -0
- package/build/testfixtures/TestViewerContext.d.ts +0 -3
- package/build/testfixtures/TestViewerContext.js +0 -6
- package/build/testfixtures/TestViewerContext.js.map +1 -1
- package/build/utils/EntityPrivacyUtils.d.ts +34 -0
- package/build/utils/EntityPrivacyUtils.js +160 -0
- package/build/utils/EntityPrivacyUtils.js.map +1 -0
- package/build/utils/__tests__/EntityPrivacyUtils-test.d.ts +1 -0
- package/build/utils/__tests__/EntityPrivacyUtils-test.js +395 -0
- package/build/utils/__tests__/EntityPrivacyUtils-test.js.map +1 -0
- package/build/utils/__tests__/mergeEntityMutationTriggerConfigurations-test.d.ts +1 -0
- package/build/utils/__tests__/mergeEntityMutationTriggerConfigurations-test.js +26 -0
- package/build/utils/__tests__/mergeEntityMutationTriggerConfigurations-test.js.map +1 -0
- package/build/utils/collections/maps.js.map +1 -1
- package/build/utils/mergeEntityMutationTriggerConfigurations.d.ts +4 -0
- package/build/utils/mergeEntityMutationTriggerConfigurations.js +28 -0
- package/build/utils/mergeEntityMutationTriggerConfigurations.js.map +1 -0
- package/build/utils/testing/PrivacyPolicyRuleTestUtils.d.ts +1 -1
- package/build/utils/testing/PrivacyPolicyRuleTestUtils.js.map +1 -1
- package/build/utils/testing/StubCacheAdapter.d.ts +3 -3
- package/build/utils/testing/StubCacheAdapter.js +3 -3
- package/build/utils/testing/StubCacheAdapter.js.map +1 -1
- package/build/utils/testing/StubDatabaseAdapter.d.ts +2 -2
- package/build/utils/testing/StubDatabaseAdapter.js +4 -2
- package/build/utils/testing/StubDatabaseAdapter.js.map +1 -1
- package/build/utils/testing/StubDatabaseAdapterProvider.d.ts +1 -1
- package/build/utils/testing/StubDatabaseAdapterProvider.js +1 -3
- package/build/utils/testing/StubDatabaseAdapterProvider.js.map +1 -1
- package/build/utils/testing/__tests__/PrivacyPolicyRuleTestUtils-test.d.ts +1 -0
- package/build/utils/testing/__tests__/PrivacyPolicyRuleTestUtils-test.js +42 -0
- package/build/utils/testing/__tests__/PrivacyPolicyRuleTestUtils-test.js.map +1 -0
- package/build/utils/testing/__tests__/StubDatabaseAdapter-test.js +53 -0
- package/build/utils/testing/__tests__/StubDatabaseAdapter-test.js.map +1 -1
- package/build/utils/testing/describeFieldTestCase.js.map +1 -1
- package/package.json +4 -3
- package/src/AuthorizationResultBasedEntityLoader.ts +297 -0
- package/src/ComposedEntityCacheAdapter.ts +6 -6
- package/src/ComposedSecondaryEntityCache.ts +8 -8
- package/src/EnforcingEntityLoader.ts +20 -19
- package/src/Entity.ts +26 -118
- package/src/EntityAssociationLoader.ts +56 -41
- package/src/EntityCompanion.ts +8 -4
- package/src/EntityCompanionProvider.ts +24 -16
- package/src/EntityConfiguration.ts +18 -7
- package/src/EntityDatabaseAdapter.ts +41 -41
- package/src/EntityFieldDefinition.ts +28 -18
- package/src/EntityFields.ts +15 -0
- package/src/EntityLoader.ts +63 -357
- package/src/EntityLoaderFactory.ts +10 -4
- package/src/EntityLoaderUtils.ts +149 -0
- package/src/EntityMutationInfo.ts +2 -2
- package/src/EntityMutationTriggerConfiguration.ts +5 -5
- package/src/EntityMutationValidator.ts +2 -2
- package/src/EntityMutator.ts +146 -144
- package/src/EntityMutatorFactory.ts +8 -8
- package/src/EntityPrivacyPolicy.ts +78 -28
- package/src/EntityQueryContext.ts +14 -13
- package/src/EntityQueryContextProvider.ts +6 -6
- package/src/EntitySecondaryCacheLoader.ts +13 -11
- package/src/GenericEntityCacheAdapter.ts +10 -10
- package/src/GenericSecondaryEntityCache.ts +6 -6
- package/src/IEntityCacheAdapter.ts +4 -4
- package/src/IEntityCacheAdapterProvider.ts +2 -2
- package/src/IEntityDatabaseAdapterProvider.ts +2 -2
- package/src/ReadonlyEntity.ts +8 -5
- package/src/ViewerContext.ts +10 -10
- package/src/ViewerScopedEntityCompanion.ts +4 -4
- package/src/ViewerScopedEntityCompanionProvider.ts +4 -5
- package/src/ViewerScopedEntityLoaderFactory.ts +10 -4
- package/src/ViewerScopedEntityMutatorFactory.ts +5 -5
- package/src/__tests__/ComposedCacheAdapter-test.ts +12 -10
- package/src/__tests__/ComposedSecondaryEntityCache-test.ts +8 -8
- package/src/__tests__/EnforcingEntityLoader-test.ts +236 -159
- package/src/__tests__/Entity-test.ts +5 -223
- package/src/__tests__/EntityAssociationLoader-test.ts +91 -169
- package/src/__tests__/EntityCommonUseCases-test.ts +36 -38
- package/src/__tests__/EntityCompanion-test.ts +57 -5
- package/src/__tests__/EntityConfiguration-test.ts +118 -0
- package/src/__tests__/EntityDatabaseAdapter-test.ts +11 -11
- package/src/__tests__/EntityEdges-test.ts +128 -118
- package/src/__tests__/EntityFields-test.ts +14 -2
- package/src/__tests__/EntityLoader-constructor-test.ts +21 -8
- package/src/__tests__/EntityLoader-test.ts +233 -105
- package/src/__tests__/EntityMutator-MutationCacheConsistency-test.ts +17 -20
- package/src/__tests__/EntityMutator-test.ts +342 -163
- package/src/__tests__/EntityPrivacyPolicy-test.ts +166 -53
- package/src/__tests__/EntityQueryContext-test.ts +30 -12
- package/src/__tests__/EntitySecondaryCacheLoader-test.ts +17 -26
- package/src/__tests__/EntitySelfReferentialEdges-test.ts +67 -115
- package/src/__tests__/GenericEntityCacheAdapter-test.ts +2 -2
- package/src/__tests__/ReadonlyEntity-test.ts +13 -15
- package/src/__tests__/ViewerContext-test.ts +3 -4
- package/src/__tests__/ViewerScopedEntityCompanion-test.ts +2 -2
- package/src/__tests__/ViewerScopedEntityCompanionProvider-test.ts +2 -2
- package/src/__tests__/ViewerScopedEntityLoaderFactory-test.ts +2 -1
- package/src/__tests__/cases/TwoEntitySameTableDisjointRows-test.ts +34 -45
- package/src/__tests__/cases/TwoEntitySameTableOverlappingRows-test.ts +22 -30
- package/src/__tests__/entityUtils-test.ts +2 -2
- package/src/entityUtils.ts +4 -4
- package/src/errors/EntityError.ts +4 -1
- package/src/errors/EntityInvalidFieldValueError.ts +2 -2
- package/src/errors/EntityNotAuthorizedError.ts +3 -3
- package/src/errors/EntityNotFoundError.ts +2 -2
- package/src/index.ts +1 -0
- package/src/internal/EntityDataManager.ts +25 -25
- package/src/internal/EntityFieldTransformationUtils.ts +39 -32
- package/src/internal/EntityTableDataCoordinator.ts +3 -3
- package/src/internal/ReadThroughEntityCache.ts +9 -9
- package/src/internal/__tests__/EntityDataManager-test.ts +62 -62
- package/src/internal/__tests__/EntityFieldTransformationUtils-test.ts +14 -10
- package/src/internal/__tests__/ReadThroughEntityCache-test.ts +74 -18
- package/src/metrics/EntityMetricsUtils.ts +4 -4
- package/src/metrics/IEntityMetricsAdapter.ts +1 -1
- package/src/rules/AlwaysAllowPrivacyPolicyRule.ts +9 -3
- package/src/rules/AlwaysDenyPrivacyPolicyRule.ts +9 -3
- package/src/rules/AlwaysSkipPrivacyPolicyRule.ts +9 -3
- package/src/rules/PrivacyPolicyRule.ts +9 -3
- package/src/rules/__tests__/AlwaysAllowPrivacyPolicyRule-test.ts +2 -1
- package/src/rules/__tests__/AlwaysDenyPrivacyPolicyRule-test.ts +2 -1
- package/src/rules/__tests__/AlwaysSkipPrivacyPolicyRule-test.ts +2 -1
- package/src/testfixtures/SimpleTestEntity.ts +8 -8
- package/src/testfixtures/TestEntity.ts +13 -16
- package/src/testfixtures/TestEntity2.ts +8 -8
- package/src/testfixtures/TestEntityWithMutationTriggers.ts +156 -0
- package/src/testfixtures/TestViewerContext.ts +1 -12
- package/src/utils/EntityPrivacyUtils.ts +325 -0
- package/src/utils/__tests__/EntityPrivacyUtils-test.ts +570 -0
- package/src/utils/__tests__/mergeEntityMutationTriggerConfigurations-test.ts +29 -0
- package/src/utils/collections/__tests__/maps-test.ts +2 -2
- package/src/utils/collections/maps.ts +11 -11
- package/src/utils/mergeEntityMutationTriggerConfigurations.ts +44 -0
- package/src/utils/testing/PrivacyPolicyRuleTestUtils.ts +25 -22
- package/src/utils/testing/StubCacheAdapter.ts +17 -15
- package/src/utils/testing/StubDatabaseAdapter.ts +35 -30
- package/src/utils/testing/StubDatabaseAdapterProvider.ts +2 -2
- package/src/utils/testing/StubQueryContextProvider.ts +2 -2
- package/src/utils/testing/__tests__/PrivacyPolicyRuleTestUtils-test.ts +42 -0
- package/src/utils/testing/__tests__/StubDatabaseAdapter-test.ts +111 -29
- package/src/utils/testing/createUnitTestEntityCompanionProvider.ts +2 -2
- package/src/utils/testing/describeFieldTestCase.ts +1 -1
- package/build/__tests__/EntityDataConfiguration-test.js +0 -68
- package/build/__tests__/EntityDataConfiguration-test.js.map +0 -1
- package/src/__tests__/EntityDataConfiguration-test.ts +0 -77
- /package/build/__tests__/{EntityDataConfiguration-test.d.ts → EntityConfiguration-test.d.ts} +0 -0
package/src/Entity.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Result
|
|
1
|
+
import { Result } from '@expo/results';
|
|
2
2
|
|
|
3
3
|
import { EntityCompanionDefinition } from './EntityCompanionProvider';
|
|
4
4
|
import { CreateMutator, UpdateMutator } from './EntityMutator';
|
|
@@ -29,7 +29,7 @@ export default abstract class Entity<
|
|
|
29
29
|
TFields extends object,
|
|
30
30
|
TID extends NonNullable<TFields[TSelectedFields]>,
|
|
31
31
|
TViewerContext extends ViewerContext,
|
|
32
|
-
TSelectedFields extends keyof TFields = keyof TFields
|
|
32
|
+
TSelectedFields extends keyof TFields = keyof TFields,
|
|
33
33
|
> extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields> {
|
|
34
34
|
/**
|
|
35
35
|
* Vend mutator for creating a new entity in given query context.
|
|
@@ -50,7 +50,7 @@ export default abstract class Entity<
|
|
|
50
50
|
TMEntity,
|
|
51
51
|
TMSelectedFields
|
|
52
52
|
>,
|
|
53
|
-
TMSelectedFields extends keyof TMFields = keyof TMFields
|
|
53
|
+
TMSelectedFields extends keyof TMFields = keyof TMFields,
|
|
54
54
|
>(
|
|
55
55
|
this: IEntityClass<
|
|
56
56
|
TMFields,
|
|
@@ -61,7 +61,10 @@ export default abstract class Entity<
|
|
|
61
61
|
TMSelectedFields
|
|
62
62
|
>,
|
|
63
63
|
viewerContext: TMViewerContext2,
|
|
64
|
-
queryContext: EntityQueryContext
|
|
64
|
+
queryContext: EntityQueryContext = viewerContext
|
|
65
|
+
.getViewerScopedEntityCompanionForClass(this)
|
|
66
|
+
.getQueryContextProvider()
|
|
67
|
+
.getQueryContext(),
|
|
65
68
|
): CreateMutator<TMFields, TMID, TMViewerContext, TMEntity, TMPrivacyPolicy, TMSelectedFields> {
|
|
66
69
|
return viewerContext
|
|
67
70
|
.getViewerScopedEntityCompanionForClass(this)
|
|
@@ -87,7 +90,7 @@ export default abstract class Entity<
|
|
|
87
90
|
TMEntity,
|
|
88
91
|
TMSelectedFields
|
|
89
92
|
>,
|
|
90
|
-
TMSelectedFields extends keyof TMFields = keyof TMFields
|
|
93
|
+
TMSelectedFields extends keyof TMFields = keyof TMFields,
|
|
91
94
|
>(
|
|
92
95
|
this: IEntityClass<
|
|
93
96
|
TMFields,
|
|
@@ -98,7 +101,11 @@ export default abstract class Entity<
|
|
|
98
101
|
TMSelectedFields
|
|
99
102
|
>,
|
|
100
103
|
existingEntity: TMEntity,
|
|
101
|
-
queryContext: EntityQueryContext
|
|
104
|
+
queryContext: EntityQueryContext = existingEntity
|
|
105
|
+
.getViewerContext()
|
|
106
|
+
.getViewerScopedEntityCompanionForClass(this)
|
|
107
|
+
.getQueryContextProvider()
|
|
108
|
+
.getQueryContext(),
|
|
102
109
|
): UpdateMutator<TMFields, TMID, TMViewerContext, TMEntity, TMPrivacyPolicy, TMSelectedFields> {
|
|
103
110
|
return existingEntity
|
|
104
111
|
.getViewerContext()
|
|
@@ -124,7 +131,7 @@ export default abstract class Entity<
|
|
|
124
131
|
TMEntity,
|
|
125
132
|
TMSelectedFields
|
|
126
133
|
>,
|
|
127
|
-
TMSelectedFields extends keyof TMFields = keyof TMFields
|
|
134
|
+
TMSelectedFields extends keyof TMFields = keyof TMFields,
|
|
128
135
|
>(
|
|
129
136
|
this: IEntityClass<
|
|
130
137
|
TMFields,
|
|
@@ -135,7 +142,11 @@ export default abstract class Entity<
|
|
|
135
142
|
TMSelectedFields
|
|
136
143
|
>,
|
|
137
144
|
existingEntity: TMEntity,
|
|
138
|
-
queryContext: EntityQueryContext
|
|
145
|
+
queryContext: EntityQueryContext = existingEntity
|
|
146
|
+
.getViewerContext()
|
|
147
|
+
.getViewerScopedEntityCompanionForClass(this)
|
|
148
|
+
.getQueryContextProvider()
|
|
149
|
+
.getQueryContext(),
|
|
139
150
|
): Promise<Result<void>> {
|
|
140
151
|
return existingEntity
|
|
141
152
|
.getViewerContext()
|
|
@@ -162,7 +173,7 @@ export default abstract class Entity<
|
|
|
162
173
|
TMEntity,
|
|
163
174
|
TMSelectedFields
|
|
164
175
|
>,
|
|
165
|
-
TMSelectedFields extends keyof TMFields = keyof TMFields
|
|
176
|
+
TMSelectedFields extends keyof TMFields = keyof TMFields,
|
|
166
177
|
>(
|
|
167
178
|
this: IEntityClass<
|
|
168
179
|
TMFields,
|
|
@@ -173,7 +184,11 @@ export default abstract class Entity<
|
|
|
173
184
|
TMSelectedFields
|
|
174
185
|
>,
|
|
175
186
|
existingEntity: TMEntity,
|
|
176
|
-
queryContext: EntityQueryContext
|
|
187
|
+
queryContext: EntityQueryContext = existingEntity
|
|
188
|
+
.getViewerContext()
|
|
189
|
+
.getViewerScopedEntityCompanionForClass(this)
|
|
190
|
+
.getQueryContextProvider()
|
|
191
|
+
.getQueryContext(),
|
|
177
192
|
): Promise<void> {
|
|
178
193
|
return existingEntity
|
|
179
194
|
.getViewerContext()
|
|
@@ -182,113 +197,6 @@ export default abstract class Entity<
|
|
|
182
197
|
.forDelete(existingEntity, queryContext)
|
|
183
198
|
.enforceDeleteAsync();
|
|
184
199
|
}
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* Check whether an entity loaded by a viewer can be updated by that same viewer.
|
|
188
|
-
*
|
|
189
|
-
* @remarks
|
|
190
|
-
*
|
|
191
|
-
* This may be useful in situations relying upon the thrown privacy policy thrown authorization error
|
|
192
|
-
* is insufficient for the task at hand. When dealing with purely a sequence of mutations it is easy
|
|
193
|
-
* to roll back all mutations given a single authorization error by wrapping them in a single transaction.
|
|
194
|
-
* When certain portions of a mutation cannot be rolled back transactionally (third pary calls,
|
|
195
|
-
* legacy code, etc), using this method can help decide whether the sequence of mutations will fail before
|
|
196
|
-
* attempting them. Note that if any privacy policy rules use a piece of data being updated in the mutations
|
|
197
|
-
* the result of this method and the update mutation itself may differ.
|
|
198
|
-
*
|
|
199
|
-
* @param existingEntity - entity loaded by viewer
|
|
200
|
-
* @param queryContext - query context in which to perform the check
|
|
201
|
-
*/
|
|
202
|
-
static async canViewerUpdateAsync<
|
|
203
|
-
TMFields extends object,
|
|
204
|
-
TMID extends NonNullable<TMFields[TMSelectedFields]>,
|
|
205
|
-
TMViewerContext extends ViewerContext,
|
|
206
|
-
TMEntity extends Entity<TMFields, TMID, TMViewerContext, TMSelectedFields>,
|
|
207
|
-
TMPrivacyPolicy extends EntityPrivacyPolicy<
|
|
208
|
-
TMFields,
|
|
209
|
-
TMID,
|
|
210
|
-
TMViewerContext,
|
|
211
|
-
TMEntity,
|
|
212
|
-
TMSelectedFields
|
|
213
|
-
>,
|
|
214
|
-
TMSelectedFields extends keyof TMFields = keyof TMFields
|
|
215
|
-
>(
|
|
216
|
-
this: IEntityClass<
|
|
217
|
-
TMFields,
|
|
218
|
-
TMID,
|
|
219
|
-
TMViewerContext,
|
|
220
|
-
TMEntity,
|
|
221
|
-
TMPrivacyPolicy,
|
|
222
|
-
TMSelectedFields
|
|
223
|
-
>,
|
|
224
|
-
existingEntity: TMEntity,
|
|
225
|
-
queryContext: EntityQueryContext
|
|
226
|
-
): Promise<boolean> {
|
|
227
|
-
const companion = existingEntity
|
|
228
|
-
.getViewerContext()
|
|
229
|
-
.getViewerScopedEntityCompanionForClass(this);
|
|
230
|
-
const privacyPolicy = companion.entityCompanion.privacyPolicy;
|
|
231
|
-
const evaluationResult = await asyncResult(
|
|
232
|
-
privacyPolicy.authorizeUpdateAsync(
|
|
233
|
-
existingEntity.getViewerContext(),
|
|
234
|
-
queryContext,
|
|
235
|
-
{ cascadingDeleteCause: null },
|
|
236
|
-
existingEntity,
|
|
237
|
-
companion.getMetricsAdapter()
|
|
238
|
-
)
|
|
239
|
-
);
|
|
240
|
-
return evaluationResult.ok;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
/**
|
|
244
|
-
* Check whether an entity loaded by a viewer can be deleted by that same viewer.
|
|
245
|
-
*
|
|
246
|
-
* @remarks
|
|
247
|
-
* See remarks for canViewerUpdate.
|
|
248
|
-
*
|
|
249
|
-
* @param existingEntity - entity loaded by viewer
|
|
250
|
-
* @param queryContext - query context in which to perform the check
|
|
251
|
-
*/
|
|
252
|
-
static async canViewerDeleteAsync<
|
|
253
|
-
TMFields extends object,
|
|
254
|
-
TMID extends NonNullable<TMFields[TMSelectedFields]>,
|
|
255
|
-
TMViewerContext extends ViewerContext,
|
|
256
|
-
TMEntity extends Entity<TMFields, TMID, TMViewerContext, TMSelectedFields>,
|
|
257
|
-
TMPrivacyPolicy extends EntityPrivacyPolicy<
|
|
258
|
-
TMFields,
|
|
259
|
-
TMID,
|
|
260
|
-
TMViewerContext,
|
|
261
|
-
TMEntity,
|
|
262
|
-
TMSelectedFields
|
|
263
|
-
>,
|
|
264
|
-
TMSelectedFields extends keyof TMFields = keyof TMFields
|
|
265
|
-
>(
|
|
266
|
-
this: IEntityClass<
|
|
267
|
-
TMFields,
|
|
268
|
-
TMID,
|
|
269
|
-
TMViewerContext,
|
|
270
|
-
TMEntity,
|
|
271
|
-
TMPrivacyPolicy,
|
|
272
|
-
TMSelectedFields
|
|
273
|
-
>,
|
|
274
|
-
existingEntity: TMEntity,
|
|
275
|
-
queryContext: EntityQueryContext
|
|
276
|
-
): Promise<boolean> {
|
|
277
|
-
const companion = existingEntity
|
|
278
|
-
.getViewerContext()
|
|
279
|
-
.getViewerScopedEntityCompanionForClass(this);
|
|
280
|
-
const privacyPolicy = companion.entityCompanion.privacyPolicy;
|
|
281
|
-
const evaluationResult = await asyncResult(
|
|
282
|
-
privacyPolicy.authorizeDeleteAsync(
|
|
283
|
-
existingEntity.getViewerContext(),
|
|
284
|
-
queryContext,
|
|
285
|
-
{ cascadingDeleteCause: null },
|
|
286
|
-
existingEntity,
|
|
287
|
-
companion.getMetricsAdapter()
|
|
288
|
-
)
|
|
289
|
-
);
|
|
290
|
-
return evaluationResult.ok;
|
|
291
|
-
}
|
|
292
200
|
}
|
|
293
201
|
|
|
294
202
|
/**
|
|
@@ -306,7 +214,7 @@ export interface IEntityClass<
|
|
|
306
214
|
TEntity,
|
|
307
215
|
TSelectedFields
|
|
308
216
|
>,
|
|
309
|
-
TSelectedFields extends keyof TFields = keyof TFields
|
|
217
|
+
TSelectedFields extends keyof TFields = keyof TFields,
|
|
310
218
|
> {
|
|
311
219
|
new (constructorParam: {
|
|
312
220
|
viewerContext: TViewerContext;
|
|
@@ -16,7 +16,7 @@ export default class EntityAssociationLoader<
|
|
|
16
16
|
TID extends NonNullable<TFields[TSelectedFields]>,
|
|
17
17
|
TViewerContext extends ViewerContext,
|
|
18
18
|
TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>,
|
|
19
|
-
TSelectedFields extends keyof TFields
|
|
19
|
+
TSelectedFields extends keyof TFields,
|
|
20
20
|
> {
|
|
21
21
|
constructor(private readonly entity: TEntity) {}
|
|
22
22
|
|
|
@@ -44,7 +44,7 @@ export default class EntityAssociationLoader<
|
|
|
44
44
|
TAssociatedEntity,
|
|
45
45
|
TAssociatedSelectedFields
|
|
46
46
|
>,
|
|
47
|
-
TAssociatedSelectedFields extends keyof TAssociatedFields = keyof TAssociatedFields
|
|
47
|
+
TAssociatedSelectedFields extends keyof TAssociatedFields = keyof TAssociatedFields,
|
|
48
48
|
>(
|
|
49
49
|
fieldIdentifyingAssociatedEntity: TIdentifyingField,
|
|
50
50
|
associatedEntityClass: IEntityClass<
|
|
@@ -55,7 +55,11 @@ export default class EntityAssociationLoader<
|
|
|
55
55
|
TAssociatedPrivacyPolicy,
|
|
56
56
|
TAssociatedSelectedFields
|
|
57
57
|
>,
|
|
58
|
-
queryContext: EntityQueryContext
|
|
58
|
+
queryContext: EntityQueryContext = this.entity
|
|
59
|
+
.getViewerContext()
|
|
60
|
+
.getViewerScopedEntityCompanionForClass(associatedEntityClass)
|
|
61
|
+
.getQueryContextProvider()
|
|
62
|
+
.getQueryContext(),
|
|
59
63
|
): Promise<
|
|
60
64
|
Result<null extends TFields[TIdentifyingField] ? TAssociatedEntity | null : TAssociatedEntity>
|
|
61
65
|
> {
|
|
@@ -70,9 +74,11 @@ export default class EntityAssociationLoader<
|
|
|
70
74
|
.getViewerContext()
|
|
71
75
|
.getViewerScopedEntityCompanionForClass(associatedEntityClass)
|
|
72
76
|
.getLoaderFactory()
|
|
73
|
-
.forLoad(queryContext, { cascadingDeleteCause: null });
|
|
77
|
+
.forLoad(queryContext, { previousValue: null, cascadingDeleteCause: null });
|
|
74
78
|
|
|
75
|
-
return (await loader
|
|
79
|
+
return (await loader
|
|
80
|
+
.withAuthorizationResults()
|
|
81
|
+
.loadByIDAsync(associatedEntityID as unknown as TAssociatedID)) as Result<
|
|
76
82
|
null extends TFields[TIdentifyingField] ? TAssociatedEntity | null : TAssociatedEntity
|
|
77
83
|
>;
|
|
78
84
|
}
|
|
@@ -102,7 +108,7 @@ export default class EntityAssociationLoader<
|
|
|
102
108
|
TAssociatedEntity,
|
|
103
109
|
TAssociatedSelectedFields
|
|
104
110
|
>,
|
|
105
|
-
TAssociatedSelectedFields extends keyof TAssociatedFields = keyof TAssociatedFields
|
|
111
|
+
TAssociatedSelectedFields extends keyof TAssociatedFields = keyof TAssociatedFields,
|
|
106
112
|
>(
|
|
107
113
|
associatedEntityClass: IEntityClass<
|
|
108
114
|
TAssociatedFields,
|
|
@@ -113,18 +119,21 @@ export default class EntityAssociationLoader<
|
|
|
113
119
|
TAssociatedSelectedFields
|
|
114
120
|
>,
|
|
115
121
|
associatedEntityFieldContainingThisID: keyof Pick<TAssociatedFields, TAssociatedSelectedFields>,
|
|
116
|
-
queryContext: EntityQueryContext
|
|
122
|
+
queryContext: EntityQueryContext = this.entity
|
|
123
|
+
.getViewerContext()
|
|
124
|
+
.getViewerScopedEntityCompanionForClass(associatedEntityClass)
|
|
125
|
+
.getQueryContextProvider()
|
|
126
|
+
.getQueryContext(),
|
|
117
127
|
): Promise<readonly Result<TAssociatedEntity>[]> {
|
|
118
128
|
const thisID = this.entity.getID();
|
|
119
129
|
const loader = this.entity
|
|
120
130
|
.getViewerContext()
|
|
121
131
|
.getViewerScopedEntityCompanionForClass(associatedEntityClass)
|
|
122
132
|
.getLoaderFactory()
|
|
123
|
-
.forLoad(queryContext, { cascadingDeleteCause: null });
|
|
124
|
-
return await loader
|
|
125
|
-
|
|
126
|
-
thisID as any
|
|
127
|
-
);
|
|
133
|
+
.forLoad(queryContext, { previousValue: null, cascadingDeleteCause: null });
|
|
134
|
+
return await loader
|
|
135
|
+
.withAuthorizationResults()
|
|
136
|
+
.loadManyByFieldEqualingAsync(associatedEntityFieldContainingThisID, thisID as any);
|
|
128
137
|
}
|
|
129
138
|
|
|
130
139
|
/**
|
|
@@ -151,7 +160,7 @@ export default class EntityAssociationLoader<
|
|
|
151
160
|
TAssociatedEntity,
|
|
152
161
|
TAssociatedSelectedFields
|
|
153
162
|
>,
|
|
154
|
-
TAssociatedSelectedFields extends keyof TAssociatedFields = keyof TAssociatedFields
|
|
163
|
+
TAssociatedSelectedFields extends keyof TAssociatedFields = keyof TAssociatedFields,
|
|
155
164
|
>(
|
|
156
165
|
fieldIdentifyingAssociatedEntity: keyof Pick<TFields, TSelectedFields>,
|
|
157
166
|
associatedEntityClass: IEntityClass<
|
|
@@ -163,7 +172,11 @@ export default class EntityAssociationLoader<
|
|
|
163
172
|
TAssociatedSelectedFields
|
|
164
173
|
>,
|
|
165
174
|
associatedEntityLookupByField: keyof Pick<TAssociatedFields, TAssociatedSelectedFields>,
|
|
166
|
-
queryContext: EntityQueryContext
|
|
175
|
+
queryContext: EntityQueryContext = this.entity
|
|
176
|
+
.getViewerContext()
|
|
177
|
+
.getViewerScopedEntityCompanionForClass(associatedEntityClass)
|
|
178
|
+
.getQueryContextProvider()
|
|
179
|
+
.getQueryContext(),
|
|
167
180
|
): Promise<Result<TAssociatedEntity> | null> {
|
|
168
181
|
const associatedFieldValue = this.entity.getField(fieldIdentifyingAssociatedEntity);
|
|
169
182
|
if (!associatedFieldValue) {
|
|
@@ -173,11 +186,10 @@ export default class EntityAssociationLoader<
|
|
|
173
186
|
.getViewerContext()
|
|
174
187
|
.getViewerScopedEntityCompanionForClass(associatedEntityClass)
|
|
175
188
|
.getLoaderFactory()
|
|
176
|
-
.forLoad(queryContext, { cascadingDeleteCause: null });
|
|
177
|
-
return await loader
|
|
178
|
-
|
|
179
|
-
associatedFieldValue as any
|
|
180
|
-
);
|
|
189
|
+
.forLoad(queryContext, { previousValue: null, cascadingDeleteCause: null });
|
|
190
|
+
return await loader
|
|
191
|
+
.withAuthorizationResults()
|
|
192
|
+
.loadByFieldEqualingAsync(associatedEntityLookupByField, associatedFieldValue as any);
|
|
181
193
|
}
|
|
182
194
|
|
|
183
195
|
/**
|
|
@@ -204,7 +216,7 @@ export default class EntityAssociationLoader<
|
|
|
204
216
|
TAssociatedEntity,
|
|
205
217
|
TAssociatedSelectedFields
|
|
206
218
|
>,
|
|
207
|
-
TAssociatedSelectedFields extends keyof TAssociatedFields = keyof TAssociatedFields
|
|
219
|
+
TAssociatedSelectedFields extends keyof TAssociatedFields = keyof TAssociatedFields,
|
|
208
220
|
>(
|
|
209
221
|
fieldIdentifyingAssociatedEntity: keyof Pick<TFields, TSelectedFields>,
|
|
210
222
|
associatedEntityClass: IEntityClass<
|
|
@@ -216,7 +228,11 @@ export default class EntityAssociationLoader<
|
|
|
216
228
|
TAssociatedSelectedFields
|
|
217
229
|
>,
|
|
218
230
|
associatedEntityLookupByField: keyof Pick<TAssociatedFields, TAssociatedSelectedFields>,
|
|
219
|
-
queryContext: EntityQueryContext
|
|
231
|
+
queryContext: EntityQueryContext = this.entity
|
|
232
|
+
.getViewerContext()
|
|
233
|
+
.getViewerScopedEntityCompanionForClass(associatedEntityClass)
|
|
234
|
+
.getQueryContextProvider()
|
|
235
|
+
.getQueryContext(),
|
|
220
236
|
): Promise<readonly Result<TAssociatedEntity>[]> {
|
|
221
237
|
const associatedFieldValue = this.entity.getField(fieldIdentifyingAssociatedEntity);
|
|
222
238
|
if (!associatedFieldValue) {
|
|
@@ -227,11 +243,10 @@ export default class EntityAssociationLoader<
|
|
|
227
243
|
.getViewerContext()
|
|
228
244
|
.getViewerScopedEntityCompanionForClass(associatedEntityClass)
|
|
229
245
|
.getLoaderFactory()
|
|
230
|
-
.forLoad(queryContext, { cascadingDeleteCause: null });
|
|
231
|
-
return await loader
|
|
232
|
-
|
|
233
|
-
associatedFieldValue as any
|
|
234
|
-
);
|
|
246
|
+
.forLoad(queryContext, { previousValue: null, cascadingDeleteCause: null });
|
|
247
|
+
return await loader
|
|
248
|
+
.withAuthorizationResults()
|
|
249
|
+
.loadManyByFieldEqualingAsync(associatedEntityLookupByField, associatedFieldValue as any);
|
|
235
250
|
}
|
|
236
251
|
|
|
237
252
|
/**
|
|
@@ -251,7 +266,7 @@ export default class EntityAssociationLoader<
|
|
|
251
266
|
TEntity2,
|
|
252
267
|
TSelectedFields2
|
|
253
268
|
>,
|
|
254
|
-
TSelectedFields2 extends keyof TFields2 = keyof TFields2
|
|
269
|
+
TSelectedFields2 extends keyof TFields2 = keyof TFields2,
|
|
255
270
|
>(
|
|
256
271
|
loadDirectives: [
|
|
257
272
|
EntityLoadThroughDirective<
|
|
@@ -263,9 +278,9 @@ export default class EntityAssociationLoader<
|
|
|
263
278
|
TPrivacyPolicy2,
|
|
264
279
|
TSelectedFields,
|
|
265
280
|
TSelectedFields2
|
|
266
|
-
|
|
281
|
+
>,
|
|
267
282
|
],
|
|
268
|
-
queryContext
|
|
283
|
+
queryContext?: EntityQueryContext,
|
|
269
284
|
): Promise<Result<TEntity2> | null>;
|
|
270
285
|
|
|
271
286
|
/**
|
|
@@ -296,7 +311,7 @@ export default class EntityAssociationLoader<
|
|
|
296
311
|
TSelectedFields3
|
|
297
312
|
>,
|
|
298
313
|
TSelectedFields2 extends keyof TFields2 = keyof TFields2,
|
|
299
|
-
TSelectedFields3 extends keyof TFields3 = keyof TFields3
|
|
314
|
+
TSelectedFields3 extends keyof TFields3 = keyof TFields3,
|
|
300
315
|
>(
|
|
301
316
|
loadDirectives: [
|
|
302
317
|
EntityLoadThroughDirective<
|
|
@@ -318,9 +333,9 @@ export default class EntityAssociationLoader<
|
|
|
318
333
|
TPrivacyPolicy3,
|
|
319
334
|
TSelectedFields2,
|
|
320
335
|
TSelectedFields3
|
|
321
|
-
|
|
336
|
+
>,
|
|
322
337
|
],
|
|
323
|
-
queryContext
|
|
338
|
+
queryContext?: EntityQueryContext,
|
|
324
339
|
): Promise<Result<TEntity3> | null>;
|
|
325
340
|
|
|
326
341
|
/**
|
|
@@ -362,9 +377,9 @@ export default class EntityAssociationLoader<
|
|
|
362
377
|
>,
|
|
363
378
|
TSelectedFields2 extends keyof TFields2 = keyof TFields2,
|
|
364
379
|
TSelectedFields3 extends keyof TFields3 = keyof TFields3,
|
|
365
|
-
TSelectedFields4 extends keyof TFields4 = keyof TFields4
|
|
380
|
+
TSelectedFields4 extends keyof TFields4 = keyof TFields4,
|
|
366
381
|
>(
|
|
367
|
-
|
|
382
|
+
loadDirectives: [
|
|
368
383
|
EntityLoadThroughDirective<
|
|
369
384
|
TViewerContext,
|
|
370
385
|
TFields,
|
|
@@ -394,9 +409,9 @@ export default class EntityAssociationLoader<
|
|
|
394
409
|
TPrivacyPolicy4,
|
|
395
410
|
TSelectedFields3,
|
|
396
411
|
TSelectedFields4
|
|
397
|
-
|
|
412
|
+
>,
|
|
398
413
|
],
|
|
399
|
-
queryContext
|
|
414
|
+
queryContext?: EntityQueryContext,
|
|
400
415
|
): Promise<Result<TEntity4> | null>;
|
|
401
416
|
|
|
402
417
|
/**
|
|
@@ -407,12 +422,12 @@ export default class EntityAssociationLoader<
|
|
|
407
422
|
*/
|
|
408
423
|
async loadAssociatedEntityThroughAsync(
|
|
409
424
|
loadDirectives: EntityLoadThroughDirective<TViewerContext, any, any, any, any, any, any, any>[],
|
|
410
|
-
queryContext
|
|
425
|
+
queryContext?: EntityQueryContext,
|
|
411
426
|
): Promise<Result<ReadonlyEntity<any, any, any, any>> | null>;
|
|
412
427
|
|
|
413
428
|
async loadAssociatedEntityThroughAsync(
|
|
414
429
|
loadDirectives: EntityLoadThroughDirective<TViewerContext, any, any, any, any, any, any, any>[],
|
|
415
|
-
queryContext
|
|
430
|
+
queryContext?: EntityQueryContext,
|
|
416
431
|
): Promise<Result<ReadonlyEntity<any, any, any, any>> | null> {
|
|
417
432
|
let currentEntity: ReadonlyEntity<any, any, any, any> = this.entity;
|
|
418
433
|
for (const loadDirective of loadDirectives) {
|
|
@@ -429,7 +444,7 @@ export default class EntityAssociationLoader<
|
|
|
429
444
|
fieldIdentifyingAssociatedEntity,
|
|
430
445
|
associatedEntityClass,
|
|
431
446
|
associatedEntityLookupByField,
|
|
432
|
-
queryContext
|
|
447
|
+
queryContext,
|
|
433
448
|
);
|
|
434
449
|
} else {
|
|
435
450
|
const associatedEntityResultLocal = await currentEntity
|
|
@@ -437,7 +452,7 @@ export default class EntityAssociationLoader<
|
|
|
437
452
|
.loadAssociatedEntityAsync(
|
|
438
453
|
fieldIdentifyingAssociatedEntity,
|
|
439
454
|
associatedEntityClass,
|
|
440
|
-
queryContext
|
|
455
|
+
queryContext,
|
|
441
456
|
);
|
|
442
457
|
|
|
443
458
|
if (associatedEntityResultLocal.ok && associatedEntityResultLocal.value === null) {
|
|
@@ -482,7 +497,7 @@ export interface EntityLoadThroughDirective<
|
|
|
482
497
|
TAssociatedSelectedFields
|
|
483
498
|
>,
|
|
484
499
|
TSelectedFields extends keyof TFields = keyof TFields,
|
|
485
|
-
TAssociatedSelectedFields extends keyof TAssociatedFields = keyof TAssociatedFields
|
|
500
|
+
TAssociatedSelectedFields extends keyof TAssociatedFields = keyof TAssociatedFields,
|
|
486
501
|
> {
|
|
487
502
|
/**
|
|
488
503
|
* Class of entity to load at this step.
|
package/src/EntityCompanion.ts
CHANGED
|
@@ -7,6 +7,7 @@ import ReadonlyEntity from './ReadonlyEntity';
|
|
|
7
7
|
import ViewerContext from './ViewerContext';
|
|
8
8
|
import EntityTableDataCoordinator from './internal/EntityTableDataCoordinator';
|
|
9
9
|
import IEntityMetricsAdapter from './metrics/IEntityMetricsAdapter';
|
|
10
|
+
import { mergeEntityMutationTriggerConfigurations } from './utils/mergeEntityMutationTriggerConfigurations';
|
|
10
11
|
|
|
11
12
|
export interface IPrivacyPolicyClass<TPrivacyPolicy> {
|
|
12
13
|
new (): TPrivacyPolicy;
|
|
@@ -27,7 +28,7 @@ export default class EntityCompanion<
|
|
|
27
28
|
TEntity,
|
|
28
29
|
TSelectedFields
|
|
29
30
|
>,
|
|
30
|
-
TSelectedFields extends keyof TFields
|
|
31
|
+
TSelectedFields extends keyof TFields,
|
|
31
32
|
> {
|
|
32
33
|
public readonly privacyPolicy: TPrivacyPolicy;
|
|
33
34
|
|
|
@@ -59,7 +60,7 @@ export default class EntityCompanion<
|
|
|
59
60
|
TSelectedFields
|
|
60
61
|
>,
|
|
61
62
|
private readonly tableDataCoordinator: EntityTableDataCoordinator<TFields>,
|
|
62
|
-
private readonly metricsAdapter: IEntityMetricsAdapter
|
|
63
|
+
private readonly metricsAdapter: IEntityMetricsAdapter,
|
|
63
64
|
) {
|
|
64
65
|
this.privacyPolicy = new entityCompanionDefinition.privacyPolicyClass();
|
|
65
66
|
this.entityLoaderFactory = new EntityLoaderFactory<
|
|
@@ -76,10 +77,13 @@ export default class EntityCompanion<
|
|
|
76
77
|
entityCompanionDefinition.entityClass,
|
|
77
78
|
this.privacyPolicy,
|
|
78
79
|
entityCompanionDefinition.mutationValidators ?? [],
|
|
79
|
-
|
|
80
|
+
mergeEntityMutationTriggerConfigurations(
|
|
81
|
+
entityCompanionDefinition.mutationTriggers ?? {},
|
|
82
|
+
entityCompanionProvider.globalMutationTriggers ?? {},
|
|
83
|
+
),
|
|
80
84
|
this.entityLoaderFactory,
|
|
81
85
|
tableDataCoordinator.databaseAdapter,
|
|
82
|
-
metricsAdapter
|
|
86
|
+
metricsAdapter,
|
|
83
87
|
);
|
|
84
88
|
}
|
|
85
89
|
|
|
@@ -61,7 +61,7 @@ export interface EntityCompanionDefinition<
|
|
|
61
61
|
TEntity,
|
|
62
62
|
TSelectedFields
|
|
63
63
|
>,
|
|
64
|
-
TSelectedFields extends keyof TFields = keyof TFields
|
|
64
|
+
TSelectedFields extends keyof TFields = keyof TFields,
|
|
65
65
|
> {
|
|
66
66
|
/**
|
|
67
67
|
* The concrete Entity class for which this is the definition.
|
|
@@ -139,6 +139,7 @@ export default class EntityCompanionProvider {
|
|
|
139
139
|
* @param metricsAdapter - An IEntityMetricsAdapter for collecting metrics on this instance
|
|
140
140
|
* @param databaseAdapterFlavors - Database adapter configurations for this instance
|
|
141
141
|
* @param cacheAdapterFlavors - Cache adapter configurations for this instance
|
|
142
|
+
* @param globalMutationTriggers - Optional set of EntityMutationTrigger to run for all entity mutations systemwide.
|
|
142
143
|
*/
|
|
143
144
|
constructor(
|
|
144
145
|
public readonly metricsAdapter: IEntityMetricsAdapter,
|
|
@@ -146,7 +147,14 @@ export default class EntityCompanionProvider {
|
|
|
146
147
|
DatabaseAdapterFlavor,
|
|
147
148
|
DatabaseAdapterFlavorDefinition
|
|
148
149
|
>,
|
|
149
|
-
private cacheAdapterFlavors: ReadonlyMap<CacheAdapterFlavor, CacheAdapterFlavorDefinition
|
|
150
|
+
private cacheAdapterFlavors: ReadonlyMap<CacheAdapterFlavor, CacheAdapterFlavorDefinition>,
|
|
151
|
+
readonly globalMutationTriggers: EntityMutationTriggerConfiguration<
|
|
152
|
+
any,
|
|
153
|
+
any,
|
|
154
|
+
any,
|
|
155
|
+
any,
|
|
156
|
+
any
|
|
157
|
+
> = {},
|
|
150
158
|
) {}
|
|
151
159
|
|
|
152
160
|
/**
|
|
@@ -167,7 +175,7 @@ export default class EntityCompanionProvider {
|
|
|
167
175
|
TEntity,
|
|
168
176
|
TSelectedFields
|
|
169
177
|
>,
|
|
170
|
-
TSelectedFields extends keyof TFields
|
|
178
|
+
TSelectedFields extends keyof TFields,
|
|
171
179
|
>(
|
|
172
180
|
entityClass: IEntityClass<
|
|
173
181
|
TFields,
|
|
@@ -176,58 +184,58 @@ export default class EntityCompanionProvider {
|
|
|
176
184
|
TEntity,
|
|
177
185
|
TPrivacyPolicy,
|
|
178
186
|
TSelectedFields
|
|
179
|
-
|
|
187
|
+
>,
|
|
180
188
|
): EntityCompanion<TFields, TID, TViewerContext, TEntity, TPrivacyPolicy, TSelectedFields> {
|
|
181
189
|
const entityCompanionDefinition = computeIfAbsent(
|
|
182
190
|
this.companionDefinitionMap,
|
|
183
191
|
entityClass.name,
|
|
184
|
-
() => entityClass.defineCompanionDefinition()
|
|
192
|
+
() => entityClass.defineCompanionDefinition(),
|
|
185
193
|
);
|
|
186
194
|
const tableDataCoordinator = this.getTableDataCoordinatorForEntity(
|
|
187
195
|
entityCompanionDefinition.entityConfiguration,
|
|
188
|
-
entityClass.name
|
|
196
|
+
entityClass.name,
|
|
189
197
|
);
|
|
190
198
|
return computeIfAbsent(this.companionMap, entityClass.name, () => {
|
|
191
199
|
return new EntityCompanion(
|
|
192
200
|
this,
|
|
193
201
|
entityCompanionDefinition,
|
|
194
202
|
tableDataCoordinator,
|
|
195
|
-
this.metricsAdapter
|
|
203
|
+
this.metricsAdapter,
|
|
196
204
|
);
|
|
197
205
|
});
|
|
198
206
|
}
|
|
199
207
|
|
|
200
208
|
getQueryContextProviderForDatabaseAdaptorFlavor(
|
|
201
|
-
databaseAdapterFlavor: DatabaseAdapterFlavor
|
|
209
|
+
databaseAdapterFlavor: DatabaseAdapterFlavor,
|
|
202
210
|
): EntityQueryContextProvider {
|
|
203
211
|
const entityDatabaseAdapterFlavor = this.databaseAdapterFlavors.get(databaseAdapterFlavor);
|
|
204
212
|
invariant(
|
|
205
213
|
entityDatabaseAdapterFlavor,
|
|
206
|
-
`No database adaptor configuration found for flavor: ${databaseAdapterFlavor}
|
|
214
|
+
`No database adaptor configuration found for flavor: ${databaseAdapterFlavor}`,
|
|
207
215
|
);
|
|
208
216
|
|
|
209
217
|
return entityDatabaseAdapterFlavor.queryContextProvider;
|
|
210
218
|
}
|
|
211
219
|
|
|
212
|
-
private getTableDataCoordinatorForEntity<TFields
|
|
220
|
+
private getTableDataCoordinatorForEntity<TFields extends Record<string, any>>(
|
|
213
221
|
entityConfiguration: EntityConfiguration<TFields>,
|
|
214
|
-
entityClassName: string
|
|
222
|
+
entityClassName: string,
|
|
215
223
|
): EntityTableDataCoordinator<TFields> {
|
|
216
224
|
return computeIfAbsent(this.tableDataCoordinatorMap, entityConfiguration.tableName, () => {
|
|
217
225
|
const entityDatabaseAdapterFlavor = this.databaseAdapterFlavors.get(
|
|
218
|
-
entityConfiguration.databaseAdapterFlavor
|
|
226
|
+
entityConfiguration.databaseAdapterFlavor,
|
|
219
227
|
);
|
|
220
228
|
invariant(
|
|
221
229
|
entityDatabaseAdapterFlavor,
|
|
222
|
-
`No database adaptor configuration found for flavor: ${entityConfiguration.databaseAdapterFlavor}
|
|
230
|
+
`No database adaptor configuration found for flavor: ${entityConfiguration.databaseAdapterFlavor}`,
|
|
223
231
|
);
|
|
224
232
|
|
|
225
233
|
const entityCacheAdapterFlavor = this.cacheAdapterFlavors.get(
|
|
226
|
-
entityConfiguration.cacheAdapterFlavor
|
|
234
|
+
entityConfiguration.cacheAdapterFlavor,
|
|
227
235
|
);
|
|
228
236
|
invariant(
|
|
229
237
|
entityCacheAdapterFlavor,
|
|
230
|
-
`No cache adaptor configuration found for flavor: ${entityConfiguration.cacheAdapterFlavor}
|
|
238
|
+
`No cache adaptor configuration found for flavor: ${entityConfiguration.cacheAdapterFlavor}`,
|
|
231
239
|
);
|
|
232
240
|
|
|
233
241
|
return new EntityTableDataCoordinator(
|
|
@@ -236,7 +244,7 @@ export default class EntityCompanionProvider {
|
|
|
236
244
|
entityCacheAdapterFlavor.cacheAdapterProvider,
|
|
237
245
|
entityDatabaseAdapterFlavor.queryContextProvider,
|
|
238
246
|
this.metricsAdapter,
|
|
239
|
-
entityClassName
|
|
247
|
+
entityClassName,
|
|
240
248
|
);
|
|
241
249
|
});
|
|
242
250
|
}
|