Skip to content

Commit 1af3b40

Browse files
tywenkclaude
andcommitted
Resolve clientPath against consuming project's CWD
Normalize relative and absolute filesystem clientPath values to file:// URLs before dynamic import so they resolve from the project root instead of this module's install location. Bare specifiers and existing file:// URLs pass through unchanged. Adds a regression test covering the file:// URL path used by the Prisma 7 setup. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 9ca03c4 commit 1af3b40

3 files changed

Lines changed: 35 additions & 3 deletions

File tree

src/contest.test.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { resolve } from 'node:path';
2+
import { pathToFileURL } from 'node:url';
13
import { beforeEach, describe, expect, it, vi } from 'vitest';
24
import {
35
type PrismaClient as PrismaClientStub,
@@ -21,7 +23,7 @@ const makeContext = async (
2123
| 'transactionEnded' = 'transactionPending',
2224
): Promise<[Awaited<ReturnType<typeof createContext>>, PrismaClientStub]> => {
2325
const context = await createContext({
24-
clientPath: '../test/prisma-client-stub.js',
26+
clientPath: './test/prisma-client-stub.js',
2527
databaseUrl: 'postgres://fake',
2628
log: ['query'],
2729
transactionOptions: { timeout: 123 },
@@ -53,6 +55,24 @@ describe('createContext', () => {
5355
await ctx.teardown();
5456
});
5557

58+
it('accepts an absolute file:// URL as clientPath', async () => {
59+
vi.stubEnv('DATABASE_URL', 'postgres://fake');
60+
const fileUrl = pathToFileURL(resolve('./test/prisma-client-stub.js')).href;
61+
const ctx = await createContext({
62+
clientPath: fileUrl,
63+
databaseUrl: 'postgres://fake',
64+
log: ['query'],
65+
transactionOptions: { timeout: 123 },
66+
});
67+
await ctx.setup();
68+
69+
expect(PrismaPgMock).toHaveBeenCalledWith({
70+
connectionString: 'postgres://fake',
71+
});
72+
73+
await ctx.teardown();
74+
});
75+
5676
it('throws when client is accessed outside of a test transaction', async () => {
5777
const [transactionPendingContext] = await makeContext('transactionPending');
5878
const [transactionEndedContext] = await makeContext('transactionEnded');

src/context.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { isAbsolute, resolve } from 'node:path';
2+
import { pathToFileURL } from 'node:url';
13
import { PrismaPg } from '@prisma/adapter-pg';
24
import type {
35
PrismaClientLike,
@@ -28,7 +30,17 @@ export async function createContext(options: PrismaPostgresEnvironmentOptions) {
2830
*/
2931
let internalEndTestTransaction: (() => void) | null = null;
3032

31-
const { PrismaClient } = await import(options.clientPath);
33+
// Normalize clientPath so relative/absolute filesystem paths resolve against
34+
// the consuming project's CWD instead of this module's location. Leave bare
35+
// module specifiers (e.g. '@prisma/client') and existing file:// URLs
36+
// untouched so ESM resolution handles them as-is.
37+
const isPathLike =
38+
options.clientPath.startsWith('.') || isAbsolute(options.clientPath);
39+
const clientImportPath = isPathLike
40+
? pathToFileURL(resolve(options.clientPath)).href
41+
: options.clientPath;
42+
43+
const { PrismaClient } = await import(clientImportPath);
3244
const originalClient: PrismaClientLike = new PrismaClient({
3345
adapter: new PrismaPg({ connectionString: process.env.DATABASE_URL }),
3446
log: options.log,

src/index.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import environment from '../src/index.js';
2424
describe('prisma-postgres environment', () => {
2525
const global: any = {};
2626
const options = {
27-
clientPath: '../test/prisma-client-stub.js',
27+
clientPath: './test/prisma-client-stub.js',
2828
};
2929

3030
beforeEach(() => {

0 commit comments

Comments
 (0)