@prisma/adapter-pg 6.15.0-dev.3 → 6.15.0-dev.30

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.
package/dist/index.d.mts CHANGED
@@ -10,9 +10,10 @@ import type { Transaction } from '@prisma/driver-adapter-utils';
10
10
 
11
11
  declare class PgQueryable<ClientT extends StdClient | TransactionClient> implements SqlQueryable {
12
12
  protected readonly client: ClientT;
13
+ protected readonly pgOptions?: PrismaPgOptions | undefined;
13
14
  readonly provider = "postgres";
14
15
  readonly adapterName: string;
15
- constructor(client: ClientT);
16
+ constructor(client: ClientT, pgOptions?: PrismaPgOptions | undefined);
16
17
  /**
17
18
  * Execute a query given as SQL, interpolating the given parameters.
18
19
  */
@@ -44,9 +45,9 @@ export declare class PrismaPg implements SqlMigrationAwareDriverAdapterFactory {
44
45
  }
45
46
 
46
47
  declare class PrismaPgAdapter extends PgQueryable<StdClient> implements SqlDriverAdapter {
47
- private options?;
48
+ protected readonly pgOptions?: PrismaPgOptions | undefined;
48
49
  private readonly release?;
49
- constructor(client: StdClient, options?: PrismaPgOptions | undefined, release?: (() => Promise<void>) | undefined);
50
+ constructor(client: StdClient, pgOptions?: PrismaPgOptions | undefined, release?: (() => Promise<void>) | undefined);
50
51
  startTransaction(isolationLevel?: IsolationLevel): Promise<Transaction>;
51
52
  executeScript(script: string): Promise<void>;
52
53
  getConnectionInfo(): ConnectionInfo;
@@ -58,10 +59,14 @@ declare type PrismaPgOptions = {
58
59
  schema?: string;
59
60
  disposeExternalPool?: boolean;
60
61
  onPoolError?: (err: Error) => void;
62
+ onConnectionError?: (err: Error) => void;
63
+ userDefinedTypeParser?: UserDefinedTypeParser;
61
64
  };
62
65
 
63
66
  declare type StdClient = pg.Pool;
64
67
 
65
68
  declare type TransactionClient = pg.PoolClient;
66
69
 
70
+ declare type UserDefinedTypeParser = (oid: number, value: unknown, adapter: SqlQueryable) => Promise<unknown>;
71
+
67
72
  export { }
package/dist/index.d.ts CHANGED
@@ -10,9 +10,10 @@ import type { Transaction } from '@prisma/driver-adapter-utils';
10
10
 
11
11
  declare class PgQueryable<ClientT extends StdClient | TransactionClient> implements SqlQueryable {
12
12
  protected readonly client: ClientT;
13
+ protected readonly pgOptions?: PrismaPgOptions | undefined;
13
14
  readonly provider = "postgres";
14
15
  readonly adapterName: string;
15
- constructor(client: ClientT);
16
+ constructor(client: ClientT, pgOptions?: PrismaPgOptions | undefined);
16
17
  /**
17
18
  * Execute a query given as SQL, interpolating the given parameters.
18
19
  */
@@ -44,9 +45,9 @@ export declare class PrismaPg implements SqlMigrationAwareDriverAdapterFactory {
44
45
  }
45
46
 
46
47
  declare class PrismaPgAdapter extends PgQueryable<StdClient> implements SqlDriverAdapter {
47
- private options?;
48
+ protected readonly pgOptions?: PrismaPgOptions | undefined;
48
49
  private readonly release?;
49
- constructor(client: StdClient, options?: PrismaPgOptions | undefined, release?: (() => Promise<void>) | undefined);
50
+ constructor(client: StdClient, pgOptions?: PrismaPgOptions | undefined, release?: (() => Promise<void>) | undefined);
50
51
  startTransaction(isolationLevel?: IsolationLevel): Promise<Transaction>;
51
52
  executeScript(script: string): Promise<void>;
52
53
  getConnectionInfo(): ConnectionInfo;
@@ -58,10 +59,14 @@ declare type PrismaPgOptions = {
58
59
  schema?: string;
59
60
  disposeExternalPool?: boolean;
60
61
  onPoolError?: (err: Error) => void;
62
+ onConnectionError?: (err: Error) => void;
63
+ userDefinedTypeParser?: UserDefinedTypeParser;
61
64
  };
62
65
 
63
66
  declare type StdClient = pg.Pool;
64
67
 
65
68
  declare type TransactionClient = pg.PoolClient;
66
69
 
70
+ declare type UserDefinedTypeParser = (oid: number, value: unknown, adapter: SqlQueryable) => Promise<unknown>;
71
+
67
72
  export { }
package/dist/index.js CHANGED
@@ -41,6 +41,9 @@ var import_pg2 = __toESM(require("pg"));
41
41
  // package.json
42
42
  var name = "@prisma/adapter-pg";
43
43
 
44
+ // src/constants.ts
45
+ var FIRST_NORMAL_OBJECT_ID = 16384;
46
+
44
47
  // src/conversion.ts
45
48
  var import_driver_adapter_utils = require("@prisma/driver-adapter-utils");
46
49
  var import_pg = __toESM(require("pg"));
@@ -282,7 +285,7 @@ function fieldToColumnType(fieldTypeId) {
282
285
  case ArrayColumnType.OID_ARRAY:
283
286
  return import_driver_adapter_utils.ColumnTypeEnum.Int64Array;
284
287
  default:
285
- if (fieldTypeId >= 1e4) {
288
+ if (fieldTypeId >= FIRST_NORMAL_OBJECT_ID) {
286
289
  return import_driver_adapter_utils.ColumnTypeEnum.Text;
287
290
  }
288
291
  throw new UnsupportedNativeDataType(fieldTypeId);
@@ -358,20 +361,51 @@ var customParsers = {
358
361
  [ArrayColumnType.VARBIT_ARRAY]: normalize_array(normalizeBit),
359
362
  [ArrayColumnType.XML_ARRAY]: normalize_array(normalize_xml)
360
363
  };
361
- function fixArrayBufferValues(values) {
362
- for (let i = 0; i < values.length; i++) {
363
- const list = values[i];
364
- if (!Array.isArray(list)) {
365
- continue;
366
- }
367
- for (let j = 0; j < list.length; j++) {
368
- const listItem = list[j];
369
- if (ArrayBuffer.isView(listItem)) {
370
- list[j] = Buffer.from(listItem.buffer, listItem.byteOffset, listItem.byteLength);
371
- }
364
+ function mapArg(arg, argType) {
365
+ if (arg === null) {
366
+ return null;
367
+ }
368
+ if (Array.isArray(arg) && argType.arity === "list") {
369
+ return arg.map((value) => mapArg(value, argType));
370
+ }
371
+ if (typeof arg === "string" && argType.scalarType === "datetime") {
372
+ arg = new Date(arg);
373
+ }
374
+ if (arg instanceof Date) {
375
+ switch (argType.dbType) {
376
+ case "TIME":
377
+ case "TIMETZ":
378
+ return formatTime(arg);
379
+ case "DATE":
380
+ return formatDate(arg);
381
+ default:
382
+ return formatDateTime(arg);
372
383
  }
373
384
  }
374
- return values;
385
+ if (typeof arg === "string" && argType.scalarType === "bytes") {
386
+ return Buffer.from(arg, "base64");
387
+ }
388
+ if (Array.isArray(arg) && argType.scalarType === "bytes") {
389
+ return Buffer.from(arg);
390
+ }
391
+ if (ArrayBuffer.isView(arg)) {
392
+ return Buffer.from(arg.buffer, arg.byteOffset, arg.byteLength);
393
+ }
394
+ return arg;
395
+ }
396
+ function formatDateTime(date) {
397
+ const pad = (n, z = 2) => String(n).padStart(z, "0");
398
+ const ms = date.getUTCMilliseconds();
399
+ return date.getUTCFullYear() + "-" + pad(date.getUTCMonth() + 1) + "-" + pad(date.getUTCDate()) + " " + pad(date.getUTCHours()) + ":" + pad(date.getUTCMinutes()) + ":" + pad(date.getUTCSeconds()) + (ms ? "." + String(ms).padStart(3, "0") : "");
400
+ }
401
+ function formatDate(date) {
402
+ const pad = (n, z = 2) => String(n).padStart(z, "0");
403
+ return date.getUTCFullYear() + "-" + pad(date.getUTCMonth() + 1) + "-" + pad(date.getUTCDate());
404
+ }
405
+ function formatTime(date) {
406
+ const pad = (n, z = 2) => String(n).padStart(z, "0");
407
+ const ms = date.getUTCMilliseconds();
408
+ return pad(date.getUTCHours()) + ":" + pad(date.getUTCMinutes()) + ":" + pad(date.getUTCSeconds()) + (ms ? "." + String(ms).padStart(3, "0") : "");
375
409
  }
376
410
 
377
411
  // src/errors.ts
@@ -555,8 +589,9 @@ function isTlsError(error) {
555
589
  var types2 = import_pg2.default.types;
556
590
  var debug = (0, import_driver_adapter_utils2.Debug)("prisma:driver-adapter:pg");
557
591
  var PgQueryable = class {
558
- constructor(client) {
592
+ constructor(client, pgOptions) {
559
593
  this.client = client;
594
+ this.pgOptions = pgOptions;
560
595
  }
561
596
  provider = "postgres";
562
597
  adapterName = name;
@@ -580,6 +615,17 @@ var PgQueryable = class {
580
615
  }
581
616
  throw e;
582
617
  }
618
+ const udtParser = this.pgOptions?.userDefinedTypeParser;
619
+ if (udtParser) {
620
+ for (let i = 0; i < fields.length; i++) {
621
+ const field = fields[i];
622
+ if (field.dataTypeID >= FIRST_NORMAL_OBJECT_ID && !Object.hasOwn(customParsers, field.dataTypeID)) {
623
+ for (let j = 0; j < rows.length; j++) {
624
+ rows[j][i] = await udtParser(field.dataTypeID, rows[j][i], this);
625
+ }
626
+ }
627
+ }
628
+ }
583
629
  return {
584
630
  columnNames,
585
631
  columnTypes,
@@ -602,12 +648,13 @@ var PgQueryable = class {
602
648
  * marked as unhealthy.
603
649
  */
604
650
  async performIO(query) {
605
- const { sql, args: values } = query;
651
+ const { sql, args } = query;
652
+ const values = args.map((arg, i) => mapArg(arg, query.argTypes[i]));
606
653
  try {
607
654
  const result = await this.client.query(
608
655
  {
609
656
  text: sql,
610
- values: fixArrayBufferValues(values),
657
+ values,
611
658
  rowMode: "array",
612
659
  types: {
613
660
  // This is the error expected:
@@ -630,7 +677,7 @@ var PgQueryable = class {
630
677
  }
631
678
  }
632
679
  },
633
- fixArrayBufferValues(values)
680
+ values
634
681
  );
635
682
  return result;
636
683
  } catch (e) {
@@ -643,9 +690,10 @@ var PgQueryable = class {
643
690
  }
644
691
  };
645
692
  var PgTransaction = class extends PgQueryable {
646
- constructor(client, options) {
647
- super(client);
693
+ constructor(client, options, pgOptions) {
694
+ super(client, pgOptions);
648
695
  this.options = options;
696
+ this.pgOptions = pgOptions;
649
697
  }
650
698
  async commit() {
651
699
  debug(`[js::commit]`);
@@ -657,9 +705,9 @@ var PgTransaction = class extends PgQueryable {
657
705
  }
658
706
  };
659
707
  var PrismaPgAdapter = class extends PgQueryable {
660
- constructor(client, options, release) {
708
+ constructor(client, pgOptions, release) {
661
709
  super(client);
662
- this.options = options;
710
+ this.pgOptions = pgOptions;
663
711
  this.release = release;
664
712
  }
665
713
  async startTransaction(isolationLevel) {
@@ -669,6 +717,10 @@ var PrismaPgAdapter = class extends PgQueryable {
669
717
  const tag = "[js::startTransaction]";
670
718
  debug("%s options: %O", tag, options);
671
719
  const conn = await this.client.connect().catch((error) => this.onError(error));
720
+ conn.on("error", (err) => {
721
+ debug(`Error from pool connection: ${err.message} %O`, err);
722
+ this.pgOptions?.onConnectionError?.(err);
723
+ });
672
724
  try {
673
725
  const tx = new PgTransaction(conn, options);
674
726
  await tx.executeRaw({ sql: "BEGIN", args: [], argTypes: [] });
@@ -697,7 +749,7 @@ var PrismaPgAdapter = class extends PgQueryable {
697
749
  }
698
750
  getConnectionInfo() {
699
751
  return {
700
- schemaName: this.options?.schema,
752
+ schemaName: this.pgOptions?.schema,
701
753
  supportsRelationJoins: true
702
754
  };
703
755
  }
package/dist/index.mjs CHANGED
@@ -5,6 +5,9 @@ import pg2 from "pg";
5
5
  // package.json
6
6
  var name = "@prisma/adapter-pg";
7
7
 
8
+ // src/constants.ts
9
+ var FIRST_NORMAL_OBJECT_ID = 16384;
10
+
8
11
  // src/conversion.ts
9
12
  import { ColumnTypeEnum } from "@prisma/driver-adapter-utils";
10
13
  import pg from "pg";
@@ -246,7 +249,7 @@ function fieldToColumnType(fieldTypeId) {
246
249
  case ArrayColumnType.OID_ARRAY:
247
250
  return ColumnTypeEnum.Int64Array;
248
251
  default:
249
- if (fieldTypeId >= 1e4) {
252
+ if (fieldTypeId >= FIRST_NORMAL_OBJECT_ID) {
250
253
  return ColumnTypeEnum.Text;
251
254
  }
252
255
  throw new UnsupportedNativeDataType(fieldTypeId);
@@ -322,20 +325,51 @@ var customParsers = {
322
325
  [ArrayColumnType.VARBIT_ARRAY]: normalize_array(normalizeBit),
323
326
  [ArrayColumnType.XML_ARRAY]: normalize_array(normalize_xml)
324
327
  };
325
- function fixArrayBufferValues(values) {
326
- for (let i = 0; i < values.length; i++) {
327
- const list = values[i];
328
- if (!Array.isArray(list)) {
329
- continue;
330
- }
331
- for (let j = 0; j < list.length; j++) {
332
- const listItem = list[j];
333
- if (ArrayBuffer.isView(listItem)) {
334
- list[j] = Buffer.from(listItem.buffer, listItem.byteOffset, listItem.byteLength);
335
- }
328
+ function mapArg(arg, argType) {
329
+ if (arg === null) {
330
+ return null;
331
+ }
332
+ if (Array.isArray(arg) && argType.arity === "list") {
333
+ return arg.map((value) => mapArg(value, argType));
334
+ }
335
+ if (typeof arg === "string" && argType.scalarType === "datetime") {
336
+ arg = new Date(arg);
337
+ }
338
+ if (arg instanceof Date) {
339
+ switch (argType.dbType) {
340
+ case "TIME":
341
+ case "TIMETZ":
342
+ return formatTime(arg);
343
+ case "DATE":
344
+ return formatDate(arg);
345
+ default:
346
+ return formatDateTime(arg);
336
347
  }
337
348
  }
338
- return values;
349
+ if (typeof arg === "string" && argType.scalarType === "bytes") {
350
+ return Buffer.from(arg, "base64");
351
+ }
352
+ if (Array.isArray(arg) && argType.scalarType === "bytes") {
353
+ return Buffer.from(arg);
354
+ }
355
+ if (ArrayBuffer.isView(arg)) {
356
+ return Buffer.from(arg.buffer, arg.byteOffset, arg.byteLength);
357
+ }
358
+ return arg;
359
+ }
360
+ function formatDateTime(date) {
361
+ const pad = (n, z = 2) => String(n).padStart(z, "0");
362
+ const ms = date.getUTCMilliseconds();
363
+ return date.getUTCFullYear() + "-" + pad(date.getUTCMonth() + 1) + "-" + pad(date.getUTCDate()) + " " + pad(date.getUTCHours()) + ":" + pad(date.getUTCMinutes()) + ":" + pad(date.getUTCSeconds()) + (ms ? "." + String(ms).padStart(3, "0") : "");
364
+ }
365
+ function formatDate(date) {
366
+ const pad = (n, z = 2) => String(n).padStart(z, "0");
367
+ return date.getUTCFullYear() + "-" + pad(date.getUTCMonth() + 1) + "-" + pad(date.getUTCDate());
368
+ }
369
+ function formatTime(date) {
370
+ const pad = (n, z = 2) => String(n).padStart(z, "0");
371
+ const ms = date.getUTCMilliseconds();
372
+ return pad(date.getUTCHours()) + ":" + pad(date.getUTCMinutes()) + ":" + pad(date.getUTCSeconds()) + (ms ? "." + String(ms).padStart(3, "0") : "");
339
373
  }
340
374
 
341
375
  // src/errors.ts
@@ -519,8 +553,9 @@ function isTlsError(error) {
519
553
  var types2 = pg2.types;
520
554
  var debug = Debug("prisma:driver-adapter:pg");
521
555
  var PgQueryable = class {
522
- constructor(client) {
556
+ constructor(client, pgOptions) {
523
557
  this.client = client;
558
+ this.pgOptions = pgOptions;
524
559
  }
525
560
  provider = "postgres";
526
561
  adapterName = name;
@@ -544,6 +579,17 @@ var PgQueryable = class {
544
579
  }
545
580
  throw e;
546
581
  }
582
+ const udtParser = this.pgOptions?.userDefinedTypeParser;
583
+ if (udtParser) {
584
+ for (let i = 0; i < fields.length; i++) {
585
+ const field = fields[i];
586
+ if (field.dataTypeID >= FIRST_NORMAL_OBJECT_ID && !Object.hasOwn(customParsers, field.dataTypeID)) {
587
+ for (let j = 0; j < rows.length; j++) {
588
+ rows[j][i] = await udtParser(field.dataTypeID, rows[j][i], this);
589
+ }
590
+ }
591
+ }
592
+ }
547
593
  return {
548
594
  columnNames,
549
595
  columnTypes,
@@ -566,12 +612,13 @@ var PgQueryable = class {
566
612
  * marked as unhealthy.
567
613
  */
568
614
  async performIO(query) {
569
- const { sql, args: values } = query;
615
+ const { sql, args } = query;
616
+ const values = args.map((arg, i) => mapArg(arg, query.argTypes[i]));
570
617
  try {
571
618
  const result = await this.client.query(
572
619
  {
573
620
  text: sql,
574
- values: fixArrayBufferValues(values),
621
+ values,
575
622
  rowMode: "array",
576
623
  types: {
577
624
  // This is the error expected:
@@ -594,7 +641,7 @@ var PgQueryable = class {
594
641
  }
595
642
  }
596
643
  },
597
- fixArrayBufferValues(values)
644
+ values
598
645
  );
599
646
  return result;
600
647
  } catch (e) {
@@ -607,9 +654,10 @@ var PgQueryable = class {
607
654
  }
608
655
  };
609
656
  var PgTransaction = class extends PgQueryable {
610
- constructor(client, options) {
611
- super(client);
657
+ constructor(client, options, pgOptions) {
658
+ super(client, pgOptions);
612
659
  this.options = options;
660
+ this.pgOptions = pgOptions;
613
661
  }
614
662
  async commit() {
615
663
  debug(`[js::commit]`);
@@ -621,9 +669,9 @@ var PgTransaction = class extends PgQueryable {
621
669
  }
622
670
  };
623
671
  var PrismaPgAdapter = class extends PgQueryable {
624
- constructor(client, options, release) {
672
+ constructor(client, pgOptions, release) {
625
673
  super(client);
626
- this.options = options;
674
+ this.pgOptions = pgOptions;
627
675
  this.release = release;
628
676
  }
629
677
  async startTransaction(isolationLevel) {
@@ -633,6 +681,10 @@ var PrismaPgAdapter = class extends PgQueryable {
633
681
  const tag = "[js::startTransaction]";
634
682
  debug("%s options: %O", tag, options);
635
683
  const conn = await this.client.connect().catch((error) => this.onError(error));
684
+ conn.on("error", (err) => {
685
+ debug(`Error from pool connection: ${err.message} %O`, err);
686
+ this.pgOptions?.onConnectionError?.(err);
687
+ });
636
688
  try {
637
689
  const tx = new PgTransaction(conn, options);
638
690
  await tx.executeRaw({ sql: "BEGIN", args: [], argTypes: [] });
@@ -661,7 +713,7 @@ var PrismaPgAdapter = class extends PgQueryable {
661
713
  }
662
714
  getConnectionInfo() {
663
715
  return {
664
- schemaName: this.options?.schema,
716
+ schemaName: this.pgOptions?.schema,
665
717
  supportsRelationJoins: true
666
718
  };
667
719
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prisma/adapter-pg",
3
- "version": "6.15.0-dev.3",
3
+ "version": "6.15.0-dev.30",
4
4
  "description": "Prisma's driver adapter for \"pg\"",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -33,7 +33,7 @@
33
33
  "dependencies": {
34
34
  "postgres-array": "3.0.4",
35
35
  "pg": "^8.11.3",
36
- "@prisma/driver-adapter-utils": "6.15.0-dev.3"
36
+ "@prisma/driver-adapter-utils": "6.15.0-dev.30"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@swc/core": "1.11.5",