@exedev/sdk 0.0.6 → 0.2.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/LICENSE +21 -0
- package/README.md +128 -46
- package/dist/client.d.ts +59 -54
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +343 -99
- package/dist/client.js.map +1 -1
- package/dist/commands.gen.d.ts +1468 -0
- package/dist/commands.gen.d.ts.map +1 -0
- package/dist/commands.gen.js +1640 -0
- package/dist/commands.gen.js.map +1 -0
- package/dist/index.d.ts +9 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -3
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +110 -9
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -1
- package/package.json +8 -5
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Bold Software, Inc.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
Official JavaScript/TypeScript SDK for the [exe.dev](https://exe.dev) HTTPS API.
|
|
4
4
|
|
|
5
|
-
## Install
|
|
6
|
-
|
|
7
5
|
```sh
|
|
8
6
|
npm install @exedev/sdk
|
|
9
7
|
```
|
|
@@ -14,71 +12,155 @@ npm install @exedev/sdk
|
|
|
14
12
|
import exedev from "@exedev/sdk";
|
|
15
13
|
|
|
16
14
|
const exe = exedev({ token: process.env.EXE_TOKEN! });
|
|
15
|
+
const vm = await exe.new({ name: "my-vm", image: "ubuntu:24.04", tag: ["dev"] });
|
|
16
|
+
// new waits for SSH by default. No create-then-ssh retry loop is needed.
|
|
17
|
+
try {
|
|
18
|
+
console.log(vm.name, vm.httpsUrl);
|
|
19
|
+
const result = await vm.ssh("uname -a");
|
|
20
|
+
console.log(result.exitCode, result.stdout, result.stderr);
|
|
21
|
+
await vm.shareAdd("friend@example.com", { message: "have a look" });
|
|
22
|
+
} finally {
|
|
23
|
+
await vm.rm();
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Client and VM API
|
|
28
|
+
|
|
29
|
+
`exedev({ token, baseURL?, fetch? })` creates a client. `baseURL` defaults to
|
|
30
|
+
`https://exe.dev`; `fetch` defaults to the global implementation. Named imports
|
|
31
|
+
of `exedev`, `ExedevClient`, and `VM` are also available.
|
|
32
|
+
|
|
33
|
+
- `exe.new(options?)` creates a VM and returns a `VM` object.
|
|
34
|
+
- `exe.ls(nameOrPattern?, options?)` returns `VM[]`.
|
|
35
|
+
- `exe.vm(name)` references an existing VM without making a request.
|
|
36
|
+
- `vm.refresh(options?)` refreshes its metadata and returns the same object.
|
|
37
|
+
- `vm.ssh(command, options?)` runs a shell command on that VM.
|
|
38
|
+
- `vm.cp({ name?, ...options })` copies it and returns a new `VM` object.
|
|
39
|
+
- Lifecycle and VM-scoped commands are methods on the VM: `vm.rm()`,
|
|
40
|
+
`vm.pause()`, `vm.resume()`, `vm.restart()`, `vm.rename(newName)`,
|
|
41
|
+
`vm.resize(options)`, `vm.stat(options)`, `vm.tag(tags)`, `vm.comment(text)`,
|
|
42
|
+
`vm.shareShow()`, `vm.sharePort(port)`, and the other generated VM commands.
|
|
43
|
+
- Account commands remain on the client: `exe.whoami()`, `exe.sshKeyList()`,
|
|
44
|
+
`exe.integrationsList()`, `exe.billingPlan()`, etc.
|
|
45
|
+
|
|
46
|
+
There is no parallel raw-command API or client-level `ssh`, `cp`, or `rm`.
|
|
47
|
+
Options for generated commands retain CLI flag names (for example,
|
|
48
|
+
`{ "no-email": true }`); each method carries the server's help text.
|
|
49
|
+
Methods with known JSON responses reject malformed JSON; other account/VM
|
|
50
|
+
commands may return JSON or text and are typed as `unknown`.
|
|
51
|
+
|
|
52
|
+
`vm.name` is the current name. `vm.httpsUrl`, `vm.sshDest`, and `vm.tags` expose
|
|
53
|
+
common metadata. `vm.info` is a read-only snapshot with `status`, `region`,
|
|
54
|
+
`comment`, `createdAt`, and `setupError` when available. A reference from
|
|
55
|
+
`exe.vm(name)` initially knows only its name. Copies do not invent a web URL;
|
|
56
|
+
call `refresh()` to fetch it. A successful `rename()` updates the same object
|
|
57
|
+
and invalidates old destinations; other references do not automatically change.
|
|
58
|
+
|
|
59
|
+
## Readiness and cancellation
|
|
60
|
+
|
|
61
|
+
`new`, `cp`, `restart`, and `resume` wait for SSH by default. Pass
|
|
62
|
+
`{ waitUntil: "created" }` to return without probing, including when the token
|
|
63
|
+
has no `ssh` permission. `vm.waitUntilReady({ timeoutMs?, signal? })` explicitly
|
|
64
|
+
waits later. The default readiness deadline is 60 seconds **after** creation or
|
|
65
|
+
the lifecycle operation returns, including probe requests and backoff.
|
|
66
|
+
|
|
67
|
+
Readiness runs only the harmless command `true`, retrying transient connection
|
|
68
|
+
failures. It does not wait for application servers or setup scripts, and it
|
|
69
|
+
never retries a user command or the creation request.
|
|
70
|
+
|
|
71
|
+
If waiting fails, `VMReadyError.vm` gives you the VM for inspection or cleanup;
|
|
72
|
+
it is not automatically deleted. All operations accept an `AbortSignal`.
|
|
73
|
+
Caller cancellation preserves `signal.reason`, including during streaming and
|
|
74
|
+
callbacks, rather than wrapping it in another error. An aborted creation may
|
|
75
|
+
still have created a VM; use an explicit name or `ls()` to recover it.
|
|
76
|
+
|
|
77
|
+
## Running commands
|
|
78
|
+
|
|
79
|
+
`vm.ssh()` resolves to `{ exitCode, stdout, stderr, stdoutBytes, stderrBytes,
|
|
80
|
+
captured }`. A nonzero exit code is a result, not an exception. Byte arrays
|
|
81
|
+
preserve binary output; strings are decoded as UTF-8. The command is a shell
|
|
82
|
+
script: quote any untrusted values you interpolate into it.
|
|
17
83
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
84
|
+
```ts
|
|
85
|
+
await vm.ssh("make", {
|
|
86
|
+
capture: false,
|
|
87
|
+
onStdout: (chunk) => { process.stdout.write(chunk); },
|
|
88
|
+
onStderr: (chunk) => { process.stderr.write(chunk); },
|
|
89
|
+
});
|
|
90
|
+
```
|
|
21
91
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
92
|
+
Callbacks are awaited serially, with incremental UTF-8 decoding per stream.
|
|
93
|
+
Their cross-stream order is approximate. Throwing from a callback cancels the
|
|
94
|
+
response and rejects with that error.
|
|
25
95
|
|
|
26
|
-
|
|
27
|
-
|
|
96
|
+
Output is captured by default, with an **8 MiB combined limit** on stdout and
|
|
97
|
+
stderr. Change it with `maxOutputBytes`; exceeding it cancels the response and
|
|
98
|
+
throws `SSHStreamError` with code `output_limit`. Set `capture: false` for
|
|
99
|
+
bounded-memory streaming of arbitrarily long output: callbacks still receive
|
|
100
|
+
it, but result/error output is empty and `captured` is false. The capture limit
|
|
101
|
+
is ignored in this mode. Invalid or oversized NDJSON frames are always rejected.
|
|
28
102
|
|
|
29
|
-
|
|
30
|
-
const info = await exe.stat("my-vm");
|
|
31
|
-
console.log(info);
|
|
103
|
+
## Errors
|
|
32
104
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
105
|
+
- `ExeAPIError`: `operation` and HTTP `status`. The message, stack, and ordinary
|
|
106
|
+
serialization omit request arguments and server response bodies. Explicitly
|
|
107
|
+
call `error.details().body` for diagnostics; this may contain secrets.
|
|
108
|
+
- `ExeProtocolError`: an incompatible response, including malformed JSON or a
|
|
109
|
+
server that does not support NDJSON SSH output.
|
|
110
|
+
- `SSHStreamError`: interrupted/invalid output or a capture limit. `code` is
|
|
111
|
+
`interrupted`, `protocol`, or `output_limit`; getters provide captured partial
|
|
112
|
+
output. The exit status is unknown. `details()` exposes opt-in server diagnostics.
|
|
113
|
+
- `VMReadyError`: readiness failed; `vm` and `cause` are available.
|
|
36
114
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
```
|
|
115
|
+
Errors do not establish that an operation never ran. Do not blindly retry a
|
|
116
|
+
mutation or remote command after a transport failure.
|
|
40
117
|
|
|
41
118
|
## Authentication
|
|
42
119
|
|
|
43
|
-
Generate
|
|
120
|
+
Generate a token via SSH:
|
|
44
121
|
|
|
45
122
|
```sh
|
|
46
|
-
ssh exe.dev
|
|
123
|
+
ssh exe.dev ssh-key generate-api-key --label=my-app --exp=30d --cmds="new,ls,ssh,rm"
|
|
47
124
|
```
|
|
48
125
|
|
|
49
|
-
See the [HTTPS API docs](https://exe.dev/docs/https-api) for
|
|
50
|
-
authentication, token permissions, and scoping.
|
|
126
|
+
See the [HTTPS API docs](https://exe.dev/docs/https-api) for permissions and scoping.
|
|
51
127
|
|
|
52
|
-
##
|
|
128
|
+
## Development
|
|
53
129
|
|
|
54
|
-
|
|
130
|
+
**All of `src/` is generated.** Edit `cmd/gensdkjs` and its TypeScript templates
|
|
131
|
+
in the exe.dev repository, then run `go run ./cmd/gensdkjs` there. Copy the
|
|
132
|
+
outputs into this checkout and test:
|
|
55
133
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
134
|
+
```sh
|
|
135
|
+
npm install
|
|
136
|
+
npm run sync-commands -- ../exe
|
|
137
|
+
npm test
|
|
138
|
+
```
|
|
60
139
|
|
|
61
|
-
|
|
140
|
+
`npm test` builds the package, checks the public TypeScript API, and runs unit
|
|
141
|
+
and live integration tests. Live tests require a tag-scoped token and create,
|
|
142
|
+
copy, execute commands on, restart, rename, and delete their own test VMs.
|
|
143
|
+
They read `$EXE_TOKEN`, or `$EXE_TOKEN_FILE` (a bare token or JSON containing
|
|
144
|
+
`token`), or `~/.config/exedev/sdk-test-token`. The expected tag is `sdk-test`
|
|
145
|
+
(override with `$EXE_TEST_TAG`). To create a test token:
|
|
62
146
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
| `ls()` | List VMs |
|
|
67
|
-
| `whoami()` | Get authenticated user |
|
|
68
|
-
| `stat(vmName)` | Get VM details |
|
|
69
|
-
| `new(name, options?)` | Create a VM |
|
|
70
|
-
| `rm(vmName)` | Delete a VM |
|
|
71
|
-
| `restart(vmName)` | Restart a VM |
|
|
72
|
-
| `rename(oldName, newName)` | Rename a VM |
|
|
73
|
-
| `sshKeyList()` | List SSH keys |
|
|
74
|
-
| `shareShow(vmName)` | Show sharing settings |
|
|
147
|
+
```sh
|
|
148
|
+
ssh exe.dev 'ssh-key generate-api-key --label=sdk-test --tag=sdk-test --exp=30d --cmds="ls,new,whoami,stat,rm,restart,rename,cp,ssh,ssh-key list,share show" --json'
|
|
149
|
+
```
|
|
75
150
|
|
|
76
|
-
|
|
151
|
+
Set `EXE_SKIP_INTEGRATION=1` to run without live access. Set
|
|
152
|
+
`EXE_SKIP_SSH_INTEGRATION=1` to exercise only the live control plane when the
|
|
153
|
+
server has not yet deployed NDJSON SSH support; this explicitly skips live SSH
|
|
154
|
+
and readiness assertions, not the corresponding unit tests. The full live
|
|
155
|
+
suite requires that protocol and does not silently fall back to raw SSH output.
|
|
77
156
|
|
|
78
|
-
|
|
157
|
+
The generator's Go tests check regeneration and command grammar assumptions.
|
|
158
|
+
Server-side wire-contract tests exercise creation, listing, copying, and SSH.
|
|
159
|
+
To run the generated SDK end-to-end against the local Go HTTP/SSH fixture:
|
|
79
160
|
|
|
80
|
-
```
|
|
81
|
-
|
|
161
|
+
```sh
|
|
162
|
+
# In the exe.dev checkout, with this SDK's npm dependencies installed:
|
|
163
|
+
EXE_SDK_JS_DIR=/absolute/path/to/exe-sdk-js go test ./execore -run TestSDKJSHTTP
|
|
82
164
|
```
|
|
83
165
|
|
|
84
166
|
## License
|
package/dist/client.d.ts
CHANGED
|
@@ -1,64 +1,69 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Arg, CallOptions, FlagKind } from "./commands.gen.js";
|
|
2
2
|
export interface ExedevOptions {
|
|
3
|
-
/**
|
|
3
|
+
/** API bearer token. */
|
|
4
4
|
token: string;
|
|
5
|
-
/**
|
|
5
|
+
/** Defaults to https://exe.dev. */
|
|
6
6
|
baseURL?: string;
|
|
7
|
+
/** Defaults to global fetch. */
|
|
8
|
+
fetch?: typeof fetch;
|
|
7
9
|
}
|
|
8
|
-
export interface
|
|
9
|
-
/**
|
|
10
|
-
|
|
10
|
+
export interface SSHOptions extends CallOptions {
|
|
11
|
+
/** Awaited serially as UTF-8 output arrives. Throwing cancels the response. */
|
|
12
|
+
onStdout?: (data: string) => void | Promise<void>;
|
|
13
|
+
onStderr?: (data: string) => void | Promise<void>;
|
|
14
|
+
/** Retain output in the result/error. Set false for bounded-memory streaming. Default true. */
|
|
15
|
+
capture?: boolean;
|
|
16
|
+
/** Maximum combined captured bytes. Default 8 MiB. Ignored with capture: false. */
|
|
17
|
+
maxOutputBytes?: number;
|
|
11
18
|
}
|
|
12
|
-
export interface
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
export interface SSHResult {
|
|
20
|
+
readonly exitCode: number;
|
|
21
|
+
readonly captured: boolean;
|
|
22
|
+
readonly stdout: string;
|
|
23
|
+
readonly stderr: string;
|
|
24
|
+
readonly stdoutBytes: Uint8Array;
|
|
25
|
+
readonly stderrBytes: Uint8Array;
|
|
19
26
|
}
|
|
20
|
-
|
|
21
|
-
/** Execute a raw command against the exe.dev API. */
|
|
22
|
-
exec(command: string, opts?: ExecOptions): Promise<ExecResult>;
|
|
23
|
-
/** List all VMs. */
|
|
24
|
-
ls(opts?: ExecOptions): Promise<VM[]>;
|
|
25
|
-
/** Get the authenticated user's identity. */
|
|
26
|
-
whoami(opts?: ExecOptions): Promise<WhoamiResponse>;
|
|
27
|
-
/** Get detailed status of a VM. */
|
|
28
|
-
stat(vmName: string, opts?: ExecOptions): Promise<StatResponse>;
|
|
29
|
-
/** Create a new VM. Returns the VM name. */
|
|
30
|
-
"new"(name: string, options?: {
|
|
31
|
-
region?: string;
|
|
32
|
-
}, opts?: ExecOptions): Promise<string>;
|
|
33
|
-
/** Delete a VM. */
|
|
34
|
-
rm(vmName: string, opts?: ExecOptions): Promise<void>;
|
|
35
|
-
/** Restart a VM. */
|
|
36
|
-
restart(vmName: string, opts?: ExecOptions): Promise<void>;
|
|
37
|
-
/** Rename a VM. */
|
|
38
|
-
rename(oldName: string, newName: string, opts?: ExecOptions): Promise<void>;
|
|
39
|
-
/** List SSH keys. */
|
|
40
|
-
sshKeyList(opts?: ExecOptions): Promise<string>;
|
|
41
|
-
/** Show sharing settings for a VM. */
|
|
42
|
-
shareShow(vmName: string, opts?: ExecOptions): Promise<string>;
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Create an exe.dev API client.
|
|
46
|
-
*
|
|
47
|
-
* @example
|
|
48
|
-
* ```ts
|
|
49
|
-
* import exedev from "@exedev/sdk";
|
|
50
|
-
*
|
|
51
|
-
* const exe = exedev({ token: process.env.EXE_TOKEN! });
|
|
52
|
-
* const vms = await exe.ls();
|
|
53
|
-
* console.log(vms);
|
|
54
|
-
* ```
|
|
55
|
-
*/
|
|
56
|
-
export default function exedev(opts: ExedevOptions): ExedevClient;
|
|
57
|
-
/** Error thrown when the exe.dev API returns a non-2xx status. */
|
|
27
|
+
/** API rejection. Neither requests nor response bodies appear in default logging. */
|
|
58
28
|
export declare class ExeAPIError extends Error {
|
|
59
|
-
|
|
29
|
+
#private;
|
|
30
|
+
readonly operation: string;
|
|
60
31
|
readonly status: number;
|
|
61
|
-
|
|
62
|
-
|
|
32
|
+
constructor(operation: string, status: number, body: string);
|
|
33
|
+
/** Opt-in server diagnostics; may contain secrets. Does not establish whether an operation ran. */
|
|
34
|
+
details(): {
|
|
35
|
+
body: string;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
export declare class ExeProtocolError extends Error {
|
|
39
|
+
readonly operation: string;
|
|
40
|
+
constructor(operation: string);
|
|
41
|
+
}
|
|
42
|
+
/** The command's exit status is unknown; captured output is only a prefix. Do not blindly retry. */
|
|
43
|
+
export declare class SSHStreamError extends Error {
|
|
44
|
+
#private;
|
|
45
|
+
readonly code: "interrupted" | "protocol" | "output_limit";
|
|
46
|
+
readonly captured: boolean;
|
|
47
|
+
constructor(code: "interrupted" | "protocol" | "output_limit", captured: boolean, stdout: Uint8Array, stderr: Uint8Array, detail?: string);
|
|
48
|
+
get stdoutBytes(): Uint8Array;
|
|
49
|
+
get stderrBytes(): Uint8Array;
|
|
50
|
+
get stdout(): string;
|
|
51
|
+
get stderr(): string;
|
|
52
|
+
/** Opt-in server diagnostics; may contain secrets. */
|
|
53
|
+
details(): {
|
|
54
|
+
message?: string;
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/** Internal transport, deliberately not exported from the package entry point. */
|
|
58
|
+
export declare class Transport {
|
|
59
|
+
#private;
|
|
60
|
+
constructor(opts: ExedevOptions);
|
|
61
|
+
call(path: string, args: readonly Arg[], options: CallOptions | undefined, flags: Readonly<Record<string, FlagKind>>, json?: boolean): Promise<any>;
|
|
62
|
+
ssh(vm: string, command: string, options?: SSHOptions): Promise<SSHResult>;
|
|
63
63
|
}
|
|
64
|
+
export declare function commandLine(path: string, args: readonly Arg[], options: CallOptions | undefined, flags: Readonly<Record<string, FlagKind>>): string;
|
|
65
|
+
export declare function quote(s: string): string;
|
|
66
|
+
/** Stop waiting for an uncooperative fetch/body/callback when the caller cancels. */
|
|
67
|
+
export declare function abortable<T>(promise: Promise<T>, signal?: AbortSignal): Promise<T>;
|
|
68
|
+
export declare function delay(ms: number, signal: AbortSignal): Promise<void>;
|
|
64
69
|
//# sourceMappingURL=client.d.ts.map
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|