@expo/entity 0.49.0 → 0.51.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.
Files changed (46) hide show
  1. package/build/src/AuthorizationResultBasedEntityMutator.d.ts +6 -6
  2. package/build/src/AuthorizationResultBasedEntityMutator.js +9 -2
  3. package/build/src/AuthorizationResultBasedEntityMutator.js.map +1 -1
  4. package/build/src/EntityCompanion.js +1 -1
  5. package/build/src/EntityCompanionProvider.d.ts +4 -4
  6. package/build/src/EntityDatabaseAdapter.d.ts +17 -0
  7. package/build/src/EntityDatabaseAdapter.js +11 -0
  8. package/build/src/EntityDatabaseAdapter.js.map +1 -1
  9. package/build/src/EntityMutationInfo.d.ts +4 -8
  10. package/build/src/EntityMutationValidatorConfiguration.d.ts +26 -0
  11. package/build/src/{EntityMutationValidator.js → EntityMutationValidatorConfiguration.js} +3 -3
  12. package/build/src/EntityMutationValidatorConfiguration.js.map +1 -0
  13. package/build/src/EntityMutatorFactory.d.ts +2 -2
  14. package/build/src/EntityMutatorFactory.js.map +1 -1
  15. package/build/src/IEntityCacheAdapter.js +2 -0
  16. package/build/src/IEntityCacheAdapter.js.map +1 -1
  17. package/build/src/IEntityCacheAdapterProvider.js +2 -0
  18. package/build/src/IEntityCacheAdapterProvider.js.map +1 -1
  19. package/build/src/IEntityDatabaseAdapterProvider.js +2 -0
  20. package/build/src/IEntityDatabaseAdapterProvider.js.map +1 -1
  21. package/build/src/IEntityGenericCacher.js +2 -0
  22. package/build/src/IEntityGenericCacher.js.map +1 -1
  23. package/build/src/index.d.ts +1 -1
  24. package/build/src/index.js +1 -1
  25. package/build/src/index.js.map +1 -1
  26. package/package.json +5 -5
  27. package/src/AuthorizationResultBasedEntityMutator.ts +28 -16
  28. package/src/EntityCompanion.ts +1 -1
  29. package/src/EntityCompanionProvider.ts +5 -5
  30. package/src/EntityDatabaseAdapter.ts +19 -0
  31. package/src/EntityMutationInfo.ts +29 -17
  32. package/src/EntityMutationValidatorConfiguration.ts +64 -0
  33. package/src/EntityMutatorFactory.ts +3 -3
  34. package/src/IEntityCacheAdapter.ts +4 -0
  35. package/src/IEntityCacheAdapterProvider.ts +4 -0
  36. package/src/IEntityDatabaseAdapterProvider.ts +4 -0
  37. package/src/IEntityGenericCacher.ts +4 -0
  38. package/src/__tests__/EntityMutator-test.ts +161 -54
  39. package/src/__tests__/GenericEntityCacheAdapter-test.ts +24 -0
  40. package/src/__tests__/GenericSecondaryEntityCache-test.ts +180 -0
  41. package/src/index.ts +1 -1
  42. package/src/utils/__testfixtures__/PrivacyPolicyRuleTestUtils.ts +2 -2
  43. package/src/utils/__testfixtures__/StubDatabaseAdapter.ts +11 -1
  44. package/build/src/EntityMutationValidator.d.ts +0 -11
  45. package/build/src/EntityMutationValidator.js.map +0 -1
  46. package/src/EntityMutationValidator.ts +0 -29
@@ -18,7 +18,10 @@ import {
18
18
  EntityMutationTriggerConfiguration,
19
19
  EntityNonTransactionalMutationTrigger,
20
20
  } from './EntityMutationTriggerConfiguration';
21
- import { EntityMutationValidator } from './EntityMutationValidator';
21
+ import {
22
+ EntityMutationValidator,
23
+ EntityMutationValidatorConfiguration,
24
+ } from './EntityMutationValidatorConfiguration';
22
25
  import { EntityPrivacyPolicy } from './EntityPrivacyPolicy';
23
26
  import { EntityQueryContext, EntityTransactionalQueryContext } from './EntityQueryContext';
24
27
  import { ViewerContext } from './ViewerContext';
@@ -142,13 +145,13 @@ export abstract class AuthorizationResultBasedBaseMutator<
142
145
  TSelectedFields
143
146
  >,
144
147
  protected readonly privacyPolicy: TPrivacyPolicy,
145
- protected readonly mutationValidators: EntityMutationValidator<
148
+ protected readonly mutationValidators: EntityMutationValidatorConfiguration<
146
149
  TFields,
147
150
  TIDField,
148
151
  TViewerContext,
149
152
  TEntity,
150
153
  TSelectedFields
151
- >[],
154
+ >,
152
155
  protected readonly mutationTriggers: EntityMutationTriggerConfiguration<
153
156
  TFields,
154
157
  TIDField,
@@ -189,13 +192,9 @@ export abstract class AuthorizationResultBasedBaseMutator<
189
192
  }
190
193
 
191
194
  protected async executeMutationValidatorsAsync(
192
- validators: EntityMutationValidator<
193
- TFields,
194
- TIDField,
195
- TViewerContext,
196
- TEntity,
197
- TSelectedFields
198
- >[],
195
+ validators:
196
+ | EntityMutationValidator<TFields, TIDField, TViewerContext, TEntity, TSelectedFields>[]
197
+ | undefined,
199
198
  queryContext: EntityTransactionalQueryContext,
200
199
  entity: TEntity,
201
200
  mutationInfo: EntityValidatorMutationInfo<
@@ -206,6 +205,10 @@ export abstract class AuthorizationResultBasedBaseMutator<
206
205
  TSelectedFields
207
206
  >,
208
207
  ): Promise<void> {
208
+ if (!validators) {
209
+ return;
210
+ }
211
+
209
212
  await Promise.all(
210
213
  validators.map((validator) =>
211
214
  validator.executeAsync(this.viewerContext, queryContext, entity, mutationInfo),
@@ -350,7 +353,7 @@ export class AuthorizationResultBasedCreateMutator<
350
353
  }
351
354
 
352
355
  await this.executeMutationValidatorsAsync(
353
- this.mutationValidators,
356
+ this.mutationValidators.beforeCreateAndUpdate,
354
357
  queryContext,
355
358
  temporaryEntityForPrivacyCheck,
356
359
  { type: EntityMutationType.CREATE },
@@ -452,13 +455,13 @@ export class AuthorizationResultBasedUpdateMutator<
452
455
  TSelectedFields
453
456
  >,
454
457
  privacyPolicy: TPrivacyPolicy,
455
- mutationValidators: EntityMutationValidator<
458
+ mutationValidators: EntityMutationValidatorConfiguration<
456
459
  TFields,
457
460
  TIDField,
458
461
  TViewerContext,
459
462
  TEntity,
460
463
  TSelectedFields
461
- >[],
464
+ >,
462
465
  mutationTriggers: EntityMutationTriggerConfiguration<
463
466
  TFields,
464
467
  TIDField,
@@ -554,7 +557,7 @@ export class AuthorizationResultBasedUpdateMutator<
554
557
  }
555
558
 
556
559
  await this.executeMutationValidatorsAsync(
557
- this.mutationValidators,
560
+ this.mutationValidators.beforeCreateAndUpdate,
558
561
  queryContext,
559
562
  entityAboutToBeUpdated,
560
563
  {
@@ -708,13 +711,13 @@ export class AuthorizationResultBasedDeleteMutator<
708
711
  TSelectedFields
709
712
  >,
710
713
  privacyPolicy: TPrivacyPolicy,
711
- mutationValidators: EntityMutationValidator<
714
+ mutationValidators: EntityMutationValidatorConfiguration<
712
715
  TFields,
713
716
  TIDField,
714
717
  TViewerContext,
715
718
  TEntity,
716
719
  TSelectedFields
717
- >[],
720
+ >,
718
721
  mutationTriggers: EntityMutationTriggerConfiguration<
719
722
  TFields,
720
723
  TIDField,
@@ -800,6 +803,15 @@ export class AuthorizationResultBasedDeleteMutator<
800
803
  processedEntityIdentifiersFromTransitiveDeletions,
801
804
  );
802
805
 
806
+ await this.executeMutationValidatorsAsync(
807
+ this.mutationValidators.beforeDelete,
808
+ queryContext,
809
+ this.entity,
810
+ {
811
+ type: EntityMutationType.DELETE,
812
+ cascadingDeleteCause: this.cascadingDeleteCause,
813
+ },
814
+ );
803
815
  await this.executeMutationTriggersAsync(
804
816
  this.mutationTriggers.beforeAll,
805
817
  queryContext,
@@ -76,7 +76,7 @@ export class EntityCompanion<
76
76
  tableDataCoordinator.entityConfiguration,
77
77
  entityCompanionDefinition.entityClass,
78
78
  this.privacyPolicy,
79
- entityCompanionDefinition.mutationValidators ?? [],
79
+ entityCompanionDefinition.mutationValidators ?? {},
80
80
  mergeEntityMutationTriggerConfigurations(
81
81
  entityCompanionDefinition.mutationTriggers ?? {},
82
82
  entityCompanionProvider.globalMutationTriggers ?? {},
@@ -4,7 +4,7 @@ import { IEntityClass } from './Entity';
4
4
  import { EntityCompanion, IPrivacyPolicyClass } from './EntityCompanion';
5
5
  import { EntityConfiguration } from './EntityConfiguration';
6
6
  import { EntityMutationTriggerConfiguration } from './EntityMutationTriggerConfiguration';
7
- import { EntityMutationValidator } from './EntityMutationValidator';
7
+ import { EntityMutationValidatorConfiguration } from './EntityMutationValidatorConfiguration';
8
8
  import { EntityPrivacyPolicy } from './EntityPrivacyPolicy';
9
9
  import { EntityQueryContextProvider } from './EntityQueryContextProvider';
10
10
  import { IEntityCacheAdapterProvider } from './IEntityCacheAdapterProvider';
@@ -86,18 +86,18 @@ export interface EntityCompanionDefinition<
86
86
  readonly privacyPolicyClass: IPrivacyPolicyClass<TPrivacyPolicy>;
87
87
 
88
88
  /**
89
- * An optional list of EntityMutationValidator for this entity.
89
+ * An optional EntityMutationValidatorConfiguration for this entity.
90
90
  */
91
- readonly mutationValidators?: EntityMutationValidator<
91
+ readonly mutationValidators?: EntityMutationValidatorConfiguration<
92
92
  TFields,
93
93
  TIDField,
94
94
  TViewerContext,
95
95
  TEntity,
96
96
  TSelectedFields
97
- >[];
97
+ >;
98
98
 
99
99
  /**
100
- * An optional list of EntityMutationTrigger for this entity.
100
+ * An optional EntityMutationTriggerConfiguration for this entity.
101
101
  */
102
102
  readonly mutationTriggers?: EntityMutationTriggerConfiguration<
103
103
  TFields,
@@ -67,8 +67,20 @@ export interface TableFieldMultiValueEqualityCondition {
67
67
  tableValues: readonly any[];
68
68
  }
69
69
 
70
+ /**
71
+ * Ordering options for `orderBy` clauses.
72
+ */
70
73
  export enum OrderByOrdering {
74
+ /**
75
+ * Ascending order (lowest to highest).
76
+ * Ascending order puts smaller values first, where "smaller" is defined in terms of the %3C operator.
77
+ */
71
78
  ASCENDING = 'asc',
79
+
80
+ /**
81
+ * Descending order (highest to lowest).
82
+ * Descending order puts larger values first, where "larger" is defined in terms of the %3E operator.
83
+ */
72
84
  DESCENDING = 'desc',
73
85
  }
74
86
 
@@ -80,7 +92,14 @@ export interface QuerySelectionModifiers<TFields extends Record<string, any>> {
80
92
  * Order the entities by specified columns and orders.
81
93
  */
82
94
  orderBy?: {
95
+ /**
96
+ * The field name to order by.
97
+ */
83
98
  fieldName: keyof TFields;
99
+
100
+ /**
101
+ * The OrderByOrdering to order by.
102
+ */
84
103
  order: OrderByOrdering;
85
104
  }[];
86
105
 
@@ -7,22 +7,6 @@ export enum EntityMutationType {
7
7
  DELETE,
8
8
  }
9
9
 
10
- export type EntityValidatorMutationInfo<
11
- TFields extends Record<string, any>,
12
- TIDField extends keyof NonNullable<Pick<TFields, TSelectedFields>>,
13
- TViewerContext extends ViewerContext,
14
- TEntity extends Entity<TFields, TIDField, TViewerContext, TSelectedFields>,
15
- TSelectedFields extends keyof TFields = keyof TFields,
16
- > =
17
- | {
18
- type: EntityMutationType.CREATE;
19
- }
20
- | {
21
- type: EntityMutationType.UPDATE;
22
- previousValue: TEntity;
23
- cascadingDeleteCause: EntityCascadingDeletionInfo | null;
24
- };
25
-
26
10
  /**
27
11
  * Information about a cascading deletion.
28
12
  */
@@ -38,7 +22,7 @@ export type EntityCascadingDeletionInfo = {
38
22
  cascadingDeleteCause: EntityCascadingDeletionInfo | null;
39
23
  };
40
24
 
41
- export type EntityTriggerMutationInfo<
25
+ type EntityTriggerOrValidatorMutationInfo<
42
26
  TFields extends Record<string, any>,
43
27
  TIDField extends keyof NonNullable<Pick<TFields, TSelectedFields>>,
44
28
  TViewerContext extends ViewerContext,
@@ -57,3 +41,31 @@ export type EntityTriggerMutationInfo<
57
41
  type: EntityMutationType.DELETE;
58
42
  cascadingDeleteCause: EntityCascadingDeletionInfo | null;
59
43
  };
44
+
45
+ export type EntityValidatorMutationInfo<
46
+ TFields extends Record<string, any>,
47
+ TIDField extends keyof NonNullable<Pick<TFields, TSelectedFields>>,
48
+ TViewerContext extends ViewerContext,
49
+ TEntity extends Entity<TFields, TIDField, TViewerContext, TSelectedFields>,
50
+ TSelectedFields extends keyof TFields = keyof TFields,
51
+ > = EntityTriggerOrValidatorMutationInfo<
52
+ TFields,
53
+ TIDField,
54
+ TViewerContext,
55
+ TEntity,
56
+ TSelectedFields
57
+ >;
58
+
59
+ export type EntityTriggerMutationInfo<
60
+ TFields extends Record<string, any>,
61
+ TIDField extends keyof NonNullable<Pick<TFields, TSelectedFields>>,
62
+ TViewerContext extends ViewerContext,
63
+ TEntity extends Entity<TFields, TIDField, TViewerContext, TSelectedFields>,
64
+ TSelectedFields extends keyof TFields = keyof TFields,
65
+ > = EntityTriggerOrValidatorMutationInfo<
66
+ TFields,
67
+ TIDField,
68
+ TViewerContext,
69
+ TEntity,
70
+ TSelectedFields
71
+ >;
@@ -0,0 +1,64 @@
1
+ import { EntityValidatorMutationInfo } from './EntityMutationInfo';
2
+ import { EntityTransactionalQueryContext } from './EntityQueryContext';
3
+ import { ReadonlyEntity } from './ReadonlyEntity';
4
+ import { ViewerContext } from './ViewerContext';
5
+
6
+ /**
7
+ * Interface to define validator behavior for entities.
8
+ */
9
+ export interface EntityMutationValidatorConfiguration<
10
+ TFields extends Record<string, any>,
11
+ TIDField extends keyof NonNullable<Pick<TFields, TSelectedFields>>,
12
+ TViewerContext extends ViewerContext,
13
+ TEntity extends ReadonlyEntity<TFields, TIDField, TViewerContext, TSelectedFields>,
14
+ TSelectedFields extends keyof TFields = keyof TFields,
15
+ > {
16
+ /**
17
+ * Validator set that runs within the transaction but before the entity is created.
18
+ */
19
+ beforeCreateAndUpdate?: EntityMutationValidator<
20
+ TFields,
21
+ TIDField,
22
+ TViewerContext,
23
+ TEntity,
24
+ TSelectedFields
25
+ >[];
26
+
27
+ /**
28
+ * Validator set that runs within the transaction but before the entity is deleted. This can be used
29
+ * to maintain constraints not expressable via other means, like checking that this entity is not referenced
30
+ * by other entities (in a non-foreign-key-manner) before proceeding with deletion.
31
+ */
32
+ beforeDelete?: EntityMutationValidator<
33
+ TFields,
34
+ TIDField,
35
+ TViewerContext,
36
+ TEntity,
37
+ TSelectedFields
38
+ >[];
39
+ }
40
+
41
+ /**
42
+ * A validator is a way to specify side-effect-free entity mutation validation that runs within the
43
+ * same transaction as the mutation itself.
44
+ */
45
+ export abstract class EntityMutationValidator<
46
+ TFields extends Record<string, any>,
47
+ TIDField extends keyof NonNullable<Pick<TFields, TSelectedFields>>,
48
+ TViewerContext extends ViewerContext,
49
+ TEntity extends ReadonlyEntity<TFields, TIDField, TViewerContext, TSelectedFields>,
50
+ TSelectedFields extends keyof TFields = keyof TFields,
51
+ > {
52
+ abstract executeAsync(
53
+ viewerContext: TViewerContext,
54
+ queryContext: EntityTransactionalQueryContext,
55
+ entity: TEntity,
56
+ mutationInfo: EntityValidatorMutationInfo<
57
+ TFields,
58
+ TIDField,
59
+ TViewerContext,
60
+ TEntity,
61
+ TSelectedFields
62
+ >,
63
+ ): Promise<void>;
64
+ }
@@ -10,7 +10,7 @@ import { EntityDatabaseAdapter } from './EntityDatabaseAdapter';
10
10
  import { EntityLoaderFactory } from './EntityLoaderFactory';
11
11
  import { EntityCascadingDeletionInfo } from './EntityMutationInfo';
12
12
  import { EntityMutationTriggerConfiguration } from './EntityMutationTriggerConfiguration';
13
- import { EntityMutationValidator } from './EntityMutationValidator';
13
+ import { EntityMutationValidatorConfiguration } from './EntityMutationValidatorConfiguration';
14
14
  import { EntityPrivacyPolicy } from './EntityPrivacyPolicy';
15
15
  import { EntityQueryContext } from './EntityQueryContext';
16
16
  import { ViewerContext } from './ViewerContext';
@@ -45,13 +45,13 @@ export class EntityMutatorFactory<
45
45
  TSelectedFields
46
46
  >,
47
47
  private readonly privacyPolicy: TPrivacyPolicy,
48
- private readonly mutationValidators: EntityMutationValidator<
48
+ private readonly mutationValidators: EntityMutationValidatorConfiguration<
49
49
  TFields,
50
50
  TIDField,
51
51
  TViewerContext,
52
52
  TEntity,
53
53
  TSelectedFields
54
- >[],
54
+ >,
55
55
  private readonly mutationTriggers: EntityMutationTriggerConfiguration<
56
56
  TFields,
57
57
  TIDField,
@@ -1,3 +1,5 @@
1
+ /* c8 ignore start - interface only */
2
+
1
3
  import { IEntityLoadKey, IEntityLoadValue } from './internal/EntityLoadInterfaces';
2
4
  import { CacheLoadResult } from './internal/ReadThroughEntityCache';
3
5
 
@@ -67,3 +69,5 @@ export interface IEntityCacheAdapter<
67
69
  values: readonly TLoadValue[],
68
70
  ): Promise<void>;
69
71
  }
72
+
73
+ /* c8 ignore stop - interface only */
@@ -1,3 +1,5 @@
1
+ /* c8 ignore start - interface only */
2
+
1
3
  import { EntityConfiguration } from './EntityConfiguration';
2
4
  import { IEntityCacheAdapter } from './IEntityCacheAdapter';
3
5
 
@@ -13,3 +15,5 @@ export interface IEntityCacheAdapterProvider {
13
15
  entityConfiguration: EntityConfiguration<TFields, TIDField>,
14
16
  ): IEntityCacheAdapter<TFields, TIDField>;
15
17
  }
18
+
19
+ /* c8 ignore stop - interface only */
@@ -1,3 +1,5 @@
1
+ /* c8 ignore start - interface only */
2
+
1
3
  import { EntityConfiguration } from './EntityConfiguration';
2
4
  import { EntityDatabaseAdapter } from './EntityDatabaseAdapter';
3
5
 
@@ -13,3 +15,5 @@ export interface IEntityDatabaseAdapterProvider {
13
15
  entityConfiguration: EntityConfiguration<TFields, TIDField>,
14
16
  ): EntityDatabaseAdapter<TFields, TIDField>;
15
17
  }
18
+
19
+ /* c8 ignore stop - interface only */
@@ -1,3 +1,5 @@
1
+ /* c8 ignore start - interface only */
2
+
1
3
  import { IEntityLoadKey, IEntityLoadValue } from './internal/EntityLoadInterfaces';
2
4
  import { CacheLoadResult } from './internal/ReadThroughEntityCache';
3
5
 
@@ -71,3 +73,5 @@ export interface IEntityGenericCacher<
71
73
  value: TLoadValue,
72
74
  ): readonly string[];
73
75
  }
76
+
77
+ /* c8 ignore stop - interface only */