Fullstack TypeScript toolkit that enhances Prisma ORM with flexible Authorization layer for RBAC/ABAC/PBAC/ReBAC, offering auto-generated type-safe APIs and frontend hooks.
Using delegates causes the response object to get decorated differently from when using the prisma client directly. This seems to affect all models with any relationship to the polymorphic model, even if it is not being queried directly.
Test Case
import { createPostgresDb, dropPostgresDb, loadSchema } from '@zenstackhq/testtools';
import Decimal from 'decimal.js';
describe('new-issue', () => {
it('regression1', async () => {
const dbUrl = await createPostgresDb('new-issue-1');
let prisma: any;
try {
const r = await loadSchema(
`
model LineItem {
id Int @id @default(autoincrement())
price Decimal
orderId Int
order Order @relation(fields: [orderId], references: [id])
}
model Order {
id Int @id @default(autoincrement())
total Decimal
lineItems LineItem[]
}
`,
{
provider: 'postgresql',
dbUrl,
enhancements: ['omit', 'delegate'],
}
);
prisma = r.prisma;
const db = r.enhance();
const create = await db.Order.create({
data: {
total: new Decimal(100_100.99),
lineItems: { create: [{ price: 90_000.66 }, { price: 20_100.33 }] },
},
});
const order = await db.Order.findFirst({ where: { id: create.id }, include: { lineItems: true } });
expect(Decimal.isDecimal(order.total)).toBe(true);
expect(order.total.toString()).toEqual('100100.99');
order.lineItems.forEach((item: any) => {
expect(Decimal.isDecimal(item.price)).toBe(true);
expect(item.price.toString()).not.toEqual('[object Object]');
});
} finally {
if (prisma) {
await prisma.$disconnect();
}
await dropPostgresDb('new-issue-1');
}
});
it('regression2', async () => {
const dbUrl = await createPostgresDb('new-issue-2');
let prisma: any;
try {
const r = await loadSchema(
`
model LineItem {
id Int @id @default(autoincrement())
price Decimal
orderId Int
order Order @relation(fields: [orderId], references: [id])
}
model Order extends BaseType {
total Decimal
lineItems LineItem[]
}
model BaseType {
id Int @id @default(autoincrement())
entityType String
@@delegate(entityType)
}
`,
{
provider: 'postgresql',
dbUrl,
enhancements: ['omit', 'delegate'],
}
);
prisma = r.prisma;
const db = r.enhance();
const create = await db.Order.create({
data: {
total: new Decimal(100_100.99),
lineItems: { create: [{ price: 90_000.66 }, { price: 20_100.33 }] },
},
});
const order = await db.Order.findFirst({ where: { id: create.id }, include: { lineItems: true } });
expect(Decimal.isDecimal(order.total)).toBe(true); // FAILS!
expect(order.total.toString()).toEqual('100100.99'); // FAILS!
order.lineItems.forEach((item: any) => {
expect(Decimal.isDecimal(item.price)).toBe(true); // FAILS!
expect(item.price.toString()).not.toEqual('[object Object]'); // ALSO FAILS!
});
const lineItems = await db.LineItem.findMany();
lineItems.forEach((item: any) => {
expect(Decimal.isDecimal(item.price)).toBe(true); // ALSO FAILS!
expect(item.price.toString()).not.toEqual('[object Object]'); // ALSO FAILS!
});
} finally {
if (prisma) {
await prisma.$disconnect();
}
await dropPostgresDb('new-issue-2');
}
});
});
That the Order model exhibits the behavior made sense once I narrowed this down to polymorphic models. However, seeing the issue again when querying LineItem was definitely unexpected.
Environment (please complete the following information):
zenstack 2.1.2
@zenstackhq/runtime 2.1.2
Prisma version: 5.15.0
Database type: Postgresql
Additional context
Add any other context about the problem here.
Description and expected behavior
Using delegates causes the response object to get decorated differently from when using the prisma client directly. This seems to affect all models with any relationship to the polymorphic model, even if it is not being queried directly.
Test Case
That the
Order
model exhibits the behavior made sense once I narrowed this down to polymorphic models. However, seeing the issue again when queryingLineItem
was definitely unexpected.Environment (please complete the following information):
Additional context Add any other context about the problem here.