@prisma/adapter-pg 6.13.0-dev.19 → 6.13.0-dev.20

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
@@ -1,6 +1,36 @@
1
+ import type { ConnectionInfo } from '@prisma/driver-adapter-utils';
2
+ import type { IsolationLevel } from '@prisma/driver-adapter-utils';
1
3
  import pg from 'pg';
2
4
  import type { SqlDriverAdapter } from '@prisma/driver-adapter-utils';
3
5
  import type { SqlMigrationAwareDriverAdapterFactory } from '@prisma/driver-adapter-utils';
6
+ import type { SqlQuery } from '@prisma/driver-adapter-utils';
7
+ import type { SqlQueryable } from '@prisma/driver-adapter-utils';
8
+ import type { SqlResultSet } from '@prisma/driver-adapter-utils';
9
+ import type { Transaction } from '@prisma/driver-adapter-utils';
10
+
11
+ declare class PgQueryable<ClientT extends StdClient | TransactionClient> implements SqlQueryable {
12
+ protected readonly client: ClientT;
13
+ readonly provider = "postgres";
14
+ readonly adapterName: string;
15
+ constructor(client: ClientT);
16
+ /**
17
+ * Execute a query given as SQL, interpolating the given parameters.
18
+ */
19
+ queryRaw(query: SqlQuery): Promise<SqlResultSet>;
20
+ /**
21
+ * Execute a query given as SQL, interpolating the given parameters and
22
+ * returning the number of affected rows.
23
+ * Note: Queryable expects a u64, but napi.rs only supports u32.
24
+ */
25
+ executeRaw(query: SqlQuery): Promise<number>;
26
+ /**
27
+ * Run a query against the database, returning the result set.
28
+ * Should the query fail due to a connection error, the connection is
29
+ * marked as unhealthy.
30
+ */
31
+ private performIO;
32
+ protected onError(error: any): never;
33
+ }
4
34
 
5
35
  export declare class PrismaPg implements SqlMigrationAwareDriverAdapterFactory {
6
36
  private readonly options?;
@@ -9,13 +39,29 @@ export declare class PrismaPg implements SqlMigrationAwareDriverAdapterFactory {
9
39
  private readonly config;
10
40
  private externalPool;
11
41
  constructor(poolOrConfig: pg.Pool | pg.PoolConfig, options?: PrismaPgOptions | undefined);
12
- connect(): Promise<SqlDriverAdapter>;
13
- connectToShadowDb(): Promise<SqlDriverAdapter>;
42
+ connect(): Promise<PrismaPgAdapter>;
43
+ connectToShadowDb(): Promise<PrismaPgAdapter>;
44
+ }
45
+
46
+ declare class PrismaPgAdapter extends PgQueryable<StdClient> implements SqlDriverAdapter {
47
+ private options?;
48
+ private readonly release?;
49
+ constructor(client: StdClient, options?: PrismaPgOptions | undefined, release?: (() => Promise<void>) | undefined);
50
+ startTransaction(isolationLevel?: IsolationLevel): Promise<Transaction>;
51
+ executeScript(script: string): Promise<void>;
52
+ getConnectionInfo(): ConnectionInfo;
53
+ dispose(): Promise<void>;
54
+ underlyingDriver(): pg.Pool;
14
55
  }
15
56
 
16
57
  declare type PrismaPgOptions = {
17
58
  schema?: string;
18
59
  disposeExternalPool?: boolean;
60
+ onPoolError?: (err: Error) => void;
19
61
  };
20
62
 
63
+ declare type StdClient = pg.Pool;
64
+
65
+ declare type TransactionClient = pg.PoolClient;
66
+
21
67
  export { }
package/dist/index.d.ts CHANGED
@@ -1,6 +1,36 @@
1
+ import type { ConnectionInfo } from '@prisma/driver-adapter-utils';
2
+ import type { IsolationLevel } from '@prisma/driver-adapter-utils';
1
3
  import pg from 'pg';
2
4
  import type { SqlDriverAdapter } from '@prisma/driver-adapter-utils';
3
5
  import type { SqlMigrationAwareDriverAdapterFactory } from '@prisma/driver-adapter-utils';
6
+ import type { SqlQuery } from '@prisma/driver-adapter-utils';
7
+ import type { SqlQueryable } from '@prisma/driver-adapter-utils';
8
+ import type { SqlResultSet } from '@prisma/driver-adapter-utils';
9
+ import type { Transaction } from '@prisma/driver-adapter-utils';
10
+
11
+ declare class PgQueryable<ClientT extends StdClient | TransactionClient> implements SqlQueryable {
12
+ protected readonly client: ClientT;
13
+ readonly provider = "postgres";
14
+ readonly adapterName: string;
15
+ constructor(client: ClientT);
16
+ /**
17
+ * Execute a query given as SQL, interpolating the given parameters.
18
+ */
19
+ queryRaw(query: SqlQuery): Promise<SqlResultSet>;
20
+ /**
21
+ * Execute a query given as SQL, interpolating the given parameters and
22
+ * returning the number of affected rows.
23
+ * Note: Queryable expects a u64, but napi.rs only supports u32.
24
+ */
25
+ executeRaw(query: SqlQuery): Promise<number>;
26
+ /**
27
+ * Run a query against the database, returning the result set.
28
+ * Should the query fail due to a connection error, the connection is
29
+ * marked as unhealthy.
30
+ */
31
+ private performIO;
32
+ protected onError(error: any): never;
33
+ }
4
34
 
5
35
  export declare class PrismaPg implements SqlMigrationAwareDriverAdapterFactory {
6
36
  private readonly options?;
@@ -9,13 +39,29 @@ export declare class PrismaPg implements SqlMigrationAwareDriverAdapterFactory {
9
39
  private readonly config;
10
40
  private externalPool;
11
41
  constructor(poolOrConfig: pg.Pool | pg.PoolConfig, options?: PrismaPgOptions | undefined);
12
- connect(): Promise<SqlDriverAdapter>;
13
- connectToShadowDb(): Promise<SqlDriverAdapter>;
42
+ connect(): Promise<PrismaPgAdapter>;
43
+ connectToShadowDb(): Promise<PrismaPgAdapter>;
44
+ }
45
+
46
+ declare class PrismaPgAdapter extends PgQueryable<StdClient> implements SqlDriverAdapter {
47
+ private options?;
48
+ private readonly release?;
49
+ constructor(client: StdClient, options?: PrismaPgOptions | undefined, release?: (() => Promise<void>) | undefined);
50
+ startTransaction(isolationLevel?: IsolationLevel): Promise<Transaction>;
51
+ executeScript(script: string): Promise<void>;
52
+ getConnectionInfo(): ConnectionInfo;
53
+ dispose(): Promise<void>;
54
+ underlyingDriver(): pg.Pool;
14
55
  }
15
56
 
16
57
  declare type PrismaPgOptions = {
17
58
  schema?: string;
18
59
  disposeExternalPool?: boolean;
60
+ onPoolError?: (err: Error) => void;
19
61
  };
20
62
 
63
+ declare type StdClient = pg.Pool;
64
+
65
+ declare type TransactionClient = pg.PoolClient;
66
+
21
67
  export { }
package/dist/index.js CHANGED
@@ -373,7 +373,63 @@ function fixArrayBufferValues(values) {
373
373
  }
374
374
 
375
375
  // src/errors.ts
376
+ var TLS_ERRORS = /* @__PURE__ */ new Set([
377
+ "UNABLE_TO_GET_ISSUER_CERT",
378
+ "UNABLE_TO_GET_CRL",
379
+ "UNABLE_TO_DECRYPT_CERT_SIGNATURE",
380
+ "UNABLE_TO_DECRYPT_CRL_SIGNATURE",
381
+ "UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY",
382
+ "CERT_SIGNATURE_FAILURE",
383
+ "CRL_SIGNATURE_FAILURE",
384
+ "CERT_NOT_YET_VALID",
385
+ "CERT_HAS_EXPIRED",
386
+ "CRL_NOT_YET_VALID",
387
+ "CRL_HAS_EXPIRED",
388
+ "ERROR_IN_CERT_NOT_BEFORE_FIELD",
389
+ "ERROR_IN_CERT_NOT_AFTER_FIELD",
390
+ "ERROR_IN_CRL_LAST_UPDATE_FIELD",
391
+ "ERROR_IN_CRL_NEXT_UPDATE_FIELD",
392
+ "DEPTH_ZERO_SELF_SIGNED_CERT",
393
+ "SELF_SIGNED_CERT_IN_CHAIN",
394
+ "UNABLE_TO_GET_ISSUER_CERT_LOCALLY",
395
+ "UNABLE_TO_VERIFY_LEAF_SIGNATURE",
396
+ "CERT_CHAIN_TOO_LONG",
397
+ "CERT_REVOKED",
398
+ "INVALID_CA",
399
+ "INVALID_PURPOSE",
400
+ "CERT_UNTRUSTED",
401
+ "CERT_REJECTED",
402
+ "HOSTNAME_MISMATCH",
403
+ "ERR_TLS_CERT_ALTNAME_FORMAT",
404
+ "ERR_TLS_CERT_ALTNAME_INVALID"
405
+ ]);
406
+ var SOCKET_ERRORS = /* @__PURE__ */ new Set(["ENOTFOUND", "ECONNREFUSED", "ECONNRESET", "ETIMEDOUT"]);
376
407
  function convertDriverError(error) {
408
+ if (isSocketError(error)) {
409
+ switch (error.code) {
410
+ case "ENOTFOUND":
411
+ case "ECONNREFUSED":
412
+ return {
413
+ kind: "DatabaseNotReachable",
414
+ host: error.address ?? error.hostname,
415
+ port: error.port
416
+ };
417
+ case "ECONNRESET":
418
+ return {
419
+ kind: "ConnectionClosed"
420
+ };
421
+ case "ETIMEDOUT":
422
+ return {
423
+ kind: "SocketTimeout"
424
+ };
425
+ }
426
+ }
427
+ if (isTlsError(error)) {
428
+ return {
429
+ kind: "TlsConnectionError",
430
+ reason: error.message
431
+ };
432
+ }
377
433
  if (!isDbError(error)) {
378
434
  throw error;
379
435
  }
@@ -468,6 +524,20 @@ function convertDriverError(error) {
468
524
  function isDbError(error) {
469
525
  return typeof error.code === "string" && typeof error.message === "string" && typeof error.severity === "string" && (typeof error.detail === "string" || error.detail === void 0) && (typeof error.column === "string" || error.column === void 0) && (typeof error.hint === "string" || error.hint === void 0);
470
526
  }
527
+ function isSocketError(error) {
528
+ return typeof error.code === "string" && typeof error.syscall === "string" && typeof error.errno === "number" && SOCKET_ERRORS.has(error.code);
529
+ }
530
+ function isTlsError(error) {
531
+ if (typeof error.code === "string") {
532
+ return TLS_ERRORS.has(error.code);
533
+ }
534
+ switch (error.message) {
535
+ case "The server does not support SSL connections":
536
+ case "There was an error establishing an SSL connection":
537
+ return true;
538
+ }
539
+ return false;
540
+ }
471
541
 
472
542
  // src/pg.ts
473
543
  var types2 = import_pg2.default.types;
@@ -622,6 +692,9 @@ var PrismaPgAdapter = class extends PgQueryable {
622
692
  async dispose() {
623
693
  return this.release?.();
624
694
  }
695
+ underlyingDriver() {
696
+ return this.client;
697
+ }
625
698
  };
626
699
  var PrismaPgAdapterFactory = class {
627
700
  constructor(poolOrConfig, options) {
@@ -640,11 +713,18 @@ var PrismaPgAdapterFactory = class {
640
713
  externalPool;
641
714
  async connect() {
642
715
  const client = this.externalPool ?? new import_pg2.default.Pool(this.config);
716
+ const onIdleClientError = (err) => {
717
+ debug(`Error from idle pool client: ${err.message} %O`, err);
718
+ this.options?.onPoolError?.(err);
719
+ };
720
+ client.on("error", onIdleClientError);
643
721
  return new PrismaPgAdapter(client, this.options, async () => {
644
722
  if (this.externalPool) {
645
723
  if (this.options?.disposeExternalPool) {
646
724
  await this.externalPool.end();
647
725
  this.externalPool = null;
726
+ } else {
727
+ this.externalPool.removeListener("error", onIdleClientError);
648
728
  }
649
729
  } else {
650
730
  await client.end();
package/dist/index.mjs CHANGED
@@ -337,7 +337,63 @@ function fixArrayBufferValues(values) {
337
337
  }
338
338
 
339
339
  // src/errors.ts
340
+ var TLS_ERRORS = /* @__PURE__ */ new Set([
341
+ "UNABLE_TO_GET_ISSUER_CERT",
342
+ "UNABLE_TO_GET_CRL",
343
+ "UNABLE_TO_DECRYPT_CERT_SIGNATURE",
344
+ "UNABLE_TO_DECRYPT_CRL_SIGNATURE",
345
+ "UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY",
346
+ "CERT_SIGNATURE_FAILURE",
347
+ "CRL_SIGNATURE_FAILURE",
348
+ "CERT_NOT_YET_VALID",
349
+ "CERT_HAS_EXPIRED",
350
+ "CRL_NOT_YET_VALID",
351
+ "CRL_HAS_EXPIRED",
352
+ "ERROR_IN_CERT_NOT_BEFORE_FIELD",
353
+ "ERROR_IN_CERT_NOT_AFTER_FIELD",
354
+ "ERROR_IN_CRL_LAST_UPDATE_FIELD",
355
+ "ERROR_IN_CRL_NEXT_UPDATE_FIELD",
356
+ "DEPTH_ZERO_SELF_SIGNED_CERT",
357
+ "SELF_SIGNED_CERT_IN_CHAIN",
358
+ "UNABLE_TO_GET_ISSUER_CERT_LOCALLY",
359
+ "UNABLE_TO_VERIFY_LEAF_SIGNATURE",
360
+ "CERT_CHAIN_TOO_LONG",
361
+ "CERT_REVOKED",
362
+ "INVALID_CA",
363
+ "INVALID_PURPOSE",
364
+ "CERT_UNTRUSTED",
365
+ "CERT_REJECTED",
366
+ "HOSTNAME_MISMATCH",
367
+ "ERR_TLS_CERT_ALTNAME_FORMAT",
368
+ "ERR_TLS_CERT_ALTNAME_INVALID"
369
+ ]);
370
+ var SOCKET_ERRORS = /* @__PURE__ */ new Set(["ENOTFOUND", "ECONNREFUSED", "ECONNRESET", "ETIMEDOUT"]);
340
371
  function convertDriverError(error) {
372
+ if (isSocketError(error)) {
373
+ switch (error.code) {
374
+ case "ENOTFOUND":
375
+ case "ECONNREFUSED":
376
+ return {
377
+ kind: "DatabaseNotReachable",
378
+ host: error.address ?? error.hostname,
379
+ port: error.port
380
+ };
381
+ case "ECONNRESET":
382
+ return {
383
+ kind: "ConnectionClosed"
384
+ };
385
+ case "ETIMEDOUT":
386
+ return {
387
+ kind: "SocketTimeout"
388
+ };
389
+ }
390
+ }
391
+ if (isTlsError(error)) {
392
+ return {
393
+ kind: "TlsConnectionError",
394
+ reason: error.message
395
+ };
396
+ }
341
397
  if (!isDbError(error)) {
342
398
  throw error;
343
399
  }
@@ -432,6 +488,20 @@ function convertDriverError(error) {
432
488
  function isDbError(error) {
433
489
  return typeof error.code === "string" && typeof error.message === "string" && typeof error.severity === "string" && (typeof error.detail === "string" || error.detail === void 0) && (typeof error.column === "string" || error.column === void 0) && (typeof error.hint === "string" || error.hint === void 0);
434
490
  }
491
+ function isSocketError(error) {
492
+ return typeof error.code === "string" && typeof error.syscall === "string" && typeof error.errno === "number" && SOCKET_ERRORS.has(error.code);
493
+ }
494
+ function isTlsError(error) {
495
+ if (typeof error.code === "string") {
496
+ return TLS_ERRORS.has(error.code);
497
+ }
498
+ switch (error.message) {
499
+ case "The server does not support SSL connections":
500
+ case "There was an error establishing an SSL connection":
501
+ return true;
502
+ }
503
+ return false;
504
+ }
435
505
 
436
506
  // src/pg.ts
437
507
  var types2 = pg2.types;
@@ -586,6 +656,9 @@ var PrismaPgAdapter = class extends PgQueryable {
586
656
  async dispose() {
587
657
  return this.release?.();
588
658
  }
659
+ underlyingDriver() {
660
+ return this.client;
661
+ }
589
662
  };
590
663
  var PrismaPgAdapterFactory = class {
591
664
  constructor(poolOrConfig, options) {
@@ -604,11 +677,18 @@ var PrismaPgAdapterFactory = class {
604
677
  externalPool;
605
678
  async connect() {
606
679
  const client = this.externalPool ?? new pg2.Pool(this.config);
680
+ const onIdleClientError = (err) => {
681
+ debug(`Error from idle pool client: ${err.message} %O`, err);
682
+ this.options?.onPoolError?.(err);
683
+ };
684
+ client.on("error", onIdleClientError);
607
685
  return new PrismaPgAdapter(client, this.options, async () => {
608
686
  if (this.externalPool) {
609
687
  if (this.options?.disposeExternalPool) {
610
688
  await this.externalPool.end();
611
689
  this.externalPool = null;
690
+ } else {
691
+ this.externalPool.removeListener("error", onIdleClientError);
612
692
  }
613
693
  } else {
614
694
  await client.end();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prisma/adapter-pg",
3
- "version": "6.13.0-dev.19",
3
+ "version": "6.13.0-dev.20",
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.13.0-dev.19"
36
+ "@prisma/driver-adapter-utils": "6.13.0-dev.20"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@swc/core": "1.11.5",