Skip to content

Commit

Permalink
merge dev to main (v2.2.4) (#1527)
Browse files Browse the repository at this point in the history
  • Loading branch information
ymc9 authored Jun 20, 2024
2 parents 0fa292c + 3e77974 commit b06cee6
Show file tree
Hide file tree
Showing 19 changed files with 272 additions and 36 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "zenstack-monorepo",
"version": "2.2.3",
"version": "2.2.4",
"description": "",
"scripts": {
"build": "pnpm -r build",
Expand Down
2 changes: 1 addition & 1 deletion packages/ide/jetbrains/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ plugins {
}

group = "dev.zenstack"
version = "2.2.3"
version = "2.2.4"

repositories {
mavenCentral()
Expand Down
2 changes: 1 addition & 1 deletion packages/ide/jetbrains/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "jetbrains",
"version": "2.2.3",
"version": "2.2.4",
"displayName": "ZenStack JetBrains IDE Plugin",
"description": "ZenStack JetBrains IDE plugin",
"homepage": "https://zenstack.dev",
Expand Down
2 changes: 1 addition & 1 deletion packages/language/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/language",
"version": "2.2.3",
"version": "2.2.4",
"displayName": "ZenStack modeling language compiler",
"description": "ZenStack modeling language compiler",
"homepage": "https://zenstack.dev",
Expand Down
2 changes: 1 addition & 1 deletion packages/misc/redwood/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zenstackhq/redwood",
"displayName": "ZenStack RedwoodJS Integration",
"version": "2.2.3",
"version": "2.2.4",
"description": "CLI and runtime for integrating ZenStack with RedwoodJS projects.",
"repository": {
"type": "git",
Expand Down
2 changes: 1 addition & 1 deletion packages/plugins/openapi/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zenstackhq/openapi",
"displayName": "ZenStack Plugin and Runtime for OpenAPI",
"version": "2.2.3",
"version": "2.2.4",
"description": "ZenStack plugin and runtime supporting OpenAPI",
"main": "index.js",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion packages/plugins/swr/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zenstackhq/swr",
"displayName": "ZenStack plugin for generating SWR hooks",
"version": "2.2.3",
"version": "2.2.4",
"description": "ZenStack plugin for generating SWR hooks",
"main": "index.js",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion packages/plugins/tanstack-query/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zenstackhq/tanstack-query",
"displayName": "ZenStack plugin for generating tanstack-query hooks",
"version": "2.2.3",
"version": "2.2.4",
"description": "ZenStack plugin for generating tanstack-query hooks",
"main": "index.js",
"exports": {
Expand Down
2 changes: 1 addition & 1 deletion packages/plugins/trpc/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zenstackhq/trpc",
"displayName": "ZenStack plugin for tRPC",
"version": "2.2.3",
"version": "2.2.4",
"description": "ZenStack plugin for tRPC",
"main": "index.js",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion packages/runtime/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zenstackhq/runtime",
"displayName": "ZenStack Runtime Library",
"version": "2.2.3",
"version": "2.2.4",
"description": "Runtime of ZenStack for both client-side and server-side environments.",
"repository": {
"type": "git",
Expand Down
71 changes: 49 additions & 22 deletions packages/runtime/src/enhancements/delegate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,15 +194,13 @@ export class DelegateProxyHandler extends DefaultPrismaProxyHandler {

if (this.injectBaseFieldSelect(model, field, value, args, kind)) {
delete args[kind][field];
} else {
if (fieldInfo && this.isDelegateOrDescendantOfDelegate(fieldInfo.type)) {
let nextValue = value;
if (nextValue === true) {
// make sure the payload is an object
args[kind][field] = nextValue = {};
}
this.injectSelectIncludeHierarchy(fieldInfo.type, nextValue);
} else if (fieldInfo.isDataModel) {
let nextValue = value;
if (nextValue === true) {
// make sure the payload is an object
args[kind][field] = nextValue = {};
}
this.injectSelectIncludeHierarchy(fieldInfo.type, nextValue);
}
}
}
Expand Down Expand Up @@ -392,8 +390,11 @@ export class DelegateProxyHandler extends DefaultPrismaProxyHandler {
);
}

// note that we can't call `createMany` directly because it doesn't support
// nested created, which is needed for creating base entities
// `createMany` doesn't support nested create, which is needed for creating entities
// inheriting a delegate base, so we need to convert it to a regular `create` here.
// Note that the main difference is `create` doesn't support `skipDuplicates` as
// `createMany` does.

return this.queryUtils.transaction(this.prisma, async (tx) => {
const r = await Promise.all(
enumerate(args.data).map(async (item) => {
Expand Down Expand Up @@ -425,17 +426,33 @@ export class DelegateProxyHandler extends DefaultPrismaProxyHandler {
this.doProcessCreatePayload(model, args);
},

createMany: (model, args, _context) => {
if (args.skipDuplicates) {
throw prismaClientValidationError(
this.prisma,
this.options.prismaModule,
'`createMany` with `skipDuplicates` set to true is not supported for delegated models'
);
}
createMany: (model, args, context) => {
// `createMany` doesn't support nested create, which is needed for creating entities
// inheriting a delegate base, so we need to convert it to a regular `create` here.
// Note that the main difference is `create` doesn't support `skipDuplicates` as
// `createMany` does.

for (const item of enumerate(args?.data)) {
this.doProcessCreatePayload(model, item);
if (this.isDelegateOrDescendantOfDelegate(model)) {
if (args.skipDuplicates) {
throw prismaClientValidationError(
this.prisma,
this.options.prismaModule,
'`createMany` with `skipDuplicates` set to true is not supported for delegated models'
);
}

// convert to regular `create`
let createPayload = context.parent.create ?? [];
if (!Array.isArray(createPayload)) {
createPayload = [createPayload];
}

for (const item of enumerate(args.data)) {
this.doProcessCreatePayload(model, item);
createPayload.push(item);
}
context.parent.create = createPayload;
delete context.parent['createMany'];
}
},
});
Expand All @@ -460,8 +477,8 @@ export class DelegateProxyHandler extends DefaultPrismaProxyHandler {
}

// ensure the full nested "create" structure is created for base types
private ensureBaseCreateHierarchy(model: string, result: any) {
let curr = result;
private ensureBaseCreateHierarchy(model: string, args: any) {
let curr = args;
let base = this.getBaseModel(model);
let sub = this.getModelInfo(model);

Expand All @@ -478,6 +495,16 @@ export class DelegateProxyHandler extends DefaultPrismaProxyHandler {
curr[baseRelationName].create[base.discriminator] = sub.name;
}
}

// Look for base id field assignments in the current level, and push
// them down to the base level
for (const idField of getIdFields(this.options.modelMeta, base.name)) {
if (curr[idField.name] !== undefined) {
curr[baseRelationName].create[idField.name] = curr[idField.name];
delete curr[idField.name];
}
}

curr = curr[baseRelationName].create;
sub = base;
base = this.getBaseModel(base.name);
Expand Down
2 changes: 1 addition & 1 deletion packages/schema/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"publisher": "zenstack",
"displayName": "ZenStack Language Tools",
"description": "Build scalable web apps with minimum code by defining authorization and validation rules inside the data schema that closer to the database",
"version": "2.2.3",
"version": "2.2.4",
"author": {
"name": "ZenStack Team"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/sdk",
"version": "2.2.3",
"version": "2.2.4",
"description": "ZenStack plugin development SDK",
"main": "index.js",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/server/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/server",
"version": "2.2.3",
"version": "2.2.4",
"displayName": "ZenStack Server-side Adapters",
"description": "ZenStack server-side adapters",
"homepage": "https://zenstack.dev",
Expand Down
2 changes: 1 addition & 1 deletion packages/testtools/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/testtools",
"version": "2.2.3",
"version": "2.2.4",
"description": "ZenStack Test Tools",
"main": "index.js",
"private": true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,22 @@ describe('Polymorphism Test', () => {
).resolves.toMatchObject({ count: 2 });
});

it('create concrete with explicit id', async () => {
const { enhance } = await loadSchema(schema, { enhancements: ['delegate'] });
const db = enhance();

await expect(
db.ratedVideo.create({ data: { id: 1, duration: 100, url: 'xyz', rating: 5 } })
).resolves.toMatchObject({
id: 1,
duration: 100,
url: 'xyz',
rating: 5,
assetType: 'Video',
videoType: 'RatedVideo',
});
});

it('read with concrete', async () => {
const { db, user, video } = await setup();

Expand Down
31 changes: 31 additions & 0 deletions tests/regression/tests/issue-1518.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { loadSchema } from '@zenstackhq/testtools';
describe('issue 1518', () => {
it('regression', async () => {
const { enhance } = await loadSchema(
`
model Activity {
id String @id @default(uuid())
title String
type String
@@delegate(type)
@@allow('all', true)
}
model TaskActivity extends Activity {
description String
@@map("task_activity")
@@allow('all', true)
}
`
);

const db = enhance();
await db.taskActivity.create({
data: {
id: '00000000-0000-0000-0000-111111111111',
title: 'Test Activity',
description: 'Description of task',
},
});
});
});
70 changes: 70 additions & 0 deletions tests/regression/tests/issue-1520.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { loadSchema } from '@zenstackhq/testtools';

describe('issue 1520', () => {
it('regression', async () => {
const { enhance } = await loadSchema(
`
model Course {
id Int @id @default(autoincrement())
title String
addedToNotifications AddedToCourseNotification[]
}
model Group {
id Int @id @default(autoincrement())
addedToNotifications AddedToGroupNotification[]
}
model Notification {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
type String
senderId Int
receiverId Int
@@delegate (type)
}
model AddedToGroupNotification extends Notification {
groupId Int
group Group @relation(fields: [groupId], references: [id], onDelete: Cascade)
}
model AddedToCourseNotification extends Notification {
courseId Int
course Course @relation(fields: [courseId], references: [id], onDelete: Cascade)
}
`,
{ enhancements: ['delegate'] }
);

const db = enhance();
const r = await db.course.create({
data: {
title: 'English classes',
addedToNotifications: {
createMany: {
data: [
{
id: 1,
receiverId: 1,
senderId: 2,
},
],
},
},
},
include: { addedToNotifications: true },
});

expect(r.addedToNotifications).toEqual(
expect.arrayContaining([
expect.objectContaining({
id: 1,
courseId: 1,
receiverId: 1,
senderId: 2,
}),
])
);
});
});
Loading

0 comments on commit b06cee6

Please sign in to comment.