@expo/entity 0.35.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 +0 -27
- package/build/Entity.js +0 -50
- package/build/Entity.js.map +1 -1
- package/build/EntityAssociationLoader.d.ts +1 -1
- package/build/EntityAssociationLoader.js +17 -8
- 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/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.js +5 -1
- package/build/ReadonlyEntity.js.map +1 -1
- package/build/ViewerContext.js +2 -0
- 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 +0 -132
- package/build/__tests__/Entity-test.js.map +1 -1
- package/build/__tests__/EntityAssociationLoader-test.js +6 -2
- package/build/__tests__/EntityAssociationLoader-test.js.map +1 -1
- package/build/__tests__/EntityCommonUseCases-test.js +24 -22
- 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 +61 -20
- 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 +16 -17
- package/build/__tests__/EntityLoader-constructor-test.js.map +1 -1
- package/build/__tests__/EntityLoader-test.js +74 -22
- package/build/__tests__/EntityLoader-test.js.map +1 -1
- package/build/__tests__/EntityMutator-MutationCacheConsistency-test.js +12 -15
- package/build/__tests__/EntityMutator-MutationCacheConsistency-test.js.map +1 -1
- package/build/__tests__/EntityMutator-test.js +54 -9
- 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__/EntitySelfReferentialEdges-test.js +42 -25
- package/build/__tests__/EntitySelfReferentialEdges-test.js.map +1 -1
- package/build/__tests__/ViewerScopedEntityLoaderFactory-test.js.map +1 -1
- package/build/__tests__/cases/TwoEntitySameTableDisjointRows-test.js +20 -18
- package/build/__tests__/cases/TwoEntitySameTableDisjointRows-test.js.map +1 -1
- package/build/__tests__/cases/TwoEntitySameTableOverlappingRows-test.js +12 -15
- 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 +6 -1
- 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__/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.js +12 -15
- package/build/testfixtures/SimpleTestEntity.js.map +1 -1
- package/build/testfixtures/TestEntity.js +12 -15
- package/build/testfixtures/TestEntity.js.map +1 -1
- 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/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 +11 -126
- package/src/EntityAssociationLoader.ts +40 -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 +5 -5
- 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 +5 -5
- package/src/ViewerContext.ts +5 -5
- 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 +0 -202
- package/src/__tests__/EntityAssociationLoader-test.ts +29 -25
- package/src/__tests__/EntityCommonUseCases-test.ts +29 -13
- 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 +108 -36
- package/src/__tests__/EntityFields-test.ts +14 -2
- package/src/__tests__/EntityLoader-constructor-test.ts +20 -7
- package/src/__tests__/EntityLoader-test.ts +214 -86
- package/src/__tests__/EntityMutator-MutationCacheConsistency-test.ts +2 -2
- package/src/__tests__/EntityMutator-test.ts +281 -96
- package/src/__tests__/EntityPrivacyPolicy-test.ts +166 -53
- package/src/__tests__/EntityQueryContext-test.ts +30 -12
- package/src/__tests__/EntitySecondaryCacheLoader-test.ts +7 -7
- package/src/__tests__/EntitySelfReferentialEdges-test.ts +46 -26
- package/src/__tests__/GenericEntityCacheAdapter-test.ts +2 -2
- package/src/__tests__/ViewerContext-test.ts +1 -1
- 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 +19 -19
- 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 +24 -24
- 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 +51 -51
- 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/TestEntity.ts +1 -1
- package/src/testfixtures/TestEntityWithMutationTriggers.ts +156 -0
- 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
|
@@ -26,7 +26,7 @@ export default class EntityMutatorFactory<
|
|
|
26
26
|
TEntity,
|
|
27
27
|
TSelectedFields
|
|
28
28
|
>,
|
|
29
|
-
TSelectedFields extends keyof TFields = keyof TFields
|
|
29
|
+
TSelectedFields extends keyof TFields = keyof TFields,
|
|
30
30
|
> {
|
|
31
31
|
constructor(
|
|
32
32
|
private readonly entityCompanionProvider: EntityCompanionProvider,
|
|
@@ -63,7 +63,7 @@ export default class EntityMutatorFactory<
|
|
|
63
63
|
TSelectedFields
|
|
64
64
|
>,
|
|
65
65
|
private readonly databaseAdapter: EntityDatabaseAdapter<TFields>,
|
|
66
|
-
private readonly metricsAdapter: IEntityMetricsAdapter
|
|
66
|
+
private readonly metricsAdapter: IEntityMetricsAdapter,
|
|
67
67
|
) {}
|
|
68
68
|
|
|
69
69
|
/**
|
|
@@ -74,7 +74,7 @@ export default class EntityMutatorFactory<
|
|
|
74
74
|
*/
|
|
75
75
|
forCreate(
|
|
76
76
|
viewerContext: TViewerContext,
|
|
77
|
-
queryContext: EntityQueryContext
|
|
77
|
+
queryContext: EntityQueryContext,
|
|
78
78
|
): CreateMutator<TFields, TID, TViewerContext, TEntity, TPrivacyPolicy, TSelectedFields> {
|
|
79
79
|
return new CreateMutator(
|
|
80
80
|
this.entityCompanionProvider,
|
|
@@ -87,7 +87,7 @@ export default class EntityMutatorFactory<
|
|
|
87
87
|
this.mutationTriggers,
|
|
88
88
|
this.entityLoaderFactory,
|
|
89
89
|
this.databaseAdapter,
|
|
90
|
-
this.metricsAdapter
|
|
90
|
+
this.metricsAdapter,
|
|
91
91
|
);
|
|
92
92
|
}
|
|
93
93
|
|
|
@@ -99,7 +99,7 @@ export default class EntityMutatorFactory<
|
|
|
99
99
|
*/
|
|
100
100
|
forUpdate(
|
|
101
101
|
existingEntity: TEntity,
|
|
102
|
-
queryContext: EntityQueryContext
|
|
102
|
+
queryContext: EntityQueryContext,
|
|
103
103
|
): UpdateMutator<TFields, TID, TViewerContext, TEntity, TPrivacyPolicy, TSelectedFields> {
|
|
104
104
|
return new UpdateMutator(
|
|
105
105
|
this.entityCompanionProvider,
|
|
@@ -113,7 +113,7 @@ export default class EntityMutatorFactory<
|
|
|
113
113
|
this.entityLoaderFactory,
|
|
114
114
|
this.databaseAdapter,
|
|
115
115
|
this.metricsAdapter,
|
|
116
|
-
existingEntity
|
|
116
|
+
existingEntity,
|
|
117
117
|
);
|
|
118
118
|
}
|
|
119
119
|
|
|
@@ -124,7 +124,7 @@ export default class EntityMutatorFactory<
|
|
|
124
124
|
*/
|
|
125
125
|
forDelete(
|
|
126
126
|
existingEntity: TEntity,
|
|
127
|
-
queryContext: EntityQueryContext
|
|
127
|
+
queryContext: EntityQueryContext,
|
|
128
128
|
): DeleteMutator<TFields, TID, TViewerContext, TEntity, TPrivacyPolicy, TSelectedFields> {
|
|
129
129
|
return new DeleteMutator(
|
|
130
130
|
this.entityCompanionProvider,
|
|
@@ -138,7 +138,7 @@ export default class EntityMutatorFactory<
|
|
|
138
138
|
this.entityLoaderFactory,
|
|
139
139
|
this.databaseAdapter,
|
|
140
140
|
this.metricsAdapter,
|
|
141
|
-
existingEntity
|
|
141
|
+
existingEntity,
|
|
142
142
|
);
|
|
143
143
|
}
|
|
144
144
|
}
|
|
@@ -11,7 +11,19 @@ import PrivacyPolicyRule, { RuleEvaluationResult } from './rules/PrivacyPolicyRu
|
|
|
11
11
|
/**
|
|
12
12
|
* Information about the reason this privacy policy is being evaluated.
|
|
13
13
|
*/
|
|
14
|
-
export type EntityPrivacyPolicyEvaluationContext
|
|
14
|
+
export type EntityPrivacyPolicyEvaluationContext<
|
|
15
|
+
TFields extends object,
|
|
16
|
+
TID extends NonNullable<TFields[TSelectedFields]>,
|
|
17
|
+
TViewerContext extends ViewerContext,
|
|
18
|
+
TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>,
|
|
19
|
+
TSelectedFields extends keyof TFields = keyof TFields,
|
|
20
|
+
> = {
|
|
21
|
+
/**
|
|
22
|
+
* When this privacy policy is being evaluated as a result of an update, this will be populated with the value
|
|
23
|
+
* of the entity before the update. Note that this doesn't only apply to UPDATE authorization actions though:
|
|
24
|
+
* when an entity is updated it is re-LOADed after the update completes.
|
|
25
|
+
*/
|
|
26
|
+
previousValue: TEntity | null;
|
|
15
27
|
/**
|
|
16
28
|
* When this privacy policy is being evaluated as a result of a cascading deletion, this will be populated
|
|
17
29
|
* with information on the cascading delete.
|
|
@@ -45,7 +57,7 @@ export type EntityPrivacyPolicyEvaluator<
|
|
|
45
57
|
TID extends NonNullable<TFields[TSelectedFields]>,
|
|
46
58
|
TViewerContext extends ViewerContext,
|
|
47
59
|
TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>,
|
|
48
|
-
TSelectedFields extends keyof TFields = keyof TFields
|
|
60
|
+
TSelectedFields extends keyof TFields = keyof TFields,
|
|
49
61
|
> =
|
|
50
62
|
| {
|
|
51
63
|
mode: EntityPrivacyPolicyEvaluationMode.ENFORCE;
|
|
@@ -53,13 +65,13 @@ export type EntityPrivacyPolicyEvaluator<
|
|
|
53
65
|
| {
|
|
54
66
|
mode: EntityPrivacyPolicyEvaluationMode.DRY_RUN;
|
|
55
67
|
denyHandler: (
|
|
56
|
-
error: EntityNotAuthorizedError<TFields, TID, TViewerContext, TEntity, TSelectedFields
|
|
68
|
+
error: EntityNotAuthorizedError<TFields, TID, TViewerContext, TEntity, TSelectedFields>,
|
|
57
69
|
) => void;
|
|
58
70
|
}
|
|
59
71
|
| {
|
|
60
72
|
mode: EntityPrivacyPolicyEvaluationMode.ENFORCE_AND_LOG;
|
|
61
73
|
denyHandler: (
|
|
62
|
-
error: EntityNotAuthorizedError<TFields, TID, TViewerContext, TEntity, TSelectedFields
|
|
74
|
+
error: EntityNotAuthorizedError<TFields, TID, TViewerContext, TEntity, TSelectedFields>,
|
|
63
75
|
) => void;
|
|
64
76
|
};
|
|
65
77
|
|
|
@@ -96,7 +108,7 @@ export default abstract class EntityPrivacyPolicy<
|
|
|
96
108
|
TID extends NonNullable<TFields[TSelectedFields]>,
|
|
97
109
|
TViewerContext extends ViewerContext,
|
|
98
110
|
TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>,
|
|
99
|
-
TSelectedFields extends keyof TFields = keyof TFields
|
|
111
|
+
TSelectedFields extends keyof TFields = keyof TFields,
|
|
100
112
|
> {
|
|
101
113
|
protected readonly createRules: readonly PrivacyPolicyRule<
|
|
102
114
|
TFields,
|
|
@@ -136,7 +148,7 @@ export default abstract class EntityPrivacyPolicy<
|
|
|
136
148
|
* Override to enable dry run evaluation of the policy.
|
|
137
149
|
*/
|
|
138
150
|
protected getPrivacyPolicyEvaluator(
|
|
139
|
-
_viewerContext: TViewerContext
|
|
151
|
+
_viewerContext: TViewerContext,
|
|
140
152
|
): EntityPrivacyPolicyEvaluator<TFields, TID, TViewerContext, TEntity, TSelectedFields> {
|
|
141
153
|
return {
|
|
142
154
|
mode: EntityPrivacyPolicyEvaluationMode.ENFORCE,
|
|
@@ -154,9 +166,15 @@ export default abstract class EntityPrivacyPolicy<
|
|
|
154
166
|
async authorizeCreateAsync(
|
|
155
167
|
viewerContext: TViewerContext,
|
|
156
168
|
queryContext: EntityQueryContext,
|
|
157
|
-
evaluationContext: EntityPrivacyPolicyEvaluationContext
|
|
169
|
+
evaluationContext: EntityPrivacyPolicyEvaluationContext<
|
|
170
|
+
TFields,
|
|
171
|
+
TID,
|
|
172
|
+
TViewerContext,
|
|
173
|
+
TEntity,
|
|
174
|
+
TSelectedFields
|
|
175
|
+
>,
|
|
158
176
|
entity: TEntity,
|
|
159
|
-
metricsAdapter: IEntityMetricsAdapter
|
|
177
|
+
metricsAdapter: IEntityMetricsAdapter,
|
|
160
178
|
): Promise<TEntity> {
|
|
161
179
|
return await this.authorizeForRulesetAsync(
|
|
162
180
|
this.createRules,
|
|
@@ -165,7 +183,7 @@ export default abstract class EntityPrivacyPolicy<
|
|
|
165
183
|
evaluationContext,
|
|
166
184
|
entity,
|
|
167
185
|
EntityAuthorizationAction.CREATE,
|
|
168
|
-
metricsAdapter
|
|
186
|
+
metricsAdapter,
|
|
169
187
|
);
|
|
170
188
|
}
|
|
171
189
|
|
|
@@ -180,9 +198,15 @@ export default abstract class EntityPrivacyPolicy<
|
|
|
180
198
|
async authorizeReadAsync(
|
|
181
199
|
viewerContext: TViewerContext,
|
|
182
200
|
queryContext: EntityQueryContext,
|
|
183
|
-
evaluationContext: EntityPrivacyPolicyEvaluationContext
|
|
201
|
+
evaluationContext: EntityPrivacyPolicyEvaluationContext<
|
|
202
|
+
TFields,
|
|
203
|
+
TID,
|
|
204
|
+
TViewerContext,
|
|
205
|
+
TEntity,
|
|
206
|
+
TSelectedFields
|
|
207
|
+
>,
|
|
184
208
|
entity: TEntity,
|
|
185
|
-
metricsAdapter: IEntityMetricsAdapter
|
|
209
|
+
metricsAdapter: IEntityMetricsAdapter,
|
|
186
210
|
): Promise<TEntity> {
|
|
187
211
|
return await this.authorizeForRulesetAsync(
|
|
188
212
|
this.readRules,
|
|
@@ -191,7 +215,7 @@ export default abstract class EntityPrivacyPolicy<
|
|
|
191
215
|
evaluationContext,
|
|
192
216
|
entity,
|
|
193
217
|
EntityAuthorizationAction.READ,
|
|
194
|
-
metricsAdapter
|
|
218
|
+
metricsAdapter,
|
|
195
219
|
);
|
|
196
220
|
}
|
|
197
221
|
|
|
@@ -206,9 +230,15 @@ export default abstract class EntityPrivacyPolicy<
|
|
|
206
230
|
async authorizeUpdateAsync(
|
|
207
231
|
viewerContext: TViewerContext,
|
|
208
232
|
queryContext: EntityQueryContext,
|
|
209
|
-
evaluationContext: EntityPrivacyPolicyEvaluationContext
|
|
233
|
+
evaluationContext: EntityPrivacyPolicyEvaluationContext<
|
|
234
|
+
TFields,
|
|
235
|
+
TID,
|
|
236
|
+
TViewerContext,
|
|
237
|
+
TEntity,
|
|
238
|
+
TSelectedFields
|
|
239
|
+
>,
|
|
210
240
|
entity: TEntity,
|
|
211
|
-
metricsAdapter: IEntityMetricsAdapter
|
|
241
|
+
metricsAdapter: IEntityMetricsAdapter,
|
|
212
242
|
): Promise<TEntity> {
|
|
213
243
|
return await this.authorizeForRulesetAsync(
|
|
214
244
|
this.updateRules,
|
|
@@ -217,7 +247,7 @@ export default abstract class EntityPrivacyPolicy<
|
|
|
217
247
|
evaluationContext,
|
|
218
248
|
entity,
|
|
219
249
|
EntityAuthorizationAction.UPDATE,
|
|
220
|
-
metricsAdapter
|
|
250
|
+
metricsAdapter,
|
|
221
251
|
);
|
|
222
252
|
}
|
|
223
253
|
|
|
@@ -232,9 +262,15 @@ export default abstract class EntityPrivacyPolicy<
|
|
|
232
262
|
async authorizeDeleteAsync(
|
|
233
263
|
viewerContext: TViewerContext,
|
|
234
264
|
queryContext: EntityQueryContext,
|
|
235
|
-
evaluationContext: EntityPrivacyPolicyEvaluationContext
|
|
265
|
+
evaluationContext: EntityPrivacyPolicyEvaluationContext<
|
|
266
|
+
TFields,
|
|
267
|
+
TID,
|
|
268
|
+
TViewerContext,
|
|
269
|
+
TEntity,
|
|
270
|
+
TSelectedFields
|
|
271
|
+
>,
|
|
236
272
|
entity: TEntity,
|
|
237
|
-
metricsAdapter: IEntityMetricsAdapter
|
|
273
|
+
metricsAdapter: IEntityMetricsAdapter,
|
|
238
274
|
): Promise<TEntity> {
|
|
239
275
|
return await this.authorizeForRulesetAsync(
|
|
240
276
|
this.deleteRules,
|
|
@@ -243,7 +279,7 @@ export default abstract class EntityPrivacyPolicy<
|
|
|
243
279
|
evaluationContext,
|
|
244
280
|
entity,
|
|
245
281
|
EntityAuthorizationAction.DELETE,
|
|
246
|
-
metricsAdapter
|
|
282
|
+
metricsAdapter,
|
|
247
283
|
);
|
|
248
284
|
}
|
|
249
285
|
|
|
@@ -251,10 +287,16 @@ export default abstract class EntityPrivacyPolicy<
|
|
|
251
287
|
ruleset: readonly PrivacyPolicyRule<TFields, TID, TViewerContext, TEntity, TSelectedFields>[],
|
|
252
288
|
viewerContext: TViewerContext,
|
|
253
289
|
queryContext: EntityQueryContext,
|
|
254
|
-
evaluationContext: EntityPrivacyPolicyEvaluationContext
|
|
290
|
+
evaluationContext: EntityPrivacyPolicyEvaluationContext<
|
|
291
|
+
TFields,
|
|
292
|
+
TID,
|
|
293
|
+
TViewerContext,
|
|
294
|
+
TEntity,
|
|
295
|
+
TSelectedFields
|
|
296
|
+
>,
|
|
255
297
|
entity: TEntity,
|
|
256
298
|
action: EntityAuthorizationAction,
|
|
257
|
-
metricsAdapter: IEntityMetricsAdapter
|
|
299
|
+
metricsAdapter: IEntityMetricsAdapter,
|
|
258
300
|
): Promise<TEntity> {
|
|
259
301
|
const privacyPolicyEvaluator = this.getPrivacyPolicyEvaluator(viewerContext);
|
|
260
302
|
switch (privacyPolicyEvaluator.mode) {
|
|
@@ -266,7 +308,7 @@ export default abstract class EntityPrivacyPolicy<
|
|
|
266
308
|
queryContext,
|
|
267
309
|
evaluationContext,
|
|
268
310
|
entity,
|
|
269
|
-
action
|
|
311
|
+
action,
|
|
270
312
|
);
|
|
271
313
|
metricsAdapter.logAuthorizationEvent({
|
|
272
314
|
entityClassName: entity.constructor.name,
|
|
@@ -295,7 +337,7 @@ export default abstract class EntityPrivacyPolicy<
|
|
|
295
337
|
queryContext,
|
|
296
338
|
evaluationContext,
|
|
297
339
|
entity,
|
|
298
|
-
action
|
|
340
|
+
action,
|
|
299
341
|
);
|
|
300
342
|
metricsAdapter.logAuthorizationEvent({
|
|
301
343
|
entityClassName: entity.constructor.name,
|
|
@@ -325,7 +367,7 @@ export default abstract class EntityPrivacyPolicy<
|
|
|
325
367
|
queryContext,
|
|
326
368
|
evaluationContext,
|
|
327
369
|
entity,
|
|
328
|
-
action
|
|
370
|
+
action,
|
|
329
371
|
);
|
|
330
372
|
metricsAdapter.logAuthorizationEvent({
|
|
331
373
|
entityClassName: entity.constructor.name,
|
|
@@ -354,9 +396,15 @@ export default abstract class EntityPrivacyPolicy<
|
|
|
354
396
|
ruleset: readonly PrivacyPolicyRule<TFields, TID, TViewerContext, TEntity, TSelectedFields>[],
|
|
355
397
|
viewerContext: TViewerContext,
|
|
356
398
|
queryContext: EntityQueryContext,
|
|
357
|
-
evaluationContext: EntityPrivacyPolicyEvaluationContext
|
|
399
|
+
evaluationContext: EntityPrivacyPolicyEvaluationContext<
|
|
400
|
+
TFields,
|
|
401
|
+
TID,
|
|
402
|
+
TViewerContext,
|
|
403
|
+
TEntity,
|
|
404
|
+
TSelectedFields
|
|
405
|
+
>,
|
|
358
406
|
entity: TEntity,
|
|
359
|
-
action: EntityAuthorizationAction
|
|
407
|
+
action: EntityAuthorizationAction,
|
|
360
408
|
): Promise<TEntity> {
|
|
361
409
|
for (let i = 0; i < ruleset.length; i++) {
|
|
362
410
|
const rule = ruleset[i]!;
|
|
@@ -364,7 +412,7 @@ export default abstract class EntityPrivacyPolicy<
|
|
|
364
412
|
viewerContext,
|
|
365
413
|
queryContext,
|
|
366
414
|
evaluationContext,
|
|
367
|
-
entity
|
|
415
|
+
entity,
|
|
368
416
|
);
|
|
369
417
|
switch (ruleEvaluationResult) {
|
|
370
418
|
case RuleEvaluationResult.DENY:
|
|
@@ -380,7 +428,9 @@ export default abstract class EntityPrivacyPolicy<
|
|
|
380
428
|
case RuleEvaluationResult.ALLOW:
|
|
381
429
|
return entity;
|
|
382
430
|
default:
|
|
383
|
-
throw new Error(
|
|
431
|
+
throw new Error(
|
|
432
|
+
`Invalid RuleEvaluationResult returned from rule: ${entity} (viewer = ${viewerContext}, action = ${EntityAuthorizationAction[action]}, ruleIndex = ${i})`,
|
|
433
|
+
);
|
|
384
434
|
}
|
|
385
435
|
}
|
|
386
436
|
|
|
@@ -388,7 +438,7 @@ export default abstract class EntityPrivacyPolicy<
|
|
|
388
438
|
entity,
|
|
389
439
|
viewerContext,
|
|
390
440
|
action,
|
|
391
|
-
-1
|
|
441
|
+
-1,
|
|
392
442
|
);
|
|
393
443
|
}
|
|
394
444
|
}
|
|
@@ -36,7 +36,7 @@ export abstract class EntityQueryContext {
|
|
|
36
36
|
|
|
37
37
|
abstract runInTransactionIfNotInTransactionAsync<T>(
|
|
38
38
|
transactionScope: (queryContext: EntityTransactionalQueryContext) => Promise<T>,
|
|
39
|
-
transactionConfig?: TransactionConfig
|
|
39
|
+
transactionConfig?: TransactionConfig,
|
|
40
40
|
): Promise<T>;
|
|
41
41
|
}
|
|
42
42
|
|
|
@@ -49,7 +49,7 @@ export abstract class EntityQueryContext {
|
|
|
49
49
|
export class EntityNonTransactionalQueryContext extends EntityQueryContext {
|
|
50
50
|
constructor(
|
|
51
51
|
queryInterface: any,
|
|
52
|
-
private readonly entityQueryContextProvider: EntityQueryContextProvider
|
|
52
|
+
private readonly entityQueryContextProvider: EntityQueryContextProvider,
|
|
53
53
|
) {
|
|
54
54
|
super(queryInterface);
|
|
55
55
|
}
|
|
@@ -60,11 +60,11 @@ export class EntityNonTransactionalQueryContext extends EntityQueryContext {
|
|
|
60
60
|
|
|
61
61
|
async runInTransactionIfNotInTransactionAsync<T>(
|
|
62
62
|
transactionScope: (queryContext: EntityTransactionalQueryContext) => Promise<T>,
|
|
63
|
-
transactionConfig?: TransactionConfig
|
|
63
|
+
transactionConfig?: TransactionConfig,
|
|
64
64
|
): Promise<T> {
|
|
65
65
|
return await this.entityQueryContextProvider.runInTransactionAsync(
|
|
66
66
|
transactionScope,
|
|
67
|
-
transactionConfig
|
|
67
|
+
transactionConfig,
|
|
68
68
|
);
|
|
69
69
|
}
|
|
70
70
|
}
|
|
@@ -82,7 +82,7 @@ export class EntityTransactionalQueryContext extends EntityQueryContext {
|
|
|
82
82
|
|
|
83
83
|
constructor(
|
|
84
84
|
queryInterface: any,
|
|
85
|
-
private readonly entityQueryContextProvider: EntityQueryContextProvider
|
|
85
|
+
private readonly entityQueryContextProvider: EntityQueryContextProvider,
|
|
86
86
|
) {
|
|
87
87
|
super(queryInterface);
|
|
88
88
|
}
|
|
@@ -98,7 +98,7 @@ export class EntityTransactionalQueryContext extends EntityQueryContext {
|
|
|
98
98
|
public appendPreCommitCallback(callback: PreCommitCallback, order: number): void {
|
|
99
99
|
assert(
|
|
100
100
|
order >= Number.MIN_SAFE_INTEGER && order <= Number.MAX_SAFE_INTEGER,
|
|
101
|
-
`Invalid order specified: ${order}
|
|
101
|
+
`Invalid order specified: ${order}`,
|
|
102
102
|
);
|
|
103
103
|
this.preCommitCallbacks.push({ callback, order });
|
|
104
104
|
}
|
|
@@ -148,21 +148,21 @@ export class EntityTransactionalQueryContext extends EntityQueryContext {
|
|
|
148
148
|
|
|
149
149
|
async runInTransactionIfNotInTransactionAsync<T>(
|
|
150
150
|
transactionScope: (queryContext: EntityTransactionalQueryContext) => Promise<T>,
|
|
151
|
-
transactionConfig?: TransactionConfig
|
|
151
|
+
transactionConfig?: TransactionConfig,
|
|
152
152
|
): Promise<T> {
|
|
153
153
|
assert(
|
|
154
154
|
transactionConfig === undefined,
|
|
155
|
-
'Should not pass transactionConfig to a nested transaction'
|
|
155
|
+
'Should not pass transactionConfig to a nested transaction',
|
|
156
156
|
);
|
|
157
157
|
return await transactionScope(this);
|
|
158
158
|
}
|
|
159
159
|
|
|
160
160
|
async runInNestedTransactionAsync<T>(
|
|
161
|
-
transactionScope: (innerQueryContext: EntityTransactionalQueryContext) => Promise<T
|
|
161
|
+
transactionScope: (innerQueryContext: EntityTransactionalQueryContext) => Promise<T>,
|
|
162
162
|
): Promise<T> {
|
|
163
163
|
return await this.entityQueryContextProvider.runInNestedTransactionAsync(
|
|
164
164
|
this,
|
|
165
|
-
transactionScope
|
|
165
|
+
transactionScope,
|
|
166
166
|
);
|
|
167
167
|
}
|
|
168
168
|
}
|
|
@@ -172,7 +172,8 @@ export class EntityTransactionalQueryContext extends EntityQueryContext {
|
|
|
172
172
|
* to EntityMutator and EntityLoader methods, those methods and their
|
|
173
173
|
* dependent triggers and validators will run within the nested transaction.
|
|
174
174
|
*
|
|
175
|
-
* This exists to forward post-commit callbacks to the parent query context
|
|
175
|
+
* This exists to forward post-commit callbacks to the parent query context but only after
|
|
176
|
+
* successful commit of the nested transaction.
|
|
176
177
|
*/
|
|
177
178
|
export class EntityNestedTransactionalQueryContext extends EntityTransactionalQueryContext {
|
|
178
179
|
private readonly postCommitInvalidationCallbacksToTransfer: PostCommitCallback[] = [];
|
|
@@ -181,7 +182,7 @@ export class EntityNestedTransactionalQueryContext extends EntityTransactionalQu
|
|
|
181
182
|
constructor(
|
|
182
183
|
queryInterface: any,
|
|
183
184
|
private readonly parentQueryContext: EntityTransactionalQueryContext,
|
|
184
|
-
entityQueryContextProvider: EntityQueryContextProvider
|
|
185
|
+
entityQueryContextProvider: EntityQueryContextProvider,
|
|
185
186
|
) {
|
|
186
187
|
super(queryInterface, entityQueryContextProvider);
|
|
187
188
|
}
|
|
@@ -196,7 +197,7 @@ export class EntityNestedTransactionalQueryContext extends EntityTransactionalQu
|
|
|
196
197
|
|
|
197
198
|
public override runPostCommitCallbacksAsync(): Promise<void> {
|
|
198
199
|
throw new Error(
|
|
199
|
-
'Must not call runPostCommitCallbacksAsync on EntityNestedTransactionalQueryContext'
|
|
200
|
+
'Must not call runPostCommitCallbacksAsync on EntityNestedTransactionalQueryContext',
|
|
200
201
|
);
|
|
201
202
|
}
|
|
202
203
|
|
|
@@ -25,11 +25,11 @@ export default abstract class EntityQueryContextProvider {
|
|
|
25
25
|
* Vend a transaction runner for use in runInTransactionAsync.
|
|
26
26
|
*/
|
|
27
27
|
protected abstract createTransactionRunner<T>(
|
|
28
|
-
transactionConfig?: TransactionConfig
|
|
28
|
+
transactionConfig?: TransactionConfig,
|
|
29
29
|
): (transactionScope: (queryInterface: any) => Promise<T>) => Promise<T>;
|
|
30
30
|
|
|
31
31
|
protected abstract createNestedTransactionRunner<T>(
|
|
32
|
-
outerQueryInterface: any
|
|
32
|
+
outerQueryInterface: any,
|
|
33
33
|
): (transactionScope: (queryInterface: any) => Promise<T>) => Promise<T>;
|
|
34
34
|
|
|
35
35
|
/**
|
|
@@ -38,7 +38,7 @@ export default abstract class EntityQueryContextProvider {
|
|
|
38
38
|
*/
|
|
39
39
|
async runInTransactionAsync<T>(
|
|
40
40
|
transactionScope: (queryContext: EntityTransactionalQueryContext) => Promise<T>,
|
|
41
|
-
transactionConfig?: TransactionConfig
|
|
41
|
+
transactionConfig?: TransactionConfig,
|
|
42
42
|
): Promise<T> {
|
|
43
43
|
const [returnedValue, queryContext] = await this.createTransactionRunner<
|
|
44
44
|
[T, EntityTransactionalQueryContext]
|
|
@@ -60,7 +60,7 @@ export default abstract class EntityQueryContextProvider {
|
|
|
60
60
|
*/
|
|
61
61
|
async runInNestedTransactionAsync<T>(
|
|
62
62
|
outerQueryContext: EntityTransactionalQueryContext,
|
|
63
|
-
transactionScope: (innerQueryContext: EntityNestedTransactionalQueryContext) => Promise<T
|
|
63
|
+
transactionScope: (innerQueryContext: EntityNestedTransactionalQueryContext) => Promise<T>,
|
|
64
64
|
): Promise<T> {
|
|
65
65
|
const [returnedValue, innerQueryContext] = await this.createNestedTransactionRunner<
|
|
66
66
|
[T, EntityNestedTransactionalQueryContext]
|
|
@@ -68,7 +68,7 @@ export default abstract class EntityQueryContextProvider {
|
|
|
68
68
|
const innerQueryContext = new EntityNestedTransactionalQueryContext(
|
|
69
69
|
innerQueryInterface,
|
|
70
70
|
outerQueryContext,
|
|
71
|
-
this
|
|
71
|
+
this,
|
|
72
72
|
);
|
|
73
73
|
const result = await transactionScope(innerQueryContext);
|
|
74
74
|
await innerQueryContext.runPreCommitCallbacksAsync();
|
|
@@ -20,8 +20,8 @@ export interface ISecondaryEntityCache<TFields, TLoadParams> {
|
|
|
20
20
|
loadManyThroughAsync(
|
|
21
21
|
loadParamsArray: readonly Readonly<TLoadParams>[],
|
|
22
22
|
fetcher: (
|
|
23
|
-
fetcherLoadParamsArray: readonly Readonly<TLoadParams>[]
|
|
24
|
-
) => Promise<ReadonlyMap<Readonly<TLoadParams>, Readonly<TFields> | null
|
|
23
|
+
fetcherLoadParamsArray: readonly Readonly<TLoadParams>[],
|
|
24
|
+
) => Promise<ReadonlyMap<Readonly<TLoadParams>, Readonly<TFields> | null>>,
|
|
25
25
|
): Promise<ReadonlyMap<Readonly<TLoadParams>, Readonly<TFields> | null>>;
|
|
26
26
|
|
|
27
27
|
/**
|
|
@@ -56,7 +56,7 @@ export default abstract class EntitySecondaryCacheLoader<
|
|
|
56
56
|
TEntity,
|
|
57
57
|
TSelectedFields
|
|
58
58
|
>,
|
|
59
|
-
TSelectedFields extends keyof TFields = keyof TFields
|
|
59
|
+
TSelectedFields extends keyof TFields = keyof TFields,
|
|
60
60
|
> {
|
|
61
61
|
constructor(
|
|
62
62
|
private readonly secondaryEntityCache: ISecondaryEntityCache<TFields, TLoadParams>,
|
|
@@ -67,7 +67,7 @@ export default abstract class EntitySecondaryCacheLoader<
|
|
|
67
67
|
TEntity,
|
|
68
68
|
TPrivacyPolicy,
|
|
69
69
|
TSelectedFields
|
|
70
|
-
|
|
70
|
+
>,
|
|
71
71
|
) {}
|
|
72
72
|
|
|
73
73
|
/**
|
|
@@ -76,17 +76,19 @@ export default abstract class EntitySecondaryCacheLoader<
|
|
|
76
76
|
* @param loadParamsArray - array of loadParams to load through the cache
|
|
77
77
|
*/
|
|
78
78
|
public async loadManyAsync(
|
|
79
|
-
loadParamsArray: readonly Readonly<TLoadParams>[]
|
|
79
|
+
loadParamsArray: readonly Readonly<TLoadParams>[],
|
|
80
80
|
): Promise<ReadonlyMap<Readonly<TLoadParams>, Result<TEntity> | null>> {
|
|
81
81
|
const loadParamsToFieldObjects = await this.secondaryEntityCache.loadManyThroughAsync(
|
|
82
82
|
loadParamsArray,
|
|
83
|
-
this.fetchObjectsFromDatabaseAsync.bind(this)
|
|
83
|
+
this.fetchObjectsFromDatabaseAsync.bind(this),
|
|
84
84
|
);
|
|
85
85
|
|
|
86
86
|
// convert value to and from array to reuse complex code
|
|
87
|
-
const entitiesMap = await this.entityLoader
|
|
88
|
-
|
|
89
|
-
|
|
87
|
+
const entitiesMap = await this.entityLoader
|
|
88
|
+
.utils()
|
|
89
|
+
.constructAndAuthorizeEntitiesAsync(
|
|
90
|
+
mapMap(loadParamsToFieldObjects, (fieldObject) => (fieldObject ? [fieldObject] : [])),
|
|
91
|
+
);
|
|
90
92
|
return mapMap(entitiesMap, (fieldObjects) => fieldObjects[0] ?? null);
|
|
91
93
|
}
|
|
92
94
|
|
|
@@ -96,7 +98,7 @@ export default abstract class EntitySecondaryCacheLoader<
|
|
|
96
98
|
* @param loadParamsArray - array of load params objects to invalidate
|
|
97
99
|
*/
|
|
98
100
|
public async invalidateManyAsync(
|
|
99
|
-
loadParamsArray: readonly Readonly<TLoadParams>[]
|
|
101
|
+
loadParamsArray: readonly Readonly<TLoadParams>[],
|
|
100
102
|
): Promise<void> {
|
|
101
103
|
await this.secondaryEntityCache.invalidateManyAsync(loadParamsArray);
|
|
102
104
|
}
|
|
@@ -107,6 +109,6 @@ export default abstract class EntitySecondaryCacheLoader<
|
|
|
107
109
|
* @param loadParamsArray - array of load params objects to load
|
|
108
110
|
*/
|
|
109
111
|
protected abstract fetchObjectsFromDatabaseAsync(
|
|
110
|
-
loadParamsArray: readonly Readonly<TLoadParams>[]
|
|
112
|
+
loadParamsArray: readonly Readonly<TLoadParams>[],
|
|
111
113
|
): Promise<ReadonlyMap<Readonly<Readonly<TLoadParams>>, Readonly<TFields> | null>>;
|
|
112
114
|
}
|
|
@@ -13,16 +13,16 @@ export default class GenericEntityCacheAdapter<TFields> implements IEntityCacheA
|
|
|
13
13
|
|
|
14
14
|
public async loadManyAsync<N extends keyof TFields>(
|
|
15
15
|
fieldName: N,
|
|
16
|
-
fieldValues: readonly NonNullable<TFields[N]>[]
|
|
16
|
+
fieldValues: readonly NonNullable<TFields[N]>[],
|
|
17
17
|
): Promise<ReadonlyMap<NonNullable<TFields[N]>, CacheLoadResult<TFields>>> {
|
|
18
18
|
const redisCacheKeyToFieldValueMapping = new Map(
|
|
19
19
|
fieldValues.map((fieldValue) => [
|
|
20
20
|
this.genericCacher.makeCacheKey(fieldName, fieldValue),
|
|
21
21
|
fieldValue,
|
|
22
|
-
])
|
|
22
|
+
]),
|
|
23
23
|
);
|
|
24
24
|
const cacheResults = await this.genericCacher.loadManyAsync(
|
|
25
|
-
Array.from(redisCacheKeyToFieldValueMapping.keys())
|
|
25
|
+
Array.from(redisCacheKeyToFieldValueMapping.keys()),
|
|
26
26
|
);
|
|
27
27
|
|
|
28
28
|
return mapKeys(cacheResults, (redisCacheKey) => {
|
|
@@ -30,7 +30,7 @@ export default class GenericEntityCacheAdapter<TFields> implements IEntityCacheA
|
|
|
30
30
|
invariant(
|
|
31
31
|
fieldValue !== undefined,
|
|
32
32
|
'Unspecified cache key %s returned from generic cacher',
|
|
33
|
-
redisCacheKey
|
|
33
|
+
redisCacheKey,
|
|
34
34
|
);
|
|
35
35
|
return fieldValue;
|
|
36
36
|
});
|
|
@@ -38,28 +38,28 @@ export default class GenericEntityCacheAdapter<TFields> implements IEntityCacheA
|
|
|
38
38
|
|
|
39
39
|
public async cacheManyAsync<N extends keyof TFields>(
|
|
40
40
|
fieldName: N,
|
|
41
|
-
objectMap: ReadonlyMap<NonNullable<TFields[N]>, Readonly<TFields
|
|
41
|
+
objectMap: ReadonlyMap<NonNullable<TFields[N]>, Readonly<TFields>>,
|
|
42
42
|
): Promise<void> {
|
|
43
43
|
await this.genericCacher.cacheManyAsync(
|
|
44
|
-
mapKeys(objectMap, (fieldValue) => this.genericCacher.makeCacheKey(fieldName, fieldValue))
|
|
44
|
+
mapKeys(objectMap, (fieldValue) => this.genericCacher.makeCacheKey(fieldName, fieldValue)),
|
|
45
45
|
);
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
public async cacheDBMissesAsync<N extends keyof TFields>(
|
|
49
49
|
fieldName: N,
|
|
50
|
-
fieldValues: readonly NonNullable<TFields[N]>[]
|
|
50
|
+
fieldValues: readonly NonNullable<TFields[N]>[],
|
|
51
51
|
): Promise<void> {
|
|
52
52
|
await this.genericCacher.cacheDBMissesAsync(
|
|
53
|
-
fieldValues.map((fieldValue) => this.genericCacher.makeCacheKey(fieldName, fieldValue))
|
|
53
|
+
fieldValues.map((fieldValue) => this.genericCacher.makeCacheKey(fieldName, fieldValue)),
|
|
54
54
|
);
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
public async invalidateManyAsync<N extends keyof TFields>(
|
|
58
58
|
fieldName: N,
|
|
59
|
-
fieldValues: readonly NonNullable<TFields[N]>[]
|
|
59
|
+
fieldValues: readonly NonNullable<TFields[N]>[],
|
|
60
60
|
): Promise<void> {
|
|
61
61
|
await this.genericCacher.invalidateManyAsync(
|
|
62
|
-
fieldValues.map((fieldValue) => this.genericCacher.makeCacheKey(fieldName, fieldValue))
|
|
62
|
+
fieldValues.map((fieldValue) => this.genericCacher.makeCacheKey(fieldName, fieldValue)),
|
|
63
63
|
);
|
|
64
64
|
}
|
|
65
65
|
}
|
|
@@ -15,14 +15,14 @@ export default abstract class GenericSecondaryEntityCache<TFields, TLoadParams>
|
|
|
15
15
|
{
|
|
16
16
|
constructor(
|
|
17
17
|
protected readonly cacher: IEntityGenericCacher<TFields>,
|
|
18
|
-
protected readonly constructCacheKey: (params: Readonly<TLoadParams>) => string
|
|
18
|
+
protected readonly constructCacheKey: (params: Readonly<TLoadParams>) => string,
|
|
19
19
|
) {}
|
|
20
20
|
|
|
21
21
|
public async loadManyThroughAsync(
|
|
22
22
|
loadParamsArray: readonly Readonly<TLoadParams>[],
|
|
23
23
|
fetcher: (
|
|
24
|
-
fetcherLoadParamsArray: readonly Readonly<TLoadParams>[]
|
|
25
|
-
) => Promise<ReadonlyMap<Readonly<TLoadParams>, Readonly<TFields> | null
|
|
24
|
+
fetcherLoadParamsArray: readonly Readonly<TLoadParams>[],
|
|
25
|
+
) => Promise<ReadonlyMap<Readonly<TLoadParams>, Readonly<TFields> | null>>,
|
|
26
26
|
): Promise<ReadonlyMap<Readonly<TLoadParams>, Readonly<TFields> | null>> {
|
|
27
27
|
const cacheKeys = loadParamsArray.map(this.constructCacheKey);
|
|
28
28
|
const cacheKeyToLoadParamsMap = zipToMap(cacheKeys, loadParamsArray);
|
|
@@ -31,14 +31,14 @@ export default abstract class GenericSecondaryEntityCache<TFields, TLoadParams>
|
|
|
31
31
|
|
|
32
32
|
invariant(
|
|
33
33
|
cacheLoadResults.size === loadParamsArray.length,
|
|
34
|
-
`${this.constructor.name} loadMany should return a result for each key
|
|
34
|
+
`${this.constructor.name} loadMany should return a result for each key`,
|
|
35
35
|
);
|
|
36
36
|
|
|
37
37
|
const cacheKeysToFetch = Array.from(
|
|
38
38
|
filterMap(
|
|
39
39
|
cacheLoadResults,
|
|
40
|
-
(cacheLoadResult) => cacheLoadResult.status === CacheStatus.MISS
|
|
41
|
-
).keys()
|
|
40
|
+
(cacheLoadResult) => cacheLoadResult.status === CacheStatus.MISS,
|
|
41
|
+
).keys(),
|
|
42
42
|
);
|
|
43
43
|
|
|
44
44
|
// put cache hits in result map
|
|
@@ -13,7 +13,7 @@ export default interface IEntityCacheAdapter<TFields> {
|
|
|
13
13
|
*/
|
|
14
14
|
loadManyAsync<N extends keyof TFields>(
|
|
15
15
|
fieldName: N,
|
|
16
|
-
fieldValues: readonly NonNullable<TFields[N]>[]
|
|
16
|
+
fieldValues: readonly NonNullable<TFields[N]>[],
|
|
17
17
|
): Promise<ReadonlyMap<NonNullable<TFields[N]>, CacheLoadResult<TFields>>>;
|
|
18
18
|
|
|
19
19
|
/**
|
|
@@ -23,7 +23,7 @@ export default interface IEntityCacheAdapter<TFields> {
|
|
|
23
23
|
*/
|
|
24
24
|
cacheManyAsync<N extends keyof TFields>(
|
|
25
25
|
fieldName: N,
|
|
26
|
-
objectMap: ReadonlyMap<NonNullable<TFields[N]>, Readonly<TFields
|
|
26
|
+
objectMap: ReadonlyMap<NonNullable<TFields[N]>, Readonly<TFields>>,
|
|
27
27
|
): Promise<void>;
|
|
28
28
|
|
|
29
29
|
/**
|
|
@@ -34,7 +34,7 @@ export default interface IEntityCacheAdapter<TFields> {
|
|
|
34
34
|
*/
|
|
35
35
|
cacheDBMissesAsync<N extends keyof TFields>(
|
|
36
36
|
fieldName: N,
|
|
37
|
-
fieldValues: readonly NonNullable<TFields[N]>[]
|
|
37
|
+
fieldValues: readonly NonNullable<TFields[N]>[],
|
|
38
38
|
): Promise<void>;
|
|
39
39
|
|
|
40
40
|
/**
|
|
@@ -44,6 +44,6 @@ export default interface IEntityCacheAdapter<TFields> {
|
|
|
44
44
|
*/
|
|
45
45
|
invalidateManyAsync<N extends keyof TFields>(
|
|
46
46
|
fieldName: N,
|
|
47
|
-
fieldValues: readonly NonNullable<TFields[N]>[]
|
|
47
|
+
fieldValues: readonly NonNullable<TFields[N]>[],
|
|
48
48
|
): Promise<void>;
|
|
49
49
|
}
|