Upgrading to Prisma 5.0.0 and typegraphql-prisma 0.27.0 breaking _count field resolver. New required fields on "ModelCount" class
erikmellum opened this issue · comments
Describe the Bug
Each relation on autogenerated ActivityCount
class has new fields that are required, ex. getChannel_types
Prisma 5.0.0
, typegraphql-prisma 0.27.0
Generated Type for ActivityCount:
import { ActivityCountAgent_states_mappingArgs } from "./args/ActivityCountAgent_states_mappingArgs";
import { ActivityCountChannel_typesArgs } from "./args/ActivityCountChannel_typesArgs";
import { ActivityCountDefault_shift_activityArgs } from "./args/ActivityCountDefault_shift_activityArgs";
import { ActivityCountDefault_shift_activity_scheduleArgs } from "./args/ActivityCountDefault_shift_activity_scheduleArgs";
import { ActivityCountSchedule_activitiesArgs } from "./args/ActivityCountSchedule_activitiesArgs";
import { ActivityCountShift_day_activitiesArgs } from "./args/ActivityCountShift_day_activitiesArgs";
import { ActivityCountTime_off_requestsArgs } from "./args/ActivityCountTime_off_requestsArgs";
export declare class ActivityCount {
channel_types: number;
schedule_activities: number;
agent_states_mapping: number;
shift_day_activities: number;
default_shift_activity: number;
default_shift_activity_schedule: number;
time_off_requests: number;
getChannel_types(root: ActivityCount, args: ActivityCountChannel_typesArgs): number;
getSchedule_activities(root: ActivityCount, args: ActivityCountSchedule_activitiesArgs): number;
getAgent_states_mapping(root: ActivityCount, args: ActivityCountAgent_states_mappingArgs): number;
getShift_day_activities(root: ActivityCount, args: ActivityCountShift_day_activitiesArgs): number;
getDefault_shift_activity(root: ActivityCount, args: ActivityCountDefault_shift_activityArgs): number;
getDefault_shift_activity_schedule(root: ActivityCount, args: ActivityCountDefault_shift_activity_scheduleArgs): number;
getTime_off_requests(root: ActivityCount, args: ActivityCountTime_off_requestsArgs): number;
}
Prisma 4.14.1
, typegraphql-prisma 0.25.1
Generated Type for ActivityCount:
export declare class ActivityCount {
channel_types: number;
schedule_activities: number;
agent_states_mapping: number;
shift_day_activities: number;
default_shift_activity: number;
default_shift_activity_schedule: number;
time_off_requests: number;
}
Relations in the ActivityModel now require a get
method in the ActivityCount class
model Activity {
/// @TypeGraphQL.omit(input: ["create", "update"])
activity_id String @id @default(cuid()) @db.VarChar(30)
/// @TypeGraphQL.omit(output: true)
account Account @relation(fields: [account_id], references: [id])
/// @TypeGraphQL.omit(output: true, input: true)
account_id String @default("")
name String @default("")
text_color String @default("")
bg_color String @default("")
activity_type ActivityType @relation(fields: [activity_type_id], references: [activity_type_id])
activity_type_id String @db.VarChar(30)
channel_types ChannelType[]
default_duration Int @default(0) // In minutes
should_calculate_adherence Boolean @default(false)
is_paid Boolean @default(false)
allow_for_time_off Boolean @default(false)
/// @TypeGraphQL.omit(output: true)
is_deleted Boolean @default(false)
/// @TypeGraphQL.omit(input: ["create", "update"])
create_time DateTime @default(now())
/// @TypeGraphQL.omit(input: ["create", "update"])
create_by String @default("")
/// @TypeGraphQL.omit(input: ["create", "update"])
modify_time DateTime @updatedAt
/// @TypeGraphQL.omit(input: ["create", "update"])
modify_by String @default("")
/// @TypeGraphQL.omit(output: true)
modify User? @relation("ModifyActivities", fields: [modify_by], references: [user_id])
create User? @relation("CreateActivities", fields: [create_by], references: [user_id])
schedule_activities ScheduleActivity[]
agent_states_mapping AgentStateActivityMapping[]
shift_day_activities ShiftDayActivity[]
default_shift_activity Shift[] @relation("DefaultShiftActivity")
default_shift_activity_schedule ScheduleDay[] @relation("DefaultShiftActivitySchedule")
time_off_requests TimeOffRequest[]
@@index([activity_type_id], map: "i_activity_type_id")
@@index([account_id], map: "i_account_id")
@@map("wfm_activities")
}
_count field resolver now has an invalid type in prisma 5.0.0 and typegraphql-prisma 0.27.0
To Reproduce
When we upgraded from:
Prisma 4.14.1
and typegraphql-prisma 0.25.1
to
Prisma 5.0.0
and typegraphql-prisma 0.27.0
We began seeing new fields in the "ActivityCount" resolver. This is also happening in other "ModelCount" generated classes.
As a result, our _count
FieldResolvers no longer work
Expected Behavior
I expected the ActivityCount class to have the same properties after upgrading as it did before upgrading. I'm not sure if we have done something to cause this or if it is a legitimate bug due to the upgrade. The only change made in my test was the version of the libraries.
Environment (please complete the following information):
- OS: Mac OSX
- Node
18.12.1
typegraphql-prisma
version0.27.0
- Prisma version
5.0.0
- TypeScript version
4.9.5
New major release = breaking changes. It was mentioned in the release notes. typegraphql-prisma
now emits code for all the Prisma features that were previously hidden behind a preview features flags. I don't plan to do anything about it.
Further explanation:
The need for get
is due to the output types for count are now having args (like where
):
When you check in your generated schema SDL, you will see that. If you reuse that generated types, you also need to figure out how to support it. typegraphql-prisma
does a trick with get
while the whole logic sits in the main CRUD resolvers body.
Thanks for the response @MichalLytek. I understand there are no plans to fix this, but I am still noticing some behaviors that I can't yet explain.
I'll document what we are finding here in case others run into this issue. The autogenerated "Count" types is presenting type errors, even when just returning a result from findMany
. I noticed some strange behaviors when spreading the _count property of type "ActivityCount".
Notice here the _count
has the correct type: "ActivityCount". This type does include the necessary get
functions:
ActivityCount
type def:
import { ActivityCountAgent_states_mappingArgs } from "./args/ActivityCountAgent_states_mappingArgs";
import { ActivityCountChannel_typesArgs } from "./args/ActivityCountChannel_typesArgs";
import { ActivityCountDefault_shift_activityArgs } from "./args/ActivityCountDefault_shift_activityArgs";
import { ActivityCountDefault_shift_activity_scheduleArgs } from "./args/ActivityCountDefault_shift_activity_scheduleArgs";
import { ActivityCountSchedule_activitiesArgs } from "./args/ActivityCountSchedule_activitiesArgs";
import { ActivityCountShift_day_activitiesArgs } from "./args/ActivityCountShift_day_activitiesArgs";
import { ActivityCountTime_off_requestsArgs } from "./args/ActivityCountTime_off_requestsArgs";
export declare class ActivityCount {
channel_types: number;
schedule_activities: number;
agent_states_mapping: number;
shift_day_activities: number;
default_shift_activity: number;
default_shift_activity_schedule: number;
time_off_requests: number;
getChannel_types(root: ActivityCount, args: ActivityCountChannel_typesArgs): number;
getSchedule_activities(root: ActivityCount, args: ActivityCountSchedule_activitiesArgs): number;
getAgent_states_mapping(root: ActivityCount, args: ActivityCountAgent_states_mappingArgs): number;
getShift_day_activities(root: ActivityCount, args: ActivityCountShift_day_activitiesArgs): number;
getDefault_shift_activity(root: ActivityCount, args: ActivityCountDefault_shift_activityArgs): number;
getDefault_shift_activity_schedule(root: ActivityCount, args: ActivityCountDefault_shift_activity_scheduleArgs): number;
getTime_off_requests(root: ActivityCount, args: ActivityCountTime_off_requestsArgs): number;
}
After the spread operation we have lost all of our get*
functions (not sure how this happens yet).
As a result of losing our get
functions when spreading, we get a type error on the return here:
Adding as ActivityCount
bandages over the type error:
But the plot thickens - the same type error is present in the response from prisma.findMany
findManyActivity
implementation is calling prisma.findMany
Drop as Activity[]
on the result of the findMany, type error goes away
One of the challenges this presents for us is the number of models we have that use _count and the autogenerated type for _count. Maintaining types for all of these _count results would not be trivial, but a bigger concern at this point is the issue with the type response from findMany
The generated XYZCount
type should not be used manually, as it's only faking the argument.
Just write your own version and use with the previous code you had.
@MichalLytek thank you for the suggestion to write our own version, happy to do that. Is the intent to no longer use the XYZModel
type manually as well?
The autogenerated XYZModel
is also no longer useable when using include: { _count: true }
in prisma calls such as findMany
or create
. Is it at all possible to make the get*
props optional when the XYZCount
is generated?
I did create my own XYZCount
class manually, it just didn't fix the issue since the return of findMany
call no longer matches XYZModel
due to it referencing XYZCount
.
Similar to above, I'm happy to write our own XYZModel
type as well if that is the intent. Perhaps we misunderstood the use case?
See the example findMany and type definition below:
They key detail is that using the Activity
from @generated/type-graphql
is no longer valid as a return type. This also affects returns from prisma.xyzModel.create
import { Activity, ActivityType, ChannelType } from '@generated/type-graphql'
@Authorized(supervisorEdit, adminEdit)
@Query(() => [Activity]) // Using Activity from @generated/type-graphql is no longer valid
async findManyActivity(
@Ctx() { request, activityService, prisma }: Context,
@Args(() => FindManyActivityArgs)
data: FindManyActivityArgs
): Promise<Activity[]> {
const { accountId } = getAccountIdAndUserIdFromToken(request)
const orderBy = activityService.getActivityOrderBy(data.sortColumn, data.sortOrder)
return await prisma.activity.findMany({
...activityService.getFindManyActivityWhereInput(data, accountId),
take: data.take,
skip: data.skip,
orderBy,
include: {
_count: true,
},
})
}
Autogenerated XYZModel
Example:
import { Account } from "../models/Account";
import { ActivityType } from "../models/ActivityType";
import { AgentStateActivityMapping } from "../models/AgentStateActivityMapping";
import { ChannelType } from "../models/ChannelType";
import { ScheduleActivity } from "../models/ScheduleActivity";
import { ScheduleDay } from "../models/ScheduleDay";
import { Shift } from "../models/Shift";
import { ShiftDayActivity } from "../models/ShiftDayActivity";
import { TimeOffRequest } from "../models/TimeOffRequest";
import { User } from "../models/User";
import { ActivityCount } from "../resolvers/outputs/ActivityCount";
export declare class Activity {
activity_id: string;
account?: Account;
account_id?: string;
name: string;
text_color: string;
bg_color: string;
activity_type?: ActivityType;
activity_type_id: string;
channel_types?: ChannelType[];
default_duration: number;
should_calculate_adherence: boolean;
is_paid: boolean;
allow_for_time_off: boolean;
is_deleted?: boolean;
create_time: Date;
create_by: string;
modify_time: Date;
modify_by: string;
modify?: User | null;
create?: User | null;
schedule_activities?: ScheduleActivity[];
agent_states_mapping?: AgentStateActivityMapping[];
shift_day_activities?: ShiftDayActivity[];
default_shift_activity?: Shift[];
default_shift_activity_schedule?: ScheduleDay[];
time_off_requests?: TimeOffRequest[];
_count?: ActivityCount | null;
}
Autogenerated XYZCount
import { ActivityCountAgent_states_mappingArgs } from "./args/ActivityCountAgent_states_mappingArgs";
import { ActivityCountChannel_typesArgs } from "./args/ActivityCountChannel_typesArgs";
import { ActivityCountDefault_shift_activityArgs } from "./args/ActivityCountDefault_shift_activityArgs";
import { ActivityCountDefault_shift_activity_scheduleArgs } from "./args/ActivityCountDefault_shift_activity_scheduleArgs";
import { ActivityCountSchedule_activitiesArgs } from "./args/ActivityCountSchedule_activitiesArgs";
import { ActivityCountShift_day_activitiesArgs } from "./args/ActivityCountShift_day_activitiesArgs";
import { ActivityCountTime_off_requestsArgs } from "./args/ActivityCountTime_off_requestsArgs";
export declare class ActivityCount {
channel_types: number;
schedule_activities: number;
agent_states_mapping: number;
shift_day_activities: number;
default_shift_activity: number;
default_shift_activity_schedule: number;
time_off_requests: number;
getChannel_types(root: ActivityCount, args: ActivityCountChannel_typesArgs): number;
getSchedule_activities(root: ActivityCount, args: ActivityCountSchedule_activitiesArgs): number;
getAgent_states_mapping(root: ActivityCount, args: ActivityCountAgent_states_mappingArgs): number;
getShift_day_activities(root: ActivityCount, args: ActivityCountShift_day_activitiesArgs): number;
getDefault_shift_activity(root: ActivityCount, args: ActivityCountDefault_shift_activityArgs): number;
getDefault_shift_activity_schedule(root: ActivityCount, args: ActivityCountDefault_shift_activity_scheduleArgs): number;
getTime_off_requests(root: ActivityCount, args: ActivityCountTime_off_requestsArgs): number;
}
Error: