-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update Prisma to v5 #2231
Update Prisma to v5 #2231
Changes from 5 commits
bc64a24
e64a137
580206d
791b9aa
fd32b88
358d094
73f9b9d
83426ba
3dabf1b
7ddd6a7
046e6af
7a7d17a
6e219aa
7383a72
65b31df
f3864d2
9654b9c
ae3bf9a
e58fdde
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,6 @@ | |
"typescript": "^5.1.0", | ||
"vite": "^4.3.9", | ||
"@types/react": "^18.0.37", | ||
"prisma": "4.16.2" | ||
"prisma": "5.18.0" | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,11 +5,8 @@ import { prisma } from 'wasp/server' | |
import { type {= userEntityUpper =} } from "wasp/entities" | ||
|
||
const prismaAdapter = new PrismaAdapter( | ||
// Using `as any` here since Lucia's model types are not compatible with Prisma 4 | ||
// model types. This is a temporary workaround until we migrate to Prisma 5. | ||
// This **works** in runtime, but Typescript complains about it. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Always love seeing these kind of changes! |
||
prisma.{= sessionEntityLower =} as any, | ||
prisma.{= authEntityLower =} as any | ||
prisma.{= sessionEntityLower =}, | ||
prisma.{= authEntityLower =}, | ||
); | ||
|
||
// PRIVATE API | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// Without this import, Prisma types are resolved incorrectly. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @sodic this is the fix I implemented in the end, it slightly nudges the I went down the rabbit hole of recursively converting all interfaces into types using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The code comment doesn't fully explain what's happening and what the tradeoffs are. Do you mind adding this playground link too. It currently implies that Anyway, both things should be clear from the playground, and you can adjust it as you see fit. BTW, what happend with trying to fix the root of the problem, the definition of the JSONSerializable type (as attempted here). Did Superjson make it too complex? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've updated the comment to mention the playground to make it more complete as an explanation.
We concluded that Then we set on to recursively convert all interfaces to types - which in the end was a long way of doing this |
||
import * as runtime from '@prisma/client/runtime'; | ||
|
||
// Prisma generated types which we use as default input and output types for CRUD | ||
// operations internally use interfaces for some types. | ||
// Our SuperJSON serialization types throw a type error when used with interfaces | ||
// because interfaces don't have a index signature. | ||
// We augment the Prisma generated types to have an index signature. | ||
// Read more https://github.com/microsoft/TypeScript/issues/15300#issuecomment-1320528385 | ||
declare module '@prisma/client/runtime/library.js' { | ||
export interface FieldRef<Model, FieldType> { | ||
[key: string]: any; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,9 +9,9 @@ import type { | |
UnauthenticatedQueryDefinition, | ||
{=/ isAuthEnabled =} | ||
_{= crud.entityUpper =}, | ||
} from "wasp/server/_types"; | ||
} from "../_types"; | ||
import type { Prisma } from "@prisma/client"; | ||
import { Payload } from "wasp/server/_types/serialization"; | ||
import type { Payload } from "../_types/serialization"; | ||
import type { | ||
{= crud.entityUpper =}, | ||
} from "wasp/entities"; | ||
|
@@ -103,7 +103,12 @@ export type CreateActionResolved = typeof _waspCreateAction | |
|
||
{=# crud.operations.Update =} | ||
{=^ overrides.Update.isDefined =} | ||
type UpdateInput = Prisma.{= crud.entityUpper =}UpdateInput & Prisma.{= crud.entityUpper =}WhereUniqueInput | ||
type UpdateInput = Prisma.XOR< | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixes |
||
Prisma.{= crud.entityUpper =}UpdateInput, | ||
Prisma.{= crud.entityUpper =}UncheckedUpdateInput | ||
> | ||
& Prisma.{= crud.entityUpper =}WhereUniqueInput | ||
|
||
type UpdateOutput = _WaspEntity | ||
export type UpdateActionResolved = {= crud.name =}.UpdateAction<UpdateInput, UpdateOutput> | ||
{=/ overrides.Update.isDefined =} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,26 @@ | ||
{{={= =}=}} | ||
import { prisma } from 'wasp/server'; | ||
import { prisma } from 'wasp/server' | ||
|
||
import type { Prisma } from "@prisma/client"; | ||
import type { | ||
{= crud.entityUpper =}, | ||
} from "wasp/entities"; | ||
{=# isAuthEnabled =} | ||
import { throwInvalidCredentialsError } from 'wasp/auth/utils' | ||
{=/ isAuthEnabled =} | ||
import type { {= crud.name =} } from "wasp/server/crud"; | ||
import type { | ||
{=# crud.operations.GetAll =} | ||
GetAllQueryResolved, | ||
{=/ crud.operations.GetAll =} | ||
{=# crud.operations.Get =} | ||
GetQueryResolved, | ||
{=/ crud.operations.Get =} | ||
{=# crud.operations.Create =} | ||
CreateActionResolved, | ||
{=/ crud.operations.Create =} | ||
{=# crud.operations.Update =} | ||
UpdateActionResolved, | ||
{=/ crud.operations.Update =} | ||
{=# crud.operations.Delete =} | ||
DeleteActionResolved, | ||
{=/ crud.operations.Delete =} | ||
} from 'wasp/server/crud/{= crud.name =}' | ||
{=# overrides.GetAll.isDefined =} | ||
{=& overrides.GetAll.importStatement =} | ||
{=/ overrides.GetAll.isDefined =} | ||
|
@@ -25,7 +37,6 @@ import type { {= crud.name =} } from "wasp/server/crud"; | |
{=& overrides.Delete.importStatement =} | ||
{=/ overrides.Delete.isDefined =} | ||
|
||
type _WaspEntity = {= crud.entityUpper =} | ||
const entities = { | ||
{= crud.entityUpper =}: prisma.{= crud.entityLower =}, | ||
} | ||
|
@@ -39,9 +50,7 @@ const entities = { | |
// 1. We either use the default implementation of the operation... | ||
=} | ||
{=^ overrides.GetAll.isDefined =} | ||
type GetAllInput = {} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For some reason, we built these types in two places: in the server and the in the SDK, but there was no need since the server can import the built types from the SDK. This change ensures that CRUD operation types are coming one a single source of truth. |
||
type GetAllOutput = _WaspEntity[] | ||
const _waspGetAllQuery: {= crud.name =}.GetAllQuery<GetAllInput, GetAllOutput> = ((args, context) => { | ||
const _waspGetAllQuery: GetAllQueryResolved = ((args, context) => { | ||
{=^ crud.operations.GetAll.isPublic =} | ||
throwIfNotAuthenticated(context) | ||
{=/ crud.operations.GetAll.isPublic =} | ||
|
@@ -73,9 +82,7 @@ export async function getAllFn(args, context) { | |
{=# crud.operations.Get =} | ||
// Get query | ||
{=^ overrides.Get.isDefined =} | ||
type GetInput = Prisma.{= crud.entityUpper =}WhereUniqueInput | ||
type GetOutput = _WaspEntity | null | ||
const _waspGetQuery: {= crud.name =}.GetQuery<GetInput, GetOutput> = ((args, context) => { | ||
const _waspGetQuery: GetQueryResolved = ((args, context) => { | ||
{=^ crud.operations.Get.isPublic =} | ||
throwIfNotAuthenticated(context) | ||
{=/ crud.operations.Get.isPublic =} | ||
|
@@ -97,9 +104,7 @@ export async function getFn(args, context) { | |
{=# crud.operations.Create =} | ||
// Create action | ||
{=^ overrides.Create.isDefined =} | ||
type CreateInput = Prisma.{= crud.entityUpper =}CreateInput | ||
type CreateOutput = _WaspEntity | ||
const _waspCreateAction: {= crud.name =}.CreateAction<CreateInput, CreateOutput> = ((args, context) => { | ||
const _waspCreateAction: CreateActionResolved = ((args, context) => { | ||
{=^ crud.operations.Create.isPublic =} | ||
throwIfNotAuthenticated(context) | ||
{=/ crud.operations.Create.isPublic =} | ||
|
@@ -121,9 +126,7 @@ export async function createFn(args, context) { | |
{=# crud.operations.Update =} | ||
// Update action | ||
{=^ overrides.Update.isDefined =} | ||
type UpdateInput = Prisma.{= crud.entityUpper =}UpdateInput & Prisma.{= crud.entityUpper =}WhereUniqueInput | ||
type UpdateOutput = _WaspEntity | ||
const _waspUpdateAction: {= crud.name =}.UpdateAction<UpdateInput, UpdateOutput> = ((args, context) => { | ||
const _waspUpdateAction: UpdateActionResolved = ((args, context) => { | ||
{=^ crud.operations.Update.isPublic =} | ||
throwIfNotAuthenticated(context) | ||
{=/ crud.operations.Update.isPublic =} | ||
|
@@ -149,9 +152,7 @@ export async function updateFn(args, context) { | |
{=# crud.operations.Delete =} | ||
// Delete action | ||
{=^ overrides.Delete.isDefined =} | ||
type DeleteInput = Prisma.{= crud.entityUpper =}WhereUniqueInput | ||
type DeleteOutput = _WaspEntity | ||
const _waspDeleteAction: {= crud.name =}.DeleteAction<DeleteInput, DeleteOutput> = ((args, context) => { | ||
const _waspDeleteAction: DeleteActionResolved = ((args, context) => { | ||
{=^ crud.operations.Delete.isPublic =} | ||
throwIfNotAuthenticated(context) | ||
{=/ crud.operations.Delete.isPublic =} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok sweet!