nitropage
Version:
A free and open source, extensible visual page builder based on SolidStart.
74 lines (63 loc) • 2.39 kB
text/typescript
import { PrismaClient } from "@prisma/client";
import { readFileSync } from "node:fs";
import { isAbsolute, join } from "node:path";
import { useServerConfig } from "./config";
import { createGlobal } from "./util";
import { onceWithGlobalThis } from "./util/once";
// TODO: Prisma 7 will remove pkg based config, we need a different approach
export const getSchemaRootDir = onceWithGlobalThis(
"prismaSchemaRootDir",
() => {
const cwd = process.cwd();
const pkg = JSON.parse(readFileSync(join(cwd, "package.json"), "utf-8"));
const pkgSchema = pkg.prisma?.schema;
return join(cwd, pkgSchema ?? "prisma");
},
);
// Prismas default DATABASE_URL resolution doesnt work nicely with nitro build
// This makes sure that relative urls are resolved to their proper absolute path (based on cwd)
// https://github.com/nuxt/nuxt/issues/22738
// https://github.com/prisma/prisma/issues/2559
const resolveRelativeDatasourceUrl = function (url?: string) {
const FILE_INDICATOR = "file:";
if (!url?.startsWith(FILE_INDICATOR)) {
return url;
}
const rawUrl = url.replace(FILE_INDICATOR, "");
if (isAbsolute(rawUrl)) {
return rawUrl;
}
const newUrl = FILE_INDICATOR + join(getSchemaRootDir(), rawUrl);
return newUrl;
};
export type PrismaClientOptions = ConstructorParameters<typeof PrismaClient>[0];
const createClient = (options?: PrismaClientOptions) => {
const prisma = new PrismaClient({
log: import.meta.env?.DEV ? ["error", "warn"] : ["error"],
datasourceUrl: resolveRelativeDatasourceUrl(process.env["DATABASE_URL"]),
...options,
});
return prisma;
};
export const [useDatabase, setDatabase] =
createGlobal<ReturnType<typeof createClient>>("npDatabase");
const initDatabase = () => {
const config = useServerConfig();
setDatabase(() => createClient(config.database?.prisma));
};
export default initDatabase;
export const connectOrDisconnect = (
id?: string | null,
connectOnly = false,
) => {
if (id) return { connect: { id } };
if (connectOnly) return;
return { disconnect: true };
};
/**
* Prisma uses null to unset nullable columns
*
* This utitlity checks if a key exists but is undefined. In that case it returns null, so that Prisma properly unsets the column
*/
export const nullable = <T extends {}, K extends keyof T>(obj: T, key: K) =>
key in obj && obj[key] === undefined ? null : obj[key];