Skip to content

Commit be40bcf

Browse files
authored
fix: Type idField in EntityConfiguration as TIDField (#425)
# Why Noticed this was mis-typed in a later PR, hoisted into this one. # How Update type of EntityConfiguration.idField to be `TIDField`, which is the most correct and precise type for the field. This will help later on when adding pagination ID field stuff. The other changes to tests are fixes since these previously were underspecified and changing the field type exposed these missing types. (claude informed me of this) # Test Plan `yarn tsc`
1 parent a9d09f4 commit be40bcf

11 files changed

Lines changed: 189 additions & 129 deletions

packages/entity/src/EntityConfiguration.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,9 @@ export class CompositeFieldInfo<
6767
keyDefinition.compositeField.length === new Set(keyDefinition.compositeField).size,
6868
'Composite field must have unique sub-fields',
6969
);
70-
const compositeFieldHolder = new CompositeFieldHolder(keyDefinition.compositeField);
70+
const compositeFieldHolder = new CompositeFieldHolder<TFields, TIDField>(
71+
keyDefinition.compositeField,
72+
);
7173
return [
7274
compositeFieldHolder.serialize(),
7375
{ compositeFieldHolder, cache: keyDefinition.cache ?? false },
@@ -79,8 +81,9 @@ export class CompositeFieldInfo<
7981
public getCompositeFieldHolderForCompositeField(
8082
compositeField: EntityCompositeField<TFields>,
8183
): CompositeFieldHolder<TFields, TIDField> | undefined {
82-
return this.compositeFieldInfoMap.get(new CompositeFieldHolder(compositeField).serialize())
83-
?.compositeFieldHolder;
84+
return this.compositeFieldInfoMap.get(
85+
new CompositeFieldHolder<TFields, TIDField>(compositeField).serialize(),
86+
)?.compositeFieldHolder;
8487
}
8588

8689
public getAllCompositeFieldHolders(): readonly CompositeFieldHolder<TFields, TIDField>[] {
@@ -89,7 +92,7 @@ export class CompositeFieldInfo<
8992

9093
public canCacheCompositeField(compositeField: EntityCompositeField<TFields>): boolean {
9194
const compositeFieldInfo = this.compositeFieldInfoMap.get(
92-
new CompositeFieldHolder(compositeField).serialize(),
95+
new CompositeFieldHolder<TFields, TIDField>(compositeField).serialize(),
9396
);
9497
invariant(
9598
compositeFieldInfo,
@@ -107,7 +110,7 @@ export class EntityConfiguration<
107110
TFields extends Record<string, any>,
108111
TIDField extends keyof TFields,
109112
> {
110-
readonly idField: keyof TFields;
113+
readonly idField: TIDField;
111114
readonly tableName: string;
112115
readonly cacheableKeys: ReadonlySet<keyof TFields>;
113116
readonly compositeFieldInfo: CompositeFieldInfo<TFields, TIDField>;

packages/entity/src/__tests__/AuthorizationResultBasedEntityLoader-test.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -506,11 +506,14 @@ describe(AuthorizationResultBasedEntityLoader, () => {
506506
new SingleFieldValueHolder<TestFields, 'dateField'>(date),
507507
],
508508
[
509-
new CompositeFieldHolder(['stringField', 'intField']),
509+
new CompositeFieldHolder<TestFields, 'customIdField'>(['stringField', 'intField']),
510510
new CompositeFieldValueHolder({ stringField: 'huh', intField: 5 }),
511511
],
512512
[
513-
new CompositeFieldHolder(['stringField', 'testIndexedField']),
513+
new CompositeFieldHolder<TestFields, 'customIdField'>([
514+
'stringField',
515+
'testIndexedField',
516+
]),
514517
new CompositeFieldValueHolder({ stringField: 'huh', testIndexedField: 'h1' }),
515518
],
516519
]),
@@ -605,11 +608,14 @@ describe(AuthorizationResultBasedEntityLoader, () => {
605608
new SingleFieldValueHolder<TestFields, 'dateField'>(date),
606609
],
607610
[
608-
new CompositeFieldHolder(['stringField', 'intField']),
611+
new CompositeFieldHolder<TestFields, 'customIdField'>(['stringField', 'intField']),
609612
new CompositeFieldValueHolder({ stringField: 'huh', intField: 5 }),
610613
],
611614
[
612-
new CompositeFieldHolder(['stringField', 'testIndexedField']),
615+
new CompositeFieldHolder<TestFields, 'customIdField'>([
616+
'stringField',
617+
'testIndexedField',
618+
]),
613619
new CompositeFieldValueHolder({ stringField: 'huh', testIndexedField: 'h1' }),
614620
],
615621
]),
@@ -708,11 +714,14 @@ describe(AuthorizationResultBasedEntityLoader, () => {
708714
new SingleFieldValueHolder<TestFields, 'dateField'>(date),
709715
],
710716
[
711-
new CompositeFieldHolder(['stringField', 'intField']),
717+
new CompositeFieldHolder<TestFields, 'customIdField'>(['stringField', 'intField']),
712718
new CompositeFieldValueHolder({ stringField: 'huh', intField: 5 }),
713719
],
714720
[
715-
new CompositeFieldHolder(['stringField', 'testIndexedField']),
721+
new CompositeFieldHolder<TestFields, 'customIdField'>([
722+
'stringField',
723+
'testIndexedField',
724+
]),
716725
new CompositeFieldValueHolder({ stringField: 'huh', testIndexedField: 'h1' }),
717726
],
718727
]),

packages/entity/src/__tests__/EntityConfiguration-test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ describe(EntityConfiguration, () => {
4646
expect(blahEntityConfiguration.databaseAdapterFlavor).toEqual('postgres');
4747
expect(blahEntityConfiguration.cacheAdapterFlavor).toEqual('redis');
4848
expect(blahEntityConfiguration.compositeFieldInfo.getAllCompositeFieldHolders()).toEqual([
49-
new CompositeFieldHolder(['id', 'cacheable']),
50-
new CompositeFieldHolder(['id', 'uniqueButNotCacheable']),
49+
new CompositeFieldHolder<BlahT, 'id'>(['id', 'cacheable']),
50+
new CompositeFieldHolder<BlahT, 'id'>(['id', 'uniqueButNotCacheable']),
5151
]);
5252
});
5353

packages/entity/src/__tests__/EntityDatabaseAdapter-test.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ describe(EntityDatabaseAdapter, () => {
8787
const adapter = new TestEntityDatabaseAdapter({ fetchResults: [{ string_field: 'hello' }] });
8888
const result = await adapter.fetchManyWhereAsync(
8989
queryContext,
90-
new SingleFieldHolder('stringField'),
90+
new SingleFieldHolder<TestFields, 'customIdField', 'stringField'>('stringField'),
9191
[new SingleFieldValueHolder('hello')],
9292
);
9393
expect(result.get(new SingleFieldValueHolder('hello'))).toEqual([{ stringField: 'hello' }]);
@@ -100,7 +100,7 @@ describe(EntityDatabaseAdapter, () => {
100100
});
101101
const result = await adapter.fetchManyWhereAsync(
102102
queryContext,
103-
new SingleFieldHolder('stringField'),
103+
new SingleFieldHolder<TestFields, 'customIdField', 'stringField'>('stringField'),
104104
[new SingleFieldValueHolder('hello'), new SingleFieldValueHolder('wat')],
105105
);
106106
expect(result.get(new SingleFieldValueHolder('hello'))).toEqual([{ stringField: 'hello' }]);
@@ -140,7 +140,7 @@ describe(EntityDatabaseAdapter, () => {
140140
const adapter = new TestEntityDatabaseAdapter({});
141141
const result = await adapter.fetchManyWhereAsync(
142142
queryContext,
143-
new SingleFieldHolder('stringField'),
143+
new SingleFieldHolder<TestFields, 'customIdField', 'stringField'>('stringField'),
144144
[new SingleFieldValueHolder('what'), new SingleFieldValueHolder('who')],
145145
);
146146
expect(Array.from(result.keys()).map((v) => v.fieldValue)).toEqual(['what', 'who']);
@@ -152,9 +152,11 @@ describe(EntityDatabaseAdapter, () => {
152152
fetchResults: [{ string_field: null }],
153153
});
154154
await expect(
155-
adapter.fetchManyWhereAsync(queryContext, new SingleFieldHolder('stringField'), [
156-
new SingleFieldValueHolder('hello'),
157-
]),
155+
adapter.fetchManyWhereAsync(
156+
queryContext,
157+
new SingleFieldHolder<TestFields, 'customIdField', 'stringField'>('stringField'),
158+
[new SingleFieldValueHolder('hello')],
159+
),
158160
).rejects.toThrow(
159161
'One or more fields from the object is invalid for key SingleField(stringField); {"stringField":null}. This may indicate a faulty database adapter implementation.',
160162
);
@@ -166,9 +168,11 @@ describe(EntityDatabaseAdapter, () => {
166168
fetchResults: [{ string_field: undefined }],
167169
});
168170
await expect(
169-
adapter.fetchManyWhereAsync(queryContext, new SingleFieldHolder('stringField'), [
170-
new SingleFieldValueHolder('hello'),
171-
]),
171+
adapter.fetchManyWhereAsync(
172+
queryContext,
173+
new SingleFieldHolder<TestFields, 'customIdField', 'stringField'>('stringField'),
174+
[new SingleFieldValueHolder('hello')],
175+
),
172176
).rejects.toThrow(
173177
'One or more fields from the object is invalid for key SingleField(stringField); {}. This may indicate a faulty database adapter implementation.',
174178
);

packages/entity/src/__tests__/EntityEdges-test.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -772,7 +772,7 @@ describe('EntityMutator.processEntityDeletionForInboundEdgesAsync', () => {
772772
'id'
773773
>;
774774
const childCachedBefore = await childCacheAdapter.loadManyAsync(
775-
new SingleFieldHolder('parent_id'),
775+
new SingleFieldHolder<ChildFields, 'id', 'parent_id'>('parent_id'),
776776
[new SingleFieldValueHolder(parent.getID())],
777777
);
778778
expect(childCachedBefore.get(new SingleFieldValueHolder(parent.getID()))?.status).toEqual(
@@ -783,9 +783,9 @@ describe('EntityMutator.processEntityDeletionForInboundEdgesAsync', () => {
783783
GrandChildEntity,
784784
)['entityCompanion']['tableDataCoordinator'][
785785
'cacheAdapter'
786-
] as InMemoryFullCacheStubCacheAdapter<ChildFields, 'id'>;
786+
] as InMemoryFullCacheStubCacheAdapter<GrandChildFields, 'id'>;
787787
const grandChildCachedBefore = await grandChildCacheAdapter.loadManyAsync(
788-
new SingleFieldHolder('parent_id'),
788+
new SingleFieldHolder<GrandChildFields, 'id', 'parent_id'>('parent_id'),
789789
[new SingleFieldValueHolder(child.getID())],
790790
);
791791
expect(grandChildCachedBefore.get(new SingleFieldValueHolder(child.getID()))?.status).toEqual(
@@ -797,15 +797,15 @@ describe('EntityMutator.processEntityDeletionForInboundEdgesAsync', () => {
797797
privacyPolicyEvaluationRecords.shouldRecord = false;
798798

799799
const childCachedAfter = await childCacheAdapter.loadManyAsync(
800-
new SingleFieldHolder('parent_id'),
800+
new SingleFieldHolder<ChildFields, 'id', 'parent_id'>('parent_id'),
801801
[new SingleFieldValueHolder(parent.getID())],
802802
);
803803
expect(childCachedAfter.get(new SingleFieldValueHolder(parent.getID()))?.status).toEqual(
804804
CacheStatus.MISS,
805805
);
806806

807807
const grandChildCachedAfter = await grandChildCacheAdapter.loadManyAsync(
808-
new SingleFieldHolder('parent_id'),
808+
new SingleFieldHolder<GrandChildFields, 'id', 'parent_id'>('parent_id'),
809809
[new SingleFieldValueHolder(child.getID())],
810810
);
811811
expect(grandChildCachedAfter.get(new SingleFieldValueHolder(child.getID()))?.status).toEqual(
@@ -922,7 +922,7 @@ describe('EntityMutator.processEntityDeletionForInboundEdgesAsync', () => {
922922
'id'
923923
>;
924924
const childCachedBefore = await childCacheAdapter.loadManyAsync(
925-
new SingleFieldHolder('parent_id'),
925+
new SingleFieldHolder<ChildFields, 'id', 'parent_id'>('parent_id'),
926926
[new SingleFieldValueHolder(parent.getID())],
927927
);
928928
expect(childCachedBefore.get(new SingleFieldValueHolder(parent.getID()))?.status).toEqual(
@@ -933,9 +933,9 @@ describe('EntityMutator.processEntityDeletionForInboundEdgesAsync', () => {
933933
GrandChildEntity,
934934
)['entityCompanion']['tableDataCoordinator'][
935935
'cacheAdapter'
936-
] as InMemoryFullCacheStubCacheAdapter<ChildFields, 'id'>;
936+
] as InMemoryFullCacheStubCacheAdapter<GrandChildFields, 'id'>;
937937
const grandChildCachedBefore = await grandChildCacheAdapter.loadManyAsync(
938-
new SingleFieldHolder('parent_id'),
938+
new SingleFieldHolder<GrandChildFields, 'id', 'parent_id'>('parent_id'),
939939
[new SingleFieldValueHolder(child.getID())],
940940
);
941941
expect(grandChildCachedBefore.get(new SingleFieldValueHolder(child.getID()))?.status).toEqual(
@@ -947,15 +947,15 @@ describe('EntityMutator.processEntityDeletionForInboundEdgesAsync', () => {
947947
privacyPolicyEvaluationRecords.shouldRecord = false;
948948

949949
const childCachedAfter = await childCacheAdapter.loadManyAsync(
950-
new SingleFieldHolder('parent_id'),
950+
new SingleFieldHolder<ChildFields, 'id', 'parent_id'>('parent_id'),
951951
[new SingleFieldValueHolder(parent.getID())],
952952
);
953953
expect(childCachedAfter.get(new SingleFieldValueHolder(parent.getID()))?.status).toEqual(
954954
CacheStatus.MISS,
955955
);
956956

957957
const grandChildCachedAfter = await grandChildCacheAdapter.loadManyAsync(
958-
new SingleFieldHolder('parent_id'),
958+
new SingleFieldHolder<GrandChildFields, 'id', 'parent_id'>('parent_id'),
959959
[new SingleFieldValueHolder(child.getID())],
960960
);
961961
expect(grandChildCachedAfter.get(new SingleFieldValueHolder(child.getID()))?.status).toEqual(

packages/entity/src/__tests__/EntityMutator-test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -376,10 +376,10 @@ const createEntityMutatorFactory = (
376376

377377
installExtensions: () => {},
378378

379-
getDatabaseAdapter<TFields extends Record<'customIdField', any>>(
380-
_entityConfiguration: EntityConfiguration<TFields, 'customIdField'>,
381-
): EntityDatabaseAdapter<TFields, 'customIdField'> {
382-
return databaseAdapter as any as EntityDatabaseAdapter<TFields, 'customIdField'>;
379+
getDatabaseAdapter<TFields extends Record<string, any>, TIDField extends keyof TFields>(
380+
_entityConfiguration: EntityConfiguration<TFields, TIDField>,
381+
): EntityDatabaseAdapter<TFields, TIDField> {
382+
return databaseAdapter as any as EntityDatabaseAdapter<TFields, TIDField>;
383383
},
384384
};
385385
const metricsAdapter = new NoOpEntityMetricsAdapter();

packages/entity/src/__tests__/EntitySelfReferentialEdges-test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -250,15 +250,15 @@ describe('EntityEdgeDeletionBehavior.CASCADE_DELETE_INVALIDATE_CACHE', () => {
250250
'cacheAdapter'
251251
] as InMemoryFullCacheStubCacheAdapter<CategoryFields, 'id'>;
252252
const subCategoryCachedBefore = await categoryCacheAdapter.loadManyAsync(
253-
new SingleFieldHolder('parent_category_id'),
253+
new SingleFieldHolder<CategoryFields, 'id', 'parent_category_id'>('parent_category_id'),
254254
[new SingleFieldValueHolder(parentCategory.getID())],
255255
);
256256
expect(
257257
subCategoryCachedBefore.get(new SingleFieldValueHolder(parentCategory.getID()))?.status,
258258
).toEqual(CacheStatus.HIT);
259259

260260
const subSubCategoryCachedBefore = await categoryCacheAdapter.loadManyAsync(
261-
new SingleFieldHolder('parent_category_id'),
261+
new SingleFieldHolder<CategoryFields, 'id', 'parent_category_id'>('parent_category_id'),
262262
[new SingleFieldValueHolder(subCategory.getID())],
263263
);
264264
expect(
@@ -268,15 +268,15 @@ describe('EntityEdgeDeletionBehavior.CASCADE_DELETE_INVALIDATE_CACHE', () => {
268268
await CategoryEntity.deleter(parentCategory).deleteAsync();
269269

270270
const subCategoryCachedAfter = await categoryCacheAdapter.loadManyAsync(
271-
new SingleFieldHolder('parent_category_id'),
271+
new SingleFieldHolder<CategoryFields, 'id', 'parent_category_id'>('parent_category_id'),
272272
[new SingleFieldValueHolder(parentCategory.getID())],
273273
);
274274
expect(
275275
subCategoryCachedAfter.get(new SingleFieldValueHolder(parentCategory.getID()))?.status,
276276
).toEqual(CacheStatus.MISS);
277277

278278
const subSubCategoryCachedAfter = await categoryCacheAdapter.loadManyAsync(
279-
new SingleFieldHolder('parent_category_id'),
279+
new SingleFieldHolder<CategoryFields, 'id', 'parent_category_id'>('parent_category_id'),
280280
[new SingleFieldValueHolder(subCategory.getID())],
281281
);
282282
expect(
@@ -329,7 +329,7 @@ describe('EntityEdgeDeletionBehavior.CASCADE_DELETE_INVALIDATE_CACHE', () => {
329329
'cacheAdapter'
330330
] as InMemoryFullCacheStubCacheAdapter<CategoryFields, 'id'>;
331331
const categoriesCachedBefore = await categoryCacheAdapter.loadManyAsync(
332-
new SingleFieldHolder('parent_category_id'),
332+
new SingleFieldHolder<CategoryFields, 'id', 'parent_category_id'>('parent_category_id'),
333333
[
334334
new SingleFieldValueHolder(categoryA.getID()),
335335
new SingleFieldValueHolder(categoryB.getID()),
@@ -345,7 +345,7 @@ describe('EntityEdgeDeletionBehavior.CASCADE_DELETE_INVALIDATE_CACHE', () => {
345345
await CategoryEntity.deleter(categoryA).deleteAsync();
346346

347347
const categoriesCachedAfter = await categoryCacheAdapter.loadManyAsync(
348-
new SingleFieldHolder('parent_category_id'),
348+
new SingleFieldHolder<CategoryFields, 'id', 'parent_category_id'>('parent_category_id'),
349349
[
350350
new SingleFieldValueHolder(categoryA.getID()),
351351
new SingleFieldValueHolder(categoryB.getID()),

0 commit comments

Comments
 (0)