@capsule-run/sdk 0.2.2 → 0.3.1
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 +135 -0
- package/dist/app.d.ts +1 -0
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js.map +1 -1
- package/dist/files.d.ts +46 -0
- package/dist/files.d.ts.map +1 -0
- package/dist/files.js +177 -0
- package/dist/files.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/task.d.ts +2 -0
- package/dist/task.d.ts.map +1 -1
- package/dist/task.js +2 -3
- package/dist/task.js.map +1 -1
- package/package.json +4 -5
- package/src/app.ts +1 -6
- package/src/files.ts +217 -0
- package/src/index.ts +2 -1
- package/src/task.ts +4 -3
- package/dist/http.d.ts +0 -72
- package/dist/http.d.ts.map +0 -1
- package/dist/http.js +0 -154
- package/dist/http.js.map +0 -1
- package/src/http.ts +0 -221
package/README.md
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# capsule
|
|
2
|
+
|
|
3
|
+
**A secure, durable runtime for agentic workflows**
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Capsule is a runtime for coordinating AI agent tasks in isolated environments. It is designed to handle long-running workflows, large-scale processing, autonomous decision-making securely, or even multi-agent systems.
|
|
8
|
+
|
|
9
|
+
Each task runs inside its own WebAssembly sandbox, providing:
|
|
10
|
+
|
|
11
|
+
- **Isolated execution**: Each task runs isolated from your host system
|
|
12
|
+
- **Resource limits**: Set CPU, memory, and timeout limits per task
|
|
13
|
+
- **Automatic retries**: Handle failures without manual intervention
|
|
14
|
+
- **Lifecycle tracking**: Monitor which tasks are running, completed, or failed
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install -g @capsule-run/cli
|
|
20
|
+
npm install @capsule-run/sdk
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
Create `hello.ts`:
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
import { task } from "@capsule-run/sdk";
|
|
29
|
+
|
|
30
|
+
export const main = task({
|
|
31
|
+
name: "main",
|
|
32
|
+
compute: "LOW",
|
|
33
|
+
ram: "64MB"
|
|
34
|
+
}, (): string => {
|
|
35
|
+
return "Hello from Capsule!";
|
|
36
|
+
});
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Run it:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
capsule run hello.ts
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## How It Works
|
|
46
|
+
|
|
47
|
+
Simply use a wrapper function to define your tasks:
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
import { task } from "@capsule-run/sdk";
|
|
51
|
+
|
|
52
|
+
export const analyzeData = task({
|
|
53
|
+
name: "analyze_data",
|
|
54
|
+
compute: "MEDIUM",
|
|
55
|
+
ram: "512MB",
|
|
56
|
+
timeout: "30s",
|
|
57
|
+
maxRetries: 1
|
|
58
|
+
}, (dataset: number[]): object => {
|
|
59
|
+
// Your code runs safely in a Wasm sandbox
|
|
60
|
+
return { processed: dataset.length, status: "complete" };
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// The "main" task is required as the entrypoint
|
|
64
|
+
export const main = task({
|
|
65
|
+
name: "main",
|
|
66
|
+
compute: "HIGH"
|
|
67
|
+
}, () => {
|
|
68
|
+
return analyzeData([1, 2, 3, 4, 5]);
|
|
69
|
+
});
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
When you run `capsule run main.ts`, your code is compiled into a WebAssembly module and executed in a dedicated sandbox.
|
|
73
|
+
|
|
74
|
+
## Documentation
|
|
75
|
+
|
|
76
|
+
### Task Configuration Options
|
|
77
|
+
|
|
78
|
+
| Parameter | Description | Type | Default | Example |
|
|
79
|
+
|-----------|-------------|------|---------|---------|
|
|
80
|
+
| `name` | Task identifier | `string` | *required* | `"process_data"` |
|
|
81
|
+
| `compute` | CPU level: `"LOW"`, `"MEDIUM"`, `"HIGH"` | `string` | `"MEDIUM"` | `"HIGH"` |
|
|
82
|
+
| `ram` | Memory limit | `string` | unlimited | `"512MB"`, `"2GB"` |
|
|
83
|
+
| `timeout` | Maximum execution time | `string` or `number` | unlimited | `"30s"`, `"5m"` |
|
|
84
|
+
| `maxRetries` | Retry attempts on failure | `number` | `0` | `3` |
|
|
85
|
+
| `allowedFiles` | Folders accessible in the sandbox | `string[]` | `[]` | `["./data", "./output"]` |
|
|
86
|
+
|
|
87
|
+
### Compute Levels
|
|
88
|
+
|
|
89
|
+
- **LOW**: Minimal allocation for lightweight tasks
|
|
90
|
+
- **MEDIUM**: Balanced resources for typical workloads
|
|
91
|
+
- **HIGH**: Maximum fuel for compute-intensive operations
|
|
92
|
+
- **CUSTOM**: Specify exact fuel value (e.g., `compute="1000000"`)
|
|
93
|
+
|
|
94
|
+
### File Access
|
|
95
|
+
|
|
96
|
+
The entry point task (main) has access to the entire project directory. Sub-tasks have no filesystem access by default and must declare `allowedFiles` to access specific paths.
|
|
97
|
+
|
|
98
|
+
Node.js built-ins like `fs` are not available in the WebAssembly sandbox. Instead, use the `files` API provided by the SDK:
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
import { task, files } from "@capsule-run/sdk";
|
|
102
|
+
|
|
103
|
+
export const restrictedWriter = task({
|
|
104
|
+
name: "restricted_writer",
|
|
105
|
+
allowedFiles: ["./output"]
|
|
106
|
+
}, async () => {
|
|
107
|
+
await files.writeText("./output/result.txt", "result");
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
export const main = task({ name: "main" }, async () => {
|
|
111
|
+
restrictedWriter();
|
|
112
|
+
return await files.readText("./data/input.txt");
|
|
113
|
+
});
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Available methods:
|
|
117
|
+
- `files.readText(path)` — Read file as string
|
|
118
|
+
- `files.readBytes(path)` — Read file as `Uint8Array`
|
|
119
|
+
- `files.writeText(path, content)` — Write string to file
|
|
120
|
+
- `files.writeBytes(path, data)` — Write bytes to file
|
|
121
|
+
- `files.list(path)` — List directory contents
|
|
122
|
+
- `files.exists(path)` — Check if file exists
|
|
123
|
+
|
|
124
|
+
## Compatibility
|
|
125
|
+
|
|
126
|
+
✅ **Supported:**
|
|
127
|
+
- npm packages and ES modules work
|
|
128
|
+
|
|
129
|
+
⚠️ **Not yet supported:**
|
|
130
|
+
- Node.js built-ins (`fs`, `path`, `os`) are not available in the sandbox
|
|
131
|
+
|
|
132
|
+
## Links
|
|
133
|
+
|
|
134
|
+
- [GitHub](https://github.com/mavdol/capsule)
|
|
135
|
+
- [Issues](https://github.com/mavdol/capsule/issues)
|
package/dist/app.d.ts
CHANGED
package/dist/app.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,QAAQ,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG;IACzD,IAAI,EAAE,CAAC,CAAC;IACR,MAAM,EAAE,UAAU,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,QAAQ,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG;IACzD,IAAI,EAAE,CAAC,CAAC;IACR,MAAM,EAAE,UAAU,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAID;;GAEG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EAC5D,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,CAAC,EACP,MAAM,EAAE,UAAU,GACjB,IAAI,CAEN;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC,GAAG,SAAS,CAE3E;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAElE;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,EAAE,CAEvC;AAQD;;;;;GAKG;AACH,qBAAa,UAAU;IACrB;;;OAGG;IACG,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAuC7C;AAED,eAAO,MAAM,OAAO,YAAmB,CAAC"}
|
package/dist/app.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA;;GAEG;AAgBH,MAAM,KAAK,GAA+B,IAAI,GAAG,EAAE,CAAC;AAEpD;;GAEG;AACH,MAAM,UAAU,YAAY,CAC1B,IAAY,EACZ,IAAO,EACP,MAAkB;IAElB,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;AACpC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,OAAO,CAAC,IAAY;IAClC,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC;AAC/B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;AACjC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY;IAC1B,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;AAClC,CAAC;AAQD;;;;;GAKG;AACH,MAAM,OAAO,UAAU;IACrB;;;OAGG;IACH,KAAK,CAAC,GAAG,CAAC,QAAgB;QACxB,IAAI,CAAC;YACH,MAAM,IAAI,GAAa,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAC5C,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,IAAI,MAAM,CAAC;YAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;YAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;YAEjC,IAAI,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;YAEjC,IAAI,CAAC,QAAQ,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;gBACrC,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;YAC7B,CAAC;YAED,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;gBAChC,MAAM,aAAa,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;gBAChD,IAAI,aAAa,EAAE,CAAC;oBAClB,QAAQ,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;gBACpC,CAAC;YACH,CAAC;YAED,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,MAAM,uDAAuD,YAAY,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3F,CAAC;YAED,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;YAEzC,IAAI,MAAM,YAAY,OAAO,EAAE,CAAC;gBAC9B,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC;gBACjC,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,WAAW,IAAI,IAAI,EAAE,CAAC,CAAC;YACzD,CAAC;YAED,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,IAAI,IAAI,EAAE,CAAC,CAAC;QACpD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,QAAQ,GAAG,CAAC,YAAY,KAAK;gBACjC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,KAAK,IAAI,EAAE,EAAE;gBAClC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACd,MAAM,QAAQ,CAAC;QACjB,CAAC;IACH,CAAC;CACF;AAED,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,UAAU,EAAE,CAAC"}
|
package/dist/files.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capsule Files API for WASM filesystem access.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Read a file as text.
|
|
6
|
+
*
|
|
7
|
+
* @param path - The path to read.
|
|
8
|
+
* @returns A promise that resolves to a string containing the file contents.
|
|
9
|
+
*/
|
|
10
|
+
export declare function readText(path: string): Promise<string>;
|
|
11
|
+
/**
|
|
12
|
+
* Read a file as bytes.
|
|
13
|
+
*
|
|
14
|
+
* @param path - The path to read.
|
|
15
|
+
* @returns A promise that resolves to a Uint8Array containing the file contents.
|
|
16
|
+
*/
|
|
17
|
+
export declare function readBytes(path: string): Promise<Uint8Array>;
|
|
18
|
+
/**
|
|
19
|
+
* Write text content to a file.
|
|
20
|
+
*
|
|
21
|
+
* @param path - The path to write.
|
|
22
|
+
* @param content - The text content to write.
|
|
23
|
+
*/
|
|
24
|
+
export declare function writeText(path: string, content: string): Promise<void>;
|
|
25
|
+
/**
|
|
26
|
+
* Write bytes to a file.
|
|
27
|
+
*
|
|
28
|
+
* @param path - The path to write.
|
|
29
|
+
* @param data - The bytes to write.
|
|
30
|
+
*/
|
|
31
|
+
export declare function writeBytes(path: string, data: Uint8Array): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* List files/directories at a path.
|
|
34
|
+
*
|
|
35
|
+
* @param path - The path to list.
|
|
36
|
+
* @returns A promise that resolves to an array of strings representing the files and directories at the specified path.
|
|
37
|
+
*/
|
|
38
|
+
export declare function list(path?: string): Promise<string[]>;
|
|
39
|
+
/**
|
|
40
|
+
* Check if a file or directory exists.
|
|
41
|
+
*
|
|
42
|
+
* @param path - The path to check.
|
|
43
|
+
* @returns A promise that resolves to a boolean indicating whether the file or directory exists.
|
|
44
|
+
*/
|
|
45
|
+
export declare function exists(path: string): Promise<boolean>;
|
|
46
|
+
//# sourceMappingURL=files.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../src/files.ts"],"names":[],"mappings":"AAAA;;GAEG;AAoFH;;;;;GAKG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAG5D;AAED;;;;;GAKG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAkBjE;AAED;;;;;GAKG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG5E;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB9E;AAED;;;;;GAKG;AACH,wBAAsB,IAAI,CAAC,IAAI,GAAE,MAAY,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CA6BhE;AAED;;;;;GAKG;AACH,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAe3D"}
|
package/dist/files.js
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capsule Files API for WASM filesystem access.
|
|
3
|
+
*/
|
|
4
|
+
function getFsBindings() {
|
|
5
|
+
try {
|
|
6
|
+
const types = globalThis['wasi:filesystem/types'];
|
|
7
|
+
const preopens = globalThis['wasi:filesystem/preopens'];
|
|
8
|
+
if (types && preopens) {
|
|
9
|
+
return { types, preopens };
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
catch { }
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
function getPreopenedDirs() {
|
|
16
|
+
const fs = getFsBindings();
|
|
17
|
+
if (!fs)
|
|
18
|
+
return [];
|
|
19
|
+
try {
|
|
20
|
+
const dirs = fs.preopens.getDirectories();
|
|
21
|
+
return (dirs || []).map((entry) => ({
|
|
22
|
+
descriptor: entry[0],
|
|
23
|
+
guestPath: entry[1]
|
|
24
|
+
}));
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function normalizePath(path) {
|
|
31
|
+
if (path.startsWith('./')) {
|
|
32
|
+
return path.slice(2);
|
|
33
|
+
}
|
|
34
|
+
return path;
|
|
35
|
+
}
|
|
36
|
+
function resolvePath(path) {
|
|
37
|
+
const preopens = getPreopenedDirs();
|
|
38
|
+
if (preopens.length === 0)
|
|
39
|
+
return null;
|
|
40
|
+
const normalizedPath = normalizePath(path);
|
|
41
|
+
for (const { descriptor, guestPath } of preopens) {
|
|
42
|
+
const normalizedGuest = normalizePath(guestPath);
|
|
43
|
+
if (normalizedGuest === '.' || normalizedGuest === '') {
|
|
44
|
+
return { dir: descriptor, relativePath: normalizedPath };
|
|
45
|
+
}
|
|
46
|
+
if (normalizedPath.startsWith(normalizedGuest + '/')) {
|
|
47
|
+
const relativePath = normalizedPath.slice(normalizedGuest.length + 1);
|
|
48
|
+
return { dir: descriptor, relativePath };
|
|
49
|
+
}
|
|
50
|
+
if (normalizedPath === normalizedGuest) {
|
|
51
|
+
return { dir: descriptor, relativePath: '.' };
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return { dir: preopens[0].descriptor, relativePath: normalizedPath };
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Read a file as text.
|
|
58
|
+
*
|
|
59
|
+
* @param path - The path to read.
|
|
60
|
+
* @returns A promise that resolves to a string containing the file contents.
|
|
61
|
+
*/
|
|
62
|
+
export async function readText(path) {
|
|
63
|
+
const bytes = await readBytes(path);
|
|
64
|
+
return new TextDecoder().decode(bytes);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Read a file as bytes.
|
|
68
|
+
*
|
|
69
|
+
* @param path - The path to read.
|
|
70
|
+
* @returns A promise that resolves to a Uint8Array containing the file contents.
|
|
71
|
+
*/
|
|
72
|
+
export async function readBytes(path) {
|
|
73
|
+
const resolved = resolvePath(path);
|
|
74
|
+
if (!resolved) {
|
|
75
|
+
throw new Error("Filesystem not available.");
|
|
76
|
+
}
|
|
77
|
+
try {
|
|
78
|
+
const pathFlags = { symlinkFollow: false };
|
|
79
|
+
const openFlags = {};
|
|
80
|
+
const descriptorFlags = { read: true };
|
|
81
|
+
const fd = resolved.dir.openAt(pathFlags, resolved.relativePath, openFlags, descriptorFlags);
|
|
82
|
+
const stat = fd.stat();
|
|
83
|
+
const [data] = fd.read(stat.size, BigInt(0));
|
|
84
|
+
return data;
|
|
85
|
+
}
|
|
86
|
+
catch (e) {
|
|
87
|
+
throw new Error(`Failed to read file '${path}': ${e}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Write text content to a file.
|
|
92
|
+
*
|
|
93
|
+
* @param path - The path to write.
|
|
94
|
+
* @param content - The text content to write.
|
|
95
|
+
*/
|
|
96
|
+
export async function writeText(path, content) {
|
|
97
|
+
const bytes = new TextEncoder().encode(content);
|
|
98
|
+
await writeBytes(path, bytes);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Write bytes to a file.
|
|
102
|
+
*
|
|
103
|
+
* @param path - The path to write.
|
|
104
|
+
* @param data - The bytes to write.
|
|
105
|
+
*/
|
|
106
|
+
export async function writeBytes(path, data) {
|
|
107
|
+
const resolved = resolvePath(path);
|
|
108
|
+
if (!resolved) {
|
|
109
|
+
throw new Error("Filesystem not available.");
|
|
110
|
+
}
|
|
111
|
+
try {
|
|
112
|
+
const pathFlags = { symlinkFollow: false };
|
|
113
|
+
const openFlags = { create: true, truncate: true };
|
|
114
|
+
const descriptorFlags = { write: true };
|
|
115
|
+
const fd = resolved.dir.openAt(pathFlags, resolved.relativePath, openFlags, descriptorFlags);
|
|
116
|
+
fd.write(data, BigInt(0));
|
|
117
|
+
}
|
|
118
|
+
catch (e) {
|
|
119
|
+
throw new Error(`Failed to write file '${path}': ${e}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* List files/directories at a path.
|
|
124
|
+
*
|
|
125
|
+
* @param path - The path to list.
|
|
126
|
+
* @returns A promise that resolves to an array of strings representing the files and directories at the specified path.
|
|
127
|
+
*/
|
|
128
|
+
export async function list(path = ".") {
|
|
129
|
+
const resolved = resolvePath(path);
|
|
130
|
+
if (!resolved) {
|
|
131
|
+
throw new Error("Filesystem not available.");
|
|
132
|
+
}
|
|
133
|
+
try {
|
|
134
|
+
let targetDir = resolved.dir;
|
|
135
|
+
if (resolved.relativePath !== ".") {
|
|
136
|
+
const pathFlags = { symlinkFollow: false };
|
|
137
|
+
const openFlags = { directory: true };
|
|
138
|
+
const descriptorFlags = { read: true };
|
|
139
|
+
targetDir = resolved.dir.openAt(pathFlags, resolved.relativePath, openFlags, descriptorFlags);
|
|
140
|
+
}
|
|
141
|
+
const stream = targetDir.readDirectory();
|
|
142
|
+
const entries = [];
|
|
143
|
+
let entry;
|
|
144
|
+
while ((entry = stream.readDirectoryEntry()) !== undefined && entry !== null) {
|
|
145
|
+
if (entry.name) {
|
|
146
|
+
entries.push(entry.name);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return entries;
|
|
150
|
+
}
|
|
151
|
+
catch (e) {
|
|
152
|
+
throw new Error(`Failed to list directory '${path}': ${e}`);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Check if a file or directory exists.
|
|
157
|
+
*
|
|
158
|
+
* @param path - The path to check.
|
|
159
|
+
* @returns A promise that resolves to a boolean indicating whether the file or directory exists.
|
|
160
|
+
*/
|
|
161
|
+
export async function exists(path) {
|
|
162
|
+
const resolved = resolvePath(path);
|
|
163
|
+
if (!resolved) {
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
try {
|
|
167
|
+
const pathFlags = { symlinkFollow: false };
|
|
168
|
+
const openFlags = {};
|
|
169
|
+
const descriptorFlags = { read: true };
|
|
170
|
+
resolved.dir.openAt(pathFlags, resolved.relativePath, openFlags, descriptorFlags);
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.js","sourceRoot":"","sources":["../src/files.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -15,6 +15,6 @@
|
|
|
15
15
|
*/
|
|
16
16
|
export { task, type TaskOptions } from "./task.js";
|
|
17
17
|
export { TaskRunner, exports, type TaskConfig } from "./app.js";
|
|
18
|
-
export * as
|
|
18
|
+
export * as files from "./files.js";
|
|
19
19
|
export { isWasmMode } from "./hostApi.js";
|
|
20
20
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,IAAI,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAChE,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,IAAI,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAChE,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,IAAI,EAAoB,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,OAAO,EAAmB,MAAM,UAAU,CAAC;AAChE,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,IAAI,EAAoB,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,OAAO,EAAmB,MAAM,UAAU,CAAC;AAChE,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/task.d.ts
CHANGED
|
@@ -19,6 +19,8 @@ export interface TaskOptions {
|
|
|
19
19
|
timeout?: string | number;
|
|
20
20
|
/** Maximum number of retries */
|
|
21
21
|
maxRetries?: number;
|
|
22
|
+
/** Files/folders accessible in the sandbox, e.g., ["./data"] */
|
|
23
|
+
allowedFiles?: string[];
|
|
22
24
|
}
|
|
23
25
|
export declare function task<TArgs extends any[], TReturn>(options: TaskOptions, fn: (...args: TArgs) => TReturn): (...args: TArgs) => TReturn;
|
|
24
26
|
//# sourceMappingURL=task.d.ts.map
|
package/dist/task.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task.d.ts","sourceRoot":"","sources":["../src/task.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,MAAM,WAAW,WAAW;IAC1B,2BAA2B;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,OAAO,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;IAC7C,sCAAsC;IACtC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,gCAAgC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"task.d.ts","sourceRoot":"","sources":["../src/task.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,MAAM,WAAW,WAAW;IAC1B,2BAA2B;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,OAAO,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;IAC7C,sCAAsC;IACtC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,gCAAgC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAoDD,wBAAgB,IAAI,CAAC,KAAK,SAAS,GAAG,EAAE,EAAE,OAAO,EAC/C,OAAO,EAAE,WAAW,EACpB,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,OAAO,GAC9B,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,OAAO,CAqC7B"}
|
package/dist/task.js
CHANGED
|
@@ -11,7 +11,6 @@ import { isWasmMode, callHost } from "./hostApi.js";
|
|
|
11
11
|
*
|
|
12
12
|
* @example
|
|
13
13
|
* ```typescript
|
|
14
|
-
* // String timeout format
|
|
15
14
|
* export const greet = task({
|
|
16
15
|
* name: "greet",
|
|
17
16
|
* compute: "LOW",
|
|
@@ -20,11 +19,10 @@ import { isWasmMode, callHost } from "./hostApi.js";
|
|
|
20
19
|
* return `Hello, ${name}!`;
|
|
21
20
|
* });
|
|
22
21
|
*
|
|
23
|
-
* // Numeric timeout format (milliseconds)
|
|
24
22
|
* export const process = task({
|
|
25
23
|
* name: "process",
|
|
26
24
|
* compute: "HIGH",
|
|
27
|
-
* timeout: 30000
|
|
25
|
+
* timeout: 30000
|
|
28
26
|
* }, (data: any): any => {
|
|
29
27
|
* return processData(data);
|
|
30
28
|
* });
|
|
@@ -61,6 +59,7 @@ export function task(options, fn) {
|
|
|
61
59
|
ram: options.ram,
|
|
62
60
|
timeout: normalizeTimeout(options.timeout),
|
|
63
61
|
maxRetries: options.maxRetries,
|
|
62
|
+
allowedFiles: options.allowedFiles,
|
|
64
63
|
};
|
|
65
64
|
const wrapper = (...args) => {
|
|
66
65
|
if (!isWasmMode()) {
|
package/dist/task.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task.js","sourceRoot":"","sources":["../src/task.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAmB,MAAM,UAAU,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"task.js","sourceRoot":"","sources":["../src/task.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAmB,MAAM,UAAU,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AA0BpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH;;;;;GAKG;AACH,SAAS,gBAAgB,CAAC,OAAyB;IACjD,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC5C,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QAChC,OAAO,GAAG,OAAO,IAAI,CAAC;IACxB,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,IAAI,CAClB,OAAoB,EACpB,EAA+B;IAE/B,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAC9B,IAAI,OAAO,GAAG,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC,WAAW,EAAE,IAAI,QAAQ,CAAC;IAEpE,MAAM,UAAU,GAAe;QAC7B,IAAI,EAAE,QAAQ;QACd,OAAO;QACP,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,OAAO,EAAE,gBAAgB,CAAC,OAAO,CAAC,OAAO,CAAC;QAC1C,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,YAAY,EAAE,OAAO,CAAC,YAAY;KACnC,CAAC;IAEF,MAAM,OAAO,GAAG,CAAC,GAAG,IAAW,EAAW,EAAE;QAC1C,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC;YAClB,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;QACrB,CAAC;QAED,MAAM,UAAU,GAAG,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;QAExD,IAAI,CAAC;YACH,MAAM,MAAM,GAAe,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YAClD,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;gBACjB,MAAM,IAAI,KAAK,CAAC,QAAQ,QAAQ,YAAY,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;YAC9D,CAAC;YACD,OAAO,MAAM,CAAC,MAAiB,CAAC;QAClC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,CAAC,YAAY,WAAW,EAAE,CAAC;gBAC7B,OAAO,UAAgC,CAAC;YAC1C,CAAC;YACD,MAAM,CAAC,CAAC;QACV,CAAC;IACH,CAAC,CAAC;IAEF,YAAY,CAAC,QAAQ,EAAE,EAAE,EAAE,UAAU,CAAC,CAAC;IAEvC,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@capsule-run/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Capsule JavaScript SDK - run AI agent tasks in secure WASM sandboxes",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -22,7 +22,8 @@
|
|
|
22
22
|
},
|
|
23
23
|
"files": [
|
|
24
24
|
"dist",
|
|
25
|
-
"src"
|
|
25
|
+
"src",
|
|
26
|
+
"README.md"
|
|
26
27
|
],
|
|
27
28
|
"scripts": {
|
|
28
29
|
"build": "tsc",
|
|
@@ -38,9 +39,7 @@
|
|
|
38
39
|
"license": "Apache-2.0",
|
|
39
40
|
"dependencies": {
|
|
40
41
|
"@bytecodealliance/jco": "^1.0.0",
|
|
41
|
-
"esbuild": "^0.27.2"
|
|
42
|
-
},
|
|
43
|
-
"devDependencies": {
|
|
42
|
+
"esbuild": "^0.27.2",
|
|
44
43
|
"typescript": "^5.9.3"
|
|
45
44
|
}
|
|
46
45
|
}
|
package/src/app.ts
CHANGED
|
@@ -13,6 +13,7 @@ export interface TaskConfig {
|
|
|
13
13
|
ram?: string;
|
|
14
14
|
timeout?: string;
|
|
15
15
|
maxRetries?: number;
|
|
16
|
+
allowedFiles?: string[];
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
const TASKS: Map<string, TaskInfo<any>> = new Map();
|
|
@@ -55,12 +56,6 @@ interface TaskArgs {
|
|
|
55
56
|
kwargs?: Record<string, any>;
|
|
56
57
|
}
|
|
57
58
|
|
|
58
|
-
interface TaskResult {
|
|
59
|
-
result?: any;
|
|
60
|
-
error?: string;
|
|
61
|
-
traceback?: string;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
59
|
/**
|
|
65
60
|
* Implementation of the capsule:host/task-runner interface.
|
|
66
61
|
*
|
package/src/files.ts
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capsule Files API for WASM filesystem access.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
declare const globalThis: {
|
|
6
|
+
'wasi:filesystem/types': any;
|
|
7
|
+
'wasi:filesystem/preopens': any;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
interface Descriptor {
|
|
11
|
+
read(length: bigint, offset: bigint): [Uint8Array, boolean];
|
|
12
|
+
write(buffer: Uint8Array, offset: bigint): bigint;
|
|
13
|
+
stat(): { size: bigint };
|
|
14
|
+
readDirectory(): any;
|
|
15
|
+
openAt(
|
|
16
|
+
pathFlags: { symlinkFollow?: boolean },
|
|
17
|
+
path: string,
|
|
18
|
+
openFlags: { create?: boolean; directory?: boolean; exclusive?: boolean; truncate?: boolean },
|
|
19
|
+
descriptorFlags: { read?: boolean; write?: boolean; mutateDirectory?: boolean }
|
|
20
|
+
): Descriptor;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface PreopenedDir {
|
|
24
|
+
descriptor: Descriptor;
|
|
25
|
+
guestPath: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function getFsBindings(): { types: any; preopens: any } | null {
|
|
29
|
+
try {
|
|
30
|
+
const types = globalThis['wasi:filesystem/types'];
|
|
31
|
+
const preopens = globalThis['wasi:filesystem/preopens'];
|
|
32
|
+
if (types && preopens) {
|
|
33
|
+
return { types, preopens };
|
|
34
|
+
}
|
|
35
|
+
} catch {}
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function getPreopenedDirs(): PreopenedDir[] {
|
|
40
|
+
const fs = getFsBindings();
|
|
41
|
+
if (!fs) return [];
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
const dirs = fs.preopens.getDirectories();
|
|
45
|
+
return (dirs || []).map((entry: [Descriptor, string]) => ({
|
|
46
|
+
descriptor: entry[0],
|
|
47
|
+
guestPath: entry[1]
|
|
48
|
+
}));
|
|
49
|
+
} catch {
|
|
50
|
+
return [];
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function normalizePath(path: string): string {
|
|
55
|
+
if (path.startsWith('./')) {
|
|
56
|
+
return path.slice(2);
|
|
57
|
+
}
|
|
58
|
+
return path;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function resolvePath(path: string): { dir: Descriptor; relativePath: string } | null {
|
|
62
|
+
const preopens = getPreopenedDirs();
|
|
63
|
+
if (preopens.length === 0) return null;
|
|
64
|
+
|
|
65
|
+
const normalizedPath = normalizePath(path);
|
|
66
|
+
|
|
67
|
+
for (const { descriptor, guestPath } of preopens) {
|
|
68
|
+
const normalizedGuest = normalizePath(guestPath);
|
|
69
|
+
|
|
70
|
+
if (normalizedGuest === '.' || normalizedGuest === '') {
|
|
71
|
+
return { dir: descriptor, relativePath: normalizedPath };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (normalizedPath.startsWith(normalizedGuest + '/')) {
|
|
75
|
+
const relativePath = normalizedPath.slice(normalizedGuest.length + 1);
|
|
76
|
+
return { dir: descriptor, relativePath };
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (normalizedPath === normalizedGuest) {
|
|
80
|
+
return { dir: descriptor, relativePath: '.' };
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return { dir: preopens[0].descriptor, relativePath: normalizedPath };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Read a file as text.
|
|
89
|
+
*
|
|
90
|
+
* @param path - The path to read.
|
|
91
|
+
* @returns A promise that resolves to a string containing the file contents.
|
|
92
|
+
*/
|
|
93
|
+
export async function readText(path: string): Promise<string> {
|
|
94
|
+
const bytes = await readBytes(path);
|
|
95
|
+
return new TextDecoder().decode(bytes);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Read a file as bytes.
|
|
100
|
+
*
|
|
101
|
+
* @param path - The path to read.
|
|
102
|
+
* @returns A promise that resolves to a Uint8Array containing the file contents.
|
|
103
|
+
*/
|
|
104
|
+
export async function readBytes(path: string): Promise<Uint8Array> {
|
|
105
|
+
const resolved = resolvePath(path);
|
|
106
|
+
if (!resolved) {
|
|
107
|
+
throw new Error("Filesystem not available.");
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
try {
|
|
111
|
+
const pathFlags = { symlinkFollow: false };
|
|
112
|
+
const openFlags = {};
|
|
113
|
+
const descriptorFlags = { read: true };
|
|
114
|
+
|
|
115
|
+
const fd = resolved.dir.openAt(pathFlags, resolved.relativePath, openFlags, descriptorFlags);
|
|
116
|
+
const stat = fd.stat();
|
|
117
|
+
const [data] = fd.read(stat.size, BigInt(0));
|
|
118
|
+
return data;
|
|
119
|
+
} catch (e) {
|
|
120
|
+
throw new Error(`Failed to read file '${path}': ${e}`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Write text content to a file.
|
|
126
|
+
*
|
|
127
|
+
* @param path - The path to write.
|
|
128
|
+
* @param content - The text content to write.
|
|
129
|
+
*/
|
|
130
|
+
export async function writeText(path: string, content: string): Promise<void> {
|
|
131
|
+
const bytes = new TextEncoder().encode(content);
|
|
132
|
+
await writeBytes(path, bytes);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Write bytes to a file.
|
|
137
|
+
*
|
|
138
|
+
* @param path - The path to write.
|
|
139
|
+
* @param data - The bytes to write.
|
|
140
|
+
*/
|
|
141
|
+
export async function writeBytes(path: string, data: Uint8Array): Promise<void> {
|
|
142
|
+
const resolved = resolvePath(path);
|
|
143
|
+
if (!resolved) {
|
|
144
|
+
throw new Error("Filesystem not available.");
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
try {
|
|
148
|
+
const pathFlags = { symlinkFollow: false };
|
|
149
|
+
const openFlags = { create: true, truncate: true };
|
|
150
|
+
const descriptorFlags = { write: true };
|
|
151
|
+
|
|
152
|
+
const fd = resolved.dir.openAt(pathFlags, resolved.relativePath, openFlags, descriptorFlags);
|
|
153
|
+
fd.write(data, BigInt(0));
|
|
154
|
+
} catch (e) {
|
|
155
|
+
throw new Error(`Failed to write file '${path}': ${e}`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* List files/directories at a path.
|
|
161
|
+
*
|
|
162
|
+
* @param path - The path to list.
|
|
163
|
+
* @returns A promise that resolves to an array of strings representing the files and directories at the specified path.
|
|
164
|
+
*/
|
|
165
|
+
export async function list(path: string = "."): Promise<string[]> {
|
|
166
|
+
const resolved = resolvePath(path);
|
|
167
|
+
if (!resolved) {
|
|
168
|
+
throw new Error("Filesystem not available.");
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
try {
|
|
172
|
+
let targetDir = resolved.dir;
|
|
173
|
+
if (resolved.relativePath !== ".") {
|
|
174
|
+
const pathFlags = { symlinkFollow: false };
|
|
175
|
+
const openFlags = { directory: true };
|
|
176
|
+
const descriptorFlags = { read: true };
|
|
177
|
+
targetDir = resolved.dir.openAt(pathFlags, resolved.relativePath, openFlags, descriptorFlags);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const stream = targetDir.readDirectory();
|
|
181
|
+
const entries: string[] = [];
|
|
182
|
+
|
|
183
|
+
let entry;
|
|
184
|
+
while ((entry = stream.readDirectoryEntry()) !== undefined && entry !== null) {
|
|
185
|
+
if (entry.name) {
|
|
186
|
+
entries.push(entry.name);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return entries;
|
|
191
|
+
} catch (e) {
|
|
192
|
+
throw new Error(`Failed to list directory '${path}': ${e}`);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Check if a file or directory exists.
|
|
198
|
+
*
|
|
199
|
+
* @param path - The path to check.
|
|
200
|
+
* @returns A promise that resolves to a boolean indicating whether the file or directory exists.
|
|
201
|
+
*/
|
|
202
|
+
export async function exists(path: string): Promise<boolean> {
|
|
203
|
+
const resolved = resolvePath(path);
|
|
204
|
+
if (!resolved) {
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
try {
|
|
209
|
+
const pathFlags = { symlinkFollow: false };
|
|
210
|
+
const openFlags = {};
|
|
211
|
+
const descriptorFlags = { read: true };
|
|
212
|
+
resolved.dir.openAt(pathFlags, resolved.relativePath, openFlags, descriptorFlags);
|
|
213
|
+
return true;
|
|
214
|
+
} catch {
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
}
|
package/src/index.ts
CHANGED
package/src/task.ts
CHANGED
|
@@ -23,6 +23,8 @@ export interface TaskOptions {
|
|
|
23
23
|
timeout?: string | number;
|
|
24
24
|
/** Maximum number of retries */
|
|
25
25
|
maxRetries?: number;
|
|
26
|
+
/** Files/folders accessible in the sandbox, e.g., ["./data"] */
|
|
27
|
+
allowedFiles?: string[];
|
|
26
28
|
}
|
|
27
29
|
|
|
28
30
|
interface TaskResult {
|
|
@@ -35,7 +37,6 @@ interface TaskResult {
|
|
|
35
37
|
*
|
|
36
38
|
* @example
|
|
37
39
|
* ```typescript
|
|
38
|
-
* // String timeout format
|
|
39
40
|
* export const greet = task({
|
|
40
41
|
* name: "greet",
|
|
41
42
|
* compute: "LOW",
|
|
@@ -44,11 +45,10 @@ interface TaskResult {
|
|
|
44
45
|
* return `Hello, ${name}!`;
|
|
45
46
|
* });
|
|
46
47
|
*
|
|
47
|
-
* // Numeric timeout format (milliseconds)
|
|
48
48
|
* export const process = task({
|
|
49
49
|
* name: "process",
|
|
50
50
|
* compute: "HIGH",
|
|
51
|
-
* timeout: 30000
|
|
51
|
+
* timeout: 30000
|
|
52
52
|
* }, (data: any): any => {
|
|
53
53
|
* return processData(data);
|
|
54
54
|
* });
|
|
@@ -90,6 +90,7 @@ export function task<TArgs extends any[], TReturn>(
|
|
|
90
90
|
ram: options.ram,
|
|
91
91
|
timeout: normalizeTimeout(options.timeout),
|
|
92
92
|
maxRetries: options.maxRetries,
|
|
93
|
+
allowedFiles: options.allowedFiles,
|
|
93
94
|
};
|
|
94
95
|
|
|
95
96
|
const wrapper = (...args: TArgs): TReturn => {
|
package/dist/http.d.ts
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Capsule SDK - HTTP Client
|
|
3
|
-
*
|
|
4
|
-
* This module provides HTTP request functions by calling the host's HTTP implementation.
|
|
5
|
-
* In WASM mode, requests go through the Rust host.
|
|
6
|
-
* In local mode, uses native fetch for testing.
|
|
7
|
-
*/
|
|
8
|
-
export interface RequestOptions {
|
|
9
|
-
headers?: Record<string, string>;
|
|
10
|
-
body?: string;
|
|
11
|
-
json?: any;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* HTTP Response wrapper with convenient methods.
|
|
15
|
-
*/
|
|
16
|
-
export declare class Response {
|
|
17
|
-
readonly status: number;
|
|
18
|
-
readonly headers: Record<string, string>;
|
|
19
|
-
readonly body: string;
|
|
20
|
-
constructor(status: number, headers: Record<string, string>, body: string);
|
|
21
|
-
/**
|
|
22
|
-
* Parse response body as JSON.
|
|
23
|
-
*/
|
|
24
|
-
json<T = any>(): T;
|
|
25
|
-
/**
|
|
26
|
-
* Get response body as text.
|
|
27
|
-
*/
|
|
28
|
-
text(): string;
|
|
29
|
-
/**
|
|
30
|
-
* Check if response status is 2xx.
|
|
31
|
-
*/
|
|
32
|
-
ok(): boolean;
|
|
33
|
-
toString(): string;
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Make an HTTP GET request.
|
|
37
|
-
*
|
|
38
|
-
* @example
|
|
39
|
-
* ```typescript
|
|
40
|
-
* const response = http.get("https://api.github.com/zen");
|
|
41
|
-
* console.log(response.text());
|
|
42
|
-
* ```
|
|
43
|
-
*/
|
|
44
|
-
export declare function get(url: string, options?: Omit<RequestOptions, "body" | "json">): Promise<Response>;
|
|
45
|
-
/**
|
|
46
|
-
* Make an HTTP POST request.
|
|
47
|
-
*
|
|
48
|
-
* @example
|
|
49
|
-
* ```typescript
|
|
50
|
-
* const response = http.post("https://api.example.com/data", {
|
|
51
|
-
* json: { key: "value" }
|
|
52
|
-
* });
|
|
53
|
-
* ```
|
|
54
|
-
*/
|
|
55
|
-
export declare function post(url: string, options?: RequestOptions): Promise<Response>;
|
|
56
|
-
/**
|
|
57
|
-
* Make an HTTP PUT request.
|
|
58
|
-
*/
|
|
59
|
-
export declare function put(url: string, options?: RequestOptions): Promise<Response>;
|
|
60
|
-
/**
|
|
61
|
-
* Make an HTTP DELETE request.
|
|
62
|
-
*/
|
|
63
|
-
export declare function del(url: string, options?: Omit<RequestOptions, "body" | "json">): Promise<Response>;
|
|
64
|
-
/**
|
|
65
|
-
* Make an HTTP PATCH request.
|
|
66
|
-
*/
|
|
67
|
-
export declare function patch(url: string, options?: RequestOptions): Promise<Response>;
|
|
68
|
-
/**
|
|
69
|
-
* Make an HTTP HEAD request.
|
|
70
|
-
*/
|
|
71
|
-
export declare function head(url: string, options?: Omit<RequestOptions, "body" | "json">): Promise<Response>;
|
|
72
|
-
//# sourceMappingURL=http.d.ts.map
|
package/dist/http.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,GAAG,CAAC;CACZ;AAED;;GAEG;AACH,qBAAa,QAAQ;IACnB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEV,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM;IAMzE;;OAEG;IACH,IAAI,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC;IAIlB;;OAEG;IACH,IAAI,IAAI,MAAM;IAId;;OAEG;IACH,EAAE,IAAI,OAAO;IAIb,QAAQ,IAAI,MAAM;CAGnB;AA+FD;;;;;;;;GAQG;AACH,wBAAsB,GAAG,CACvB,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAAM,GAClD,OAAO,CAAC,QAAQ,CAAC,CAEnB;AAED;;;;;;;;;GASG;AACH,wBAAsB,IAAI,CACxB,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,QAAQ,CAAC,CAEnB;AAED;;GAEG;AACH,wBAAsB,GAAG,CACvB,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,QAAQ,CAAC,CAEnB;AAED;;GAEG;AACH,wBAAsB,GAAG,CACvB,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAAM,GAClD,OAAO,CAAC,QAAQ,CAAC,CAEnB;AAED;;GAEG;AACH,wBAAsB,KAAK,CACzB,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,QAAQ,CAAC,CAEnB;AAED;;GAEG;AACH,wBAAsB,IAAI,CACxB,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAAM,GAClD,OAAO,CAAC,QAAQ,CAAC,CAEnB"}
|
package/dist/http.js
DELETED
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Capsule SDK - HTTP Client
|
|
3
|
-
*
|
|
4
|
-
* This module provides HTTP request functions by calling the host's HTTP implementation.
|
|
5
|
-
* In WASM mode, requests go through the Rust host.
|
|
6
|
-
* In local mode, uses native fetch for testing.
|
|
7
|
-
*/
|
|
8
|
-
import { isWasmMode } from "./hostApi.js";
|
|
9
|
-
/**
|
|
10
|
-
* HTTP Response wrapper with convenient methods.
|
|
11
|
-
*/
|
|
12
|
-
export class Response {
|
|
13
|
-
constructor(status, headers, body) {
|
|
14
|
-
this.status = status;
|
|
15
|
-
this.headers = headers;
|
|
16
|
-
this.body = body;
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Parse response body as JSON.
|
|
20
|
-
*/
|
|
21
|
-
json() {
|
|
22
|
-
return JSON.parse(this.body);
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Get response body as text.
|
|
26
|
-
*/
|
|
27
|
-
text() {
|
|
28
|
-
return this.body;
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Check if response status is 2xx.
|
|
32
|
-
*/
|
|
33
|
-
ok() {
|
|
34
|
-
return this.status >= 200 && this.status < 300;
|
|
35
|
-
}
|
|
36
|
-
toString() {
|
|
37
|
-
return `<Response [${this.status}]>`;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Internal function to make HTTP requests.
|
|
42
|
-
* In WASM mode: calls the host API
|
|
43
|
-
* In local mode: uses fetch
|
|
44
|
-
*/
|
|
45
|
-
async function makeRequest(method, url, options = {}) {
|
|
46
|
-
return isWasmMode()
|
|
47
|
-
? makeHostRequest(method, url, options)
|
|
48
|
-
: makeLocalRequest(method, url, options);
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Make HTTP request using native fetch (local mode only).
|
|
52
|
-
*/
|
|
53
|
-
async function makeLocalRequest(method, url, options = {}) {
|
|
54
|
-
const headers = { ...options.headers };
|
|
55
|
-
let body = options.body;
|
|
56
|
-
if (options.json !== undefined) {
|
|
57
|
-
body = JSON.stringify(options.json);
|
|
58
|
-
headers["Content-Type"] = "application/json";
|
|
59
|
-
}
|
|
60
|
-
const fetchOptions = {
|
|
61
|
-
method,
|
|
62
|
-
headers,
|
|
63
|
-
};
|
|
64
|
-
if (body !== undefined) {
|
|
65
|
-
fetchOptions.body = body;
|
|
66
|
-
}
|
|
67
|
-
const fetchResponse = await fetch(url, fetchOptions);
|
|
68
|
-
const responseText = await fetchResponse.text();
|
|
69
|
-
const responseHeaders = {};
|
|
70
|
-
fetchResponse.headers.forEach((value, key) => {
|
|
71
|
-
responseHeaders[key] = value;
|
|
72
|
-
});
|
|
73
|
-
return new Response(fetchResponse.status, responseHeaders, responseText);
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Make HTTP request via the Rust host (WASM mode).
|
|
77
|
-
*/
|
|
78
|
-
function makeHostRequest(method, url, options = {}) {
|
|
79
|
-
try {
|
|
80
|
-
const hostModule = globalThis["capsule:host/api"];
|
|
81
|
-
if (!hostModule || !hostModule.httpRequest) {
|
|
82
|
-
throw new Error("Host HTTP API not available");
|
|
83
|
-
}
|
|
84
|
-
const headers = [];
|
|
85
|
-
const requestHeaders = options.headers || {};
|
|
86
|
-
for (const [key, value] of Object.entries(requestHeaders)) {
|
|
87
|
-
headers.push([key, value]);
|
|
88
|
-
}
|
|
89
|
-
let body = options.body;
|
|
90
|
-
if (options.json !== undefined) {
|
|
91
|
-
body = JSON.stringify(options.json);
|
|
92
|
-
headers.push(["Content-Type", "application/json"]);
|
|
93
|
-
}
|
|
94
|
-
const result = hostModule.httpRequest(method, url, headers, body);
|
|
95
|
-
const responseHeaders = {};
|
|
96
|
-
for (const [key, value] of result.headers) {
|
|
97
|
-
responseHeaders[key] = value;
|
|
98
|
-
}
|
|
99
|
-
return new Response(result.status, responseHeaders, result.body);
|
|
100
|
-
}
|
|
101
|
-
catch (error) {
|
|
102
|
-
throw new Error(`HTTP request failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Make an HTTP GET request.
|
|
107
|
-
*
|
|
108
|
-
* @example
|
|
109
|
-
* ```typescript
|
|
110
|
-
* const response = http.get("https://api.github.com/zen");
|
|
111
|
-
* console.log(response.text());
|
|
112
|
-
* ```
|
|
113
|
-
*/
|
|
114
|
-
export async function get(url, options = {}) {
|
|
115
|
-
return makeRequest("GET", url, options);
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Make an HTTP POST request.
|
|
119
|
-
*
|
|
120
|
-
* @example
|
|
121
|
-
* ```typescript
|
|
122
|
-
* const response = http.post("https://api.example.com/data", {
|
|
123
|
-
* json: { key: "value" }
|
|
124
|
-
* });
|
|
125
|
-
* ```
|
|
126
|
-
*/
|
|
127
|
-
export async function post(url, options = {}) {
|
|
128
|
-
return makeRequest("POST", url, options);
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* Make an HTTP PUT request.
|
|
132
|
-
*/
|
|
133
|
-
export async function put(url, options = {}) {
|
|
134
|
-
return makeRequest("PUT", url, options);
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Make an HTTP DELETE request.
|
|
138
|
-
*/
|
|
139
|
-
export async function del(url, options = {}) {
|
|
140
|
-
return makeRequest("DELETE", url, options);
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* Make an HTTP PATCH request.
|
|
144
|
-
*/
|
|
145
|
-
export async function patch(url, options = {}) {
|
|
146
|
-
return makeRequest("PATCH", url, options);
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* Make an HTTP HEAD request.
|
|
150
|
-
*/
|
|
151
|
-
export async function head(url, options = {}) {
|
|
152
|
-
return makeRequest("HEAD", url, options);
|
|
153
|
-
}
|
|
154
|
-
//# sourceMappingURL=http.js.map
|
package/dist/http.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
|
package/src/http.ts
DELETED
|
@@ -1,221 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Capsule SDK - HTTP Client
|
|
3
|
-
*
|
|
4
|
-
* This module provides HTTP request functions by calling the host's HTTP implementation.
|
|
5
|
-
* In WASM mode, requests go through the Rust host.
|
|
6
|
-
* In local mode, uses native fetch for testing.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { isWasmMode } from "./hostApi.js";
|
|
10
|
-
|
|
11
|
-
export interface RequestOptions {
|
|
12
|
-
headers?: Record<string, string>;
|
|
13
|
-
body?: string;
|
|
14
|
-
json?: any;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* HTTP Response wrapper with convenient methods.
|
|
19
|
-
*/
|
|
20
|
-
export class Response {
|
|
21
|
-
readonly status: number;
|
|
22
|
-
readonly headers: Record<string, string>;
|
|
23
|
-
readonly body: string;
|
|
24
|
-
|
|
25
|
-
constructor(status: number, headers: Record<string, string>, body: string) {
|
|
26
|
-
this.status = status;
|
|
27
|
-
this.headers = headers;
|
|
28
|
-
this.body = body;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Parse response body as JSON.
|
|
33
|
-
*/
|
|
34
|
-
json<T = any>(): T {
|
|
35
|
-
return JSON.parse(this.body);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Get response body as text.
|
|
40
|
-
*/
|
|
41
|
-
text(): string {
|
|
42
|
-
return this.body;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Check if response status is 2xx.
|
|
47
|
-
*/
|
|
48
|
-
ok(): boolean {
|
|
49
|
-
return this.status >= 200 && this.status < 300;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
toString(): string {
|
|
53
|
-
return `<Response [${this.status}]>`;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Internal function to make HTTP requests.
|
|
59
|
-
* In WASM mode: calls the host API
|
|
60
|
-
* In local mode: uses fetch
|
|
61
|
-
*/
|
|
62
|
-
async function makeRequest(
|
|
63
|
-
method: string,
|
|
64
|
-
url: string,
|
|
65
|
-
options: RequestOptions = {}
|
|
66
|
-
): Promise<Response> {
|
|
67
|
-
return isWasmMode()
|
|
68
|
-
? makeHostRequest(method, url, options)
|
|
69
|
-
: makeLocalRequest(method, url, options);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Make HTTP request using native fetch (local mode only).
|
|
74
|
-
*/
|
|
75
|
-
async function makeLocalRequest(
|
|
76
|
-
method: string,
|
|
77
|
-
url: string,
|
|
78
|
-
options: RequestOptions = {}
|
|
79
|
-
): Promise<Response> {
|
|
80
|
-
const headers: Record<string, string> = { ...options.headers };
|
|
81
|
-
let body: string | undefined = options.body;
|
|
82
|
-
|
|
83
|
-
if (options.json !== undefined) {
|
|
84
|
-
body = JSON.stringify(options.json);
|
|
85
|
-
headers["Content-Type"] = "application/json";
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const fetchOptions: RequestInit = {
|
|
89
|
-
method,
|
|
90
|
-
headers,
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
if (body !== undefined) {
|
|
94
|
-
fetchOptions.body = body;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
const fetchResponse = await fetch(url, fetchOptions);
|
|
98
|
-
const responseText = await fetchResponse.text();
|
|
99
|
-
|
|
100
|
-
const responseHeaders: Record<string, string> = {};
|
|
101
|
-
fetchResponse.headers.forEach((value, key) => {
|
|
102
|
-
responseHeaders[key] = value;
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
return new Response(fetchResponse.status, responseHeaders, responseText);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Make HTTP request via the Rust host (WASM mode).
|
|
110
|
-
*/
|
|
111
|
-
function makeHostRequest(
|
|
112
|
-
method: string,
|
|
113
|
-
url: string,
|
|
114
|
-
options: RequestOptions = {}
|
|
115
|
-
): Response {
|
|
116
|
-
try {
|
|
117
|
-
const hostModule = (globalThis as any)["capsule:host/api"];
|
|
118
|
-
|
|
119
|
-
if (!hostModule || !hostModule.httpRequest) {
|
|
120
|
-
throw new Error("Host HTTP API not available");
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
const headers: [string, string][] = [];
|
|
124
|
-
const requestHeaders = options.headers || {};
|
|
125
|
-
|
|
126
|
-
for (const [key, value] of Object.entries(requestHeaders)) {
|
|
127
|
-
headers.push([key, value]);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
let body: string | undefined = options.body;
|
|
131
|
-
|
|
132
|
-
if (options.json !== undefined) {
|
|
133
|
-
body = JSON.stringify(options.json);
|
|
134
|
-
headers.push(["Content-Type", "application/json"]);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
const result = hostModule.httpRequest(method, url, headers, body);
|
|
138
|
-
|
|
139
|
-
const responseHeaders: Record<string, string> = {};
|
|
140
|
-
for (const [key, value] of result.headers) {
|
|
141
|
-
responseHeaders[key] = value;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
return new Response(result.status, responseHeaders, result.body);
|
|
145
|
-
} catch (error) {
|
|
146
|
-
throw new Error(`HTTP request failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Make an HTTP GET request.
|
|
152
|
-
*
|
|
153
|
-
* @example
|
|
154
|
-
* ```typescript
|
|
155
|
-
* const response = http.get("https://api.github.com/zen");
|
|
156
|
-
* console.log(response.text());
|
|
157
|
-
* ```
|
|
158
|
-
*/
|
|
159
|
-
export async function get(
|
|
160
|
-
url: string,
|
|
161
|
-
options: Omit<RequestOptions, "body" | "json"> = {}
|
|
162
|
-
): Promise<Response> {
|
|
163
|
-
return makeRequest("GET", url, options);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* Make an HTTP POST request.
|
|
168
|
-
*
|
|
169
|
-
* @example
|
|
170
|
-
* ```typescript
|
|
171
|
-
* const response = http.post("https://api.example.com/data", {
|
|
172
|
-
* json: { key: "value" }
|
|
173
|
-
* });
|
|
174
|
-
* ```
|
|
175
|
-
*/
|
|
176
|
-
export async function post(
|
|
177
|
-
url: string,
|
|
178
|
-
options: RequestOptions = {}
|
|
179
|
-
): Promise<Response> {
|
|
180
|
-
return makeRequest("POST", url, options);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Make an HTTP PUT request.
|
|
185
|
-
*/
|
|
186
|
-
export async function put(
|
|
187
|
-
url: string,
|
|
188
|
-
options: RequestOptions = {}
|
|
189
|
-
): Promise<Response> {
|
|
190
|
-
return makeRequest("PUT", url, options);
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
/**
|
|
194
|
-
* Make an HTTP DELETE request.
|
|
195
|
-
*/
|
|
196
|
-
export async function del(
|
|
197
|
-
url: string,
|
|
198
|
-
options: Omit<RequestOptions, "body" | "json"> = {}
|
|
199
|
-
): Promise<Response> {
|
|
200
|
-
return makeRequest("DELETE", url, options);
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
/**
|
|
204
|
-
* Make an HTTP PATCH request.
|
|
205
|
-
*/
|
|
206
|
-
export async function patch(
|
|
207
|
-
url: string,
|
|
208
|
-
options: RequestOptions = {}
|
|
209
|
-
): Promise<Response> {
|
|
210
|
-
return makeRequest("PATCH", url, options);
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* Make an HTTP HEAD request.
|
|
215
|
-
*/
|
|
216
|
-
export async function head(
|
|
217
|
-
url: string,
|
|
218
|
-
options: Omit<RequestOptions, "body" | "json"> = {}
|
|
219
|
-
): Promise<Response> {
|
|
220
|
-
return makeRequest("HEAD", url, options);
|
|
221
|
-
}
|