@compforge/harness-toolbox 0.3.10 → 0.3.11
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/README.md +42 -0
- package/dist/{chunk-zhkrydeg.js → chunk-20kv4wc3.js} +4 -1
- package/dist/{chunk-p6k59m3q.js → chunk-8axd2y2m.js} +1 -1
- package/dist/{chunk-b7f39m4v.js → chunk-8mb6natq.js} +1 -1
- package/dist/{chunk-fhtbvj0s.js → chunk-9n9z2pty.js} +1 -1
- package/dist/{chunk-y94xq8b4.js → chunk-a1cb44ga.js} +5 -5
- package/dist/chunk-ba883sdp.js +60 -0
- package/dist/{chunk-ahc00qs5.js → chunk-h73h2b7y.js} +5 -5
- package/dist/chunk-mxyvpy79.js +62 -0
- package/dist/chunk-mzdz6wwc.js +91 -0
- package/dist/datasource.js +1 -1
- package/dist/errors.d.ts +2 -0
- package/dist/errors.js +4 -2
- package/dist/file/client.d.ts +17 -0
- package/dist/file/client.js +10 -0
- package/dist/file/index.d.ts +5 -0
- package/dist/file/index.js +24 -0
- package/dist/file/local.d.ts +13 -0
- package/dist/file/local.js +11 -0
- package/dist/file/pod.d.ts +31 -0
- package/dist/file/pod.js +11 -0
- package/dist/kubernetes/client.js +4 -4
- package/dist/kubernetes/environment.js +4 -4
- package/dist/kubernetes/pod-log-datasource.js +1 -1
- package/dist/kubernetes/resources.js +2 -2
- package/dist/kubernetes/workload.js +2 -2
- package/dist/mysql/client.js +3 -3
- package/dist/mysql/index.js +12 -12
- package/dist/opensearch/client.js +2 -2
- package/dist/opensearch/index.js +7 -7
- package/dist/s3/datasource.js +1 -1
- package/dist/s3/index.js +1 -1
- package/package.json +6 -5
package/README.md
CHANGED
|
@@ -16,6 +16,48 @@ claiming snapshot consistency; callers supply cancellation and decide how to per
|
|
|
16
16
|
Protocol adapters have separate entry points; importing lifecycle or transport contracts does
|
|
17
17
|
not load database or Kubernetes drivers.
|
|
18
18
|
|
|
19
|
+
## File sources
|
|
20
|
+
|
|
21
|
+
Use `LocalFileDataSource` for a local file or `PodFileDataSource` for a file in an explicit
|
|
22
|
+
namespace/Pod/container. Both extend Common's `FileDataSource`, so a Service can store them directly
|
|
23
|
+
as DataSources and consumers can recognize files with `instanceof FileDataSource`. No additional
|
|
24
|
+
`id` or `kind` wrapper is required; consumer-owned selection names remain separate from client identity.
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import { ClientManager, FileDataSource } from "@compforge/harness-common";
|
|
28
|
+
import { LocalFileDataSource, PodFileDataSource } from "@compforge/harness-toolbox/file";
|
|
29
|
+
|
|
30
|
+
const source = new LocalFileDataSource("./config.yaml", { concurrency: 2 });
|
|
31
|
+
const clients = new ClientManager();
|
|
32
|
+
try {
|
|
33
|
+
if (source instanceof FileDataSource) {
|
|
34
|
+
const file = await clients.get(source);
|
|
35
|
+
const bytes = await file.read({ maxBytes: 1024 * 1024, timeoutMs: 15_000 });
|
|
36
|
+
console.log(source.path, new TextDecoder("utf-8", { fatal: true }).decode(bytes));
|
|
37
|
+
}
|
|
38
|
+
} finally {
|
|
39
|
+
await clients.dispose();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// `environment` is a KubernetesEnvironment (or an equivalent ClientProvider).
|
|
43
|
+
// Resolve Workloads first and create one source per chosen Pod/container.
|
|
44
|
+
const podSource = new PodFileDataSource(environment,
|
|
45
|
+
{ namespace: "app", pod: "worker-abc", container: "worker" },
|
|
46
|
+
"/etc/app/config.yaml", { concurrency: 2 });
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Each read reopens the file; the manager shares clients, not previous file contents. The byte limit
|
|
50
|
+
rejects oversized reads, including a zero-byte limit on a nonempty file. Timeouts include queue time;
|
|
51
|
+
caller cancellation and disposal cancel active reads. Keep the source path and Pod target with any
|
|
52
|
+
persisted evidence. A successful read describes bytes at that location, not the application's parsed
|
|
53
|
+
or effective configuration and not an atomic filesystem snapshot.
|
|
54
|
+
|
|
55
|
+
Local files may be symlinks to regular files. Pod reads require `pods/exec` access and `head -c` in the
|
|
56
|
+
selected container; paths are passed as argv without a shell. A Pod name is an access location, not
|
|
57
|
+
a UID fence; callers needing incarnation guarantees must verify discovery around collection. Pod
|
|
58
|
+
sources borrow Kubernetes access from the root manager and never close it themselves. Unsupported
|
|
59
|
+
commands, missing paths and denied reads fail explicitly; they are not empty file results.
|
|
60
|
+
|
|
19
61
|
## Workload discovery
|
|
20
62
|
|
|
21
63
|
Borrow a KubernetesClient through KubernetesEnvironment and the shared ClientManager lifecycle, then call
|
|
@@ -12,6 +12,9 @@ class ToolboxError extends Error {
|
|
|
12
12
|
|
|
13
13
|
class KubernetesError extends ToolboxError {
|
|
14
14
|
}
|
|
15
|
+
|
|
16
|
+
class FileError extends ToolboxError {
|
|
17
|
+
}
|
|
15
18
|
function kubernetesHttpError(status) {
|
|
16
19
|
const kind = {
|
|
17
20
|
401: "authentication_failed",
|
|
@@ -38,4 +41,4 @@ function kubernetesCommandError(result) {
|
|
|
38
41
|
return status ? kubernetesHttpError(status) : new KubernetesError("Kubernetes resource request failed", { kind: "operation_failed" });
|
|
39
42
|
}
|
|
40
43
|
|
|
41
|
-
export { ToolboxError, KubernetesError, kubernetesHttpError, kubernetesCommandError };
|
|
44
|
+
export { ToolboxError, KubernetesError, FileError, kubernetesHttpError, kubernetesCommandError };
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
resolveWorkload
|
|
3
|
+
} from "./chunk-8axd2y2m.js";
|
|
1
4
|
import {
|
|
2
5
|
ServicePortForwarder
|
|
3
6
|
} from "./chunk-2171tajs.js";
|
|
4
7
|
import {
|
|
5
8
|
resourceAccess
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import {
|
|
8
|
-
resolveWorkload
|
|
9
|
-
} from "./chunk-p6k59m3q.js";
|
|
9
|
+
} from "./chunk-9n9z2pty.js";
|
|
10
10
|
import {
|
|
11
11
|
KubernetesError
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-20kv4wc3.js";
|
|
13
13
|
import {
|
|
14
14
|
KubectlExecutor
|
|
15
15
|
} from "./chunk-hmah9t8e.js";
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BoundedFileClient,
|
|
3
|
+
fileClientOptions
|
|
4
|
+
} from "./chunk-mzdz6wwc.js";
|
|
5
|
+
import {
|
|
6
|
+
FileError
|
|
7
|
+
} from "./chunk-20kv4wc3.js";
|
|
8
|
+
|
|
9
|
+
// src/file/local.ts
|
|
10
|
+
import { constants } from "node:fs";
|
|
11
|
+
import { open } from "node:fs/promises";
|
|
12
|
+
import { resolve } from "node:path";
|
|
13
|
+
import { clientKey, FileDataSource } from "@compforge/harness-common";
|
|
14
|
+
class LocalFileClient extends BoundedFileClient {
|
|
15
|
+
async capture(signal, limits, receive) {
|
|
16
|
+
try {
|
|
17
|
+
const file = await open(this.path, constants.O_RDONLY | constants.O_NONBLOCK);
|
|
18
|
+
try {
|
|
19
|
+
signal.throwIfAborted();
|
|
20
|
+
if (!(await file.stat()).isFile()) {
|
|
21
|
+
throw new FileError(`Not a regular file: ${this.path}`, { kind: "unsupported_operation" });
|
|
22
|
+
}
|
|
23
|
+
const stream = file.createReadStream({ autoClose: false, signal, highWaterMark: Math.min(limits.maxBytes + 1, 64 * 1024) });
|
|
24
|
+
for await (const bytes of stream)
|
|
25
|
+
receive(bytes);
|
|
26
|
+
} finally {
|
|
27
|
+
await file.close();
|
|
28
|
+
}
|
|
29
|
+
} catch (cause) {
|
|
30
|
+
signal.throwIfAborted();
|
|
31
|
+
if (cause instanceof FileError)
|
|
32
|
+
throw cause;
|
|
33
|
+
const code = cause?.code;
|
|
34
|
+
throw new FileError(`Cannot read local file: ${this.path}`, {
|
|
35
|
+
kind: code === "ENOENT" || code === "ENOTDIR" ? "resource_not_found" : code === "EACCES" || code === "EPERM" ? "permission_denied" : "operation_failed",
|
|
36
|
+
code,
|
|
37
|
+
cause
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
class LocalFileDataSource extends FileDataSource {
|
|
44
|
+
path;
|
|
45
|
+
clientKey;
|
|
46
|
+
#options;
|
|
47
|
+
constructor(path, options) {
|
|
48
|
+
super();
|
|
49
|
+
if (!path || path.includes("\x00"))
|
|
50
|
+
throw new FileError("File path must be nonempty and contain no NUL", { kind: "invalid_argument" });
|
|
51
|
+
this.path = resolve(path);
|
|
52
|
+
this.#options = fileClientOptions(options);
|
|
53
|
+
this.clientKey = clientKey("local-file", { path: this.path, options: this.#options });
|
|
54
|
+
}
|
|
55
|
+
createClient(_clients, signal) {
|
|
56
|
+
return new LocalFileClient(this.path, this.#options, signal);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export { LocalFileClient, LocalFileDataSource };
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
queryMysqlViaPod,
|
|
3
|
+
queryMysqlViaPodBatch
|
|
4
|
+
} from "./chunk-m91t44jh.js";
|
|
1
5
|
import {
|
|
2
6
|
queryReadonlySession,
|
|
3
7
|
validateQueryLimits
|
|
@@ -5,13 +9,9 @@ import {
|
|
|
5
9
|
import {
|
|
6
10
|
destroyMysqlConnection
|
|
7
11
|
} from "./chunk-136egyff.js";
|
|
8
|
-
import {
|
|
9
|
-
queryMysqlViaPod,
|
|
10
|
-
queryMysqlViaPodBatch
|
|
11
|
-
} from "./chunk-m91t44jh.js";
|
|
12
12
|
import {
|
|
13
13
|
ToolboxError
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-20kv4wc3.js";
|
|
15
15
|
import {
|
|
16
16
|
ConcurrencyPool
|
|
17
17
|
} from "./chunk-v3hxvnrc.js";
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BoundedFileClient,
|
|
3
|
+
fileClientOptions
|
|
4
|
+
} from "./chunk-mzdz6wwc.js";
|
|
5
|
+
import {
|
|
6
|
+
FileError
|
|
7
|
+
} from "./chunk-20kv4wc3.js";
|
|
8
|
+
|
|
9
|
+
// src/file/pod.ts
|
|
10
|
+
import { posix } from "node:path";
|
|
11
|
+
import { clientKey, FileDataSource } from "@compforge/harness-common";
|
|
12
|
+
class PodFileClient extends BoundedFileClient {
|
|
13
|
+
target;
|
|
14
|
+
acquire;
|
|
15
|
+
#kubernetes;
|
|
16
|
+
constructor(path, target, options, signal, acquire) {
|
|
17
|
+
super(path, options, signal);
|
|
18
|
+
this.target = target;
|
|
19
|
+
this.acquire = acquire;
|
|
20
|
+
}
|
|
21
|
+
async initializeAccess() {
|
|
22
|
+
this.#kubernetes = await this.acquire();
|
|
23
|
+
}
|
|
24
|
+
async capture(signal, limits, receive) {
|
|
25
|
+
const result = await this.#kubernetes.exec(this.target.namespace, this.target, ["head", "-c", String(limits.maxBytes + 1), this.path], { signal, timeoutMs: limits.timeoutMs, collectStdout: false, onStdoutBytes: receive });
|
|
26
|
+
signal.throwIfAborted();
|
|
27
|
+
if (!result.ok)
|
|
28
|
+
throw new FileError(`Cannot read Pod file: ${this.target.namespace}/${this.target.pod}/${this.target.container} ${this.path}`, { kind: result.timedOut ? "timeout" : "operation_failed", code: result.exitCode ?? undefined });
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
class PodFileDataSource extends FileDataSource {
|
|
33
|
+
kubernetes;
|
|
34
|
+
path;
|
|
35
|
+
target;
|
|
36
|
+
clientKey;
|
|
37
|
+
#options;
|
|
38
|
+
constructor(kubernetes, target, path, options) {
|
|
39
|
+
super();
|
|
40
|
+
this.kubernetes = kubernetes;
|
|
41
|
+
if (!posix.isAbsolute(path) || path.includes("\x00")) {
|
|
42
|
+
throw new FileError("Pod file path must be absolute and contain no NUL", { kind: "invalid_argument" });
|
|
43
|
+
}
|
|
44
|
+
if ([target.namespace, target.pod, target.container].some((value) => !value.trim())) {
|
|
45
|
+
throw new FileError("Pod file namespace, Pod and Container are required", { kind: "invalid_argument" });
|
|
46
|
+
}
|
|
47
|
+
this.path = path;
|
|
48
|
+
this.target = Object.freeze({ namespace: target.namespace, pod: target.pod, container: target.container });
|
|
49
|
+
this.#options = fileClientOptions(options);
|
|
50
|
+
this.clientKey = clientKey("pod-file", {
|
|
51
|
+
access: kubernetes.clientKey,
|
|
52
|
+
target: this.target,
|
|
53
|
+
path: this.path,
|
|
54
|
+
options: this.#options
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
createClient(clients, signal) {
|
|
58
|
+
return new PodFileClient(this.path, this.target, this.#options, signal, () => clients.get(this.kubernetes));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export { PodFileClient, PodFileDataSource };
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FileError,
|
|
3
|
+
ToolboxError
|
|
4
|
+
} from "./chunk-20kv4wc3.js";
|
|
5
|
+
import {
|
|
6
|
+
ConcurrencyPool
|
|
7
|
+
} from "./chunk-v3hxvnrc.js";
|
|
8
|
+
|
|
9
|
+
// src/file/client.ts
|
|
10
|
+
function fileClientOptions(options) {
|
|
11
|
+
if (!Number.isSafeInteger(options.concurrency) || options.concurrency < 1) {
|
|
12
|
+
throw new FileError("File concurrency must be a positive integer", { kind: "invalid_argument" });
|
|
13
|
+
}
|
|
14
|
+
return Object.freeze({ concurrency: options.concurrency });
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
class BoundedFileClient {
|
|
18
|
+
path;
|
|
19
|
+
#controller = new AbortController;
|
|
20
|
+
#signal;
|
|
21
|
+
#pool;
|
|
22
|
+
#operations = new Set;
|
|
23
|
+
#ready = false;
|
|
24
|
+
#disposal;
|
|
25
|
+
constructor(path, options, signal) {
|
|
26
|
+
this.path = path;
|
|
27
|
+
this.#pool = new ConcurrencyPool(fileClientOptions(options).concurrency);
|
|
28
|
+
this.#signal = AbortSignal.any([signal, this.#controller.signal]);
|
|
29
|
+
}
|
|
30
|
+
async initialize() {
|
|
31
|
+
this.#signal.throwIfAborted();
|
|
32
|
+
await this.initializeAccess();
|
|
33
|
+
this.#signal.throwIfAborted();
|
|
34
|
+
this.#ready = true;
|
|
35
|
+
}
|
|
36
|
+
async initializeAccess() {}
|
|
37
|
+
async read(options) {
|
|
38
|
+
this.#signal.throwIfAborted();
|
|
39
|
+
if (!this.#ready)
|
|
40
|
+
throw new FileError(`File client is not initialized: ${this.path}`, { kind: "operation_failed" });
|
|
41
|
+
if (!Number.isSafeInteger(options.maxBytes) || options.maxBytes < 0 || options.maxBytes === Number.MAX_SAFE_INTEGER || !Number.isSafeInteger(options.timeoutMs) || options.timeoutMs <= 0 || options.timeoutMs > 2147483647) {
|
|
42
|
+
throw new FileError(`Invalid file read limits: ${this.path}`, { kind: "invalid_argument" });
|
|
43
|
+
}
|
|
44
|
+
const { maxBytes, timeoutMs } = options;
|
|
45
|
+
const controller = new AbortController;
|
|
46
|
+
const signal = AbortSignal.any([this.#signal, controller.signal, ...options.signal ? [options.signal] : []]);
|
|
47
|
+
const timer = setTimeout(() => controller.abort(new FileError(`File read timed out: ${this.path}`, { kind: "timeout" })), timeoutMs);
|
|
48
|
+
const operation = this.#pool.run(async () => {
|
|
49
|
+
const chunks = [];
|
|
50
|
+
let size = 0;
|
|
51
|
+
await this.capture(signal, { maxBytes, timeoutMs }, (bytes) => {
|
|
52
|
+
if (signal.aborted)
|
|
53
|
+
return;
|
|
54
|
+
if (bytes.byteLength > maxBytes - size) {
|
|
55
|
+
controller.abort(new FileError(`File exceeds ${maxBytes} bytes: ${this.path}`, { kind: "limit_exceeded" }));
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
chunks.push(Uint8Array.from(bytes));
|
|
59
|
+
size += bytes.byteLength;
|
|
60
|
+
});
|
|
61
|
+
signal.throwIfAborted();
|
|
62
|
+
const result = new Uint8Array(size);
|
|
63
|
+
let offset = 0;
|
|
64
|
+
for (const chunk of chunks) {
|
|
65
|
+
result.set(chunk, offset);
|
|
66
|
+
offset += chunk.byteLength;
|
|
67
|
+
}
|
|
68
|
+
return result;
|
|
69
|
+
}, signal);
|
|
70
|
+
this.#operations.add(operation);
|
|
71
|
+
try {
|
|
72
|
+
return await operation;
|
|
73
|
+
} catch (cause) {
|
|
74
|
+
signal.throwIfAborted();
|
|
75
|
+
if (cause instanceof ToolboxError)
|
|
76
|
+
throw cause;
|
|
77
|
+
throw new FileError(`Cannot read file: ${this.path}`, { kind: "operation_failed", cause });
|
|
78
|
+
} finally {
|
|
79
|
+
clearTimeout(timer);
|
|
80
|
+
this.#operations.delete(operation);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
dispose() {
|
|
84
|
+
return this.#disposal ??= (async () => {
|
|
85
|
+
this.#controller.abort(new Error(`File client disposed: ${this.path}`));
|
|
86
|
+
await Promise.allSettled(this.#operations);
|
|
87
|
+
})();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export { fileClientOptions, BoundedFileClient };
|
package/dist/datasource.js
CHANGED
package/dist/errors.d.ts
CHANGED
|
@@ -11,6 +11,8 @@ export declare class ToolboxError extends Error {
|
|
|
11
11
|
}
|
|
12
12
|
export declare class KubernetesError extends ToolboxError {
|
|
13
13
|
}
|
|
14
|
+
export declare class FileError extends ToolboxError {
|
|
15
|
+
}
|
|
14
16
|
export declare function kubernetesHttpError(status: number): KubernetesError;
|
|
15
17
|
/**
|
|
16
18
|
* Normalize a failed kubectl resource request at the transport boundary.
|
package/dist/errors.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
|
+
FileError,
|
|
2
3
|
KubernetesError,
|
|
3
4
|
ToolboxError,
|
|
4
5
|
kubernetesCommandError,
|
|
5
6
|
kubernetesHttpError
|
|
6
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-20kv4wc3.js";
|
|
7
8
|
export {
|
|
8
9
|
kubernetesHttpError,
|
|
9
10
|
kubernetesCommandError,
|
|
10
11
|
ToolboxError,
|
|
11
|
-
KubernetesError
|
|
12
|
+
KubernetesError,
|
|
13
|
+
FileError
|
|
12
14
|
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { FileClient, FileReadOptions } from "@compforge/harness-common";
|
|
2
|
+
export interface FileClientOptions {
|
|
3
|
+
concurrency: number;
|
|
4
|
+
}
|
|
5
|
+
export declare function fileClientOptions(options: FileClientOptions): Readonly<FileClientOptions>;
|
|
6
|
+
/** Shared limits and lifecycle; transports stream bytes and own per-read resource cleanup. */
|
|
7
|
+
export declare abstract class BoundedFileClient implements FileClient {
|
|
8
|
+
#private;
|
|
9
|
+
readonly path: string;
|
|
10
|
+
constructor(path: string, options: FileClientOptions, signal: AbortSignal);
|
|
11
|
+
initialize(): Promise<void>;
|
|
12
|
+
protected initializeAccess(): Promise<void>;
|
|
13
|
+
protected abstract capture(signal: AbortSignal, limits: Pick<FileReadOptions, "maxBytes" | "timeoutMs">, receive: (bytes: Uint8Array) => void): Promise<void>;
|
|
14
|
+
/** @spec Limits apply while streaming; a failed read never publishes partial bytes. */
|
|
15
|
+
read(options: FileReadOptions): Promise<Uint8Array>;
|
|
16
|
+
dispose(): Promise<void>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { FileDataSource, type FileClient, type FileReadOptions } from "@compforge/harness-common";
|
|
2
|
+
export { FileError } from "../errors";
|
|
3
|
+
export type { FileClientOptions } from "./client";
|
|
4
|
+
export { LocalFileDataSource, LocalFileClient } from "./local";
|
|
5
|
+
export { PodFileDataSource, PodFileClient, type PodFileTarget } from "./pod";
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import {
|
|
2
|
+
PodFileClient,
|
|
3
|
+
PodFileDataSource
|
|
4
|
+
} from "../chunk-mxyvpy79.js";
|
|
5
|
+
import {
|
|
6
|
+
LocalFileClient,
|
|
7
|
+
LocalFileDataSource
|
|
8
|
+
} from "../chunk-ba883sdp.js";
|
|
9
|
+
import"../chunk-mzdz6wwc.js";
|
|
10
|
+
import {
|
|
11
|
+
FileError
|
|
12
|
+
} from "../chunk-20kv4wc3.js";
|
|
13
|
+
import"../chunk-v3hxvnrc.js";
|
|
14
|
+
|
|
15
|
+
// src/file/index.ts
|
|
16
|
+
import { FileDataSource } from "@compforge/harness-common";
|
|
17
|
+
export {
|
|
18
|
+
PodFileDataSource,
|
|
19
|
+
PodFileClient,
|
|
20
|
+
LocalFileDataSource,
|
|
21
|
+
LocalFileClient,
|
|
22
|
+
FileError,
|
|
23
|
+
FileDataSource
|
|
24
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { FileDataSource, type ClientManager, type FileReadOptions } from "@compforge/harness-common";
|
|
2
|
+
import { BoundedFileClient, type FileClientOptions } from "./client";
|
|
3
|
+
export declare class LocalFileClient extends BoundedFileClient {
|
|
4
|
+
protected capture(signal: AbortSignal, limits: Pick<FileReadOptions, "maxBytes" | "timeoutMs">, receive: (bytes: Uint8Array) => void): Promise<void>;
|
|
5
|
+
}
|
|
6
|
+
/** @spec Resolve relative paths once at declaration; reads reopen the path to observe replaced mounted files. */
|
|
7
|
+
export declare class LocalFileDataSource extends FileDataSource<LocalFileClient> {
|
|
8
|
+
#private;
|
|
9
|
+
readonly path: string;
|
|
10
|
+
readonly clientKey: string;
|
|
11
|
+
constructor(path: string, options: FileClientOptions);
|
|
12
|
+
createClient(_clients: Pick<ClientManager, "get">, signal: AbortSignal): LocalFileClient;
|
|
13
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { FileDataSource, type ClientManager, type ClientProvider, type FileReadOptions } from "@compforge/harness-common";
|
|
2
|
+
import type { KubernetesClient } from "../kubernetes/client";
|
|
3
|
+
import { BoundedFileClient, type FileClientOptions } from "./client";
|
|
4
|
+
export interface PodFileTarget {
|
|
5
|
+
namespace: string;
|
|
6
|
+
pod: string;
|
|
7
|
+
container: string;
|
|
8
|
+
}
|
|
9
|
+
export type PodFileAccess = Pick<KubernetesClient, "initialize" | "dispose" | "exec">;
|
|
10
|
+
export declare class PodFileClient extends BoundedFileClient {
|
|
11
|
+
#private;
|
|
12
|
+
readonly target: Readonly<PodFileTarget>;
|
|
13
|
+
private readonly acquire;
|
|
14
|
+
constructor(path: string, target: Readonly<PodFileTarget>, options: FileClientOptions, signal: AbortSignal, acquire: () => Promise<PodFileAccess>);
|
|
15
|
+
protected initializeAccess(): Promise<void>;
|
|
16
|
+
protected capture(signal: AbortSignal, limits: Pick<FileReadOptions, "maxBytes" | "timeoutMs">, receive: (bytes: Uint8Array) => void): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* @spec One explicit Pod/container/path per source; workload discovery and replica traversal belong to callers.
|
|
20
|
+
* @rule Borrow Kubernetes access from the root manager; file clients never dispose that shared dependency.
|
|
21
|
+
* @see {@link component://../../../docs/toolbox.md}
|
|
22
|
+
*/
|
|
23
|
+
export declare class PodFileDataSource extends FileDataSource<PodFileClient> {
|
|
24
|
+
#private;
|
|
25
|
+
private readonly kubernetes;
|
|
26
|
+
readonly path: string;
|
|
27
|
+
readonly target: Readonly<PodFileTarget>;
|
|
28
|
+
readonly clientKey: string;
|
|
29
|
+
constructor(kubernetes: ClientProvider<PodFileAccess>, target: PodFileTarget, path: string, options: FileClientOptions);
|
|
30
|
+
createClient(clients: Pick<ClientManager, "get">, signal: AbortSignal): PodFileClient;
|
|
31
|
+
}
|
package/dist/file/pod.js
ADDED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
KubernetesClient
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-a1cb44ga.js";
|
|
4
|
+
import"../chunk-8axd2y2m.js";
|
|
4
5
|
import"../chunk-2171tajs.js";
|
|
5
6
|
import"../chunk-j46x7j7c.js";
|
|
6
7
|
import"../chunk-6fnhzhdb.js";
|
|
7
|
-
import"../chunk-
|
|
8
|
-
import"../chunk-
|
|
9
|
-
import"../chunk-zhkrydeg.js";
|
|
8
|
+
import"../chunk-9n9z2pty.js";
|
|
9
|
+
import"../chunk-20kv4wc3.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-
|
|
3
|
+
} from "../chunk-a1cb44ga.js";
|
|
4
|
+
import"../chunk-8axd2y2m.js";
|
|
4
5
|
import"../chunk-2171tajs.js";
|
|
5
6
|
import"../chunk-j46x7j7c.js";
|
|
6
7
|
import"../chunk-6fnhzhdb.js";
|
|
7
|
-
import"../chunk-
|
|
8
|
-
import"../chunk-p6k59m3q.js";
|
|
8
|
+
import"../chunk-9n9z2pty.js";
|
|
9
9
|
import {
|
|
10
10
|
clientKey
|
|
11
11
|
} from "../chunk-a9htb6cr.js";
|
|
12
|
-
import"../chunk-
|
|
12
|
+
import"../chunk-20kv4wc3.js";
|
|
13
13
|
import"../chunk-v3hxvnrc.js";
|
|
14
14
|
import"../chunk-631vce5z.js";
|
|
15
15
|
import"../chunk-hmah9t8e.js";
|
package/dist/mysql/client.js
CHANGED
|
@@ -2,11 +2,11 @@ import {
|
|
|
2
2
|
MysqlClient,
|
|
3
3
|
MysqlDatabase,
|
|
4
4
|
openMysql
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-h73h2b7y.js";
|
|
6
|
+
import"../chunk-m91t44jh.js";
|
|
6
7
|
import"../chunk-age65q4n.js";
|
|
7
8
|
import"../chunk-136egyff.js";
|
|
8
|
-
import"../chunk-
|
|
9
|
-
import"../chunk-zhkrydeg.js";
|
|
9
|
+
import"../chunk-20kv4wc3.js";
|
|
10
10
|
import"../chunk-v3hxvnrc.js";
|
|
11
11
|
import"../chunk-h8fwx0k7.js";
|
|
12
12
|
import"../chunk-wv4jwhvj.js";
|
package/dist/mysql/index.js
CHANGED
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
parseMysqlEnvTarget
|
|
3
|
-
} from "../chunk-qq77x9ek.js";
|
|
4
|
-
import {
|
|
5
|
-
limitedRows,
|
|
6
|
-
limitedStatement,
|
|
7
|
-
queryLimited
|
|
8
|
-
} from "../chunk-1gyshqd9.js";
|
|
9
|
-
import"../chunk-pfar9cm3.js";
|
|
10
1
|
import {
|
|
11
2
|
withReadScope
|
|
12
3
|
} from "../chunk-4sqvppz7.js";
|
|
@@ -14,11 +5,20 @@ import {
|
|
|
14
5
|
MysqlClient,
|
|
15
6
|
MysqlDatabase,
|
|
16
7
|
openMysql
|
|
17
|
-
} from "../chunk-
|
|
8
|
+
} from "../chunk-h73h2b7y.js";
|
|
9
|
+
import"../chunk-m91t44jh.js";
|
|
18
10
|
import"../chunk-age65q4n.js";
|
|
11
|
+
import {
|
|
12
|
+
parseMysqlEnvTarget
|
|
13
|
+
} from "../chunk-qq77x9ek.js";
|
|
14
|
+
import {
|
|
15
|
+
limitedRows,
|
|
16
|
+
limitedStatement,
|
|
17
|
+
queryLimited
|
|
18
|
+
} from "../chunk-1gyshqd9.js";
|
|
19
19
|
import"../chunk-136egyff.js";
|
|
20
|
-
import"../chunk-
|
|
21
|
-
import"../chunk-
|
|
20
|
+
import"../chunk-pfar9cm3.js";
|
|
21
|
+
import"../chunk-20kv4wc3.js";
|
|
22
22
|
import"../chunk-v3hxvnrc.js";
|
|
23
23
|
import"../chunk-h8fwx0k7.js";
|
|
24
24
|
import"../chunk-wv4jwhvj.js";
|
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
OpenSearchEngine,
|
|
4
4
|
isOpenSearchReadApi,
|
|
5
5
|
openOpenSearch
|
|
6
|
-
} from "../chunk-
|
|
7
|
-
import"../chunk-
|
|
6
|
+
} from "../chunk-8mb6natq.js";
|
|
7
|
+
import"../chunk-20kv4wc3.js";
|
|
8
8
|
import"../chunk-h8fwx0k7.js";
|
|
9
9
|
import"../chunk-wv4jwhvj.js";
|
|
10
10
|
import"../chunk-631vce5z.js";
|
package/dist/opensearch/index.js
CHANGED
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
OpenSearchClient,
|
|
3
|
-
OpenSearchEngine,
|
|
4
|
-
isOpenSearchReadApi,
|
|
5
|
-
openOpenSearch
|
|
6
|
-
} from "../chunk-b7f39m4v.js";
|
|
7
1
|
import {
|
|
8
2
|
searchAfterPages
|
|
9
3
|
} from "../chunk-99p0zt4f.js";
|
|
@@ -11,7 +5,13 @@ import {
|
|
|
11
5
|
parseOpenSearchEndpoint
|
|
12
6
|
} from "../chunk-s1sjyem7.js";
|
|
13
7
|
import"../chunk-djk4kmxb.js";
|
|
14
|
-
import
|
|
8
|
+
import {
|
|
9
|
+
OpenSearchClient,
|
|
10
|
+
OpenSearchEngine,
|
|
11
|
+
isOpenSearchReadApi,
|
|
12
|
+
openOpenSearch
|
|
13
|
+
} from "../chunk-8mb6natq.js";
|
|
14
|
+
import"../chunk-20kv4wc3.js";
|
|
15
15
|
import"../chunk-h8fwx0k7.js";
|
|
16
16
|
import"../chunk-wv4jwhvj.js";
|
|
17
17
|
import"../chunk-631vce5z.js";
|
package/dist/s3/datasource.js
CHANGED
package/dist/s3/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@compforge/harness-toolbox",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.11",
|
|
4
4
|
"description": "Shared infrastructure clients, transports and bounded data capture",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -88,6 +88,10 @@
|
|
|
88
88
|
"./data-loader": {
|
|
89
89
|
"types": "./dist/data-loader.d.ts",
|
|
90
90
|
"import": "./dist/data-loader.js"
|
|
91
|
+
},
|
|
92
|
+
"./file": {
|
|
93
|
+
"types": "./dist/file/index.d.ts",
|
|
94
|
+
"import": "./dist/file/index.js"
|
|
91
95
|
}
|
|
92
96
|
},
|
|
93
97
|
"files": [
|
|
@@ -95,7 +99,7 @@
|
|
|
95
99
|
"README.md"
|
|
96
100
|
],
|
|
97
101
|
"dependencies": {
|
|
98
|
-
"@compforge/harness-common": "0.3
|
|
102
|
+
"@compforge/harness-common": "0.5.3",
|
|
99
103
|
"@aws-sdk/client-s3": "3.1133.0",
|
|
100
104
|
"@kubernetes/client-node": "1.4.0",
|
|
101
105
|
"@opensearch-project/opensearch": "3.6.0",
|
|
@@ -110,9 +114,6 @@
|
|
|
110
114
|
"@types/node-fetch": "2.6.13",
|
|
111
115
|
"@types/node": "^22"
|
|
112
116
|
},
|
|
113
|
-
"overrides": {
|
|
114
|
-
"@compforge/harness-common": "file:../common"
|
|
115
|
-
},
|
|
116
117
|
"publishConfig": {
|
|
117
118
|
"access": "public"
|
|
118
119
|
},
|