{"version":3,"file":"normalize-error-DnabvDFD.mjs","names":[],"sources":["../src/core/descriptor-meta.ts","../src/normalize-error.ts"],"sourcesContent":["export const postgresDriverDescriptorMeta = {\n  kind: 'driver',\n  familyId: 'sql',\n  targetId: 'postgres',\n  id: 'postgres',\n  version: '0.0.1',\n  capabilities: {},\n} as const;\n","import { SqlConnectionError, SqlQueryError } from '@prisma-next/sql-errors';\n\n/**\n * Postgres error shape from the pg library.\n *\n * Note: The pg library doesn't export a DatabaseError type or interface, but errors\n * thrown by pg.query() and pg.Client have this shape at runtime. We define this\n * interface to match the actual runtime structure documented in the pg library\n * (https://github.com/brianc/node-postgres/blob/master/packages/pg/lib/errors.js).\n *\n * The @types/pg package also doesn't provide comprehensive error type definitions,\n * so we define our own interface based on the runtime error properties.\n */\ninterface PostgresError extends Error {\n  readonly code?: string;\n  readonly constraint?: string;\n  readonly table?: string;\n  readonly column?: string;\n  readonly detail?: string;\n  readonly hint?: string;\n  readonly position?: string;\n  readonly internalPosition?: string;\n  readonly internalQuery?: string;\n  readonly where?: string;\n  readonly schema?: string;\n  readonly file?: string;\n  readonly line?: string;\n  readonly routine?: string;\n}\n\n/**\n * Checks if an error is a connection-related error.\n */\nfunction isConnectionError(error: Error): boolean {\n  const code = (error as { code?: string }).code;\n  if (code) {\n    // Node.js error codes for connection issues\n    if (\n      code === 'ECONNRESET' ||\n      code === 'ETIMEDOUT' ||\n      code === 'ECONNREFUSED' ||\n      code === 'ENOTFOUND' ||\n      code === 'EHOSTUNREACH'\n    ) {\n      return true;\n    }\n  }\n\n  // Check error message for connection-related strings\n  const message = error.message.toLowerCase();\n  if (\n    message.includes('connection terminated') ||\n    message.includes('connection closed') ||\n    message.includes('connection refused') ||\n    message.includes('connection timeout') ||\n    message.includes('connection reset')\n  ) {\n    return true;\n  }\n\n  return false;\n}\n\n/**\n * Checks if a connection error is transient (might succeed on retry).\n */\nfunction isTransientConnectionError(error: Error): boolean {\n  const code = (error as { code?: string }).code;\n  if (code) {\n    // Timeouts and connection resets are often transient\n    if (code === 'ETIMEDOUT' || code === 'ECONNRESET') {\n      return true;\n    }\n    // Connection refused is usually not transient (server is down)\n    if (code === 'ECONNREFUSED') {\n      return false;\n    }\n  }\n\n  const message = error.message.toLowerCase();\n  if (message.includes('timeout') || message.includes('connection reset')) {\n    return true;\n  }\n\n  return false;\n}\n\n/**\n * PostgreSQL-specific error properties that indicate an error originated from pg library.\n * These properties are not present on Node.js system errors.\n * Excludes generic properties like 'detail', 'file', 'line', and 'position' that could appear on any error.\n */\nconst PG_ERROR_PROPERTIES = [\n  'constraint',\n  'table',\n  'column',\n  'hint',\n  'internalPosition',\n  'internalQuery',\n  'where',\n  'schema',\n  'routine',\n] as const;\n\n/**\n * Type predicate to check if an error is a Postgres error from the pg library.\n *\n * Distinguishes pg library errors from Node.js system errors by checking for:\n * - SQLSTATE codes (5-character alphanumeric codes like '23505', '42601')\n * - pg-specific properties (constraint, table, column, hint, etc.) that Node.js errors don't have\n *\n * Node.js system errors (ECONNREFUSED, ETIMEDOUT, etc.) are excluded to prevent false positives.\n */\nexport function isPostgresError(error: unknown): error is PostgresError {\n  if (!(error instanceof Error)) {\n    return false;\n  }\n\n  const pgError = error as PostgresError;\n\n  // Check for SQLSTATE code (5-character alphanumeric) - primary indicator of pg errors\n  if (pgError.code && isPostgresSqlState(pgError.code)) {\n    return true;\n  }\n\n  // Check for pg-specific properties that Node.js system errors don't have\n  // These properties indicate the error originated from pg library query execution\n  return PG_ERROR_PROPERTIES.some((prop) => pgError[prop] !== undefined);\n}\n\n/**\n * Checks if an error is an \"already connected\" error from pg.Client.connect().\n * When calling connect() on an already-connected client, pg throws an error that can be safely ignored.\n */\nexport function isAlreadyConnectedError(error: unknown): error is Error {\n  if (!(error instanceof Error)) {\n    return false;\n  }\n  const message = error.message.toLowerCase();\n  return message.includes('already') && message.includes('connected');\n}\n\n/**\n * Checks if an error code is a Postgres SQLSTATE (5-character alphanumeric code).\n * SQLSTATE codes are standardized SQL error codes (e.g., '23505' for unique violation).\n */\nfunction isPostgresSqlState(code: string | undefined): boolean {\n  if (!code) {\n    return false;\n  }\n  // Postgres SQLSTATE codes are 5-character alphanumeric strings\n  // Examples: '23505' (unique violation), '42501' (insufficient privilege), '42601' (syntax error)\n  return /^[A-Z0-9]{5}$/.test(code);\n}\n\n/**\n * Normalizes a Postgres error into a SQL-shared error type.\n *\n * - Postgres SQLSTATE errors (5-char codes like '23505') → SqlQueryError\n * - Connection errors (ECONNRESET, ETIMEDOUT, etc.) → SqlConnectionError\n * - Unknown errors → returns the original error as-is\n *\n * The original error is preserved via Error.cause to maintain stack traces.\n *\n * @param error - The error to normalize (typically from pg library)\n * @returns SqlQueryError for query-related failures\n * @returns SqlConnectionError for connection-related failures\n * @returns The original error if it cannot be normalized\n */\nexport function normalizePgError(error: unknown): SqlQueryError | SqlConnectionError | Error {\n  if (!(error instanceof Error)) {\n    // Wrap non-Error values in an Error object\n    return new Error(String(error));\n  }\n\n  const pgError = error as PostgresError;\n\n  // Check for Postgres SQLSTATE (query errors)\n  if (isPostgresSqlState(pgError.code)) {\n    // isPostgresSqlState ensures code is defined and is a valid SQLSTATE\n    // biome-ignore lint/style/noNonNullAssertion: isPostgresSqlState guarantees code is defined\n    const sqlState = pgError.code!;\n    const options: {\n      cause: Error;\n      sqlState: string;\n      constraint?: string;\n      table?: string;\n      column?: string;\n      detail?: string;\n    } = {\n      cause: error,\n      sqlState,\n    };\n    if (pgError.constraint !== undefined) {\n      options.constraint = pgError.constraint;\n    }\n    if (pgError.table !== undefined) {\n      options.table = pgError.table;\n    }\n    if (pgError.column !== undefined) {\n      options.column = pgError.column;\n    }\n    if (pgError.detail !== undefined) {\n      options.detail = pgError.detail;\n    }\n    return new SqlQueryError(error.message, options);\n  }\n\n  // Check for connection errors\n  if (isConnectionError(error)) {\n    return new SqlConnectionError(error.message, {\n      cause: error,\n      transient: isTransientConnectionError(error),\n    });\n  }\n\n  // Unknown error - return as-is to preserve original error and stack trace\n  return error;\n}\n"],"mappings":";;AAAA,MAAa,+BAA+B;CAC1C,MAAM;CACN,UAAU;CACV,UAAU;CACV,IAAI;CACJ,SAAS;CACT,cAAc,CAAC;AACjB;;;;;;AC0BA,SAAS,kBAAkB,OAAuB;CAChD,MAAM,OAAQ,MAA4B;CAC1C,IAAI;MAGA,SAAS,gBACT,SAAS,eACT,SAAS,kBACT,SAAS,eACT,SAAS,gBAET,OAAO;CAAA;CAKX,MAAM,UAAU,MAAM,QAAQ,YAAY;CAC1C,IACE,QAAQ,SAAS,uBAAuB,KACxC,QAAQ,SAAS,mBAAmB,KACpC,QAAQ,SAAS,oBAAoB,KACrC,QAAQ,SAAS,oBAAoB,KACrC,QAAQ,SAAS,kBAAkB,GAEnC,OAAO;CAGT,OAAO;AACT;;;;AAKA,SAAS,2BAA2B,OAAuB;CACzD,MAAM,OAAQ,MAA4B;CAC1C,IAAI,MAAM;EAER,IAAI,SAAS,eAAe,SAAS,cACnC,OAAO;EAGT,IAAI,SAAS,gBACX,OAAO;CAEX;CAEA,MAAM,UAAU,MAAM,QAAQ,YAAY;CAC1C,IAAI,QAAQ,SAAS,SAAS,KAAK,QAAQ,SAAS,kBAAkB,GACpE,OAAO;CAGT,OAAO;AACT;;;;;;AAOA,MAAM,sBAAsB;CAC1B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;;;;;;;;;;AAWA,SAAgB,gBAAgB,OAAwC;CACtE,IAAI,EAAE,iBAAiB,QACrB,OAAO;CAGT,MAAM,UAAU;CAGhB,IAAI,QAAQ,QAAQ,mBAAmB,QAAQ,IAAI,GACjD,OAAO;CAKT,OAAO,oBAAoB,MAAM,SAAS,QAAQ,UAAU,KAAA,CAAS;AACvE;;;;;AAMA,SAAgB,wBAAwB,OAAgC;CACtE,IAAI,EAAE,iBAAiB,QACrB,OAAO;CAET,MAAM,UAAU,MAAM,QAAQ,YAAY;CAC1C,OAAO,QAAQ,SAAS,SAAS,KAAK,QAAQ,SAAS,WAAW;AACpE;;;;;AAMA,SAAS,mBAAmB,MAAmC;CAC7D,IAAI,CAAC,MACH,OAAO;CAIT,OAAO,gBAAgB,KAAK,IAAI;AAClC;;;;;;;;;;;;;;;AAgBA,SAAgB,iBAAiB,OAA4D;CAC3F,IAAI,EAAE,iBAAiB,QAErB,OAAO,IAAI,MAAM,OAAO,KAAK,CAAC;CAGhC,MAAM,UAAU;CAGhB,IAAI,mBAAmB,QAAQ,IAAI,GAAG;EAIpC,MAAM,UAOF;GACF,OAAO;GACP,UAVe,QAAQ;EAWzB;EACA,IAAI,QAAQ,eAAe,KAAA,GACzB,QAAQ,aAAa,QAAQ;EAE/B,IAAI,QAAQ,UAAU,KAAA,GACpB,QAAQ,QAAQ,QAAQ;EAE1B,IAAI,QAAQ,WAAW,KAAA,GACrB,QAAQ,SAAS,QAAQ;EAE3B,IAAI,QAAQ,WAAW,KAAA,GACrB,QAAQ,SAAS,QAAQ;EAE3B,OAAO,IAAI,cAAc,MAAM,SAAS,OAAO;CACjD;CAGA,IAAI,kBAAkB,KAAK,GACzB,OAAO,IAAI,mBAAmB,MAAM,SAAS;EAC3C,OAAO;EACP,WAAW,2BAA2B,KAAK;CAC7C,CAAC;CAIH,OAAO;AACT"}