@compforge/harness-toolbox 0.3.6 → 0.3.9

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.
@@ -9,6 +9,9 @@ import {
9
9
  queryMysqlViaPod,
10
10
  queryMysqlViaPodBatch
11
11
  } from "./chunk-m91t44jh.js";
12
+ import {
13
+ ToolboxError
14
+ } from "./chunk-zhkrydeg.js";
12
15
  import {
13
16
  ConcurrencyPool
14
17
  } from "./chunk-v3hxvnrc.js";
@@ -18,6 +21,16 @@ import {
18
21
 
19
22
  // src/mysql/client.ts
20
23
  import { createConnection } from "mysql2/promise";
24
+ function mysqlOperationError(error, phase) {
25
+ if (!error || typeof error !== "object" || !("code" in error) || error.code !== "PROTOCOL_CONNECTION_LOST")
26
+ return error;
27
+ return new ToolboxError(`MySQL ${phase} failed: connection lost (PROTOCOL_CONNECTION_LOST)`, {
28
+ kind: "connection_lost",
29
+ code: error.code,
30
+ cause: error
31
+ });
32
+ }
33
+
21
34
  class MysqlDatabase {
22
35
  transports;
23
36
  options;
@@ -56,6 +69,8 @@ class MysqlDatabase {
56
69
  throw new Error("Bounded readonly MySQL queries require a native TCP transport");
57
70
  try {
58
71
  return await queryReadonlySession(session.connection, sql, values, limits, this.options.signal);
72
+ } catch (error) {
73
+ throw mysqlOperationError(error, "query");
59
74
  } finally {
60
75
  destroyMysqlConnection(session.connection);
61
76
  }
@@ -94,7 +109,7 @@ class MysqlDatabase {
94
109
  this.#connections.delete(key);
95
110
  if (session?.kind === "tcp")
96
111
  destroyMysqlConnection(session.connection);
97
- throw error;
112
+ throw session ? mysqlOperationError(error, "query") : error;
98
113
  }
99
114
  }
100
115
  async#query(target, sql, values) {
@@ -130,9 +145,11 @@ class MysqlDatabase {
130
145
  this.options.onRoute?.({ transport: endpoint.host === target.host && endpoint.port === target.port ? "direct" : transport.name, reason });
131
146
  return { kind: "tcp", connection };
132
147
  } catch (error) {
133
- if (!isConnectionNetworkError(error) || i === this.transports.length - 1)
134
- throw error;
135
- reason = String(error.code);
148
+ const failure = mysqlOperationError(error, "connect");
149
+ const connectionLost = failure instanceof ToolboxError && failure.kind === "connection_lost";
150
+ if (!isConnectionNetworkError(failure) && !connectionLost || i === this.transports.length - 1)
151
+ throw failure;
152
+ reason = String(failure.code);
136
153
  }
137
154
  }
138
155
  throw new Error("MySQL DataSource has no transport");
@@ -2,7 +2,7 @@ import {
2
2
  KubernetesError,
3
3
  ToolboxError,
4
4
  kubernetesHttpError
5
- } from "./chunk-ntfm5e85.js";
5
+ } from "./chunk-zhkrydeg.js";
6
6
  import {
7
7
  ConcurrencyPool
8
8
  } from "./chunk-v3hxvnrc.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  KubernetesError
3
- } from "./chunk-ntfm5e85.js";
3
+ } from "./chunk-zhkrydeg.js";
4
4
 
5
5
  // src/kubernetes/workload.ts
6
6
  function failure(message, kind) {
@@ -3,13 +3,13 @@ import {
3
3
  } from "./chunk-2171tajs.js";
4
4
  import {
5
5
  resourceAccess
6
- } from "./chunk-2m0mh09h.js";
6
+ } from "./chunk-fhtbvj0s.js";
7
7
  import {
8
8
  resolveWorkload
9
- } from "./chunk-y3dx8jh6.js";
9
+ } from "./chunk-p6k59m3q.js";
10
10
  import {
11
11
  KubernetesError
12
- } from "./chunk-ntfm5e85.js";
12
+ } from "./chunk-zhkrydeg.js";
13
13
  import {
14
14
  KubectlExecutor
15
15
  } from "./chunk-hmah9t8e.js";
@@ -0,0 +1,41 @@
1
+ // src/errors.ts
2
+ class ToolboxError extends Error {
3
+ kind;
4
+ code;
5
+ constructor(message, options) {
6
+ super(message, { cause: options.cause });
7
+ this.name = new.target.name;
8
+ this.kind = options.kind;
9
+ this.code = options.code;
10
+ }
11
+ }
12
+
13
+ class KubernetesError extends ToolboxError {
14
+ }
15
+ function kubernetesHttpError(status) {
16
+ const kind = {
17
+ 401: "authentication_failed",
18
+ 403: "permission_denied",
19
+ 404: "resource_not_found",
20
+ 408: "timeout",
21
+ 429: "limit_exceeded",
22
+ 504: "timeout"
23
+ }[status] ?? "operation_failed";
24
+ return new KubernetesError("Kubernetes resource request failed", { kind, code: status });
25
+ }
26
+ function kubernetesCommandError(result) {
27
+ if (result.timedOut)
28
+ return new KubernetesError("Kubernetes resource request timed out", { kind: "timeout" });
29
+ const reason = /^Error from server \(([^)]+)\):/m.exec(result.stderr)?.[1];
30
+ const status = reason ? {
31
+ Unauthorized: 401,
32
+ Forbidden: 403,
33
+ NotFound: 404,
34
+ Timeout: 408,
35
+ TooManyRequests: 429,
36
+ ServerTimeout: 504
37
+ }[reason] : undefined;
38
+ return status ? kubernetesHttpError(status) : new KubernetesError("Kubernetes resource request failed", { kind: "operation_failed" });
39
+ }
40
+
41
+ export { ToolboxError, KubernetesError, kubernetesHttpError, kubernetesCommandError };
@@ -6,7 +6,7 @@ import {
6
6
  import {
7
7
  KubernetesError,
8
8
  ToolboxError
9
- } from "./chunk-ntfm5e85.js";
9
+ } from "./chunk-zhkrydeg.js";
10
10
  export {
11
11
  clientKey,
12
12
  ToolboxError,
package/dist/errors.d.ts CHANGED
@@ -12,3 +12,13 @@ export declare class ToolboxError extends Error {
12
12
  export declare class KubernetesError extends ToolboxError {
13
13
  }
14
14
  export declare function kubernetesHttpError(status: number): KubernetesError;
15
+ /**
16
+ * Normalize a failed kubectl resource request at the transport boundary.
17
+ * Only the server's Status reason is authoritative; arbitrary stderr containing
18
+ * "not found" (including a missing kubectl binary) does not prove resource absence.
19
+ * Do not apply this to a command executed inside a container.
20
+ */
21
+ export declare function kubernetesCommandError(result: {
22
+ stderr: string;
23
+ timedOut: boolean;
24
+ }): KubernetesError;
package/dist/errors.js CHANGED
@@ -1,10 +1,12 @@
1
1
  import {
2
2
  KubernetesError,
3
3
  ToolboxError,
4
+ kubernetesCommandError,
4
5
  kubernetesHttpError
5
- } from "./chunk-ntfm5e85.js";
6
+ } from "./chunk-zhkrydeg.js";
6
7
  export {
7
8
  kubernetesHttpError,
9
+ kubernetesCommandError,
8
10
  ToolboxError,
9
11
  KubernetesError
10
12
  };
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  KubernetesClient
3
- } from "../chunk-1e3arqz3.js";
3
+ } from "../chunk-y94xq8b4.js";
4
4
  import"../chunk-2171tajs.js";
5
5
  import"../chunk-j46x7j7c.js";
6
6
  import"../chunk-6fnhzhdb.js";
7
- import"../chunk-2m0mh09h.js";
8
- import"../chunk-y3dx8jh6.js";
9
- import"../chunk-ntfm5e85.js";
7
+ import"../chunk-fhtbvj0s.js";
8
+ import"../chunk-p6k59m3q.js";
9
+ import"../chunk-zhkrydeg.js";
10
10
  import"../chunk-v3hxvnrc.js";
11
11
  import"../chunk-631vce5z.js";
12
12
  import"../chunk-hmah9t8e.js";
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  KubernetesClient
3
- } from "../chunk-1e3arqz3.js";
3
+ } from "../chunk-y94xq8b4.js";
4
4
  import"../chunk-2171tajs.js";
5
5
  import"../chunk-j46x7j7c.js";
6
6
  import"../chunk-6fnhzhdb.js";
7
- import"../chunk-2m0mh09h.js";
8
- import"../chunk-y3dx8jh6.js";
7
+ import"../chunk-fhtbvj0s.js";
8
+ import"../chunk-p6k59m3q.js";
9
9
  import {
10
10
  clientKey
11
11
  } from "../chunk-a9htb6cr.js";
12
- import"../chunk-ntfm5e85.js";
12
+ import"../chunk-zhkrydeg.js";
13
13
  import"../chunk-v3hxvnrc.js";
14
14
  import"../chunk-631vce5z.js";
15
15
  import"../chunk-hmah9t8e.js";
@@ -8,7 +8,7 @@ import"../chunk-a9htb6cr.js";
8
8
  import {
9
9
  clientKey
10
10
  } from "../chunk-z5pm2emz.js";
11
- import"../chunk-ntfm5e85.js";
11
+ import"../chunk-zhkrydeg.js";
12
12
  import"../chunk-v3hxvnrc.js";
13
13
 
14
14
  // src/kubernetes/pod-log-datasource.ts
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  resourceAccess
3
- } from "../chunk-2m0mh09h.js";
4
- import"../chunk-ntfm5e85.js";
3
+ } from "../chunk-fhtbvj0s.js";
4
+ import"../chunk-zhkrydeg.js";
5
5
  import"../chunk-v3hxvnrc.js";
6
6
  export {
7
7
  resourceAccess
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  resolveWorkload
3
- } from "../chunk-y3dx8jh6.js";
4
- import"../chunk-ntfm5e85.js";
3
+ } from "../chunk-p6k59m3q.js";
4
+ import"../chunk-zhkrydeg.js";
5
5
  export {
6
6
  resolveWorkload
7
7
  };
@@ -8,7 +8,11 @@ export interface MysqlDatabaseOptions extends ClientLifecycle {
8
8
  queryTimeoutMs: number;
9
9
  }
10
10
  type ConnectionFactory = (options: ConnectionOptions) => Promise<Connection>;
11
- /** SQL is executed once; only native connection establishment may advance to another transport. */
11
+ /**
12
+ * @spec SQL is executed once; only native connection establishment may advance to another transport.
13
+ * @why mysql2 reports a socket closed during handshake as PROTOCOL_CONNECTION_LOST, before any SQL is sent.
14
+ * @case id=mysql_handshake_closed,desc=`Peer closes during handshake`,expect=`Try the next transport`,forbid=`Replay an interrupted query`
15
+ */
12
16
  export declare class MysqlDatabase implements Database {
13
17
  #private;
14
18
  private readonly transports;
@@ -2,10 +2,11 @@ import {
2
2
  MysqlClient,
3
3
  MysqlDatabase,
4
4
  openMysql
5
- } from "../chunk-qqntng20.js";
5
+ } from "../chunk-ahc00qs5.js";
6
6
  import"../chunk-age65q4n.js";
7
7
  import"../chunk-136egyff.js";
8
8
  import"../chunk-m91t44jh.js";
9
+ import"../chunk-zhkrydeg.js";
9
10
  import"../chunk-v3hxvnrc.js";
10
11
  import"../chunk-h8fwx0k7.js";
11
12
  import"../chunk-wv4jwhvj.js";
@@ -14,10 +14,11 @@ import {
14
14
  MysqlClient,
15
15
  MysqlDatabase,
16
16
  openMysql
17
- } from "../chunk-qqntng20.js";
17
+ } from "../chunk-ahc00qs5.js";
18
18
  import"../chunk-age65q4n.js";
19
19
  import"../chunk-136egyff.js";
20
20
  import"../chunk-m91t44jh.js";
21
+ import"../chunk-zhkrydeg.js";
21
22
  import"../chunk-v3hxvnrc.js";
22
23
  import"../chunk-h8fwx0k7.js";
23
24
  import"../chunk-wv4jwhvj.js";
@@ -2,7 +2,7 @@ import {
2
2
  S3DataSource
3
3
  } from "../chunk-35cjec9z.js";
4
4
  import"../chunk-z5pm2emz.js";
5
- import"../chunk-ntfm5e85.js";
5
+ import"../chunk-zhkrydeg.js";
6
6
  import"../chunk-zp1s833x.js";
7
7
  import"../chunk-v3hxvnrc.js";
8
8
  import"../chunk-x4ntb898.js";
package/dist/s3/index.js CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  S3DataSource
3
3
  } from "../chunk-35cjec9z.js";
4
4
  import"../chunk-z5pm2emz.js";
5
- import"../chunk-ntfm5e85.js";
5
+ import"../chunk-zhkrydeg.js";
6
6
  import {
7
7
  S3Client
8
8
  } from "../chunk-zp1s833x.js";
@@ -1,4 +1,10 @@
1
1
  export interface S3Target {
2
+ /**
3
+ * Complete endpoint URL, including the scheme, host and any non-default port.
4
+ * A Kubernetes Service host includes its namespace (for example, http://s3.storage:9000).
5
+ * The source resolves the full address; downstream clients and transports use it as-is,
6
+ * without appending host suffixes or inferring a namespace from the consuming Service.
7
+ */
2
8
  endpoint: string;
3
9
  region: string;
4
10
  credentials: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@compforge/harness-toolbox",
3
- "version": "0.3.6",
3
+ "version": "0.3.9",
4
4
  "description": "Shared infrastructure clients, transports and bounded data capture",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -110,6 +110,9 @@
110
110
  "@types/node-fetch": "2.6.13",
111
111
  "@types/node": "^22"
112
112
  },
113
+ "overrides": {
114
+ "@compforge/harness-common": "file:../common"
115
+ },
113
116
  "publishConfig": {
114
117
  "access": "public"
115
118
  },
@@ -1,27 +0,0 @@
1
- // src/errors.ts
2
- class ToolboxError extends Error {
3
- kind;
4
- code;
5
- constructor(message, options) {
6
- super(message, { cause: options.cause });
7
- this.name = new.target.name;
8
- this.kind = options.kind;
9
- this.code = options.code;
10
- }
11
- }
12
-
13
- class KubernetesError extends ToolboxError {
14
- }
15
- function kubernetesHttpError(status) {
16
- const kind = {
17
- 401: "authentication_failed",
18
- 403: "permission_denied",
19
- 404: "resource_not_found",
20
- 408: "timeout",
21
- 429: "limit_exceeded",
22
- 504: "timeout"
23
- }[status] ?? "operation_failed";
24
- return new KubernetesError("Kubernetes resource request failed", { kind, code: status });
25
- }
26
-
27
- export { ToolboxError, KubernetesError, kubernetesHttpError };