@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
|
@@ -14,19 +14,19 @@ export default class ComposedSecondaryEntityCache<TLoadParams, TFields>
|
|
|
14
14
|
* Typically, caches closer to the application should be ordered before caches closer to the database.
|
|
15
15
|
*/
|
|
16
16
|
constructor(
|
|
17
|
-
private readonly secondaryEntityCaches: ISecondaryEntityCache<TFields, TLoadParams>[]
|
|
17
|
+
private readonly secondaryEntityCaches: ISecondaryEntityCache<TFields, TLoadParams>[],
|
|
18
18
|
) {}
|
|
19
19
|
|
|
20
20
|
async 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
|
return await ComposedSecondaryEntityCache.loadManyThroughRecursivelyAsync(
|
|
27
27
|
this.secondaryEntityCaches,
|
|
28
28
|
loadParamsArray,
|
|
29
|
-
fetcher
|
|
29
|
+
fetcher,
|
|
30
30
|
);
|
|
31
31
|
}
|
|
32
32
|
|
|
@@ -34,8 +34,8 @@ export default class ComposedSecondaryEntityCache<TLoadParams, TFields>
|
|
|
34
34
|
secondaryEntityCaches: ISecondaryEntityCache<TFields, TLoadParams>[],
|
|
35
35
|
loadParamsArray: readonly Readonly<TLoadParams>[],
|
|
36
36
|
fetcher: (
|
|
37
|
-
fetcherLoadParamsArray: readonly Readonly<TLoadParams>[]
|
|
38
|
-
) => Promise<ReadonlyMap<Readonly<TLoadParams>, Readonly<TFields> | null
|
|
37
|
+
fetcherLoadParamsArray: readonly Readonly<TLoadParams>[],
|
|
38
|
+
) => Promise<ReadonlyMap<Readonly<TLoadParams>, Readonly<TFields> | null>>,
|
|
39
39
|
): Promise<ReadonlyMap<Readonly<TLoadParams>, Readonly<TFields> | null>> {
|
|
40
40
|
if (secondaryEntityCaches.length === 0) {
|
|
41
41
|
return await fetcher(loadParamsArray);
|
|
@@ -49,8 +49,8 @@ export default class ComposedSecondaryEntityCache<TLoadParams, TFields>
|
|
|
49
49
|
ComposedSecondaryEntityCache.loadManyThroughRecursivelyAsync(
|
|
50
50
|
restCaches,
|
|
51
51
|
fetcherLoadParamsArray,
|
|
52
|
-
fetcher
|
|
53
|
-
)
|
|
52
|
+
fetcher,
|
|
53
|
+
),
|
|
54
54
|
);
|
|
55
55
|
}
|
|
56
56
|
|
|
@@ -1,17 +1,18 @@
|
|
|
1
|
+
import AuthorizationResultBasedEntityLoader from './AuthorizationResultBasedEntityLoader';
|
|
1
2
|
import {
|
|
2
3
|
FieldEqualityCondition,
|
|
3
4
|
QuerySelectionModifiers,
|
|
4
5
|
QuerySelectionModifiersWithOrderByRaw,
|
|
5
6
|
} from './EntityDatabaseAdapter';
|
|
6
|
-
import EntityLoader from './EntityLoader';
|
|
7
7
|
import EntityPrivacyPolicy from './EntityPrivacyPolicy';
|
|
8
8
|
import ReadonlyEntity from './ReadonlyEntity';
|
|
9
9
|
import ViewerContext from './ViewerContext';
|
|
10
10
|
import { mapMap } from './utils/collections/maps';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
|
-
* Enforcing
|
|
14
|
-
*
|
|
13
|
+
* Enforcing entity loader. All normal loads are batched,
|
|
14
|
+
* cached, and authorized against the entity's EntityPrivacyPolicy. All loads
|
|
15
|
+
* through this loader will throw if the load is not successful.
|
|
15
16
|
*/
|
|
16
17
|
export default class EnforcingEntityLoader<
|
|
17
18
|
TFields extends object,
|
|
@@ -25,17 +26,17 @@ export default class EnforcingEntityLoader<
|
|
|
25
26
|
TEntity,
|
|
26
27
|
TSelectedFields
|
|
27
28
|
>,
|
|
28
|
-
TSelectedFields extends keyof TFields
|
|
29
|
+
TSelectedFields extends keyof TFields,
|
|
29
30
|
> {
|
|
30
31
|
constructor(
|
|
31
|
-
private readonly entityLoader:
|
|
32
|
+
private readonly entityLoader: AuthorizationResultBasedEntityLoader<
|
|
32
33
|
TFields,
|
|
33
34
|
TID,
|
|
34
35
|
TViewerContext,
|
|
35
36
|
TEntity,
|
|
36
37
|
TPrivacyPolicy,
|
|
37
38
|
TSelectedFields
|
|
38
|
-
|
|
39
|
+
>,
|
|
39
40
|
) {}
|
|
40
41
|
|
|
41
42
|
/**
|
|
@@ -44,14 +45,14 @@ export default class EnforcingEntityLoader<
|
|
|
44
45
|
*/
|
|
45
46
|
async loadManyByFieldEqualingManyAsync<N extends keyof Pick<TFields, TSelectedFields>>(
|
|
46
47
|
fieldName: N,
|
|
47
|
-
fieldValues: readonly NonNullable<TFields[N]>[]
|
|
48
|
+
fieldValues: readonly NonNullable<TFields[N]>[],
|
|
48
49
|
): Promise<ReadonlyMap<NonNullable<TFields[N]>, readonly TEntity[]>> {
|
|
49
50
|
const fieldValuesToResults = await this.entityLoader.loadManyByFieldEqualingManyAsync(
|
|
50
51
|
fieldName,
|
|
51
|
-
fieldValues
|
|
52
|
+
fieldValues,
|
|
52
53
|
);
|
|
53
54
|
return mapMap(fieldValuesToResults, (results) =>
|
|
54
|
-
results.map((result) => result.enforceValue())
|
|
55
|
+
results.map((result) => result.enforceValue()),
|
|
55
56
|
);
|
|
56
57
|
}
|
|
57
58
|
|
|
@@ -61,11 +62,11 @@ export default class EnforcingEntityLoader<
|
|
|
61
62
|
*/
|
|
62
63
|
async loadManyByFieldEqualingAsync<N extends keyof Pick<TFields, TSelectedFields>>(
|
|
63
64
|
fieldName: N,
|
|
64
|
-
fieldValue: NonNullable<TFields[N]
|
|
65
|
+
fieldValue: NonNullable<TFields[N]>,
|
|
65
66
|
): Promise<readonly TEntity[]> {
|
|
66
67
|
const entityResults = await this.entityLoader.loadManyByFieldEqualingAsync(
|
|
67
68
|
fieldName,
|
|
68
|
-
fieldValue
|
|
69
|
+
fieldValue,
|
|
69
70
|
);
|
|
70
71
|
return entityResults.map((result) => result.enforceValue());
|
|
71
72
|
}
|
|
@@ -77,11 +78,11 @@ export default class EnforcingEntityLoader<
|
|
|
77
78
|
*/
|
|
78
79
|
async loadByFieldEqualingAsync<N extends keyof Pick<TFields, TSelectedFields>>(
|
|
79
80
|
uniqueFieldName: N,
|
|
80
|
-
fieldValue: NonNullable<TFields[N]
|
|
81
|
+
fieldValue: NonNullable<TFields[N]>,
|
|
81
82
|
): Promise<TEntity | null> {
|
|
82
83
|
const entityResult = await this.entityLoader.loadByFieldEqualingAsync(
|
|
83
84
|
uniqueFieldName,
|
|
84
|
-
fieldValue
|
|
85
|
+
fieldValue,
|
|
85
86
|
);
|
|
86
87
|
return entityResult ? entityResult.enforceValue() : null;
|
|
87
88
|
}
|
|
@@ -130,11 +131,11 @@ export default class EnforcingEntityLoader<
|
|
|
130
131
|
async loadFirstByFieldEqualityConjunctionAsync<N extends keyof Pick<TFields, TSelectedFields>>(
|
|
131
132
|
fieldEqualityOperands: FieldEqualityCondition<TFields, N>[],
|
|
132
133
|
querySelectionModifiers: Omit<QuerySelectionModifiers<TFields>, 'limit'> &
|
|
133
|
-
Required<Pick<QuerySelectionModifiers<TFields>, 'orderBy'
|
|
134
|
+
Required<Pick<QuerySelectionModifiers<TFields>, 'orderBy'>>,
|
|
134
135
|
): Promise<TEntity | null> {
|
|
135
136
|
const entityResult = await this.entityLoader.loadFirstByFieldEqualityConjunctionAsync(
|
|
136
137
|
fieldEqualityOperands,
|
|
137
|
-
querySelectionModifiers
|
|
138
|
+
querySelectionModifiers,
|
|
138
139
|
);
|
|
139
140
|
return entityResult ? entityResult.enforceValue() : null;
|
|
140
141
|
}
|
|
@@ -145,11 +146,11 @@ export default class EnforcingEntityLoader<
|
|
|
145
146
|
*/
|
|
146
147
|
async loadManyByFieldEqualityConjunctionAsync<N extends keyof Pick<TFields, TSelectedFields>>(
|
|
147
148
|
fieldEqualityOperands: FieldEqualityCondition<TFields, N>[],
|
|
148
|
-
querySelectionModifiers: QuerySelectionModifiers<TFields> = {}
|
|
149
|
+
querySelectionModifiers: QuerySelectionModifiers<TFields> = {},
|
|
149
150
|
): Promise<readonly TEntity[]> {
|
|
150
151
|
const entityResults = await this.entityLoader.loadManyByFieldEqualityConjunctionAsync(
|
|
151
152
|
fieldEqualityOperands,
|
|
152
|
-
querySelectionModifiers
|
|
153
|
+
querySelectionModifiers,
|
|
153
154
|
);
|
|
154
155
|
return entityResults.map((result) => result.enforceValue());
|
|
155
156
|
}
|
|
@@ -161,12 +162,12 @@ export default class EnforcingEntityLoader<
|
|
|
161
162
|
async loadManyByRawWhereClauseAsync(
|
|
162
163
|
rawWhereClause: string,
|
|
163
164
|
bindings: any[] | object,
|
|
164
|
-
querySelectionModifiers: QuerySelectionModifiersWithOrderByRaw<TFields> = {}
|
|
165
|
+
querySelectionModifiers: QuerySelectionModifiersWithOrderByRaw<TFields> = {},
|
|
165
166
|
): Promise<readonly TEntity[]> {
|
|
166
167
|
const entityResults = await this.entityLoader.loadManyByRawWhereClauseAsync(
|
|
167
168
|
rawWhereClause,
|
|
168
169
|
bindings,
|
|
169
|
-
querySelectionModifiers
|
|
170
|
+
querySelectionModifiers,
|
|
170
171
|
);
|
|
171
172
|
return entityResults.map((result) => result.enforceValue());
|
|
172
173
|
}
|
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,
|
|
@@ -64,7 +64,7 @@ export default abstract class Entity<
|
|
|
64
64
|
queryContext: EntityQueryContext = viewerContext
|
|
65
65
|
.getViewerScopedEntityCompanionForClass(this)
|
|
66
66
|
.getQueryContextProvider()
|
|
67
|
-
.getQueryContext()
|
|
67
|
+
.getQueryContext(),
|
|
68
68
|
): CreateMutator<TMFields, TMID, TMViewerContext, TMEntity, TMPrivacyPolicy, TMSelectedFields> {
|
|
69
69
|
return viewerContext
|
|
70
70
|
.getViewerScopedEntityCompanionForClass(this)
|
|
@@ -90,7 +90,7 @@ export default abstract class Entity<
|
|
|
90
90
|
TMEntity,
|
|
91
91
|
TMSelectedFields
|
|
92
92
|
>,
|
|
93
|
-
TMSelectedFields extends keyof TMFields = keyof TMFields
|
|
93
|
+
TMSelectedFields extends keyof TMFields = keyof TMFields,
|
|
94
94
|
>(
|
|
95
95
|
this: IEntityClass<
|
|
96
96
|
TMFields,
|
|
@@ -105,7 +105,7 @@ export default abstract class Entity<
|
|
|
105
105
|
.getViewerContext()
|
|
106
106
|
.getViewerScopedEntityCompanionForClass(this)
|
|
107
107
|
.getQueryContextProvider()
|
|
108
|
-
.getQueryContext()
|
|
108
|
+
.getQueryContext(),
|
|
109
109
|
): UpdateMutator<TMFields, TMID, TMViewerContext, TMEntity, TMPrivacyPolicy, TMSelectedFields> {
|
|
110
110
|
return existingEntity
|
|
111
111
|
.getViewerContext()
|
|
@@ -131,7 +131,7 @@ export default abstract class Entity<
|
|
|
131
131
|
TMEntity,
|
|
132
132
|
TMSelectedFields
|
|
133
133
|
>,
|
|
134
|
-
TMSelectedFields extends keyof TMFields = keyof TMFields
|
|
134
|
+
TMSelectedFields extends keyof TMFields = keyof TMFields,
|
|
135
135
|
>(
|
|
136
136
|
this: IEntityClass<
|
|
137
137
|
TMFields,
|
|
@@ -146,7 +146,7 @@ export default abstract class Entity<
|
|
|
146
146
|
.getViewerContext()
|
|
147
147
|
.getViewerScopedEntityCompanionForClass(this)
|
|
148
148
|
.getQueryContextProvider()
|
|
149
|
-
.getQueryContext()
|
|
149
|
+
.getQueryContext(),
|
|
150
150
|
): Promise<Result<void>> {
|
|
151
151
|
return existingEntity
|
|
152
152
|
.getViewerContext()
|
|
@@ -173,7 +173,7 @@ export default abstract class Entity<
|
|
|
173
173
|
TMEntity,
|
|
174
174
|
TMSelectedFields
|
|
175
175
|
>,
|
|
176
|
-
TMSelectedFields extends keyof TMFields = keyof TMFields
|
|
176
|
+
TMSelectedFields extends keyof TMFields = keyof TMFields,
|
|
177
177
|
>(
|
|
178
178
|
this: IEntityClass<
|
|
179
179
|
TMFields,
|
|
@@ -188,7 +188,7 @@ export default abstract class Entity<
|
|
|
188
188
|
.getViewerContext()
|
|
189
189
|
.getViewerScopedEntityCompanionForClass(this)
|
|
190
190
|
.getQueryContextProvider()
|
|
191
|
-
.getQueryContext()
|
|
191
|
+
.getQueryContext(),
|
|
192
192
|
): Promise<void> {
|
|
193
193
|
return existingEntity
|
|
194
194
|
.getViewerContext()
|
|
@@ -197,121 +197,6 @@ export default abstract class Entity<
|
|
|
197
197
|
.forDelete(existingEntity, queryContext)
|
|
198
198
|
.enforceDeleteAsync();
|
|
199
199
|
}
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* Check whether an entity loaded by a viewer can be updated by that same viewer.
|
|
203
|
-
*
|
|
204
|
-
* @remarks
|
|
205
|
-
*
|
|
206
|
-
* This may be useful in situations relying upon the thrown privacy policy thrown authorization error
|
|
207
|
-
* is insufficient for the task at hand. When dealing with purely a sequence of mutations it is easy
|
|
208
|
-
* to roll back all mutations given a single authorization error by wrapping them in a single transaction.
|
|
209
|
-
* When certain portions of a mutation cannot be rolled back transactionally (third pary calls,
|
|
210
|
-
* legacy code, etc), using this method can help decide whether the sequence of mutations will fail before
|
|
211
|
-
* attempting them. Note that if any privacy policy rules use a piece of data being updated in the mutations
|
|
212
|
-
* the result of this method and the update mutation itself may differ.
|
|
213
|
-
*
|
|
214
|
-
* @param existingEntity - entity loaded by viewer
|
|
215
|
-
* @param queryContext - query context in which to perform the check
|
|
216
|
-
*/
|
|
217
|
-
static async canViewerUpdateAsync<
|
|
218
|
-
TMFields extends object,
|
|
219
|
-
TMID extends NonNullable<TMFields[TMSelectedFields]>,
|
|
220
|
-
TMViewerContext extends ViewerContext,
|
|
221
|
-
TMEntity extends Entity<TMFields, TMID, TMViewerContext, TMSelectedFields>,
|
|
222
|
-
TMPrivacyPolicy extends EntityPrivacyPolicy<
|
|
223
|
-
TMFields,
|
|
224
|
-
TMID,
|
|
225
|
-
TMViewerContext,
|
|
226
|
-
TMEntity,
|
|
227
|
-
TMSelectedFields
|
|
228
|
-
>,
|
|
229
|
-
TMSelectedFields extends keyof TMFields = keyof TMFields
|
|
230
|
-
>(
|
|
231
|
-
this: IEntityClass<
|
|
232
|
-
TMFields,
|
|
233
|
-
TMID,
|
|
234
|
-
TMViewerContext,
|
|
235
|
-
TMEntity,
|
|
236
|
-
TMPrivacyPolicy,
|
|
237
|
-
TMSelectedFields
|
|
238
|
-
>,
|
|
239
|
-
existingEntity: TMEntity,
|
|
240
|
-
queryContext: EntityQueryContext = existingEntity
|
|
241
|
-
.getViewerContext()
|
|
242
|
-
.getViewerScopedEntityCompanionForClass(this)
|
|
243
|
-
.getQueryContextProvider()
|
|
244
|
-
.getQueryContext()
|
|
245
|
-
): Promise<boolean> {
|
|
246
|
-
const companion = existingEntity
|
|
247
|
-
.getViewerContext()
|
|
248
|
-
.getViewerScopedEntityCompanionForClass(this);
|
|
249
|
-
const privacyPolicy = companion.entityCompanion.privacyPolicy;
|
|
250
|
-
const evaluationResult = await asyncResult(
|
|
251
|
-
privacyPolicy.authorizeUpdateAsync(
|
|
252
|
-
existingEntity.getViewerContext(),
|
|
253
|
-
queryContext,
|
|
254
|
-
{ cascadingDeleteCause: null },
|
|
255
|
-
existingEntity,
|
|
256
|
-
companion.getMetricsAdapter()
|
|
257
|
-
)
|
|
258
|
-
);
|
|
259
|
-
return evaluationResult.ok;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
/**
|
|
263
|
-
* Check whether an entity loaded by a viewer can be deleted by that same viewer.
|
|
264
|
-
*
|
|
265
|
-
* @remarks
|
|
266
|
-
* See remarks for canViewerUpdate.
|
|
267
|
-
*
|
|
268
|
-
* @param existingEntity - entity loaded by viewer
|
|
269
|
-
* @param queryContext - query context in which to perform the check
|
|
270
|
-
*/
|
|
271
|
-
static async canViewerDeleteAsync<
|
|
272
|
-
TMFields extends object,
|
|
273
|
-
TMID extends NonNullable<TMFields[TMSelectedFields]>,
|
|
274
|
-
TMViewerContext extends ViewerContext,
|
|
275
|
-
TMEntity extends Entity<TMFields, TMID, TMViewerContext, TMSelectedFields>,
|
|
276
|
-
TMPrivacyPolicy extends EntityPrivacyPolicy<
|
|
277
|
-
TMFields,
|
|
278
|
-
TMID,
|
|
279
|
-
TMViewerContext,
|
|
280
|
-
TMEntity,
|
|
281
|
-
TMSelectedFields
|
|
282
|
-
>,
|
|
283
|
-
TMSelectedFields extends keyof TMFields = keyof TMFields
|
|
284
|
-
>(
|
|
285
|
-
this: IEntityClass<
|
|
286
|
-
TMFields,
|
|
287
|
-
TMID,
|
|
288
|
-
TMViewerContext,
|
|
289
|
-
TMEntity,
|
|
290
|
-
TMPrivacyPolicy,
|
|
291
|
-
TMSelectedFields
|
|
292
|
-
>,
|
|
293
|
-
existingEntity: TMEntity,
|
|
294
|
-
queryContext: EntityQueryContext = existingEntity
|
|
295
|
-
.getViewerContext()
|
|
296
|
-
.getViewerScopedEntityCompanionForClass(this)
|
|
297
|
-
.getQueryContextProvider()
|
|
298
|
-
.getQueryContext()
|
|
299
|
-
): Promise<boolean> {
|
|
300
|
-
const companion = existingEntity
|
|
301
|
-
.getViewerContext()
|
|
302
|
-
.getViewerScopedEntityCompanionForClass(this);
|
|
303
|
-
const privacyPolicy = companion.entityCompanion.privacyPolicy;
|
|
304
|
-
const evaluationResult = await asyncResult(
|
|
305
|
-
privacyPolicy.authorizeDeleteAsync(
|
|
306
|
-
existingEntity.getViewerContext(),
|
|
307
|
-
queryContext,
|
|
308
|
-
{ cascadingDeleteCause: null },
|
|
309
|
-
existingEntity,
|
|
310
|
-
companion.getMetricsAdapter()
|
|
311
|
-
)
|
|
312
|
-
);
|
|
313
|
-
return evaluationResult.ok;
|
|
314
|
-
}
|
|
315
200
|
}
|
|
316
201
|
|
|
317
202
|
/**
|
|
@@ -329,7 +214,7 @@ export interface IEntityClass<
|
|
|
329
214
|
TEntity,
|
|
330
215
|
TSelectedFields
|
|
331
216
|
>,
|
|
332
|
-
TSelectedFields extends keyof TFields = keyof TFields
|
|
217
|
+
TSelectedFields extends keyof TFields = keyof TFields,
|
|
333
218
|
> {
|
|
334
219
|
new (constructorParam: {
|
|
335
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<
|
|
@@ -59,7 +59,7 @@ export default class EntityAssociationLoader<
|
|
|
59
59
|
.getViewerContext()
|
|
60
60
|
.getViewerScopedEntityCompanionForClass(associatedEntityClass)
|
|
61
61
|
.getQueryContextProvider()
|
|
62
|
-
.getQueryContext()
|
|
62
|
+
.getQueryContext(),
|
|
63
63
|
): Promise<
|
|
64
64
|
Result<null extends TFields[TIdentifyingField] ? TAssociatedEntity | null : TAssociatedEntity>
|
|
65
65
|
> {
|
|
@@ -74,9 +74,11 @@ export default class EntityAssociationLoader<
|
|
|
74
74
|
.getViewerContext()
|
|
75
75
|
.getViewerScopedEntityCompanionForClass(associatedEntityClass)
|
|
76
76
|
.getLoaderFactory()
|
|
77
|
-
.forLoad(queryContext, { cascadingDeleteCause: null });
|
|
77
|
+
.forLoad(queryContext, { previousValue: null, cascadingDeleteCause: null });
|
|
78
78
|
|
|
79
|
-
return (await loader
|
|
79
|
+
return (await loader
|
|
80
|
+
.withAuthorizationResults()
|
|
81
|
+
.loadByIDAsync(associatedEntityID as unknown as TAssociatedID)) as Result<
|
|
80
82
|
null extends TFields[TIdentifyingField] ? TAssociatedEntity | null : TAssociatedEntity
|
|
81
83
|
>;
|
|
82
84
|
}
|
|
@@ -106,7 +108,7 @@ export default class EntityAssociationLoader<
|
|
|
106
108
|
TAssociatedEntity,
|
|
107
109
|
TAssociatedSelectedFields
|
|
108
110
|
>,
|
|
109
|
-
TAssociatedSelectedFields extends keyof TAssociatedFields = keyof TAssociatedFields
|
|
111
|
+
TAssociatedSelectedFields extends keyof TAssociatedFields = keyof TAssociatedFields,
|
|
110
112
|
>(
|
|
111
113
|
associatedEntityClass: IEntityClass<
|
|
112
114
|
TAssociatedFields,
|
|
@@ -121,18 +123,17 @@ export default class EntityAssociationLoader<
|
|
|
121
123
|
.getViewerContext()
|
|
122
124
|
.getViewerScopedEntityCompanionForClass(associatedEntityClass)
|
|
123
125
|
.getQueryContextProvider()
|
|
124
|
-
.getQueryContext()
|
|
126
|
+
.getQueryContext(),
|
|
125
127
|
): Promise<readonly Result<TAssociatedEntity>[]> {
|
|
126
128
|
const thisID = this.entity.getID();
|
|
127
129
|
const loader = this.entity
|
|
128
130
|
.getViewerContext()
|
|
129
131
|
.getViewerScopedEntityCompanionForClass(associatedEntityClass)
|
|
130
132
|
.getLoaderFactory()
|
|
131
|
-
.forLoad(queryContext, { cascadingDeleteCause: null });
|
|
132
|
-
return await loader
|
|
133
|
-
|
|
134
|
-
thisID as any
|
|
135
|
-
);
|
|
133
|
+
.forLoad(queryContext, { previousValue: null, cascadingDeleteCause: null });
|
|
134
|
+
return await loader
|
|
135
|
+
.withAuthorizationResults()
|
|
136
|
+
.loadManyByFieldEqualingAsync(associatedEntityFieldContainingThisID, thisID as any);
|
|
136
137
|
}
|
|
137
138
|
|
|
138
139
|
/**
|
|
@@ -159,7 +160,7 @@ export default class EntityAssociationLoader<
|
|
|
159
160
|
TAssociatedEntity,
|
|
160
161
|
TAssociatedSelectedFields
|
|
161
162
|
>,
|
|
162
|
-
TAssociatedSelectedFields extends keyof TAssociatedFields = keyof TAssociatedFields
|
|
163
|
+
TAssociatedSelectedFields extends keyof TAssociatedFields = keyof TAssociatedFields,
|
|
163
164
|
>(
|
|
164
165
|
fieldIdentifyingAssociatedEntity: keyof Pick<TFields, TSelectedFields>,
|
|
165
166
|
associatedEntityClass: IEntityClass<
|
|
@@ -175,7 +176,7 @@ export default class EntityAssociationLoader<
|
|
|
175
176
|
.getViewerContext()
|
|
176
177
|
.getViewerScopedEntityCompanionForClass(associatedEntityClass)
|
|
177
178
|
.getQueryContextProvider()
|
|
178
|
-
.getQueryContext()
|
|
179
|
+
.getQueryContext(),
|
|
179
180
|
): Promise<Result<TAssociatedEntity> | null> {
|
|
180
181
|
const associatedFieldValue = this.entity.getField(fieldIdentifyingAssociatedEntity);
|
|
181
182
|
if (!associatedFieldValue) {
|
|
@@ -185,11 +186,10 @@ export default class EntityAssociationLoader<
|
|
|
185
186
|
.getViewerContext()
|
|
186
187
|
.getViewerScopedEntityCompanionForClass(associatedEntityClass)
|
|
187
188
|
.getLoaderFactory()
|
|
188
|
-
.forLoad(queryContext, { cascadingDeleteCause: null });
|
|
189
|
-
return await loader
|
|
190
|
-
|
|
191
|
-
associatedFieldValue as any
|
|
192
|
-
);
|
|
189
|
+
.forLoad(queryContext, { previousValue: null, cascadingDeleteCause: null });
|
|
190
|
+
return await loader
|
|
191
|
+
.withAuthorizationResults()
|
|
192
|
+
.loadByFieldEqualingAsync(associatedEntityLookupByField, associatedFieldValue as any);
|
|
193
193
|
}
|
|
194
194
|
|
|
195
195
|
/**
|
|
@@ -216,7 +216,7 @@ export default class EntityAssociationLoader<
|
|
|
216
216
|
TAssociatedEntity,
|
|
217
217
|
TAssociatedSelectedFields
|
|
218
218
|
>,
|
|
219
|
-
TAssociatedSelectedFields extends keyof TAssociatedFields = keyof TAssociatedFields
|
|
219
|
+
TAssociatedSelectedFields extends keyof TAssociatedFields = keyof TAssociatedFields,
|
|
220
220
|
>(
|
|
221
221
|
fieldIdentifyingAssociatedEntity: keyof Pick<TFields, TSelectedFields>,
|
|
222
222
|
associatedEntityClass: IEntityClass<
|
|
@@ -232,7 +232,7 @@ export default class EntityAssociationLoader<
|
|
|
232
232
|
.getViewerContext()
|
|
233
233
|
.getViewerScopedEntityCompanionForClass(associatedEntityClass)
|
|
234
234
|
.getQueryContextProvider()
|
|
235
|
-
.getQueryContext()
|
|
235
|
+
.getQueryContext(),
|
|
236
236
|
): Promise<readonly Result<TAssociatedEntity>[]> {
|
|
237
237
|
const associatedFieldValue = this.entity.getField(fieldIdentifyingAssociatedEntity);
|
|
238
238
|
if (!associatedFieldValue) {
|
|
@@ -243,11 +243,10 @@ export default class EntityAssociationLoader<
|
|
|
243
243
|
.getViewerContext()
|
|
244
244
|
.getViewerScopedEntityCompanionForClass(associatedEntityClass)
|
|
245
245
|
.getLoaderFactory()
|
|
246
|
-
.forLoad(queryContext, { cascadingDeleteCause: null });
|
|
247
|
-
return await loader
|
|
248
|
-
|
|
249
|
-
associatedFieldValue as any
|
|
250
|
-
);
|
|
246
|
+
.forLoad(queryContext, { previousValue: null, cascadingDeleteCause: null });
|
|
247
|
+
return await loader
|
|
248
|
+
.withAuthorizationResults()
|
|
249
|
+
.loadManyByFieldEqualingAsync(associatedEntityLookupByField, associatedFieldValue as any);
|
|
251
250
|
}
|
|
252
251
|
|
|
253
252
|
/**
|
|
@@ -267,7 +266,7 @@ export default class EntityAssociationLoader<
|
|
|
267
266
|
TEntity2,
|
|
268
267
|
TSelectedFields2
|
|
269
268
|
>,
|
|
270
|
-
TSelectedFields2 extends keyof TFields2 = keyof TFields2
|
|
269
|
+
TSelectedFields2 extends keyof TFields2 = keyof TFields2,
|
|
271
270
|
>(
|
|
272
271
|
loadDirectives: [
|
|
273
272
|
EntityLoadThroughDirective<
|
|
@@ -279,9 +278,9 @@ export default class EntityAssociationLoader<
|
|
|
279
278
|
TPrivacyPolicy2,
|
|
280
279
|
TSelectedFields,
|
|
281
280
|
TSelectedFields2
|
|
282
|
-
|
|
281
|
+
>,
|
|
283
282
|
],
|
|
284
|
-
queryContext?: EntityQueryContext
|
|
283
|
+
queryContext?: EntityQueryContext,
|
|
285
284
|
): Promise<Result<TEntity2> | null>;
|
|
286
285
|
|
|
287
286
|
/**
|
|
@@ -312,7 +311,7 @@ export default class EntityAssociationLoader<
|
|
|
312
311
|
TSelectedFields3
|
|
313
312
|
>,
|
|
314
313
|
TSelectedFields2 extends keyof TFields2 = keyof TFields2,
|
|
315
|
-
TSelectedFields3 extends keyof TFields3 = keyof TFields3
|
|
314
|
+
TSelectedFields3 extends keyof TFields3 = keyof TFields3,
|
|
316
315
|
>(
|
|
317
316
|
loadDirectives: [
|
|
318
317
|
EntityLoadThroughDirective<
|
|
@@ -334,9 +333,9 @@ export default class EntityAssociationLoader<
|
|
|
334
333
|
TPrivacyPolicy3,
|
|
335
334
|
TSelectedFields2,
|
|
336
335
|
TSelectedFields3
|
|
337
|
-
|
|
336
|
+
>,
|
|
338
337
|
],
|
|
339
|
-
queryContext?: EntityQueryContext
|
|
338
|
+
queryContext?: EntityQueryContext,
|
|
340
339
|
): Promise<Result<TEntity3> | null>;
|
|
341
340
|
|
|
342
341
|
/**
|
|
@@ -378,9 +377,9 @@ export default class EntityAssociationLoader<
|
|
|
378
377
|
>,
|
|
379
378
|
TSelectedFields2 extends keyof TFields2 = keyof TFields2,
|
|
380
379
|
TSelectedFields3 extends keyof TFields3 = keyof TFields3,
|
|
381
|
-
TSelectedFields4 extends keyof TFields4 = keyof TFields4
|
|
380
|
+
TSelectedFields4 extends keyof TFields4 = keyof TFields4,
|
|
382
381
|
>(
|
|
383
|
-
|
|
382
|
+
loadDirectives: [
|
|
384
383
|
EntityLoadThroughDirective<
|
|
385
384
|
TViewerContext,
|
|
386
385
|
TFields,
|
|
@@ -410,9 +409,9 @@ export default class EntityAssociationLoader<
|
|
|
410
409
|
TPrivacyPolicy4,
|
|
411
410
|
TSelectedFields3,
|
|
412
411
|
TSelectedFields4
|
|
413
|
-
|
|
412
|
+
>,
|
|
414
413
|
],
|
|
415
|
-
queryContext?: EntityQueryContext
|
|
414
|
+
queryContext?: EntityQueryContext,
|
|
416
415
|
): Promise<Result<TEntity4> | null>;
|
|
417
416
|
|
|
418
417
|
/**
|
|
@@ -423,12 +422,12 @@ export default class EntityAssociationLoader<
|
|
|
423
422
|
*/
|
|
424
423
|
async loadAssociatedEntityThroughAsync(
|
|
425
424
|
loadDirectives: EntityLoadThroughDirective<TViewerContext, any, any, any, any, any, any, any>[],
|
|
426
|
-
queryContext?: EntityQueryContext
|
|
425
|
+
queryContext?: EntityQueryContext,
|
|
427
426
|
): Promise<Result<ReadonlyEntity<any, any, any, any>> | null>;
|
|
428
427
|
|
|
429
428
|
async loadAssociatedEntityThroughAsync(
|
|
430
429
|
loadDirectives: EntityLoadThroughDirective<TViewerContext, any, any, any, any, any, any, any>[],
|
|
431
|
-
queryContext?: EntityQueryContext
|
|
430
|
+
queryContext?: EntityQueryContext,
|
|
432
431
|
): Promise<Result<ReadonlyEntity<any, any, any, any>> | null> {
|
|
433
432
|
let currentEntity: ReadonlyEntity<any, any, any, any> = this.entity;
|
|
434
433
|
for (const loadDirective of loadDirectives) {
|
|
@@ -445,7 +444,7 @@ export default class EntityAssociationLoader<
|
|
|
445
444
|
fieldIdentifyingAssociatedEntity,
|
|
446
445
|
associatedEntityClass,
|
|
447
446
|
associatedEntityLookupByField,
|
|
448
|
-
queryContext
|
|
447
|
+
queryContext,
|
|
449
448
|
);
|
|
450
449
|
} else {
|
|
451
450
|
const associatedEntityResultLocal = await currentEntity
|
|
@@ -453,7 +452,7 @@ export default class EntityAssociationLoader<
|
|
|
453
452
|
.loadAssociatedEntityAsync(
|
|
454
453
|
fieldIdentifyingAssociatedEntity,
|
|
455
454
|
associatedEntityClass,
|
|
456
|
-
queryContext
|
|
455
|
+
queryContext,
|
|
457
456
|
);
|
|
458
457
|
|
|
459
458
|
if (associatedEntityResultLocal.ok && associatedEntityResultLocal.value === null) {
|
|
@@ -498,7 +497,7 @@ export interface EntityLoadThroughDirective<
|
|
|
498
497
|
TAssociatedSelectedFields
|
|
499
498
|
>,
|
|
500
499
|
TSelectedFields extends keyof TFields = keyof TFields,
|
|
501
|
-
TAssociatedSelectedFields extends keyof TAssociatedFields = keyof TAssociatedFields
|
|
500
|
+
TAssociatedSelectedFields extends keyof TAssociatedFields = keyof TAssociatedFields,
|
|
502
501
|
> {
|
|
503
502
|
/**
|
|
504
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
|
|