Skip to content

Instantly share code, notes, and snippets.

@hasparus
Last active January 21, 2021 20:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hasparus/878cf5828505290090199f154b223d7e to your computer and use it in GitHub Desktop.
Save hasparus/878cf5828505290090199f154b223d7e to your computer and use it in GitHub Desktop.
// Imagine that @prisma/client is a normal library and it doesn't have different types in userspace and libraries
import {GetEvents, LogDefinition, LogLevel, PrismaClient, PrismaClientOptions} from "@prisma/client"
import {exec} from "child_process"
interface EnhancedPrismaClient<
// TypeScript doesn't have higher (i.e. * -> * -> *) order types, so
// we can't use anything like ConstructorParameters<typeof PrismaClient>,
// because ConstructorParameter will "strip" generics.
//
// The only way to preserve generic parameters is to copy them.
T extends PrismaClientOptions = PrismaClientOptions,
U = keyof T extends "log"
? T["log"] extends Array<LogLevel | LogDefinition>
? GetEvents<T["log"]>
: never
: never
> extends PrismaClient<T, U> {
$reset: () => Promise<void>
}
interface EnhancedPrismaClientConstructor {
new <
T extends PrismaClientOptions = PrismaClientOptions,
U = keyof T extends "log"
? T["log"] extends Array<LogLevel | LogDefinition>
? GetEvents<T["log"]>
: never
: never
>(
options?: T,
): EnhancedPrismaClient<T, U>
}
export const enhancePrisma = (base: typeof PrismaClient): EnhancedPrismaClientConstructor => {
return new Proxy(base as EnhancedPrismaClientConstructor, {
construct(target, args) {
if (typeof window !== "undefined" && process.env.JEST_WORKER_ID === undefined) {
// Return empty object if in the browser
// Skip in Jest tests because window is defined in Jest tests
return {}
}
if (!global._blitz_prismaClient) {
const client = new target(...args) as EnhancedPrismaClient
client.$reset = function reset() {
if (process.env.NODE_ENV === "production") {
throw new Error(
"You are calling db.$reset() in a production environment. We think you probably didn't mean to do that, so we are throwing this error instead of destroying your life's work.",
)
}
return new Promise<void>((res, rej) =>
exec("prisma migrate reset --force --skip-generate --preview-feature", function (err) {
if (err) {
rej(err)
} else {
res()
}
}),
)
}
global._blitz_prismaClient = client
}
return global._blitz_prismaClient
},
})
}
const EnhancedPrisma = enhancePrisma(PrismaClient)
export * from "@prisma/client"
export default new EnhancedPrisma()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment