prisma-flare 1.1.6 → 1.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -376,25 +376,6 @@ function hasCustomPrismaOutput(rootDir) {
376
376
  }
377
377
 
378
378
  // src/cli/generate-client.ts
379
- function createSymlinkSafe(target, linkPath) {
380
- try {
381
- if (fs5.existsSync(linkPath)) {
382
- const stats = fs5.lstatSync(linkPath);
383
- if (stats.isSymbolicLink()) {
384
- fs5.unlinkSync(linkPath);
385
- } else if (stats.isDirectory()) {
386
- fs5.rmSync(linkPath, { recursive: true });
387
- } else {
388
- fs5.unlinkSync(linkPath);
389
- }
390
- }
391
- const linkType = process.platform === "win32" ? "junction" : "dir";
392
- fs5.symlinkSync(target, linkPath, linkType);
393
- return true;
394
- } catch (error) {
395
- return false;
396
- }
397
- }
398
379
  function generateClient() {
399
380
  const rootDir = findProjectRoot(process.cwd());
400
381
  const config = loadConfig(rootDir);
@@ -404,35 +385,28 @@ function generateClient() {
404
385
  } else {
405
386
  prismaClientImport = getPrismaClientPath(rootDir);
406
387
  }
388
+ const isCustomOutput = hasCustomPrismaOutput(rootDir);
389
+ generateInNodeModules(rootDir, prismaClientImport, isCustomOutput);
390
+ if (isCustomOutput || config.prismaClientPath && config.prismaClientPath !== "@prisma/client") {
391
+ generateNextToPrismaClient(rootDir, prismaClientImport);
392
+ }
393
+ }
394
+ function generateInNodeModules(rootDir, prismaClientImport, isCustomOutput) {
407
395
  const nodeModulesDir = path5.join(rootDir, "node_modules");
408
396
  const prismaFlareDir = path5.join(nodeModulesDir, ".prisma-flare");
409
397
  if (!fs5.existsSync(prismaFlareDir)) {
410
398
  fs5.mkdirSync(prismaFlareDir, { recursive: true });
411
399
  }
412
400
  let resolvedImport;
413
- let useSymlink = false;
414
401
  if (prismaClientImport === "@prisma/client") {
415
402
  resolvedImport = "@prisma/client";
416
403
  } else {
417
- const symlinkPath = path5.join(prismaFlareDir, "prisma-client");
418
- let targetDir = prismaClientImport;
419
- if (targetDir.endsWith("/client") || targetDir.endsWith("\\client")) {
420
- targetDir = path5.dirname(targetDir);
421
- }
422
- if (createSymlinkSafe(targetDir, symlinkPath)) {
423
- useSymlink = true;
424
- const hasClientEntry = fs5.existsSync(path5.join(targetDir, "client.ts")) || fs5.existsSync(path5.join(targetDir, "client.js"));
425
- resolvedImport = hasClientEntry ? "./prisma-client/client" : "./prisma-client";
426
- } else {
427
- console.warn("\u26A0\uFE0F Could not create symlink. Some bundlers may have issues with the generated import path.");
428
- resolvedImport = path5.relative(prismaFlareDir, prismaClientImport);
429
- if (!resolvedImport.startsWith(".")) {
430
- resolvedImport = "./" + resolvedImport;
431
- }
432
- resolvedImport = resolvedImport.replace(/\\/g, "/");
404
+ resolvedImport = path5.relative(prismaFlareDir, prismaClientImport);
405
+ if (!resolvedImport.startsWith(".")) {
406
+ resolvedImport = "./" + resolvedImport;
433
407
  }
408
+ resolvedImport = resolvedImport.replace(/\\/g, "/");
434
409
  }
435
- const isCustomOutput = hasCustomPrismaOutput(rootDir);
436
410
  const esmContent = `// Generated by prisma-flare - DO NOT EDIT
437
411
  // This file provides FlareClient configured for your Prisma client output path
438
412
  // Import path: ${prismaClientImport}
@@ -519,16 +493,77 @@ export declare class FlareClient extends BasePrismaClient {
519
493
  JSON.stringify(packageJson, null, 2)
520
494
  );
521
495
  if (isCustomOutput) {
522
- console.log(`\u2705 Generated prisma-flare client with custom Prisma output: ${prismaClientImport}`);
523
- if (useSymlink) {
524
- console.log(` Using symlink for bundler compatibility`);
525
- }
496
+ console.log(`\u2705 Generated .prisma-flare with custom Prisma output: ${prismaClientImport}`);
497
+ console.log(` Location: ${prismaFlareDir}`);
498
+ console.log(`
499
+ \u26A0\uFE0F For Turbopack/bundler compatibility, import from the generated flare.ts instead.`);
526
500
  } else {
527
501
  console.log(`\u2705 Generated prisma-flare client using @prisma/client`);
502
+ console.log(` Location: ${prismaFlareDir}`);
503
+ console.log(`
504
+ Import: import { FlareClient } from 'prisma-flare';`);
528
505
  }
529
- console.log(` Location: ${prismaFlareDir}`);
506
+ }
507
+ function generateNextToPrismaClient(rootDir, prismaClientImport) {
508
+ let prismaOutputDir = prismaClientImport;
509
+ if (prismaOutputDir.endsWith("/client") || prismaOutputDir.endsWith("\\client")) {
510
+ prismaOutputDir = path5.dirname(prismaOutputDir);
511
+ }
512
+ const hasClientEntry = fs5.existsSync(path5.join(prismaOutputDir, "client.ts")) || fs5.existsSync(path5.join(prismaOutputDir, "client.js"));
513
+ const prismaImportPath = hasClientEntry ? "./client" : "./index";
514
+ const flareFilePath = path5.join(prismaOutputDir, "flare.ts");
515
+ const flareContent = `// Generated by prisma-flare - DO NOT EDIT
516
+ // This file provides FlareClient configured for your Prisma client
517
+ // Re-run 'npx prisma-flare generate' after 'npx prisma generate'
518
+
519
+ import { PrismaClient, Prisma } from '${prismaImportPath}';
520
+ import { createFlareClient } from 'prisma-flare';
521
+
522
+ // Create and export FlareClient using the factory
523
+ export const FlareClient = createFlareClient(PrismaClient, Prisma);
524
+
525
+ // Re-export PrismaClient and Prisma for convenience
526
+ export { PrismaClient, Prisma };
527
+
528
+ // Re-export types from prisma-flare for convenience
529
+ export type { FlareClientOptions, ModelName } from 'prisma-flare';
530
+ export { default as FlareBuilder } from 'prisma-flare/flareBuilder';
531
+ `;
532
+ const flareDtsPath = path5.join(prismaOutputDir, "flare.d.ts");
533
+ const flareDtsContent = `// Generated by prisma-flare - DO NOT EDIT
534
+ // TypeScript declarations for FlareClient
535
+
536
+ import { PrismaClient as BasePrismaClient, Prisma as BasePrisma } from '${prismaImportPath}';
537
+ import type { FlareClientOptions, ModelName } from 'prisma-flare';
538
+ import type FlareBuilder from 'prisma-flare/flareBuilder';
539
+
540
+ // Re-export PrismaClient and Prisma
541
+ export { BasePrismaClient as PrismaClient, BasePrisma as Prisma };
542
+
543
+ // Re-export types from prisma-flare
544
+ export type { FlareClientOptions, ModelName };
545
+ export { FlareBuilder };
546
+
547
+ // FlareClient type that extends the project's PrismaClient
548
+ export declare const FlareClient: {
549
+ new (options?: FlareClientOptions): BasePrismaClient & {
550
+ from<T extends ModelName>(modelName: T): FlareBuilder<T>;
551
+ transaction<R>(
552
+ fn: (tx: BasePrismaClient) => Promise<R>,
553
+ options?: { maxWait?: number; timeout?: number; isolationLevel?: any }
554
+ ): Promise<R>;
555
+ };
556
+ };
557
+ `;
558
+ fs5.writeFileSync(flareFilePath, flareContent);
559
+ fs5.writeFileSync(flareDtsPath, flareDtsContent);
560
+ const relativeFlareDir = path5.relative(rootDir, prismaOutputDir);
561
+ const relativeImportPath = "./" + path5.join(relativeFlareDir, "flare").replace(/\\/g, "/");
562
+ console.log(`\u2705 Generated prisma-flare client with custom Prisma output`);
563
+ console.log(` Location: ${prismaOutputDir}`);
564
+ console.log(` Files: flare.ts, flare.d.ts`);
530
565
  console.log(`
531
- Import: import { FlareClient } from 'prisma-flare';`);
566
+ Import: import { FlareClient } from '${relativeImportPath}';`);
532
567
  }
533
568
 
534
569
  // src/cli/index.ts
package/dist/cli/index.js CHANGED
@@ -353,25 +353,6 @@ function hasCustomPrismaOutput(rootDir) {
353
353
  }
354
354
 
355
355
  // src/cli/generate-client.ts
356
- function createSymlinkSafe(target, linkPath) {
357
- try {
358
- if (fs5.existsSync(linkPath)) {
359
- const stats = fs5.lstatSync(linkPath);
360
- if (stats.isSymbolicLink()) {
361
- fs5.unlinkSync(linkPath);
362
- } else if (stats.isDirectory()) {
363
- fs5.rmSync(linkPath, { recursive: true });
364
- } else {
365
- fs5.unlinkSync(linkPath);
366
- }
367
- }
368
- const linkType = process.platform === "win32" ? "junction" : "dir";
369
- fs5.symlinkSync(target, linkPath, linkType);
370
- return true;
371
- } catch (error) {
372
- return false;
373
- }
374
- }
375
356
  function generateClient() {
376
357
  const rootDir = findProjectRoot(process.cwd());
377
358
  const config = loadConfig(rootDir);
@@ -381,35 +362,28 @@ function generateClient() {
381
362
  } else {
382
363
  prismaClientImport = getPrismaClientPath(rootDir);
383
364
  }
365
+ const isCustomOutput = hasCustomPrismaOutput(rootDir);
366
+ generateInNodeModules(rootDir, prismaClientImport, isCustomOutput);
367
+ if (isCustomOutput || config.prismaClientPath && config.prismaClientPath !== "@prisma/client") {
368
+ generateNextToPrismaClient(rootDir, prismaClientImport);
369
+ }
370
+ }
371
+ function generateInNodeModules(rootDir, prismaClientImport, isCustomOutput) {
384
372
  const nodeModulesDir = path5.join(rootDir, "node_modules");
385
373
  const prismaFlareDir = path5.join(nodeModulesDir, ".prisma-flare");
386
374
  if (!fs5.existsSync(prismaFlareDir)) {
387
375
  fs5.mkdirSync(prismaFlareDir, { recursive: true });
388
376
  }
389
377
  let resolvedImport;
390
- let useSymlink = false;
391
378
  if (prismaClientImport === "@prisma/client") {
392
379
  resolvedImport = "@prisma/client";
393
380
  } else {
394
- const symlinkPath = path5.join(prismaFlareDir, "prisma-client");
395
- let targetDir = prismaClientImport;
396
- if (targetDir.endsWith("/client") || targetDir.endsWith("\\client")) {
397
- targetDir = path5.dirname(targetDir);
398
- }
399
- if (createSymlinkSafe(targetDir, symlinkPath)) {
400
- useSymlink = true;
401
- const hasClientEntry = fs5.existsSync(path5.join(targetDir, "client.ts")) || fs5.existsSync(path5.join(targetDir, "client.js"));
402
- resolvedImport = hasClientEntry ? "./prisma-client/client" : "./prisma-client";
403
- } else {
404
- console.warn("\u26A0\uFE0F Could not create symlink. Some bundlers may have issues with the generated import path.");
405
- resolvedImport = path5.relative(prismaFlareDir, prismaClientImport);
406
- if (!resolvedImport.startsWith(".")) {
407
- resolvedImport = "./" + resolvedImport;
408
- }
409
- resolvedImport = resolvedImport.replace(/\\/g, "/");
381
+ resolvedImport = path5.relative(prismaFlareDir, prismaClientImport);
382
+ if (!resolvedImport.startsWith(".")) {
383
+ resolvedImport = "./" + resolvedImport;
410
384
  }
385
+ resolvedImport = resolvedImport.replace(/\\/g, "/");
411
386
  }
412
- const isCustomOutput = hasCustomPrismaOutput(rootDir);
413
387
  const esmContent = `// Generated by prisma-flare - DO NOT EDIT
414
388
  // This file provides FlareClient configured for your Prisma client output path
415
389
  // Import path: ${prismaClientImport}
@@ -496,16 +470,77 @@ export declare class FlareClient extends BasePrismaClient {
496
470
  JSON.stringify(packageJson, null, 2)
497
471
  );
498
472
  if (isCustomOutput) {
499
- console.log(`\u2705 Generated prisma-flare client with custom Prisma output: ${prismaClientImport}`);
500
- if (useSymlink) {
501
- console.log(` Using symlink for bundler compatibility`);
502
- }
473
+ console.log(`\u2705 Generated .prisma-flare with custom Prisma output: ${prismaClientImport}`);
474
+ console.log(` Location: ${prismaFlareDir}`);
475
+ console.log(`
476
+ \u26A0\uFE0F For Turbopack/bundler compatibility, import from the generated flare.ts instead.`);
503
477
  } else {
504
478
  console.log(`\u2705 Generated prisma-flare client using @prisma/client`);
479
+ console.log(` Location: ${prismaFlareDir}`);
480
+ console.log(`
481
+ Import: import { FlareClient } from 'prisma-flare';`);
505
482
  }
506
- console.log(` Location: ${prismaFlareDir}`);
483
+ }
484
+ function generateNextToPrismaClient(rootDir, prismaClientImport) {
485
+ let prismaOutputDir = prismaClientImport;
486
+ if (prismaOutputDir.endsWith("/client") || prismaOutputDir.endsWith("\\client")) {
487
+ prismaOutputDir = path5.dirname(prismaOutputDir);
488
+ }
489
+ const hasClientEntry = fs5.existsSync(path5.join(prismaOutputDir, "client.ts")) || fs5.existsSync(path5.join(prismaOutputDir, "client.js"));
490
+ const prismaImportPath = hasClientEntry ? "./client" : "./index";
491
+ const flareFilePath = path5.join(prismaOutputDir, "flare.ts");
492
+ const flareContent = `// Generated by prisma-flare - DO NOT EDIT
493
+ // This file provides FlareClient configured for your Prisma client
494
+ // Re-run 'npx prisma-flare generate' after 'npx prisma generate'
495
+
496
+ import { PrismaClient, Prisma } from '${prismaImportPath}';
497
+ import { createFlareClient } from 'prisma-flare';
498
+
499
+ // Create and export FlareClient using the factory
500
+ export const FlareClient = createFlareClient(PrismaClient, Prisma);
501
+
502
+ // Re-export PrismaClient and Prisma for convenience
503
+ export { PrismaClient, Prisma };
504
+
505
+ // Re-export types from prisma-flare for convenience
506
+ export type { FlareClientOptions, ModelName } from 'prisma-flare';
507
+ export { default as FlareBuilder } from 'prisma-flare/flareBuilder';
508
+ `;
509
+ const flareDtsPath = path5.join(prismaOutputDir, "flare.d.ts");
510
+ const flareDtsContent = `// Generated by prisma-flare - DO NOT EDIT
511
+ // TypeScript declarations for FlareClient
512
+
513
+ import { PrismaClient as BasePrismaClient, Prisma as BasePrisma } from '${prismaImportPath}';
514
+ import type { FlareClientOptions, ModelName } from 'prisma-flare';
515
+ import type FlareBuilder from 'prisma-flare/flareBuilder';
516
+
517
+ // Re-export PrismaClient and Prisma
518
+ export { BasePrismaClient as PrismaClient, BasePrisma as Prisma };
519
+
520
+ // Re-export types from prisma-flare
521
+ export type { FlareClientOptions, ModelName };
522
+ export { FlareBuilder };
523
+
524
+ // FlareClient type that extends the project's PrismaClient
525
+ export declare const FlareClient: {
526
+ new (options?: FlareClientOptions): BasePrismaClient & {
527
+ from<T extends ModelName>(modelName: T): FlareBuilder<T>;
528
+ transaction<R>(
529
+ fn: (tx: BasePrismaClient) => Promise<R>,
530
+ options?: { maxWait?: number; timeout?: number; isolationLevel?: any }
531
+ ): Promise<R>;
532
+ };
533
+ };
534
+ `;
535
+ fs5.writeFileSync(flareFilePath, flareContent);
536
+ fs5.writeFileSync(flareDtsPath, flareDtsContent);
537
+ const relativeFlareDir = path5.relative(rootDir, prismaOutputDir);
538
+ const relativeImportPath = "./" + path5.join(relativeFlareDir, "flare").replace(/\\/g, "/");
539
+ console.log(`\u2705 Generated prisma-flare client with custom Prisma output`);
540
+ console.log(` Location: ${prismaOutputDir}`);
541
+ console.log(` Files: flare.ts, flare.d.ts`);
507
542
  console.log(`
508
- Import: import { FlareClient } from 'prisma-flare';`);
543
+ Import: import { FlareClient } from '${relativeImportPath}';`);
509
544
  }
510
545
 
511
546
  // src/cli/index.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prisma-flare",
3
- "version": "1.1.6",
3
+ "version": "1.1.8",
4
4
  "description": "Prisma utilities package with callback system and query builder for chained operations",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",
package/readme.md CHANGED
@@ -149,17 +149,46 @@ Example with custom plurals:
149
149
 
150
150
  ### Custom Prisma Output Path
151
151
 
152
- If you use a custom `output` in your Prisma schema, prisma-flare automatically detects and supports it:
152
+ If you use a custom `output` in your Prisma schema (common with Prisma 7+), prisma-flare automatically detects it:
153
153
 
154
154
  ```prisma
155
155
  // schema.prisma
156
156
  generator client {
157
157
  provider = "prisma-client-js"
158
- output = "./generated/client" // Custom output path
158
+ output = "./generated" // Custom output path
159
159
  }
160
160
  ```
161
161
 
162
- Just run `npx prisma-flare generate` - it parses your `schema.prisma` and configures everything automatically. No extra configuration needed.
162
+ Run `npx prisma-flare generate` after `npx prisma generate`:
163
+
164
+ ```bash
165
+ npx prisma generate
166
+ npx prisma-flare generate
167
+ ```
168
+
169
+ This generates FlareClient in **two locations**:
170
+ 1. `node_modules/.prisma-flare/` - for Node.js and general use
171
+ 2. `prisma/generated/flare.ts` - for bundler compatibility (Turbopack, Webpack, Vite)
172
+
173
+ **For Turbopack / Next.js 15+ users:** Import from the generated `flare.ts`:
174
+
175
+ ```typescript
176
+ // prisma/db.ts
177
+ import './callbacks';
178
+ import { FlareClient } from './generated/flare'; // ← Bundler-compatible path
179
+
180
+ export const db = new FlareClient();
181
+ ```
182
+
183
+ **For Node.js / non-Turbopack users:** You can still import from `prisma-flare`:
184
+
185
+ ```typescript
186
+ // prisma/db.ts
187
+ import './callbacks';
188
+ import { FlareClient } from 'prisma-flare'; // ← Works in Node.js
189
+
190
+ export const db = new FlareClient();
191
+ ```
163
192
 
164
193
  **Manual override:** If auto-detection doesn't work, add to `prisma-flare.config.json`:
165
194