Skip to content

Commit 8962ad9

Browse files
authored
fix: issue with zod generation for self-relation involving delegate types (#2238)
1 parent 25da0c7 commit 8962ad9

File tree

3 files changed

+55
-2
lines changed

3 files changed

+55
-2
lines changed

packages/schema/src/plugins/zod/transformer.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,21 @@ export default class Transformer {
342342
// "Input" or "NestedInput" suffix
343343
mappedInputTypeName += match[4];
344344

345-
processedInputType = { ...inputType, type: mappedInputTypeName };
345+
// Prisma's naming is inconsistent for update input types, so we need
346+
// to check for a few other candidates and use the one that matches
347+
// a DMMF input type name
348+
const candidates = [mappedInputTypeName];
349+
if (mappedInputTypeName.includes('UpdateOne')) {
350+
candidates.push(...candidates.map((name) => name.replace('UpdateOne', 'Update')));
351+
}
352+
if (mappedInputTypeName.includes('NestedInput')) {
353+
candidates.push(...candidates.map((name) => name.replace('NestedInput', 'Input')));
354+
}
355+
356+
const finalMappedName =
357+
candidates.find((name) => this.inputObjectTypes.some((it) => it.name === name)) ?? mappedInputTypeName;
358+
359+
processedInputType = { ...inputType, type: finalMappedName };
346360
}
347361
return processedInputType;
348362
}

packages/sdk/src/utils.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -659,8 +659,16 @@ export function getRelationBackLink(field: DataModelField) {
659659

660660
const targetModel = field.type.reference.ref as DataModel;
661661

662+
const sameField = (f1: DataModelField, f2: DataModelField) => {
663+
// for fields inherited from a delegate model, always use
664+
// the base to compare
665+
const parent1 = f1.$inheritedFrom ?? f1.$container;
666+
const parent2 = f2.$inheritedFrom ?? f2.$container;
667+
return f1.name === f2.name && parent1 === parent2;
668+
};
669+
662670
for (const otherField of targetModel.fields) {
663-
if (otherField === field) {
671+
if (sameField(otherField, field)) {
664672
// backlink field is never self
665673
continue;
666674
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { loadSchema } from '@zenstackhq/testtools';
2+
3+
describe('issue 2226', () => {
4+
it('regression', async () => {
5+
const { zodSchemas } = await loadSchema(
6+
`
7+
model Registration {
8+
id String @id
9+
regType String
10+
@@delegate(regType)
11+
12+
replacedRegistrationId String?
13+
replacedRegistration Registration? @relation("ReplacedBy", fields: [replacedRegistrationId], references: [id])
14+
replacements Registration[] @relation("ReplacedBy")
15+
}
16+
17+
// Delegated subtype
18+
model RegistrationFramework extends Registration {
19+
}
20+
`,
21+
{ fullZod: true }
22+
);
23+
24+
const schema = zodSchemas.objects.RegistrationFrameworkUpdateInputObjectSchema;
25+
expect(schema).toBeDefined();
26+
const parsed = schema.safeParse({
27+
replacedRegistrationId: '123',
28+
});
29+
expect(parsed.success).toBe(true);
30+
});
31+
});

0 commit comments

Comments
 (0)