prisma-flare 1.1.2 → 1.1.3

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.
@@ -1 +1,2 @@
1
1
  #!/usr/bin/env node
2
+ import '.prisma-flare';
@@ -1 +1,2 @@
1
1
  #!/usr/bin/env node
2
+ import '.prisma-flare';
@@ -320,15 +320,186 @@ ${imports}
320
320
  console.log(`\u2705 Generated callbacks index: ${callbacksDir}/index.ts (${callbackFiles.length} callbacks)`);
321
321
  }
322
322
 
323
+ // src/cli/generate-client.ts
324
+ var fs5 = __toESM(require("fs"), 1);
325
+ var path5 = __toESM(require("path"), 1);
326
+
327
+ // src/cli/schema-parser.ts
328
+ var fs4 = __toESM(require("fs"), 1);
329
+ var path4 = __toESM(require("path"), 1);
330
+ function parseGeneratorClient(schemaContent) {
331
+ const generatorRegex = /generator\s+client\s*\{([^}]+)\}/s;
332
+ const match = schemaContent.match(generatorRegex);
333
+ if (!match) return null;
334
+ const blockContent = match[1];
335
+ const config = { provider: "prisma-client-js" };
336
+ const providerMatch = blockContent.match(/provider\s*=\s*["']([^"']+)["']/);
337
+ if (providerMatch) {
338
+ config.provider = providerMatch[1];
339
+ }
340
+ const outputMatch = blockContent.match(/output\s*=\s*["']([^"']+)["']/);
341
+ if (outputMatch) {
342
+ config.output = outputMatch[1];
343
+ }
344
+ return config;
345
+ }
346
+ function resolvePrismaClientPath(rootDir, output) {
347
+ if (!output) {
348
+ return "@prisma/client";
349
+ }
350
+ const schemaDir = path4.join(rootDir, "prisma");
351
+ const absolutePath = path4.resolve(schemaDir, output);
352
+ return absolutePath;
353
+ }
354
+ function getPrismaClientPath(rootDir) {
355
+ const schemaPath = path4.join(rootDir, "prisma", "schema.prisma");
356
+ if (!fs4.existsSync(schemaPath)) {
357
+ return "@prisma/client";
358
+ }
359
+ const schemaContent = fs4.readFileSync(schemaPath, "utf-8");
360
+ const config = parseGeneratorClient(schemaContent);
361
+ return resolvePrismaClientPath(rootDir, config?.output);
362
+ }
363
+ function hasCustomPrismaOutput(rootDir) {
364
+ const schemaPath = path4.join(rootDir, "prisma", "schema.prisma");
365
+ if (!fs4.existsSync(schemaPath)) {
366
+ return false;
367
+ }
368
+ const schemaContent = fs4.readFileSync(schemaPath, "utf-8");
369
+ const config = parseGeneratorClient(schemaContent);
370
+ return config?.output != null;
371
+ }
372
+
373
+ // src/cli/generate-client.ts
374
+ function generateClient() {
375
+ const rootDir = findProjectRoot(process.cwd());
376
+ const config = loadConfig(rootDir);
377
+ let prismaClientImport;
378
+ if (config.prismaClientPath) {
379
+ prismaClientImport = config.prismaClientPath;
380
+ } else {
381
+ prismaClientImport = getPrismaClientPath(rootDir);
382
+ }
383
+ const nodeModulesDir = path5.join(rootDir, "node_modules");
384
+ const prismaFlareDir = path5.join(nodeModulesDir, ".prisma-flare");
385
+ if (!fs5.existsSync(prismaFlareDir)) {
386
+ fs5.mkdirSync(prismaFlareDir, { recursive: true });
387
+ }
388
+ let resolvedImport;
389
+ if (prismaClientImport === "@prisma/client") {
390
+ resolvedImport = "@prisma/client";
391
+ } else {
392
+ resolvedImport = path5.relative(prismaFlareDir, prismaClientImport);
393
+ if (!resolvedImport.startsWith(".")) {
394
+ resolvedImport = "./" + resolvedImport;
395
+ }
396
+ resolvedImport = resolvedImport.replace(/\\/g, "/");
397
+ }
398
+ const isCustomOutput = hasCustomPrismaOutput(rootDir);
399
+ const esmContent = `// Generated by prisma-flare - DO NOT EDIT
400
+ // This file provides FlareClient configured for your Prisma client output path
401
+ // Import path: ${prismaClientImport}
402
+
403
+ import { PrismaClient, Prisma } from '${resolvedImport}';
404
+ import { createFlareClient } from 'prisma-flare';
405
+
406
+ // Create and export FlareClient using the factory
407
+ export const FlareClient = createFlareClient(PrismaClient, Prisma);
408
+
409
+ // Re-export PrismaClient and Prisma for convenience
410
+ export { PrismaClient, Prisma };
411
+ `;
412
+ const cjsContent = `// Generated by prisma-flare - DO NOT EDIT
413
+ // This file provides FlareClient configured for your Prisma client output path
414
+ // Import path: ${prismaClientImport}
415
+
416
+ const { PrismaClient, Prisma } = require('${resolvedImport}');
417
+ const { createFlareClient } = require('prisma-flare');
418
+
419
+ // Create FlareClient using the factory
420
+ const FlareClient = createFlareClient(PrismaClient, Prisma);
421
+
422
+ module.exports = {
423
+ FlareClient,
424
+ PrismaClient,
425
+ Prisma
426
+ };
427
+ `;
428
+ const dtsContent = `// Generated by prisma-flare - DO NOT EDIT
429
+ // This file provides FlareClient configured for your Prisma client output path
430
+
431
+ import { PrismaClient as BasePrismaClient, Prisma as BasePrisma } from '${resolvedImport}';
432
+ import type { FlareClientOptions } from 'prisma-flare';
433
+ import type { ModelName } from 'prisma-flare';
434
+ import type FlareBuilder from 'prisma-flare/flareBuilder';
435
+
436
+ // Re-export PrismaClient and Prisma from the configured path
437
+ export { BasePrismaClient as PrismaClient, BasePrisma as Prisma };
438
+
439
+ // FlareClient type that extends the project's PrismaClient
440
+ export declare class FlareClient extends BasePrismaClient {
441
+ constructor(options?: FlareClientOptions);
442
+
443
+ /**
444
+ * Creates a new FlareBuilder instance for the specified model.
445
+ * @param modelName - The name of the model.
446
+ * @returns FlareBuilder instance
447
+ */
448
+ from<T extends ModelName>(modelName: T): FlareBuilder<T>;
449
+
450
+ /**
451
+ * Executes a transaction with the FlareClient capabilities.
452
+ * @param fn - The transaction function.
453
+ * @param options - Transaction options.
454
+ * @returns The result of the transaction.
455
+ */
456
+ transaction<R>(
457
+ fn: (tx: FlareClient) => Promise<R>,
458
+ options?: { maxWait?: number; timeout?: number; isolationLevel?: any }
459
+ ): Promise<R>;
460
+ }
461
+ `;
462
+ fs5.writeFileSync(path5.join(prismaFlareDir, "index.js"), esmContent);
463
+ fs5.writeFileSync(path5.join(prismaFlareDir, "index.cjs"), cjsContent);
464
+ fs5.writeFileSync(path5.join(prismaFlareDir, "index.d.ts"), dtsContent);
465
+ const packageJson = {
466
+ name: ".prisma-flare",
467
+ version: "0.0.0",
468
+ main: "./index.cjs",
469
+ module: "./index.js",
470
+ types: "./index.d.ts",
471
+ type: "module",
472
+ exports: {
473
+ ".": {
474
+ types: "./index.d.ts",
475
+ import: "./index.js",
476
+ require: "./index.cjs"
477
+ }
478
+ }
479
+ };
480
+ fs5.writeFileSync(
481
+ path5.join(prismaFlareDir, "package.json"),
482
+ JSON.stringify(packageJson, null, 2)
483
+ );
484
+ if (isCustomOutput) {
485
+ console.log(`\u2705 Generated prisma-flare client with custom Prisma output: ${prismaClientImport}`);
486
+ } else {
487
+ console.log(`\u2705 Generated prisma-flare client using @prisma/client`);
488
+ }
489
+ console.log(` Location: ${prismaFlareDir}`);
490
+ console.log(`
491
+ Import: import { FlareClient } from 'prisma-flare/client';`);
492
+ }
493
+
323
494
  // src/cli/index.ts
324
495
  var import_child_process = require("child_process");
325
- var path4 = __toESM(require("path"), 1);
326
- var fs4 = __toESM(require("fs"), 1);
496
+ var path6 = __toESM(require("path"), 1);
497
+ var fs6 = __toESM(require("fs"), 1);
327
498
  var import_url = require("url");
328
499
  var import_meta = {};
329
500
  var getDirname = () => {
330
501
  try {
331
- return path4.dirname((0, import_url.fileURLToPath)(import_meta.url));
502
+ return path6.dirname((0, import_url.fileURLToPath)(import_meta.url));
332
503
  } catch {
333
504
  return __dirname;
334
505
  }
@@ -349,6 +520,7 @@ if (!command) {
349
520
  }
350
521
  switch (command) {
351
522
  case "generate":
523
+ generateClient();
352
524
  generateQueries();
353
525
  generateCallbacksIndex();
354
526
  break;
@@ -376,10 +548,10 @@ function runScript(scriptName) {
376
548
  console.error(`No script found for ${scriptName}`);
377
549
  return;
378
550
  }
379
- let scriptPath = path4.join(__dirname_, file.replace(".ts", ".js"));
380
- if (!fs4.existsSync(scriptPath)) {
381
- const cliScriptPath = path4.join(__dirname_, "cli", file.replace(".ts", ".js"));
382
- if (fs4.existsSync(cliScriptPath)) {
551
+ let scriptPath = path6.join(__dirname_, file.replace(".ts", ".js"));
552
+ if (!fs6.existsSync(scriptPath)) {
553
+ const cliScriptPath = path6.join(__dirname_, "cli", file.replace(".ts", ".js"));
554
+ if (fs6.existsSync(cliScriptPath)) {
383
555
  scriptPath = cliScriptPath;
384
556
  }
385
557
  }
package/dist/cli/index.js CHANGED
@@ -297,14 +297,185 @@ ${imports}
297
297
  console.log(`\u2705 Generated callbacks index: ${callbacksDir}/index.ts (${callbackFiles.length} callbacks)`);
298
298
  }
299
299
 
300
+ // src/cli/generate-client.ts
301
+ import * as fs5 from "fs";
302
+ import * as path5 from "path";
303
+
304
+ // src/cli/schema-parser.ts
305
+ import * as fs4 from "fs";
306
+ import * as path4 from "path";
307
+ function parseGeneratorClient(schemaContent) {
308
+ const generatorRegex = /generator\s+client\s*\{([^}]+)\}/s;
309
+ const match = schemaContent.match(generatorRegex);
310
+ if (!match) return null;
311
+ const blockContent = match[1];
312
+ const config = { provider: "prisma-client-js" };
313
+ const providerMatch = blockContent.match(/provider\s*=\s*["']([^"']+)["']/);
314
+ if (providerMatch) {
315
+ config.provider = providerMatch[1];
316
+ }
317
+ const outputMatch = blockContent.match(/output\s*=\s*["']([^"']+)["']/);
318
+ if (outputMatch) {
319
+ config.output = outputMatch[1];
320
+ }
321
+ return config;
322
+ }
323
+ function resolvePrismaClientPath(rootDir, output) {
324
+ if (!output) {
325
+ return "@prisma/client";
326
+ }
327
+ const schemaDir = path4.join(rootDir, "prisma");
328
+ const absolutePath = path4.resolve(schemaDir, output);
329
+ return absolutePath;
330
+ }
331
+ function getPrismaClientPath(rootDir) {
332
+ const schemaPath = path4.join(rootDir, "prisma", "schema.prisma");
333
+ if (!fs4.existsSync(schemaPath)) {
334
+ return "@prisma/client";
335
+ }
336
+ const schemaContent = fs4.readFileSync(schemaPath, "utf-8");
337
+ const config = parseGeneratorClient(schemaContent);
338
+ return resolvePrismaClientPath(rootDir, config?.output);
339
+ }
340
+ function hasCustomPrismaOutput(rootDir) {
341
+ const schemaPath = path4.join(rootDir, "prisma", "schema.prisma");
342
+ if (!fs4.existsSync(schemaPath)) {
343
+ return false;
344
+ }
345
+ const schemaContent = fs4.readFileSync(schemaPath, "utf-8");
346
+ const config = parseGeneratorClient(schemaContent);
347
+ return config?.output != null;
348
+ }
349
+
350
+ // src/cli/generate-client.ts
351
+ function generateClient() {
352
+ const rootDir = findProjectRoot(process.cwd());
353
+ const config = loadConfig(rootDir);
354
+ let prismaClientImport;
355
+ if (config.prismaClientPath) {
356
+ prismaClientImport = config.prismaClientPath;
357
+ } else {
358
+ prismaClientImport = getPrismaClientPath(rootDir);
359
+ }
360
+ const nodeModulesDir = path5.join(rootDir, "node_modules");
361
+ const prismaFlareDir = path5.join(nodeModulesDir, ".prisma-flare");
362
+ if (!fs5.existsSync(prismaFlareDir)) {
363
+ fs5.mkdirSync(prismaFlareDir, { recursive: true });
364
+ }
365
+ let resolvedImport;
366
+ if (prismaClientImport === "@prisma/client") {
367
+ resolvedImport = "@prisma/client";
368
+ } else {
369
+ resolvedImport = path5.relative(prismaFlareDir, prismaClientImport);
370
+ if (!resolvedImport.startsWith(".")) {
371
+ resolvedImport = "./" + resolvedImport;
372
+ }
373
+ resolvedImport = resolvedImport.replace(/\\/g, "/");
374
+ }
375
+ const isCustomOutput = hasCustomPrismaOutput(rootDir);
376
+ const esmContent = `// Generated by prisma-flare - DO NOT EDIT
377
+ // This file provides FlareClient configured for your Prisma client output path
378
+ // Import path: ${prismaClientImport}
379
+
380
+ import { PrismaClient, Prisma } from '${resolvedImport}';
381
+ import { createFlareClient } from 'prisma-flare';
382
+
383
+ // Create and export FlareClient using the factory
384
+ export const FlareClient = createFlareClient(PrismaClient, Prisma);
385
+
386
+ // Re-export PrismaClient and Prisma for convenience
387
+ export { PrismaClient, Prisma };
388
+ `;
389
+ const cjsContent = `// Generated by prisma-flare - DO NOT EDIT
390
+ // This file provides FlareClient configured for your Prisma client output path
391
+ // Import path: ${prismaClientImport}
392
+
393
+ const { PrismaClient, Prisma } = require('${resolvedImport}');
394
+ const { createFlareClient } = require('prisma-flare');
395
+
396
+ // Create FlareClient using the factory
397
+ const FlareClient = createFlareClient(PrismaClient, Prisma);
398
+
399
+ module.exports = {
400
+ FlareClient,
401
+ PrismaClient,
402
+ Prisma
403
+ };
404
+ `;
405
+ const dtsContent = `// Generated by prisma-flare - DO NOT EDIT
406
+ // This file provides FlareClient configured for your Prisma client output path
407
+
408
+ import { PrismaClient as BasePrismaClient, Prisma as BasePrisma } from '${resolvedImport}';
409
+ import type { FlareClientOptions } from 'prisma-flare';
410
+ import type { ModelName } from 'prisma-flare';
411
+ import type FlareBuilder from 'prisma-flare/flareBuilder';
412
+
413
+ // Re-export PrismaClient and Prisma from the configured path
414
+ export { BasePrismaClient as PrismaClient, BasePrisma as Prisma };
415
+
416
+ // FlareClient type that extends the project's PrismaClient
417
+ export declare class FlareClient extends BasePrismaClient {
418
+ constructor(options?: FlareClientOptions);
419
+
420
+ /**
421
+ * Creates a new FlareBuilder instance for the specified model.
422
+ * @param modelName - The name of the model.
423
+ * @returns FlareBuilder instance
424
+ */
425
+ from<T extends ModelName>(modelName: T): FlareBuilder<T>;
426
+
427
+ /**
428
+ * Executes a transaction with the FlareClient capabilities.
429
+ * @param fn - The transaction function.
430
+ * @param options - Transaction options.
431
+ * @returns The result of the transaction.
432
+ */
433
+ transaction<R>(
434
+ fn: (tx: FlareClient) => Promise<R>,
435
+ options?: { maxWait?: number; timeout?: number; isolationLevel?: any }
436
+ ): Promise<R>;
437
+ }
438
+ `;
439
+ fs5.writeFileSync(path5.join(prismaFlareDir, "index.js"), esmContent);
440
+ fs5.writeFileSync(path5.join(prismaFlareDir, "index.cjs"), cjsContent);
441
+ fs5.writeFileSync(path5.join(prismaFlareDir, "index.d.ts"), dtsContent);
442
+ const packageJson = {
443
+ name: ".prisma-flare",
444
+ version: "0.0.0",
445
+ main: "./index.cjs",
446
+ module: "./index.js",
447
+ types: "./index.d.ts",
448
+ type: "module",
449
+ exports: {
450
+ ".": {
451
+ types: "./index.d.ts",
452
+ import: "./index.js",
453
+ require: "./index.cjs"
454
+ }
455
+ }
456
+ };
457
+ fs5.writeFileSync(
458
+ path5.join(prismaFlareDir, "package.json"),
459
+ JSON.stringify(packageJson, null, 2)
460
+ );
461
+ if (isCustomOutput) {
462
+ console.log(`\u2705 Generated prisma-flare client with custom Prisma output: ${prismaClientImport}`);
463
+ } else {
464
+ console.log(`\u2705 Generated prisma-flare client using @prisma/client`);
465
+ }
466
+ console.log(` Location: ${prismaFlareDir}`);
467
+ console.log(`
468
+ Import: import { FlareClient } from 'prisma-flare/client';`);
469
+ }
470
+
300
471
  // src/cli/index.ts
301
472
  import { spawn } from "child_process";
302
- import * as path4 from "path";
303
- import * as fs4 from "fs";
473
+ import * as path6 from "path";
474
+ import * as fs6 from "fs";
304
475
  import { fileURLToPath } from "url";
305
476
  var getDirname = () => {
306
477
  try {
307
- return path4.dirname(fileURLToPath(import.meta.url));
478
+ return path6.dirname(fileURLToPath(import.meta.url));
308
479
  } catch {
309
480
  return __dirname;
310
481
  }
@@ -325,6 +496,7 @@ if (!command) {
325
496
  }
326
497
  switch (command) {
327
498
  case "generate":
499
+ generateClient();
328
500
  generateQueries();
329
501
  generateCallbacksIndex();
330
502
  break;
@@ -352,10 +524,10 @@ function runScript(scriptName) {
352
524
  console.error(`No script found for ${scriptName}`);
353
525
  return;
354
526
  }
355
- let scriptPath = path4.join(__dirname_, file.replace(".ts", ".js"));
356
- if (!fs4.existsSync(scriptPath)) {
357
- const cliScriptPath = path4.join(__dirname_, "cli", file.replace(".ts", ".js"));
358
- if (fs4.existsSync(cliScriptPath)) {
527
+ let scriptPath = path6.join(__dirname_, file.replace(".ts", ".js"));
528
+ if (!fs6.existsSync(scriptPath)) {
529
+ const cliScriptPath = path6.join(__dirname_, "cli", file.replace(".ts", ".js"));
530
+ if (fs6.existsSync(cliScriptPath)) {
359
531
  scriptPath = cliScriptPath;
360
532
  }
361
533
  }
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/client/index.ts
21
+ var client_exports = {};
22
+ __export(client_exports, {
23
+ FlareClient: () => import__.FlareClient,
24
+ Prisma: () => import__.Prisma,
25
+ PrismaClient: () => import__.PrismaClient
26
+ });
27
+ module.exports = __toCommonJS(client_exports);
28
+ var import__ = require(".prisma-flare");
29
+ // Annotate the CommonJS export names for ESM import in node:
30
+ 0 && (module.exports = {
31
+ FlareClient,
32
+ Prisma,
33
+ PrismaClient
34
+ });
@@ -0,0 +1 @@
1
+ export { FlareClient, Prisma, PrismaClient } from '.prisma-flare';
@@ -0,0 +1 @@
1
+ export { FlareClient, Prisma, PrismaClient } from '.prisma-flare';
@@ -0,0 +1,7 @@
1
+ // src/client/index.ts
2
+ import { FlareClient, Prisma, PrismaClient } from ".prisma-flare";
3
+ export {
4
+ FlareClient,
5
+ Prisma,
6
+ PrismaClient
7
+ };
@@ -87,7 +87,12 @@ var ModelRegistry = class {
87
87
  return Array.from(this.models.keys());
88
88
  }
89
89
  };
90
- var modelRegistry = new ModelRegistry();
90
+ var MODEL_REGISTRY_SYMBOL = /* @__PURE__ */ Symbol.for("prisma-flare.modelRegistry");
91
+ var globalObj = globalThis;
92
+ if (!globalObj[MODEL_REGISTRY_SYMBOL]) {
93
+ globalObj[MODEL_REGISTRY_SYMBOL] = new ModelRegistry();
94
+ }
95
+ var modelRegistry = globalObj[MODEL_REGISTRY_SYMBOL];
91
96
 
92
97
  // src/core/flareBuilder.ts
93
98
  function deepClone(obj) {
@@ -61,7 +61,12 @@ var ModelRegistry = class {
61
61
  return Array.from(this.models.keys());
62
62
  }
63
63
  };
64
- var modelRegistry = new ModelRegistry();
64
+ var MODEL_REGISTRY_SYMBOL = /* @__PURE__ */ Symbol.for("prisma-flare.modelRegistry");
65
+ var globalObj = globalThis;
66
+ if (!globalObj[MODEL_REGISTRY_SYMBOL]) {
67
+ globalObj[MODEL_REGISTRY_SYMBOL] = new ModelRegistry();
68
+ }
69
+ var modelRegistry = globalObj[MODEL_REGISTRY_SYMBOL];
65
70
 
66
71
  // src/core/flareBuilder.ts
67
72
  function deepClone(obj) {
@@ -199,7 +199,12 @@ var HookRegistry = class {
199
199
  this.config = { ...DEFAULT_CONFIG };
200
200
  }
201
201
  };
202
- var hookRegistry = new HookRegistry();
202
+ var HOOK_REGISTRY_SYMBOL = /* @__PURE__ */ Symbol.for("prisma-flare.hookRegistry");
203
+ var globalObj = globalThis;
204
+ if (!globalObj[HOOK_REGISTRY_SYMBOL]) {
205
+ globalObj[HOOK_REGISTRY_SYMBOL] = new HookRegistry();
206
+ }
207
+ var hookRegistry = globalObj[HOOK_REGISTRY_SYMBOL];
203
208
  var hookRegistry_default = hookRegistry;
204
209
 
205
210
  // src/core/hooks.ts
@@ -166,7 +166,12 @@ var HookRegistry = class {
166
166
  this.config = { ...DEFAULT_CONFIG };
167
167
  }
168
168
  };
169
- var hookRegistry = new HookRegistry();
169
+ var HOOK_REGISTRY_SYMBOL = /* @__PURE__ */ Symbol.for("prisma-flare.hookRegistry");
170
+ var globalObj = globalThis;
171
+ if (!globalObj[HOOK_REGISTRY_SYMBOL]) {
172
+ globalObj[HOOK_REGISTRY_SYMBOL] = new HookRegistry();
173
+ }
174
+ var hookRegistry = globalObj[HOOK_REGISTRY_SYMBOL];
170
175
  var hookRegistry_default = hookRegistry;
171
176
 
172
177
  // src/core/hooks.ts
package/dist/index.cjs CHANGED
@@ -41,6 +41,7 @@ __export(index_exports, {
41
41
  beforeCreate: () => beforeCreate,
42
42
  beforeDelete: () => beforeDelete,
43
43
  beforeUpdate: () => beforeUpdate,
44
+ createFlareClient: () => createFlareClient,
44
45
  createHooksExtension: () => createHooksExtension,
45
46
  dbAdapterRegistry: () => registry,
46
47
  hookRegistry: () => hookRegistry_default,
@@ -117,7 +118,12 @@ var ModelRegistry = class {
117
118
  return Array.from(this.models.keys());
118
119
  }
119
120
  };
120
- var modelRegistry = new ModelRegistry();
121
+ var MODEL_REGISTRY_SYMBOL = /* @__PURE__ */ Symbol.for("prisma-flare.modelRegistry");
122
+ var globalObj = globalThis;
123
+ if (!globalObj[MODEL_REGISTRY_SYMBOL]) {
124
+ globalObj[MODEL_REGISTRY_SYMBOL] = new ModelRegistry();
125
+ }
126
+ var modelRegistry = globalObj[MODEL_REGISTRY_SYMBOL];
121
127
 
122
128
  // src/core/flareBuilder.ts
123
129
  function deepClone(obj) {
@@ -878,7 +884,12 @@ var HookRegistry = class {
878
884
  this.config = { ...DEFAULT_CONFIG };
879
885
  }
880
886
  };
881
- var hookRegistry = new HookRegistry();
887
+ var HOOK_REGISTRY_SYMBOL = /* @__PURE__ */ Symbol.for("prisma-flare.hookRegistry");
888
+ var globalObj2 = globalThis;
889
+ if (!globalObj2[HOOK_REGISTRY_SYMBOL]) {
890
+ globalObj2[HOOK_REGISTRY_SYMBOL] = new HookRegistry();
891
+ }
892
+ var hookRegistry = globalObj2[HOOK_REGISTRY_SYMBOL];
882
893
  var hookRegistry_default = hookRegistry;
883
894
 
884
895
  // src/core/hookMiddleware.ts
@@ -1073,6 +1084,67 @@ var FlareClient = class extends import_client2.PrismaClient {
1073
1084
  };
1074
1085
  var ExtendedPrismaClient = FlareClient;
1075
1086
 
1087
+ // src/core/createFlareClient.ts
1088
+ function supportsPrisma6Middleware3(prisma) {
1089
+ return typeof prisma.$use === "function";
1090
+ }
1091
+ function createFlareClient(BasePrismaClient, _PrismaNamespace) {
1092
+ const FlareClientImpl = class extends BasePrismaClient {
1093
+ constructor(options = {}) {
1094
+ const { callbacks = true, ...prismaOptions } = options;
1095
+ super(prismaOptions);
1096
+ if (callbacks) {
1097
+ if (supportsPrisma6Middleware3(this)) {
1098
+ registerHooksLegacy(this);
1099
+ } else {
1100
+ const extension = createHooksExtension(this);
1101
+ return this.$extends(extension);
1102
+ }
1103
+ }
1104
+ }
1105
+ /**
1106
+ * Creates a new FlareBuilder instance for the specified model.
1107
+ * @param modelName - The name of the model.
1108
+ * @returns FlareBuilder instance
1109
+ */
1110
+ from(modelName) {
1111
+ const key = modelName.charAt(0).toLowerCase() + modelName.slice(1);
1112
+ const model = this[key];
1113
+ if (!model) {
1114
+ throw new Error(`Model ${modelName} does not exist on PrismaClient.`);
1115
+ }
1116
+ return new FlareBuilder(model);
1117
+ }
1118
+ /**
1119
+ * Executes a transaction with the FlareClient capabilities.
1120
+ * @param fn - The transaction function.
1121
+ * @param options - Transaction options.
1122
+ * @returns The result of the transaction.
1123
+ */
1124
+ async transaction(fn, options) {
1125
+ return this.$transaction(async (tx) => {
1126
+ const extendedTx = new Proxy(tx, {
1127
+ get: (target, prop, receiver) => {
1128
+ if (prop === "from") {
1129
+ return (modelName) => {
1130
+ const key = modelName.charAt(0).toLowerCase() + modelName.slice(1);
1131
+ const model = target[key];
1132
+ if (!model) {
1133
+ throw new Error(`Model ${modelName} does not exist on TransactionClient.`);
1134
+ }
1135
+ return new FlareBuilder(model);
1136
+ };
1137
+ }
1138
+ return Reflect.get(target, prop, receiver);
1139
+ }
1140
+ });
1141
+ return fn(extendedTx);
1142
+ }, options);
1143
+ }
1144
+ };
1145
+ return FlareClientImpl;
1146
+ }
1147
+
1076
1148
  // src/core/hooks.ts
1077
1149
  function normalizeModelName(model) {
1078
1150
  return model.toLowerCase();
@@ -1271,6 +1343,7 @@ registry.register(SqliteAdapter);
1271
1343
  beforeCreate,
1272
1344
  beforeDelete,
1273
1345
  beforeUpdate,
1346
+ createFlareClient,
1274
1347
  createHooksExtension,
1275
1348
  dbAdapterRegistry,
1276
1349
  hookRegistry,
package/dist/index.d.cts CHANGED
@@ -48,6 +48,77 @@ declare class FlareClient extends PrismaClient {
48
48
  */
49
49
  declare const ExtendedPrismaClient: typeof FlareClient;
50
50
 
51
+ /**
52
+ * Options for FlareClient created via the factory.
53
+ * Extends the standard PrismaClient options.
54
+ */
55
+ interface FactoryFlareClientOptions {
56
+ /**
57
+ * Enable callbacks/hooks middleware. When true (default), the middleware
58
+ * that executes your registered callbacks (beforeCreate, afterUpdate, etc.)
59
+ * is automatically attached.
60
+ *
61
+ * @default true
62
+ */
63
+ callbacks?: boolean;
64
+ /**
65
+ * Driver adapter for serverless/edge environments.
66
+ * Pass an adapter instance (e.g., from @prisma/adapter-pg, @prisma/adapter-d1, etc.)
67
+ */
68
+ adapter?: DriverAdapter;
69
+ /**
70
+ * Any additional PrismaClient options are passed through
71
+ */
72
+ [key: string]: unknown;
73
+ }
74
+ /**
75
+ * Type for the Prisma namespace (contains Result, defineExtension, etc.)
76
+ */
77
+ type PrismaNamespace = {
78
+ defineExtension: (extension: any) => any;
79
+ [key: string]: unknown;
80
+ };
81
+ /**
82
+ * Type for a PrismaClient-like constructor
83
+ */
84
+ interface PrismaClientLike {
85
+ new (options?: Record<string, unknown>): PrismaClient;
86
+ }
87
+ /**
88
+ * The shape of a FlareClient class created by the factory
89
+ */
90
+ interface FlareClientClass {
91
+ new (options?: FactoryFlareClientOptions): FlareClientInstance;
92
+ }
93
+ /**
94
+ * Instance type for FlareClient
95
+ */
96
+ interface FlareClientInstance extends PrismaClient {
97
+ from<M extends ModelName>(modelName: M): FlareBuilder<M>;
98
+ transaction<R>(fn: (tx: FlareClientInstance) => Promise<R>, options?: {
99
+ maxWait?: number;
100
+ timeout?: number;
101
+ isolationLevel?: unknown;
102
+ }): Promise<R>;
103
+ }
104
+ /**
105
+ * Creates a FlareClient class that extends the provided PrismaClient.
106
+ * This factory enables support for custom Prisma client output paths.
107
+ *
108
+ * @param BasePrismaClient - The PrismaClient class to extend
109
+ * @param _PrismaNamespace - The Prisma namespace (optional, for future type inference)
110
+ * @returns A FlareClient class that extends BasePrismaClient
111
+ *
112
+ * @example
113
+ * // For custom Prisma output paths:
114
+ * import { PrismaClient, Prisma } from './generated/client';
115
+ * import { createFlareClient } from 'prisma-flare';
116
+ *
117
+ * const FlareClient = createFlareClient(PrismaClient, Prisma);
118
+ * export const db = new FlareClient();
119
+ */
120
+ declare function createFlareClient(BasePrismaClient: PrismaClientLike, _PrismaNamespace?: PrismaNamespace): FlareClientClass;
121
+
51
122
  type ModelClass<T extends ModelName = any> = new () => FlareBuilder<T, any>;
52
123
  /**
53
124
  * Registry for custom model classes that extend FlareBuilder.
@@ -248,4 +319,4 @@ declare class AdapterRegistry {
248
319
  }
249
320
  declare const registry: AdapterRegistry;
250
321
 
251
- export { AfterHookCallback, BeforeHookCallback, ColumnChangeCallback, type DatabaseAdapter, ExtendedPrismaClient, FlareBuilder, FlareClient, type FlareClientOptions, type HookConfig, HookTiming, ModelName, PrismaOperation, createHooksExtension, registry as dbAdapterRegistry, hookRegistry, loadCallbacks, modelRegistry, registerHooks, registerHooksLegacy };
322
+ export { AfterHookCallback, BeforeHookCallback, ColumnChangeCallback, type DatabaseAdapter, ExtendedPrismaClient, type FactoryFlareClientOptions, FlareBuilder, FlareClient, type FlareClientClass, type FlareClientInstance, type FlareClientOptions, type HookConfig, HookTiming, ModelName, type PrismaClientLike, type PrismaNamespace, PrismaOperation, createFlareClient, createHooksExtension, registry as dbAdapterRegistry, hookRegistry, loadCallbacks, modelRegistry, registerHooks, registerHooksLegacy };
package/dist/index.d.ts CHANGED
@@ -48,6 +48,77 @@ declare class FlareClient extends PrismaClient {
48
48
  */
49
49
  declare const ExtendedPrismaClient: typeof FlareClient;
50
50
 
51
+ /**
52
+ * Options for FlareClient created via the factory.
53
+ * Extends the standard PrismaClient options.
54
+ */
55
+ interface FactoryFlareClientOptions {
56
+ /**
57
+ * Enable callbacks/hooks middleware. When true (default), the middleware
58
+ * that executes your registered callbacks (beforeCreate, afterUpdate, etc.)
59
+ * is automatically attached.
60
+ *
61
+ * @default true
62
+ */
63
+ callbacks?: boolean;
64
+ /**
65
+ * Driver adapter for serverless/edge environments.
66
+ * Pass an adapter instance (e.g., from @prisma/adapter-pg, @prisma/adapter-d1, etc.)
67
+ */
68
+ adapter?: DriverAdapter;
69
+ /**
70
+ * Any additional PrismaClient options are passed through
71
+ */
72
+ [key: string]: unknown;
73
+ }
74
+ /**
75
+ * Type for the Prisma namespace (contains Result, defineExtension, etc.)
76
+ */
77
+ type PrismaNamespace = {
78
+ defineExtension: (extension: any) => any;
79
+ [key: string]: unknown;
80
+ };
81
+ /**
82
+ * Type for a PrismaClient-like constructor
83
+ */
84
+ interface PrismaClientLike {
85
+ new (options?: Record<string, unknown>): PrismaClient;
86
+ }
87
+ /**
88
+ * The shape of a FlareClient class created by the factory
89
+ */
90
+ interface FlareClientClass {
91
+ new (options?: FactoryFlareClientOptions): FlareClientInstance;
92
+ }
93
+ /**
94
+ * Instance type for FlareClient
95
+ */
96
+ interface FlareClientInstance extends PrismaClient {
97
+ from<M extends ModelName>(modelName: M): FlareBuilder<M>;
98
+ transaction<R>(fn: (tx: FlareClientInstance) => Promise<R>, options?: {
99
+ maxWait?: number;
100
+ timeout?: number;
101
+ isolationLevel?: unknown;
102
+ }): Promise<R>;
103
+ }
104
+ /**
105
+ * Creates a FlareClient class that extends the provided PrismaClient.
106
+ * This factory enables support for custom Prisma client output paths.
107
+ *
108
+ * @param BasePrismaClient - The PrismaClient class to extend
109
+ * @param _PrismaNamespace - The Prisma namespace (optional, for future type inference)
110
+ * @returns A FlareClient class that extends BasePrismaClient
111
+ *
112
+ * @example
113
+ * // For custom Prisma output paths:
114
+ * import { PrismaClient, Prisma } from './generated/client';
115
+ * import { createFlareClient } from 'prisma-flare';
116
+ *
117
+ * const FlareClient = createFlareClient(PrismaClient, Prisma);
118
+ * export const db = new FlareClient();
119
+ */
120
+ declare function createFlareClient(BasePrismaClient: PrismaClientLike, _PrismaNamespace?: PrismaNamespace): FlareClientClass;
121
+
51
122
  type ModelClass<T extends ModelName = any> = new () => FlareBuilder<T, any>;
52
123
  /**
53
124
  * Registry for custom model classes that extend FlareBuilder.
@@ -248,4 +319,4 @@ declare class AdapterRegistry {
248
319
  }
249
320
  declare const registry: AdapterRegistry;
250
321
 
251
- export { AfterHookCallback, BeforeHookCallback, ColumnChangeCallback, type DatabaseAdapter, ExtendedPrismaClient, FlareBuilder, FlareClient, type FlareClientOptions, type HookConfig, HookTiming, ModelName, PrismaOperation, createHooksExtension, registry as dbAdapterRegistry, hookRegistry, loadCallbacks, modelRegistry, registerHooks, registerHooksLegacy };
322
+ export { AfterHookCallback, BeforeHookCallback, ColumnChangeCallback, type DatabaseAdapter, ExtendedPrismaClient, type FactoryFlareClientOptions, FlareBuilder, FlareClient, type FlareClientClass, type FlareClientInstance, type FlareClientOptions, type HookConfig, HookTiming, ModelName, type PrismaClientLike, type PrismaNamespace, PrismaOperation, createFlareClient, createHooksExtension, registry as dbAdapterRegistry, hookRegistry, loadCallbacks, modelRegistry, registerHooks, registerHooksLegacy };
package/dist/index.js CHANGED
@@ -64,7 +64,12 @@ var ModelRegistry = class {
64
64
  return Array.from(this.models.keys());
65
65
  }
66
66
  };
67
- var modelRegistry = new ModelRegistry();
67
+ var MODEL_REGISTRY_SYMBOL = /* @__PURE__ */ Symbol.for("prisma-flare.modelRegistry");
68
+ var globalObj = globalThis;
69
+ if (!globalObj[MODEL_REGISTRY_SYMBOL]) {
70
+ globalObj[MODEL_REGISTRY_SYMBOL] = new ModelRegistry();
71
+ }
72
+ var modelRegistry = globalObj[MODEL_REGISTRY_SYMBOL];
68
73
 
69
74
  // src/core/flareBuilder.ts
70
75
  function deepClone(obj) {
@@ -825,7 +830,12 @@ var HookRegistry = class {
825
830
  this.config = { ...DEFAULT_CONFIG };
826
831
  }
827
832
  };
828
- var hookRegistry = new HookRegistry();
833
+ var HOOK_REGISTRY_SYMBOL = /* @__PURE__ */ Symbol.for("prisma-flare.hookRegistry");
834
+ var globalObj2 = globalThis;
835
+ if (!globalObj2[HOOK_REGISTRY_SYMBOL]) {
836
+ globalObj2[HOOK_REGISTRY_SYMBOL] = new HookRegistry();
837
+ }
838
+ var hookRegistry = globalObj2[HOOK_REGISTRY_SYMBOL];
829
839
  var hookRegistry_default = hookRegistry;
830
840
 
831
841
  // src/core/hookMiddleware.ts
@@ -1020,6 +1030,67 @@ var FlareClient = class extends PrismaClient2 {
1020
1030
  };
1021
1031
  var ExtendedPrismaClient = FlareClient;
1022
1032
 
1033
+ // src/core/createFlareClient.ts
1034
+ function supportsPrisma6Middleware3(prisma) {
1035
+ return typeof prisma.$use === "function";
1036
+ }
1037
+ function createFlareClient(BasePrismaClient, _PrismaNamespace) {
1038
+ const FlareClientImpl = class extends BasePrismaClient {
1039
+ constructor(options = {}) {
1040
+ const { callbacks = true, ...prismaOptions } = options;
1041
+ super(prismaOptions);
1042
+ if (callbacks) {
1043
+ if (supportsPrisma6Middleware3(this)) {
1044
+ registerHooksLegacy(this);
1045
+ } else {
1046
+ const extension = createHooksExtension(this);
1047
+ return this.$extends(extension);
1048
+ }
1049
+ }
1050
+ }
1051
+ /**
1052
+ * Creates a new FlareBuilder instance for the specified model.
1053
+ * @param modelName - The name of the model.
1054
+ * @returns FlareBuilder instance
1055
+ */
1056
+ from(modelName) {
1057
+ const key = modelName.charAt(0).toLowerCase() + modelName.slice(1);
1058
+ const model = this[key];
1059
+ if (!model) {
1060
+ throw new Error(`Model ${modelName} does not exist on PrismaClient.`);
1061
+ }
1062
+ return new FlareBuilder(model);
1063
+ }
1064
+ /**
1065
+ * Executes a transaction with the FlareClient capabilities.
1066
+ * @param fn - The transaction function.
1067
+ * @param options - Transaction options.
1068
+ * @returns The result of the transaction.
1069
+ */
1070
+ async transaction(fn, options) {
1071
+ return this.$transaction(async (tx) => {
1072
+ const extendedTx = new Proxy(tx, {
1073
+ get: (target, prop, receiver) => {
1074
+ if (prop === "from") {
1075
+ return (modelName) => {
1076
+ const key = modelName.charAt(0).toLowerCase() + modelName.slice(1);
1077
+ const model = target[key];
1078
+ if (!model) {
1079
+ throw new Error(`Model ${modelName} does not exist on TransactionClient.`);
1080
+ }
1081
+ return new FlareBuilder(model);
1082
+ };
1083
+ }
1084
+ return Reflect.get(target, prop, receiver);
1085
+ }
1086
+ });
1087
+ return fn(extendedTx);
1088
+ }, options);
1089
+ }
1090
+ };
1091
+ return FlareClientImpl;
1092
+ }
1093
+
1023
1094
  // src/core/hooks.ts
1024
1095
  function normalizeModelName(model) {
1025
1096
  return model.toLowerCase();
@@ -1217,6 +1288,7 @@ export {
1217
1288
  beforeCreate,
1218
1289
  beforeDelete,
1219
1290
  beforeUpdate,
1291
+ createFlareClient,
1220
1292
  createHooksExtension,
1221
1293
  registry as dbAdapterRegistry,
1222
1294
  hookRegistry_default as hookRegistry,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prisma-flare",
3
- "version": "1.1.2",
3
+ "version": "1.1.3",
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",
@@ -78,6 +78,11 @@
78
78
  "import": "./dist/index.js",
79
79
  "require": "./dist/index.cjs"
80
80
  },
81
+ "./client": {
82
+ "types": "./dist/client/index.d.ts",
83
+ "import": "./dist/client/index.js",
84
+ "require": "./dist/client/index.cjs"
85
+ },
81
86
  "./generated": {
82
87
  "types": "./dist/generated.d.ts",
83
88
  "import": "./dist/generated.js",
@@ -96,6 +101,9 @@
96
101
  },
97
102
  "typesVersions": {
98
103
  "*": {
104
+ "client": [
105
+ "./dist/client/index.d.ts"
106
+ ],
99
107
  "generated": [
100
108
  "./dist/generated.d.ts"
101
109
  ],
package/readme.md CHANGED
@@ -75,11 +75,13 @@ Replace your standard `PrismaClient` with `FlareClient` in your database setup f
75
75
  ```typescript
76
76
  // prisma/db.ts
77
77
  import './callbacks'; // Import generated index to register all hooks
78
- import { FlareClient } from 'prisma-flare';
78
+ import { FlareClient } from 'prisma-flare/client';
79
79
 
80
80
  export const db = new FlareClient();
81
81
  ```
82
82
 
83
+ **Note:** Always import `FlareClient` from `prisma-flare/client` - this ensures compatibility with custom Prisma output paths (see [Custom Prisma Output Path](#custom-prisma-output-path) below).
84
+
83
85
  `FlareClient` automatically attaches the callbacks middleware (using the appropriate API for your Prisma version). The callbacks import loads a generated barrel file that registers all your hooks - this pattern works in all environments (bundlers, Node.js, serverless, etc.).
84
86
 
85
87
  **With Prisma adapters:**
@@ -87,7 +89,7 @@ export const db = new FlareClient();
87
89
  ```typescript
88
90
  import './callbacks';
89
91
  import { PrismaPg } from '@prisma/adapter-pg';
90
- import { FlareClient } from 'prisma-flare';
92
+ import { FlareClient } from 'prisma-flare/client';
91
93
 
92
94
  const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL });
93
95
 
@@ -97,7 +99,7 @@ export const db = new FlareClient({ adapter });
97
99
  **Disable callbacks middleware:**
98
100
 
99
101
  ```typescript
100
- import { FlareClient } from 'prisma-flare';
102
+ import { FlareClient } from 'prisma-flare/client';
101
103
 
102
104
  // If you don't use callbacks, disable the middleware for slightly less overhead
103
105
  export const db = new FlareClient({ callbacks: false });
@@ -147,6 +149,52 @@ Example with custom plurals:
147
149
  }
148
150
  ```
149
151
 
152
+ ### Custom Prisma Output Path
153
+
154
+ If you use a custom `output` in your Prisma schema, prisma-flare automatically detects and supports it:
155
+
156
+ ```prisma
157
+ // schema.prisma
158
+ generator client {
159
+ provider = "prisma-client-js"
160
+ output = "./generated/client" // Custom output path
161
+ }
162
+ ```
163
+
164
+ The `prisma-flare generate` command:
165
+ 1. Parses your `schema.prisma` to detect custom output paths
166
+ 2. Generates `node_modules/.prisma-flare/` with the correct import path
167
+ 3. `prisma-flare/client` automatically uses this generated client
168
+
169
+ **That's it!** Just import from `prisma-flare/client` and it works:
170
+
171
+ ```typescript
172
+ import { FlareClient } from 'prisma-flare/client'; // Works with any Prisma output path
173
+ import { hookRegistry } from 'prisma-flare'; // Hooks/utilities from main package
174
+
175
+ export const db = new FlareClient();
176
+ ```
177
+
178
+ **Manual override:** If auto-detection doesn't work for your setup, you can explicitly configure the path:
179
+
180
+ ```json
181
+ {
182
+ "prismaClientPath": "./src/generated/prisma"
183
+ }
184
+ ```
185
+
186
+ **Advanced: Factory function**
187
+
188
+ For full control, use `createFlareClient` to create a FlareClient from any PrismaClient:
189
+
190
+ ```typescript
191
+ import { createFlareClient } from 'prisma-flare';
192
+ import { PrismaClient, Prisma } from './my/custom/prisma/path';
193
+
194
+ const FlareClient = createFlareClient(PrismaClient, Prisma);
195
+ export const db = new FlareClient();
196
+ ```
197
+
150
198
  ## Usage
151
199
 
152
200
  ### Flare Builder