@expo/entity 0.38.0 → 0.40.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/AuthorizationResultBasedEntityAssociationLoader.d.ts +99 -0
- package/build/AuthorizationResultBasedEntityAssociationLoader.js +124 -0
- package/build/AuthorizationResultBasedEntityAssociationLoader.js.map +1 -0
- package/build/AuthorizationResultBasedEntityLoader.d.ts +1 -1
- package/build/AuthorizationResultBasedEntityLoader.js.map +1 -1
- package/build/{EntityMutator.d.ts → AuthorizationResultBasedEntityMutator.d.ts} +5 -17
- package/build/{EntityMutator.js → AuthorizationResultBasedEntityMutator.js} +22 -48
- package/build/AuthorizationResultBasedEntityMutator.js.map +1 -0
- package/build/EnforcingEntityAssociationLoader.d.ts +79 -0
- package/build/EnforcingEntityAssociationLoader.js +62 -0
- package/build/EnforcingEntityAssociationLoader.js.map +1 -0
- package/build/EnforcingEntityCreator.d.ts +24 -0
- package/build/EnforcingEntityCreator.js +32 -0
- package/build/EnforcingEntityCreator.js.map +1 -0
- package/build/EnforcingEntityDeleter.d.ts +17 -0
- package/build/EnforcingEntityDeleter.js +22 -0
- package/build/EnforcingEntityDeleter.js.map +1 -0
- package/build/EnforcingEntityUpdater.d.ts +24 -0
- package/build/EnforcingEntityUpdater.js +32 -0
- package/build/EnforcingEntityUpdater.js.map +1 -0
- package/build/Entity.d.ts +8 -12
- package/build/Entity.js +9 -34
- package/build/Entity.js.map +1 -1
- package/build/EntityAssociationLoader.d.ts +12 -91
- package/build/EntityAssociationLoader.js +20 -126
- package/build/EntityAssociationLoader.js.map +1 -1
- package/build/EntityCompanionProvider.d.ts +2 -2
- package/build/EntityCompanionProvider.js.map +1 -1
- package/build/EntityCreator.d.ts +27 -0
- package/build/EntityCreator.js +39 -0
- package/build/EntityCreator.js.map +1 -0
- package/build/EntityDatabaseAdapter.js +2 -2
- package/build/EntityDatabaseAdapter.js.map +1 -1
- package/build/EntityDeleter.d.ts +27 -0
- package/build/EntityDeleter.js +40 -0
- package/build/EntityDeleter.js.map +1 -0
- package/build/EntityLoader.d.ts +4 -14
- package/build/EntityLoader.js +7 -20
- package/build/EntityLoader.js.map +1 -1
- package/build/EntityLoaderFactory.d.ts +2 -2
- package/build/EntityLoaderFactory.js +4 -2
- package/build/EntityLoaderFactory.js.map +1 -1
- package/build/EntityMutatorFactory.d.ts +4 -4
- package/build/EntityMutatorFactory.js +4 -4
- package/build/EntityMutatorFactory.js.map +1 -1
- package/build/EntitySecondaryCacheLoader.d.ts +3 -3
- package/build/EntitySecondaryCacheLoader.js +1 -3
- package/build/EntitySecondaryCacheLoader.js.map +1 -1
- package/build/EntityUpdater.d.ts +27 -0
- package/build/EntityUpdater.js +40 -0
- package/build/EntityUpdater.js.map +1 -0
- package/build/ReadonlyEntity.d.ts +2 -2
- package/build/ReadonlyEntity.js +4 -6
- package/build/ReadonlyEntity.js.map +1 -1
- package/build/ViewerScopedEntityLoaderFactory.d.ts +2 -2
- package/build/ViewerScopedEntityLoaderFactory.js.map +1 -1
- package/build/ViewerScopedEntityMutatorFactory.d.ts +4 -4
- package/build/ViewerScopedEntityMutatorFactory.js.map +1 -1
- package/build/__tests__/AuthorizationResultBasedEntityAssociationLoader-test.d.ts +1 -0
- package/build/__tests__/AuthorizationResultBasedEntityAssociationLoader-test.js +273 -0
- package/build/__tests__/AuthorizationResultBasedEntityAssociationLoader-test.js.map +1 -0
- package/build/__tests__/{EntityLoader-constructor-test.js → AuthorizationResultBasedEntityLoader-constructor-test.js} +11 -11
- package/build/__tests__/AuthorizationResultBasedEntityLoader-constructor-test.js.map +1 -0
- package/build/__tests__/AuthorizationResultBasedEntityLoader-test.d.ts +1 -0
- package/build/__tests__/AuthorizationResultBasedEntityLoader-test.js +401 -0
- package/build/__tests__/AuthorizationResultBasedEntityLoader-test.js.map +1 -0
- package/build/__tests__/EnforcingEntityAssociationLoader-test.d.ts +1 -0
- package/build/__tests__/EnforcingEntityAssociationLoader-test.js +115 -0
- package/build/__tests__/EnforcingEntityAssociationLoader-test.js.map +1 -0
- package/build/__tests__/Entity-test.js +23 -5
- package/build/__tests__/Entity-test.js.map +1 -1
- package/build/__tests__/EntityAssociationLoader-test.js +14 -184
- package/build/__tests__/EntityAssociationLoader-test.js.map +1 -1
- package/build/__tests__/EntityCommonUseCases-test.js +34 -12
- package/build/__tests__/EntityCommonUseCases-test.js.map +1 -1
- package/build/__tests__/EntityCompanion-test.js +17 -7
- package/build/__tests__/EntityCompanion-test.js.map +1 -1
- package/build/__tests__/EntityDatabaseAdapter-test.js.map +1 -1
- package/build/__tests__/EntityEdges-test.js +41 -23
- package/build/__tests__/EntityEdges-test.js.map +1 -1
- package/build/__tests__/EntityLoader-test.js +22 -386
- package/build/__tests__/EntityLoader-test.js.map +1 -1
- package/build/__tests__/EntityMutator-MutationCacheConsistency-test.js +4 -3
- package/build/__tests__/EntityMutator-MutationCacheConsistency-test.js.map +1 -1
- package/build/__tests__/EntityMutator-test.js +67 -70
- package/build/__tests__/EntityMutator-test.js.map +1 -1
- package/build/__tests__/EntityPrivacyPolicy-test.js +17 -7
- package/build/__tests__/EntityPrivacyPolicy-test.js.map +1 -1
- package/build/__tests__/EntitySecondaryCacheLoader-test.js +7 -7
- package/build/__tests__/EntitySecondaryCacheLoader-test.js.map +1 -1
- package/build/__tests__/EntitySelfReferentialEdges-test.js +36 -24
- package/build/__tests__/EntitySelfReferentialEdges-test.js.map +1 -1
- package/build/__tests__/ReadonlyEntity-test.js +1 -1
- package/build/__tests__/ReadonlyEntity-test.js.map +1 -1
- package/build/__tests__/cases/TwoEntitySameTableDisjointRows-test.js +4 -2
- package/build/__tests__/cases/TwoEntitySameTableDisjointRows-test.js.map +1 -1
- package/build/__tests__/cases/TwoEntitySameTableOverlappingRows-test.js +7 -4
- package/build/__tests__/cases/TwoEntitySameTableOverlappingRows-test.js.map +1 -1
- package/build/__tests__/entityUtils-test.js +8 -0
- package/build/__tests__/entityUtils-test.js.map +1 -1
- package/build/entityUtils.d.ts +7 -0
- package/build/entityUtils.js +20 -10
- package/build/entityUtils.js.map +1 -1
- package/build/errors/EntityCacheAdapterError.js +17 -7
- package/build/errors/EntityCacheAdapterError.js.map +1 -1
- package/build/errors/EntityDatabaseAdapterError.js +17 -7
- package/build/errors/EntityDatabaseAdapterError.js.map +1 -1
- package/build/errors/EntityInvalidFieldValueError.js +17 -7
- package/build/errors/EntityInvalidFieldValueError.js.map +1 -1
- package/build/errors/EntityNotAuthorizedError.js +17 -7
- package/build/errors/EntityNotAuthorizedError.js.map +1 -1
- package/build/errors/EntityNotFoundError.js +17 -7
- package/build/errors/EntityNotFoundError.js.map +1 -1
- package/build/index.d.ts +19 -11
- package/build/index.js +24 -7
- package/build/index.js.map +1 -1
- package/build/internal/EntityFieldTransformationUtils.js.map +1 -1
- package/build/internal/__tests__/EntityDataManager-test.js +42 -32
- package/build/internal/__tests__/EntityDataManager-test.js.map +1 -1
- package/build/internal/__tests__/ReadThroughEntityCache-test.js +17 -7
- package/build/internal/__tests__/ReadThroughEntityCache-test.js.map +1 -1
- package/build/rules/AlwaysAllowPrivacyPolicyRule.js +17 -7
- package/build/rules/AlwaysAllowPrivacyPolicyRule.js.map +1 -1
- package/build/rules/AlwaysDenyPrivacyPolicyRule.js +17 -7
- package/build/rules/AlwaysDenyPrivacyPolicyRule.js.map +1 -1
- package/build/rules/AlwaysSkipPrivacyPolicyRule.js +17 -7
- package/build/rules/AlwaysSkipPrivacyPolicyRule.js.map +1 -1
- package/build/utils/EntityPrivacyUtils.d.ts +32 -4
- package/build/utils/EntityPrivacyUtils.js +68 -24
- package/build/utils/EntityPrivacyUtils.js.map +1 -1
- package/build/utils/__tests__/EntityPrivacyUtils-test.js +148 -23
- package/build/utils/__tests__/EntityPrivacyUtils-test.js.map +1 -1
- package/build/utils/__tests__/canViewerDeleteAsync-edgeDeletionPermissionInferenceBehavior-test.js +8 -5
- package/build/utils/__tests__/canViewerDeleteAsync-edgeDeletionPermissionInferenceBehavior-test.js.map +1 -1
- package/build/utils/collections/__tests__/maps-test.js +1 -1
- package/build/utils/collections/__tests__/maps-test.js.map +1 -1
- package/build/utils/collections/maps.js +2 -2
- package/build/utils/collections/maps.js.map +1 -1
- package/build/utils/mergeEntityMutationTriggerConfigurations.js +1 -2
- package/build/utils/mergeEntityMutationTriggerConfigurations.js.map +1 -1
- package/build/utils/testing/PrivacyPolicyRuleTestUtils.js +1 -1
- package/build/utils/testing/PrivacyPolicyRuleTestUtils.js.map +1 -1
- package/build/utils/testing/StubDatabaseAdapter.js +17 -7
- package/build/utils/testing/StubDatabaseAdapter.js.map +1 -1
- package/build/utils/testing/StubQueryContextProvider.d.ts +1 -3
- package/build/utils/testing/StubQueryContextProvider.js +1 -3
- package/build/utils/testing/StubQueryContextProvider.js.map +1 -1
- package/build/utils/testing/createUnitTestEntityCompanionProvider.js +2 -1
- package/build/utils/testing/createUnitTestEntityCompanionProvider.js.map +1 -1
- package/build/utils/testing/describeFieldTestCase.js +1 -1
- package/build/utils/testing/describeFieldTestCase.js.map +1 -1
- package/package.json +19 -3
- package/src/AuthorizationResultBasedEntityAssociationLoader.ts +492 -0
- package/src/AuthorizationResultBasedEntityLoader.ts +2 -2
- package/src/{EntityMutator.ts → AuthorizationResultBasedEntityMutator.ts} +62 -58
- package/src/EnforcingEntityAssociationLoader.ts +390 -0
- package/src/EnforcingEntityCreator.ts +55 -0
- package/src/EnforcingEntityDeleter.ts +44 -0
- package/src/EnforcingEntityUpdater.ts +55 -0
- package/src/Entity.ts +20 -65
- package/src/EntityAssociationLoader.ts +38 -495
- package/src/EntityCompanionProvider.ts +5 -2
- package/src/EntityCreator.ts +73 -0
- package/src/EntityDeleter.ts +73 -0
- package/src/EntityLoader.ts +10 -49
- package/src/EntityLoaderFactory.ts +20 -3
- package/src/EntityMutatorFactory.ts +32 -7
- package/src/EntitySecondaryCacheLoader.ts +5 -7
- package/src/EntityUpdater.ts +73 -0
- package/src/ReadonlyEntity.ts +14 -13
- package/src/ViewerScopedEntityLoaderFactory.ts +9 -2
- package/src/ViewerScopedEntityMutatorFactory.ts +29 -4
- package/src/__tests__/AuthorizationResultBasedEntityAssociationLoader-test.ts +354 -0
- package/src/__tests__/{EntityLoader-constructor-test.ts → AuthorizationResultBasedEntityLoader-constructor-test.ts} +17 -10
- package/src/__tests__/AuthorizationResultBasedEntityLoader-test.ts +730 -0
- package/src/__tests__/EnforcingEntityAssociationLoader-test.ts +253 -0
- package/src/__tests__/Entity-test.ts +24 -5
- package/src/__tests__/EntityAssociationLoader-test.ts +16 -259
- package/src/__tests__/EntityCommonUseCases-test.ts +20 -8
- package/src/__tests__/EntityCompanion-test.ts +1 -1
- package/src/__tests__/EntityDatabaseAdapter-test.ts +6 -6
- package/src/__tests__/EntityEdges-test.ts +24 -16
- package/src/__tests__/EntityLoader-test.ts +25 -675
- package/src/__tests__/EntityMutator-MutationCacheConsistency-test.ts +4 -3
- package/src/__tests__/EntityMutator-test.ts +116 -103
- package/src/__tests__/EntitySecondaryCacheLoader-test.ts +7 -7
- package/src/__tests__/EntitySelfReferentialEdges-test.ts +36 -24
- package/src/__tests__/ReadonlyEntity-test.ts +1 -1
- package/src/__tests__/cases/TwoEntitySameTableDisjointRows-test.ts +4 -2
- package/src/__tests__/cases/TwoEntitySameTableOverlappingRows-test.ts +7 -4
- package/src/__tests__/entityUtils-test.ts +12 -0
- package/src/entityUtils.ts +24 -9
- package/src/index.ts +19 -11
- package/src/internal/EntityFieldTransformationUtils.ts +2 -2
- package/src/internal/__tests__/EntityDataManager-test.ts +29 -29
- package/src/utils/EntityPrivacyUtils.ts +188 -107
- package/src/utils/__tests__/EntityPrivacyUtils-test.ts +169 -29
- package/src/utils/__tests__/canViewerDeleteAsync-edgeDeletionPermissionInferenceBehavior-test.ts +8 -5
- package/src/utils/collections/__tests__/maps-test.ts +1 -1
- package/src/utils/testing/PrivacyPolicyRuleTestUtils.ts +1 -1
- package/src/utils/testing/StubDatabaseAdapter.ts +1 -1
- package/src/utils/testing/StubQueryContextProvider.ts +1 -3
- package/src/utils/testing/createUnitTestEntityCompanionProvider.ts +3 -1
- package/build/EntityMutator.js.map +0 -1
- package/build/__tests__/EntityLoader-constructor-test.js.map +0 -1
- /package/build/__tests__/{EntityLoader-constructor-test.d.ts → AuthorizationResultBasedEntityLoader-constructor-test.d.ts} +0 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { AuthorizationResultBasedDeleteMutator } from './AuthorizationResultBasedEntityMutator';
|
|
2
|
+
import EnforcingEntityDeleter from './EnforcingEntityDeleter';
|
|
3
|
+
import { IEntityClass } from './Entity';
|
|
4
|
+
import EntityPrivacyPolicy from './EntityPrivacyPolicy';
|
|
5
|
+
import { EntityQueryContext } from './EntityQueryContext';
|
|
6
|
+
import ReadonlyEntity from './ReadonlyEntity';
|
|
7
|
+
import ViewerContext from './ViewerContext';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The primary interface for deleting entities.
|
|
11
|
+
*/
|
|
12
|
+
export default class EntityDeleter<
|
|
13
|
+
TFields extends object,
|
|
14
|
+
TID extends NonNullable<TFields[TSelectedFields]>,
|
|
15
|
+
TViewerContext extends ViewerContext,
|
|
16
|
+
TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>,
|
|
17
|
+
TPrivacyPolicy extends EntityPrivacyPolicy<
|
|
18
|
+
TFields,
|
|
19
|
+
TID,
|
|
20
|
+
TViewerContext,
|
|
21
|
+
TEntity,
|
|
22
|
+
TSelectedFields
|
|
23
|
+
>,
|
|
24
|
+
TSelectedFields extends keyof TFields,
|
|
25
|
+
> {
|
|
26
|
+
constructor(
|
|
27
|
+
private readonly existingEntity: TEntity,
|
|
28
|
+
private readonly queryContext: EntityQueryContext,
|
|
29
|
+
private readonly entityClass: IEntityClass<
|
|
30
|
+
TFields,
|
|
31
|
+
TID,
|
|
32
|
+
TViewerContext,
|
|
33
|
+
TEntity,
|
|
34
|
+
TPrivacyPolicy,
|
|
35
|
+
TSelectedFields
|
|
36
|
+
>,
|
|
37
|
+
) {}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Enforcing entity deleter. All deletes through this deleter are
|
|
41
|
+
* guaranteed to be successful and will throw otherwise.
|
|
42
|
+
*/
|
|
43
|
+
enforcing(): EnforcingEntityDeleter<
|
|
44
|
+
TFields,
|
|
45
|
+
TID,
|
|
46
|
+
TViewerContext,
|
|
47
|
+
TEntity,
|
|
48
|
+
TPrivacyPolicy,
|
|
49
|
+
TSelectedFields
|
|
50
|
+
> {
|
|
51
|
+
return new EnforcingEntityDeleter(this.withAuthorizationResults());
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Authorization-result-based entity deleter. All deletes through this
|
|
56
|
+
* deleter are results, where an unsuccessful result means an authorization
|
|
57
|
+
* error or entity construction error occurred. Other errors are thrown.
|
|
58
|
+
*/
|
|
59
|
+
withAuthorizationResults(): AuthorizationResultBasedDeleteMutator<
|
|
60
|
+
TFields,
|
|
61
|
+
TID,
|
|
62
|
+
TViewerContext,
|
|
63
|
+
TEntity,
|
|
64
|
+
TPrivacyPolicy,
|
|
65
|
+
TSelectedFields
|
|
66
|
+
> {
|
|
67
|
+
return this.existingEntity
|
|
68
|
+
.getViewerContext()
|
|
69
|
+
.getViewerScopedEntityCompanionForClass(this.entityClass)
|
|
70
|
+
.getMutatorFactory()
|
|
71
|
+
.forDelete(this.existingEntity, this.queryContext);
|
|
72
|
+
}
|
|
73
|
+
}
|
package/src/EntityLoader.ts
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
import AuthorizationResultBasedEntityLoader from './AuthorizationResultBasedEntityLoader';
|
|
2
2
|
import EnforcingEntityLoader from './EnforcingEntityLoader';
|
|
3
3
|
import { IEntityClass } from './Entity';
|
|
4
|
-
import EntityConfiguration from './EntityConfiguration';
|
|
5
4
|
import EntityLoaderUtils from './EntityLoaderUtils';
|
|
6
|
-
import EntityPrivacyPolicy
|
|
5
|
+
import EntityPrivacyPolicy from './EntityPrivacyPolicy';
|
|
7
6
|
import { EntityQueryContext } from './EntityQueryContext';
|
|
8
7
|
import ReadonlyEntity from './ReadonlyEntity';
|
|
9
8
|
import ViewerContext from './ViewerContext';
|
|
10
|
-
import EntityDataManager from './internal/EntityDataManager';
|
|
11
|
-
import IEntityMetricsAdapter from './metrics/IEntityMetricsAdapter';
|
|
12
9
|
|
|
13
10
|
/**
|
|
14
11
|
* The primary interface for loading entities. All normal loads are batched,
|
|
@@ -18,6 +15,7 @@ export default class EntityLoader<
|
|
|
18
15
|
TFields extends object,
|
|
19
16
|
TID extends NonNullable<TFields[TSelectedFields]>,
|
|
20
17
|
TViewerContext extends ViewerContext,
|
|
18
|
+
TViewerContext2 extends TViewerContext,
|
|
21
19
|
TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>,
|
|
22
20
|
TPrivacyPolicy extends EntityPrivacyPolicy<
|
|
23
21
|
TFields,
|
|
@@ -28,26 +26,9 @@ export default class EntityLoader<
|
|
|
28
26
|
>,
|
|
29
27
|
TSelectedFields extends keyof TFields,
|
|
30
28
|
> {
|
|
31
|
-
private readonly utilsPrivate: EntityLoaderUtils<
|
|
32
|
-
TFields,
|
|
33
|
-
TID,
|
|
34
|
-
TViewerContext,
|
|
35
|
-
TEntity,
|
|
36
|
-
TPrivacyPolicy,
|
|
37
|
-
TSelectedFields
|
|
38
|
-
>;
|
|
39
|
-
|
|
40
29
|
constructor(
|
|
41
|
-
private readonly viewerContext:
|
|
30
|
+
private readonly viewerContext: TViewerContext2,
|
|
42
31
|
private readonly queryContext: EntityQueryContext,
|
|
43
|
-
private readonly privacyPolicyEvaluationContext: EntityPrivacyPolicyEvaluationContext<
|
|
44
|
-
TFields,
|
|
45
|
-
TID,
|
|
46
|
-
TViewerContext,
|
|
47
|
-
TEntity,
|
|
48
|
-
TSelectedFields
|
|
49
|
-
>,
|
|
50
|
-
private readonly entityConfiguration: EntityConfiguration<TFields>,
|
|
51
32
|
private readonly entityClass: IEntityClass<
|
|
52
33
|
TFields,
|
|
53
34
|
TID,
|
|
@@ -56,23 +37,7 @@ export default class EntityLoader<
|
|
|
56
37
|
TPrivacyPolicy,
|
|
57
38
|
TSelectedFields
|
|
58
39
|
>,
|
|
59
|
-
|
|
60
|
-
private readonly privacyPolicy: TPrivacyPolicy,
|
|
61
|
-
private readonly dataManager: EntityDataManager<TFields>,
|
|
62
|
-
protected readonly metricsAdapter: IEntityMetricsAdapter,
|
|
63
|
-
) {
|
|
64
|
-
this.utilsPrivate = new EntityLoaderUtils(
|
|
65
|
-
this.viewerContext,
|
|
66
|
-
this.queryContext,
|
|
67
|
-
this.privacyPolicyEvaluationContext,
|
|
68
|
-
this.entityConfiguration,
|
|
69
|
-
this.entityClass,
|
|
70
|
-
this.entitySelectedFields,
|
|
71
|
-
this.privacyPolicy,
|
|
72
|
-
this.dataManager,
|
|
73
|
-
this.metricsAdapter,
|
|
74
|
-
);
|
|
75
|
-
}
|
|
40
|
+
) {}
|
|
76
41
|
|
|
77
42
|
/**
|
|
78
43
|
* Enforcing entity loader. All loads through this loader are
|
|
@@ -92,7 +57,7 @@ export default class EntityLoader<
|
|
|
92
57
|
|
|
93
58
|
/**
|
|
94
59
|
* Authorization-result-based entity loader. All loads through this
|
|
95
|
-
* loader are
|
|
60
|
+
* loader are results (or null for some loader methods), where an unsuccessful result
|
|
96
61
|
* means an authorization error or entity construction error occurred. Other errors are thrown.
|
|
97
62
|
*/
|
|
98
63
|
withAuthorizationResults(): AuthorizationResultBasedEntityLoader<
|
|
@@ -103,14 +68,10 @@ export default class EntityLoader<
|
|
|
103
68
|
TPrivacyPolicy,
|
|
104
69
|
TSelectedFields
|
|
105
70
|
> {
|
|
106
|
-
return
|
|
107
|
-
this.
|
|
108
|
-
|
|
109
|
-
this.
|
|
110
|
-
this.dataManager,
|
|
111
|
-
this.metricsAdapter,
|
|
112
|
-
this.utilsPrivate,
|
|
113
|
-
);
|
|
71
|
+
return this.viewerContext
|
|
72
|
+
.getViewerScopedEntityCompanionForClass(this.entityClass)
|
|
73
|
+
.getLoaderFactory()
|
|
74
|
+
.forLoad(this.queryContext, { previousValue: null, cascadingDeleteCause: null });
|
|
114
75
|
}
|
|
115
76
|
|
|
116
77
|
/**
|
|
@@ -125,6 +86,6 @@ export default class EntityLoader<
|
|
|
125
86
|
TPrivacyPolicy,
|
|
126
87
|
TSelectedFields
|
|
127
88
|
> {
|
|
128
|
-
return this.
|
|
89
|
+
return this.withAuthorizationResults().utils;
|
|
129
90
|
}
|
|
130
91
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import AuthorizationResultBasedEntityLoader from './AuthorizationResultBasedEntityLoader';
|
|
1
2
|
import EntityCompanion from './EntityCompanion';
|
|
2
|
-
import
|
|
3
|
+
import EntityLoaderUtils from './EntityLoaderUtils';
|
|
3
4
|
import EntityPrivacyPolicy, { EntityPrivacyPolicyEvaluationContext } from './EntityPrivacyPolicy';
|
|
4
5
|
import { EntityQueryContext } from './EntityQueryContext';
|
|
5
6
|
import ReadonlyEntity from './ReadonlyEntity';
|
|
@@ -52,8 +53,15 @@ export default class EntityLoaderFactory<
|
|
|
52
53
|
TEntity,
|
|
53
54
|
TSelectedFields
|
|
54
55
|
>,
|
|
55
|
-
):
|
|
56
|
-
|
|
56
|
+
): AuthorizationResultBasedEntityLoader<
|
|
57
|
+
TFields,
|
|
58
|
+
TID,
|
|
59
|
+
TViewerContext,
|
|
60
|
+
TEntity,
|
|
61
|
+
TPrivacyPolicy,
|
|
62
|
+
TSelectedFields
|
|
63
|
+
> {
|
|
64
|
+
const utils = new EntityLoaderUtils(
|
|
57
65
|
viewerContext,
|
|
58
66
|
queryContext,
|
|
59
67
|
privacyPolicyEvaluationContext,
|
|
@@ -64,5 +72,14 @@ export default class EntityLoaderFactory<
|
|
|
64
72
|
this.dataManager,
|
|
65
73
|
this.metricsAdapter,
|
|
66
74
|
);
|
|
75
|
+
|
|
76
|
+
return new AuthorizationResultBasedEntityLoader(
|
|
77
|
+
queryContext,
|
|
78
|
+
this.entityCompanion.entityCompanionDefinition.entityConfiguration,
|
|
79
|
+
this.entityCompanion.entityCompanionDefinition.entityClass,
|
|
80
|
+
this.dataManager,
|
|
81
|
+
this.metricsAdapter,
|
|
82
|
+
utils,
|
|
83
|
+
);
|
|
67
84
|
}
|
|
68
85
|
}
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AuthorizationResultBasedCreateMutator,
|
|
3
|
+
AuthorizationResultBasedUpdateMutator,
|
|
4
|
+
AuthorizationResultBasedDeleteMutator,
|
|
5
|
+
} from './AuthorizationResultBasedEntityMutator';
|
|
1
6
|
import Entity, { IEntityClass } from './Entity';
|
|
2
7
|
import EntityCompanionProvider from './EntityCompanionProvider';
|
|
3
8
|
import EntityConfiguration from './EntityConfiguration';
|
|
@@ -5,7 +10,6 @@ import EntityDatabaseAdapter from './EntityDatabaseAdapter';
|
|
|
5
10
|
import EntityLoaderFactory from './EntityLoaderFactory';
|
|
6
11
|
import EntityMutationTriggerConfiguration from './EntityMutationTriggerConfiguration';
|
|
7
12
|
import EntityMutationValidator from './EntityMutationValidator';
|
|
8
|
-
import { CreateMutator, UpdateMutator, DeleteMutator } from './EntityMutator';
|
|
9
13
|
import EntityPrivacyPolicy from './EntityPrivacyPolicy';
|
|
10
14
|
import { EntityQueryContext } from './EntityQueryContext';
|
|
11
15
|
import ViewerContext from './ViewerContext';
|
|
@@ -75,8 +79,15 @@ export default class EntityMutatorFactory<
|
|
|
75
79
|
forCreate(
|
|
76
80
|
viewerContext: TViewerContext,
|
|
77
81
|
queryContext: EntityQueryContext,
|
|
78
|
-
):
|
|
79
|
-
|
|
82
|
+
): AuthorizationResultBasedCreateMutator<
|
|
83
|
+
TFields,
|
|
84
|
+
TID,
|
|
85
|
+
TViewerContext,
|
|
86
|
+
TEntity,
|
|
87
|
+
TPrivacyPolicy,
|
|
88
|
+
TSelectedFields
|
|
89
|
+
> {
|
|
90
|
+
return new AuthorizationResultBasedCreateMutator(
|
|
80
91
|
this.entityCompanionProvider,
|
|
81
92
|
viewerContext,
|
|
82
93
|
queryContext,
|
|
@@ -100,8 +111,15 @@ export default class EntityMutatorFactory<
|
|
|
100
111
|
forUpdate(
|
|
101
112
|
existingEntity: TEntity,
|
|
102
113
|
queryContext: EntityQueryContext,
|
|
103
|
-
):
|
|
104
|
-
|
|
114
|
+
): AuthorizationResultBasedUpdateMutator<
|
|
115
|
+
TFields,
|
|
116
|
+
TID,
|
|
117
|
+
TViewerContext,
|
|
118
|
+
TEntity,
|
|
119
|
+
TPrivacyPolicy,
|
|
120
|
+
TSelectedFields
|
|
121
|
+
> {
|
|
122
|
+
return new AuthorizationResultBasedUpdateMutator(
|
|
105
123
|
this.entityCompanionProvider,
|
|
106
124
|
existingEntity.getViewerContext(),
|
|
107
125
|
queryContext,
|
|
@@ -125,8 +143,15 @@ export default class EntityMutatorFactory<
|
|
|
125
143
|
forDelete(
|
|
126
144
|
existingEntity: TEntity,
|
|
127
145
|
queryContext: EntityQueryContext,
|
|
128
|
-
):
|
|
129
|
-
|
|
146
|
+
): AuthorizationResultBasedDeleteMutator<
|
|
147
|
+
TFields,
|
|
148
|
+
TID,
|
|
149
|
+
TViewerContext,
|
|
150
|
+
TEntity,
|
|
151
|
+
TPrivacyPolicy,
|
|
152
|
+
TSelectedFields
|
|
153
|
+
> {
|
|
154
|
+
return new AuthorizationResultBasedDeleteMutator(
|
|
130
155
|
this.entityCompanionProvider,
|
|
131
156
|
existingEntity.getViewerContext(),
|
|
132
157
|
queryContext,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Result } from '@expo/results';
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import AuthorizationResultBasedEntityLoader from './AuthorizationResultBasedEntityLoader';
|
|
4
4
|
import EntityPrivacyPolicy from './EntityPrivacyPolicy';
|
|
5
5
|
import ReadonlyEntity from './ReadonlyEntity';
|
|
6
6
|
import ViewerContext from './ViewerContext';
|
|
@@ -60,7 +60,7 @@ export default abstract class EntitySecondaryCacheLoader<
|
|
|
60
60
|
> {
|
|
61
61
|
constructor(
|
|
62
62
|
private readonly secondaryEntityCache: ISecondaryEntityCache<TFields, TLoadParams>,
|
|
63
|
-
protected readonly entityLoader:
|
|
63
|
+
protected readonly entityLoader: AuthorizationResultBasedEntityLoader<
|
|
64
64
|
TFields,
|
|
65
65
|
TID,
|
|
66
66
|
TViewerContext,
|
|
@@ -84,11 +84,9 @@ export default abstract class EntitySecondaryCacheLoader<
|
|
|
84
84
|
);
|
|
85
85
|
|
|
86
86
|
// convert value to and from array to reuse complex code
|
|
87
|
-
const entitiesMap = await this.entityLoader
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
mapMap(loadParamsToFieldObjects, (fieldObject) => (fieldObject ? [fieldObject] : [])),
|
|
91
|
-
);
|
|
87
|
+
const entitiesMap = await this.entityLoader.utils.constructAndAuthorizeEntitiesAsync(
|
|
88
|
+
mapMap(loadParamsToFieldObjects, (fieldObject) => (fieldObject ? [fieldObject] : [])),
|
|
89
|
+
);
|
|
92
90
|
return mapMap(entitiesMap, (fieldObjects) => fieldObjects[0] ?? null);
|
|
93
91
|
}
|
|
94
92
|
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { AuthorizationResultBasedUpdateMutator } from './AuthorizationResultBasedEntityMutator';
|
|
2
|
+
import EnforcingEntityUpdater from './EnforcingEntityUpdater';
|
|
3
|
+
import { IEntityClass } from './Entity';
|
|
4
|
+
import EntityPrivacyPolicy from './EntityPrivacyPolicy';
|
|
5
|
+
import { EntityQueryContext } from './EntityQueryContext';
|
|
6
|
+
import ReadonlyEntity from './ReadonlyEntity';
|
|
7
|
+
import ViewerContext from './ViewerContext';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The primary interface for updating entities.
|
|
11
|
+
*/
|
|
12
|
+
export default class EntityUpdater<
|
|
13
|
+
TFields extends object,
|
|
14
|
+
TID extends NonNullable<TFields[TSelectedFields]>,
|
|
15
|
+
TViewerContext extends ViewerContext,
|
|
16
|
+
TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>,
|
|
17
|
+
TPrivacyPolicy extends EntityPrivacyPolicy<
|
|
18
|
+
TFields,
|
|
19
|
+
TID,
|
|
20
|
+
TViewerContext,
|
|
21
|
+
TEntity,
|
|
22
|
+
TSelectedFields
|
|
23
|
+
>,
|
|
24
|
+
TSelectedFields extends keyof TFields,
|
|
25
|
+
> {
|
|
26
|
+
constructor(
|
|
27
|
+
private readonly existingEntity: TEntity,
|
|
28
|
+
private readonly queryContext: EntityQueryContext,
|
|
29
|
+
private readonly entityClass: IEntityClass<
|
|
30
|
+
TFields,
|
|
31
|
+
TID,
|
|
32
|
+
TViewerContext,
|
|
33
|
+
TEntity,
|
|
34
|
+
TPrivacyPolicy,
|
|
35
|
+
TSelectedFields
|
|
36
|
+
>,
|
|
37
|
+
) {}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Enforcing entity updater. All updates through this updater are
|
|
41
|
+
* guaranteed to be successful and will throw otherwise.
|
|
42
|
+
*/
|
|
43
|
+
enforcing(): EnforcingEntityUpdater<
|
|
44
|
+
TFields,
|
|
45
|
+
TID,
|
|
46
|
+
TViewerContext,
|
|
47
|
+
TEntity,
|
|
48
|
+
TPrivacyPolicy,
|
|
49
|
+
TSelectedFields
|
|
50
|
+
> {
|
|
51
|
+
return new EnforcingEntityUpdater(this.withAuthorizationResults());
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Authorization-result-based entity updater. All updates through this
|
|
56
|
+
* updater are results, where an unsuccessful result means an authorization
|
|
57
|
+
* error or entity construction error occurred. Other errors are thrown.
|
|
58
|
+
*/
|
|
59
|
+
withAuthorizationResults(): AuthorizationResultBasedUpdateMutator<
|
|
60
|
+
TFields,
|
|
61
|
+
TID,
|
|
62
|
+
TViewerContext,
|
|
63
|
+
TEntity,
|
|
64
|
+
TPrivacyPolicy,
|
|
65
|
+
TSelectedFields
|
|
66
|
+
> {
|
|
67
|
+
return this.existingEntity
|
|
68
|
+
.getViewerContext()
|
|
69
|
+
.getViewerScopedEntityCompanionForClass(this.entityClass)
|
|
70
|
+
.getMutatorFactory()
|
|
71
|
+
.forUpdate(this.existingEntity, this.queryContext);
|
|
72
|
+
}
|
|
73
|
+
}
|
package/src/ReadonlyEntity.ts
CHANGED
|
@@ -84,14 +84,10 @@ export default abstract class ReadonlyEntity<
|
|
|
84
84
|
/**
|
|
85
85
|
* @returns EntityAssociationLoader for this entity
|
|
86
86
|
*/
|
|
87
|
-
associationLoader(
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
this,
|
|
92
|
-
TSelectedFields
|
|
93
|
-
> {
|
|
94
|
-
return new EntityAssociationLoader(this);
|
|
87
|
+
associationLoader(
|
|
88
|
+
queryContext?: EntityQueryContext,
|
|
89
|
+
): EntityAssociationLoader<TFields, TID, TViewerContext, this, TSelectedFields> {
|
|
90
|
+
return new EntityAssociationLoader(this, queryContext);
|
|
95
91
|
}
|
|
96
92
|
|
|
97
93
|
/**
|
|
@@ -152,10 +148,15 @@ export default abstract class ReadonlyEntity<
|
|
|
152
148
|
.getViewerScopedEntityCompanionForClass(this)
|
|
153
149
|
.getQueryContextProvider()
|
|
154
150
|
.getQueryContext(),
|
|
155
|
-
): EntityLoader<
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
151
|
+
): EntityLoader<
|
|
152
|
+
TMFields,
|
|
153
|
+
TMID,
|
|
154
|
+
TMViewerContext,
|
|
155
|
+
TMViewerContext2,
|
|
156
|
+
TMEntity,
|
|
157
|
+
TMPrivacyPolicy,
|
|
158
|
+
TMSelectedFields
|
|
159
|
+
> {
|
|
160
|
+
return new EntityLoader(viewerContext, queryContext, this);
|
|
160
161
|
}
|
|
161
162
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import AuthorizationResultBasedEntityLoader from './AuthorizationResultBasedEntityLoader';
|
|
2
2
|
import EntityLoaderFactory from './EntityLoaderFactory';
|
|
3
3
|
import EntityPrivacyPolicy, { EntityPrivacyPolicyEvaluationContext } from './EntityPrivacyPolicy';
|
|
4
4
|
import { EntityQueryContext } from './EntityQueryContext';
|
|
@@ -43,7 +43,14 @@ export default class ViewerScopedEntityLoaderFactory<
|
|
|
43
43
|
TEntity,
|
|
44
44
|
TSelectedFields
|
|
45
45
|
>,
|
|
46
|
-
):
|
|
46
|
+
): AuthorizationResultBasedEntityLoader<
|
|
47
|
+
TFields,
|
|
48
|
+
TID,
|
|
49
|
+
TViewerContext,
|
|
50
|
+
TEntity,
|
|
51
|
+
TPrivacyPolicy,
|
|
52
|
+
TSelectedFields
|
|
53
|
+
> {
|
|
47
54
|
return this.entityLoaderFactory.forLoad(
|
|
48
55
|
this.viewerContext,
|
|
49
56
|
queryContext,
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
AuthorizationResultBasedCreateMutator,
|
|
3
|
+
AuthorizationResultBasedUpdateMutator,
|
|
4
|
+
AuthorizationResultBasedDeleteMutator,
|
|
5
|
+
} from './AuthorizationResultBasedEntityMutator';
|
|
2
6
|
import EntityMutatorFactory from './EntityMutatorFactory';
|
|
3
7
|
import EntityPrivacyPolicy from './EntityPrivacyPolicy';
|
|
4
8
|
import { EntityQueryContext } from './EntityQueryContext';
|
|
@@ -36,21 +40,42 @@ export default class ViewerScopedEntityMutatorFactory<
|
|
|
36
40
|
|
|
37
41
|
forCreate(
|
|
38
42
|
queryContext: EntityQueryContext,
|
|
39
|
-
):
|
|
43
|
+
): AuthorizationResultBasedCreateMutator<
|
|
44
|
+
TFields,
|
|
45
|
+
TID,
|
|
46
|
+
TViewerContext,
|
|
47
|
+
TEntity,
|
|
48
|
+
TPrivacyPolicy,
|
|
49
|
+
TSelectedFields
|
|
50
|
+
> {
|
|
40
51
|
return this.entityMutatorFactory.forCreate(this.viewerContext, queryContext);
|
|
41
52
|
}
|
|
42
53
|
|
|
43
54
|
forUpdate(
|
|
44
55
|
existingEntity: TEntity,
|
|
45
56
|
queryContext: EntityQueryContext,
|
|
46
|
-
):
|
|
57
|
+
): AuthorizationResultBasedUpdateMutator<
|
|
58
|
+
TFields,
|
|
59
|
+
TID,
|
|
60
|
+
TViewerContext,
|
|
61
|
+
TEntity,
|
|
62
|
+
TPrivacyPolicy,
|
|
63
|
+
TSelectedFields
|
|
64
|
+
> {
|
|
47
65
|
return this.entityMutatorFactory.forUpdate(existingEntity, queryContext);
|
|
48
66
|
}
|
|
49
67
|
|
|
50
68
|
forDelete(
|
|
51
69
|
existingEntity: TEntity,
|
|
52
70
|
queryContext: EntityQueryContext,
|
|
53
|
-
):
|
|
71
|
+
): AuthorizationResultBasedDeleteMutator<
|
|
72
|
+
TFields,
|
|
73
|
+
TID,
|
|
74
|
+
TViewerContext,
|
|
75
|
+
TEntity,
|
|
76
|
+
TPrivacyPolicy,
|
|
77
|
+
TSelectedFields
|
|
78
|
+
> {
|
|
54
79
|
return this.entityMutatorFactory.forDelete(existingEntity, queryContext);
|
|
55
80
|
}
|
|
56
81
|
}
|