@expo/entity 0.34.0 → 0.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/AuthorizationResultBasedEntityLoader.d.ts +128 -0
- package/build/AuthorizationResultBasedEntityLoader.js +196 -0
- package/build/AuthorizationResultBasedEntityLoader.js.map +1 -0
- package/build/ComposedEntityCacheAdapter.js +1 -0
- package/build/ComposedEntityCacheAdapter.js.map +1 -1
- package/build/ComposedSecondaryEntityCache.js +1 -0
- package/build/ComposedSecondaryEntityCache.js.map +1 -1
- package/build/EnforcingEntityLoader.d.ts +5 -4
- package/build/EnforcingEntityLoader.js +4 -2
- package/build/EnforcingEntityLoader.js.map +1 -1
- package/build/Entity.d.ts +4 -31
- package/build/Entity.js +19 -46
- package/build/Entity.js.map +1 -1
- package/build/EntityAssociationLoader.d.ts +9 -9
- package/build/EntityAssociationLoader.js +37 -12
- package/build/EntityAssociationLoader.js.map +1 -1
- package/build/EntityCompanion.js +9 -1
- package/build/EntityCompanion.js.map +1 -1
- package/build/EntityCompanionProvider.d.ts +3 -1
- package/build/EntityCompanionProvider.js +10 -4
- package/build/EntityCompanionProvider.js.map +1 -1
- package/build/EntityConfiguration.d.ts +2 -1
- package/build/EntityConfiguration.js +19 -1
- package/build/EntityConfiguration.js.map +1 -1
- package/build/EntityDatabaseAdapter.d.ts +2 -2
- package/build/EntityDatabaseAdapter.js +5 -3
- package/build/EntityDatabaseAdapter.js.map +1 -1
- package/build/EntityFieldDefinition.d.ts +21 -10
- package/build/EntityFieldDefinition.js +8 -9
- package/build/EntityFieldDefinition.js.map +1 -1
- package/build/EntityFields.d.ts +10 -0
- package/build/EntityFields.js +15 -1
- package/build/EntityFields.js.map +1 -1
- package/build/EntityLoader.d.ts +12 -125
- package/build/EntityLoader.js +24 -239
- package/build/EntityLoader.js.map +1 -1
- package/build/EntityLoaderFactory.d.ts +1 -1
- package/build/EntityLoaderFactory.js +3 -0
- package/build/EntityLoaderFactory.js.map +1 -1
- package/build/EntityLoaderUtils.d.ts +58 -0
- package/build/EntityLoaderUtils.js +109 -0
- package/build/EntityLoaderUtils.js.map +1 -0
- package/build/EntityMutator.d.ts +1 -0
- package/build/EntityMutator.js +71 -56
- package/build/EntityMutator.js.map +1 -1
- package/build/EntityMutatorFactory.js +9 -0
- package/build/EntityMutatorFactory.js.map +1 -1
- package/build/EntityPrivacyPolicy.d.ts +11 -5
- package/build/EntityPrivacyPolicy.js +5 -7
- package/build/EntityPrivacyPolicy.js.map +1 -1
- package/build/EntityQueryContext.d.ts +2 -1
- package/build/EntityQueryContext.js +11 -6
- package/build/EntityQueryContext.js.map +1 -1
- package/build/EntityQueryContextProvider.d.ts +1 -1
- package/build/EntityQueryContextProvider.js +1 -1
- package/build/EntityQueryContextProvider.js.map +1 -1
- package/build/EntitySecondaryCacheLoader.js +5 -1
- package/build/EntitySecondaryCacheLoader.js.map +1 -1
- package/build/GenericEntityCacheAdapter.js +1 -0
- package/build/GenericEntityCacheAdapter.js.map +1 -1
- package/build/GenericSecondaryEntityCache.js +2 -0
- package/build/GenericSecondaryEntityCache.js.map +1 -1
- package/build/IEntityCacheAdapterProvider.d.ts +1 -1
- package/build/IEntityDatabaseAdapterProvider.d.ts +1 -1
- package/build/ReadonlyEntity.d.ts +1 -1
- package/build/ReadonlyEntity.js +9 -2
- package/build/ReadonlyEntity.js.map +1 -1
- package/build/ViewerContext.d.ts +2 -2
- package/build/ViewerContext.js +5 -3
- package/build/ViewerContext.js.map +1 -1
- package/build/ViewerScopedEntityCompanion.js +2 -0
- package/build/ViewerScopedEntityCompanion.js.map +1 -1
- package/build/ViewerScopedEntityCompanionProvider.d.ts +0 -1
- package/build/ViewerScopedEntityCompanionProvider.js +2 -1
- package/build/ViewerScopedEntityCompanionProvider.js.map +1 -1
- package/build/ViewerScopedEntityLoaderFactory.d.ts +1 -1
- package/build/ViewerScopedEntityLoaderFactory.js +2 -0
- package/build/ViewerScopedEntityLoaderFactory.js.map +1 -1
- package/build/ViewerScopedEntityMutatorFactory.js +2 -0
- package/build/ViewerScopedEntityMutatorFactory.js.map +1 -1
- package/build/__tests__/ComposedCacheAdapter-test.js +2 -0
- package/build/__tests__/ComposedCacheAdapter-test.js.map +1 -1
- package/build/__tests__/ComposedSecondaryEntityCache-test.js +1 -0
- package/build/__tests__/ComposedSecondaryEntityCache-test.js.map +1 -1
- package/build/__tests__/EnforcingEntityLoader-test.js +101 -113
- package/build/__tests__/EnforcingEntityLoader-test.js.map +1 -1
- package/build/__tests__/Entity-test.js +5 -137
- package/build/__tests__/Entity-test.js.map +1 -1
- package/build/__tests__/EntityAssociationLoader-test.js +37 -65
- package/build/__tests__/EntityAssociationLoader-test.js.map +1 -1
- package/build/__tests__/EntityCommonUseCases-test.js +31 -37
- package/build/__tests__/EntityCommonUseCases-test.js.map +1 -1
- package/build/__tests__/EntityCompanion-test.js +26 -3
- package/build/__tests__/EntityCompanion-test.js.map +1 -1
- package/build/__tests__/EntityConfiguration-test.js +103 -0
- package/build/__tests__/EntityConfiguration-test.js.map +1 -0
- package/build/__tests__/EntityDatabaseAdapter-test.js +6 -0
- package/build/__tests__/EntityDatabaseAdapter-test.js.map +1 -1
- package/build/__tests__/EntityEdges-test.js +89 -80
- package/build/__tests__/EntityEdges-test.js.map +1 -1
- package/build/__tests__/EntityFields-test.js +6 -0
- package/build/__tests__/EntityFields-test.js.map +1 -1
- package/build/__tests__/EntityLoader-constructor-test.js +17 -18
- package/build/__tests__/EntityLoader-constructor-test.js.map +1 -1
- package/build/__tests__/EntityLoader-test.js +93 -41
- package/build/__tests__/EntityLoader-test.js.map +1 -1
- package/build/__tests__/EntityMutator-MutationCacheConsistency-test.js +18 -21
- package/build/__tests__/EntityMutator-MutationCacheConsistency-test.js.map +1 -1
- package/build/__tests__/EntityMutator-test.js +74 -29
- package/build/__tests__/EntityMutator-test.js.map +1 -1
- package/build/__tests__/EntityPrivacyPolicy-test.js +77 -59
- package/build/__tests__/EntityPrivacyPolicy-test.js.map +1 -1
- package/build/__tests__/EntityQueryContext-test.js +9 -0
- package/build/__tests__/EntityQueryContext-test.js.map +1 -1
- package/build/__tests__/EntitySecondaryCacheLoader-test.js +10 -10
- package/build/__tests__/EntitySecondaryCacheLoader-test.js.map +1 -1
- package/build/__tests__/EntitySelfReferentialEdges-test.js +59 -74
- package/build/__tests__/EntitySelfReferentialEdges-test.js.map +1 -1
- package/build/__tests__/ReadonlyEntity-test.js +13 -13
- package/build/__tests__/ReadonlyEntity-test.js.map +1 -1
- package/build/__tests__/ViewerContext-test.js +2 -2
- package/build/__tests__/ViewerContext-test.js.map +1 -1
- package/build/__tests__/ViewerScopedEntityLoaderFactory-test.js.map +1 -1
- package/build/__tests__/cases/TwoEntitySameTableDisjointRows-test.js +26 -28
- package/build/__tests__/cases/TwoEntitySameTableDisjointRows-test.js.map +1 -1
- package/build/__tests__/cases/TwoEntitySameTableOverlappingRows-test.js +25 -30
- package/build/__tests__/cases/TwoEntitySameTableOverlappingRows-test.js.map +1 -1
- package/build/entityUtils.d.ts +1 -1
- package/build/entityUtils.js.map +1 -1
- package/build/errors/EntityCacheAdapterError.js +2 -5
- package/build/errors/EntityCacheAdapterError.js.map +1 -1
- package/build/errors/EntityDatabaseAdapterError.js +14 -35
- package/build/errors/EntityDatabaseAdapterError.js.map +1 -1
- package/build/errors/EntityError.js +1 -0
- package/build/errors/EntityError.js.map +1 -1
- package/build/errors/EntityInvalidFieldValueError.js +2 -2
- package/build/errors/EntityInvalidFieldValueError.js.map +1 -1
- package/build/errors/EntityNotAuthorizedError.js +3 -2
- package/build/errors/EntityNotAuthorizedError.js.map +1 -1
- package/build/errors/EntityNotFoundError.js +2 -2
- package/build/errors/EntityNotFoundError.js.map +1 -1
- package/build/index.d.ts +1 -0
- package/build/index.js +1 -0
- package/build/index.js.map +1 -1
- package/build/internal/EntityDataManager.d.ts +1 -1
- package/build/internal/EntityDataManager.js +7 -2
- package/build/internal/EntityDataManager.js.map +1 -1
- package/build/internal/EntityFieldTransformationUtils.d.ts +5 -5
- package/build/internal/EntityFieldTransformationUtils.js +5 -8
- package/build/internal/EntityFieldTransformationUtils.js.map +1 -1
- package/build/internal/EntityTableDataCoordinator.d.ts +1 -1
- package/build/internal/EntityTableDataCoordinator.js +5 -0
- package/build/internal/EntityTableDataCoordinator.js.map +1 -1
- package/build/internal/ReadThroughEntityCache.d.ts +1 -1
- package/build/internal/ReadThroughEntityCache.js +2 -0
- package/build/internal/ReadThroughEntityCache.js.map +1 -1
- package/build/internal/__tests__/EntityDataManager-test.js +11 -11
- package/build/internal/__tests__/EntityDataManager-test.js.map +1 -1
- package/build/internal/__tests__/EntityFieldTransformationUtils-test.js +6 -2
- package/build/internal/__tests__/EntityFieldTransformationUtils-test.js.map +1 -1
- package/build/internal/__tests__/ReadThroughEntityCache-test.js +33 -0
- package/build/internal/__tests__/ReadThroughEntityCache-test.js.map +1 -1
- package/build/metrics/IEntityMetricsAdapter.d.ts +1 -1
- package/build/rules/AlwaysAllowPrivacyPolicyRule.d.ts +1 -1
- package/build/rules/AlwaysAllowPrivacyPolicyRule.js.map +1 -1
- package/build/rules/AlwaysDenyPrivacyPolicyRule.d.ts +1 -1
- package/build/rules/AlwaysDenyPrivacyPolicyRule.js.map +1 -1
- package/build/rules/AlwaysSkipPrivacyPolicyRule.d.ts +1 -1
- package/build/rules/AlwaysSkipPrivacyPolicyRule.js.map +1 -1
- package/build/rules/PrivacyPolicyRule.d.ts +1 -1
- package/build/rules/PrivacyPolicyRule.js.map +1 -1
- package/build/rules/__tests__/AlwaysAllowPrivacyPolicyRule-test.js.map +1 -1
- package/build/rules/__tests__/AlwaysDenyPrivacyPolicyRule-test.js.map +1 -1
- package/build/rules/__tests__/AlwaysSkipPrivacyPolicyRule-test.js.map +1 -1
- package/build/testfixtures/DateIDTestEntity.js +12 -15
- package/build/testfixtures/DateIDTestEntity.js.map +1 -1
- package/build/testfixtures/SimpleTestEntity.d.ts +8 -8
- package/build/testfixtures/SimpleTestEntity.js +12 -15
- package/build/testfixtures/SimpleTestEntity.js.map +1 -1
- package/build/testfixtures/TestEntity.d.ts +12 -12
- package/build/testfixtures/TestEntity.js +12 -15
- package/build/testfixtures/TestEntity.js.map +1 -1
- package/build/testfixtures/TestEntity2.d.ts +8 -8
- package/build/testfixtures/TestEntity2.js +12 -15
- package/build/testfixtures/TestEntity2.js.map +1 -1
- package/build/testfixtures/TestEntityNumberKey.js +12 -15
- package/build/testfixtures/TestEntityNumberKey.js.map +1 -1
- package/build/testfixtures/TestEntityWithMutationTriggers.d.ts +36 -0
- package/build/testfixtures/TestEntityWithMutationTriggers.js +82 -0
- package/build/testfixtures/TestEntityWithMutationTriggers.js.map +1 -0
- package/build/testfixtures/TestViewerContext.d.ts +0 -3
- package/build/testfixtures/TestViewerContext.js +0 -6
- package/build/testfixtures/TestViewerContext.js.map +1 -1
- package/build/utils/EntityPrivacyUtils.d.ts +34 -0
- package/build/utils/EntityPrivacyUtils.js +160 -0
- package/build/utils/EntityPrivacyUtils.js.map +1 -0
- package/build/utils/__tests__/EntityPrivacyUtils-test.d.ts +1 -0
- package/build/utils/__tests__/EntityPrivacyUtils-test.js +395 -0
- package/build/utils/__tests__/EntityPrivacyUtils-test.js.map +1 -0
- package/build/utils/__tests__/mergeEntityMutationTriggerConfigurations-test.d.ts +1 -0
- package/build/utils/__tests__/mergeEntityMutationTriggerConfigurations-test.js +26 -0
- package/build/utils/__tests__/mergeEntityMutationTriggerConfigurations-test.js.map +1 -0
- package/build/utils/collections/maps.js.map +1 -1
- package/build/utils/mergeEntityMutationTriggerConfigurations.d.ts +4 -0
- package/build/utils/mergeEntityMutationTriggerConfigurations.js +28 -0
- package/build/utils/mergeEntityMutationTriggerConfigurations.js.map +1 -0
- package/build/utils/testing/PrivacyPolicyRuleTestUtils.d.ts +1 -1
- package/build/utils/testing/PrivacyPolicyRuleTestUtils.js.map +1 -1
- package/build/utils/testing/StubCacheAdapter.d.ts +3 -3
- package/build/utils/testing/StubCacheAdapter.js +3 -3
- package/build/utils/testing/StubCacheAdapter.js.map +1 -1
- package/build/utils/testing/StubDatabaseAdapter.d.ts +2 -2
- package/build/utils/testing/StubDatabaseAdapter.js +4 -2
- package/build/utils/testing/StubDatabaseAdapter.js.map +1 -1
- package/build/utils/testing/StubDatabaseAdapterProvider.d.ts +1 -1
- package/build/utils/testing/StubDatabaseAdapterProvider.js +1 -3
- package/build/utils/testing/StubDatabaseAdapterProvider.js.map +1 -1
- package/build/utils/testing/__tests__/PrivacyPolicyRuleTestUtils-test.d.ts +1 -0
- package/build/utils/testing/__tests__/PrivacyPolicyRuleTestUtils-test.js +42 -0
- package/build/utils/testing/__tests__/PrivacyPolicyRuleTestUtils-test.js.map +1 -0
- package/build/utils/testing/__tests__/StubDatabaseAdapter-test.js +53 -0
- package/build/utils/testing/__tests__/StubDatabaseAdapter-test.js.map +1 -1
- package/build/utils/testing/describeFieldTestCase.js.map +1 -1
- package/package.json +4 -3
- package/src/AuthorizationResultBasedEntityLoader.ts +297 -0
- package/src/ComposedEntityCacheAdapter.ts +6 -6
- package/src/ComposedSecondaryEntityCache.ts +8 -8
- package/src/EnforcingEntityLoader.ts +20 -19
- package/src/Entity.ts +26 -118
- package/src/EntityAssociationLoader.ts +56 -41
- package/src/EntityCompanion.ts +8 -4
- package/src/EntityCompanionProvider.ts +24 -16
- package/src/EntityConfiguration.ts +18 -7
- package/src/EntityDatabaseAdapter.ts +41 -41
- package/src/EntityFieldDefinition.ts +28 -18
- package/src/EntityFields.ts +15 -0
- package/src/EntityLoader.ts +63 -357
- package/src/EntityLoaderFactory.ts +10 -4
- package/src/EntityLoaderUtils.ts +149 -0
- package/src/EntityMutationInfo.ts +2 -2
- package/src/EntityMutationTriggerConfiguration.ts +5 -5
- package/src/EntityMutationValidator.ts +2 -2
- package/src/EntityMutator.ts +146 -144
- package/src/EntityMutatorFactory.ts +8 -8
- package/src/EntityPrivacyPolicy.ts +78 -28
- package/src/EntityQueryContext.ts +14 -13
- package/src/EntityQueryContextProvider.ts +6 -6
- package/src/EntitySecondaryCacheLoader.ts +13 -11
- package/src/GenericEntityCacheAdapter.ts +10 -10
- package/src/GenericSecondaryEntityCache.ts +6 -6
- package/src/IEntityCacheAdapter.ts +4 -4
- package/src/IEntityCacheAdapterProvider.ts +2 -2
- package/src/IEntityDatabaseAdapterProvider.ts +2 -2
- package/src/ReadonlyEntity.ts +8 -5
- package/src/ViewerContext.ts +10 -10
- package/src/ViewerScopedEntityCompanion.ts +4 -4
- package/src/ViewerScopedEntityCompanionProvider.ts +4 -5
- package/src/ViewerScopedEntityLoaderFactory.ts +10 -4
- package/src/ViewerScopedEntityMutatorFactory.ts +5 -5
- package/src/__tests__/ComposedCacheAdapter-test.ts +12 -10
- package/src/__tests__/ComposedSecondaryEntityCache-test.ts +8 -8
- package/src/__tests__/EnforcingEntityLoader-test.ts +236 -159
- package/src/__tests__/Entity-test.ts +5 -223
- package/src/__tests__/EntityAssociationLoader-test.ts +91 -169
- package/src/__tests__/EntityCommonUseCases-test.ts +36 -38
- package/src/__tests__/EntityCompanion-test.ts +57 -5
- package/src/__tests__/EntityConfiguration-test.ts +118 -0
- package/src/__tests__/EntityDatabaseAdapter-test.ts +11 -11
- package/src/__tests__/EntityEdges-test.ts +128 -118
- package/src/__tests__/EntityFields-test.ts +14 -2
- package/src/__tests__/EntityLoader-constructor-test.ts +21 -8
- package/src/__tests__/EntityLoader-test.ts +233 -105
- package/src/__tests__/EntityMutator-MutationCacheConsistency-test.ts +17 -20
- package/src/__tests__/EntityMutator-test.ts +342 -163
- package/src/__tests__/EntityPrivacyPolicy-test.ts +166 -53
- package/src/__tests__/EntityQueryContext-test.ts +30 -12
- package/src/__tests__/EntitySecondaryCacheLoader-test.ts +17 -26
- package/src/__tests__/EntitySelfReferentialEdges-test.ts +67 -115
- package/src/__tests__/GenericEntityCacheAdapter-test.ts +2 -2
- package/src/__tests__/ReadonlyEntity-test.ts +13 -15
- package/src/__tests__/ViewerContext-test.ts +3 -4
- package/src/__tests__/ViewerScopedEntityCompanion-test.ts +2 -2
- package/src/__tests__/ViewerScopedEntityCompanionProvider-test.ts +2 -2
- package/src/__tests__/ViewerScopedEntityLoaderFactory-test.ts +2 -1
- package/src/__tests__/cases/TwoEntitySameTableDisjointRows-test.ts +34 -45
- package/src/__tests__/cases/TwoEntitySameTableOverlappingRows-test.ts +22 -30
- package/src/__tests__/entityUtils-test.ts +2 -2
- package/src/entityUtils.ts +4 -4
- package/src/errors/EntityError.ts +4 -1
- package/src/errors/EntityInvalidFieldValueError.ts +2 -2
- package/src/errors/EntityNotAuthorizedError.ts +3 -3
- package/src/errors/EntityNotFoundError.ts +2 -2
- package/src/index.ts +1 -0
- package/src/internal/EntityDataManager.ts +25 -25
- package/src/internal/EntityFieldTransformationUtils.ts +39 -32
- package/src/internal/EntityTableDataCoordinator.ts +3 -3
- package/src/internal/ReadThroughEntityCache.ts +9 -9
- package/src/internal/__tests__/EntityDataManager-test.ts +62 -62
- package/src/internal/__tests__/EntityFieldTransformationUtils-test.ts +14 -10
- package/src/internal/__tests__/ReadThroughEntityCache-test.ts +74 -18
- package/src/metrics/EntityMetricsUtils.ts +4 -4
- package/src/metrics/IEntityMetricsAdapter.ts +1 -1
- package/src/rules/AlwaysAllowPrivacyPolicyRule.ts +9 -3
- package/src/rules/AlwaysDenyPrivacyPolicyRule.ts +9 -3
- package/src/rules/AlwaysSkipPrivacyPolicyRule.ts +9 -3
- package/src/rules/PrivacyPolicyRule.ts +9 -3
- package/src/rules/__tests__/AlwaysAllowPrivacyPolicyRule-test.ts +2 -1
- package/src/rules/__tests__/AlwaysDenyPrivacyPolicyRule-test.ts +2 -1
- package/src/rules/__tests__/AlwaysSkipPrivacyPolicyRule-test.ts +2 -1
- package/src/testfixtures/SimpleTestEntity.ts +8 -8
- package/src/testfixtures/TestEntity.ts +13 -16
- package/src/testfixtures/TestEntity2.ts +8 -8
- package/src/testfixtures/TestEntityWithMutationTriggers.ts +156 -0
- package/src/testfixtures/TestViewerContext.ts +1 -12
- package/src/utils/EntityPrivacyUtils.ts +325 -0
- package/src/utils/__tests__/EntityPrivacyUtils-test.ts +570 -0
- package/src/utils/__tests__/mergeEntityMutationTriggerConfigurations-test.ts +29 -0
- package/src/utils/collections/__tests__/maps-test.ts +2 -2
- package/src/utils/collections/maps.ts +11 -11
- package/src/utils/mergeEntityMutationTriggerConfigurations.ts +44 -0
- package/src/utils/testing/PrivacyPolicyRuleTestUtils.ts +25 -22
- package/src/utils/testing/StubCacheAdapter.ts +17 -15
- package/src/utils/testing/StubDatabaseAdapter.ts +35 -30
- package/src/utils/testing/StubDatabaseAdapterProvider.ts +2 -2
- package/src/utils/testing/StubQueryContextProvider.ts +2 -2
- package/src/utils/testing/__tests__/PrivacyPolicyRuleTestUtils-test.ts +42 -0
- package/src/utils/testing/__tests__/StubDatabaseAdapter-test.ts +111 -29
- package/src/utils/testing/createUnitTestEntityCompanionProvider.ts +2 -2
- package/src/utils/testing/describeFieldTestCase.ts +1 -1
- package/build/__tests__/EntityDataConfiguration-test.js +0 -68
- package/build/__tests__/EntityDataConfiguration-test.js.map +0 -1
- package/src/__tests__/EntityDataConfiguration-test.ts +0 -77
- /package/build/__tests__/{EntityDataConfiguration-test.d.ts → EntityConfiguration-test.d.ts} +0 -0
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
import Entity from '../../Entity';
|
|
2
2
|
import { EntityCompanionDefinition } from '../../EntityCompanionProvider';
|
|
3
3
|
import EntityConfiguration from '../../EntityConfiguration';
|
|
4
|
-
import { UUIDField,
|
|
4
|
+
import { UUIDField, StringField, StrictEnumField } from '../../EntityFields';
|
|
5
5
|
import EntityPrivacyPolicy from '../../EntityPrivacyPolicy';
|
|
6
|
+
import ViewerContext from '../../ViewerContext';
|
|
6
7
|
import { successfulResults, failedResults } from '../../entityUtils';
|
|
7
8
|
import AlwaysAllowPrivacyPolicyRule from '../../rules/AlwaysAllowPrivacyPolicyRule';
|
|
8
|
-
import TestViewerContext from '../../testfixtures/TestViewerContext';
|
|
9
9
|
import { createUnitTestEntityCompanionProvider } from '../../utils/testing/createUnitTestEntityCompanionProvider';
|
|
10
10
|
|
|
11
11
|
describe('Two entities backed by the same table', () => {
|
|
12
12
|
test('load by different types', async () => {
|
|
13
13
|
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
14
|
-
const viewerContext = new
|
|
14
|
+
const viewerContext = new ViewerContext(companionProvider);
|
|
15
15
|
|
|
16
|
-
const one = await OneTestEntity.creator(viewerContext
|
|
16
|
+
const one = await OneTestEntity.creator(viewerContext)
|
|
17
17
|
.setField('entity_type', EntityType.ONE)
|
|
18
18
|
.setField('common_other_field', 'wat')
|
|
19
19
|
.enforceCreateAsync();
|
|
20
20
|
|
|
21
|
-
const two = await TwoTestEntity.creator(viewerContext
|
|
21
|
+
const two = await TwoTestEntity.creator(viewerContext)
|
|
22
22
|
.setField('entity_type', EntityType.TWO)
|
|
23
23
|
.setField('other_field', 'blah')
|
|
24
24
|
.setField('common_other_field', 'wat')
|
|
@@ -28,21 +28,16 @@ describe('Two entities backed by the same table', () => {
|
|
|
28
28
|
expect(two).toBeInstanceOf(TwoTestEntity);
|
|
29
29
|
|
|
30
30
|
await expect(
|
|
31
|
-
TwoTestEntity.loader(viewerContext
|
|
32
|
-
.enforcing()
|
|
33
|
-
.loadByIDAsync(one.getID())
|
|
31
|
+
TwoTestEntity.loader(viewerContext).enforcing().loadByIDAsync(one.getID()),
|
|
34
32
|
).rejects.toThrowError('TwoTestEntity must be instantiated with two data');
|
|
35
33
|
|
|
36
34
|
await expect(
|
|
37
|
-
OneTestEntity.loader(viewerContext
|
|
38
|
-
.enforcing()
|
|
39
|
-
.loadByIDAsync(two.getID())
|
|
35
|
+
OneTestEntity.loader(viewerContext).enforcing().loadByIDAsync(two.getID()),
|
|
40
36
|
).rejects.toThrowError('OneTestEntity must be instantiated with one data');
|
|
41
37
|
|
|
42
|
-
const manyResults = await OneTestEntity.loader(
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
).loadManyByFieldEqualingAsync('common_other_field', 'wat');
|
|
38
|
+
const manyResults = await OneTestEntity.loader(viewerContext)
|
|
39
|
+
.withAuthorizationResults()
|
|
40
|
+
.loadManyByFieldEqualingAsync('common_other_field', 'wat');
|
|
46
41
|
const successfulManyResults = successfulResults(manyResults);
|
|
47
42
|
const failedManyResults = failedResults(manyResults);
|
|
48
43
|
|
|
@@ -51,23 +46,22 @@ describe('Two entities backed by the same table', () => {
|
|
|
51
46
|
|
|
52
47
|
expect(successfulManyResults[0]!.enforceValue().getID()).toEqual(one.getID());
|
|
53
48
|
expect(failedManyResults[0]!.enforceError().message).toEqual(
|
|
54
|
-
'OneTestEntity must be instantiated with one data'
|
|
49
|
+
'OneTestEntity must be instantiated with one data',
|
|
55
50
|
);
|
|
56
51
|
|
|
57
|
-
const fieldEqualityConjunctionResults = await OneTestEntity.loader(
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
]);
|
|
52
|
+
const fieldEqualityConjunctionResults = await OneTestEntity.loader(viewerContext)
|
|
53
|
+
.withAuthorizationResults()
|
|
54
|
+
.loadManyByFieldEqualityConjunctionAsync([
|
|
55
|
+
{
|
|
56
|
+
fieldName: 'common_other_field',
|
|
57
|
+
fieldValue: 'wat',
|
|
58
|
+
},
|
|
59
|
+
]);
|
|
66
60
|
const successfulfieldEqualityConjunctionResultsResults = successfulResults(
|
|
67
|
-
fieldEqualityConjunctionResults
|
|
61
|
+
fieldEqualityConjunctionResults,
|
|
68
62
|
);
|
|
69
63
|
const failedfieldEqualityConjunctionResultsResults = failedResults(
|
|
70
|
-
fieldEqualityConjunctionResults
|
|
64
|
+
fieldEqualityConjunctionResults,
|
|
71
65
|
);
|
|
72
66
|
expect(successfulfieldEqualityConjunctionResultsResults).toHaveLength(1);
|
|
73
67
|
expect(failedfieldEqualityConjunctionResultsResults).toHaveLength(1);
|
|
@@ -103,38 +97,33 @@ const testEntityConfiguration = new EntityConfiguration<TestFields>({
|
|
|
103
97
|
common_other_field: new StringField({
|
|
104
98
|
columnName: 'common_other_field',
|
|
105
99
|
}),
|
|
106
|
-
entity_type: new
|
|
100
|
+
entity_type: new StrictEnumField({
|
|
107
101
|
columnName: 'entity_type',
|
|
102
|
+
enum: EntityType,
|
|
108
103
|
}),
|
|
109
104
|
},
|
|
110
105
|
databaseAdapterFlavor: 'postgres',
|
|
111
106
|
cacheAdapterFlavor: 'redis',
|
|
112
107
|
});
|
|
113
108
|
|
|
114
|
-
class TestEntityPrivacyPolicy extends EntityPrivacyPolicy<
|
|
115
|
-
any,
|
|
116
|
-
string,
|
|
117
|
-
TestViewerContext,
|
|
118
|
-
any,
|
|
119
|
-
any
|
|
120
|
-
> {
|
|
109
|
+
class TestEntityPrivacyPolicy extends EntityPrivacyPolicy<any, string, ViewerContext, any, any> {
|
|
121
110
|
protected override readonly readRules = [
|
|
122
|
-
new AlwaysAllowPrivacyPolicyRule<any, string,
|
|
111
|
+
new AlwaysAllowPrivacyPolicyRule<any, string, ViewerContext, any, any>(),
|
|
123
112
|
];
|
|
124
113
|
protected override readonly createRules = [
|
|
125
|
-
new AlwaysAllowPrivacyPolicyRule<any, string,
|
|
114
|
+
new AlwaysAllowPrivacyPolicyRule<any, string, ViewerContext, any, any>(),
|
|
126
115
|
];
|
|
127
116
|
protected override readonly updateRules = [
|
|
128
|
-
new AlwaysAllowPrivacyPolicyRule<any, string,
|
|
117
|
+
new AlwaysAllowPrivacyPolicyRule<any, string, ViewerContext, any, any>(),
|
|
129
118
|
];
|
|
130
119
|
protected override readonly deleteRules = [
|
|
131
|
-
new AlwaysAllowPrivacyPolicyRule<any, string,
|
|
120
|
+
new AlwaysAllowPrivacyPolicyRule<any, string, ViewerContext, any, any>(),
|
|
132
121
|
];
|
|
133
122
|
}
|
|
134
123
|
|
|
135
|
-
class OneTestEntity extends Entity<TestFields, string,
|
|
124
|
+
class OneTestEntity extends Entity<TestFields, string, ViewerContext, OneTestFields> {
|
|
136
125
|
constructor(constructorParams: {
|
|
137
|
-
viewerContext:
|
|
126
|
+
viewerContext: ViewerContext;
|
|
138
127
|
id: string;
|
|
139
128
|
databaseFields: Readonly<TestFields>;
|
|
140
129
|
selectedFields: Readonly<Pick<TestFields, OneTestFields>>;
|
|
@@ -148,7 +137,7 @@ class OneTestEntity extends Entity<TestFields, string, TestViewerContext, OneTes
|
|
|
148
137
|
static defineCompanionDefinition(): EntityCompanionDefinition<
|
|
149
138
|
TestFields,
|
|
150
139
|
string,
|
|
151
|
-
|
|
140
|
+
ViewerContext,
|
|
152
141
|
OneTestEntity,
|
|
153
142
|
TestEntityPrivacyPolicy,
|
|
154
143
|
OneTestFields
|
|
@@ -162,9 +151,9 @@ class OneTestEntity extends Entity<TestFields, string, TestViewerContext, OneTes
|
|
|
162
151
|
}
|
|
163
152
|
}
|
|
164
153
|
|
|
165
|
-
class TwoTestEntity extends Entity<TestFields, string,
|
|
154
|
+
class TwoTestEntity extends Entity<TestFields, string, ViewerContext, TwoTestFields> {
|
|
166
155
|
constructor(constructorParams: {
|
|
167
|
-
viewerContext:
|
|
156
|
+
viewerContext: ViewerContext;
|
|
168
157
|
id: string;
|
|
169
158
|
databaseFields: Readonly<TestFields>;
|
|
170
159
|
selectedFields: Readonly<Pick<TestFields, TwoTestFields>>;
|
|
@@ -178,7 +167,7 @@ class TwoTestEntity extends Entity<TestFields, string, TestViewerContext, TwoTes
|
|
|
178
167
|
static defineCompanionDefinition(): EntityCompanionDefinition<
|
|
179
168
|
TestFields,
|
|
180
169
|
string,
|
|
181
|
-
|
|
170
|
+
ViewerContext,
|
|
182
171
|
TwoTestEntity,
|
|
183
172
|
TestEntityPrivacyPolicy,
|
|
184
173
|
TwoTestFields
|
|
@@ -3,26 +3,26 @@ import { EntityCompanionDefinition } from '../../EntityCompanionProvider';
|
|
|
3
3
|
import EntityConfiguration from '../../EntityConfiguration';
|
|
4
4
|
import { UUIDField, StringField } from '../../EntityFields';
|
|
5
5
|
import EntityPrivacyPolicy from '../../EntityPrivacyPolicy';
|
|
6
|
+
import ViewerContext from '../../ViewerContext';
|
|
6
7
|
import AlwaysAllowPrivacyPolicyRule from '../../rules/AlwaysAllowPrivacyPolicyRule';
|
|
7
|
-
import TestViewerContext from '../../testfixtures/TestViewerContext';
|
|
8
8
|
import { createUnitTestEntityCompanionProvider } from '../../utils/testing/createUnitTestEntityCompanionProvider';
|
|
9
9
|
|
|
10
10
|
describe('Two entities backed by the same table', () => {
|
|
11
11
|
test('mutate through different types and keep consistent cache and dataloader', async () => {
|
|
12
12
|
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
13
|
-
const viewerContext = new
|
|
13
|
+
const viewerContext = new ViewerContext(companionProvider);
|
|
14
14
|
|
|
15
|
-
const entity1 = await OneTestEntity.creator(viewerContext
|
|
15
|
+
const entity1 = await OneTestEntity.creator(viewerContext)
|
|
16
16
|
.setField('fake_field', 'hello')
|
|
17
17
|
.enforceCreateAsync();
|
|
18
18
|
expect(entity1).toBeInstanceOf(OneTestEntity);
|
|
19
19
|
|
|
20
|
-
const entity2 = await TwoTestEntity.loader(viewerContext
|
|
20
|
+
const entity2 = await TwoTestEntity.loader(viewerContext)
|
|
21
21
|
.enforcing()
|
|
22
22
|
.loadByIDAsync(entity1.getID());
|
|
23
23
|
expect(entity2).toBeInstanceOf(TwoTestEntity);
|
|
24
24
|
|
|
25
|
-
const updated2 = await TwoTestEntity.updater(entity2
|
|
25
|
+
const updated2 = await TwoTestEntity.updater(entity2)
|
|
26
26
|
.setField('fake_field', 'world')
|
|
27
27
|
.setField('other_field', 'wat')
|
|
28
28
|
.enforceUpdateAsync();
|
|
@@ -32,7 +32,7 @@ describe('Two entities backed by the same table', () => {
|
|
|
32
32
|
fake_field: 'world',
|
|
33
33
|
});
|
|
34
34
|
|
|
35
|
-
const loaded1 = await OneTestEntity.loader(viewerContext
|
|
35
|
+
const loaded1 = await OneTestEntity.loader(viewerContext)
|
|
36
36
|
.enforcing()
|
|
37
37
|
.loadByIDAsync(entity1.getID());
|
|
38
38
|
expect(loaded1.getAllFields()).toMatchObject({
|
|
@@ -43,14 +43,14 @@ describe('Two entities backed by the same table', () => {
|
|
|
43
43
|
|
|
44
44
|
test('cached field that differs between the two to test invalidation', async () => {
|
|
45
45
|
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
46
|
-
const viewerContext = new
|
|
46
|
+
const viewerContext = new ViewerContext(companionProvider);
|
|
47
47
|
|
|
48
|
-
const entity = await TwoTestEntity.creator(viewerContext
|
|
48
|
+
const entity = await TwoTestEntity.creator(viewerContext)
|
|
49
49
|
.setField('fake_field', 'hello')
|
|
50
50
|
.setField('other_field', 'huh')
|
|
51
51
|
.enforceCreateAsync();
|
|
52
52
|
|
|
53
|
-
const loadedEntity = await TwoTestEntity.loader(viewerContext
|
|
53
|
+
const loadedEntity = await TwoTestEntity.loader(viewerContext)
|
|
54
54
|
.enforcing()
|
|
55
55
|
.loadByFieldEqualingAsync('other_field', 'huh');
|
|
56
56
|
expect(loadedEntity?.getAllFields()).toMatchObject({
|
|
@@ -59,14 +59,12 @@ describe('Two entities backed by the same table', () => {
|
|
|
59
59
|
other_field: 'huh',
|
|
60
60
|
});
|
|
61
61
|
|
|
62
|
-
const loaded1 = await OneTestEntity.loader(viewerContext
|
|
62
|
+
const loaded1 = await OneTestEntity.loader(viewerContext)
|
|
63
63
|
.enforcing()
|
|
64
64
|
.loadByIDAsync(entity.getID());
|
|
65
|
-
await OneTestEntity.updater(loaded1,
|
|
66
|
-
.setField('fake_field', 'world')
|
|
67
|
-
.enforceUpdateAsync();
|
|
65
|
+
await OneTestEntity.updater(loaded1).setField('fake_field', 'world').enforceUpdateAsync();
|
|
68
66
|
|
|
69
|
-
const loaded2 = await TwoTestEntity.loader(viewerContext
|
|
67
|
+
const loaded2 = await TwoTestEntity.loader(viewerContext)
|
|
70
68
|
.enforcing()
|
|
71
69
|
.loadByFieldEqualingAsync('other_field', 'huh');
|
|
72
70
|
expect(loaded2?.getAllFields()).toMatchObject({
|
|
@@ -75,7 +73,7 @@ describe('Two entities backed by the same table', () => {
|
|
|
75
73
|
other_field: 'huh',
|
|
76
74
|
});
|
|
77
75
|
|
|
78
|
-
const loaded22 = await TwoTestEntity.loader(viewerContext
|
|
76
|
+
const loaded22 = await TwoTestEntity.loader(viewerContext)
|
|
79
77
|
.enforcing()
|
|
80
78
|
.loadByFieldEqualingAsync('fake_field', 'world');
|
|
81
79
|
expect(loaded22?.getAllFields()).toMatchObject({
|
|
@@ -116,32 +114,26 @@ const testEntityConfiguration = new EntityConfiguration<TestFields>({
|
|
|
116
114
|
cacheAdapterFlavor: 'redis',
|
|
117
115
|
});
|
|
118
116
|
|
|
119
|
-
class TestEntityPrivacyPolicy extends EntityPrivacyPolicy<
|
|
120
|
-
any,
|
|
121
|
-
string,
|
|
122
|
-
TestViewerContext,
|
|
123
|
-
any,
|
|
124
|
-
any
|
|
125
|
-
> {
|
|
117
|
+
class TestEntityPrivacyPolicy extends EntityPrivacyPolicy<any, string, ViewerContext, any, any> {
|
|
126
118
|
protected override readonly readRules = [
|
|
127
|
-
new AlwaysAllowPrivacyPolicyRule<any, string,
|
|
119
|
+
new AlwaysAllowPrivacyPolicyRule<any, string, ViewerContext, any, any>(),
|
|
128
120
|
];
|
|
129
121
|
protected override readonly createRules = [
|
|
130
|
-
new AlwaysAllowPrivacyPolicyRule<any, string,
|
|
122
|
+
new AlwaysAllowPrivacyPolicyRule<any, string, ViewerContext, any, any>(),
|
|
131
123
|
];
|
|
132
124
|
protected override readonly updateRules = [
|
|
133
|
-
new AlwaysAllowPrivacyPolicyRule<any, string,
|
|
125
|
+
new AlwaysAllowPrivacyPolicyRule<any, string, ViewerContext, any, any>(),
|
|
134
126
|
];
|
|
135
127
|
protected override readonly deleteRules = [
|
|
136
|
-
new AlwaysAllowPrivacyPolicyRule<any, string,
|
|
128
|
+
new AlwaysAllowPrivacyPolicyRule<any, string, ViewerContext, any, any>(),
|
|
137
129
|
];
|
|
138
130
|
}
|
|
139
131
|
|
|
140
|
-
class OneTestEntity extends Entity<TestFields, string,
|
|
132
|
+
class OneTestEntity extends Entity<TestFields, string, ViewerContext, OneTestFields> {
|
|
141
133
|
static defineCompanionDefinition(): EntityCompanionDefinition<
|
|
142
134
|
TestFields,
|
|
143
135
|
string,
|
|
144
|
-
|
|
136
|
+
ViewerContext,
|
|
145
137
|
OneTestEntity,
|
|
146
138
|
TestEntityPrivacyPolicy,
|
|
147
139
|
OneTestFields
|
|
@@ -155,11 +147,11 @@ class OneTestEntity extends Entity<TestFields, string, TestViewerContext, OneTes
|
|
|
155
147
|
}
|
|
156
148
|
}
|
|
157
149
|
|
|
158
|
-
class TwoTestEntity extends Entity<TestFields, string,
|
|
150
|
+
class TwoTestEntity extends Entity<TestFields, string, ViewerContext, TwoTestFields> {
|
|
159
151
|
static defineCompanionDefinition(): EntityCompanionDefinition<
|
|
160
152
|
TestFields,
|
|
161
153
|
string,
|
|
162
|
-
|
|
154
|
+
ViewerContext,
|
|
163
155
|
TwoTestEntity,
|
|
164
156
|
TestEntityPrivacyPolicy,
|
|
165
157
|
TwoTestFields
|
|
@@ -52,7 +52,7 @@ describe(successfulResultsFilterMap, () => {
|
|
|
52
52
|
a: result1,
|
|
53
53
|
b: result2,
|
|
54
54
|
c: result3,
|
|
55
|
-
})
|
|
55
|
+
}),
|
|
56
56
|
);
|
|
57
57
|
|
|
58
58
|
const resultingMap = successfulResultsFilterMap(allResults);
|
|
@@ -73,7 +73,7 @@ describe(failedResultsFilterMap, () => {
|
|
|
73
73
|
a: result1,
|
|
74
74
|
b: result2,
|
|
75
75
|
c: result3,
|
|
76
|
-
})
|
|
76
|
+
}),
|
|
77
77
|
);
|
|
78
78
|
|
|
79
79
|
const resultingMap = failedResultsFilterMap(allResults);
|
package/src/entityUtils.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { Result, Success, Failure } from '@expo/results';
|
|
|
5
5
|
* @param resultsPromise - promise returning an array of results to enforce
|
|
6
6
|
*/
|
|
7
7
|
export const enforceResultsAsync = async <T>(
|
|
8
|
-
resultsPromise: Promise<readonly Result<T>[]
|
|
8
|
+
resultsPromise: Promise<readonly Result<T>[]>,
|
|
9
9
|
): Promise<readonly T[]> => {
|
|
10
10
|
const results = await resultsPromise;
|
|
11
11
|
return results.map((result) => result.enforceValue());
|
|
@@ -44,7 +44,7 @@ export const failedResults = <T>(results: readonly Result<T>[]): readonly Failur
|
|
|
44
44
|
* @param results - map of results to filter.
|
|
45
45
|
*/
|
|
46
46
|
export const successfulResultsFilterMap = <K, T>(
|
|
47
|
-
results: ReadonlyMap<K, Result<T
|
|
47
|
+
results: ReadonlyMap<K, Result<T>>,
|
|
48
48
|
): ReadonlyMap<K, Success<T>> => {
|
|
49
49
|
const ret: Map<K, Success<T>> = new Map();
|
|
50
50
|
for (const [k, result] of results) {
|
|
@@ -60,7 +60,7 @@ export const successfulResultsFilterMap = <K, T>(
|
|
|
60
60
|
* @param results - map of results to filter.
|
|
61
61
|
*/
|
|
62
62
|
export const failedResultsFilterMap = <K, T>(
|
|
63
|
-
results: ReadonlyMap<K, Result<T
|
|
63
|
+
results: ReadonlyMap<K, Result<T>>,
|
|
64
64
|
): ReadonlyMap<K, Failure<T>> => {
|
|
65
65
|
const ret: Map<K, Failure<T>> = new Map();
|
|
66
66
|
for (const [k, result] of results) {
|
|
@@ -97,6 +97,6 @@ const isError = <T>(value: T | Error): value is Error => {
|
|
|
97
97
|
export const pick = <T extends object, U extends keyof T>(object: T, props: U[]): Pick<T, U> => {
|
|
98
98
|
const propsSet = new Set(props);
|
|
99
99
|
return Object.fromEntries(
|
|
100
|
-
Object.entries(object).filter((entry) => propsSet.has(entry[0] as any))
|
|
100
|
+
Object.entries(object).filter((entry) => propsSet.has(entry[0] as any)),
|
|
101
101
|
) as any;
|
|
102
102
|
};
|
|
@@ -24,7 +24,10 @@ export default abstract class EntityError extends ES6Error {
|
|
|
24
24
|
public abstract readonly state: EntityErrorState;
|
|
25
25
|
public abstract readonly code: EntityErrorCode;
|
|
26
26
|
|
|
27
|
-
constructor(
|
|
27
|
+
constructor(
|
|
28
|
+
message: string,
|
|
29
|
+
public override readonly cause?: Error,
|
|
30
|
+
) {
|
|
28
31
|
super(message);
|
|
29
32
|
}
|
|
30
33
|
}
|
|
@@ -17,7 +17,7 @@ export default class EntityInvalidFieldValueError<
|
|
|
17
17
|
TSelectedFields
|
|
18
18
|
>,
|
|
19
19
|
N extends keyof TFields,
|
|
20
|
-
TSelectedFields extends keyof TFields = keyof TFields
|
|
20
|
+
TSelectedFields extends keyof TFields = keyof TFields,
|
|
21
21
|
> extends EntityError {
|
|
22
22
|
public readonly state = EntityErrorState.PERMANENT;
|
|
23
23
|
public readonly code = EntityErrorCode.ERR_ENTITY_INVALID_FIELD_VALUE;
|
|
@@ -32,7 +32,7 @@ export default class EntityInvalidFieldValueError<
|
|
|
32
32
|
TSelectedFields
|
|
33
33
|
>,
|
|
34
34
|
fieldName: N,
|
|
35
|
-
fieldValue?: TFields[N]
|
|
35
|
+
fieldValue?: TFields[N],
|
|
36
36
|
) {
|
|
37
37
|
super(`Entity field not valid: ${entityClass.name} (${String(fieldName)} = ${fieldValue})`);
|
|
38
38
|
}
|
|
@@ -8,7 +8,7 @@ export default class EntityNotAuthorizedError<
|
|
|
8
8
|
TID extends NonNullable<TFields[TSelectedFields]>,
|
|
9
9
|
TViewerContext extends ViewerContext,
|
|
10
10
|
TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>,
|
|
11
|
-
TSelectedFields extends keyof TFields = keyof TFields
|
|
11
|
+
TSelectedFields extends keyof TFields = keyof TFields,
|
|
12
12
|
> extends EntityError {
|
|
13
13
|
public readonly state = EntityErrorState.PERMANENT;
|
|
14
14
|
public readonly code = EntityErrorCode.ERR_ENTITY_NOT_AUTHORIZED;
|
|
@@ -19,10 +19,10 @@ export default class EntityNotAuthorizedError<
|
|
|
19
19
|
entity: TEntity,
|
|
20
20
|
viewerContext: TViewerContext,
|
|
21
21
|
action: EntityAuthorizationAction,
|
|
22
|
-
ruleIndex: number
|
|
22
|
+
ruleIndex: number,
|
|
23
23
|
) {
|
|
24
24
|
super(
|
|
25
|
-
`Entity not authorized: ${entity} (viewer = ${viewerContext}, action = ${EntityAuthorizationAction[action]}, ruleIndex = ${ruleIndex})
|
|
25
|
+
`Entity not authorized: ${entity} (viewer = ${viewerContext}, action = ${EntityAuthorizationAction[action]}, ruleIndex = ${ruleIndex})`,
|
|
26
26
|
);
|
|
27
27
|
this.entityClassName = entity.constructor.name;
|
|
28
28
|
}
|
|
@@ -17,7 +17,7 @@ export default class EntityNotFoundError<
|
|
|
17
17
|
TSelectedFields
|
|
18
18
|
>,
|
|
19
19
|
N extends keyof TFields,
|
|
20
|
-
TSelectedFields extends keyof TFields = keyof TFields
|
|
20
|
+
TSelectedFields extends keyof TFields = keyof TFields,
|
|
21
21
|
> extends EntityError {
|
|
22
22
|
public readonly state = EntityErrorState.PERMANENT;
|
|
23
23
|
public readonly code = EntityErrorCode.ERR_ENTITY_NOT_FOUND;
|
|
@@ -32,7 +32,7 @@ export default class EntityNotFoundError<
|
|
|
32
32
|
TSelectedFields
|
|
33
33
|
>,
|
|
34
34
|
fieldName: N,
|
|
35
|
-
fieldValue: TFields[N]
|
|
35
|
+
fieldValue: TFields[N],
|
|
36
36
|
) {
|
|
37
37
|
super(`Entity not found: ${entityClass.name} (${String(fieldName)} = ${fieldValue})`);
|
|
38
38
|
}
|
package/src/index.ts
CHANGED
|
@@ -76,3 +76,4 @@ export { default as StubDatabaseAdapterProvider } from './utils/testing/StubData
|
|
|
76
76
|
export { default as StubQueryContextProvider } from './utils/testing/StubQueryContextProvider';
|
|
77
77
|
export * from './utils/testing/createUnitTestEntityCompanionProvider';
|
|
78
78
|
export * from './utils/collections/maps';
|
|
79
|
+
export * from './utils/EntityPrivacyUtils';
|
|
@@ -25,7 +25,7 @@ import { computeIfAbsent, zipToMap } from '../utils/collections/maps';
|
|
|
25
25
|
*
|
|
26
26
|
* It is also responsible for invalidating all sources of data when mutated using EntityMutator.
|
|
27
27
|
*/
|
|
28
|
-
export default class EntityDataManager<TFields
|
|
28
|
+
export default class EntityDataManager<TFields extends Record<string, any>> {
|
|
29
29
|
private readonly fieldDataLoaders: Map<
|
|
30
30
|
keyof TFields,
|
|
31
31
|
DataLoader<NonNullable<TFields[keyof TFields]>, readonly Readonly<TFields>[]>
|
|
@@ -36,30 +36,30 @@ export default class EntityDataManager<TFields> {
|
|
|
36
36
|
private readonly entityCache: ReadThroughEntityCache<TFields>,
|
|
37
37
|
private readonly queryContextProvider: EntityQueryContextProvider,
|
|
38
38
|
private readonly metricsAdapter: IEntityMetricsAdapter,
|
|
39
|
-
private readonly entityClassName: string
|
|
39
|
+
private readonly entityClassName: string,
|
|
40
40
|
) {}
|
|
41
41
|
|
|
42
42
|
private getFieldDataLoaderForFieldName<N extends keyof TFields>(
|
|
43
|
-
fieldName: N
|
|
43
|
+
fieldName: N,
|
|
44
44
|
): DataLoader<NonNullable<TFields[N]>, readonly Readonly<TFields>[]> {
|
|
45
45
|
return computeIfAbsent(this.fieldDataLoaders, fieldName, () => {
|
|
46
46
|
return new DataLoader(
|
|
47
47
|
async (
|
|
48
|
-
fieldValues: readonly NonNullable<TFields[N]>[]
|
|
48
|
+
fieldValues: readonly NonNullable<TFields[N]>[],
|
|
49
49
|
): Promise<readonly (readonly TFields[])[]> => {
|
|
50
50
|
const objectMap = await this.loadManyForDataLoaderByFieldEqualingAsync(
|
|
51
51
|
fieldName,
|
|
52
|
-
fieldValues
|
|
52
|
+
fieldValues,
|
|
53
53
|
);
|
|
54
54
|
return fieldValues.map((fv) => objectMap.get(fv) ?? []);
|
|
55
|
-
}
|
|
55
|
+
},
|
|
56
56
|
);
|
|
57
57
|
});
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
private async loadManyForDataLoaderByFieldEqualingAsync<N extends keyof TFields>(
|
|
61
61
|
fieldName: N,
|
|
62
|
-
fieldValues: readonly NonNullable<TFields[N]>[]
|
|
62
|
+
fieldValues: readonly NonNullable<TFields[N]>[],
|
|
63
63
|
): Promise<ReadonlyMap<NonNullable<TFields[N]>, readonly Readonly<TFields>[]>> {
|
|
64
64
|
this.metricsAdapter.incrementDataManagerLoadCount({
|
|
65
65
|
type: IncrementLoadCountEventType.CACHE,
|
|
@@ -76,11 +76,11 @@ export default class EntityDataManager<TFields> {
|
|
|
76
76
|
entityClassName: this.entityClassName,
|
|
77
77
|
});
|
|
78
78
|
return await this.databaseAdapter.fetchManyWhereAsync(
|
|
79
|
-
this.queryContextProvider.
|
|
79
|
+
this.queryContextProvider.getQueryContext(),
|
|
80
80
|
fieldName,
|
|
81
|
-
fetcherValues
|
|
81
|
+
fetcherValues,
|
|
82
82
|
);
|
|
83
|
-
}
|
|
83
|
+
},
|
|
84
84
|
);
|
|
85
85
|
}
|
|
86
86
|
|
|
@@ -95,28 +95,28 @@ export default class EntityDataManager<TFields> {
|
|
|
95
95
|
async loadManyByFieldEqualingAsync<N extends keyof TFields>(
|
|
96
96
|
queryContext: EntityQueryContext,
|
|
97
97
|
fieldName: N,
|
|
98
|
-
fieldValues: readonly NonNullable<TFields[N]>[]
|
|
98
|
+
fieldValues: readonly NonNullable<TFields[N]>[],
|
|
99
99
|
): Promise<ReadonlyMap<NonNullable<TFields[N]>, readonly Readonly<TFields>[]>> {
|
|
100
100
|
return await timeAndLogLoadMapEventAsync(
|
|
101
101
|
this.metricsAdapter,
|
|
102
102
|
EntityMetricsLoadType.LOAD_MANY,
|
|
103
|
-
this.entityClassName
|
|
103
|
+
this.entityClassName,
|
|
104
104
|
)(this.loadManyByFieldEqualingInternalAsync(queryContext, fieldName, fieldValues));
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
private async loadManyByFieldEqualingInternalAsync<N extends keyof TFields>(
|
|
108
108
|
queryContext: EntityQueryContext,
|
|
109
109
|
fieldName: N,
|
|
110
|
-
fieldValues: readonly NonNullable<TFields[N]>[]
|
|
110
|
+
fieldValues: readonly NonNullable<TFields[N]>[],
|
|
111
111
|
): Promise<ReadonlyMap<NonNullable<TFields[N]>, readonly Readonly<TFields>[]>> {
|
|
112
112
|
const nullOrUndefinedValueIndex = fieldValues.findIndex(
|
|
113
|
-
(value) => value === null || value === undefined
|
|
113
|
+
(value) => value === null || value === undefined,
|
|
114
114
|
);
|
|
115
115
|
if (nullOrUndefinedValueIndex >= 0) {
|
|
116
116
|
throw new Error(
|
|
117
117
|
`Invalid load: ${this.entityClassName} (${String(fieldName)} = ${
|
|
118
118
|
fieldValues[nullOrUndefinedValueIndex]
|
|
119
|
-
})
|
|
119
|
+
})`,
|
|
120
120
|
);
|
|
121
121
|
}
|
|
122
122
|
|
|
@@ -153,18 +153,18 @@ export default class EntityDataManager<TFields> {
|
|
|
153
153
|
async loadManyByFieldEqualityConjunctionAsync<N extends keyof TFields>(
|
|
154
154
|
queryContext: EntityQueryContext,
|
|
155
155
|
fieldEqualityOperands: FieldEqualityCondition<TFields, N>[],
|
|
156
|
-
querySelectionModifiers: QuerySelectionModifiers<TFields
|
|
156
|
+
querySelectionModifiers: QuerySelectionModifiers<TFields>,
|
|
157
157
|
): Promise<readonly Readonly<TFields>[]> {
|
|
158
158
|
return await timeAndLogLoadEventAsync(
|
|
159
159
|
this.metricsAdapter,
|
|
160
160
|
EntityMetricsLoadType.LOAD_MANY_EQUALITY_CONJUNCTION,
|
|
161
|
-
this.entityClassName
|
|
161
|
+
this.entityClassName,
|
|
162
162
|
)(
|
|
163
163
|
this.databaseAdapter.fetchManyByFieldEqualityConjunctionAsync(
|
|
164
164
|
queryContext,
|
|
165
165
|
fieldEqualityOperands,
|
|
166
|
-
querySelectionModifiers
|
|
167
|
-
)
|
|
166
|
+
querySelectionModifiers,
|
|
167
|
+
),
|
|
168
168
|
);
|
|
169
169
|
}
|
|
170
170
|
|
|
@@ -181,25 +181,25 @@ export default class EntityDataManager<TFields> {
|
|
|
181
181
|
queryContext: EntityQueryContext,
|
|
182
182
|
rawWhereClause: string,
|
|
183
183
|
bindings: any[] | object,
|
|
184
|
-
querySelectionModifiers: QuerySelectionModifiersWithOrderByRaw<TFields
|
|
184
|
+
querySelectionModifiers: QuerySelectionModifiersWithOrderByRaw<TFields>,
|
|
185
185
|
): Promise<readonly Readonly<TFields>[]> {
|
|
186
186
|
return await timeAndLogLoadEventAsync(
|
|
187
187
|
this.metricsAdapter,
|
|
188
188
|
EntityMetricsLoadType.LOAD_MANY_RAW,
|
|
189
|
-
this.entityClassName
|
|
189
|
+
this.entityClassName,
|
|
190
190
|
)(
|
|
191
191
|
this.databaseAdapter.fetchManyByRawWhereClauseAsync(
|
|
192
192
|
queryContext,
|
|
193
193
|
rawWhereClause,
|
|
194
194
|
bindings,
|
|
195
|
-
querySelectionModifiers
|
|
196
|
-
)
|
|
195
|
+
querySelectionModifiers,
|
|
196
|
+
),
|
|
197
197
|
);
|
|
198
198
|
}
|
|
199
199
|
|
|
200
200
|
private async invalidateManyByFieldEqualingAsync<N extends keyof TFields>(
|
|
201
201
|
fieldName: N,
|
|
202
|
-
fieldValues: readonly NonNullable<TFields[N]>[]
|
|
202
|
+
fieldValues: readonly NonNullable<TFields[N]>[],
|
|
203
203
|
): Promise<void> {
|
|
204
204
|
await this.entityCache.invalidateManyAsync(fieldName, fieldValues);
|
|
205
205
|
const dataLoader = this.getFieldDataLoaderForFieldName(fieldName);
|
|
@@ -222,7 +222,7 @@ export default class EntityDataManager<TFields> {
|
|
|
222
222
|
value as NonNullable<TFields[keyof TFields]>,
|
|
223
223
|
]);
|
|
224
224
|
}
|
|
225
|
-
})
|
|
225
|
+
}),
|
|
226
226
|
);
|
|
227
227
|
}
|
|
228
228
|
}
|