@expo/entity 0.16.0 → 0.20.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 (210) hide show
  1. package/build/EnforcingEntityLoader.js +2 -2
  2. package/build/EnforcingEntityLoader.js.map +1 -1
  3. package/build/Entity.js +8 -2
  4. package/build/Entity.js.map +1 -1
  5. package/build/EntityAssociationLoader.js +3 -3
  6. package/build/EntityAssociationLoader.js.map +1 -1
  7. package/build/EntityCompanion.d.ts +5 -0
  8. package/build/EntityCompanion.js +8 -1
  9. package/build/EntityCompanion.js.map +1 -1
  10. package/build/EntityCompanionProvider.d.ts +1 -1
  11. package/build/EntityCompanionProvider.js +5 -5
  12. package/build/EntityCompanionProvider.js.map +1 -1
  13. package/build/EntityConfiguration.d.ts +1 -1
  14. package/build/EntityConfiguration.js +3 -3
  15. package/build/EntityConfiguration.js.map +1 -1
  16. package/build/EntityDatabaseAdapter.d.ts +4 -4
  17. package/build/EntityDatabaseAdapter.js +13 -13
  18. package/build/EntityDatabaseAdapter.js.map +1 -1
  19. package/build/EntityFieldDefinition.d.ts +77 -0
  20. package/build/EntityFieldDefinition.js +53 -0
  21. package/build/EntityFieldDefinition.js.map +1 -0
  22. package/build/EntityFields.d.ts +5 -78
  23. package/build/EntityFields.js +19 -61
  24. package/build/EntityFields.js.map +1 -1
  25. package/build/EntityLoader.d.ts +3 -1
  26. package/build/EntityLoader.js +19 -15
  27. package/build/EntityLoader.js.map +1 -1
  28. package/build/EntityLoaderFactory.d.ts +3 -1
  29. package/build/EntityLoaderFactory.js +3 -2
  30. package/build/EntityLoaderFactory.js.map +1 -1
  31. package/build/EntityMutationInfo.d.ts +26 -0
  32. package/build/EntityMutationInfo.js +10 -0
  33. package/build/EntityMutationInfo.js.map +1 -0
  34. package/build/EntityMutationTriggerConfiguration.d.ts +4 -4
  35. package/build/EntityMutationValidator.d.ts +3 -3
  36. package/build/EntityMutationValidator.js.map +1 -1
  37. package/build/EntityMutator.d.ts +5 -16
  38. package/build/EntityMutator.js +62 -58
  39. package/build/EntityMutator.js.map +1 -1
  40. package/build/EntityPrivacyPolicy.d.ts +5 -4
  41. package/build/EntityPrivacyPolicy.js +60 -12
  42. package/build/EntityPrivacyPolicy.js.map +1 -1
  43. package/build/EntityQueryContext.d.ts +13 -0
  44. package/build/EntityQueryContext.js +18 -0
  45. package/build/EntityQueryContext.js.map +1 -1
  46. package/build/EntitySecondaryCacheLoader.js +2 -2
  47. package/build/EntitySecondaryCacheLoader.js.map +1 -1
  48. package/build/ReadonlyEntity.js +3 -4
  49. package/build/ReadonlyEntity.js.map +1 -1
  50. package/build/ViewerScopedEntityCompanion.d.ts +5 -0
  51. package/build/ViewerScopedEntityCompanion.js +6 -0
  52. package/build/ViewerScopedEntityCompanion.js.map +1 -1
  53. package/build/__tests__/EnforcingEntityLoader-test.js +82 -82
  54. package/build/__tests__/EnforcingEntityLoader-test.js.map +1 -1
  55. package/build/__tests__/Entity-test.js +6 -6
  56. package/build/__tests__/Entity-test.js.map +1 -1
  57. package/build/__tests__/EntityAssociationLoader-test.js +40 -40
  58. package/build/__tests__/EntityAssociationLoader-test.js.map +1 -1
  59. package/build/__tests__/EntityCommonUseCases-test.js +11 -11
  60. package/build/__tests__/EntityCommonUseCases-test.js.map +1 -1
  61. package/build/__tests__/EntityCompanion-test.js +3 -3
  62. package/build/__tests__/EntityCompanion-test.js.map +1 -1
  63. package/build/__tests__/EntityCompanionProvider-test.js +1 -1
  64. package/build/__tests__/EntityCompanionProvider-test.js.map +1 -1
  65. package/build/__tests__/EntityDatabaseAdapter-test.js +12 -12
  66. package/build/__tests__/EntityDatabaseAdapter-test.js.map +1 -1
  67. package/build/__tests__/EntityEdges-test.js +103 -6
  68. package/build/__tests__/EntityEdges-test.js.map +1 -1
  69. package/build/__tests__/EntityFields-test.js +18 -26
  70. package/build/__tests__/EntityFields-test.js.map +1 -1
  71. package/build/__tests__/EntityLoader-constructor-test.d.ts +22 -0
  72. package/build/__tests__/EntityLoader-constructor-test.js +111 -0
  73. package/build/__tests__/EntityLoader-constructor-test.js.map +1 -0
  74. package/build/__tests__/EntityLoader-test.js +81 -73
  75. package/build/__tests__/EntityLoader-test.js.map +1 -1
  76. package/build/__tests__/EntityMutator-MutationCacheConsistency-test.d.ts +1 -0
  77. package/build/__tests__/EntityMutator-MutationCacheConsistency-test.js +81 -0
  78. package/build/__tests__/EntityMutator-MutationCacheConsistency-test.js.map +1 -0
  79. package/build/__tests__/EntityMutator-test.js +138 -136
  80. package/build/__tests__/EntityMutator-test.js.map +1 -1
  81. package/build/__tests__/EntityPrivacyPolicy-test.js +143 -67
  82. package/build/__tests__/EntityPrivacyPolicy-test.js.map +1 -1
  83. package/build/__tests__/EntitySecondaryCacheLoader-test.js +15 -15
  84. package/build/__tests__/EntitySecondaryCacheLoader-test.js.map +1 -1
  85. package/build/__tests__/EntitySelfReferentialEdges-test.js +13 -12
  86. package/build/__tests__/EntitySelfReferentialEdges-test.js.map +1 -1
  87. package/build/__tests__/ReadonlyEntity-test.js +12 -12
  88. package/build/__tests__/ReadonlyEntity-test.js.map +1 -1
  89. package/build/__tests__/ViewerContext-test.js +2 -2
  90. package/build/__tests__/ViewerContext-test.js.map +1 -1
  91. package/build/__tests__/ViewerScopedEntityCompanion-test.js +2 -2
  92. package/build/__tests__/ViewerScopedEntityCompanion-test.js.map +1 -1
  93. package/build/__tests__/ViewerScopedEntityCompanionProvider-test.js +2 -2
  94. package/build/__tests__/ViewerScopedEntityCompanionProvider-test.js.map +1 -1
  95. package/build/__tests__/ViewerScopedEntityLoaderFactory-test.js +5 -5
  96. package/build/__tests__/ViewerScopedEntityLoaderFactory-test.js.map +1 -1
  97. package/build/__tests__/ViewerScopedEntityMutatorFactory-test.js +5 -5
  98. package/build/__tests__/ViewerScopedEntityMutatorFactory-test.js.map +1 -1
  99. package/build/__tests__/cases/TwoEntitySameTableDisjointRows-test.js +5 -5
  100. package/build/__tests__/cases/TwoEntitySameTableDisjointRows-test.js.map +1 -1
  101. package/build/__tests__/cases/TwoEntitySameTableOverlappingRows-test.js +2 -2
  102. package/build/__tests__/cases/TwoEntitySameTableOverlappingRows-test.js.map +1 -1
  103. package/build/__tests__/entityUtils-test.js +21 -21
  104. package/build/__tests__/entityUtils-test.js.map +1 -1
  105. package/build/index.d.ts +3 -0
  106. package/build/index.js +5 -1
  107. package/build/index.js.map +1 -1
  108. package/build/internal/EntityDataManager.js +8 -7
  109. package/build/internal/EntityDataManager.js.map +1 -1
  110. package/build/internal/EntityFieldTransformationUtils.js +2 -2
  111. package/build/internal/EntityFieldTransformationUtils.js.map +1 -1
  112. package/build/internal/ReadThroughEntityCache.js +4 -4
  113. package/build/internal/ReadThroughEntityCache.js.map +1 -1
  114. package/build/internal/__tests__/EntityDataManager-test.js +21 -21
  115. package/build/internal/__tests__/EntityDataManager-test.js.map +1 -1
  116. package/build/internal/__tests__/EntityFieldTransformationUtils-test.js +8 -8
  117. package/build/internal/__tests__/EntityFieldTransformationUtils-test.js.map +1 -1
  118. package/build/internal/__tests__/ReadThroughEntityCache-test.js +48 -48
  119. package/build/internal/__tests__/ReadThroughEntityCache-test.js.map +1 -1
  120. package/build/metrics/EntityMetricsUtils.js +1 -1
  121. package/build/metrics/EntityMetricsUtils.js.map +1 -1
  122. package/build/metrics/IEntityMetricsAdapter.d.ts +16 -0
  123. package/build/metrics/IEntityMetricsAdapter.js +6 -1
  124. package/build/metrics/IEntityMetricsAdapter.js.map +1 -1
  125. package/build/metrics/NoOpEntityMetricsAdapter.d.ts +2 -1
  126. package/build/metrics/NoOpEntityMetricsAdapter.js +1 -0
  127. package/build/metrics/NoOpEntityMetricsAdapter.js.map +1 -1
  128. package/build/rules/__tests__/AlwaysAllowPrivacyPolicyRule-test.js +4 -4
  129. package/build/rules/__tests__/AlwaysAllowPrivacyPolicyRule-test.js.map +1 -1
  130. package/build/rules/__tests__/AlwaysDenyPrivacyPolicyRule-test.js +4 -4
  131. package/build/rules/__tests__/AlwaysDenyPrivacyPolicyRule-test.js.map +1 -1
  132. package/build/rules/__tests__/AlwaysSkipPrivacyPolicyRule-test.js +4 -4
  133. package/build/rules/__tests__/AlwaysSkipPrivacyPolicyRule-test.js.map +1 -1
  134. package/build/testfixtures/DateIDTestEntity.js.map +1 -1
  135. package/build/testfixtures/SimpleTestEntity.js.map +1 -1
  136. package/build/testfixtures/TestEntity.d.ts +6 -6
  137. package/build/testfixtures/TestEntity.js +4 -4
  138. package/build/testfixtures/TestEntity.js.map +1 -1
  139. package/build/testfixtures/TestEntity2.d.ts +5 -5
  140. package/build/testfixtures/TestEntity2.js.map +1 -1
  141. package/build/testfixtures/TestEntityNumberKey.js +1 -1
  142. package/build/testfixtures/TestEntityNumberKey.js.map +1 -1
  143. package/build/utils/collections/__tests__/maps-test.js +13 -13
  144. package/build/utils/collections/__tests__/maps-test.js.map +1 -1
  145. package/build/utils/collections/maps.js +1 -1
  146. package/build/utils/collections/maps.js.map +1 -1
  147. package/build/utils/testing/PrivacyPolicyRuleTestUtils.d.ts +6 -6
  148. package/build/utils/testing/PrivacyPolicyRuleTestUtils.js +1 -1
  149. package/build/utils/testing/PrivacyPolicyRuleTestUtils.js.map +1 -1
  150. package/build/utils/testing/StubCacheAdapter.js +1 -1
  151. package/build/utils/testing/StubCacheAdapter.js.map +1 -1
  152. package/build/utils/testing/StubDatabaseAdapter.js +7 -7
  153. package/build/utils/testing/StubDatabaseAdapter.js.map +1 -1
  154. package/build/utils/testing/__tests__/StubDatabaseAdapter-test.js +26 -26
  155. package/build/utils/testing/__tests__/StubDatabaseAdapter-test.js.map +1 -1
  156. package/build/utils/testing/describeFieldTestCase.d.ts +2 -0
  157. package/build/utils/testing/describeFieldTestCase.js +18 -0
  158. package/build/utils/testing/describeFieldTestCase.js.map +1 -0
  159. package/package.json +2 -1
  160. package/src/Entity.ts +10 -2
  161. package/src/EntityAssociationLoader.ts +1 -1
  162. package/src/EntityCompanion.ts +10 -2
  163. package/src/EntityCompanionProvider.ts +5 -9
  164. package/src/EntityConfiguration.ts +1 -1
  165. package/src/EntityDatabaseAdapter.ts +10 -8
  166. package/src/EntityFieldDefinition.ts +124 -0
  167. package/src/EntityFields.ts +11 -126
  168. package/src/EntityLoader.ts +12 -4
  169. package/src/EntityLoaderFactory.ts +5 -2
  170. package/src/EntityMutationInfo.ts +47 -0
  171. package/src/EntityMutationTriggerConfiguration.ts +5 -5
  172. package/src/EntityMutationValidator.ts +10 -4
  173. package/src/EntityMutator.ts +98 -76
  174. package/src/EntityPrivacyPolicy.ts +77 -19
  175. package/src/EntityQueryContext.ts +20 -0
  176. package/src/ReadonlyEntity.ts +3 -2
  177. package/src/ViewerScopedEntityCompanion.ts +8 -0
  178. package/src/__tests__/Entity-test.ts +8 -8
  179. package/src/__tests__/EntityCommonUseCases-test.ts +4 -4
  180. package/src/__tests__/EntityEdges-test.ts +169 -14
  181. package/src/__tests__/EntityFields-test.ts +6 -23
  182. package/src/__tests__/EntityLoader-constructor-test.ts +177 -0
  183. package/src/__tests__/EntityLoader-test.ts +48 -20
  184. package/src/__tests__/EntityMutator-MutationCacheConsistency-test.ts +105 -0
  185. package/src/__tests__/EntityMutator-test.ts +153 -146
  186. package/src/__tests__/EntityPrivacyPolicy-test.ts +215 -78
  187. package/src/__tests__/EntitySecondaryCacheLoader-test.ts +7 -9
  188. package/src/__tests__/EntitySelfReferentialEdges-test.ts +6 -5
  189. package/src/__tests__/ReadonlyEntity-test.ts +1 -1
  190. package/src/__tests__/ViewerContext-test.ts +7 -6
  191. package/src/__tests__/ViewerScopedEntityCompanion-test.ts +11 -10
  192. package/src/__tests__/ViewerScopedEntityMutatorFactory-test.ts +4 -3
  193. package/src/__tests__/cases/TwoEntitySameTableDisjointRows-test.ts +6 -6
  194. package/src/__tests__/cases/TwoEntitySameTableOverlappingRows-test.ts +4 -4
  195. package/src/index.ts +3 -0
  196. package/src/internal/EntityDataManager.ts +2 -1
  197. package/src/internal/__tests__/EntityDataManager-test.ts +6 -6
  198. package/src/internal/__tests__/ReadThroughEntityCache-test.ts +15 -13
  199. package/src/metrics/EntityMetricsUtils.ts +56 -50
  200. package/src/metrics/IEntityMetricsAdapter.ts +23 -0
  201. package/src/metrics/NoOpEntityMetricsAdapter.ts +2 -0
  202. package/src/testfixtures/DateIDTestEntity.ts +4 -4
  203. package/src/testfixtures/SimpleTestEntity.ts +4 -4
  204. package/src/testfixtures/TestEntity.ts +8 -8
  205. package/src/testfixtures/TestEntity2.ts +4 -4
  206. package/src/testfixtures/TestEntityNumberKey.ts +6 -6
  207. package/src/utils/testing/StubDatabaseAdapter.ts +4 -4
  208. package/src/utils/testing/__tests__/StubDatabaseAdapter-test.ts +18 -18
  209. package/src/utils/testing/describeFieldTestCase.ts +21 -0
  210. package/CHANGELOG.md +0 -241
@@ -45,8 +45,8 @@ describe('Two entities backed by the same table', () => {
45
45
  expect(successfulManyResults).toHaveLength(1);
46
46
  expect(failedManyResults).toHaveLength(1);
47
47
 
48
- expect(successfulManyResults[0].enforceValue().getID()).toEqual(one.getID());
49
- expect(failedManyResults[0].enforceError().message).toEqual(
48
+ expect(successfulManyResults[0]!.enforceValue().getID()).toEqual(one.getID());
49
+ expect(failedManyResults[0]!.enforceError().message).toEqual(
50
50
  'OneTestEntity must be instantiated with one data'
51
51
  );
52
52
 
@@ -107,16 +107,16 @@ const testEntityConfiguration = new EntityConfiguration<TestFields>({
107
107
  });
108
108
 
109
109
  class TestEntityPrivacyPolicy extends EntityPrivacyPolicy<any, string, ViewerContext, any, any> {
110
- protected readonly readRules = [
110
+ protected override readonly readRules = [
111
111
  new AlwaysAllowPrivacyPolicyRule<any, string, ViewerContext, any, any>(),
112
112
  ];
113
- protected readonly createRules = [
113
+ protected override readonly createRules = [
114
114
  new AlwaysAllowPrivacyPolicyRule<any, string, ViewerContext, any, any>(),
115
115
  ];
116
- protected readonly updateRules = [
116
+ protected override readonly updateRules = [
117
117
  new AlwaysAllowPrivacyPolicyRule<any, string, ViewerContext, any, any>(),
118
118
  ];
119
- protected readonly deleteRules = [
119
+ protected override readonly deleteRules = [
120
120
  new AlwaysAllowPrivacyPolicyRule<any, string, ViewerContext, any, any>(),
121
121
  ];
122
122
  }
@@ -115,16 +115,16 @@ const testEntityConfiguration = new EntityConfiguration<TestFields>({
115
115
  });
116
116
 
117
117
  class TestEntityPrivacyPolicy extends EntityPrivacyPolicy<any, string, ViewerContext, any, any> {
118
- protected readonly readRules = [
118
+ protected override readonly readRules = [
119
119
  new AlwaysAllowPrivacyPolicyRule<any, string, ViewerContext, any, any>(),
120
120
  ];
121
- protected readonly createRules = [
121
+ protected override readonly createRules = [
122
122
  new AlwaysAllowPrivacyPolicyRule<any, string, ViewerContext, any, any>(),
123
123
  ];
124
- protected readonly updateRules = [
124
+ protected override readonly updateRules = [
125
125
  new AlwaysAllowPrivacyPolicyRule<any, string, ViewerContext, any, any>(),
126
126
  ];
127
- protected readonly deleteRules = [
127
+ protected override readonly deleteRules = [
128
128
  new AlwaysAllowPrivacyPolicyRule<any, string, ViewerContext, any, any>(),
129
129
  ];
130
130
  }
package/src/index.ts CHANGED
@@ -26,12 +26,14 @@ export { default as EntityError } from './errors/EntityError';
26
26
  export { default as EntityNotAuthorizedError } from './errors/EntityNotAuthorizedError';
27
27
  export { default as EntityNotFoundError } from './errors/EntityNotFoundError';
28
28
  export * from './EntityFields';
29
+ export * from './EntityFieldDefinition';
29
30
  export { default as EntityLoader } from './EntityLoader';
30
31
  export { default as EntityLoaderFactory } from './EntityLoaderFactory';
31
32
  export { default as EntitySecondaryCacheLoader } from './EntitySecondaryCacheLoader';
32
33
  export * from './EntitySecondaryCacheLoader';
33
34
  export * from './EntityMutator';
34
35
  export { default as EntityMutationValidator } from './EntityMutationValidator';
36
+ export * from './EntityMutationInfo';
35
37
  export * from './EntityMutationTriggerConfiguration';
36
38
  export { default as EntityMutationTriggerConfiguration } from './EntityMutationTriggerConfiguration';
37
39
  export { default as EntityMutatorFactory } from './EntityMutatorFactory';
@@ -63,6 +65,7 @@ export { default as PrivacyPolicyRule } from './rules/PrivacyPolicyRule';
63
65
  export * from './rules/PrivacyPolicyRule';
64
66
  export * from './utils/testing/PrivacyPolicyRuleTestUtils';
65
67
  export * from './utils/testing/StubCacheAdapter';
68
+ export { default as describeFieldTestCase } from './utils/testing/describeFieldTestCase';
66
69
  export { default as StubDatabaseAdapter } from './utils/testing/StubDatabaseAdapter';
67
70
  export { default as StubDatabaseAdapterProvider } from './utils/testing/StubDatabaseAdapterProvider';
68
71
  export { default as StubQueryContextProvider } from './utils/testing/StubQueryContextProvider';
@@ -125,7 +125,8 @@ export default class EntityDataManager<TFields> {
125
125
  const results = await dataLoader.loadMany(fieldValues);
126
126
  const [values, errors] = partitionErrors(results);
127
127
  if (errors.length > 0) {
128
- throw errors[0];
128
+ const error = errors[0]!;
129
+ throw error;
129
130
  }
130
131
 
131
132
  return zipToMap(fieldValues, values);
@@ -34,7 +34,7 @@ const getObjects = (): Map<string, TestFields[]> =>
34
34
  customIdField: '1',
35
35
  testIndexedField: 'unique1',
36
36
  stringField: 'hello',
37
- numberField: 1,
37
+ intField: 1,
38
38
  dateField: new Date(),
39
39
  nullableField: null,
40
40
  },
@@ -42,7 +42,7 @@ const getObjects = (): Map<string, TestFields[]> =>
42
42
  customIdField: '2',
43
43
  testIndexedField: 'unique2',
44
44
  stringField: 'hello',
45
- numberField: 1,
45
+ intField: 1,
46
46
  dateField: new Date(),
47
47
  nullableField: null,
48
48
  },
@@ -50,7 +50,7 @@ const getObjects = (): Map<string, TestFields[]> =>
50
50
  customIdField: '3',
51
51
  testIndexedField: 'unique3',
52
52
  stringField: 'world',
53
- numberField: 1,
53
+ intField: 1,
54
54
  dateField: new Date(),
55
55
  nullableField: null,
56
56
  },
@@ -298,7 +298,7 @@ describe(EntityDataManager, () => {
298
298
  );
299
299
  const queryContext = StubQueryContextProvider.getQueryContext();
300
300
 
301
- const objectInQuestion = objects.get(testEntityConfiguration.tableName)![1];
301
+ const objectInQuestion = objects.get(testEntityConfiguration.tableName)![1]!;
302
302
 
303
303
  const dbSpy = jest.spyOn(databaseAdapter, 'fetchManyWhereAsync');
304
304
  const cacheSpy = jest.spyOn(entityCache, 'readManyThroughAsync');
@@ -337,7 +337,7 @@ describe(EntityDataManager, () => {
337
337
  );
338
338
  const queryContext = StubQueryContextProvider.getQueryContext();
339
339
 
340
- const objectInQuestion = objects.get(testEntityConfiguration.tableName)![1];
340
+ const objectInQuestion = objects.get(testEntityConfiguration.tableName)![1]!;
341
341
 
342
342
  const dbSpy = jest.spyOn(databaseAdapter, 'fetchManyWhereAsync');
343
343
  const cacheSpy = jest.spyOn(entityCache, 'readManyThroughAsync');
@@ -425,7 +425,7 @@ describe(EntityDataManager, () => {
425
425
  fieldValue: 'hello',
426
426
  },
427
427
  {
428
- fieldName: 'numberField',
428
+ fieldName: 'intField',
429
429
  fieldValue: 1,
430
430
  },
431
431
  ],
@@ -20,19 +20,21 @@ const makeEntityConfiguration = (cacheIdField: boolean): EntityConfiguration<Bla
20
20
  cacheAdapterFlavor: 'redis',
21
21
  });
22
22
 
23
- const createIdFetcher = (ids: string[]) => async <N extends keyof BlahFields>(
24
- fetcherFieldValues: readonly NonNullable<BlahFields[N]>[]
25
- ): Promise<ReadonlyMap<NonNullable<BlahFields[N]>, readonly Readonly<BlahFields>[]>> => {
26
- const results = new Map();
27
- fetcherFieldValues.forEach((v) => {
28
- if (ids.includes(v)) {
29
- results.set(v, [{ id: v }]);
30
- } else {
31
- results.set(v, []);
32
- }
33
- });
34
- return results;
35
- };
23
+ const createIdFetcher =
24
+ (ids: string[]) =>
25
+ async <N extends keyof BlahFields>(
26
+ fetcherFieldValues: readonly NonNullable<BlahFields[N]>[]
27
+ ): Promise<ReadonlyMap<NonNullable<BlahFields[N]>, readonly Readonly<BlahFields>[]>> => {
28
+ const results = new Map();
29
+ fetcherFieldValues.forEach((v) => {
30
+ if (ids.includes(v)) {
31
+ results.set(v, [{ id: v }]);
32
+ } else {
33
+ results.set(v, []);
34
+ }
35
+ });
36
+ return results;
37
+ };
36
38
 
37
39
  describe(ReadThroughEntityCache, () => {
38
40
  describe('readManyThroughAsync', () => {
@@ -4,62 +4,68 @@ import IEntityMetricsAdapter, {
4
4
  EntityMetricsMutationType,
5
5
  } from './IEntityMetricsAdapter';
6
6
 
7
- export const timeAndLogLoadEventAsync = (
8
- metricsAdapter: IEntityMetricsAdapter,
9
- loadType: EntityMetricsLoadType,
10
- entityClassName: string
11
- ) => async <TFields>(promise: Promise<readonly Readonly<TFields>[]>) => {
12
- const startTime = Date.now();
13
- const result = await promise;
14
- const endTime = Date.now();
7
+ export const timeAndLogLoadEventAsync =
8
+ (
9
+ metricsAdapter: IEntityMetricsAdapter,
10
+ loadType: EntityMetricsLoadType,
11
+ entityClassName: string
12
+ ) =>
13
+ async <TFields>(promise: Promise<readonly Readonly<TFields>[]>) => {
14
+ const startTime = Date.now();
15
+ const result = await promise;
16
+ const endTime = Date.now();
15
17
 
16
- metricsAdapter.logDataManagerLoadEvent({
17
- type: loadType,
18
- entityClassName,
19
- duration: endTime - startTime,
20
- count: result.length,
21
- });
18
+ metricsAdapter.logDataManagerLoadEvent({
19
+ type: loadType,
20
+ entityClassName,
21
+ duration: endTime - startTime,
22
+ count: result.length,
23
+ });
22
24
 
23
- return result;
24
- };
25
+ return result;
26
+ };
25
27
 
26
- export const timeAndLogLoadMapEventAsync = (
27
- metricsAdapter: IEntityMetricsAdapter,
28
- loadType: EntityMetricsLoadType,
29
- entityClassName: string
30
- ) => async <TFields, N extends keyof TFields>(
31
- promise: Promise<ReadonlyMap<NonNullable<TFields[N]>, readonly Readonly<TFields>[]>>
32
- ) => {
33
- const startTime = Date.now();
34
- const result = await promise;
35
- const endTime = Date.now();
28
+ export const timeAndLogLoadMapEventAsync =
29
+ (
30
+ metricsAdapter: IEntityMetricsAdapter,
31
+ loadType: EntityMetricsLoadType,
32
+ entityClassName: string
33
+ ) =>
34
+ async <TFields, N extends keyof TFields>(
35
+ promise: Promise<ReadonlyMap<NonNullable<TFields[N]>, readonly Readonly<TFields>[]>>
36
+ ) => {
37
+ const startTime = Date.now();
38
+ const result = await promise;
39
+ const endTime = Date.now();
36
40
 
37
- const count = reduceMap(result, (acc, v) => acc + v.length, 0);
41
+ const count = reduceMap(result, (acc, v) => acc + v.length, 0);
38
42
 
39
- metricsAdapter.logDataManagerLoadEvent({
40
- type: loadType,
41
- entityClassName,
42
- duration: endTime - startTime,
43
- count,
44
- });
43
+ metricsAdapter.logDataManagerLoadEvent({
44
+ type: loadType,
45
+ entityClassName,
46
+ duration: endTime - startTime,
47
+ count,
48
+ });
45
49
 
46
- return result;
47
- };
50
+ return result;
51
+ };
48
52
 
49
- export const timeAndLogMutationEventAsync = (
50
- metricsAdapter: IEntityMetricsAdapter,
51
- mutationType: EntityMetricsMutationType,
52
- entityClassName: string
53
- ) => async <T>(promise: Promise<T>) => {
54
- const startTime = Date.now();
55
- const result = await promise;
56
- const endTime = Date.now();
53
+ export const timeAndLogMutationEventAsync =
54
+ (
55
+ metricsAdapter: IEntityMetricsAdapter,
56
+ mutationType: EntityMetricsMutationType,
57
+ entityClassName: string
58
+ ) =>
59
+ async <T>(promise: Promise<T>) => {
60
+ const startTime = Date.now();
61
+ const result = await promise;
62
+ const endTime = Date.now();
57
63
 
58
- metricsAdapter.logMutatorMutationEvent({
59
- type: mutationType,
60
- entityClassName,
61
- duration: endTime - startTime,
62
- });
64
+ metricsAdapter.logMutatorMutationEvent({
65
+ type: mutationType,
66
+ entityClassName,
67
+ duration: endTime - startTime,
68
+ });
63
69
 
64
- return result;
65
- };
70
+ return result;
71
+ };
@@ -1,3 +1,8 @@
1
+ import {
2
+ EntityAuthorizationAction,
3
+ EntityPrivacyPolicyEvaluationMode,
4
+ } from '../EntityPrivacyPolicy';
5
+
1
6
  export enum EntityMetricsLoadType {
2
7
  LOAD_MANY,
3
8
  LOAD_MANY_EQUALITY_CONJUNCTION,
@@ -28,11 +33,29 @@ export interface IncrementLoadCountEvent {
28
33
  entityClassName: string;
29
34
  }
30
35
 
36
+ export enum EntityMetricsAuthorizationResult {
37
+ DENY,
38
+ ALLOW,
39
+ }
40
+
41
+ export interface EntityMetricsAuthorizationEvent {
42
+ entityClassName: string;
43
+ action: EntityAuthorizationAction;
44
+ evaluationResult: EntityMetricsAuthorizationResult;
45
+ privacyPolicyEvaluationMode: EntityPrivacyPolicyEvaluationMode;
46
+ }
47
+
31
48
  /**
32
49
  * An interface for gathering metrics about the Entity framework. Information about
33
50
  * entity load and mutation operations is piped to an instance of this adapter.
34
51
  */
35
52
  export default interface IEntityMetricsAdapter {
53
+ /**
54
+ * Called when a {@link EntityPrivacyPolicy} authorization succeeds or fails.
55
+ * @param authorizationEvent - info about the authorization event
56
+ */
57
+ logAuthorizationEvent(authorizationEvent: EntityMetricsAuthorizationEvent): void;
58
+
36
59
  /**
37
60
  * Called when any load occurs.
38
61
  * @param loadEvent - info about the load event
@@ -1,10 +1,12 @@
1
1
  import IEntityMetricsAdapter, {
2
+ EntityMetricsAuthorizationEvent,
2
3
  EntityMetricsLoadEvent,
3
4
  EntityMetricsMutationEvent,
4
5
  IncrementLoadCountEvent,
5
6
  } from './IEntityMetricsAdapter';
6
7
 
7
8
  export default class NoOpEntityMetricsAdapter implements IEntityMetricsAdapter {
9
+ logAuthorizationEvent(_authorizationEvent: EntityMetricsAuthorizationEvent): void {}
8
10
  logDataManagerLoadEvent(_loadEvent: EntityMetricsLoadEvent): void {}
9
11
  logMutatorMutationEvent(_mutationEvent: EntityMetricsMutationEvent): void {}
10
12
  incrementDataManagerDataloaderLoadCount(
@@ -28,16 +28,16 @@ export class DateIDTestEntityPrivacyPolicy extends EntityPrivacyPolicy<
28
28
  ViewerContext,
29
29
  DateIDTestEntity
30
30
  > {
31
- protected readonly readRules = [
31
+ protected override readonly readRules = [
32
32
  new AlwaysAllowPrivacyPolicyRule<DateIDTestFields, Date, ViewerContext, DateIDTestEntity>(),
33
33
  ];
34
- protected readonly createRules = [
34
+ protected override readonly createRules = [
35
35
  new AlwaysAllowPrivacyPolicyRule<DateIDTestFields, Date, ViewerContext, DateIDTestEntity>(),
36
36
  ];
37
- protected readonly updateRules = [
37
+ protected override readonly updateRules = [
38
38
  new AlwaysAllowPrivacyPolicyRule<DateIDTestFields, Date, ViewerContext, DateIDTestEntity>(),
39
39
  ];
40
- protected readonly deleteRules = [
40
+ protected override readonly deleteRules = [
41
41
  new AlwaysAllowPrivacyPolicyRule<DateIDTestFields, Date, ViewerContext, DateIDTestEntity>(),
42
42
  ];
43
43
  }
@@ -31,7 +31,7 @@ export class SimpleTestEntityPrivacyPolicy extends EntityPrivacyPolicy<
31
31
  SimpleTestEntity,
32
32
  SimpleTestFieldSelection
33
33
  > {
34
- protected readonly readRules = [
34
+ protected override readonly readRules = [
35
35
  new AlwaysAllowPrivacyPolicyRule<
36
36
  SimpleTestFields,
37
37
  string,
@@ -40,7 +40,7 @@ export class SimpleTestEntityPrivacyPolicy extends EntityPrivacyPolicy<
40
40
  SimpleTestFieldSelection
41
41
  >(),
42
42
  ];
43
- protected readonly createRules = [
43
+ protected override readonly createRules = [
44
44
  new AlwaysAllowPrivacyPolicyRule<
45
45
  SimpleTestFields,
46
46
  string,
@@ -49,7 +49,7 @@ export class SimpleTestEntityPrivacyPolicy extends EntityPrivacyPolicy<
49
49
  SimpleTestFieldSelection
50
50
  >(),
51
51
  ];
52
- protected readonly updateRules = [
52
+ protected override readonly updateRules = [
53
53
  new AlwaysAllowPrivacyPolicyRule<
54
54
  SimpleTestFields,
55
55
  string,
@@ -58,7 +58,7 @@ export class SimpleTestEntityPrivacyPolicy extends EntityPrivacyPolicy<
58
58
  SimpleTestFieldSelection
59
59
  >(),
60
60
  ];
61
- protected readonly deleteRules = [
61
+ protected override readonly deleteRules = [
62
62
  new AlwaysAllowPrivacyPolicyRule<
63
63
  SimpleTestFields,
64
64
  string,
@@ -3,7 +3,7 @@ import { result, Result } from '@expo/results';
3
3
  import Entity from '../Entity';
4
4
  import { EntityCompanionDefinition } from '../EntityCompanionProvider';
5
5
  import EntityConfiguration from '../EntityConfiguration';
6
- import { UUIDField, StringField, DateField, NumberField } from '../EntityFields';
6
+ import { UUIDField, StringField, DateField, IntField } from '../EntityFields';
7
7
  import EntityPrivacyPolicy from '../EntityPrivacyPolicy';
8
8
  import ViewerContext from '../ViewerContext';
9
9
  import AlwaysAllowPrivacyPolicyRule from '../rules/AlwaysAllowPrivacyPolicyRule';
@@ -12,7 +12,7 @@ export type TestFields = {
12
12
  customIdField: string;
13
13
  testIndexedField: string;
14
14
  stringField: string;
15
- numberField: number;
15
+ intField: number;
16
16
  dateField: Date;
17
17
  nullableField: string | null;
18
18
  };
@@ -31,7 +31,7 @@ export const testEntityConfiguration = new EntityConfiguration<TestFields>({
31
31
  stringField: new StringField({
32
32
  columnName: 'string_field',
33
33
  }),
34
- numberField: new NumberField({
34
+ intField: new IntField({
35
35
  columnName: 'number_field',
36
36
  }),
37
37
  dateField: new DateField({
@@ -51,16 +51,16 @@ export class TestEntityPrivacyPolicy extends EntityPrivacyPolicy<
51
51
  ViewerContext,
52
52
  TestEntity
53
53
  > {
54
- protected readonly readRules = [
54
+ protected override readonly readRules = [
55
55
  new AlwaysAllowPrivacyPolicyRule<TestFields, string, ViewerContext, TestEntity>(),
56
56
  ];
57
- protected readonly createRules = [
57
+ protected override readonly createRules = [
58
58
  new AlwaysAllowPrivacyPolicyRule<TestFields, string, ViewerContext, TestEntity>(),
59
59
  ];
60
- protected readonly updateRules = [
60
+ protected override readonly updateRules = [
61
61
  new AlwaysAllowPrivacyPolicyRule<TestFields, string, ViewerContext, TestEntity>(),
62
62
  ];
63
- protected readonly deleteRules = [
63
+ protected override readonly deleteRules = [
64
64
  new AlwaysAllowPrivacyPolicyRule<TestFields, string, ViewerContext, TestEntity>(),
65
65
  ];
66
66
  }
@@ -86,7 +86,7 @@ export default class TestEntity extends Entity<TestFields, string, ViewerContext
86
86
  customIdField: testValue,
87
87
  testIndexedField: 'hello',
88
88
  stringField: 'hello',
89
- numberField: 1,
89
+ intField: 1,
90
90
  dateField: new Date(),
91
91
  nullableField: null,
92
92
  })
@@ -32,16 +32,16 @@ export class TestEntity2PrivacyPolicy extends EntityPrivacyPolicy<
32
32
  ViewerContext,
33
33
  TestEntity2
34
34
  > {
35
- protected readonly readRules = [
35
+ protected override readonly readRules = [
36
36
  new AlwaysAllowPrivacyPolicyRule<Test2Fields, string, ViewerContext, TestEntity2>(),
37
37
  ];
38
- protected readonly createRules = [
38
+ protected override readonly createRules = [
39
39
  new AlwaysAllowPrivacyPolicyRule<Test2Fields, string, ViewerContext, TestEntity2>(),
40
40
  ];
41
- protected readonly updateRules = [
41
+ protected override readonly updateRules = [
42
42
  new AlwaysAllowPrivacyPolicyRule<Test2Fields, string, ViewerContext, TestEntity2>(),
43
43
  ];
44
- protected readonly deleteRules = [
44
+ protected override readonly deleteRules = [
45
45
  new AlwaysAllowPrivacyPolicyRule<Test2Fields, string, ViewerContext, TestEntity2>(),
46
46
  ];
47
47
  }
@@ -1,7 +1,7 @@
1
1
  import Entity from '../Entity';
2
2
  import { EntityCompanionDefinition } from '../EntityCompanionProvider';
3
3
  import EntityConfiguration from '../EntityConfiguration';
4
- import { NumberField } from '../EntityFields';
4
+ import { IntField } from '../EntityFields';
5
5
  import EntityPrivacyPolicy from '../EntityPrivacyPolicy';
6
6
  import ViewerContext from '../ViewerContext';
7
7
  import AlwaysAllowPrivacyPolicyRule from '../rules/AlwaysAllowPrivacyPolicyRule';
@@ -14,7 +14,7 @@ export const numberKeyEntityConfiguration = new EntityConfiguration<NumberKeyFie
14
14
  idField: 'id',
15
15
  tableName: 'simple_test_entity_should_not_write_to_db',
16
16
  schema: {
17
- id: new NumberField({
17
+ id: new IntField({
18
18
  columnName: 'custom_id',
19
19
  }),
20
20
  },
@@ -28,16 +28,16 @@ export class NumberKeyPrivacyPolicy extends EntityPrivacyPolicy<
28
28
  ViewerContext,
29
29
  NumberKeyEntity
30
30
  > {
31
- protected readonly readRules = [
31
+ protected override readonly readRules = [
32
32
  new AlwaysAllowPrivacyPolicyRule<NumberKeyFields, number, ViewerContext, NumberKeyEntity>(),
33
33
  ];
34
- protected readonly createRules = [
34
+ protected override readonly createRules = [
35
35
  new AlwaysAllowPrivacyPolicyRule<NumberKeyFields, number, ViewerContext, NumberKeyEntity>(),
36
36
  ];
37
- protected readonly updateRules = [
37
+ protected override readonly updateRules = [
38
38
  new AlwaysAllowPrivacyPolicyRule<NumberKeyFields, number, ViewerContext, NumberKeyEntity>(),
39
39
  ];
40
- protected readonly deleteRules = [
40
+ protected override readonly deleteRules = [
41
41
  new AlwaysAllowPrivacyPolicyRule<NumberKeyFields, number, ViewerContext, NumberKeyEntity>(),
42
42
  ];
43
43
  }
@@ -8,7 +8,7 @@ import EntityDatabaseAdapter, {
8
8
  TableQuerySelectionModifiers,
9
9
  OrderByOrdering,
10
10
  } from '../../EntityDatabaseAdapter';
11
- import { StringField, NumberField } from '../../EntityFields';
11
+ import { StringField, IntField } from '../../EntityFields';
12
12
  import {
13
13
  getDatabaseFieldForEntityField,
14
14
  FieldTransformerMap,
@@ -71,7 +71,7 @@ export default class StubDatabaseAdapter<T> extends EntityDatabaseAdapter<T> {
71
71
  return 0;
72
72
  }
73
73
 
74
- const currentOrderBy = orderBys[0];
74
+ const currentOrderBy = orderBys[0]!;
75
75
  const aField = objectA[currentOrderBy.columnName];
76
76
  const bField = objectB[currentOrderBy.columnName];
77
77
  switch (currentOrderBy.order) {
@@ -161,7 +161,7 @@ export default class StubDatabaseAdapter<T> extends EntityDatabaseAdapter<T> {
161
161
  invariant(idSchemaField, `No schema field found for ${this.entityConfiguration2.idField}`);
162
162
  if (idSchemaField instanceof StringField) {
163
163
  return uuidv4();
164
- } else if (idSchemaField instanceof NumberField) {
164
+ } else if (idSchemaField instanceof IntField) {
165
165
  return Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
166
166
  } else {
167
167
  throw new Error(
@@ -211,7 +211,7 @@ export default class StubDatabaseAdapter<T> extends EntityDatabaseAdapter<T> {
211
211
  ...objectCollection[objectIndex],
212
212
  ...object,
213
213
  };
214
- return [objectCollection[objectIndex]];
214
+ return [objectCollection[objectIndex]!];
215
215
  }
216
216
 
217
217
  protected async deleteInternalAsync(