feat(prisma version updated) - v2
This commit is contained in:
1211
package-lock.json
generated
1211
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
10
package.json
10
package.json
@@ -8,9 +8,9 @@
|
|||||||
"lint": "turbo run lint",
|
"lint": "turbo run lint",
|
||||||
"check-types": "turbo run check-types",
|
"check-types": "turbo run check-types",
|
||||||
"format": "prettier --write \"**/*.{ts,tsx,md}\"",
|
"format": "prettier --write \"**/*.{ts,tsx,md}\"",
|
||||||
"db:generate": "prisma generate --schema=packages/db/prisma/schema.prisma && ts-node packages/db/scripts/patch-zod-buffer.ts",
|
"db:generate": "npx prisma generate --config=packages/db/prisma/prisma.config.ts --schema=packages/db/prisma/schema.prisma && npx ts-node packages/db/scripts/patch-prisma-imports.ts && ts-node packages/db/scripts/patch-zod-buffer.ts",
|
||||||
"db:migrate": "dotenv -e packages/db/.env -- prisma migrate dev --schema=packages/db/prisma/schema.prisma",
|
"db:migrate": "npx prisma migrate dev --config=packages/db/prisma/prisma.config.ts --schema=packages/db/prisma/schema.prisma",
|
||||||
"db:seed": "prisma db seed --schema=packages/db/prisma/schema.prisma",
|
"db:seed": "npx prisma db seed --config=packages/db/prisma/prisma.config.ts --schema=packages/db/prisma/schema.prisma",
|
||||||
"setup:env": "shx cp packages/db/prisma/.env.example packages/db/prisma/.env && shx cp apps/Frontend/.env.example apps/Frontend/.env && shx cp apps/Backend/.env.example apps/Backend/.env && shx cp apps/PatientDataExtractorService/.env.example apps/PatientDataExtractorService/.env && shx cp apps/SeleniumService/.env.example apps/SeleniumService/.env && shx cp apps/PaymentOCRService/.env.example apps/PaymentOCRService/.env",
|
"setup:env": "shx cp packages/db/prisma/.env.example packages/db/prisma/.env && shx cp apps/Frontend/.env.example apps/Frontend/.env && shx cp apps/Backend/.env.example apps/Backend/.env && shx cp apps/PatientDataExtractorService/.env.example apps/PatientDataExtractorService/.env && shx cp apps/SeleniumService/.env.example apps/SeleniumService/.env && shx cp apps/PaymentOCRService/.env.example apps/PaymentOCRService/.env",
|
||||||
"postinstall": "npm --prefix apps/PatientDataExtractorService run postinstall && npm --prefix apps/PaymentOCRService run postinstall"
|
"postinstall": "npm --prefix apps/PatientDataExtractorService run postinstall && npm --prefix apps/PaymentOCRService run postinstall"
|
||||||
},
|
},
|
||||||
@@ -21,7 +21,6 @@
|
|||||||
"@types/react-redux": "^7.1.34",
|
"@types/react-redux": "^7.1.34",
|
||||||
"prettier": "^3.5.3",
|
"prettier": "^3.5.3",
|
||||||
"prettier-plugin-tailwindcss": "^0.6.11",
|
"prettier-plugin-tailwindcss": "^0.6.11",
|
||||||
"prisma": "^6.16.2",
|
|
||||||
"turbo": "^2.5.3"
|
"turbo": "^2.5.3"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -33,11 +32,12 @@
|
|||||||
"packages/*"
|
"packages/*"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@prisma/client": "^6.16.2",
|
"@prisma/client": "^7.0.1",
|
||||||
"@reduxjs/toolkit": "^2.8.2",
|
"@reduxjs/toolkit": "^2.8.2",
|
||||||
"decimal.js": "^10.6.0",
|
"decimal.js": "^10.6.0",
|
||||||
"dotenv": "^16.5.0",
|
"dotenv": "^16.5.0",
|
||||||
"dotenv-cli": "^8.0.0",
|
"dotenv-cli": "^8.0.0",
|
||||||
|
"prisma": "^7.0.1",
|
||||||
"react-redux": "^9.2.0",
|
"react-redux": "^9.2.0",
|
||||||
"shx": "^0.4.0"
|
"shx": "^0.4.0"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,18 +12,18 @@
|
|||||||
"type": "commonjs",
|
"type": "commonjs",
|
||||||
"exports": {
|
"exports": {
|
||||||
"./client": "./src/index.ts",
|
"./client": "./src/index.ts",
|
||||||
"./shared/schemas" : "./shared/schemas/index.ts",
|
"./shared/schemas": "./shared/schemas/index.ts",
|
||||||
"./usedSchemas" : "./usedSchemas/index.ts",
|
"./usedSchemas": "./usedSchemas/index.ts",
|
||||||
"./generated/prisma" : "./generated/prisma/index.d.ts",
|
"./types": "./types/index.ts"
|
||||||
"./types" : "./types/index.ts"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@prisma/client": "^6.10.0",
|
"@prisma/adapter-pg": "^7.0.1",
|
||||||
"prisma-zod-generator": "^0.8.13"
|
"@prisma/client": "^7.0.0",
|
||||||
|
"prisma-zod-generator": "^2.1.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^22.15.17",
|
"@types/node": "^22.15.17",
|
||||||
"prisma": "^6.7.0",
|
"prisma": "^7.0.0",
|
||||||
"tsx": "^4.19.4",
|
"tsx": "^4.19.4",
|
||||||
"typescript": "^5.8.2"
|
"typescript": "^5.8.2"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,12 @@
|
|||||||
import "dotenv/config";
|
import dotenv from "dotenv";
|
||||||
|
import path from "path";
|
||||||
import { defineConfig, env } from "prisma/config";
|
import { defineConfig, env } from "prisma/config";
|
||||||
|
|
||||||
|
dotenv.config({ path: path.resolve(__dirname, ".env") });
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
// if prisma.config.ts sits in the same folder as schema.prisma:
|
schema: "schema.prisma",
|
||||||
schema: "schema.prisma", // or "prisma/schema.prisma" if config is at project root
|
|
||||||
|
|
||||||
// required with the current Prisma types
|
|
||||||
engine: "classic",
|
|
||||||
|
|
||||||
datasource: {
|
datasource: {
|
||||||
// use Prisma's env() helper instead of process.env for nicer types
|
|
||||||
url: env("DATABASE_URL"),
|
url: env("DATABASE_URL"),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
274
packages/db/scripts/patch-prisma-imports.ts
Normal file
274
packages/db/scripts/patch-prisma-imports.ts
Normal file
@@ -0,0 +1,274 @@
|
|||||||
|
#!/usr/bin/env ts-node
|
||||||
|
/**
|
||||||
|
* patch-prisma-imports.ts (SAFE)
|
||||||
|
*
|
||||||
|
* - Converts value-level imports/exports of `Prisma` -> type-only imports/exports
|
||||||
|
* (splits mixed imports).
|
||||||
|
* - Replaces runtime usages of `Prisma.Decimal` -> `Decimal`.
|
||||||
|
* - Ensures exactly one `import Decimal from "decimal.js";` per file.
|
||||||
|
* - DEDICATED: only modifies TypeScript source files (.ts/.tsx).
|
||||||
|
* - SKIPS: files under packages/db/generated/prisma (the Prisma runtime package).
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* npx ts-node packages/db/scripts/patch-prisma-imports.ts
|
||||||
|
*
|
||||||
|
* Run after `prisma generate` (and make sure generated runtime .js are restored
|
||||||
|
* if they were modified — see notes below).
|
||||||
|
*/
|
||||||
|
|
||||||
|
import fs from "fs";
|
||||||
|
import path from "path";
|
||||||
|
import fg from "fast-glob";
|
||||||
|
|
||||||
|
const repoRoot = process.cwd();
|
||||||
|
const GENERATED_FRAGMENT = path.join("packages", "db", "generated", "prisma");
|
||||||
|
|
||||||
|
// Only operate on TS sources (do NOT touch .js)
|
||||||
|
const GLOBS = [
|
||||||
|
"packages/db/shared/**/*.ts",
|
||||||
|
"packages/db/shared/**/*.tsx",
|
||||||
|
"packages/db/generated/**/*.ts",
|
||||||
|
"packages/db/generated/**/*.tsx",
|
||||||
|
];
|
||||||
|
|
||||||
|
// -------------------- helpers --------------------
|
||||||
|
|
||||||
|
function isFromGeneratedPrisma(fromPath: string) {
|
||||||
|
// match relative imports that include generated/prisma
|
||||||
|
return (
|
||||||
|
fromPath.includes("generated/prisma") ||
|
||||||
|
fromPath.includes("/generated/prisma") ||
|
||||||
|
fromPath.includes("\\generated\\prisma")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function splitSpecifiers(list: string) {
|
||||||
|
return list
|
||||||
|
.split(",")
|
||||||
|
.map((s) => s.trim())
|
||||||
|
.filter(Boolean);
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildNamedImport(specs: string[]) {
|
||||||
|
return `{ ${specs.join(", ")} }`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function extractDecimalLines(src: string) {
|
||||||
|
const lines = src.split(/\r?\n/);
|
||||||
|
const matches: number[] = [];
|
||||||
|
|
||||||
|
const regexes = [
|
||||||
|
/^import\s+Decimal\s+from\s+['"]decimal\.js['"]\s*;?/,
|
||||||
|
/^import\s+\{\s*Decimal\s*\}\s+from\s+['"]decimal\.js['"]\s*;?/,
|
||||||
|
/^import\s+\*\s+as\s+Decimal\s+from\s+['"]decimal\.js['"]\s*;?/,
|
||||||
|
/^(const|let|var)\s+Decimal\s*=\s*require\(\s*['"]decimal\.js['"]\s*\)\s*;?/,
|
||||||
|
/^(const|let|var)\s+Decimal\s*=\s*require\(\s*['"]decimal\.js['"]\s*\)\.default\s*;?/,
|
||||||
|
];
|
||||||
|
|
||||||
|
lines.forEach((line, i) => {
|
||||||
|
for (const re of regexes) {
|
||||||
|
if (re.test(line)) {
|
||||||
|
matches.push(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return { lines, matches };
|
||||||
|
}
|
||||||
|
|
||||||
|
function ensureSingleDecimalImport(src: string) {
|
||||||
|
const { lines, matches } = extractDecimalLines(src);
|
||||||
|
|
||||||
|
if (matches.length === 0) return src;
|
||||||
|
|
||||||
|
// remove all matched import/require lines
|
||||||
|
// do in reverse index order to keep indices valid
|
||||||
|
matches
|
||||||
|
.slice()
|
||||||
|
.sort((a, b) => b - a)
|
||||||
|
.forEach((idx) => lines.splice(idx, 1));
|
||||||
|
|
||||||
|
let result = lines.join("\n");
|
||||||
|
|
||||||
|
// insert single canonical import if missing
|
||||||
|
if (!/import\s+Decimal\s+from\s+['"]decimal\.js['"]/.test(result)) {
|
||||||
|
const importBlockMatch = result.match(/^(?:\s*import[\s\S]*?;\r?\n)+/);
|
||||||
|
if (importBlockMatch && importBlockMatch.index !== undefined) {
|
||||||
|
const idx = importBlockMatch[0].length;
|
||||||
|
result =
|
||||||
|
result.slice(0, idx) +
|
||||||
|
`\nimport Decimal from "decimal.js";\n` +
|
||||||
|
result.slice(idx);
|
||||||
|
} else {
|
||||||
|
result = `import Decimal from "decimal.js";\n` + result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// collapse excessive blank lines
|
||||||
|
result = result.replace(/\n{3,}/g, "\n\n");
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function replacePrismaDecimalRuntime(src: string) {
|
||||||
|
if (!/\bPrisma\.Decimal\b/.test(src)) return { out: src, changed: false };
|
||||||
|
|
||||||
|
// mask import/export-from lines so we don't accidentally change them
|
||||||
|
const placeholder =
|
||||||
|
"__MASK_IMPORT_EXPORT__" + Math.random().toString(36).slice(2);
|
||||||
|
const saved: string[] = [];
|
||||||
|
|
||||||
|
const masked = src.replace(
|
||||||
|
/(^\s*(?:import|export)\s+[\s\S]*?from\s+['"][^'"]+['"]\s*;?)/gm,
|
||||||
|
(m) => {
|
||||||
|
saved.push(m);
|
||||||
|
return `${placeholder}${saved.length - 1}__\n`;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const replaced = masked.replace(/\bPrisma\.Decimal\b/g, "Decimal");
|
||||||
|
|
||||||
|
const restored = replaced.replace(
|
||||||
|
new RegExp(`${placeholder}(\\d+)__\\n`, "g"),
|
||||||
|
(_m, i) => saved[Number(i)] || ""
|
||||||
|
);
|
||||||
|
|
||||||
|
return { out: restored, changed: true };
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------- patching logic --------------------
|
||||||
|
|
||||||
|
function patchFileContent(src: string, filePath: string) {
|
||||||
|
// safety: do not edit runtime prisma package files
|
||||||
|
const normalized = path.normalize(filePath);
|
||||||
|
if (normalized.includes(path.normalize(GENERATED_FRAGMENT))) {
|
||||||
|
// skip any files inside packages/db/generated/prisma
|
||||||
|
return { out: src, changed: false, skipped: true };
|
||||||
|
}
|
||||||
|
|
||||||
|
let out = src;
|
||||||
|
let changed = false;
|
||||||
|
|
||||||
|
// 1) Named imports
|
||||||
|
out = out.replace(
|
||||||
|
/import\s+(?!type)(\{[^}]+\})\s+from\s+(['"])([^'"]+)\2\s*;?/gm,
|
||||||
|
(match, specBlock: string, q: string, fromPath: string) => {
|
||||||
|
if (!isFromGeneratedPrisma(fromPath)) return match;
|
||||||
|
|
||||||
|
const specList = specBlock.replace(/^\{|\}$/g, "").trim();
|
||||||
|
const specs = splitSpecifiers(specList);
|
||||||
|
|
||||||
|
const prismaEntries = specs.filter((s) =>
|
||||||
|
/^\s*Prisma(\s+as\s+\w+)?\s*$/.test(s)
|
||||||
|
);
|
||||||
|
const otherEntries = specs.filter(
|
||||||
|
(s) => !/^\s*Prisma(\s+as\s+\w+)?\s*$/.test(s)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (prismaEntries.length === 0) return match;
|
||||||
|
|
||||||
|
changed = true;
|
||||||
|
let replacement = `import type ${buildNamedImport(prismaEntries)} from ${q}${fromPath}${q};`;
|
||||||
|
if (otherEntries.length > 0) {
|
||||||
|
replacement += `\nimport ${buildNamedImport(otherEntries)} from ${q}${fromPath}${q};`;
|
||||||
|
}
|
||||||
|
return replacement;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 2) Named exports
|
||||||
|
out = out.replace(
|
||||||
|
/export\s+(?!type)(\{[^}]+\})\s+from\s+(['"])([^'"]+)\2\s*;?/gm,
|
||||||
|
(match, specBlock: string, q: string, fromPath: string) => {
|
||||||
|
if (!isFromGeneratedPrisma(fromPath)) return match;
|
||||||
|
|
||||||
|
const specList = specBlock.replace(/^\{|\}$/g, "").trim();
|
||||||
|
const specs = splitSpecifiers(specList);
|
||||||
|
|
||||||
|
const prismaEntries = specs.filter((s) =>
|
||||||
|
/^\s*Prisma(\s+as\s+\w+)?\s*$/.test(s)
|
||||||
|
);
|
||||||
|
const otherEntries = specs.filter(
|
||||||
|
(s) => !/^\s*Prisma(\s+as\s+\w+)?\s*$/.test(s)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (prismaEntries.length === 0) return match;
|
||||||
|
|
||||||
|
changed = true;
|
||||||
|
let replacement = `export type ${buildNamedImport(prismaEntries)} from ${q}${fromPath}${q};`;
|
||||||
|
if (otherEntries.length > 0) {
|
||||||
|
replacement += `\nexport ${buildNamedImport(otherEntries)} from ${q}${fromPath}${q};`;
|
||||||
|
}
|
||||||
|
return replacement;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 3) Namespace imports
|
||||||
|
out = out.replace(
|
||||||
|
/import\s+\*\s+as\s+([A-Za-z0-9_$]+)\s+from\s+(['"])([^'"]+)\2\s*;?/gm,
|
||||||
|
(match, ns: string, q: string, fromPath: string) => {
|
||||||
|
if (!isFromGeneratedPrisma(fromPath)) return match;
|
||||||
|
changed = true;
|
||||||
|
return `import type * as ${ns} from ${q}${fromPath}${q};`;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 4) Default imports
|
||||||
|
out = out.replace(
|
||||||
|
/import\s+(?!type)([A-Za-z0-9_$]+)\s+from\s+(['"])([^'"]+)\2\s*;?/gm,
|
||||||
|
(match, binding: string, q: string, fromPath: string) => {
|
||||||
|
if (!isFromGeneratedPrisma(fromPath)) return match;
|
||||||
|
changed = true;
|
||||||
|
return `import type ${binding} from ${q}${fromPath}${q};`;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 5) Replace Prisma.Decimal -> Decimal safely
|
||||||
|
if (/\bPrisma\.Decimal\b/.test(out)) {
|
||||||
|
const { out: decimalOut, changed: decimalChanged } =
|
||||||
|
replacePrismaDecimalRuntime(out);
|
||||||
|
out = decimalOut;
|
||||||
|
if (decimalChanged) changed = true;
|
||||||
|
// Ensure a single Decimal import exists
|
||||||
|
out = ensureSingleDecimalImport(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
return { out, changed, skipped: false };
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------- runner --------------------
|
||||||
|
|
||||||
|
async function run() {
|
||||||
|
const files = await fg(GLOBS, { absolute: true, cwd: repoRoot, dot: true });
|
||||||
|
if (!files || files.length === 0) {
|
||||||
|
console.warn(
|
||||||
|
"No files matched. Check the GLOBS patterns and run from repo root."
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const file of files) {
|
||||||
|
try {
|
||||||
|
const src = fs.readFileSync(file, "utf8");
|
||||||
|
const { out, changed, skipped } = patchFileContent(src, file);
|
||||||
|
if (skipped) {
|
||||||
|
// intentionally skipped runtime-prisma files
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (changed && out !== src) {
|
||||||
|
fs.writeFileSync(file, out, "utf8");
|
||||||
|
console.log("patched:", path.relative(repoRoot, file));
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("failed patching", file, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("done.");
|
||||||
|
}
|
||||||
|
|
||||||
|
run().catch((err) => {
|
||||||
|
console.error(err);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
@@ -1,8 +1,152 @@
|
|||||||
import { PrismaClient } from "../generated/prisma";
|
import dotenv from "dotenv";
|
||||||
|
dotenv.config();
|
||||||
|
|
||||||
const globalForPrisma = global as unknown as { prisma: PrismaClient };
|
type AnyFn = new (...a: any[]) => any;
|
||||||
|
let PrismaClientCtor: AnyFn | undefined;
|
||||||
|
|
||||||
|
// --- load generated or installed PrismaClient ctor ---
|
||||||
|
try {
|
||||||
|
// prefer the local generated client in the monorepo
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports
|
||||||
|
const local = require("../generated/prisma");
|
||||||
|
PrismaClientCtor =
|
||||||
|
local.PrismaClient ||
|
||||||
|
local.default ||
|
||||||
|
(typeof local === "function" ? local : undefined);
|
||||||
|
} catch (e) {
|
||||||
|
try {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports
|
||||||
|
const installed = require("@prisma/client");
|
||||||
|
PrismaClientCtor =
|
||||||
|
installed.PrismaClient ||
|
||||||
|
installed.default ||
|
||||||
|
(typeof installed === "function" ? installed : undefined);
|
||||||
|
} catch (e2) {
|
||||||
|
throw new Error(
|
||||||
|
"Unable to load PrismaClient from local generated client or @prisma/client. Run `npm run db:generate` and ensure the generated client exists."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!PrismaClientCtor) {
|
||||||
|
throw new Error(
|
||||||
|
"PrismaClient constructor not found in loaded prisma package."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
type PrismaClientType = InstanceType<typeof PrismaClientCtor>;
|
||||||
|
const globalForPrisma = global as unknown as { prisma?: PrismaClientType };
|
||||||
|
|
||||||
|
// --- robust adapter loader & diagnostics ---
|
||||||
|
function tryLoadPgAdapter() {
|
||||||
|
try {
|
||||||
|
// require the package
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports
|
||||||
|
const mod = require("@prisma/adapter-pg");
|
||||||
|
|
||||||
|
// possible export names we've seen in docs / examples
|
||||||
|
const candidates = [
|
||||||
|
"PrismaPg",
|
||||||
|
"PrismaPgAdapter",
|
||||||
|
"PrismaPgAdapterDefault",
|
||||||
|
"default",
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const name of candidates) {
|
||||||
|
const candidate = (mod &&
|
||||||
|
(mod[name] || (name === "default" && mod.default))) as any;
|
||||||
|
if (typeof candidate === "function") {
|
||||||
|
return { ctor: candidate, usedExport: name, module: mod };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if module itself is a ctor (commonjs default export)
|
||||||
|
if (typeof mod === "function") {
|
||||||
|
return { ctor: mod, usedExport: "moduleAsCtor", module: mod };
|
||||||
|
}
|
||||||
|
|
||||||
|
// no usable export found
|
||||||
|
return { ctor: undefined, usedExport: undefined, module: mod };
|
||||||
|
} catch (err: any) {
|
||||||
|
return { error: err };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createPgAdapterInstance(ctor: any) {
|
||||||
|
const dbUrl = process.env.DATABASE_URL;
|
||||||
|
// different adapter versions accept different option names; attempt common ones
|
||||||
|
const tryOptions = [
|
||||||
|
{ connectionString: dbUrl },
|
||||||
|
{ url: dbUrl },
|
||||||
|
{ connectionString: dbUrl || "" },
|
||||||
|
{ url: dbUrl || "" },
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const opts of tryOptions) {
|
||||||
|
try {
|
||||||
|
const inst = new ctor(opts);
|
||||||
|
return { instance: inst, optsUsed: opts };
|
||||||
|
} catch (err) {
|
||||||
|
// ignore and try next shape
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// final attempt: no args
|
||||||
|
try {
|
||||||
|
return { instance: new ctor(), optsUsed: null };
|
||||||
|
} catch (err) {
|
||||||
|
return { instance: undefined };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to load adapter only for Postgres projects (your schema shows provider = "postgresql")
|
||||||
|
const adapterLoadResult = tryLoadPgAdapter();
|
||||||
|
|
||||||
|
if (adapterLoadResult.error) {
|
||||||
|
// adapter package couldn't be required at all
|
||||||
|
console.warn(
|
||||||
|
"[prisma-adapter] require('@prisma/adapter-pg') failed:",
|
||||||
|
adapterLoadResult.error.message || adapterLoadResult.error
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let adapter: any | undefined;
|
||||||
|
|
||||||
|
if (adapterLoadResult.ctor) {
|
||||||
|
const { instance, optsUsed } = createPgAdapterInstance(
|
||||||
|
adapterLoadResult.ctor
|
||||||
|
);
|
||||||
|
adapter = instance;
|
||||||
|
// console.info("[prisma-adapter] Found adapter export:", adapterLoadResult.usedExport, "optsUsed:", optsUsed);
|
||||||
|
} else if (adapterLoadResult.module) {
|
||||||
|
console.warn(
|
||||||
|
"[prisma-adapter] module loaded but no ctor export found. Keys:",
|
||||||
|
Object.keys(adapterLoadResult.module)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If adapter couldn't be constructed, fail loud — constructing PrismaClient without adapter on v7 causes obscure __internal errors.
|
||||||
|
if (!adapter) {
|
||||||
|
const missing = adapterLoadResult.error
|
||||||
|
? "package-not-installed"
|
||||||
|
: "no-export-or-constructor";
|
||||||
|
const msg = [
|
||||||
|
"Prisma adapter for Postgres could not be created.",
|
||||||
|
`reason=${missing}`,
|
||||||
|
"To fix: ensure you have @prisma/adapter-pg installed in the package where this code runs and that its peer 'pg' (node-postgres) is resolvable.",
|
||||||
|
"Examples:",
|
||||||
|
" npm install @prisma/adapter-pg pg",
|
||||||
|
"or in monorepo: npm --workspace packages/db install @prisma/adapter-pg pg",
|
||||||
|
"After installing, run: npm run db:generate and restart dev server.",
|
||||||
|
].join(" ");
|
||||||
|
// throw so we don't instantiate PrismaClient and get the __internal crash
|
||||||
|
throw new Error(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// instantiate prisma with adapter
|
||||||
export const prisma =
|
export const prisma =
|
||||||
globalForPrisma.prisma || new PrismaClient();
|
globalForPrisma.prisma || new PrismaClientCtor({ adapter });
|
||||||
|
|
||||||
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;
|
if (process.env.NODE_ENV !== "production") {
|
||||||
|
globalForPrisma.prisma = prisma;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user