@sandbox-kit/sandbox 0.1.0 → 0.1.2
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 +106 -46
- package/dist/client/client.d.ts +7 -126
- package/dist/client/client.js +37 -564
- package/dist/client/errors.d.ts +35 -0
- package/dist/client/errors.js +88 -0
- package/dist/client/operation.d.ts +12 -0
- package/dist/client/operation.js +73 -0
- package/dist/client/sandbox.d.ts +33 -0
- package/dist/client/sandbox.js +160 -0
- package/dist/client/types.d.ts +63 -0
- package/dist/client/types.js +3 -0
- package/dist/client/validation.d.ts +9 -0
- package/dist/client/validation.js +221 -0
- package/dist/contracts/sandbox_data_contracts.d.ts +10 -7
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/internal/net_validate.d.ts +4 -0
- package/dist/internal/net_validate.js +53 -0
- package/package.json +9 -3
package/README.md
CHANGED
|
@@ -1,70 +1,130 @@
|
|
|
1
|
-
#
|
|
1
|
+
# `@sandbox-kit/sandbox`
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
`@sandbox-kit/daytona`
|
|
5
|
-
|
|
6
|
-
`CreateOptions` / `ClientConfig` (`Config` plus `provider`): nested exclusive
|
|
7
|
-
fields (`auth: { apiKey: … }`, `source: { image: … }`, `readiness: { command: … }`),
|
|
8
|
-
plain maps/allowlists (`outboundCidrs: string[]`), and millisecond timeouts.
|
|
9
|
-
`ErrorInfo.field` uses canonical protobuf paths (`CreateField*` / `ConfigField*` /
|
|
10
|
-
`InfoField*`), matching Go. Closing the client releases local provider SDK
|
|
11
|
-
resources only; it does not stop or delete cloud sandboxes.
|
|
3
|
+
Create and manage cloud sandboxes from one TypeScript API. Pick a provider
|
|
4
|
+
package (`@sandbox-kit/daytona` or `@sandbox-kit/modal`), construct a client,
|
|
5
|
+
then create or open sandboxes through the same methods.
|
|
12
6
|
|
|
13
|
-
|
|
7
|
+
Closing a client or handle releases **local** SDK resources only. It does not
|
|
8
|
+
stop, terminate, or delete the remote sandbox.
|
|
14
9
|
|
|
15
|
-
|
|
16
|
-
`Client`, requests are converted before Protovalidate and provider mapping:
|
|
10
|
+
## Install
|
|
17
11
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
4. **Provider mappings** — native SDK calls using the validated wire request.
|
|
12
|
+
```sh
|
|
13
|
+
npm install @sandbox-kit/sandbox @sandbox-kit/daytona
|
|
14
|
+
# or
|
|
15
|
+
npm install @sandbox-kit/sandbox @sandbox-kit/modal
|
|
16
|
+
```
|
|
24
17
|
|
|
25
|
-
|
|
18
|
+
Requires Node.js 20, 22, or 24.15+.
|
|
26
19
|
|
|
27
|
-
##
|
|
20
|
+
## Quick start
|
|
28
21
|
|
|
29
22
|
```ts
|
|
30
|
-
import {
|
|
31
|
-
Client,
|
|
32
|
-
type ClientConfig,
|
|
33
|
-
type CreateOptions,
|
|
34
|
-
} from "@sandbox-kit/sandbox";
|
|
35
23
|
import { daytona } from "@sandbox-kit/daytona";
|
|
24
|
+
import { Client } from "@sandbox-kit/sandbox";
|
|
36
25
|
|
|
37
|
-
|
|
26
|
+
await using client = new Client({
|
|
38
27
|
provider: daytona(),
|
|
39
28
|
auth: { apiKey: { key: process.env.DAYTONA_API_KEY! } },
|
|
40
29
|
timeout: 120_000,
|
|
41
|
-
};
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const sandbox = await client.create();
|
|
33
|
+
console.log(sandbox.id, client.providerName);
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Prefer `await using` when available. Otherwise call `await client.close()` in a
|
|
37
|
+
`finally` block.
|
|
38
|
+
|
|
39
|
+
## Client configuration
|
|
40
|
+
|
|
41
|
+
Pass the provider on `ClientConfig`, then shared settings:
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
| Field | Purpose |
|
|
44
|
+
| ---------- | --------------------------------------------------------------- |
|
|
45
|
+
| `provider` | Provider factory (`daytona()`, `modal()`, …) |
|
|
46
|
+
| `auth` | One credential shape (`apiKey`, `bearerToken`, `tokenPair`, …) |
|
|
47
|
+
| `scope` | App, environment, organization, or project (provider-dependent) |
|
|
48
|
+
| `endpoint` | API URL when the provider supports it |
|
|
49
|
+
| `region` | Target or placement preference |
|
|
50
|
+
| `timeout` | Default operation deadline in **milliseconds** |
|
|
51
|
+
|
|
52
|
+
Omit `auth` when the provider SDK should resolve credentials from its own
|
|
53
|
+
environment. Provider-specific auth and scope rules live in each provider
|
|
54
|
+
package README.
|
|
55
|
+
|
|
56
|
+
## Create a sandbox
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
const sandbox = await client.create({
|
|
44
60
|
source: { image: { reference: "daytonaio/playground:latest" } },
|
|
45
61
|
provisioning: { timeout: 120_000 },
|
|
46
|
-
};
|
|
62
|
+
});
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
`create()` with no options uses the provider default when that is valid (for
|
|
66
|
+
example Daytona's default snapshot). Timeouts and delays are millisecond
|
|
67
|
+
numbers. Nested exclusive fields use shapes like `source: { image: … }` or
|
|
68
|
+
`auth: { apiKey: … }`.
|
|
69
|
+
|
|
70
|
+
## Open an existing sandbox
|
|
47
71
|
|
|
48
|
-
|
|
49
|
-
const
|
|
50
|
-
|
|
72
|
+
```ts
|
|
73
|
+
const attached = await client.attach(id); // provider must support attach
|
|
74
|
+
const fetched = await client.get(id); // provider-verified lookup
|
|
51
75
|
```
|
|
52
76
|
|
|
53
|
-
|
|
54
|
-
otherwise call `await client.close()` in `finally`. Both forms have identical
|
|
55
|
-
cleanup semantics.
|
|
77
|
+
## Sandbox handle
|
|
56
78
|
|
|
57
|
-
|
|
79
|
+
| Method | Purpose |
|
|
80
|
+
| ---------------- | --------------------------------------------- |
|
|
81
|
+
| `id` | Sandbox identifier |
|
|
82
|
+
| `info()` | Copied metadata |
|
|
83
|
+
| `capabilities()` | Lifecycle operations this handle can run |
|
|
84
|
+
| `supports(...)` | Check one capability |
|
|
85
|
+
| `refresh` | Refresh metadata from the provider |
|
|
86
|
+
| `start` | Start |
|
|
87
|
+
| `stop` | Stop (`force` when supported) |
|
|
88
|
+
| `pause` | Pause |
|
|
89
|
+
| `archive` | Archive |
|
|
90
|
+
| `delete` | Delete (`wait` when supported) |
|
|
91
|
+
| `terminate` | Terminate (`wait` when supported) |
|
|
92
|
+
| `close` | Drop the local handle (not the cloud sandbox) |
|
|
58
93
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
| TypeScript | [examples/typescript](../../../examples/typescript/README.md) |
|
|
62
|
-
| Go | [examples/go](../../../examples/go/README.md) |
|
|
94
|
+
Unsupported operations throw before the provider call. Use `supports(...)` when
|
|
95
|
+
the sandbox class may differ (for example Daytona container vs VM).
|
|
63
96
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
97
|
+
## Errors
|
|
98
|
+
|
|
99
|
+
Failures throw `SandboxError` with `kind`, `provider`, `operation`, `field`,
|
|
100
|
+
and `message`:
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
import { Client, SandboxError } from "@sandbox-kit/sandbox";
|
|
104
|
+
|
|
105
|
+
try {
|
|
106
|
+
await client.create({ resources: { cpuCores: -1 } });
|
|
107
|
+
} catch (error) {
|
|
108
|
+
if (error instanceof SandboxError) {
|
|
109
|
+
console.error(error.kind, error.field, error.message);
|
|
110
|
+
} else {
|
|
111
|
+
throw error;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
67
114
|
```
|
|
68
115
|
|
|
69
|
-
|
|
70
|
-
|
|
116
|
+
## Providers
|
|
117
|
+
|
|
118
|
+
| Package | Role |
|
|
119
|
+
| ---------------------- | ----------------- |
|
|
120
|
+
| `@sandbox-kit/daytona` | Daytona sandboxes |
|
|
121
|
+
| `@sandbox-kit/modal` | Modal sandboxes |
|
|
122
|
+
|
|
123
|
+
## Examples
|
|
124
|
+
|
|
125
|
+
Runnable projects:
|
|
126
|
+
[examples/typescript](https://github.com/sandbox-kit/kit/tree/main/examples/typescript).
|
|
127
|
+
|
|
128
|
+
## License
|
|
129
|
+
|
|
130
|
+
MIT
|
package/dist/client/client.d.ts
CHANGED
|
@@ -1,128 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
import type { StripProto } from "#internal/strip_proto.js";
|
|
9
|
-
/** Public credential shapes (no protobuf `$typeName` / getters). */
|
|
10
|
-
export type APIKeyCredentials = StripProto<WireAPIKeyCredentials>;
|
|
11
|
-
export type TokenPairCredentials = StripProto<WireTokenPairCredentials>;
|
|
12
|
-
export type BearerTokenCredentials = StripProto<WireBearerTokenCredentials>;
|
|
13
|
-
export type OAuthCredentials = StripProto<WireOAuthCredentials>;
|
|
14
|
-
export type Scope = StripProto<import("@sandbox-kit/contracts/client").Scope>;
|
|
15
|
-
/** Public auth: set exactly one credential variant (no protobuf `{ case, value }`). */
|
|
16
|
-
export type AuthInput = FlattenOneof<NonNullable<AuthConfig["credentials"]>>;
|
|
17
|
-
/**
|
|
18
|
-
* Public client settings (ms timeout, flat auth).
|
|
19
|
-
* Prefer {@link ClientConfig} at construction (`Config` plus `provider`).
|
|
20
|
-
*/
|
|
21
|
-
export type Config = DurationFieldsToMs<RemapFields<StripProto<MessageInitShape<typeof ConfigSchema>>, {
|
|
22
|
-
auth: AuthInput;
|
|
23
|
-
}>>;
|
|
24
|
-
export declare const ErrorKind: {
|
|
25
|
-
readonly Unknown: ProtoErrorKind.UNKNOWN;
|
|
26
|
-
readonly InvalidArgument: ProtoErrorKind.INVALID_ARGUMENT;
|
|
27
|
-
readonly Unsupported: ProtoErrorKind.UNSUPPORTED;
|
|
28
|
-
readonly Authentication: ProtoErrorKind.AUTHENTICATION;
|
|
29
|
-
readonly PermissionDenied: ProtoErrorKind.PERMISSION_DENIED;
|
|
30
|
-
readonly NotFound: ProtoErrorKind.NOT_FOUND;
|
|
31
|
-
readonly AlreadyExists: ProtoErrorKind.ALREADY_EXISTS;
|
|
32
|
-
readonly Conflict: ProtoErrorKind.CONFLICT;
|
|
33
|
-
readonly RateLimited: ProtoErrorKind.RATE_LIMITED;
|
|
34
|
-
readonly ResourceExhausted: ProtoErrorKind.RESOURCE_EXHAUSTED;
|
|
35
|
-
readonly Timeout: ProtoErrorKind.TIMEOUT;
|
|
36
|
-
readonly Canceled: ProtoErrorKind.CANCELED;
|
|
37
|
-
readonly Unavailable: ProtoErrorKind.UNAVAILABLE;
|
|
38
|
-
readonly InvalidResponse: ProtoErrorKind.INVALID_RESPONSE;
|
|
39
|
-
readonly Internal: ProtoErrorKind.INTERNAL;
|
|
40
|
-
readonly FailedPrecondition: ProtoErrorKind.FAILED_PRECONDITION;
|
|
41
|
-
};
|
|
42
|
-
export type ErrorKind = (typeof ErrorKind)[keyof typeof ErrorKind];
|
|
43
|
-
export interface OperationOptions {
|
|
44
|
-
readonly signal?: AbortSignal;
|
|
45
|
-
/** Operation deadline in milliseconds. */
|
|
46
|
-
readonly timeout?: number;
|
|
47
|
-
}
|
|
48
|
-
/** Public stop options: Kit call options plus optional force. */
|
|
49
|
-
export type StopCallOptions = OperationOptions & {
|
|
50
|
-
readonly force?: boolean;
|
|
51
|
-
};
|
|
52
|
-
/** Public terminate options: Kit call options plus optional wait. */
|
|
53
|
-
export type TerminateCallOptions = OperationOptions & {
|
|
54
|
-
readonly wait?: boolean;
|
|
55
|
-
};
|
|
56
|
-
/** Public delete options: Kit call options plus optional wait. */
|
|
57
|
-
export type DeleteCallOptions = OperationOptions & {
|
|
58
|
-
readonly wait?: boolean;
|
|
59
|
-
};
|
|
60
|
-
export interface Backend {
|
|
61
|
-
readonly name: string;
|
|
62
|
-
create?(request: CreateOptions, options: OperationOptions): Promise<CreateResult>;
|
|
63
|
-
attach?(id: string, options: OperationOptions): Promise<SandboxInfo>;
|
|
64
|
-
refresh?(id: string, options: OperationOptions): Promise<SandboxInfo>;
|
|
65
|
-
start?(id: string, request: StartOptions, options: OperationOptions): Promise<SandboxInfo>;
|
|
66
|
-
stop?(id: string, request: StopOptions, options: OperationOptions): Promise<SandboxInfo>;
|
|
67
|
-
pause?(id: string, request: PauseOptions, options: OperationOptions): Promise<SandboxInfo>;
|
|
68
|
-
terminate?(id: string, request: TerminateOptions, options: OperationOptions): Promise<ExitResult>;
|
|
69
|
-
archive?(id: string, request: ArchiveOptions, options: OperationOptions): Promise<SandboxInfo>;
|
|
70
|
-
delete?(id: string, request: DeleteOptions, options: OperationOptions): Promise<SandboxInfo>;
|
|
71
|
-
close(options: OperationOptions): Promise<void>;
|
|
72
|
-
closeSandbox?(id: string, options: OperationOptions): Promise<void>;
|
|
73
|
-
capabilities?(info: SandboxInfo): readonly LifecycleCapability[];
|
|
74
|
-
}
|
|
75
|
-
export interface Provider {
|
|
76
|
-
readonly name: string;
|
|
77
|
-
/** Receives public {@link Config}. */
|
|
78
|
-
initialize(config: Config): Backend;
|
|
79
|
-
}
|
|
80
|
-
/** Provider selection stays handwritten and is never part of the portable Config message. */
|
|
81
|
-
export type ClientConfig = Config & {
|
|
82
|
-
readonly provider: Provider;
|
|
83
|
-
};
|
|
84
|
-
export declare class SandboxError extends Error {
|
|
85
|
-
readonly kind: ErrorInfo["kind"];
|
|
86
|
-
readonly provider: string;
|
|
87
|
-
readonly operation: string;
|
|
88
|
-
readonly field: string;
|
|
89
|
-
readonly rule: string | undefined;
|
|
90
|
-
readonly statusCode: number | undefined;
|
|
91
|
-
readonly providerCode: string | undefined;
|
|
92
|
-
readonly providerSource: string | undefined;
|
|
93
|
-
constructor(info: ErrorInfo, options?: ErrorOptions);
|
|
94
|
-
}
|
|
95
|
-
export declare function sandboxError(info: ErrorInfo, cause?: unknown): SandboxError;
|
|
96
|
-
/**
|
|
97
|
-
* Rejects public {@link CreateOptions} the shared contract cannot represent.
|
|
98
|
-
* Materializes wire form privately for Protovalidate. Provider-specific checks
|
|
99
|
-
* remain in each provider adapter.
|
|
100
|
-
*/
|
|
101
|
-
export declare function validateCreateOptions(value: CreateOptions, provider?: string, operation?: string): void;
|
|
102
|
-
export declare function validateConfig(value: Config, provider?: string, operation?: string): void;
|
|
103
|
-
interface ClientLifecycle {
|
|
104
|
-
begin(operation: string): () => void;
|
|
105
|
-
isClosed(): boolean;
|
|
106
|
-
}
|
|
107
|
-
declare const sandboxConstructorToken: unique symbol;
|
|
108
|
-
export declare class Sandbox implements AsyncDisposable {
|
|
109
|
-
#private;
|
|
110
|
-
constructor(token: typeof sandboxConstructorToken, backend: Backend, owner: ClientLifecycle, info: SandboxInfo, timeout?: number);
|
|
111
|
-
get id(): string;
|
|
112
|
-
get providerName(): string;
|
|
113
|
-
info(): SandboxInfo;
|
|
114
|
-
capabilities(): readonly LifecycleCapability[];
|
|
115
|
-
supports(capability: LifecycleCapability): boolean;
|
|
116
|
-
refresh(options?: OperationOptions): Promise<SandboxInfo>;
|
|
117
|
-
start(options?: OperationOptions): Promise<SandboxInfo>;
|
|
118
|
-
stop(options?: StopCallOptions): Promise<SandboxInfo>;
|
|
119
|
-
pause(options?: OperationOptions): Promise<SandboxInfo>;
|
|
120
|
-
terminate(options?: TerminateCallOptions): Promise<ExitResult>;
|
|
121
|
-
archive(options?: OperationOptions): Promise<SandboxInfo>;
|
|
122
|
-
delete(options?: DeleteCallOptions): Promise<SandboxInfo>;
|
|
123
|
-
close(options?: OperationOptions): Promise<void>;
|
|
124
|
-
[Symbol.asyncDispose](): Promise<void>;
|
|
125
|
-
}
|
|
1
|
+
import type { CreateOptions } from "#contracts/sandbox_data_contracts.js";
|
|
2
|
+
import { Sandbox } from "#client/sandbox.js";
|
|
3
|
+
import type { ClientConfig, OperationOptions } from "#client/types.js";
|
|
4
|
+
export type { APIKeyCredentials, AuthInput, Backend, BearerTokenCredentials, ClientConfig, Config, DeleteCallOptions, OAuthCredentials, OperationOptions, Provider, Scope, StopCallOptions, TerminateCallOptions, TokenPairCredentials, } from "#client/types.js";
|
|
5
|
+
export { ErrorKind, SandboxError, sandboxError } from "#client/errors.js";
|
|
6
|
+
export { Sandbox } from "#client/sandbox.js";
|
|
7
|
+
export { validateConfig, validateCreateOptions } from "#client/validation.js";
|
|
126
8
|
export declare class Client implements AsyncDisposable {
|
|
127
9
|
#private;
|
|
128
10
|
constructor(config: ClientConfig);
|
|
@@ -133,4 +15,3 @@ export declare class Client implements AsyncDisposable {
|
|
|
133
15
|
close(options?: OperationOptions): Promise<void>;
|
|
134
16
|
[Symbol.asyncDispose](): Promise<void>;
|
|
135
17
|
}
|
|
136
|
-
export {};
|