@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
|
@@ -11,7 +11,7 @@ import invariant from 'invariant';
|
|
|
11
11
|
export const computeIfAbsent = <K, V>(
|
|
12
12
|
map: Map<K, V>,
|
|
13
13
|
key: K,
|
|
14
|
-
mappingFunction: (key: K) => V
|
|
14
|
+
mappingFunction: (key: K) => V,
|
|
15
15
|
): V => {
|
|
16
16
|
if (!map.has(key)) {
|
|
17
17
|
const value = mappingFunction(key);
|
|
@@ -28,7 +28,7 @@ export const computeIfAbsent = <K, V>(
|
|
|
28
28
|
*/
|
|
29
29
|
export const mapMap = <K, V, M>(
|
|
30
30
|
map: ReadonlyMap<K, V>,
|
|
31
|
-
mapper: (value: V, key: K) => M
|
|
31
|
+
mapper: (value: V, key: K) => M,
|
|
32
32
|
): Map<K, M> => {
|
|
33
33
|
const resultingMap = new Map();
|
|
34
34
|
for (const [k, v] of map) {
|
|
@@ -45,7 +45,7 @@ export const mapMap = <K, V, M>(
|
|
|
45
45
|
*/
|
|
46
46
|
export const mapMapAsync = async function <K, V, M>(
|
|
47
47
|
map: ReadonlyMap<K, V>,
|
|
48
|
-
mapper: (value: V, key: K) => Promise<M
|
|
48
|
+
mapper: (value: V, key: K) => Promise<M>,
|
|
49
49
|
): Promise<Map<K, M>> {
|
|
50
50
|
const resultingMap: Map<K, M> = new Map();
|
|
51
51
|
await Promise.all(
|
|
@@ -53,7 +53,7 @@ export const mapMapAsync = async function <K, V, M>(
|
|
|
53
53
|
const initialValue = map.get(k) as V;
|
|
54
54
|
const result = await mapper(initialValue, k);
|
|
55
55
|
resultingMap.set(k, result);
|
|
56
|
-
})
|
|
56
|
+
}),
|
|
57
57
|
);
|
|
58
58
|
return resultingMap;
|
|
59
59
|
};
|
|
@@ -69,7 +69,7 @@ export const mapMapAsync = async function <K, V, M>(
|
|
|
69
69
|
*/
|
|
70
70
|
export const mapKeys = <K, V, K2>(
|
|
71
71
|
map: ReadonlyMap<K, V>,
|
|
72
|
-
mapper: (key: K, value: V) => K2
|
|
72
|
+
mapper: (key: K, value: V) => K2,
|
|
73
73
|
): Map<K2, V> => {
|
|
74
74
|
const resultingMap = new Map();
|
|
75
75
|
for (const [k, v] of map) {
|
|
@@ -92,7 +92,7 @@ export const mapKeys = <K, V, K2>(
|
|
|
92
92
|
export const zipToMap = <K, V>(keys: readonly K[], values: readonly V[]): Map<K, V> => {
|
|
93
93
|
invariant(
|
|
94
94
|
keys.length === values.length,
|
|
95
|
-
`zipToMap input length mismatch: keys[${keys.length}], values[${values.length}]
|
|
95
|
+
`zipToMap input length mismatch: keys[${keys.length}], values[${values.length}]`,
|
|
96
96
|
);
|
|
97
97
|
const resultingMap = new Map();
|
|
98
98
|
for (let i = 0; i < keys.length; i++) {
|
|
@@ -126,7 +126,7 @@ export const invertMap = <K, V>(map: ReadonlyMap<K, V>): Map<V, K> => {
|
|
|
126
126
|
export const reduceMap = <K, V, A>(
|
|
127
127
|
map: ReadonlyMap<K, V>,
|
|
128
128
|
reducer: (accumulator: A, value: V, key: K) => A,
|
|
129
|
-
initialValue: A
|
|
129
|
+
initialValue: A,
|
|
130
130
|
): A => {
|
|
131
131
|
let newAccumulator = initialValue;
|
|
132
132
|
for (const [k, v] of map) {
|
|
@@ -147,7 +147,7 @@ export const reduceMap = <K, V, A>(
|
|
|
147
147
|
export const reduceMapAsync = async <K, V, A>(
|
|
148
148
|
map: ReadonlyMap<K, V>,
|
|
149
149
|
reducer: (accumulator: A, value: V, key: K) => Promise<A>,
|
|
150
|
-
initialValue: A
|
|
150
|
+
initialValue: A,
|
|
151
151
|
): Promise<A> => {
|
|
152
152
|
let newAccumulator = initialValue;
|
|
153
153
|
for (const [k, v] of map) {
|
|
@@ -163,7 +163,7 @@ export const reduceMapAsync = async <K, V, A>(
|
|
|
163
163
|
*/
|
|
164
164
|
export function filterMap<K, V, S extends V>(
|
|
165
165
|
map: ReadonlyMap<K, V>,
|
|
166
|
-
predicate: (value: V, key: K) => value is S
|
|
166
|
+
predicate: (value: V, key: K) => value is S,
|
|
167
167
|
): Map<K, S>;
|
|
168
168
|
|
|
169
169
|
/**
|
|
@@ -173,7 +173,7 @@ export function filterMap<K, V, S extends V>(
|
|
|
173
173
|
*/
|
|
174
174
|
export function filterMap<K, V>(
|
|
175
175
|
map: ReadonlyMap<K, V>,
|
|
176
|
-
predicate: (value: V, key: K) => boolean
|
|
176
|
+
predicate: (value: V, key: K) => boolean,
|
|
177
177
|
): Map<K, V>;
|
|
178
178
|
|
|
179
179
|
/**
|
|
@@ -183,7 +183,7 @@ export function filterMap<K, V>(
|
|
|
183
183
|
*/
|
|
184
184
|
export function filterMap<K, V>(
|
|
185
185
|
map: ReadonlyMap<K, V>,
|
|
186
|
-
predicate: (value: V, key: K) => unknown
|
|
186
|
+
predicate: (value: V, key: K) => unknown,
|
|
187
187
|
): Map<K, V> {
|
|
188
188
|
const resultingMap = new Map();
|
|
189
189
|
map.forEach((v, k) => {
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import EntityMutationTriggerConfiguration from '../EntityMutationTriggerConfiguration';
|
|
2
|
+
import ReadonlyEntity from '../ReadonlyEntity';
|
|
3
|
+
import ViewerContext from '../ViewerContext';
|
|
4
|
+
|
|
5
|
+
function nonNullish<TValue>(value: TValue | null | undefined): value is NonNullable<TValue> {
|
|
6
|
+
return value !== null && value !== undefined;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function mergeEntityMutationTriggerConfigurations<
|
|
10
|
+
TFields extends object,
|
|
11
|
+
TID extends NonNullable<TFields[TSelectedFields]>,
|
|
12
|
+
TViewerContext extends ViewerContext,
|
|
13
|
+
TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>,
|
|
14
|
+
TSelectedFields extends keyof TFields,
|
|
15
|
+
>(
|
|
16
|
+
...mutationTriggerConfigurations: EntityMutationTriggerConfiguration<
|
|
17
|
+
TFields,
|
|
18
|
+
TID,
|
|
19
|
+
TViewerContext,
|
|
20
|
+
TEntity,
|
|
21
|
+
TSelectedFields
|
|
22
|
+
>[]
|
|
23
|
+
): EntityMutationTriggerConfiguration<TFields, TID, TViewerContext, TEntity, TSelectedFields> {
|
|
24
|
+
const merged = {
|
|
25
|
+
beforeCreate: mutationTriggerConfigurations.flatMap((c) => c.beforeCreate).filter(nonNullish),
|
|
26
|
+
afterCreate: mutationTriggerConfigurations.flatMap((c) => c.afterCreate).filter(nonNullish),
|
|
27
|
+
beforeUpdate: mutationTriggerConfigurations.flatMap((c) => c.beforeUpdate).filter(nonNullish),
|
|
28
|
+
afterUpdate: mutationTriggerConfigurations.flatMap((c) => c.afterUpdate).filter(nonNullish),
|
|
29
|
+
beforeDelete: mutationTriggerConfigurations.flatMap((c) => c.beforeDelete).filter(nonNullish),
|
|
30
|
+
afterDelete: mutationTriggerConfigurations.flatMap((c) => c.afterDelete).filter(nonNullish),
|
|
31
|
+
beforeAll: mutationTriggerConfigurations.flatMap((c) => c.beforeAll).filter(nonNullish),
|
|
32
|
+
afterAll: mutationTriggerConfigurations.flatMap((c) => c.afterAll).filter(nonNullish),
|
|
33
|
+
afterCommit: mutationTriggerConfigurations.flatMap((c) => c.afterCommit).filter(nonNullish),
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/** Remove any trigger that is an empty array */
|
|
37
|
+
for (const key of Object.keys(merged) as (keyof typeof merged)[]) {
|
|
38
|
+
if (merged[key].length === 0) {
|
|
39
|
+
delete merged[key];
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return merged;
|
|
44
|
+
}
|
|
@@ -9,11 +9,17 @@ export interface Case<
|
|
|
9
9
|
TID extends NonNullable<TFields[TSelectedFields]>,
|
|
10
10
|
TViewerContext extends ViewerContext,
|
|
11
11
|
TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>,
|
|
12
|
-
TSelectedFields extends keyof TFields
|
|
12
|
+
TSelectedFields extends keyof TFields,
|
|
13
13
|
> {
|
|
14
14
|
viewerContext: TViewerContext;
|
|
15
15
|
queryContext: EntityQueryContext;
|
|
16
|
-
evaluationContext: EntityPrivacyPolicyEvaluationContext
|
|
16
|
+
evaluationContext: EntityPrivacyPolicyEvaluationContext<
|
|
17
|
+
TFields,
|
|
18
|
+
TID,
|
|
19
|
+
TViewerContext,
|
|
20
|
+
TEntity,
|
|
21
|
+
TSelectedFields
|
|
22
|
+
>;
|
|
17
23
|
entity: TEntity;
|
|
18
24
|
}
|
|
19
25
|
|
|
@@ -22,7 +28,7 @@ export type CaseMap<
|
|
|
22
28
|
TID extends NonNullable<TFields[TSelectedFields]>,
|
|
23
29
|
TViewerContext extends ViewerContext,
|
|
24
30
|
TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>,
|
|
25
|
-
TSelectedFields extends keyof TFields
|
|
31
|
+
TSelectedFields extends keyof TFields,
|
|
26
32
|
> = Map<string, () => Promise<Case<TFields, TID, TViewerContext, TEntity, TSelectedFields>>>;
|
|
27
33
|
|
|
28
34
|
/**
|
|
@@ -33,7 +39,7 @@ export const describePrivacyPolicyRuleWithAsyncTestCase = <
|
|
|
33
39
|
TID extends NonNullable<TFields[TSelectedFields]>,
|
|
34
40
|
TViewerContext extends ViewerContext,
|
|
35
41
|
TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>,
|
|
36
|
-
TSelectedFields extends keyof TFields = keyof TFields
|
|
42
|
+
TSelectedFields extends keyof TFields = keyof TFields,
|
|
37
43
|
>(
|
|
38
44
|
privacyPolicyRule: PrivacyPolicyRule<TFields, TID, TViewerContext, TEntity, TSelectedFields>,
|
|
39
45
|
{
|
|
@@ -44,17 +50,16 @@ export const describePrivacyPolicyRuleWithAsyncTestCase = <
|
|
|
44
50
|
allowCases?: CaseMap<TFields, TID, TViewerContext, TEntity, TSelectedFields>;
|
|
45
51
|
skipCases?: CaseMap<TFields, TID, TViewerContext, TEntity, TSelectedFields>;
|
|
46
52
|
denyCases?: CaseMap<TFields, TID, TViewerContext, TEntity, TSelectedFields>;
|
|
47
|
-
}
|
|
53
|
+
},
|
|
48
54
|
): void => {
|
|
49
55
|
describe(privacyPolicyRule.constructor.name, () => {
|
|
50
56
|
if (allowCases && allowCases.size > 0) {
|
|
51
57
|
describe('allow cases', () => {
|
|
52
58
|
test.each(Array.from(allowCases.keys()))('%p', async (caseKey) => {
|
|
53
|
-
const { viewerContext, queryContext, evaluationContext, entity } =
|
|
54
|
-
caseKey
|
|
55
|
-
)!();
|
|
59
|
+
const { viewerContext, queryContext, evaluationContext, entity } =
|
|
60
|
+
await allowCases.get(caseKey)!();
|
|
56
61
|
await expect(
|
|
57
|
-
privacyPolicyRule.evaluateAsync(viewerContext, queryContext, evaluationContext, entity)
|
|
62
|
+
privacyPolicyRule.evaluateAsync(viewerContext, queryContext, evaluationContext, entity),
|
|
58
63
|
).resolves.toEqual(RuleEvaluationResult.ALLOW);
|
|
59
64
|
});
|
|
60
65
|
});
|
|
@@ -63,11 +68,10 @@ export const describePrivacyPolicyRuleWithAsyncTestCase = <
|
|
|
63
68
|
if (skipCases && skipCases.size > 0) {
|
|
64
69
|
describe('skip cases', () => {
|
|
65
70
|
test.each(Array.from(skipCases.keys()))('%p', async (caseKey) => {
|
|
66
|
-
const { viewerContext, queryContext, evaluationContext, entity } =
|
|
67
|
-
caseKey
|
|
68
|
-
)!();
|
|
71
|
+
const { viewerContext, queryContext, evaluationContext, entity } =
|
|
72
|
+
await skipCases.get(caseKey)!();
|
|
69
73
|
await expect(
|
|
70
|
-
privacyPolicyRule.evaluateAsync(viewerContext, queryContext, evaluationContext, entity)
|
|
74
|
+
privacyPolicyRule.evaluateAsync(viewerContext, queryContext, evaluationContext, entity),
|
|
71
75
|
).resolves.toEqual(RuleEvaluationResult.SKIP);
|
|
72
76
|
});
|
|
73
77
|
});
|
|
@@ -76,11 +80,10 @@ export const describePrivacyPolicyRuleWithAsyncTestCase = <
|
|
|
76
80
|
if (denyCases && denyCases.size > 0) {
|
|
77
81
|
describe('deny cases', () => {
|
|
78
82
|
test.each(Array.from(denyCases.keys()))('%p', async (caseKey) => {
|
|
79
|
-
const { viewerContext, queryContext, evaluationContext, entity } =
|
|
80
|
-
caseKey
|
|
81
|
-
)!();
|
|
83
|
+
const { viewerContext, queryContext, evaluationContext, entity } =
|
|
84
|
+
await denyCases.get(caseKey)!();
|
|
82
85
|
await expect(
|
|
83
|
-
privacyPolicyRule.evaluateAsync(viewerContext, queryContext, evaluationContext, entity)
|
|
86
|
+
privacyPolicyRule.evaluateAsync(viewerContext, queryContext, evaluationContext, entity),
|
|
84
87
|
).resolves.toEqual(RuleEvaluationResult.DENY);
|
|
85
88
|
});
|
|
86
89
|
});
|
|
@@ -96,7 +99,7 @@ export const describePrivacyPolicyRule = <
|
|
|
96
99
|
TID extends NonNullable<TFields[TSelectedFields]>,
|
|
97
100
|
TViewerContext extends ViewerContext,
|
|
98
101
|
TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>,
|
|
99
|
-
TSelectedFields extends keyof TFields = keyof TFields
|
|
102
|
+
TSelectedFields extends keyof TFields = keyof TFields,
|
|
100
103
|
>(
|
|
101
104
|
privacyPolicyRule: PrivacyPolicyRule<TFields, TID, TViewerContext, TEntity, TSelectedFields>,
|
|
102
105
|
{
|
|
@@ -107,21 +110,21 @@ export const describePrivacyPolicyRule = <
|
|
|
107
110
|
allowCases?: Case<TFields, TID, TViewerContext, TEntity, TSelectedFields>[];
|
|
108
111
|
skipCases?: Case<TFields, TID, TViewerContext, TEntity, TSelectedFields>[];
|
|
109
112
|
denyCases?: Case<TFields, TID, TViewerContext, TEntity, TSelectedFields>[];
|
|
110
|
-
}
|
|
113
|
+
},
|
|
111
114
|
): void => {
|
|
112
115
|
const makeCasesMap = (
|
|
113
|
-
cases: Case<TFields, TID, TViewerContext, TEntity, TSelectedFields>[]
|
|
116
|
+
cases: Case<TFields, TID, TViewerContext, TEntity, TSelectedFields>[],
|
|
114
117
|
): CaseMap<TFields, TID, TViewerContext, TEntity, TSelectedFields> =>
|
|
115
118
|
cases.reduce(
|
|
116
119
|
(
|
|
117
120
|
acc: CaseMap<TFields, TID, TViewerContext, TEntity, TSelectedFields>,
|
|
118
121
|
testCase: Case<TFields, TID, TViewerContext, TEntity, TSelectedFields>,
|
|
119
|
-
index
|
|
122
|
+
index,
|
|
120
123
|
) => {
|
|
121
124
|
acc.set(`case ${index}`, async () => testCase);
|
|
122
125
|
return acc;
|
|
123
126
|
},
|
|
124
|
-
new Map()
|
|
127
|
+
new Map(),
|
|
125
128
|
);
|
|
126
129
|
|
|
127
130
|
return describePrivacyPolicyRuleWithAsyncTestCase(privacyPolicyRule, {
|
|
@@ -6,8 +6,8 @@ import IEntityCacheAdapterProvider from '../../IEntityCacheAdapterProvider';
|
|
|
6
6
|
import { CacheStatus, CacheLoadResult } from '../../internal/ReadThroughEntityCache';
|
|
7
7
|
|
|
8
8
|
export class NoCacheStubCacheAdapterProvider implements IEntityCacheAdapterProvider {
|
|
9
|
-
getCacheAdapter<TFields
|
|
10
|
-
_entityConfiguration: EntityConfiguration<TFields
|
|
9
|
+
getCacheAdapter<TFields extends Record<string, any>>(
|
|
10
|
+
_entityConfiguration: EntityConfiguration<TFields>,
|
|
11
11
|
): IEntityCacheAdapter<TFields> {
|
|
12
12
|
return new NoCacheStubCacheAdapter();
|
|
13
13
|
}
|
|
@@ -16,7 +16,7 @@ export class NoCacheStubCacheAdapterProvider implements IEntityCacheAdapterProvi
|
|
|
16
16
|
export class NoCacheStubCacheAdapter<TFields> implements IEntityCacheAdapter<TFields> {
|
|
17
17
|
public async loadManyAsync<N extends keyof TFields>(
|
|
18
18
|
_fieldName: N,
|
|
19
|
-
fieldValues: readonly NonNullable<TFields[N]>[]
|
|
19
|
+
fieldValues: readonly NonNullable<TFields[N]>[],
|
|
20
20
|
): Promise<ReadonlyMap<NonNullable<TFields[N]>, CacheLoadResult<TFields>>> {
|
|
21
21
|
return fieldValues.reduce((acc: Map<NonNullable<TFields[N]>, CacheLoadResult<TFields>>, v) => {
|
|
22
22
|
acc.set(v, {
|
|
@@ -28,42 +28,44 @@ export class NoCacheStubCacheAdapter<TFields> implements IEntityCacheAdapter<TFi
|
|
|
28
28
|
|
|
29
29
|
public async cacheManyAsync<N extends keyof TFields>(
|
|
30
30
|
_fieldName: N,
|
|
31
|
-
_objectMap: ReadonlyMap<NonNullable<TFields[N]>, Readonly<TFields
|
|
31
|
+
_objectMap: ReadonlyMap<NonNullable<TFields[N]>, Readonly<TFields>>,
|
|
32
32
|
): Promise<void> {}
|
|
33
33
|
|
|
34
34
|
public async cacheDBMissesAsync<N extends keyof TFields>(
|
|
35
35
|
_fieldName: N,
|
|
36
|
-
_fieldValues: readonly NonNullable<TFields[N]>[]
|
|
36
|
+
_fieldValues: readonly NonNullable<TFields[N]>[],
|
|
37
37
|
): Promise<void> {}
|
|
38
38
|
|
|
39
39
|
async invalidateManyAsync<N extends keyof TFields>(
|
|
40
40
|
_fieldName: N,
|
|
41
|
-
_fieldValues: readonly TFields[N][]
|
|
41
|
+
_fieldValues: readonly TFields[N][],
|
|
42
42
|
): Promise<void> {}
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
export class InMemoryFullCacheStubCacheAdapterProvider implements IEntityCacheAdapterProvider {
|
|
46
46
|
cache: Map<string, Readonly<object>> = new Map();
|
|
47
47
|
|
|
48
|
-
getCacheAdapter<TFields
|
|
49
|
-
entityConfiguration: EntityConfiguration<TFields
|
|
48
|
+
getCacheAdapter<TFields extends Record<string, any>>(
|
|
49
|
+
entityConfiguration: EntityConfiguration<TFields>,
|
|
50
50
|
): IEntityCacheAdapter<TFields> {
|
|
51
51
|
return new InMemoryFullCacheStubCacheAdapter(
|
|
52
52
|
entityConfiguration,
|
|
53
|
-
this.cache as Map<string, Readonly<TFields
|
|
53
|
+
this.cache as Map<string, Readonly<TFields>>,
|
|
54
54
|
);
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
export class InMemoryFullCacheStubCacheAdapter<TFields
|
|
58
|
+
export class InMemoryFullCacheStubCacheAdapter<TFields extends Record<string, any>>
|
|
59
|
+
implements IEntityCacheAdapter<TFields>
|
|
60
|
+
{
|
|
59
61
|
constructor(
|
|
60
62
|
private readonly entityConfiguration: EntityConfiguration<TFields>,
|
|
61
|
-
readonly cache: Map<string, Readonly<TFields
|
|
63
|
+
readonly cache: Map<string, Readonly<TFields>>,
|
|
62
64
|
) {}
|
|
63
65
|
|
|
64
66
|
public async loadManyAsync<N extends keyof TFields>(
|
|
65
67
|
fieldName: N,
|
|
66
|
-
fieldValues: readonly NonNullable<TFields[N]>[]
|
|
68
|
+
fieldValues: readonly NonNullable<TFields[N]>[],
|
|
67
69
|
): Promise<ReadonlyMap<NonNullable<TFields[N]>, CacheLoadResult<TFields>>> {
|
|
68
70
|
const results = new Map<NonNullable<TFields[N]>, CacheLoadResult<TFields>>();
|
|
69
71
|
fieldValues.forEach((fieldValue) => {
|
|
@@ -86,7 +88,7 @@ export class InMemoryFullCacheStubCacheAdapter<TFields> implements IEntityCacheA
|
|
|
86
88
|
|
|
87
89
|
public async cacheManyAsync<N extends keyof TFields>(
|
|
88
90
|
fieldName: N,
|
|
89
|
-
objectMap: ReadonlyMap<NonNullable<TFields[N]>, Readonly<TFields
|
|
91
|
+
objectMap: ReadonlyMap<NonNullable<TFields[N]>, Readonly<TFields>>,
|
|
90
92
|
): Promise<void> {
|
|
91
93
|
objectMap.forEach((obj, fieldValue) => {
|
|
92
94
|
const cacheKey = this.createCacheKey(fieldName, fieldValue);
|
|
@@ -96,12 +98,12 @@ export class InMemoryFullCacheStubCacheAdapter<TFields> implements IEntityCacheA
|
|
|
96
98
|
|
|
97
99
|
public async cacheDBMissesAsync<N extends keyof TFields>(
|
|
98
100
|
_fieldName: N,
|
|
99
|
-
_fieldValues: readonly NonNullable<TFields[N]>[]
|
|
101
|
+
_fieldValues: readonly NonNullable<TFields[N]>[],
|
|
100
102
|
): Promise<void> {}
|
|
101
103
|
|
|
102
104
|
public async invalidateManyAsync<N extends keyof TFields>(
|
|
103
105
|
fieldName: N,
|
|
104
|
-
fieldValues: readonly NonNullable<TFields[N]>[]
|
|
106
|
+
fieldValues: readonly NonNullable<TFields[N]>[],
|
|
105
107
|
): Promise<void> {
|
|
106
108
|
fieldValues.forEach((fieldValue) => {
|
|
107
109
|
const cacheKey = this.createCacheKey(fieldName, fieldValue);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import invariant from 'invariant';
|
|
2
|
-
import {
|
|
2
|
+
import { uuidv7 } from 'uuidv7';
|
|
3
3
|
|
|
4
4
|
import EntityConfiguration from '../../EntityConfiguration';
|
|
5
5
|
import EntityDatabaseAdapter, {
|
|
@@ -16,22 +16,24 @@ import {
|
|
|
16
16
|
} from '../../internal/EntityFieldTransformationUtils';
|
|
17
17
|
import { computeIfAbsent, mapMap } from '../collections/maps';
|
|
18
18
|
|
|
19
|
-
export default class StubDatabaseAdapter<
|
|
19
|
+
export default class StubDatabaseAdapter<
|
|
20
|
+
T extends Record<string, any>,
|
|
21
|
+
> extends EntityDatabaseAdapter<T> {
|
|
20
22
|
constructor(
|
|
21
23
|
private readonly entityConfiguration2: EntityConfiguration<T>,
|
|
22
|
-
private readonly dataStore: Map<string, Readonly<{ [key: string]: any }>[]
|
|
24
|
+
private readonly dataStore: Map<string, Readonly<{ [key: string]: any }>[]>,
|
|
23
25
|
) {
|
|
24
26
|
super(entityConfiguration2);
|
|
25
27
|
}
|
|
26
28
|
|
|
27
|
-
public static convertFieldObjectsToDataStore<T
|
|
29
|
+
public static convertFieldObjectsToDataStore<T extends Record<string, any>>(
|
|
28
30
|
entityConfiguration: EntityConfiguration<T>,
|
|
29
|
-
dataStore: Map<string, Readonly<T>[]
|
|
31
|
+
dataStore: Map<string, Readonly<T>[]>,
|
|
30
32
|
): Map<string, Readonly<{ [key: string]: any }>[]> {
|
|
31
33
|
return mapMap(dataStore, (objectsForTable) =>
|
|
32
34
|
objectsForTable.map((objectForTable) =>
|
|
33
|
-
transformFieldsToDatabaseObject(entityConfiguration, new Map(), objectForTable)
|
|
34
|
-
)
|
|
35
|
+
transformFieldsToDatabaseObject(entityConfiguration, new Map(), objectForTable),
|
|
36
|
+
),
|
|
35
37
|
);
|
|
36
38
|
}
|
|
37
39
|
|
|
@@ -47,16 +49,19 @@ export default class StubDatabaseAdapter<T> extends EntityDatabaseAdapter<T> {
|
|
|
47
49
|
_queryInterface: any,
|
|
48
50
|
tableName: string,
|
|
49
51
|
tableField: string,
|
|
50
|
-
tableValues: readonly any[]
|
|
52
|
+
tableValues: readonly any[],
|
|
51
53
|
): Promise<object[]> {
|
|
52
54
|
const objectCollection = this.getObjectCollectionForTable(tableName);
|
|
53
|
-
return tableValues.reduce(
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
55
|
+
return tableValues.reduce(
|
|
56
|
+
(acc, fieldValue) => {
|
|
57
|
+
return acc.concat(
|
|
58
|
+
objectCollection.filter((obj) => {
|
|
59
|
+
return obj[tableField] === fieldValue;
|
|
60
|
+
}),
|
|
61
|
+
);
|
|
62
|
+
},
|
|
63
|
+
[] as { [key: string]: any },
|
|
64
|
+
);
|
|
60
65
|
}
|
|
61
66
|
|
|
62
67
|
private static compareByOrderBys(
|
|
@@ -65,7 +70,7 @@ export default class StubDatabaseAdapter<T> extends EntityDatabaseAdapter<T> {
|
|
|
65
70
|
order: OrderByOrdering;
|
|
66
71
|
}[],
|
|
67
72
|
objectA: { [key: string]: any },
|
|
68
|
-
objectB: { [key: string]: any }
|
|
73
|
+
objectB: { [key: string]: any },
|
|
69
74
|
): 0 | 1 | -1 {
|
|
70
75
|
if (orderBys.length === 0) {
|
|
71
76
|
return 0;
|
|
@@ -88,8 +93,8 @@ export default class StubDatabaseAdapter<T> extends EntityDatabaseAdapter<T> {
|
|
|
88
93
|
return aField > bField
|
|
89
94
|
? -1
|
|
90
95
|
: aField < bField
|
|
91
|
-
|
|
92
|
-
|
|
96
|
+
? 1
|
|
97
|
+
: this.compareByOrderBys(orderBys.slice(1), objectA, objectB);
|
|
93
98
|
}
|
|
94
99
|
case OrderByOrdering.ASCENDING: {
|
|
95
100
|
// simulate NULLS LAST for ASC
|
|
@@ -104,8 +109,8 @@ export default class StubDatabaseAdapter<T> extends EntityDatabaseAdapter<T> {
|
|
|
104
109
|
return bField > aField
|
|
105
110
|
? -1
|
|
106
111
|
: bField < aField
|
|
107
|
-
|
|
108
|
-
|
|
112
|
+
? 1
|
|
113
|
+
: this.compareByOrderBys(orderBys.slice(1), objectA, objectB);
|
|
109
114
|
}
|
|
110
115
|
}
|
|
111
116
|
}
|
|
@@ -115,7 +120,7 @@ export default class StubDatabaseAdapter<T> extends EntityDatabaseAdapter<T> {
|
|
|
115
120
|
tableName: string,
|
|
116
121
|
tableFieldSingleValueEqualityOperands: TableFieldSingleValueEqualityCondition[],
|
|
117
122
|
tableFieldMultiValueEqualityOperands: TableFieldMultiValueEqualityCondition[],
|
|
118
|
-
querySelectionModifiers: TableQuerySelectionModifiers
|
|
123
|
+
querySelectionModifiers: TableQuerySelectionModifiers,
|
|
119
124
|
): Promise<object[]> {
|
|
120
125
|
let filteredObjects = this.getObjectCollectionForTable(tableName);
|
|
121
126
|
for (const { tableField, tableValue } of tableFieldSingleValueEqualityOperands) {
|
|
@@ -129,7 +134,7 @@ export default class StubDatabaseAdapter<T> extends EntityDatabaseAdapter<T> {
|
|
|
129
134
|
const orderBy = querySelectionModifiers.orderBy;
|
|
130
135
|
if (orderBy !== undefined) {
|
|
131
136
|
filteredObjects = filteredObjects.sort((a, b) =>
|
|
132
|
-
StubDatabaseAdapter.compareByOrderBys(orderBy, a, b)
|
|
137
|
+
StubDatabaseAdapter.compareByOrderBys(orderBy, a, b),
|
|
133
138
|
);
|
|
134
139
|
}
|
|
135
140
|
|
|
@@ -151,7 +156,7 @@ export default class StubDatabaseAdapter<T> extends EntityDatabaseAdapter<T> {
|
|
|
151
156
|
_tableName: string,
|
|
152
157
|
_rawWhereClause: string,
|
|
153
158
|
_bindings: object | any[],
|
|
154
|
-
_querySelectionModifiers: TableQuerySelectionModifiers
|
|
159
|
+
_querySelectionModifiers: TableQuerySelectionModifiers,
|
|
155
160
|
): Promise<object[]> {
|
|
156
161
|
throw new Error('Raw WHERE clauses not supported for StubDatabaseAdapter');
|
|
157
162
|
}
|
|
@@ -160,15 +165,15 @@ export default class StubDatabaseAdapter<T> extends EntityDatabaseAdapter<T> {
|
|
|
160
165
|
const idSchemaField = this.entityConfiguration2.schema.get(this.entityConfiguration2.idField);
|
|
161
166
|
invariant(
|
|
162
167
|
idSchemaField,
|
|
163
|
-
`No schema field found for ${String(this.entityConfiguration2.idField)}
|
|
168
|
+
`No schema field found for ${String(this.entityConfiguration2.idField)}`,
|
|
164
169
|
);
|
|
165
170
|
if (idSchemaField instanceof StringField) {
|
|
166
|
-
return
|
|
171
|
+
return uuidv7();
|
|
167
172
|
} else if (idSchemaField instanceof IntField) {
|
|
168
173
|
return Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
|
|
169
174
|
} else {
|
|
170
175
|
throw new Error(
|
|
171
|
-
`Unsupported ID type for StubDatabaseAdapter: ${idSchemaField.constructor.name}
|
|
176
|
+
`Unsupported ID type for StubDatabaseAdapter: ${idSchemaField.constructor.name}`,
|
|
172
177
|
);
|
|
173
178
|
}
|
|
174
179
|
}
|
|
@@ -176,13 +181,13 @@ export default class StubDatabaseAdapter<T> extends EntityDatabaseAdapter<T> {
|
|
|
176
181
|
protected async insertInternalAsync(
|
|
177
182
|
_queryInterface: any,
|
|
178
183
|
tableName: string,
|
|
179
|
-
object: object
|
|
184
|
+
object: object,
|
|
180
185
|
): Promise<object[]> {
|
|
181
186
|
const objectCollection = this.getObjectCollectionForTable(tableName);
|
|
182
187
|
|
|
183
188
|
const idField = getDatabaseFieldForEntityField(
|
|
184
189
|
this.entityConfiguration2,
|
|
185
|
-
this.entityConfiguration2.idField
|
|
190
|
+
this.entityConfiguration2.idField,
|
|
186
191
|
);
|
|
187
192
|
const objectToInsert = {
|
|
188
193
|
[idField]: this.generateRandomID(),
|
|
@@ -197,7 +202,7 @@ export default class StubDatabaseAdapter<T> extends EntityDatabaseAdapter<T> {
|
|
|
197
202
|
tableName: string,
|
|
198
203
|
tableIdField: string,
|
|
199
204
|
id: any,
|
|
200
|
-
object: object
|
|
205
|
+
object: object,
|
|
201
206
|
): Promise<object[]> {
|
|
202
207
|
// SQL does not support empty updates, mirror behavior here for better test simulation
|
|
203
208
|
if (Object.keys(object).length === 0) {
|
|
@@ -221,7 +226,7 @@ export default class StubDatabaseAdapter<T> extends EntityDatabaseAdapter<T> {
|
|
|
221
226
|
_queryInterface: any,
|
|
222
227
|
tableName: string,
|
|
223
228
|
tableIdField: string,
|
|
224
|
-
id: any
|
|
229
|
+
id: any,
|
|
225
230
|
): Promise<number> {
|
|
226
231
|
const objectCollection = this.getObjectCollectionForTable(tableName);
|
|
227
232
|
|
|
@@ -6,8 +6,8 @@ import IEntityDatabaseAdapterProvider from '../../IEntityDatabaseAdapterProvider
|
|
|
6
6
|
export default class StubDatabaseAdapterProvider implements IEntityDatabaseAdapterProvider {
|
|
7
7
|
private readonly objectCollection = new Map();
|
|
8
8
|
|
|
9
|
-
getDatabaseAdapter<TFields
|
|
10
|
-
entityConfiguration: EntityConfiguration<TFields
|
|
9
|
+
getDatabaseAdapter<TFields extends Record<string, any>>(
|
|
10
|
+
entityConfiguration: EntityConfiguration<TFields>,
|
|
11
11
|
): EntityDatabaseAdapter<TFields> {
|
|
12
12
|
return new StubDatabaseAdapter(entityConfiguration, this.objectCollection);
|
|
13
13
|
}
|
|
@@ -7,13 +7,13 @@ export class StubQueryContextProvider extends EntityQueryContextProvider {
|
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
protected createTransactionRunner<T>(
|
|
10
|
-
_transactionConfig?: TransactionConfig
|
|
10
|
+
_transactionConfig?: TransactionConfig,
|
|
11
11
|
): (transactionScope: (queryInterface: any) => Promise<T>) => Promise<T> {
|
|
12
12
|
return (transactionScope) => Promise.resolve(transactionScope({}));
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
protected createNestedTransactionRunner<T>(
|
|
16
|
-
_outerQueryInterface: any
|
|
16
|
+
_outerQueryInterface: any,
|
|
17
17
|
): (transactionScope: (queryInterface: any) => Promise<T>) => Promise<T> {
|
|
18
18
|
return (transactionScope) => Promise.resolve(transactionScope({}));
|
|
19
19
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { anything, instance, mock } from 'ts-mockito';
|
|
2
|
+
|
|
3
|
+
import { EntityPrivacyPolicyEvaluationContext } from '../../../EntityPrivacyPolicy';
|
|
4
|
+
import { EntityQueryContext } from '../../../EntityQueryContext';
|
|
5
|
+
import ViewerContext from '../../../ViewerContext';
|
|
6
|
+
import AlwaysAllowPrivacyPolicyRule from '../../../rules/AlwaysAllowPrivacyPolicyRule';
|
|
7
|
+
import AlwaysDenyPrivacyPolicyRule from '../../../rules/AlwaysDenyPrivacyPolicyRule';
|
|
8
|
+
import { describePrivacyPolicyRuleWithAsyncTestCase } from '../PrivacyPolicyRuleTestUtils';
|
|
9
|
+
|
|
10
|
+
describe(describePrivacyPolicyRuleWithAsyncTestCase, () => {
|
|
11
|
+
describe('default args do not execute', () => {
|
|
12
|
+
describePrivacyPolicyRuleWithAsyncTestCase(new AlwaysAllowPrivacyPolicyRule(), {
|
|
13
|
+
allowCases: new Map([
|
|
14
|
+
[
|
|
15
|
+
'case',
|
|
16
|
+
async () => ({
|
|
17
|
+
viewerContext: instance(mock(ViewerContext)),
|
|
18
|
+
queryContext: instance(mock(EntityQueryContext)),
|
|
19
|
+
evaluationContext:
|
|
20
|
+
instance(mock<EntityPrivacyPolicyEvaluationContext<any, any, any, any, any>>()),
|
|
21
|
+
entity: anything(),
|
|
22
|
+
}),
|
|
23
|
+
],
|
|
24
|
+
]),
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
describePrivacyPolicyRuleWithAsyncTestCase(new AlwaysDenyPrivacyPolicyRule(), {
|
|
28
|
+
denyCases: new Map([
|
|
29
|
+
[
|
|
30
|
+
'case',
|
|
31
|
+
async () => ({
|
|
32
|
+
viewerContext: instance(mock(ViewerContext)),
|
|
33
|
+
queryContext: instance(mock(EntityQueryContext)),
|
|
34
|
+
evaluationContext:
|
|
35
|
+
instance(mock<EntityPrivacyPolicyEvaluationContext<any, any, any, any, any>>()),
|
|
36
|
+
entity: anything(),
|
|
37
|
+
}),
|
|
38
|
+
],
|
|
39
|
+
]),
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
});
|