Skip to content

Commit eede3f6

Browse files
committed
fix(reference-loader): make key dynamic in createLoader and loader calls
1 parent 9b495c1 commit eede3f6

File tree

2 files changed

+10
-10
lines changed

2 files changed

+10
-10
lines changed

packages/query-graphql/src/loader/reference.loader.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,43 +4,43 @@ import { Class, Filter, QueryService } from '@ptc-org/nestjs-query-core'
44
import { NestjsQueryDataloader } from './relations.loader'
55

66
export type ReferenceArgs = {
7-
id: string | number
7+
[key: string]: string | number
88
}
99

1010
export class ReferenceLoader<DTO> implements NestjsQueryDataloader<DTO, ReferenceArgs, DTO | undefined | Error> {
1111
private readonly logger = new Logger(ReferenceLoader.name)
1212

1313
constructor(readonly DTOClass: Class<DTO>) {}
1414

15-
public createLoader(service: QueryService<DTO, unknown, unknown>) {
15+
public createLoader(service: QueryService<DTO, unknown, unknown>, key = 'id') {
1616
return async (args: ReadonlyArray<ReferenceArgs>): Promise<(DTO | undefined | Error)[]> => {
1717
// Deduplicate IDs while preserving original order mapping
18-
const uniqueIds = [...new Set(args.map((arg) => arg.id))]
18+
const uniqueIds = [...new Set(args.map((arg) => arg[key]))]
1919

2020
try {
21-
const filter = { id: { in: uniqueIds } } as unknown as Filter<DTO>
21+
const filter = { [key]: { in: uniqueIds } } as unknown as Filter<DTO>
2222
const entities = await service.query({ filter })
2323

2424
// Create entity map for efficient lookup
2525
// Use string keys because representation.id from federation may differ in type from entity.id
2626
const entityMap = new Map<string, DTO>()
2727
entities?.forEach((entity) => {
28-
const id = (entity as Record<string, unknown>).id
28+
const id = (entity as Record<string, unknown>)[key]
2929
entityMap.set(String(id), entity)
3030
})
3131

3232
// Return results in the same order as requested
3333
const results = args.map((arg) => {
34-
const entity = entityMap.get(String(arg.id))
34+
const entity = entityMap.get(String(arg[key]))
3535
if (!entity) {
36-
this.logger.warn(`Entity not found for ID: ${arg.id} in ${this.DTOClass.name}`)
36+
this.logger.warn(`Entity not found for ${key}: ${arg[key]} in ${this.DTOClass.name}`)
3737
}
3838
return entity || undefined
3939
})
4040

4141
return results
4242
} catch (error) {
43-
this.logger.error(`Batch query failed for ${this.DTOClass.name}:`, error)
43+
this.logger.error(`Batch query failed for ${this.DTOClass.name} with key ${key}:`, error)
4444
// Return error for each request, let DataLoader handle it
4545
return args.map(() => (error instanceof Error ? error : new Error(String(error))))
4646
}

packages/query-graphql/src/resolvers/reference.resolver.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export const Referenceable =
5656
const loader = DataLoaderFactory.getOrCreateLoader(
5757
context,
5858
uniqueLoaderName,
59-
() => referenceLoader.createLoader(this.service),
59+
() => referenceLoader.createLoader(this.service, key),
6060
{
6161
// Ensure batching is enabled for performance
6262
batch: true,
@@ -66,7 +66,7 @@ export const Referenceable =
6666
}
6767
)
6868

69-
const result = await loader.load({ id: id as string | number })
69+
const result = await loader.load({ [key]: id as string | number })
7070

7171
if (!result) {
7272
this.logger.error(`Unable to find ${baseName} with ${key}: ${String(id)}`)

0 commit comments

Comments
 (0)