pgsql-test 2.20.8 → 2.22.0

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/connect.js CHANGED
@@ -9,6 +9,7 @@ const pgsql_client_1 = require("pgsql-client");
9
9
  const admin_1 = require("./admin");
10
10
  const manager_1 = require("./manager");
11
11
  const seed_1 = require("./seed");
12
+ const utils_1 = require("./utils");
12
13
  let manager;
13
14
  const getPgRootAdmin = (config, connOpts = {}) => {
14
15
  const opts = (0, pg_env_1.getPgEnvOptions)({
@@ -76,9 +77,9 @@ const getConnections = async (cn = {}, seedAdapters = [seed_1.seed.pgpm()]) => {
76
77
  });
77
78
  }
78
79
  catch (error) {
79
- const err = error;
80
- const msg = err && (err.stack || err.message) ? (err.stack || err.message) : String(err);
81
- process.stderr.write(`[pgsql-test] Seed error (continuing): ${msg}\n`);
80
+ // Format the error with PostgreSQL extended fields for better debugging
81
+ const formatted = (0, utils_1.formatPgError)(error);
82
+ process.stderr.write(`[pgsql-test] Seed error (continuing):\n${formatted}\n`);
82
83
  // continue without teardown to allow caller-managed lifecycle
83
84
  }
84
85
  }
package/esm/connect.js CHANGED
@@ -6,6 +6,7 @@ import { getDefaultRole } from 'pgsql-client';
6
6
  import { DbAdmin } from './admin';
7
7
  import { PgTestConnector } from './manager';
8
8
  import { seed } from './seed';
9
+ import { formatPgError } from './utils';
9
10
  let manager;
10
11
  export const getPgRootAdmin = (config, connOpts = {}) => {
11
12
  const opts = getPgEnvOptions({
@@ -72,9 +73,9 @@ export const getConnections = async (cn = {}, seedAdapters = [seed.pgpm()]) => {
72
73
  });
73
74
  }
74
75
  catch (error) {
75
- const err = error;
76
- const msg = err && (err.stack || err.message) ? (err.stack || err.message) : String(err);
77
- process.stderr.write(`[pgsql-test] Seed error (continuing): ${msg}\n`);
76
+ // Format the error with PostgreSQL extended fields for better debugging
77
+ const formatted = formatPgError(error);
78
+ process.stderr.write(`[pgsql-test] Seed error (continuing):\n${formatted}\n`);
78
79
  // continue without teardown to allow caller-managed lifecycle
79
80
  }
80
81
  }
package/esm/index.js CHANGED
@@ -3,4 +3,4 @@ export * from './connect';
3
3
  export * from './manager';
4
4
  export * from './seed';
5
5
  export * from './test-client';
6
- export { snapshot } from './utils';
6
+ export { snapshot, getErrorCode } from './utils';
@@ -3,9 +3,36 @@ import { insertJsonMap } from 'pgsql-seed';
3
3
  import { loadCsvMap } from 'pgsql-seed';
4
4
  import { loadSqlFiles } from 'pgsql-seed';
5
5
  import { deployPgpm } from 'pgsql-seed';
6
+ import { formatPgError } from './utils';
6
7
  export class PgTestClient extends PgClient {
8
+ testOpts;
7
9
  constructor(config, opts = {}) {
8
10
  super(config, opts);
11
+ this.testOpts = opts;
12
+ }
13
+ /**
14
+ * Check if enhanced errors are enabled. Defaults to true.
15
+ * Can be disabled by setting enhancedErrors: false in options.
16
+ */
17
+ shouldEnhanceErrors() {
18
+ // Default to true unless explicitly disabled via option
19
+ return this.testOpts.enhancedErrors !== false;
20
+ }
21
+ /**
22
+ * Override query to enhance PostgreSQL errors with extended fields.
23
+ * When enhancedErrors is enabled, errors will include detail, hint, where, position, etc.
24
+ */
25
+ async query(query, values) {
26
+ try {
27
+ return await super.query(query, values);
28
+ }
29
+ catch (err) {
30
+ if (this.shouldEnhanceErrors()) {
31
+ // Enhance the error message with PostgreSQL extended fields
32
+ err.message = formatPgError(err, { query, values });
33
+ }
34
+ throw err;
35
+ }
9
36
  }
10
37
  async beforeEach() {
11
38
  await this.begin();
package/esm/utils.js CHANGED
@@ -1,3 +1,24 @@
1
+ import { extractPgErrorFields, formatPgErrorFields, formatPgError } from '@pgpmjs/types';
2
+ // Re-export PostgreSQL error formatting utilities
3
+ export { extractPgErrorFields, formatPgErrorFields, formatPgError };
4
+ /**
5
+ * Extract the error code from an error message.
6
+ *
7
+ * Enhanced error messages from PgTestClient include additional context on subsequent lines
8
+ * (Where, Query, Values, etc.). This function returns only the first line, which contains
9
+ * the actual error code raised by PostgreSQL.
10
+ *
11
+ * @param message - The error message (may contain multiple lines with debug context)
12
+ * @returns The first line of the error message (the error code)
13
+ *
14
+ * @example
15
+ * // Error message with enhanced context:
16
+ * // "NONEXISTENT_TYPE\nWhere: PL/pgSQL function...\nQuery: INSERT INTO..."
17
+ * getErrorCode(err.message) // => "NONEXISTENT_TYPE"
18
+ */
19
+ export function getErrorCode(message) {
20
+ return message.split('\n')[0];
21
+ }
1
22
  const uuidRegexp = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
2
23
  const idReplacement = (v, idHash) => {
3
24
  if (!v)
package/index.d.ts CHANGED
@@ -3,4 +3,4 @@ export * from './connect';
3
3
  export * from './manager';
4
4
  export * from './seed';
5
5
  export * from './test-client';
6
- export { snapshot } from './utils';
6
+ export { snapshot, getErrorCode } from './utils';
package/index.js CHANGED
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.snapshot = void 0;
17
+ exports.getErrorCode = exports.snapshot = void 0;
18
18
  __exportStar(require("./admin"), exports);
19
19
  __exportStar(require("./connect"), exports);
20
20
  __exportStar(require("./manager"), exports);
@@ -22,3 +22,4 @@ __exportStar(require("./seed"), exports);
22
22
  __exportStar(require("./test-client"), exports);
23
23
  var utils_1 = require("./utils");
24
24
  Object.defineProperty(exports, "snapshot", { enumerable: true, get: function () { return utils_1.snapshot; } });
25
+ Object.defineProperty(exports, "getErrorCode", { enumerable: true, get: function () { return utils_1.getErrorCode; } });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pgsql-test",
3
- "version": "2.20.8",
3
+ "version": "2.22.0",
4
4
  "author": "Constructive <developers@constructive.io>",
5
5
  "description": "pgsql-test offers isolated, role-aware, and rollback-friendly PostgreSQL environments for integration tests — giving developers realistic test coverage without external state pollution",
6
6
  "main": "index.js",
@@ -55,20 +55,21 @@
55
55
  "test:watch": "jest --watch"
56
56
  },
57
57
  "devDependencies": {
58
+ "@pgpmjs/core": "4.7.1",
58
59
  "@types/pg": "^8.16.0",
59
60
  "@types/pg-copy-streams": "^1.2.5",
60
- "makage": "^0.1.9"
61
+ "makage": "^0.1.10"
61
62
  },
62
63
  "dependencies": {
63
- "@pgpmjs/env": "^2.9.1",
64
- "@pgpmjs/logger": "^1.3.6",
65
- "@pgpmjs/server-utils": "^2.8.13",
66
- "@pgpmjs/types": "^2.13.0",
64
+ "@pgpmjs/env": "^2.9.2",
65
+ "@pgpmjs/logger": "^1.3.7",
66
+ "@pgpmjs/server-utils": "^2.8.14",
67
+ "@pgpmjs/types": "^2.14.0",
67
68
  "pg": "^8.16.3",
68
- "pg-cache": "^1.6.13",
69
- "pg-env": "^1.2.4",
70
- "pgsql-client": "^1.1.8",
71
- "pgsql-seed": "^0.2.10"
69
+ "pg-cache": "^1.6.14",
70
+ "pg-env": "^1.2.5",
71
+ "pgsql-client": "^1.1.10",
72
+ "pgsql-seed": "^0.2.12"
72
73
  },
73
- "gitHead": "e53cd1f303d796268d94b47e95cde30916e39c1f"
74
+ "gitHead": "acb072b93704ad5218dd2c38306680f3750ead09"
74
75
  }
package/test-client.d.ts CHANGED
@@ -2,9 +2,28 @@ import { PgConfig } from 'pg-env';
2
2
  import { PgClient, PgClientOpts } from 'pgsql-client';
3
3
  import { type JsonSeedMap } from 'pgsql-seed';
4
4
  import { type CsvSeedMap } from 'pgsql-seed';
5
- export type PgTestClientOpts = PgClientOpts;
5
+ import { QueryResult } from 'pg';
6
+ export type PgTestClientOpts = PgClientOpts & {
7
+ /**
8
+ * Enable enhanced PostgreSQL error messages with extended fields.
9
+ * Defaults to true. Errors will include detail, hint, where, position, etc.
10
+ * Can be disabled by setting enhancedErrors: false.
11
+ */
12
+ enhancedErrors?: boolean;
13
+ };
6
14
  export declare class PgTestClient extends PgClient {
15
+ protected testOpts: PgTestClientOpts;
7
16
  constructor(config: PgConfig, opts?: PgTestClientOpts);
17
+ /**
18
+ * Check if enhanced errors are enabled. Defaults to true.
19
+ * Can be disabled by setting enhancedErrors: false in options.
20
+ */
21
+ private shouldEnhanceErrors;
22
+ /**
23
+ * Override query to enhance PostgreSQL errors with extended fields.
24
+ * When enhancedErrors is enabled, errors will include detail, hint, where, position, etc.
25
+ */
26
+ query<T = any>(query: string, values?: any[]): Promise<QueryResult<T>>;
8
27
  beforeEach(): Promise<void>;
9
28
  afterEach(): Promise<void>;
10
29
  /**
package/test-client.js CHANGED
@@ -6,9 +6,36 @@ const pgsql_seed_1 = require("pgsql-seed");
6
6
  const pgsql_seed_2 = require("pgsql-seed");
7
7
  const pgsql_seed_3 = require("pgsql-seed");
8
8
  const pgsql_seed_4 = require("pgsql-seed");
9
+ const utils_1 = require("./utils");
9
10
  class PgTestClient extends pgsql_client_1.PgClient {
11
+ testOpts;
10
12
  constructor(config, opts = {}) {
11
13
  super(config, opts);
14
+ this.testOpts = opts;
15
+ }
16
+ /**
17
+ * Check if enhanced errors are enabled. Defaults to true.
18
+ * Can be disabled by setting enhancedErrors: false in options.
19
+ */
20
+ shouldEnhanceErrors() {
21
+ // Default to true unless explicitly disabled via option
22
+ return this.testOpts.enhancedErrors !== false;
23
+ }
24
+ /**
25
+ * Override query to enhance PostgreSQL errors with extended fields.
26
+ * When enhancedErrors is enabled, errors will include detail, hint, where, position, etc.
27
+ */
28
+ async query(query, values) {
29
+ try {
30
+ return await super.query(query, values);
31
+ }
32
+ catch (err) {
33
+ if (this.shouldEnhanceErrors()) {
34
+ // Enhance the error message with PostgreSQL extended fields
35
+ err.message = (0, utils_1.formatPgError)(err, { query, values });
36
+ }
37
+ throw err;
38
+ }
12
39
  }
13
40
  async beforeEach() {
14
41
  await this.begin();
package/utils.d.ts CHANGED
@@ -1,3 +1,21 @@
1
+ import { extractPgErrorFields, formatPgErrorFields, formatPgError, type PgErrorFields, type PgErrorContext } from '@pgpmjs/types';
2
+ export { extractPgErrorFields, formatPgErrorFields, formatPgError, type PgErrorFields, type PgErrorContext };
3
+ /**
4
+ * Extract the error code from an error message.
5
+ *
6
+ * Enhanced error messages from PgTestClient include additional context on subsequent lines
7
+ * (Where, Query, Values, etc.). This function returns only the first line, which contains
8
+ * the actual error code raised by PostgreSQL.
9
+ *
10
+ * @param message - The error message (may contain multiple lines with debug context)
11
+ * @returns The first line of the error message (the error code)
12
+ *
13
+ * @example
14
+ * // Error message with enhanced context:
15
+ * // "NONEXISTENT_TYPE\nWhere: PL/pgSQL function...\nQuery: INSERT INTO..."
16
+ * getErrorCode(err.message) // => "NONEXISTENT_TYPE"
17
+ */
18
+ export declare function getErrorCode(message: string): string;
1
19
  export type IdHash = Record<string, number | string>;
2
20
  type AnyObject = Record<string, any>;
3
21
  export declare const pruneDates: (row: AnyObject) => AnyObject;
@@ -14,4 +32,3 @@ export declare const defaultPruners: Pruner[];
14
32
  export declare const prune: (row: AnyObject, idHash?: IdHash) => AnyObject;
15
33
  export declare const createSnapshot: (pruners: Pruner[]) => (obj: unknown, idHash?: IdHash) => unknown;
16
34
  export declare const snapshot: (obj: unknown, idHash?: IdHash) => unknown;
17
- export {};
package/utils.js CHANGED
@@ -1,6 +1,29 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.snapshot = exports.createSnapshot = exports.prune = exports.defaultPruners = exports.composePruners = exports.pruneTokens = exports.prunePeoplestamps = exports.pruneSchemas = exports.pruneHashes = exports.pruneUUIDs = exports.pruneIdArrays = exports.pruneIds = exports.pruneDates = void 0;
3
+ exports.snapshot = exports.createSnapshot = exports.prune = exports.defaultPruners = exports.composePruners = exports.pruneTokens = exports.prunePeoplestamps = exports.pruneSchemas = exports.pruneHashes = exports.pruneUUIDs = exports.pruneIdArrays = exports.pruneIds = exports.pruneDates = exports.formatPgError = exports.formatPgErrorFields = exports.extractPgErrorFields = void 0;
4
+ exports.getErrorCode = getErrorCode;
5
+ const types_1 = require("@pgpmjs/types");
6
+ Object.defineProperty(exports, "extractPgErrorFields", { enumerable: true, get: function () { return types_1.extractPgErrorFields; } });
7
+ Object.defineProperty(exports, "formatPgErrorFields", { enumerable: true, get: function () { return types_1.formatPgErrorFields; } });
8
+ Object.defineProperty(exports, "formatPgError", { enumerable: true, get: function () { return types_1.formatPgError; } });
9
+ /**
10
+ * Extract the error code from an error message.
11
+ *
12
+ * Enhanced error messages from PgTestClient include additional context on subsequent lines
13
+ * (Where, Query, Values, etc.). This function returns only the first line, which contains
14
+ * the actual error code raised by PostgreSQL.
15
+ *
16
+ * @param message - The error message (may contain multiple lines with debug context)
17
+ * @returns The first line of the error message (the error code)
18
+ *
19
+ * @example
20
+ * // Error message with enhanced context:
21
+ * // "NONEXISTENT_TYPE\nWhere: PL/pgSQL function...\nQuery: INSERT INTO..."
22
+ * getErrorCode(err.message) // => "NONEXISTENT_TYPE"
23
+ */
24
+ function getErrorCode(message) {
25
+ return message.split('\n')[0];
26
+ }
4
27
  const uuidRegexp = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
5
28
  const idReplacement = (v, idHash) => {
6
29
  if (!v)