callman-core 1.18.0 → 1.20.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.
Files changed (105) hide show
  1. package/dist/host/db/connectionMapping.d.ts +4 -0
  2. package/dist/host/db/connectionMapping.d.ts.map +1 -1
  3. package/dist/host/db/connectionMapping.js +4 -0
  4. package/dist/host/db/connectionMapping.js.map +1 -1
  5. package/dist/host/db/pgClientConfig.d.ts +11 -0
  6. package/dist/host/db/pgClientConfig.d.ts.map +1 -0
  7. package/dist/host/db/pgClientConfig.js +83 -0
  8. package/dist/host/db/pgClientConfig.js.map +1 -0
  9. package/dist/host/db/pgSessionManager.d.ts +18 -0
  10. package/dist/host/db/pgSessionManager.d.ts.map +1 -0
  11. package/dist/host/db/pgSessionManager.js +162 -0
  12. package/dist/host/db/pgSessionManager.js.map +1 -0
  13. package/dist/host/db/postgresAdapter.d.ts.map +1 -1
  14. package/dist/host/db/postgresAdapter.js +7 -36
  15. package/dist/host/db/postgresAdapter.js.map +1 -1
  16. package/dist/host/db/queryExecutor.d.ts +4 -0
  17. package/dist/host/db/queryExecutor.d.ts.map +1 -1
  18. package/dist/host/db/queryExecutor.js +40 -2
  19. package/dist/host/db/queryExecutor.js.map +1 -1
  20. package/dist/host/db/sqlState.d.ts +2 -0
  21. package/dist/host/db/sqlState.d.ts.map +1 -0
  22. package/dist/host/db/sqlState.js +14 -0
  23. package/dist/host/db/sqlState.js.map +1 -0
  24. package/dist/host/db/types.d.ts +13 -0
  25. package/dist/host/db/types.d.ts.map +1 -1
  26. package/dist/host/index.d.ts +3 -0
  27. package/dist/host/index.d.ts.map +1 -1
  28. package/dist/host/index.js +7 -0
  29. package/dist/host/index.js.map +1 -1
  30. package/dist/scenario-runner/adapters/connection-config.d.ts +4 -0
  31. package/dist/scenario-runner/adapters/connection-config.d.ts.map +1 -1
  32. package/dist/scenario-runner/adapters/db-executor.d.ts +7 -1
  33. package/dist/scenario-runner/adapters/db-executor.d.ts.map +1 -1
  34. package/dist/scenario-runner/adapters/db-executor.js +106 -1
  35. package/dist/scenario-runner/adapters/db-executor.js.map +1 -1
  36. package/dist/scenario-runner/adapters/index.d.ts +2 -1
  37. package/dist/scenario-runner/adapters/index.d.ts.map +1 -1
  38. package/dist/scenario-runner/adapters/index.js +11 -1
  39. package/dist/scenario-runner/adapters/index.js.map +1 -1
  40. package/dist/scenario-runner/adapters/types.d.ts +9 -0
  41. package/dist/scenario-runner/adapters/types.d.ts.map +1 -1
  42. package/dist/scenario-runner/adapters/websocket-executor.d.ts +4 -0
  43. package/dist/scenario-runner/adapters/websocket-executor.d.ts.map +1 -0
  44. package/dist/scenario-runner/adapters/websocket-executor.js +20 -0
  45. package/dist/scenario-runner/adapters/websocket-executor.js.map +1 -0
  46. package/dist/scenario-runner/condition.d.ts +1 -0
  47. package/dist/scenario-runner/condition.d.ts.map +1 -1
  48. package/dist/scenario-runner/condition.js +138 -2
  49. package/dist/scenario-runner/condition.js.map +1 -1
  50. package/dist/scenario-runner/conditionTypes.d.ts +1 -1
  51. package/dist/scenario-runner/conditionTypes.d.ts.map +1 -1
  52. package/dist/scenario-runner/graphTraversal.d.ts +8 -0
  53. package/dist/scenario-runner/graphTraversal.d.ts.map +1 -1
  54. package/dist/scenario-runner/graphTraversal.js +9 -0
  55. package/dist/scenario-runner/graphTraversal.js.map +1 -1
  56. package/dist/scenario-runner/index.d.ts +1 -0
  57. package/dist/scenario-runner/index.d.ts.map +1 -1
  58. package/dist/scenario-runner/index.js +1 -0
  59. package/dist/scenario-runner/index.js.map +1 -1
  60. package/dist/scenario-runner/nodePolicy.d.ts +2 -2
  61. package/dist/scenario-runner/nodePolicy.d.ts.map +1 -1
  62. package/dist/scenario-runner/nodePolicy.js +2 -0
  63. package/dist/scenario-runner/nodePolicy.js.map +1 -1
  64. package/dist/scenario-runner/runScenario.d.ts.map +1 -1
  65. package/dist/scenario-runner/runScenario.js +202 -2
  66. package/dist/scenario-runner/runScenario.js.map +1 -1
  67. package/dist/scenario-runner/types.d.ts +142 -3
  68. package/dist/scenario-runner/types.d.ts.map +1 -1
  69. package/dist/scenario-runner/websocket.d.ts +17 -0
  70. package/dist/scenario-runner/websocket.d.ts.map +1 -0
  71. package/dist/scenario-runner/websocket.js +74 -0
  72. package/dist/scenario-runner/websocket.js.map +1 -0
  73. package/dist-cjs/host/db/connectionMapping.js +4 -0
  74. package/dist-cjs/host/db/connectionMapping.js.map +1 -1
  75. package/dist-cjs/host/db/pgClientConfig.js +90 -0
  76. package/dist-cjs/host/db/pgClientConfig.js.map +1 -0
  77. package/dist-cjs/host/db/pgSessionManager.js +170 -0
  78. package/dist-cjs/host/db/pgSessionManager.js.map +1 -0
  79. package/dist-cjs/host/db/postgresAdapter.js +7 -36
  80. package/dist-cjs/host/db/postgresAdapter.js.map +1 -1
  81. package/dist-cjs/host/db/queryExecutor.js +40 -2
  82. package/dist-cjs/host/db/queryExecutor.js.map +1 -1
  83. package/dist-cjs/host/db/sqlState.js +18 -0
  84. package/dist-cjs/host/db/sqlState.js.map +1 -0
  85. package/dist-cjs/host/index.js +16 -1
  86. package/dist-cjs/host/index.js.map +1 -1
  87. package/dist-cjs/scenario-runner/adapters/db-executor.js +108 -2
  88. package/dist-cjs/scenario-runner/adapters/db-executor.js.map +1 -1
  89. package/dist-cjs/scenario-runner/adapters/index.js +14 -1
  90. package/dist-cjs/scenario-runner/adapters/index.js.map +1 -1
  91. package/dist-cjs/scenario-runner/adapters/websocket-executor.js +24 -0
  92. package/dist-cjs/scenario-runner/adapters/websocket-executor.js.map +1 -0
  93. package/dist-cjs/scenario-runner/condition.js +140 -3
  94. package/dist-cjs/scenario-runner/condition.js.map +1 -1
  95. package/dist-cjs/scenario-runner/graphTraversal.js +10 -1
  96. package/dist-cjs/scenario-runner/graphTraversal.js.map +1 -1
  97. package/dist-cjs/scenario-runner/index.js +1 -0
  98. package/dist-cjs/scenario-runner/index.js.map +1 -1
  99. package/dist-cjs/scenario-runner/nodePolicy.js +2 -0
  100. package/dist-cjs/scenario-runner/nodePolicy.js.map +1 -1
  101. package/dist-cjs/scenario-runner/runScenario.js +201 -1
  102. package/dist-cjs/scenario-runner/runScenario.js.map +1 -1
  103. package/dist-cjs/scenario-runner/websocket.js +79 -0
  104. package/dist-cjs/scenario-runner/websocket.js.map +1 -0
  105. package/package.json +1 -1
@@ -12,6 +12,10 @@ export interface DatabaseConnectionConfigLike {
12
12
  ssl?: boolean;
13
13
  instanceName?: string;
14
14
  trustServerCertificate?: boolean;
15
+ sslMode?: "disable" | "require" | "verify-ca" | "verify-full";
16
+ caCert?: string;
17
+ clientCert?: string;
18
+ clientKey?: string;
15
19
  }
16
20
  export declare const databaseConfigToDbConnection: (input: {
17
21
  id?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"connectionMapping.d.ts","sourceRoot":"","sources":["../../../src/host/db/connectionMapping.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,YAAY,CAAC;AAEjE,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,YAAY,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAUrF,MAAM,WAAW,4BAA4B;IAC3C,cAAc,EAAE,UAAU,GAAG,kBAAkB,CAAC;IAChD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,eAAO,MAAM,4BAA4B,GAAI,OAAO;IAClD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,cAAc,CAAC;IACzB,MAAM,EAAE,4BAA4B,CAAC;CACtC,KAAG,YAeF,CAAC"}
1
+ {"version":3,"file":"connectionMapping.d.ts","sourceRoot":"","sources":["../../../src/host/db/connectionMapping.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,YAAY,CAAC;AAEjE,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,YAAY,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAUrF,MAAM,WAAW,4BAA4B;IAC3C,cAAc,EAAE,UAAU,GAAG,kBAAkB,CAAC;IAChD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAIjC,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,aAAa,CAAC;IAC9D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,4BAA4B,GAAI,OAAO;IAClD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,cAAc,CAAC;IACzB,MAAM,EAAE,4BAA4B,CAAC;CACtC,KAAG,YAmBF,CAAC"}
@@ -26,5 +26,9 @@ export const databaseConfigToDbConnection = (input) => ({
26
26
  password: input.config.password ?? "",
27
27
  ssl: input.config.ssl,
28
28
  trustServerCertificate: input.config.trustServerCertificate,
29
+ sslMode: input.config.sslMode,
30
+ caCert: input.config.caCert,
31
+ clientCert: input.config.clientCert,
32
+ clientKey: input.config.clientKey,
29
33
  });
30
34
  //# sourceMappingURL=connectionMapping.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"connectionMapping.js","sourceRoot":"","sources":["../../../src/host/db/connectionMapping.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,wEAAwE;AACxE,yEAAyE;AACzE,8EAA8E;AAC9E,8EAA8E;AAC9E,oBAAoB;AAMpB,MAAM,gBAAgB,GAA6C;IACjE,OAAO,EAAE,OAAO;IAChB,UAAU,EAAE,UAAU;IACtB,KAAK,EAAE,OAAO;IACd,MAAM,EAAE,QAAQ;IAChB,KAAK,EAAE,OAAO;CACf,CAAC;AAgBF,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,KAK5C,EAAgB,EAAE,CAAC,CAAC;IACnB,EAAE,EAAE,KAAK,CAAC,EAAE,IAAI,qBAAqB;IACrC,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,EAAE;IACtB,IAAI,EAAE,gBAAgB,CAAC,KAAK,CAAC,QAAQ,CAAC;IACtC,cAAc,EAAE,KAAK,CAAC,MAAM,CAAC,cAAc;IAC3C,gBAAgB,EAAE,KAAK,CAAC,MAAM,CAAC,gBAAgB;IAC/C,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE;IAC7B,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC;IAC5B,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,QAAQ;IAC/B,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,WAAW;IACrC,YAAY,EAAE,KAAK,CAAC,MAAM,CAAC,YAAY;IACvC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE;IACrC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE;IACrC,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG;IACrB,sBAAsB,EAAE,KAAK,CAAC,MAAM,CAAC,sBAAsB;CAC5D,CAAC,CAAC"}
1
+ {"version":3,"file":"connectionMapping.js","sourceRoot":"","sources":["../../../src/host/db/connectionMapping.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,wEAAwE;AACxE,yEAAyE;AACzE,8EAA8E;AAC9E,8EAA8E;AAC9E,oBAAoB;AAMpB,MAAM,gBAAgB,GAA6C;IACjE,OAAO,EAAE,OAAO;IAChB,UAAU,EAAE,UAAU;IACtB,KAAK,EAAE,OAAO;IACd,MAAM,EAAE,QAAQ;IAChB,KAAK,EAAE,OAAO;CACf,CAAC;AAuBF,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,KAK5C,EAAgB,EAAE,CAAC,CAAC;IACnB,EAAE,EAAE,KAAK,CAAC,EAAE,IAAI,qBAAqB;IACrC,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,EAAE;IACtB,IAAI,EAAE,gBAAgB,CAAC,KAAK,CAAC,QAAQ,CAAC;IACtC,cAAc,EAAE,KAAK,CAAC,MAAM,CAAC,cAAc;IAC3C,gBAAgB,EAAE,KAAK,CAAC,MAAM,CAAC,gBAAgB;IAC/C,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE;IAC7B,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC;IAC5B,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,QAAQ;IAC/B,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,WAAW;IACrC,YAAY,EAAE,KAAK,CAAC,MAAM,CAAC,YAAY;IACvC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE;IACrC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE;IACrC,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG;IACrB,sBAAsB,EAAE,KAAK,CAAC,MAAM,CAAC,sBAAsB;IAC3D,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO;IAC7B,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM;IAC3B,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,UAAU;IACnC,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,SAAS;CAClC,CAAC,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { DbConnection } from "./types.js";
2
+ export declare const buildPgSslConfig: (connection: DbConnection) => Record<string, unknown> | undefined;
3
+ export declare const buildPgClientConfig: (connection: DbConnection) => Record<string, unknown>;
4
+ export declare const normalizePgValue: (value: unknown) => unknown;
5
+ export declare const runPgQuery: (client: {
6
+ query: (text: string, params?: unknown[]) => Promise<unknown>;
7
+ }, query: string, params?: unknown[]) => Promise<{
8
+ rows: unknown[];
9
+ rowCount: number;
10
+ }>;
11
+ //# sourceMappingURL=pgClientConfig.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pgClientConfig.d.ts","sourceRoot":"","sources":["../../../src/host/db/pgClientConfig.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAQ/C,eAAO,MAAM,gBAAgB,GAC3B,YAAY,YAAY,KACvB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAyB5B,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,YAAY,YAAY,KACvB,MAAM,CAAC,MAAM,EAAE,OAAO,CAcxB,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,OAAO,OAAO,KAAG,OAU/C,CAAC;AAOJ,eAAO,MAAM,UAAU,GACrB,QAAQ;IAAE,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CAAE,EACzE,OAAO,MAAM,EACb,SAAQ,OAAO,EAAO,KACrB,OAAO,CAAC;IAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAc/C,CAAC"}
@@ -0,0 +1,83 @@
1
+ // Shared pg client construction + query execution for the one-shot adapter
2
+ // (postgresAdapter) and the run-scoped session manager (pgSessionManager),
3
+ // so TLS handling and result normalization can never drift between them.
4
+ import { stripTrailingSqlTerminator } from "./sqlNormalize.js";
5
+ // TLS material for a Postgres connection. `sslMode` semantics follow
6
+ // libpq: "require" encrypts without verification, "verify-ca" verifies the
7
+ // chain against `caCert` but not the hostname, "verify-full" verifies both.
8
+ // When `sslMode` is absent the legacy boolean `ssl` keeps its historical
9
+ // behavior (encrypt, no verification) so existing connections don't break.
10
+ export const buildPgSslConfig = (connection) => {
11
+ const mode = connection.sslMode;
12
+ if (!mode) {
13
+ return connection.ssl ? { rejectUnauthorized: false } : undefined;
14
+ }
15
+ if (mode === "disable") {
16
+ return undefined;
17
+ }
18
+ const material = {};
19
+ if (connection.caCert?.trim())
20
+ material.ca = connection.caCert;
21
+ if (connection.clientCert?.trim())
22
+ material.cert = connection.clientCert;
23
+ if (connection.clientKey?.trim())
24
+ material.key = connection.clientKey;
25
+ if (mode === "require") {
26
+ return { ...material, rejectUnauthorized: false };
27
+ }
28
+ if (mode === "verify-ca") {
29
+ // Verify the chain but skip hostname verification (libpq verify-ca).
30
+ return {
31
+ ...material,
32
+ rejectUnauthorized: true,
33
+ checkServerIdentity: () => undefined,
34
+ };
35
+ }
36
+ // verify-full: chain + hostname.
37
+ return { ...material, rejectUnauthorized: true };
38
+ };
39
+ export const buildPgClientConfig = (connection) => {
40
+ const ssl = buildPgSslConfig(connection);
41
+ if (connection.connectionString?.trim()) {
42
+ return { connectionString: connection.connectionString.trim(), ssl, connectionTimeoutMillis: 8000 };
43
+ }
44
+ return {
45
+ host: connection.host,
46
+ port: connection.port,
47
+ database: connection.database,
48
+ user: connection.username,
49
+ password: connection.password,
50
+ ssl,
51
+ connectionTimeoutMillis: 8000,
52
+ };
53
+ };
54
+ export const normalizePgValue = (value) => JSON.parse(JSON.stringify(value, (_key, entry) => {
55
+ if (typeof entry === "bigint")
56
+ return entry.toString();
57
+ if (entry instanceof Date)
58
+ return entry.toISOString();
59
+ if (Buffer.isBuffer(entry) || entry instanceof Uint8Array) {
60
+ return Buffer.from(entry).toString("hex");
61
+ }
62
+ return entry;
63
+ }));
64
+ // Run one query on an already-connected client. Params are OMITTED when
65
+ // empty so node-pg keeps the simple protocol — that is what allows
66
+ // multi-statement setup/teardown scripts (`INSERT …; INSERT …;`) and
67
+ // `DO $$ … $$` blocks in a db node with no bind params. A multi-statement
68
+ // script returns the LAST statement's rows (matches psql's display).
69
+ export const runPgQuery = async (client, query, params = []) => {
70
+ const finalQuery = stripTrailingSqlTerminator(query, "postgres");
71
+ const result = params.length > 0
72
+ ? await client.query(finalQuery, params)
73
+ : await client.query(finalQuery);
74
+ const last = Array.isArray(result) ? result[result.length - 1] : result;
75
+ const rawRows = last?.rows;
76
+ const rows = Array.isArray(rawRows) ? rawRows.map(normalizePgValue) : [];
77
+ const rowCount = last?.rowCount;
78
+ return {
79
+ rows,
80
+ rowCount: typeof rowCount === "number" ? rowCount : rows.length,
81
+ };
82
+ };
83
+ //# sourceMappingURL=pgClientConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pgClientConfig.js","sourceRoot":"","sources":["../../../src/host/db/pgClientConfig.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,2EAA2E;AAC3E,yEAAyE;AAGzE,OAAO,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AAE/D,qEAAqE;AACrE,2EAA2E;AAC3E,4EAA4E;AAC5E,yEAAyE;AACzE,2EAA2E;AAC3E,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,UAAwB,EACa,EAAE;IACvC,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC;IAChC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IACpE,CAAC;IACD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,QAAQ,GAA4B,EAAE,CAAC;IAC7C,IAAI,UAAU,CAAC,MAAM,EAAE,IAAI,EAAE;QAAE,QAAQ,CAAC,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC;IAC/D,IAAI,UAAU,CAAC,UAAU,EAAE,IAAI,EAAE;QAAE,QAAQ,CAAC,IAAI,GAAG,UAAU,CAAC,UAAU,CAAC;IACzE,IAAI,UAAU,CAAC,SAAS,EAAE,IAAI,EAAE;QAAE,QAAQ,CAAC,GAAG,GAAG,UAAU,CAAC,SAAS,CAAC;IACtE,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,EAAE,GAAG,QAAQ,EAAE,kBAAkB,EAAE,KAAK,EAAE,CAAC;IACpD,CAAC;IACD,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;QACzB,qEAAqE;QACrE,OAAO;YACL,GAAG,QAAQ;YACX,kBAAkB,EAAE,IAAI;YACxB,mBAAmB,EAAE,GAAG,EAAE,CAAC,SAAS;SACrC,CAAC;IACJ,CAAC;IACD,iCAAiC;IACjC,OAAO,EAAE,GAAG,QAAQ,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC;AACnD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,UAAwB,EACC,EAAE;IAC3B,MAAM,GAAG,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC;IACzC,IAAI,UAAU,CAAC,gBAAgB,EAAE,IAAI,EAAE,EAAE,CAAC;QACxC,OAAO,EAAE,gBAAgB,EAAE,UAAU,CAAC,gBAAgB,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,uBAAuB,EAAE,IAAI,EAAE,CAAC;IACtG,CAAC;IACD,OAAO;QACL,IAAI,EAAE,UAAU,CAAC,IAAI;QACrB,IAAI,EAAE,UAAU,CAAC,IAAI;QACrB,QAAQ,EAAE,UAAU,CAAC,QAAQ;QAC7B,IAAI,EAAE,UAAU,CAAC,QAAQ;QACzB,QAAQ,EAAE,UAAU,CAAC,QAAQ;QAC7B,GAAG;QACH,uBAAuB,EAAE,IAAI;KAC9B,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,KAAc,EAAW,EAAE,CAC1D,IAAI,CAAC,KAAK,CACR,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;IACpC,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;IACvD,IAAI,KAAK,YAAY,IAAI;QAAE,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC;IACtD,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,YAAY,UAAU,EAAE,CAAC;QAC1D,OAAO,MAAM,CAAC,IAAI,CAAC,KAAmB,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC,CAAC,CACH,CAAC;AAEJ,wEAAwE;AACxE,mEAAmE;AACnE,qEAAqE;AACrE,0EAA0E;AAC1E,qEAAqE;AACrE,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,EAC7B,MAAyE,EACzE,KAAa,EACb,SAAoB,EAAE,EAC0B,EAAE;IAClD,MAAM,UAAU,GAAG,0BAA0B,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IACjE,MAAM,MAAM,GACV,MAAM,CAAC,MAAM,GAAG,CAAC;QACf,CAAC,CAAC,MAAM,MAAM,CAAC,KAAK,CAAC,UAAU,EAAE,MAAM,CAAC;QACxC,CAAC,CAAC,MAAM,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACrC,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IACxE,MAAM,OAAO,GAAI,IAA2B,EAAE,IAAI,CAAC;IACnD,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACzE,MAAM,QAAQ,GAAI,IAA+B,EAAE,QAAQ,CAAC;IAC5D,OAAO;QACL,IAAI;QACJ,QAAQ,EAAE,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM;KAChE,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { DbConnection } from "./types.js";
2
+ export type PgSessionTransactionMode = "none" | "rollback" | "commit";
3
+ export declare const __setPgSessionDriverForTests: (driver: any | null) => void;
4
+ export interface PgSessionExecuteInput {
5
+ connection: DbConnection;
6
+ runId: string;
7
+ transactionMode: PgSessionTransactionMode;
8
+ query: string;
9
+ params?: unknown[];
10
+ }
11
+ export declare const executePostgresQueryInSession: (input: PgSessionExecuteInput) => Promise<{
12
+ rows: unknown[];
13
+ rowCount: number;
14
+ }>;
15
+ export declare const releasePostgresSessionsForRun: (runId: string, outcome: "commit" | "rollback") => Promise<void>;
16
+ export declare const closeAllPostgresSessions: () => Promise<void>;
17
+ export declare const __getPgSessionCountForTests: () => number;
18
+ //# sourceMappingURL=pgSessionManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pgSessionManager.d.ts","sourceRoot":"","sources":["../../../src/host/db/pgSessionManager.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG/C,MAAM,MAAM,wBAAwB,GAAG,MAAM,GAAG,UAAU,GAAG,QAAQ,CAAC;AA0BtE,eAAO,MAAM,4BAA4B,GAAI,QAAQ,GAAG,GAAG,IAAI,KAAG,IAEjE,CAAC;AA4FF,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,YAAY,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,wBAAwB,CAAC;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;CACpB;AAED,eAAO,MAAM,6BAA6B,GACxC,OAAO,qBAAqB,KAC3B,OAAO,CAAC;IAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CA+B/C,CAAC;AAKF,eAAO,MAAM,6BAA6B,GACxC,OAAO,MAAM,EACb,SAAS,QAAQ,GAAG,UAAU,KAC7B,OAAO,CAAC,IAAI,CAYd,CAAC;AAGF,eAAO,MAAM,wBAAwB,QAAa,OAAO,CAAC,IAAI,CAQ7D,CAAC;AAGF,eAAO,MAAM,2BAA2B,QAAO,MAAuB,CAAC"}
@@ -0,0 +1,162 @@
1
+ // Run-scoped PostgreSQL sessions for scenario db nodes (`useSession`).
2
+ //
3
+ // One live `pg` Client per (runId, connection identity). All session-joined
4
+ // nodes of a run share that client, so `BEGIN`, temp tables, GUCs and
5
+ // advisory locks survive between nodes — the foundation of the
6
+ // seed → call function → assert → ROLLBACK stored-function testing pattern.
7
+ //
8
+ // Modeled on callman-backend's kafka-client-pool: lazy open, per-session
9
+ // serialization, idle sweeper, explicit shutdown hook. Postgres-only by
10
+ // design — other providers reject `useSession` at the host driver.
11
+ import { loadOptionalModule } from "../lazy.js";
12
+ import { buildPgClientConfig, runPgQuery } from "./pgClientConfig.js";
13
+ const IDLE_SWEEP_INTERVAL_MS = 60_000;
14
+ const IDLE_SESSION_TTL_MS = 5 * 60_000;
15
+ const sessions = new Map();
16
+ let sweeper = null;
17
+ const unwrap = (mod) => (mod && mod.default && !mod.Client ? mod.default : mod);
18
+ // Test seam mirroring postgresAdapter's — lets unit tests inject a fake
19
+ // driver without a live server.
20
+ let pgDriverOverride = null;
21
+ export const __setPgSessionDriverForTests = (driver) => {
22
+ pgDriverOverride = driver;
23
+ };
24
+ const loadPgDriver = async () => {
25
+ if (pgDriverOverride)
26
+ return pgDriverOverride;
27
+ try {
28
+ return unwrap(await loadOptionalModule("pg"));
29
+ }
30
+ catch {
31
+ throw new Error("PostgreSQL driver (`pg`) is not installed. Install `pg` to use PostgreSQL sessions.");
32
+ }
33
+ };
34
+ // Connection identity participates in the key so two different connections
35
+ // in one run never share a client, even if their `id`s degenerate to the
36
+ // same normalized placeholder.
37
+ const sessionKey = (runId, connection) => [
38
+ runId,
39
+ connection.id,
40
+ connection.connectionString ?? "",
41
+ connection.host,
42
+ String(connection.port),
43
+ connection.database ?? "",
44
+ connection.username,
45
+ ].join("::");
46
+ const ensureSweeper = () => {
47
+ if (sweeper)
48
+ return;
49
+ sweeper = setInterval(() => {
50
+ const now = Date.now();
51
+ for (const [key, entry] of sessions) {
52
+ if (now - entry.lastUsedAtMs > IDLE_SESSION_TTL_MS) {
53
+ sessions.delete(key);
54
+ void destroyEntry(entry, "rollback");
55
+ }
56
+ }
57
+ if (sessions.size === 0 && sweeper) {
58
+ clearInterval(sweeper);
59
+ sweeper = null;
60
+ }
61
+ }, IDLE_SWEEP_INTERVAL_MS);
62
+ // Never keep the host process alive just for the sweeper.
63
+ sweeper.unref?.();
64
+ };
65
+ const destroyEntry = async (entry, outcome) => {
66
+ try {
67
+ const client = await entry.clientPromise;
68
+ if (entry.transactionOpen && !entry.poisoned) {
69
+ try {
70
+ await client.query(outcome === "commit" ? "COMMIT" : "ROLLBACK");
71
+ }
72
+ catch {
73
+ // The transaction dies with the connection either way.
74
+ }
75
+ }
76
+ try {
77
+ await client.end();
78
+ }
79
+ catch {
80
+ // Best-effort teardown.
81
+ }
82
+ }
83
+ catch {
84
+ // Client never connected — nothing to tear down.
85
+ }
86
+ };
87
+ const openEntry = (runId, connection) => {
88
+ const entry = {
89
+ clientPromise: (async () => {
90
+ const { Client } = await loadPgDriver();
91
+ const client = new Client(buildPgClientConfig(connection));
92
+ await client.connect();
93
+ // Socket-level errors surface here (killed backend, network drop);
94
+ // mark the session so the next query fails fast with the cause.
95
+ client.on?.("error", (error) => {
96
+ entry.poisoned =
97
+ error instanceof Error ? error.message : "PostgreSQL session connection lost";
98
+ });
99
+ return client;
100
+ })(),
101
+ chain: Promise.resolve(),
102
+ transactionOpen: false,
103
+ poisoned: null,
104
+ lastUsedAtMs: Date.now(),
105
+ runId,
106
+ };
107
+ return entry;
108
+ };
109
+ export const executePostgresQueryInSession = async (input) => {
110
+ const key = sessionKey(input.runId, input.connection);
111
+ let entry = sessions.get(key);
112
+ if (!entry) {
113
+ entry = openEntry(input.runId, input.connection);
114
+ sessions.set(key, entry);
115
+ ensureSweeper();
116
+ }
117
+ const run = entry.chain.then(async () => {
118
+ if (entry.poisoned) {
119
+ throw new Error(`PostgreSQL session is unusable: ${entry.poisoned}`);
120
+ }
121
+ const client = await entry.clientPromise;
122
+ if (input.transactionMode !== "none" && !entry.transactionOpen) {
123
+ await client.query("BEGIN");
124
+ entry.transactionOpen = true;
125
+ }
126
+ return runPgQuery(client, input.query, input.params ?? []);
127
+ });
128
+ // The chain must survive a failed query (SQL errors are normal in
129
+ // expectError flows) — swallow for chaining purposes only.
130
+ entry.chain = run.then(() => undefined, () => undefined).then(() => {
131
+ entry.lastUsedAtMs = Date.now();
132
+ });
133
+ return run;
134
+ };
135
+ // Close every session belonging to `runId` — COMMIT/ROLLBACK per the run
136
+ // outcome, then end the client. Queued statements finish (or fail) first
137
+ // thanks to the serialization chain.
138
+ export const releasePostgresSessionsForRun = async (runId, outcome) => {
139
+ const owned = [];
140
+ for (const [key, entry] of sessions) {
141
+ if (entry.runId === runId)
142
+ owned.push([key, entry]);
143
+ }
144
+ await Promise.all(owned.map(async ([key, entry]) => {
145
+ sessions.delete(key);
146
+ await entry.chain;
147
+ await destroyEntry(entry, outcome);
148
+ }));
149
+ };
150
+ // Shutdown hook for hosts (backend process exit, CLI end, electron quit).
151
+ export const closeAllPostgresSessions = async () => {
152
+ const all = Array.from(sessions.values());
153
+ sessions.clear();
154
+ if (sweeper) {
155
+ clearInterval(sweeper);
156
+ sweeper = null;
157
+ }
158
+ await Promise.all(all.map((entry) => destroyEntry(entry, "rollback")));
159
+ };
160
+ // Introspection for tests.
161
+ export const __getPgSessionCountForTests = () => sessions.size;
162
+ //# sourceMappingURL=pgSessionManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pgSessionManager.js","sourceRoot":"","sources":["../../../src/host/db/pgSessionManager.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"postgresAdapter.d.ts","sourceRoot":"","sources":["../../../src/host/db/postgresAdapter.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAO/C,eAAO,MAAM,2BAA2B,GAAI,QAAQ,GAAG,GAAG,IAAI,KAAG,IAEhE,CAAC;AA2CF,eAAO,MAAM,sBAAsB,GAAU,YAAY,YAAY,KAAG,OAAO,CAAC,IAAI,CASnF,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,YAAY,YAAY,EACxB,OAAO,MAAM,EACb,SAAQ,OAAO,EAAO,KACrB,OAAO,CAAC;IAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAe/C,CAAC"}
1
+ {"version":3,"file":"postgresAdapter.d.ts","sourceRoot":"","sources":["../../../src/host/db/postgresAdapter.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAO/C,eAAO,MAAM,2BAA2B,GAAI,QAAQ,GAAG,GAAG,IAAI,KAAG,IAEhE,CAAC;AAeF,eAAO,MAAM,sBAAsB,GAAU,YAAY,YAAY,KAAG,OAAO,CAAC,IAAI,CASnF,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,YAAY,YAAY,EACxB,OAAO,MAAM,EACb,SAAQ,OAAO,EAAO,KACrB,OAAO,CAAC;IAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAS/C,CAAC"}
@@ -1,7 +1,9 @@
1
1
  // PostgreSQL adapter. Ported from `pmanfrontend/electron/db/postgresAdapter.ts`
2
- // with lazy `pg` loading via `loadOptionalModule`.
2
+ // with lazy `pg` loading via `loadOptionalModule`. Client config (incl. TLS
3
+ // modes) and query execution are shared with the session manager through
4
+ // pgClientConfig.ts.
3
5
  import { loadOptionalModule } from "../lazy.js";
4
- import { stripTrailingSqlTerminator } from "./sqlNormalize.js";
6
+ import { buildPgClientConfig, runPgQuery } from "./pgClientConfig.js";
5
7
  const unwrap = (mod) => (mod && mod.default && !mod.Client ? mod.default : mod);
6
8
  // Test-only seam (see mongoAdapter).
7
9
  let pgDriverOverride = null;
@@ -19,34 +21,9 @@ const loadPgDriver = async () => {
19
21
  throw new Error("PostgreSQL driver (`pg`) is not installed. Install `pg` to use PostgreSQL connections.");
20
22
  }
21
23
  };
22
- const buildClientConfig = (connection) => {
23
- const ssl = connection.ssl ? { rejectUnauthorized: false } : undefined;
24
- if (connection.connectionString?.trim()) {
25
- return { connectionString: connection.connectionString.trim(), ssl, connectionTimeoutMillis: 8000 };
26
- }
27
- return {
28
- host: connection.host,
29
- port: connection.port,
30
- database: connection.database,
31
- user: connection.username,
32
- password: connection.password,
33
- ssl,
34
- connectionTimeoutMillis: 8000,
35
- };
36
- };
37
- const normalizePgValue = (value) => JSON.parse(JSON.stringify(value, (_key, entry) => {
38
- if (typeof entry === "bigint")
39
- return entry.toString();
40
- if (entry instanceof Date)
41
- return entry.toISOString();
42
- if (Buffer.isBuffer(entry) || entry instanceof Uint8Array) {
43
- return Buffer.from(entry).toString("hex");
44
- }
45
- return entry;
46
- }));
47
24
  export const testPostgresConnection = async (connection) => {
48
25
  const { Client } = await loadPgDriver();
49
- const client = new Client(buildClientConfig(connection));
26
+ const client = new Client(buildPgClientConfig(connection));
50
27
  await client.connect();
51
28
  try {
52
29
  await client.query("SELECT 1");
@@ -57,16 +34,10 @@ export const testPostgresConnection = async (connection) => {
57
34
  };
58
35
  export const executePostgresQuery = async (connection, query, params = []) => {
59
36
  const { Client } = await loadPgDriver();
60
- const client = new Client(buildClientConfig(connection));
37
+ const client = new Client(buildPgClientConfig(connection));
61
38
  await client.connect();
62
39
  try {
63
- const finalQuery = stripTrailingSqlTerminator(query, "postgres");
64
- const result = await client.query(finalQuery, params);
65
- const rows = Array.isArray(result.rows) ? result.rows.map(normalizePgValue) : [];
66
- return {
67
- rows,
68
- rowCount: typeof result.rowCount === "number" ? result.rowCount : rows.length,
69
- };
40
+ return await runPgQuery(client, query, params);
70
41
  }
71
42
  finally {
72
43
  await client.end();
@@ -1 +1 @@
1
- {"version":3,"file":"postgresAdapter.js","sourceRoot":"","sources":["../../../src/host/db/postgresAdapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"postgresAdapter.js","sourceRoot":"","sources":["../../../src/host/db/postgresAdapter.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,4EAA4E;AAC5E,yEAAyE;AACzE,qBAAqB;AAErB,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEhD,OAAO,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtE,MAAM,MAAM,GAAG,CAAC,GAAQ,EAAO,EAAE,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;AAE1F,qCAAqC;AACrC,IAAI,gBAAgB,GAAQ,IAAI,CAAC;AACjC,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,MAAkB,EAAQ,EAAE;IACtE,gBAAgB,GAAG,MAAM,CAAC;AAC5B,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,KAAK,IAAkB,EAAE;IAC5C,IAAI,gBAAgB,EAAE,CAAC;QACrB,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IACD,IAAI,CAAC;QACH,OAAO,MAAM,CAAC,MAAM,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACb,wFAAwF,CACzF,CAAC;IACJ,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,EAAE,UAAwB,EAAiB,EAAE;IACtF,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,YAAY,EAAE,CAAC;IACxC,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC,CAAC;IAC3D,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;IACvB,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACjC,CAAC;YAAS,CAAC;QACT,MAAM,MAAM,CAAC,GAAG,EAAE,CAAC;IACrB,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,EACvC,UAAwB,EACxB,KAAa,EACb,SAAoB,EAAE,EAC0B,EAAE;IAClD,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,YAAY,EAAE,CAAC;IACxC,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC,CAAC;IAC3D,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;IACvB,IAAI,CAAC;QACH,OAAO,MAAM,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACjD,CAAC;YAAS,CAAC;QACT,MAAM,MAAM,CAAC,GAAG,EAAE,CAAC;IACrB,CAAC;AACH,CAAC,CAAC"}
@@ -3,6 +3,10 @@ export declare const executeResolvedDbQuery: (input: {
3
3
  connection: DbConnectionInput;
4
4
  resolvedQuery: string;
5
5
  params?: unknown[];
6
+ session?: {
7
+ runId: string;
8
+ transactionMode: "none" | "rollback" | "commit";
9
+ };
6
10
  }) => Promise<{
7
11
  rows: unknown[];
8
12
  rowCount: number;
@@ -1 +1 @@
1
- {"version":3,"file":"queryExecutor.d.ts","sourceRoot":"","sources":["../../../src/host/db/queryExecutor.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAEV,iBAAiB,EACjB,sBAAsB,EACtB,sBAAsB,EACtB,qBAAqB,EACtB,MAAM,YAAY,CAAC;AAyBpB,eAAO,MAAM,sBAAsB,GAAI,OAAO;IAC5C,UAAU,EAAE,iBAAiB,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;CACpB,KAAG,OAAO,CAAC;IAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAK9C,CAAC;AAyBJ,eAAO,MAAM,gBAAgB,GAC3B,iBAAiB,iBAAiB,KACjC,OAAO,CAAC,sBAAsB,CA4BhC,CAAC;AAEF,eAAO,MAAM,YAAY,GACvB,SAAS,qBAAqB,KAC7B,OAAO,CAAC,sBAAsB,CA2DhC,CAAC"}
1
+ {"version":3,"file":"queryExecutor.d.ts","sourceRoot":"","sources":["../../../src/host/db/queryExecutor.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAEV,iBAAiB,EACjB,sBAAsB,EACtB,sBAAsB,EACtB,qBAAqB,EACtB,MAAM,YAAY,CAAC;AA8BpB,eAAO,MAAM,sBAAsB,GAAI,OAAO;IAC5C,UAAU,EAAE,iBAAiB,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,GAAG,UAAU,GAAG,QAAQ,CAAA;KAAE,CAAC;CAC9E,KAAG,OAAO,CAAC;IAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAmBhD,CAAC;AA6BF,eAAO,MAAM,gBAAgB,GAC3B,iBAAiB,iBAAiB,KACjC,OAAO,CAAC,sBAAsB,CA4BhC,CAAC;AAEF,eAAO,MAAM,YAAY,GACvB,SAAS,qBAAqB,KAC7B,OAAO,CAAC,sBAAsB,CAyEhC,CAAC"}
@@ -7,6 +7,8 @@ import { executeMongoQuery, testMongoConnection } from "./mongoAdapter.js";
7
7
  import { executeMysqlQuery, testMysqlConnection } from "./mysqlAdapter.js";
8
8
  import { executeOracleQuery, testOracleConnection } from "./oracleAdapter.js";
9
9
  import { executePostgresQuery, testPostgresConnection } from "./postgresAdapter.js";
10
+ import { executePostgresQueryInSession } from "./pgSessionManager.js";
11
+ import { extractSqlState } from "./sqlState.js";
10
12
  import { resolveTemplate } from "./templateResolver.js";
11
13
  import { executeMssqlQuery, testMssqlConnection } from "./mssqlAdapter.js";
12
14
  const executeAgainstConnection = async (connection, resolvedQuery, params = []) => {
@@ -27,7 +29,27 @@ const executeAgainstConnection = async (connection, resolvedQuery, params = [])
27
29
  // right driver, WITHOUT re-resolving templates. This is the canonical entry for
28
30
  // the scenario / `databaseExecutor` path (core's scenario runner resolves the
29
31
  // template before calling the host), so hosts must not duplicate adapter logic.
30
- export const executeResolvedDbQuery = (input) => executeAgainstConnection(normalizeConnectionInput(input.connection), input.resolvedQuery, input.params ?? []);
32
+ //
33
+ // `session` (additive) routes the query through the run-scoped Postgres
34
+ // session instead of a one-shot client — see pgSessionManager. Only Postgres
35
+ // supports sessions; other providers fail with an actionable message so a
36
+ // `useSession` node never silently runs autocommit.
37
+ export const executeResolvedDbQuery = (input) => {
38
+ const connection = normalizeConnectionInput(input.connection);
39
+ if (input.session) {
40
+ if (connection.type !== "postgres") {
41
+ return Promise.reject(new Error(`Scenario DB sessions are only supported for PostgreSQL connections (got "${connection.type}"). Disable 'Run in scenario transaction' on this node.`));
42
+ }
43
+ return executePostgresQueryInSession({
44
+ connection,
45
+ runId: input.session.runId,
46
+ transactionMode: input.session.transactionMode,
47
+ query: input.resolvedQuery,
48
+ params: input.params ?? [],
49
+ });
50
+ }
51
+ return executeAgainstConnection(connection, input.resolvedQuery, input.params ?? []);
52
+ };
31
53
  const normalizeConnectionInput = (connectionInput) => ({
32
54
  id: connectionInput.id?.trim() || "runtime-connection",
33
55
  name: connectionInput.name.trim(),
@@ -46,6 +68,10 @@ const normalizeConnectionInput = (connectionInput) => ({
46
68
  password: connectionInput.password,
47
69
  ssl: connectionInput.ssl,
48
70
  trustServerCertificate: connectionInput.trustServerCertificate,
71
+ sslMode: connectionInput.sslMode,
72
+ caCert: connectionInput.caCert,
73
+ clientCert: connectionInput.clientCert,
74
+ clientKey: connectionInput.clientKey,
49
75
  });
50
76
  // Connectivity check for a draft/saved connection. Ported from the desktop
51
77
  // host so consumers (Electron `db:test-connection`) don't reimplement it.
@@ -104,7 +130,18 @@ export const executeQuery = async (payload) => {
104
130
  }
105
131
  try {
106
132
  const resolvedQuery = resolveTemplate(payload.query, payload.context ?? {});
107
- const result = await executeAgainstConnection(connection, resolvedQuery, payload.params ?? []);
133
+ if (payload.session && connection.type !== "postgres") {
134
+ throw new Error(`Scenario DB sessions are only supported for PostgreSQL connections (got "${connection.type}"). Disable 'Run in scenario transaction' on this node.`);
135
+ }
136
+ const result = payload.session
137
+ ? await executePostgresQueryInSession({
138
+ connection,
139
+ runId: payload.session.runId,
140
+ transactionMode: payload.session.transactionMode,
141
+ query: resolvedQuery,
142
+ params: payload.params ?? [],
143
+ })
144
+ : await executeAgainstConnection(connection, resolvedQuery, payload.params ?? []);
108
145
  return {
109
146
  success: true,
110
147
  phase: payload.phase,
@@ -135,6 +172,7 @@ export const executeQuery = async (payload) => {
135
172
  durationMs: Math.round(performance.now() - startedAt),
136
173
  executedAt: new Date().toISOString(),
137
174
  error: error instanceof Error ? error.message : String(error),
175
+ ...(extractSqlState(error) ? { sqlState: extractSqlState(error) } : {}),
138
176
  };
139
177
  }
140
178
  };
@@ -1 +1 @@
1
- {"version":3,"file":"queryExecutor.js","sourceRoot":"","sources":["../../../src/host/db/queryExecutor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"queryExecutor.js","sourceRoot":"","sources":["../../../src/host/db/queryExecutor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const extractSqlState: (error: unknown) => string | undefined;
2
+ //# sourceMappingURL=sqlState.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlState.d.ts","sourceRoot":"","sources":["../../../src/host/db/sqlState.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,eAAe,GAAI,OAAO,OAAO,KAAG,MAAM,GAAG,SAOzD,CAAC"}
@@ -0,0 +1,14 @@
1
+ // SQLSTATE extraction shared by the scenario db-executor, the host query
2
+ // executor, and desktop adapters. Postgres SQLSTATE is 5 alphanumeric chars;
3
+ // `pg` errors expose it as `.code`. `.sqlState` is checked first so hosts
4
+ // can attach it explicitly without colliding with Node's `error.code`
5
+ // values (e.g. ECONNREFUSED).
6
+ export const extractSqlState = (error) => {
7
+ if (!error || typeof error !== "object")
8
+ return undefined;
9
+ const candidate = error.sqlState ?? error.code;
10
+ return typeof candidate === "string" && /^[0-9A-Z]{5}$/.test(candidate)
11
+ ? candidate
12
+ : undefined;
13
+ };
14
+ //# sourceMappingURL=sqlState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlState.js","sourceRoot":"","sources":["../../../src/host/db/sqlState.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,6EAA6E;AAC7E,0EAA0E;AAC1E,sEAAsE;AACtE,8BAA8B;AAC9B,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,KAAc,EAAsB,EAAE;IACpE,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAC1D,MAAM,SAAS,GACZ,KAAgC,CAAC,QAAQ,IAAK,KAA4B,CAAC,IAAI,CAAC;IACnF,OAAO,OAAO,SAAS,KAAK,QAAQ,IAAI,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC;QACrE,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC,CAAC"}
@@ -16,6 +16,10 @@ export interface DbConnection {
16
16
  password: string;
17
17
  ssl?: boolean;
18
18
  trustServerCertificate?: boolean;
19
+ sslMode?: "disable" | "require" | "verify-ca" | "verify-full";
20
+ caCert?: string;
21
+ clientCert?: string;
22
+ clientKey?: string;
19
23
  }
20
24
  export interface DbConnectionInput {
21
25
  id?: string;
@@ -32,6 +36,10 @@ export interface DbConnectionInput {
32
36
  password: string;
33
37
  ssl?: boolean;
34
38
  trustServerCertificate?: boolean;
39
+ sslMode?: "disable" | "require" | "verify-ca" | "verify-full";
40
+ caCert?: string;
41
+ clientCert?: string;
42
+ clientKey?: string;
35
43
  }
36
44
  export interface DbTemplateContext {
37
45
  response?: unknown | null;
@@ -45,6 +53,10 @@ export interface ExecuteDbQueryPayload {
45
53
  params?: unknown[];
46
54
  phase: DbQueryPhase;
47
55
  context?: DbTemplateContext;
56
+ session?: {
57
+ runId: string;
58
+ transactionMode: "none" | "rollback" | "commit";
59
+ };
48
60
  }
49
61
  export interface DbQueryExecutionResult {
50
62
  success: boolean;
@@ -59,6 +71,7 @@ export interface DbQueryExecutionResult {
59
71
  durationMs: number;
60
72
  executedAt: string;
61
73
  error?: string;
74
+ sqlState?: string;
62
75
  }
63
76
  export interface DbConnectionTestResult {
64
77
  success: boolean;