@fabric-harness/connectors 0.5.0 → 0.6.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/README.md +34 -3
- package/dist/azure-blob.d.ts +49 -0
- package/dist/azure-blob.d.ts.map +1 -0
- package/dist/azure-blob.js +117 -0
- package/dist/azure-blob.js.map +1 -0
- package/dist/databricks-volume.d.ts +53 -0
- package/dist/databricks-volume.d.ts.map +1 -0
- package/dist/databricks-volume.js +107 -0
- package/dist/databricks-volume.js.map +1 -0
- package/dist/gcs.d.ts +38 -0
- package/dist/gcs.d.ts.map +1 -0
- package/dist/gcs.js +86 -0
- package/dist/gcs.js.map +1 -0
- package/dist/github.d.ts +30 -0
- package/dist/github.d.ts.map +1 -0
- package/dist/github.js +100 -0
- package/dist/github.js.map +1 -0
- package/dist/k8s.d.ts +62 -0
- package/dist/k8s.d.ts.map +1 -0
- package/dist/k8s.js +155 -0
- package/dist/k8s.js.map +1 -0
- package/dist/s3.d.ts +78 -0
- package/dist/s3.d.ts.map +1 -0
- package/dist/s3.js +114 -0
- package/dist/s3.js.map +1 -0
- package/package.json +61 -2
package/README.md
CHANGED
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
> Modular connector helpers and recipes for [Fabric Harness](https://github.com/Fabric-Pro/fabric-harness).
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Three ways to use this package:
|
|
6
6
|
|
|
7
|
-
1.
|
|
8
|
-
2.
|
|
7
|
+
1. **Concrete data sources** on dedicated subpath exports (`@fabric-harness/connectors/s3`, `/azure-blob`, `/gcs`, `/github`, `/databricks-volume`, `/k8s`). Each peer-deps the vendor SDK so you only install what you use.
|
|
8
|
+
2. **Sandbox adapters** for Daytona, E2B, Modal, plus the structural `remoteSandbox` for any provider-owned remote sandbox (`s3FilesystemSource`, `azureBlobFilesystemSource` from the root export are the older structural sources for advanced cases).
|
|
9
|
+
3. **Markdown recipes** via `fh add <name>` that you pipe into your coding agent to scaffold a project-local adapter.
|
|
9
10
|
|
|
10
11
|
## Install
|
|
11
12
|
|
|
@@ -13,6 +14,36 @@ Use this package in two ways:
|
|
|
13
14
|
npm install @fabric-harness/connectors
|
|
14
15
|
```
|
|
15
16
|
|
|
17
|
+
## Data sources
|
|
18
|
+
|
|
19
|
+
Mount external services as files inside the sandbox. The agent's built-in
|
|
20
|
+
`read`, `glob`, `grep`, and `bash` tools then operate over the mounted prefix.
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import { s3Source } from '@fabric-harness/connectors/s3';
|
|
24
|
+
|
|
25
|
+
const fabric = await init({ sandbox: 'local' });
|
|
26
|
+
const session = await fabric.session();
|
|
27
|
+
|
|
28
|
+
// `@aws-sdk/client-s3` is a peer dependency — install it explicitly.
|
|
29
|
+
await session.mount('/mnt/logs', s3Source({ bucket: 'my-logs', prefix: '2026/' }));
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Each source is a `FilesystemSource` that yields `(path, content)` pairs;
|
|
33
|
+
`session.mount(mountAt, source)` writes them into the sandbox at the given
|
|
34
|
+
path. Absolute mount paths outside the sandbox cwd are rerooted under it.
|
|
35
|
+
|
|
36
|
+
Available subpath exports (peer-dep'd vendor SDKs):
|
|
37
|
+
|
|
38
|
+
| Export | Functions | Peer dependency |
|
|
39
|
+
|---|---|---|
|
|
40
|
+
| `@fabric-harness/connectors/s3` | `s3Source`, `s3Writer` | `@aws-sdk/client-s3` |
|
|
41
|
+
| `@fabric-harness/connectors/azure-blob` | `azureBlobSource`, `azureBlobWriter` | `@azure/storage-blob` |
|
|
42
|
+
| `@fabric-harness/connectors/gcs` | `gcsSource`, `gcsWriter` | `@google-cloud/storage` |
|
|
43
|
+
| `@fabric-harness/connectors/github` | `githubSource` | `octokit` |
|
|
44
|
+
| `@fabric-harness/connectors/databricks-volume` | `databricksVolumeSource`, `databricksVolumeWriter` | _(none — uses `fetch`)_ |
|
|
45
|
+
| `@fabric-harness/connectors/k8s` | `kubernetesSandbox`, `createKubernetesPod` | `@kubernetes/client-node` |
|
|
46
|
+
|
|
16
47
|
## Sandbox adapters
|
|
17
48
|
|
|
18
49
|
```ts
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { FilesystemSource } from '@fabric-harness/sdk';
|
|
2
|
+
/**
|
|
3
|
+
* Concrete Azure Blob connector backed by `@azure/storage-blob`.
|
|
4
|
+
*
|
|
5
|
+
* Install peer deps:
|
|
6
|
+
* ```sh
|
|
7
|
+
* npm install @azure/storage-blob
|
|
8
|
+
* # optional, for managed identity:
|
|
9
|
+
* npm install @azure/identity
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
export interface AzureBlobSourceOptions {
|
|
13
|
+
/** Storage account URL, e.g. `https://acct.blob.core.windows.net`. */
|
|
14
|
+
accountUrl?: string;
|
|
15
|
+
/** Container name. Required. */
|
|
16
|
+
container: string;
|
|
17
|
+
/** Optional blob name prefix. */
|
|
18
|
+
prefix?: string;
|
|
19
|
+
/** Override prefix-stripping in mounted paths. Defaults to `prefix`. */
|
|
20
|
+
stripPrefix?: string;
|
|
21
|
+
/** Filter applied to each blob name. */
|
|
22
|
+
include?: (name: string) => boolean;
|
|
23
|
+
/** Page size for listings. */
|
|
24
|
+
pageSize?: number;
|
|
25
|
+
/** Stable name for telemetry / logs. */
|
|
26
|
+
name?: string;
|
|
27
|
+
/** Account-level connection string. Mutually exclusive with `accountUrl` + credential. */
|
|
28
|
+
connectionString?: string;
|
|
29
|
+
/** SAS or storage-shared-key credential, or `@azure/identity` credential. */
|
|
30
|
+
credential?: unknown;
|
|
31
|
+
/** Pre-built ContainerClient. Overrides accountUrl/container/credential. */
|
|
32
|
+
containerClient?: unknown;
|
|
33
|
+
}
|
|
34
|
+
export declare function azureBlobSource(options: AzureBlobSourceOptions): FilesystemSource;
|
|
35
|
+
export interface AzureBlobWriterOptions extends Omit<AzureBlobSourceOptions, 'prefix' | 'stripPrefix' | 'include' | 'pageSize' | 'name'> {
|
|
36
|
+
prefix?: string;
|
|
37
|
+
}
|
|
38
|
+
export interface AzureBlobWriter {
|
|
39
|
+
put(name: string, content: string | Uint8Array, options?: {
|
|
40
|
+
contentType?: string;
|
|
41
|
+
metadata?: Record<string, string>;
|
|
42
|
+
}): Promise<{
|
|
43
|
+
name: string;
|
|
44
|
+
container: string;
|
|
45
|
+
}>;
|
|
46
|
+
delete(name: string): Promise<void>;
|
|
47
|
+
}
|
|
48
|
+
export declare function azureBlobWriter(options: AzureBlobWriterOptions): AzureBlobWriter;
|
|
49
|
+
//# sourceMappingURL=azure-blob.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"azure-blob.d.ts","sourceRoot":"","sources":["../src/azure-blob.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAK5D;;;;;;;;;GASG;AACH,MAAM,WAAW,sBAAsB;IACrC,sEAAsE;IACtE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gCAAgC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,iCAAiC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wCAAwC;IACxC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IACpC,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wCAAwC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0FAA0F;IAC1F,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,6EAA6E;IAC7E,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,4EAA4E;IAC5E,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAQD,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,gBAAgB,CAgCjF;AAED,MAAM,WAAW,sBAAuB,SAAQ,IAAI,CAAC,sBAAsB,EAAE,QAAQ,GAAG,aAAa,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;IACtI,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,OAAO,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrK,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,eAAe,CAyBhF"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
import { azureBlobFilesystemSource } from './index.js';
|
|
3
|
+
const requireFromHere = createRequire(import.meta.url);
|
|
4
|
+
export function azureBlobSource(options) {
|
|
5
|
+
const container = createContainerClient(options);
|
|
6
|
+
return azureBlobFilesystemSource({
|
|
7
|
+
async listBlobs(listOpts) {
|
|
8
|
+
const blobs = [];
|
|
9
|
+
const iterable = container.listBlobsFlat(listOpts?.prefix ? { prefix: listOpts.prefix } : {});
|
|
10
|
+
for await (const blob of iterable) {
|
|
11
|
+
blobs.push(blob);
|
|
12
|
+
if (listOpts?.maxPageSize && blobs.length >= listOpts.maxPageSize)
|
|
13
|
+
break;
|
|
14
|
+
}
|
|
15
|
+
return { blobs };
|
|
16
|
+
},
|
|
17
|
+
async downloadBlob(name) {
|
|
18
|
+
const blobClient = container.getBlobClient?.(name) ?? container.getBlockBlobClient?.(name);
|
|
19
|
+
if (!blobClient)
|
|
20
|
+
return null;
|
|
21
|
+
const response = await blobClient.download();
|
|
22
|
+
const bytes = await streamToBytes(response.readableStreamBody, response.blobBody);
|
|
23
|
+
return {
|
|
24
|
+
body: bytes,
|
|
25
|
+
...(response.contentType ? { contentType: response.contentType } : {}),
|
|
26
|
+
};
|
|
27
|
+
},
|
|
28
|
+
}, {
|
|
29
|
+
...(options.prefix !== undefined ? { prefix: options.prefix } : {}),
|
|
30
|
+
...(options.stripPrefix !== undefined ? { stripPrefix: options.stripPrefix } : {}),
|
|
31
|
+
...(options.include !== undefined ? { include: options.include } : {}),
|
|
32
|
+
...(options.pageSize !== undefined ? { pageSize: options.pageSize } : {}),
|
|
33
|
+
name: options.name ?? `azure-blob:${options.container}/${options.prefix ?? ''}`,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
export function azureBlobWriter(options) {
|
|
37
|
+
const container = createContainerClient(options);
|
|
38
|
+
const prefix = options.prefix ?? '';
|
|
39
|
+
const fullName = (name) => `${prefix}${name.replace(/^\/+/, '')}`;
|
|
40
|
+
return {
|
|
41
|
+
async put(name, content, putOptions) {
|
|
42
|
+
const blob = container.getBlockBlobClient?.(fullName(name));
|
|
43
|
+
if (!blob || typeof blob.uploadData !== 'function') {
|
|
44
|
+
throw new Error('azureBlobWriter: container client does not expose getBlockBlobClient(name).uploadData()');
|
|
45
|
+
}
|
|
46
|
+
const data = typeof content === 'string' ? new TextEncoder().encode(content) : content;
|
|
47
|
+
const uploadOptions = {};
|
|
48
|
+
if (putOptions?.contentType)
|
|
49
|
+
uploadOptions.blobHTTPHeaders = { blobContentType: putOptions.contentType };
|
|
50
|
+
if (putOptions?.metadata)
|
|
51
|
+
uploadOptions.metadata = putOptions.metadata;
|
|
52
|
+
await blob.uploadData(data, uploadOptions);
|
|
53
|
+
return { name: fullName(name), container: options.container };
|
|
54
|
+
},
|
|
55
|
+
async delete(name) {
|
|
56
|
+
const blob = container.getBlockBlobClient?.(fullName(name));
|
|
57
|
+
if (!blob || typeof blob.deleteIfExists !== 'function') {
|
|
58
|
+
throw new Error('azureBlobWriter: container client does not expose getBlockBlobClient(name).deleteIfExists()');
|
|
59
|
+
}
|
|
60
|
+
await blob.deleteIfExists();
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function createContainerClient(options) {
|
|
65
|
+
if (options.containerClient) {
|
|
66
|
+
if (typeof options.containerClient.listBlobsFlat !== 'function') {
|
|
67
|
+
throw new Error('azureBlobSource: provided `containerClient` does not implement listBlobsFlat().');
|
|
68
|
+
}
|
|
69
|
+
return options.containerClient;
|
|
70
|
+
}
|
|
71
|
+
const mod = loadAzureBlobModule();
|
|
72
|
+
if (options.connectionString) {
|
|
73
|
+
const service = mod.BlobServiceClient.fromConnectionString(options.connectionString);
|
|
74
|
+
return service.getContainerClient(options.container);
|
|
75
|
+
}
|
|
76
|
+
if (!options.accountUrl) {
|
|
77
|
+
throw new Error('azureBlobSource: provide `containerClient`, `connectionString`, or `accountUrl`.');
|
|
78
|
+
}
|
|
79
|
+
const service = new mod.BlobServiceClient(options.accountUrl, options.credential);
|
|
80
|
+
return service.getContainerClient(options.container);
|
|
81
|
+
}
|
|
82
|
+
let cachedModule;
|
|
83
|
+
function loadAzureBlobModule() {
|
|
84
|
+
if (cachedModule)
|
|
85
|
+
return cachedModule;
|
|
86
|
+
try {
|
|
87
|
+
const mod = requireFromHere('@azure/storage-blob');
|
|
88
|
+
cachedModule = mod;
|
|
89
|
+
return mod;
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
throw new Error('azureBlobSource/azureBlobWriter requires the `@azure/storage-blob` peer dependency. Install it with: npm install @azure/storage-blob');
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
async function streamToBytes(stream, blobBody) {
|
|
96
|
+
if (blobBody) {
|
|
97
|
+
const blob = await blobBody;
|
|
98
|
+
return new Uint8Array(await blob.arrayBuffer());
|
|
99
|
+
}
|
|
100
|
+
if (!stream)
|
|
101
|
+
return new Uint8Array();
|
|
102
|
+
const chunks = [];
|
|
103
|
+
for await (const chunk of stream) {
|
|
104
|
+
chunks.push(typeof chunk === 'string' ? new TextEncoder().encode(chunk) : chunk);
|
|
105
|
+
}
|
|
106
|
+
let total = 0;
|
|
107
|
+
for (const c of chunks)
|
|
108
|
+
total += c.byteLength;
|
|
109
|
+
const out = new Uint8Array(total);
|
|
110
|
+
let offset = 0;
|
|
111
|
+
for (const c of chunks) {
|
|
112
|
+
out.set(c, offset);
|
|
113
|
+
offset += c.byteLength;
|
|
114
|
+
}
|
|
115
|
+
return out;
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=azure-blob.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"azure-blob.js","sourceRoot":"","sources":["../src/azure-blob.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { FilesystemSource } from '@fabric-harness/sdk';
|
|
2
|
+
/**
|
|
3
|
+
* Databricks Unity Catalog Volume connector backed by the Files API
|
|
4
|
+
* (`/api/2.0/fs/files/...`). No SDK dependency — uses `fetch` directly.
|
|
5
|
+
*
|
|
6
|
+
* Volume paths are addressed as `/Volumes/<catalog>/<schema>/<volume>/<path>`.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { databricksVolumeSource } from '@fabric-harness/connectors/databricks-volume';
|
|
11
|
+
*
|
|
12
|
+
* const source = databricksVolumeSource({
|
|
13
|
+
* host: process.env.DATABRICKS_HOST!,
|
|
14
|
+
* token: process.env.DATABRICKS_TOKEN!,
|
|
15
|
+
* volumePath: '/Volumes/main/landing/raw',
|
|
16
|
+
* });
|
|
17
|
+
* await session.mount('/mnt/dbx', source);
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export interface DatabricksVolumeSourceOptions {
|
|
21
|
+
/** Databricks workspace host, e.g. `https://adb-123.azuredatabricks.net`. */
|
|
22
|
+
host: string;
|
|
23
|
+
/** Personal access token or `() => Promise<string>` for short-lived tokens. */
|
|
24
|
+
token: string | (() => string | Promise<string>);
|
|
25
|
+
/** Volume path, e.g. `/Volumes/<catalog>/<schema>/<volume>/<subpath>`. */
|
|
26
|
+
volumePath: string;
|
|
27
|
+
/** Filter applied to each file's relative path. */
|
|
28
|
+
include?: (path: string) => boolean;
|
|
29
|
+
/** Stable name for telemetry / logs. */
|
|
30
|
+
name?: string;
|
|
31
|
+
/** Page size for directory listings. */
|
|
32
|
+
pageSize?: number;
|
|
33
|
+
/** Custom fetch implementation (defaults to global `fetch`). */
|
|
34
|
+
fetchImpl?: typeof fetch;
|
|
35
|
+
}
|
|
36
|
+
export declare function databricksVolumeSource(options: DatabricksVolumeSourceOptions): FilesystemSource;
|
|
37
|
+
export interface DatabricksVolumeWriterOptions {
|
|
38
|
+
host: string;
|
|
39
|
+
token: string | (() => string | Promise<string>);
|
|
40
|
+
/** Volume path that all writes are scoped under. */
|
|
41
|
+
volumePath: string;
|
|
42
|
+
fetchImpl?: typeof fetch;
|
|
43
|
+
}
|
|
44
|
+
export interface DatabricksVolumeWriter {
|
|
45
|
+
put(name: string, content: string | Uint8Array, options?: {
|
|
46
|
+
overwrite?: boolean;
|
|
47
|
+
}): Promise<{
|
|
48
|
+
path: string;
|
|
49
|
+
}>;
|
|
50
|
+
delete(name: string): Promise<void>;
|
|
51
|
+
}
|
|
52
|
+
export declare function databricksVolumeWriter(options: DatabricksVolumeWriterOptions): DatabricksVolumeWriter;
|
|
53
|
+
//# sourceMappingURL=databricks-volume.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"databricks-volume.d.ts","sourceRoot":"","sources":["../src/databricks-volume.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmB,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE7E;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,6BAA6B;IAC5C,6EAA6E;IAC7E,IAAI,EAAE,MAAM,CAAC;IACb,+EAA+E;IAC/E,KAAK,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IACjD,0EAA0E;IAC1E,UAAU,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IACpC,wCAAwC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAeD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,6BAA6B,GAAG,gBAAgB,CAS/F;AAiCD,MAAM,WAAW,6BAA6B;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IACjD,oDAAoD;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAED,MAAM,WAAW,sBAAsB;IACrC,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9G,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,6BAA6B,GAAG,sBAAsB,CAgBrG"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
export function databricksVolumeSource(options) {
|
|
2
|
+
const include = options.include ?? (() => true);
|
|
3
|
+
const root = normalizeVolumePath(options.volumePath);
|
|
4
|
+
return {
|
|
5
|
+
name: options.name ?? `databricks-volume:${root}`,
|
|
6
|
+
async *entries() {
|
|
7
|
+
yield* walkVolume(options, root, root, include);
|
|
8
|
+
},
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
async function* walkVolume(options, root, dir, include) {
|
|
12
|
+
let pageToken;
|
|
13
|
+
do {
|
|
14
|
+
const params = new URLSearchParams();
|
|
15
|
+
if (options.pageSize)
|
|
16
|
+
params.set('page_size', String(options.pageSize));
|
|
17
|
+
if (pageToken)
|
|
18
|
+
params.set('page_token', pageToken);
|
|
19
|
+
const listing = await dbxRequest(options, 'GET', `/api/2.0/fs/directories${dir}`, params);
|
|
20
|
+
for (const entry of listing.contents ?? []) {
|
|
21
|
+
if (!entry.path)
|
|
22
|
+
continue;
|
|
23
|
+
if (entry.is_directory) {
|
|
24
|
+
yield* walkVolume(options, root, entry.path, include);
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
const relative = entry.path.startsWith(root) ? entry.path.slice(root.length).replace(/^\/+/, '') : entry.path.replace(/^\/+/, '');
|
|
28
|
+
if (!relative)
|
|
29
|
+
continue;
|
|
30
|
+
if (!include(relative))
|
|
31
|
+
continue;
|
|
32
|
+
const bytes = await dbxRequestBytes(options, 'GET', `/api/2.0/fs/files${entry.path}`);
|
|
33
|
+
yield {
|
|
34
|
+
path: relative,
|
|
35
|
+
content: bytes,
|
|
36
|
+
metadata: {
|
|
37
|
+
key: entry.path,
|
|
38
|
+
...(entry.file_size !== undefined ? { size: entry.file_size } : {}),
|
|
39
|
+
...(entry.modification_time !== undefined ? { lastModified: new Date(entry.modification_time).toISOString() } : {}),
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
pageToken = listing.next_page_token;
|
|
44
|
+
} while (pageToken);
|
|
45
|
+
}
|
|
46
|
+
export function databricksVolumeWriter(options) {
|
|
47
|
+
const root = normalizeVolumePath(options.volumePath);
|
|
48
|
+
return {
|
|
49
|
+
async put(name, content, putOptions) {
|
|
50
|
+
const path = `${root}/${name.replace(/^\/+/, '')}`;
|
|
51
|
+
const params = new URLSearchParams();
|
|
52
|
+
if (putOptions?.overwrite)
|
|
53
|
+
params.set('overwrite', 'true');
|
|
54
|
+
const body = typeof content === 'string' ? new TextEncoder().encode(content) : content;
|
|
55
|
+
await dbxRequest(options, 'PUT', `/api/2.0/fs/files${path}`, params, body);
|
|
56
|
+
return { path };
|
|
57
|
+
},
|
|
58
|
+
async delete(name) {
|
|
59
|
+
const path = `${root}/${name.replace(/^\/+/, '')}`;
|
|
60
|
+
await dbxRequest(options, 'DELETE', `/api/2.0/fs/files${path}`);
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function normalizeVolumePath(volumePath) {
|
|
65
|
+
if (!volumePath.startsWith('/Volumes/')) {
|
|
66
|
+
throw new Error(`databricks-volume: volumePath must start with /Volumes/, got: ${volumePath}`);
|
|
67
|
+
}
|
|
68
|
+
return volumePath.replace(/\/+$/, '');
|
|
69
|
+
}
|
|
70
|
+
async function dbxRequest(options, method, path, params, body) {
|
|
71
|
+
const fetchImpl = options.fetchImpl ?? fetch;
|
|
72
|
+
const token = typeof options.token === 'function' ? await options.token() : options.token;
|
|
73
|
+
const url = new URL(`${options.host.replace(/\/$/, '')}${path}`);
|
|
74
|
+
if (params)
|
|
75
|
+
for (const [key, value] of params)
|
|
76
|
+
url.searchParams.set(key, value);
|
|
77
|
+
const headers = { authorization: `Bearer ${token}` };
|
|
78
|
+
const init = { method, headers };
|
|
79
|
+
if (body !== undefined) {
|
|
80
|
+
init.body = body;
|
|
81
|
+
if (typeof body !== 'string')
|
|
82
|
+
headers['content-type'] = 'application/octet-stream';
|
|
83
|
+
}
|
|
84
|
+
const response = await fetchImpl(url, init);
|
|
85
|
+
if (!response.ok) {
|
|
86
|
+
const text = await response.text();
|
|
87
|
+
throw new Error(`databricks-volume: ${method} ${path} -> ${response.status} ${response.statusText}: ${text.slice(0, 500)}`);
|
|
88
|
+
}
|
|
89
|
+
if (response.status === 204)
|
|
90
|
+
return undefined;
|
|
91
|
+
const contentType = response.headers.get('content-type') ?? '';
|
|
92
|
+
if (contentType.includes('application/json'))
|
|
93
|
+
return await response.json();
|
|
94
|
+
return undefined;
|
|
95
|
+
}
|
|
96
|
+
async function dbxRequestBytes(options, method, path) {
|
|
97
|
+
const fetchImpl = options.fetchImpl ?? fetch;
|
|
98
|
+
const token = typeof options.token === 'function' ? await options.token() : options.token;
|
|
99
|
+
const url = new URL(`${options.host.replace(/\/$/, '')}${path}`);
|
|
100
|
+
const response = await fetchImpl(url, { method, headers: { authorization: `Bearer ${token}` } });
|
|
101
|
+
if (!response.ok) {
|
|
102
|
+
const text = await response.text();
|
|
103
|
+
throw new Error(`databricks-volume: ${method} ${path} -> ${response.status} ${response.statusText}: ${text.slice(0, 500)}`);
|
|
104
|
+
}
|
|
105
|
+
return new Uint8Array(await response.arrayBuffer());
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=databricks-volume.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"databricks-volume.js","sourceRoot":"","sources":["../src/databricks-volume.ts"],"names":[],"mappings":"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"}
|
package/dist/gcs.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { FilesystemSource } from '@fabric-harness/sdk';
|
|
2
|
+
/**
|
|
3
|
+
* Concrete Google Cloud Storage connector backed by `@google-cloud/storage`.
|
|
4
|
+
*
|
|
5
|
+
* Install peer dep:
|
|
6
|
+
* ```sh
|
|
7
|
+
* npm install @google-cloud/storage
|
|
8
|
+
* ```
|
|
9
|
+
*/
|
|
10
|
+
export interface GcsSourceOptions {
|
|
11
|
+
bucket: string;
|
|
12
|
+
prefix?: string;
|
|
13
|
+
stripPrefix?: string;
|
|
14
|
+
include?: (name: string) => boolean;
|
|
15
|
+
name?: string;
|
|
16
|
+
/** GCP project id. Falls back to ADC. */
|
|
17
|
+
projectId?: string;
|
|
18
|
+
/** Path to service account key JSON. */
|
|
19
|
+
keyFilename?: string;
|
|
20
|
+
/** Pre-built `Storage` instance. Overrides projectId/keyFilename. */
|
|
21
|
+
client?: unknown;
|
|
22
|
+
}
|
|
23
|
+
export declare function gcsSource(options: GcsSourceOptions): FilesystemSource;
|
|
24
|
+
export interface GcsWriterOptions extends Omit<GcsSourceOptions, 'prefix' | 'stripPrefix' | 'include' | 'name'> {
|
|
25
|
+
prefix?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface GcsWriter {
|
|
28
|
+
put(name: string, content: string | Uint8Array, options?: {
|
|
29
|
+
contentType?: string;
|
|
30
|
+
metadata?: Record<string, string>;
|
|
31
|
+
}): Promise<{
|
|
32
|
+
name: string;
|
|
33
|
+
bucket: string;
|
|
34
|
+
}>;
|
|
35
|
+
delete(name: string): Promise<void>;
|
|
36
|
+
}
|
|
37
|
+
export declare function gcsWriter(options: GcsWriterOptions): GcsWriter;
|
|
38
|
+
//# sourceMappingURL=gcs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gcs.d.ts","sourceRoot":"","sources":["../src/gcs.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAmB,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAI7E;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IACpC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qEAAqE;IACrE,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAWD,wBAAgB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,gBAAgB,CA+BrE;AAED,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAAC,gBAAgB,EAAE,QAAQ,GAAG,aAAa,GAAG,SAAS,GAAG,MAAM,CAAC;IAC7G,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,OAAO,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClK,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,SAAS,CAkB9D"}
|
package/dist/gcs.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
const requireFromHere = createRequire(import.meta.url);
|
|
3
|
+
export function gcsSource(options) {
|
|
4
|
+
const bucket = createBucket(options);
|
|
5
|
+
const prefix = options.prefix ?? '';
|
|
6
|
+
const stripPrefix = options.stripPrefix ?? prefix;
|
|
7
|
+
const include = options.include ?? (() => true);
|
|
8
|
+
return {
|
|
9
|
+
name: options.name ?? `gcs:${options.bucket}/${prefix}`,
|
|
10
|
+
async *entries() {
|
|
11
|
+
let pageToken;
|
|
12
|
+
do {
|
|
13
|
+
const [files, query] = await bucket.getFiles({ ...(prefix ? { prefix } : {}), ...(pageToken ? { pageToken } : {}) });
|
|
14
|
+
for (const file of files) {
|
|
15
|
+
if (!include(file.name))
|
|
16
|
+
continue;
|
|
17
|
+
const relative = file.name.startsWith(stripPrefix) ? file.name.slice(stripPrefix.length) : file.name;
|
|
18
|
+
if (!relative)
|
|
19
|
+
continue;
|
|
20
|
+
const [buffer] = await file.download();
|
|
21
|
+
yield {
|
|
22
|
+
path: relative.replace(/^\/+/, ''),
|
|
23
|
+
content: new Uint8Array(buffer),
|
|
24
|
+
metadata: {
|
|
25
|
+
key: file.name,
|
|
26
|
+
...(file.metadata?.size !== undefined ? { size: Number(file.metadata.size) } : {}),
|
|
27
|
+
...(file.metadata?.contentType ? { contentType: file.metadata.contentType } : {}),
|
|
28
|
+
...(file.metadata?.updated ? { lastModified: file.metadata.updated } : {}),
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
pageToken = query?.pageToken;
|
|
33
|
+
} while (pageToken);
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
export function gcsWriter(options) {
|
|
38
|
+
const bucket = createBucket(options);
|
|
39
|
+
const prefix = options.prefix ?? '';
|
|
40
|
+
const fullName = (name) => `${prefix}${name.replace(/^\/+/, '')}`;
|
|
41
|
+
return {
|
|
42
|
+
async put(name, content, putOptions) {
|
|
43
|
+
const file = bucket.file(fullName(name));
|
|
44
|
+
const data = typeof content === 'string' ? new TextEncoder().encode(content) : content;
|
|
45
|
+
const saveOptions = {};
|
|
46
|
+
if (putOptions?.contentType)
|
|
47
|
+
saveOptions.contentType = putOptions.contentType;
|
|
48
|
+
if (putOptions?.metadata)
|
|
49
|
+
saveOptions.metadata = { metadata: putOptions.metadata };
|
|
50
|
+
await file.save(data, saveOptions);
|
|
51
|
+
return { name: fullName(name), bucket: options.bucket };
|
|
52
|
+
},
|
|
53
|
+
async delete(name) {
|
|
54
|
+
await bucket.file(fullName(name)).delete();
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
function createBucket(options) {
|
|
59
|
+
if (options.client) {
|
|
60
|
+
const client = options.client;
|
|
61
|
+
if (typeof client.bucket !== 'function')
|
|
62
|
+
throw new Error('gcsSource: provided `client` does not implement bucket(name).');
|
|
63
|
+
return client.bucket(options.bucket);
|
|
64
|
+
}
|
|
65
|
+
const mod = loadGcsModule();
|
|
66
|
+
const config = {};
|
|
67
|
+
if (options.projectId)
|
|
68
|
+
config.projectId = options.projectId;
|
|
69
|
+
if (options.keyFilename)
|
|
70
|
+
config.keyFilename = options.keyFilename;
|
|
71
|
+
return new mod.Storage(config).bucket(options.bucket);
|
|
72
|
+
}
|
|
73
|
+
let cachedModule;
|
|
74
|
+
function loadGcsModule() {
|
|
75
|
+
if (cachedModule)
|
|
76
|
+
return cachedModule;
|
|
77
|
+
try {
|
|
78
|
+
const mod = requireFromHere('@google-cloud/storage');
|
|
79
|
+
cachedModule = mod;
|
|
80
|
+
return mod;
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
throw new Error('gcsSource/gcsWriter requires the `@google-cloud/storage` peer dependency. Install it with: npm install @google-cloud/storage');
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=gcs.js.map
|
package/dist/gcs.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gcs.js","sourceRoot":"","sources":["../src/gcs.ts"],"names":[],"mappings":"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"}
|
package/dist/github.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { FilesystemSource } from '@fabric-harness/sdk';
|
|
2
|
+
/**
|
|
3
|
+
* Read-only GitHub repository connector backed by `octokit`.
|
|
4
|
+
*
|
|
5
|
+
* Mounts a repository (at a given ref) as files inside the sandbox.
|
|
6
|
+
* Uses the Git Trees API in recursive mode for efficient enumeration.
|
|
7
|
+
*
|
|
8
|
+
* Install peer dep:
|
|
9
|
+
* ```sh
|
|
10
|
+
* npm install octokit
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
export interface GithubSourceOptions {
|
|
14
|
+
owner: string;
|
|
15
|
+
repo: string;
|
|
16
|
+
/** Branch name, tag, or commit SHA. Defaults to the repo's default branch. */
|
|
17
|
+
ref?: string;
|
|
18
|
+
/** Path within the repo to mount. Defaults to repo root. */
|
|
19
|
+
path?: string;
|
|
20
|
+
/** Filter applied to each repo-relative path. */
|
|
21
|
+
include?: (path: string) => boolean;
|
|
22
|
+
/** Stable name for telemetry / logs. */
|
|
23
|
+
name?: string;
|
|
24
|
+
/** Personal access token. Falls back to `GITHUB_TOKEN` env. */
|
|
25
|
+
token?: string;
|
|
26
|
+
/** Pre-built Octokit instance. Overrides `token`. */
|
|
27
|
+
client?: unknown;
|
|
28
|
+
}
|
|
29
|
+
export declare function githubSource(options: GithubSourceOptions): FilesystemSource;
|
|
30
|
+
//# sourceMappingURL=github.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../src/github.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAmB,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAI7E;;;;;;;;;;GAUG;AACH,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IACpC,wCAAwC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAMD,wBAAgB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,gBAAgB,CA2C3E"}
|
package/dist/github.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
const requireFromHere = createRequire(import.meta.url);
|
|
3
|
+
export function githubSource(options) {
|
|
4
|
+
const octokit = createOctokit(options);
|
|
5
|
+
const include = options.include ?? (() => true);
|
|
6
|
+
const subpath = (options.path ?? '').replace(/^\/+|\/+$/g, '');
|
|
7
|
+
const ref = options.ref;
|
|
8
|
+
return {
|
|
9
|
+
name: options.name ?? `github:${options.owner}/${options.repo}@${ref ?? 'default'}/${subpath}`,
|
|
10
|
+
async *entries() {
|
|
11
|
+
const resolvedSha = await resolveTreeSha(octokit, options.owner, options.repo, ref);
|
|
12
|
+
const treeResponse = await octokit.request('GET /repos/{owner}/{repo}/git/trees/{tree_sha}', {
|
|
13
|
+
owner: options.owner,
|
|
14
|
+
repo: options.repo,
|
|
15
|
+
tree_sha: resolvedSha,
|
|
16
|
+
recursive: '1',
|
|
17
|
+
});
|
|
18
|
+
const tree = treeResponse.data.tree ?? [];
|
|
19
|
+
for (const entry of tree) {
|
|
20
|
+
if (entry.type !== 'blob' || !entry.path || !entry.sha)
|
|
21
|
+
continue;
|
|
22
|
+
if (subpath && !entry.path.startsWith(`${subpath}/`) && entry.path !== subpath)
|
|
23
|
+
continue;
|
|
24
|
+
const relative = subpath ? entry.path.slice(subpath.length).replace(/^\/+/, '') : entry.path;
|
|
25
|
+
if (!relative)
|
|
26
|
+
continue;
|
|
27
|
+
if (!include(relative))
|
|
28
|
+
continue;
|
|
29
|
+
const blob = await octokit.request('GET /repos/{owner}/{repo}/git/blobs/{file_sha}', {
|
|
30
|
+
owner: options.owner,
|
|
31
|
+
repo: options.repo,
|
|
32
|
+
file_sha: entry.sha,
|
|
33
|
+
});
|
|
34
|
+
const data = blob.data;
|
|
35
|
+
if (typeof data.content !== 'string')
|
|
36
|
+
continue;
|
|
37
|
+
const content = data.encoding === 'base64' ? new Uint8Array(Buffer.from(data.content, 'base64')) : new TextEncoder().encode(data.content);
|
|
38
|
+
yield {
|
|
39
|
+
path: relative,
|
|
40
|
+
content,
|
|
41
|
+
metadata: {
|
|
42
|
+
key: entry.path,
|
|
43
|
+
sha: entry.sha,
|
|
44
|
+
...(entry.size !== undefined ? { size: entry.size } : {}),
|
|
45
|
+
...(ref ? { ref } : {}),
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
async function resolveTreeSha(octokit, owner, repo, ref) {
|
|
53
|
+
if (ref && /^[0-9a-f]{40}$/i.test(ref))
|
|
54
|
+
return ref;
|
|
55
|
+
const branch = ref ?? await defaultBranch(octokit, owner, repo);
|
|
56
|
+
const refResponse = await octokit.request('GET /repos/{owner}/{repo}/commits/{ref}', { owner, repo, ref: branch });
|
|
57
|
+
const sha = refResponse.data.commit?.tree?.sha;
|
|
58
|
+
if (!sha)
|
|
59
|
+
throw new Error(`githubSource: could not resolve tree sha for ${owner}/${repo}@${branch}`);
|
|
60
|
+
return sha;
|
|
61
|
+
}
|
|
62
|
+
async function defaultBranch(octokit, owner, repo) {
|
|
63
|
+
const response = await octokit.request('GET /repos/{owner}/{repo}', { owner, repo });
|
|
64
|
+
const branch = response.data.default_branch;
|
|
65
|
+
if (!branch)
|
|
66
|
+
throw new Error(`githubSource: ${owner}/${repo} has no default_branch`);
|
|
67
|
+
return branch;
|
|
68
|
+
}
|
|
69
|
+
function createOctokit(options) {
|
|
70
|
+
if (options.client) {
|
|
71
|
+
const client = options.client;
|
|
72
|
+
if (typeof client.request !== 'function')
|
|
73
|
+
throw new Error('githubSource: provided `client` does not implement request().');
|
|
74
|
+
return client;
|
|
75
|
+
}
|
|
76
|
+
const mod = loadOctokitModule();
|
|
77
|
+
const token = options.token ?? process.env.GITHUB_TOKEN;
|
|
78
|
+
return new mod.Octokit(token ? { auth: token } : {});
|
|
79
|
+
}
|
|
80
|
+
let cachedModule;
|
|
81
|
+
function loadOctokitModule() {
|
|
82
|
+
if (cachedModule)
|
|
83
|
+
return cachedModule;
|
|
84
|
+
try {
|
|
85
|
+
const mod = requireFromHere('octokit');
|
|
86
|
+
cachedModule = mod;
|
|
87
|
+
return mod;
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
try {
|
|
91
|
+
const rest = requireFromHere('@octokit/rest');
|
|
92
|
+
cachedModule = rest;
|
|
93
|
+
return rest;
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
throw new Error('githubSource requires the `octokit` (or `@octokit/rest`) peer dependency. Install it with: npm install octokit');
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=github.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.js","sourceRoot":"","sources":["../src/github.ts"],"names":[],"mappings":"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"}
|
package/dist/k8s.d.ts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { FileStat, SandboxEnv } from '@fabric-harness/sdk';
|
|
2
|
+
import type { RemoteAdapterOptions } from './index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Structural Kubernetes pod adapter. The caller wires up
|
|
5
|
+
* `@kubernetes/client-node` (or any SPDY/exec-capable client) and supplies
|
|
6
|
+
* an object that satisfies `KubernetesPodLike`.
|
|
7
|
+
*
|
|
8
|
+
* Why structural: cluster auth, RBAC, and the exec wire format vary too
|
|
9
|
+
* much across environments (in-cluster, kubeconfig, AKS managed identity,
|
|
10
|
+
* GKE Workload Identity, EKS IRSA, …) for a single concrete adapter to be
|
|
11
|
+
* sensible. Pattern matches `daytonaSandbox` / `e2bSandbox`.
|
|
12
|
+
*
|
|
13
|
+
* For Azure-hosted clusters use the higher-level `aksSandbox()` from
|
|
14
|
+
* `@fabric-harness/azure`, which wires this adapter to Azure-managed
|
|
15
|
+
* credentials.
|
|
16
|
+
*/
|
|
17
|
+
export interface KubernetesPodLike {
|
|
18
|
+
/** Run a shell command inside the pod. */
|
|
19
|
+
exec(command: string, options?: {
|
|
20
|
+
cwd?: string;
|
|
21
|
+
env?: Record<string, string>;
|
|
22
|
+
timeoutMs?: number;
|
|
23
|
+
}): Promise<{
|
|
24
|
+
stdout?: string;
|
|
25
|
+
stderr?: string;
|
|
26
|
+
exitCode?: number;
|
|
27
|
+
}>;
|
|
28
|
+
/** Read a file's bytes. May implement via `kubectl cp` or `cat`+base64. */
|
|
29
|
+
readFile(path: string): Promise<Uint8Array>;
|
|
30
|
+
/** Write content to a file. */
|
|
31
|
+
writeFile(path: string, content: Uint8Array): Promise<void>;
|
|
32
|
+
/** Optional: implement stat (default falls back to `stat -c` via exec). */
|
|
33
|
+
stat?(path: string): Promise<FileStat | null>;
|
|
34
|
+
/** Optional: delete the pod when the sandbox is cleaned up. */
|
|
35
|
+
delete?(): Promise<void> | void;
|
|
36
|
+
}
|
|
37
|
+
export interface KubernetesSandboxOptions extends RemoteAdapterOptions {
|
|
38
|
+
/** Working directory inside the pod. Defaults to `/workspace`. */
|
|
39
|
+
cwd?: string;
|
|
40
|
+
}
|
|
41
|
+
export declare function kubernetesSandbox(pod: KubernetesPodLike, options?: KubernetesSandboxOptions): SandboxEnv;
|
|
42
|
+
/**
|
|
43
|
+
* Convenience helper: build a `KubernetesPodLike` from a `@kubernetes/client-node`
|
|
44
|
+
* `KubeConfig` plus pod identity. Suitable when `kubectl` already gets you in
|
|
45
|
+
* the door — for AKS, prefer `aksSandbox()` from `@fabric-harness/azure`.
|
|
46
|
+
*
|
|
47
|
+
* Files are transferred over `exec` using base64-encoded `cat` / `tee`. Works
|
|
48
|
+
* for text and small binaries; for large objects mount external storage via
|
|
49
|
+
* `s3Source` / `gcsSource` / `azureBlobSource` instead.
|
|
50
|
+
*/
|
|
51
|
+
export interface CreateKubernetesPodOptions {
|
|
52
|
+
/** A `KubeConfig` instance from `@kubernetes/client-node`. */
|
|
53
|
+
kubeConfig: unknown;
|
|
54
|
+
namespace: string;
|
|
55
|
+
podName: string;
|
|
56
|
+
/** Container name inside the pod. Defaults to the first container. */
|
|
57
|
+
container?: string;
|
|
58
|
+
/** If true, delete the pod when `cleanup()` runs. */
|
|
59
|
+
ownsPod?: boolean;
|
|
60
|
+
}
|
|
61
|
+
export declare function createKubernetesPod(options: CreateKubernetesPodOptions): KubernetesPodLike;
|
|
62
|
+
//# sourceMappingURL=k8s.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"k8s.d.ts","sourceRoot":"","sources":["../src/k8s.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAoB,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAClF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAIvD;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,iBAAiB;IAChC,0CAA0C;IAC1C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACtK,2EAA2E;IAC3E,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAC5C,+BAA+B;IAC/B,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,2EAA2E;IAC3E,IAAI,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IAC9C,+DAA+D;IAC/D,MAAM,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,wBAAyB,SAAQ,oBAAoB;IACpE,kEAAkE;IAClE,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,iBAAiB,EAAE,OAAO,GAAE,wBAA6B,GAAG,UAAU,CAmE5G;AAMD;;;;;;;;GAQG;AACH,MAAM,WAAW,0BAA0B;IACzC,8DAA8D;IAC9D,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,0BAA0B,GAAG,iBAAiB,CAsD1F"}
|
package/dist/k8s.js
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
import { createRemoteSandboxEnv } from '@fabric-harness/sdk';
|
|
3
|
+
const requireFromHere = createRequire(import.meta.url);
|
|
4
|
+
export function kubernetesSandbox(pod, options = {}) {
|
|
5
|
+
const api = {
|
|
6
|
+
async exec(command, execOptions) {
|
|
7
|
+
const runOptions = {};
|
|
8
|
+
if (execOptions?.cwd !== undefined)
|
|
9
|
+
runOptions.cwd = execOptions.cwd;
|
|
10
|
+
if (execOptions?.env !== undefined)
|
|
11
|
+
runOptions.env = execOptions.env;
|
|
12
|
+
if (execOptions?.timeout !== undefined)
|
|
13
|
+
runOptions.timeoutMs = execOptions.timeout;
|
|
14
|
+
const result = await pod.exec(command, runOptions);
|
|
15
|
+
return { command, exitCode: result.exitCode ?? 0, stdout: result.stdout ?? '', stderr: result.stderr ?? '' };
|
|
16
|
+
},
|
|
17
|
+
async readFile(path) {
|
|
18
|
+
return new TextDecoder().decode(await pod.readFile(path));
|
|
19
|
+
},
|
|
20
|
+
async readFileBuffer(path) {
|
|
21
|
+
return pod.readFile(path);
|
|
22
|
+
},
|
|
23
|
+
async writeFile(path, content) {
|
|
24
|
+
const data = typeof content === 'string' ? new TextEncoder().encode(content) : content;
|
|
25
|
+
await pod.writeFile(path, data);
|
|
26
|
+
},
|
|
27
|
+
async stat(path) {
|
|
28
|
+
if (pod.stat) {
|
|
29
|
+
const result = await pod.stat(path);
|
|
30
|
+
if (result)
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
const result = await pod.exec(`stat -c '%F %s' ${shellQuote(path)} 2>/dev/null || echo MISSING`);
|
|
34
|
+
const stdout = (result.stdout ?? '').trim();
|
|
35
|
+
if (stdout === 'MISSING' || result.exitCode !== 0)
|
|
36
|
+
throw new Error(`No such file or directory: ${path}`);
|
|
37
|
+
const [type, sizeRaw] = stdout.split(' ');
|
|
38
|
+
const size = Number.parseInt(sizeRaw ?? '0', 10);
|
|
39
|
+
return {
|
|
40
|
+
type: type?.includes('directory') ? 'directory' : type?.includes('symbolic') ? 'symlink' : 'file',
|
|
41
|
+
size: Number.isFinite(size) ? size : 0,
|
|
42
|
+
};
|
|
43
|
+
},
|
|
44
|
+
async readdir(path) {
|
|
45
|
+
const result = await pod.exec(`ls -1 ${shellQuote(path)}`);
|
|
46
|
+
if (result.exitCode !== 0)
|
|
47
|
+
throw new Error(result.stderr ?? `readdir failed: ${path}`);
|
|
48
|
+
return (result.stdout ?? '').split('\n').filter((line) => line.length > 0);
|
|
49
|
+
},
|
|
50
|
+
async exists(path) {
|
|
51
|
+
const result = await pod.exec(`test -e ${shellQuote(path)}`);
|
|
52
|
+
return result.exitCode === 0;
|
|
53
|
+
},
|
|
54
|
+
async mkdir(path, mkdirOptions) {
|
|
55
|
+
const flag = mkdirOptions?.recursive ? '-p' : '';
|
|
56
|
+
const result = await pod.exec(`mkdir ${flag} ${shellQuote(path)}`.trim());
|
|
57
|
+
if (result.exitCode !== 0)
|
|
58
|
+
throw new Error(result.stderr ?? `mkdir failed: ${path}`);
|
|
59
|
+
},
|
|
60
|
+
async rm(path, rmOptions) {
|
|
61
|
+
const flagChars = `${rmOptions?.recursive ? 'r' : ''}${rmOptions?.force ? 'f' : ''}`;
|
|
62
|
+
const flag = flagChars ? `-${flagChars} ` : '';
|
|
63
|
+
const result = await pod.exec(`rm ${flag}${shellQuote(path)}`.replace(/\s+/g, ' '));
|
|
64
|
+
if (result.exitCode !== 0 && !rmOptions?.force)
|
|
65
|
+
throw new Error(result.stderr ?? `rm failed: ${path}`);
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
const podDelete = pod.delete;
|
|
69
|
+
const cleanup = options.cleanup === true && podDelete
|
|
70
|
+
? async () => { await podDelete.call(pod); }
|
|
71
|
+
: typeof options.cleanup === 'function'
|
|
72
|
+
? async () => { await options.cleanup(); }
|
|
73
|
+
: undefined;
|
|
74
|
+
return createRemoteSandboxEnv(api, {
|
|
75
|
+
cwd: options.cwd ?? '/workspace',
|
|
76
|
+
...(options.capabilities ? { capabilities: options.capabilities } : {}),
|
|
77
|
+
...(cleanup ? { cleanup } : {}),
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
function shellQuote(value) {
|
|
81
|
+
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
82
|
+
}
|
|
83
|
+
export function createKubernetesPod(options) {
|
|
84
|
+
const { Exec, CoreV1Api } = loadK8sModule();
|
|
85
|
+
const kc = options.kubeConfig;
|
|
86
|
+
const exec = new Exec(kc);
|
|
87
|
+
const core = kc.makeApiClient(CoreV1Api);
|
|
88
|
+
async function runExec(command) {
|
|
89
|
+
let stdout = '';
|
|
90
|
+
let stderr = '';
|
|
91
|
+
const stdoutStream = makeWritable((chunk) => { stdout += chunk.toString('utf8'); });
|
|
92
|
+
const stderrStream = makeWritable((chunk) => { stderr += chunk.toString('utf8'); });
|
|
93
|
+
const status = await new Promise((resolve, reject) => {
|
|
94
|
+
void exec.exec(options.namespace, options.podName, options.container ?? '', command, stdoutStream, stderrStream, null, false, (s) => resolve(s)).catch(reject);
|
|
95
|
+
});
|
|
96
|
+
const exitCode = status?.status === 'Success' ? 0 : (status?.code ?? 1);
|
|
97
|
+
return { stdout, stderr, exitCode };
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
async exec(command, runOptions) {
|
|
101
|
+
const wrapped = runOptions?.cwd
|
|
102
|
+
? `cd ${shellQuote(runOptions.cwd)} && ${envPrefix(runOptions.env)}${command}`
|
|
103
|
+
: `${envPrefix(runOptions?.env)}${command}`;
|
|
104
|
+
return runExec(['sh', '-c', wrapped]);
|
|
105
|
+
},
|
|
106
|
+
async readFile(path) {
|
|
107
|
+
const { stdout, exitCode, stderr } = await runExec(['sh', '-c', `base64 -w0 ${shellQuote(path)} 2>/dev/null || base64 ${shellQuote(path)}`]);
|
|
108
|
+
if (exitCode !== 0)
|
|
109
|
+
throw new Error(stderr || `readFile failed: ${path}`);
|
|
110
|
+
return new Uint8Array(Buffer.from(stdout.trim(), 'base64'));
|
|
111
|
+
},
|
|
112
|
+
async writeFile(path, content) {
|
|
113
|
+
const encoded = Buffer.from(content).toString('base64');
|
|
114
|
+
const { exitCode, stderr } = await runExec(['sh', '-c', `mkdir -p "$(dirname ${shellQuote(path)})" && printf '%s' ${shellQuote(encoded)} | base64 -d > ${shellQuote(path)}`]);
|
|
115
|
+
if (exitCode !== 0)
|
|
116
|
+
throw new Error(stderr || `writeFile failed: ${path}`);
|
|
117
|
+
},
|
|
118
|
+
async delete() {
|
|
119
|
+
if (!options.ownsPod)
|
|
120
|
+
return;
|
|
121
|
+
try {
|
|
122
|
+
await core.deleteNamespacedPod(options.podName, options.namespace);
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
/* best-effort cleanup */
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
function envPrefix(env) {
|
|
131
|
+
if (!env)
|
|
132
|
+
return '';
|
|
133
|
+
return Object.entries(env).map(([k, v]) => `${k}=${shellQuote(v)} `).join('');
|
|
134
|
+
}
|
|
135
|
+
function makeWritable(onChunk) {
|
|
136
|
+
return {
|
|
137
|
+
write(chunk) { onChunk(typeof chunk === 'string' ? Buffer.from(chunk) : chunk); return true; },
|
|
138
|
+
end() { },
|
|
139
|
+
on() { },
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
let cachedK8sModule;
|
|
143
|
+
function loadK8sModule() {
|
|
144
|
+
if (cachedK8sModule)
|
|
145
|
+
return cachedK8sModule;
|
|
146
|
+
try {
|
|
147
|
+
const mod = requireFromHere('@kubernetes/client-node');
|
|
148
|
+
cachedK8sModule = mod;
|
|
149
|
+
return mod;
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
throw new Error('createKubernetesPod requires the `@kubernetes/client-node` peer dependency. Install it with: npm install @kubernetes/client-node');
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=k8s.js.map
|
package/dist/k8s.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"k8s.js","sourceRoot":"","sources":["../src/k8s.ts"],"names":[],"mappings":"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"}
|
package/dist/s3.d.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { FilesystemSource } from '@fabric-harness/sdk';
|
|
2
|
+
/**
|
|
3
|
+
* Concrete S3 connector backed by `@aws-sdk/client-s3`. Users pass bucket
|
|
4
|
+
* config; this module constructs the SDK client internally and adapts it to
|
|
5
|
+
* Fabric Harness's `FilesystemSource` contract.
|
|
6
|
+
*
|
|
7
|
+
* Install peer dep:
|
|
8
|
+
* ```sh
|
|
9
|
+
* npm install @aws-sdk/client-s3
|
|
10
|
+
* ```
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* ```ts
|
|
14
|
+
* import { s3Source } from '@fabric-harness/connectors/s3';
|
|
15
|
+
*
|
|
16
|
+
* const source = s3Source({ bucket: 'my-logs', prefix: '2026/' });
|
|
17
|
+
* await session.mount('/mnt/logs', source);
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export interface S3SourceOptions {
|
|
21
|
+
/** Bucket name. Required. */
|
|
22
|
+
bucket: string;
|
|
23
|
+
/** Optional key prefix to scope listing. */
|
|
24
|
+
prefix?: string;
|
|
25
|
+
/** Override prefix-stripping behavior in mounted paths. Defaults to `prefix`. */
|
|
26
|
+
stripPrefix?: string;
|
|
27
|
+
/** Filter applied to each listed key. Return false to skip. */
|
|
28
|
+
include?: (key: string) => boolean;
|
|
29
|
+
/** Page size for ListObjectsV2 (defaults to AWS SDK default). */
|
|
30
|
+
pageSize?: number;
|
|
31
|
+
/** Stable name for telemetry / logs. */
|
|
32
|
+
name?: string;
|
|
33
|
+
/** AWS region. Falls back to AWS SDK default chain. */
|
|
34
|
+
region?: string;
|
|
35
|
+
/** Custom endpoint (e.g. for LocalStack, MinIO, s3mock). */
|
|
36
|
+
endpoint?: string;
|
|
37
|
+
/** Force path-style addressing. Required for most S3-compatible services. */
|
|
38
|
+
forcePathStyle?: boolean;
|
|
39
|
+
/** Static credentials. Falls back to AWS SDK default credential chain. */
|
|
40
|
+
credentials?: {
|
|
41
|
+
accessKeyId: string;
|
|
42
|
+
secretAccessKey: string;
|
|
43
|
+
sessionToken?: string;
|
|
44
|
+
};
|
|
45
|
+
/** Pre-built S3Client. Overrides region/endpoint/credentials when provided. */
|
|
46
|
+
client?: unknown;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Read-only S3 connector. Mount with `session.mount(mountAt, s3Source(...))`.
|
|
50
|
+
*
|
|
51
|
+
* The agent's built-in `read`, `grep`, `glob`, and `bash` tools then operate
|
|
52
|
+
* over the mounted prefix as if it were a local directory.
|
|
53
|
+
*/
|
|
54
|
+
export declare function s3Source(options: S3SourceOptions): FilesystemSource;
|
|
55
|
+
/**
|
|
56
|
+
* Write-side helper for S3. Use to publish artifacts or mount a writable view.
|
|
57
|
+
*
|
|
58
|
+
* ```ts
|
|
59
|
+
* const writer = s3Writer({ bucket: 'reports' });
|
|
60
|
+
* await writer.put('2026/05/06/summary.md', summary);
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export interface S3WriterOptions extends Omit<S3SourceOptions, 'prefix' | 'stripPrefix' | 'include' | 'pageSize' | 'name'> {
|
|
64
|
+
/** Default prefix prepended to every put/delete key. */
|
|
65
|
+
prefix?: string;
|
|
66
|
+
}
|
|
67
|
+
export interface S3Writer {
|
|
68
|
+
put(key: string, content: string | Uint8Array, options?: {
|
|
69
|
+
contentType?: string;
|
|
70
|
+
metadata?: Record<string, string>;
|
|
71
|
+
}): Promise<{
|
|
72
|
+
key: string;
|
|
73
|
+
bucket: string;
|
|
74
|
+
}>;
|
|
75
|
+
delete(key: string): Promise<void>;
|
|
76
|
+
}
|
|
77
|
+
export declare function s3Writer(options: S3WriterOptions): S3Writer;
|
|
78
|
+
//# sourceMappingURL=s3.d.ts.map
|
package/dist/s3.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"s3.d.ts","sourceRoot":"","sources":["../src/s3.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAK5D;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,eAAe;IAC9B,6BAA6B;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,4CAA4C;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iFAAiF;IACjF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+DAA+D;IAC/D,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IACnC,iEAAiE;IACjE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wCAAwC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,0EAA0E;IAC1E,WAAW,CAAC,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACtF,+EAA+E;IAC/E,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAkBD;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,gBAAgB,CAyCnE;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAAC,eAAe,EAAE,QAAQ,GAAG,aAAa,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;IACxH,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,QAAQ;IACvB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,OAAO,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChK,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACpC;AAED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,QAAQ,CAmB3D"}
|
package/dist/s3.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
import { s3FilesystemSource } from './index.js';
|
|
3
|
+
const requireFromHere = createRequire(import.meta.url);
|
|
4
|
+
/**
|
|
5
|
+
* Read-only S3 connector. Mount with `session.mount(mountAt, s3Source(...))`.
|
|
6
|
+
*
|
|
7
|
+
* The agent's built-in `read`, `grep`, `glob`, and `bash` tools then operate
|
|
8
|
+
* over the mounted prefix as if it were a local directory.
|
|
9
|
+
*/
|
|
10
|
+
export function s3Source(options) {
|
|
11
|
+
const client = createS3Client(options);
|
|
12
|
+
return s3FilesystemSource({
|
|
13
|
+
async listObjects(listOpts) {
|
|
14
|
+
const input = { Bucket: options.bucket };
|
|
15
|
+
if (listOpts?.prefix)
|
|
16
|
+
input.Prefix = listOpts.prefix;
|
|
17
|
+
if (listOpts?.continuationToken)
|
|
18
|
+
input.ContinuationToken = listOpts.continuationToken;
|
|
19
|
+
if (listOpts?.maxKeys)
|
|
20
|
+
input.MaxKeys = listOpts.maxKeys;
|
|
21
|
+
const command = await buildCommand('ListObjectsV2Command', input);
|
|
22
|
+
const response = await client.send(command);
|
|
23
|
+
return {
|
|
24
|
+
objects: (response.Contents ?? [])
|
|
25
|
+
.filter((c) => typeof c.Key === 'string')
|
|
26
|
+
.map((c) => ({
|
|
27
|
+
key: c.Key,
|
|
28
|
+
...(c.Size !== undefined ? { size: c.Size } : {}),
|
|
29
|
+
...(c.LastModified !== undefined ? { lastModified: c.LastModified } : {}),
|
|
30
|
+
})),
|
|
31
|
+
...(response.NextContinuationToken ? { nextContinuationToken: response.NextContinuationToken } : {}),
|
|
32
|
+
};
|
|
33
|
+
},
|
|
34
|
+
async getObject(key) {
|
|
35
|
+
const command = await buildCommand('GetObjectCommand', { Bucket: options.bucket, Key: key });
|
|
36
|
+
const response = await client.send(command);
|
|
37
|
+
if (!response.Body)
|
|
38
|
+
return null;
|
|
39
|
+
return {
|
|
40
|
+
body: response.Body,
|
|
41
|
+
...(response.ContentType ? { contentType: response.ContentType } : {}),
|
|
42
|
+
...(response.Metadata ? { metadata: response.Metadata } : {}),
|
|
43
|
+
};
|
|
44
|
+
},
|
|
45
|
+
}, {
|
|
46
|
+
...(options.prefix !== undefined ? { prefix: options.prefix } : {}),
|
|
47
|
+
...(options.stripPrefix !== undefined ? { stripPrefix: options.stripPrefix } : {}),
|
|
48
|
+
...(options.include !== undefined ? { include: options.include } : {}),
|
|
49
|
+
...(options.pageSize !== undefined ? { pageSize: options.pageSize } : {}),
|
|
50
|
+
name: options.name ?? `s3:${options.bucket}/${options.prefix ?? ''}`,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
export function s3Writer(options) {
|
|
54
|
+
const client = createS3Client(options);
|
|
55
|
+
const prefix = options.prefix ?? '';
|
|
56
|
+
const fullKey = (key) => `${prefix}${key.replace(/^\/+/, '')}`;
|
|
57
|
+
return {
|
|
58
|
+
async put(key, content, putOptions) {
|
|
59
|
+
const Body = typeof content === 'string' ? new TextEncoder().encode(content) : content;
|
|
60
|
+
const input = { Bucket: options.bucket, Key: fullKey(key), Body };
|
|
61
|
+
if (putOptions?.contentType)
|
|
62
|
+
input.ContentType = putOptions.contentType;
|
|
63
|
+
if (putOptions?.metadata)
|
|
64
|
+
input.Metadata = putOptions.metadata;
|
|
65
|
+
const command = await buildCommand('PutObjectCommand', input);
|
|
66
|
+
await client.send(command);
|
|
67
|
+
return { key: fullKey(key), bucket: options.bucket };
|
|
68
|
+
},
|
|
69
|
+
async delete(key) {
|
|
70
|
+
const command = await buildCommand('DeleteObjectCommand', { Bucket: options.bucket, Key: fullKey(key) });
|
|
71
|
+
await client.send(command);
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function createS3Client(options) {
|
|
76
|
+
if (options.client) {
|
|
77
|
+
if (typeof options.client.send !== 'function') {
|
|
78
|
+
throw new Error('s3Source: provided `client` does not implement `send()`. Pass an `@aws-sdk/client-s3` `S3Client` instance.');
|
|
79
|
+
}
|
|
80
|
+
return options.client;
|
|
81
|
+
}
|
|
82
|
+
const { S3Client } = loadS3Module();
|
|
83
|
+
const config = {};
|
|
84
|
+
if (options.region)
|
|
85
|
+
config.region = options.region;
|
|
86
|
+
if (options.endpoint)
|
|
87
|
+
config.endpoint = options.endpoint;
|
|
88
|
+
if (options.forcePathStyle !== undefined)
|
|
89
|
+
config.forcePathStyle = options.forcePathStyle;
|
|
90
|
+
if (options.credentials)
|
|
91
|
+
config.credentials = options.credentials;
|
|
92
|
+
return new S3Client(config);
|
|
93
|
+
}
|
|
94
|
+
async function buildCommand(name, input) {
|
|
95
|
+
const mod = loadS3Module();
|
|
96
|
+
const Ctor = mod[name];
|
|
97
|
+
if (!Ctor)
|
|
98
|
+
throw new Error(`s3Source: @aws-sdk/client-s3 is missing ${name}. Update the peer dependency.`);
|
|
99
|
+
return new Ctor(input);
|
|
100
|
+
}
|
|
101
|
+
let cachedS3Module;
|
|
102
|
+
function loadS3Module() {
|
|
103
|
+
if (cachedS3Module)
|
|
104
|
+
return cachedS3Module;
|
|
105
|
+
try {
|
|
106
|
+
const mod = requireFromHere('@aws-sdk/client-s3');
|
|
107
|
+
cachedS3Module = mod;
|
|
108
|
+
return mod;
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
throw new Error('s3Source/s3Writer requires the `@aws-sdk/client-s3` peer dependency. Install it with: npm install @aws-sdk/client-s3');
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=s3.js.map
|
package/dist/s3.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"s3.js","sourceRoot":"","sources":["../src/s3.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fabric-harness/connectors",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Connector recipes (sandbox, mcp, data) for Fabric Harness — markdown-based provider integrations.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Fabric",
|
|
@@ -31,15 +31,74 @@
|
|
|
31
31
|
},
|
|
32
32
|
"main": "dist/index.js",
|
|
33
33
|
"types": "dist/index.d.ts",
|
|
34
|
+
"exports": {
|
|
35
|
+
".": {
|
|
36
|
+
"types": "./dist/index.d.ts",
|
|
37
|
+
"import": "./dist/index.js"
|
|
38
|
+
},
|
|
39
|
+
"./s3": {
|
|
40
|
+
"types": "./dist/s3.d.ts",
|
|
41
|
+
"import": "./dist/s3.js"
|
|
42
|
+
},
|
|
43
|
+
"./azure-blob": {
|
|
44
|
+
"types": "./dist/azure-blob.d.ts",
|
|
45
|
+
"import": "./dist/azure-blob.js"
|
|
46
|
+
},
|
|
47
|
+
"./gcs": {
|
|
48
|
+
"types": "./dist/gcs.d.ts",
|
|
49
|
+
"import": "./dist/gcs.js"
|
|
50
|
+
},
|
|
51
|
+
"./github": {
|
|
52
|
+
"types": "./dist/github.d.ts",
|
|
53
|
+
"import": "./dist/github.js"
|
|
54
|
+
},
|
|
55
|
+
"./databricks-volume": {
|
|
56
|
+
"types": "./dist/databricks-volume.d.ts",
|
|
57
|
+
"import": "./dist/databricks-volume.js"
|
|
58
|
+
},
|
|
59
|
+
"./k8s": {
|
|
60
|
+
"types": "./dist/k8s.d.ts",
|
|
61
|
+
"import": "./dist/k8s.js"
|
|
62
|
+
}
|
|
63
|
+
},
|
|
34
64
|
"files": [
|
|
35
65
|
"dist",
|
|
36
66
|
"README.md",
|
|
37
67
|
"LICENSE"
|
|
38
68
|
],
|
|
39
69
|
"dependencies": {
|
|
40
|
-
"@fabric-harness/sdk": "0.
|
|
70
|
+
"@fabric-harness/sdk": "0.6.0"
|
|
71
|
+
},
|
|
72
|
+
"peerDependencies": {
|
|
73
|
+
"@aws-sdk/client-s3": "^3.0.0",
|
|
74
|
+
"@azure/storage-blob": "^12.0.0",
|
|
75
|
+
"@google-cloud/storage": "^7.0.0",
|
|
76
|
+
"@kubernetes/client-node": "^0.21.0",
|
|
77
|
+
"octokit": "^4.0.0"
|
|
78
|
+
},
|
|
79
|
+
"peerDependenciesMeta": {
|
|
80
|
+
"@aws-sdk/client-s3": {
|
|
81
|
+
"optional": true
|
|
82
|
+
},
|
|
83
|
+
"@azure/storage-blob": {
|
|
84
|
+
"optional": true
|
|
85
|
+
},
|
|
86
|
+
"@google-cloud/storage": {
|
|
87
|
+
"optional": true
|
|
88
|
+
},
|
|
89
|
+
"@kubernetes/client-node": {
|
|
90
|
+
"optional": true
|
|
91
|
+
},
|
|
92
|
+
"octokit": {
|
|
93
|
+
"optional": true
|
|
94
|
+
}
|
|
41
95
|
},
|
|
42
96
|
"devDependencies": {
|
|
97
|
+
"@aws-sdk/client-s3": "^3.0.0",
|
|
98
|
+
"@azure/storage-blob": "^12.0.0",
|
|
99
|
+
"@google-cloud/storage": "^7.0.0",
|
|
100
|
+
"@kubernetes/client-node": "^0.21.0",
|
|
101
|
+
"octokit": "^4.0.0",
|
|
43
102
|
"typescript": "^5.8.3",
|
|
44
103
|
"vitest": "^4.1.5"
|
|
45
104
|
},
|