Skip to content

Commit e9bcc60

Browse files
genuclaude
andcommitted
fix(orm): handle omitted needs dependencies for ext result fields
When a user omits a field that is a `needs` dependency of an active ext result field, the computed field was silently missing from results. Ensure needs dependencies are un-omitted for the DB query and stripped from the final result, mirroring the existing `select` path behavior. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 5d83b85 commit e9bcc60

2 files changed

Lines changed: 42 additions & 2 deletions

File tree

packages/orm/src/client/client-impl.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -917,9 +917,17 @@ function prepareArgsForExtResult(
917917

918918
if (omit && extResultDefs.size > 0) {
919919
const newOmit = { ...omit };
920-
for (const fieldName of extResultDefs.keys()) {
920+
for (const [fieldName, fieldDef] of extResultDefs) {
921921
if (newOmit[fieldName]) {
922+
// strip ext result field names from omit (they don't exist in the DB)
922923
delete newOmit[fieldName];
924+
} else {
925+
// this ext result field is active — ensure its needs are not omitted
926+
for (const needField of Object.keys(fieldDef.needs)) {
927+
if (newOmit[needField]) {
928+
delete newOmit[needField];
929+
}
930+
}
923931
}
924932
}
925933
result = { ...result, omit: newOmit };
@@ -1039,9 +1047,16 @@ function applyExtResultToRow(
10391047
}
10401048

10411049
if (omit && extResultDefs.size > 0) {
1042-
for (const fieldName of extResultDefs.keys()) {
1050+
for (const [fieldName, fieldDef] of extResultDefs) {
10431051
if (omit[fieldName]) {
10441052
omittedExtResultFields!.add(fieldName);
1053+
} else {
1054+
// this ext result field is active — track needs that were originally omitted
1055+
for (const needField of Object.keys(fieldDef.needs)) {
1056+
if (omit[needField]) {
1057+
injectedNeedsFields.add(needField);
1058+
}
1059+
}
10451060
}
10461061
}
10471062
}

tests/e2e/orm/plugin-infra/ext-result.test.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,31 @@ describe('Plugin extended result fields', () => {
280280
expect((users[0] as any).upperName).toBeUndefined();
281281
});
282282

283+
it('should still compute virtual fields when their needs dependency is omitted', async () => {
284+
const extDb = db.$use(
285+
definePlugin({
286+
id: 'greeting',
287+
result: {
288+
User: {
289+
upperName: {
290+
needs: { name: true },
291+
compute: (user) => user.name.toUpperCase(),
292+
},
293+
},
294+
},
295+
}),
296+
);
297+
298+
await extDb.user.create({ data: { name: 'Alice' } });
299+
300+
// omit the `name` field which is a `needs` dependency of `upperName`
301+
const users = await extDb.user.findMany({ omit: { name: true } });
302+
// upperName should still be computed even though its needs dep was omitted
303+
expect(users[0]!.upperName).toBe('ALICE');
304+
// the omitted `name` field should not appear in the result
305+
expect((users[0] as any).name).toBeUndefined();
306+
});
307+
283308
it('should compose virtual fields from multiple plugins', async () => {
284309
const plugin1 = definePlugin({
285310
id: 'plugin1',

0 commit comments

Comments
 (0)