@brimble/sandbox 0.1.0 → 0.1.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.
Files changed (48) hide show
  1. package/dist/package.json +9 -2
  2. package/package.json +7 -3
  3. package/CODEX.md +0 -188
  4. package/PLAN.md +0 -364
  5. package/src/client.ts +0 -61
  6. package/src/constants.ts +0 -17
  7. package/src/enums/code-language.ts +0 -4
  8. package/src/enums/destroy-reason.ts +0 -8
  9. package/src/enums/destroy-timeout.ts +0 -8
  10. package/src/enums/index.ts +0 -7
  11. package/src/enums/sandbox-status.ts +0 -9
  12. package/src/enums/snapshot-mode.ts +0 -4
  13. package/src/enums/snapshot-status.ts +0 -5
  14. package/src/enums/volume-type.ts +0 -3
  15. package/src/errors/index.ts +0 -2
  16. package/src/errors/sandbox-api-error.ts +0 -54
  17. package/src/index.ts +0 -71
  18. package/src/resources/exec.ts +0 -56
  19. package/src/resources/files.ts +0 -46
  20. package/src/resources/index.ts +0 -8
  21. package/src/resources/path.ts +0 -16
  22. package/src/resources/sandbox-handle.ts +0 -215
  23. package/src/resources/sandboxes.ts +0 -297
  24. package/src/resources/scoped-sandbox.ts +0 -65
  25. package/src/resources/snapshots.ts +0 -104
  26. package/src/resources/stats.ts +0 -30
  27. package/src/resources/volumes.ts +0 -95
  28. package/src/transport/auth.ts +0 -4
  29. package/src/transport/http.ts +0 -501
  30. package/src/transport/pagination.ts +0 -10
  31. package/src/types/exec.ts +0 -42
  32. package/src/types/files.ts +0 -1
  33. package/src/types/index.ts +0 -23
  34. package/src/types/pagination.ts +0 -16
  35. package/src/types/region.ts +0 -19
  36. package/src/types/sandbox.ts +0 -103
  37. package/src/types/snapshot.ts +0 -17
  38. package/src/types/stats.ts +0 -35
  39. package/src/types/template.ts +0 -5
  40. package/src/types/volume.ts +0 -26
  41. package/test/integration/sandbox.integration.test.ts +0 -269
  42. package/test/unit/client.test.ts +0 -87
  43. package/test/unit/sandboxes.test.ts +0 -69
  44. package/test/unit/transport.test.ts +0 -126
  45. package/test/unit/volumes.test.ts +0 -122
  46. package/tsconfig.json +0 -16
  47. package/vitest.config.ts +0 -12
  48. package/vitest.integration.config.ts +0 -15
@@ -1,297 +0,0 @@
1
- import { DEFAULT_PAGE, DEFAULT_PAGE_LIMIT } from '../constants';
2
- import { VolumeType } from '../enums';
3
- import type { RequestOptions } from '../transport/http';
4
- import { HttpTransport } from '../transport/http';
5
- import { toPaginationQuery } from '../transport/pagination';
6
- import type {
7
- AckMessage,
8
- CreateSandboxRequest,
9
- CreateSandboxResult,
10
- CreateSandboxWithVolumeInput,
11
- CreateVolumeInput,
12
- Paginated,
13
- Sandbox,
14
- SandboxReadyRequestOptions,
15
- SandboxRegionInput,
16
- SandboxRegionsResult,
17
- SandboxTemplate,
18
- TeamScopedPagination,
19
- Volume,
20
- WaitPreference,
21
- } from '../types';
22
- import { SandboxHandle } from './sandbox-handle';
23
- import { ScopedSandboxResource } from './scoped-sandbox';
24
- import { VolumesResource } from './volumes';
25
-
26
- export type QuickstartSandboxInput = Omit<CreateSandboxRequest, 'template' | 'persistent' | 'persistentDiskGB'> & {
27
- template?: string;
28
- persistentDiskGB?: number;
29
- waitUntilReady?: WaitPreference;
30
- };
31
-
32
- export class SandboxesResource {
33
- private readonly transport: HttpTransport;
34
- private readonly volumes: VolumesResource;
35
-
36
- /** @internal Create the sandboxes resource wrapper. */
37
- public constructor(transport: HttpTransport) {
38
- this.transport = transport;
39
- this.volumes = new VolumesResource(transport);
40
- }
41
-
42
- /**
43
- * Create a new sandbox.
44
- * Region is optional; when omitted this SDK picks the first available region.
45
- * The sandbox starts asynchronously, so fetch it until `status` is `ready`
46
- * before running commands or file operations.
47
- */
48
- public async create(input: CreateSandboxRequest, options?: RequestOptions): Promise<SandboxHandle> {
49
- const region = await this.resolveRegionId(input.region, options);
50
- const body: CreateSandboxRequest = {
51
- ...input,
52
- region,
53
- };
54
-
55
- const result = (await this.transport.requestJson<CreateSandboxResult>({
56
- endpoint: '/sandboxes',
57
- method: 'POST',
58
- body,
59
- ...options,
60
- })) as CreateSandboxResult;
61
-
62
- return new SandboxHandle(this, result);
63
- }
64
-
65
- /** Create a sandbox and wait until it is `ready` before returning it. */
66
- public async createReady(input: CreateSandboxRequest, options: SandboxReadyRequestOptions = {}): Promise<SandboxHandle> {
67
- const sandbox = await this.create(input, options.request);
68
- await sandbox.waitUntilReady(options.wait);
69
- return sandbox;
70
- }
71
-
72
- /**
73
- * Create a volume and then create a sandbox attached to that volume.
74
- * This is the one-call helper for persistent sandbox workflows.
75
- */
76
- public async withVolume(input: CreateSandboxWithVolumeInput, options?: RequestOptions): Promise<SandboxHandle> {
77
- const region = await this.resolveRegionId(input.sandbox.region ?? input.volume.region, options);
78
-
79
- const volume = await this.volumes.create(
80
- {
81
- ...input.volume,
82
- region,
83
- type: VolumeType.Sandbox,
84
- },
85
- options,
86
- );
87
-
88
- return this.create(
89
- {
90
- ...input.sandbox,
91
- region,
92
- volumeId: volume.id,
93
- },
94
- options,
95
- );
96
- }
97
-
98
- /** Create a sandbox-scoped volume with package-level defaults and validation. */
99
- public createVolume(input: CreateVolumeInput, options?: RequestOptions): Promise<Volume> {
100
- return this.volumes.create(input, options);
101
- }
102
-
103
- /** List your sandboxes with pagination. */
104
- public async list(query: TeamScopedPagination = {}, options?: RequestOptions): Promise<Paginated<SandboxHandle>> {
105
- const page = await this.listData(query, options);
106
-
107
- return {
108
- ...page,
109
- data: page.data.map((sandbox) => new SandboxHandle(this, sandbox)),
110
- };
111
- }
112
-
113
- /** Iterate over all sandbox handles across paginated results. */
114
- public async *iterate(query: TeamScopedPagination = {}, options?: RequestOptions): AsyncGenerator<SandboxHandle> {
115
- const limit = query.limit ?? DEFAULT_PAGE_LIMIT;
116
- let page = query.page ?? DEFAULT_PAGE;
117
-
118
- while (true) {
119
- const paginated = await this.list({ ...query, page, limit }, options);
120
-
121
- for (const sandbox of paginated.data) {
122
- yield sandbox;
123
- }
124
-
125
- if (page >= paginated.totalPages || paginated.data.length === 0) {
126
- return;
127
- }
128
-
129
- page += 1;
130
- }
131
- }
132
-
133
- /** Fetch one sandbox handle by id. */
134
- public async get(sandboxId: string, options?: RequestOptions): Promise<SandboxHandle> {
135
- const sandbox = await this.getData(sandboxId, options);
136
- return new SandboxHandle(this, sandbox);
137
- }
138
-
139
- /** Fetch one sandbox and wait for `ready` before returning the handle. */
140
- public async getReady(sandboxId: string, options: SandboxReadyRequestOptions = {}): Promise<SandboxHandle> {
141
- const sandbox = await this.get(sandboxId, options.request);
142
- await sandbox.waitUntilReady(options.wait);
143
- return sandbox;
144
- }
145
-
146
- /** @internal Fetch raw sandbox payload by id. */
147
- public getData(sandboxId: string, options?: RequestOptions): Promise<Sandbox> {
148
- return this.transport.requestJson<Sandbox>({
149
- endpoint: `/sandboxes/${sandboxId}`,
150
- method: 'GET',
151
- ...options,
152
- }) as Promise<Sandbox>;
153
- }
154
-
155
- /** @internal Fetch raw paginated sandbox payload. */
156
- public listData(query: TeamScopedPagination = {}, options?: RequestOptions): Promise<Paginated<Sandbox>> {
157
- const params = toPaginationQuery(query);
158
-
159
- if (query.teamId) {
160
- params.set('teamId', query.teamId);
161
- }
162
-
163
- return this.transport.requestJson<Paginated<Sandbox>>({
164
- endpoint: '/sandboxes',
165
- method: 'GET',
166
- query: params,
167
- ...options,
168
- }) as Promise<Paginated<Sandbox>>;
169
- }
170
-
171
- /** List regions where sandboxes can be provisioned. */
172
- public listRegions(options?: RequestOptions): Promise<SandboxRegionsResult> {
173
- return this.transport.requestJson<SandboxRegionsResult>({
174
- endpoint: '/sandboxes/regions',
175
- method: 'GET',
176
- ...options,
177
- }) as Promise<SandboxRegionsResult>;
178
- }
179
-
180
- /** List sandbox templates available for create operations. */
181
- public async listTemplates(options?: RequestOptions): Promise<SandboxTemplate[]> {
182
- const payload = await this.transport.requestJson<unknown>({
183
- endpoint: '/sandbox/templates',
184
- method: 'GET',
185
- ...options,
186
- });
187
-
188
- if (Array.isArray(payload)) {
189
- return payload as SandboxTemplate[];
190
- }
191
-
192
- if (payload && typeof payload === 'object' && 'templates' in payload) {
193
- const templates = (payload as { templates?: unknown }).templates;
194
- if (Array.isArray(templates)) {
195
- return templates as SandboxTemplate[];
196
- }
197
- }
198
-
199
- return [];
200
- }
201
-
202
- /** Fetch one template by name from the template catalog. */
203
- public async getTemplate(templateName: string, options?: RequestOptions): Promise<SandboxTemplate | undefined> {
204
- const templates = await this.listTemplates(options);
205
- return templates.find((template) => template.name === templateName);
206
- }
207
-
208
- /** Destroy a sandbox (idempotent). */
209
- public async destroy(sandboxId: string, options?: RequestOptions): Promise<void> {
210
- await this.transport.requestJson({
211
- endpoint: `/sandboxes/${sandboxId}`,
212
- method: 'DELETE',
213
- ...options,
214
- });
215
- }
216
-
217
- /** Request sandbox pause. */
218
- public pause(sandboxId: string, options?: RequestOptions): Promise<AckMessage | undefined> {
219
- return this.transport.requestJson<AckMessage>({
220
- endpoint: `/sandboxes/${sandboxId}/pause`,
221
- method: 'POST',
222
- ...options,
223
- });
224
- }
225
-
226
- /** Request sandbox resume. */
227
- public resume(sandboxId: string, options?: RequestOptions): Promise<AckMessage | undefined> {
228
- return this.transport.requestJson<AckMessage>({
229
- endpoint: `/sandboxes/${sandboxId}/resume`,
230
- method: 'POST',
231
- ...options,
232
- });
233
- }
234
-
235
- /** Use runtime operations for a specific sandbox id. */
236
- public use(sandboxId: string): ScopedSandboxResource {
237
- return new ScopedSandboxResource(this.transport, sandboxId);
238
- }
239
-
240
- /** Opinionated Node.js quickstart (persistent sandbox + optional wait). */
241
- public async quickstartNode(input: QuickstartSandboxInput = {}, options?: RequestOptions): Promise<SandboxHandle> {
242
- return this.quickstart({
243
- ...input,
244
- template: input.template ?? 'node-22',
245
- persistentDiskGB: input.persistentDiskGB ?? 20,
246
- }, options);
247
- }
248
-
249
- /** Opinionated Python quickstart (persistent sandbox + optional wait). */
250
- public async quickstartPython(input: QuickstartSandboxInput = {}, options?: RequestOptions): Promise<SandboxHandle> {
251
- return this.quickstart({
252
- ...input,
253
- template: input.template ?? 'python-3.12',
254
- persistentDiskGB: input.persistentDiskGB ?? 20,
255
- }, options);
256
- }
257
-
258
- private async quickstart(input: QuickstartSandboxInput, options?: RequestOptions): Promise<SandboxHandle> {
259
- const { waitUntilReady, persistentDiskGB, ...createInput } = input;
260
-
261
- const sandbox = await this.create(
262
- {
263
- ...createInput,
264
- persistent: true,
265
- persistentDiskGB,
266
- },
267
- options,
268
- );
269
-
270
- if (waitUntilReady === false) {
271
- return sandbox;
272
- }
273
-
274
- if (typeof waitUntilReady === 'object') {
275
- await sandbox.waitUntilReady(waitUntilReady);
276
- return sandbox;
277
- }
278
-
279
- await sandbox.waitUntilReady();
280
- return sandbox;
281
- }
282
-
283
- private async resolveRegionId(region: SandboxRegionInput | undefined, options?: RequestOptions): Promise<string> {
284
- if (region && region !== 'auto') {
285
- return region;
286
- }
287
-
288
- const { regions } = await this.listRegions(options);
289
- const regionId = regions[0]?.id;
290
-
291
- if (!regionId) {
292
- throw new Error('No sandbox regions available for this account.');
293
- }
294
-
295
- return regionId;
296
- }
297
- }
@@ -1,65 +0,0 @@
1
- import { ExecResource } from './exec';
2
- import { FilesResource } from './files';
3
- import { SnapshotScopeResource } from './snapshots';
4
- import { StatsResource } from './stats';
5
- import { HttpTransport } from '../transport/http';
6
- import type { CodeInput, CreateSnapshotInput, ExecInput, ExecResult, FileUploadBody, Paginated, Pagination, Snapshot, Stats, StatsQuery } from '../types';
7
- import type { RequestOptions } from '../transport/http';
8
-
9
- export class ScopedSandboxResource {
10
- /** Lower-level exec/code runner resource. */
11
- public readonly execResource: ExecResource;
12
- /** File upload/download resource. */
13
- public readonly files: FilesResource;
14
- /** Snapshot resource scoped to this sandbox. */
15
- public readonly snapshots: SnapshotScopeResource;
16
- /** Stats resource scoped to this sandbox. */
17
- public readonly statsResource: StatsResource;
18
-
19
- /** @internal Create a sandbox-scoped resource wrapper. */
20
- public constructor(transport: HttpTransport, sandboxId: string) {
21
- this.execResource = new ExecResource(transport, sandboxId);
22
- this.files = new FilesResource(transport, sandboxId);
23
- this.snapshots = new SnapshotScopeResource(transport, sandboxId);
24
- this.statsResource = new StatsResource(transport, sandboxId);
25
- }
26
-
27
- /** Run a shell command in this sandbox. */
28
- public exec(input: ExecInput & { stream: true }, options?: RequestOptions): Promise<ReadableStream<Uint8Array>>;
29
- public exec(input: ExecInput, options?: RequestOptions): Promise<ExecResult>;
30
- public exec(input: ExecInput, options?: RequestOptions): Promise<ExecResult | ReadableStream<Uint8Array>> {
31
- return this.execResource.exec(input, options);
32
- }
33
-
34
- /** Run a code snippet in this sandbox. */
35
- public runCode(input: CodeInput & { stream: true }, options?: RequestOptions): Promise<ReadableStream<Uint8Array>>;
36
- public runCode(input: CodeInput, options?: RequestOptions): Promise<ExecResult>;
37
- public runCode(input: CodeInput, options?: RequestOptions): Promise<ExecResult | ReadableStream<Uint8Array>> {
38
- return this.execResource.runCode(input, options);
39
- }
40
-
41
- /** Upload bytes to a file path inside this sandbox. */
42
- public putFile(path: string, body: FileUploadBody, options?: RequestOptions): Promise<void> {
43
- return this.files.put(path, body, options);
44
- }
45
-
46
- /** Download file bytes from this sandbox as a stream. */
47
- public getFile(path: string, options?: RequestOptions): Promise<ReadableStream<Uint8Array>> {
48
- return this.files.get(path, options);
49
- }
50
-
51
- /** Fetch CPU, memory, and network stats for this sandbox. */
52
- public stats(query: StatsQuery = {}, options?: RequestOptions): Promise<Stats> {
53
- return this.statsResource.stats(query, options);
54
- }
55
-
56
- /** Create a snapshot for this sandbox. */
57
- public createSnapshot(input: CreateSnapshotInput, options?: RequestOptions): Promise<Snapshot> {
58
- return this.snapshots.create(input, options);
59
- }
60
-
61
- /** List snapshots for this sandbox. */
62
- public listSnapshots(query: Pagination = {}, options?: RequestOptions): Promise<Paginated<Snapshot>> {
63
- return this.snapshots.list(query, options);
64
- }
65
- }
@@ -1,104 +0,0 @@
1
- import type { RequestOptions } from '../transport/http';
2
- import { HttpTransport } from '../transport/http';
3
- import { toPaginationQuery } from '../transport/pagination';
4
- import type { CreateSnapshotInput, Paginated, Pagination, Snapshot } from '../types';
5
- import { DEFAULT_PAGE, DEFAULT_PAGE_LIMIT } from '../constants';
6
-
7
- export class SnapshotScopeResource {
8
- private readonly transport: HttpTransport;
9
- private readonly sandboxId: string;
10
-
11
- /** @internal Create a sandbox-scoped snapshots wrapper. */
12
- public constructor(transport: HttpTransport, sandboxId: string) {
13
- this.transport = transport;
14
- this.sandboxId = sandboxId;
15
- }
16
-
17
- /** Create a snapshot for this specific sandbox. */
18
- public create(input: CreateSnapshotInput, options?: RequestOptions): Promise<Snapshot> {
19
- return this.transport.requestJson<Snapshot>({
20
- endpoint: `/sandboxes/${this.sandboxId}/snapshots`,
21
- method: 'POST',
22
- body: input,
23
- ...options,
24
- }) as Promise<Snapshot>;
25
- }
26
-
27
- /** List snapshots for this specific sandbox. */
28
- public list(query: Pagination = {}, options?: RequestOptions): Promise<Paginated<Snapshot>> {
29
- return this.transport.requestJson<Paginated<Snapshot>>({
30
- endpoint: `/sandboxes/${this.sandboxId}/snapshots`,
31
- method: 'GET',
32
- query: toPaginationQuery(query),
33
- ...options,
34
- }) as Promise<Paginated<Snapshot>>;
35
- }
36
-
37
- /** Iterate over all snapshots for this sandbox across pages. */
38
- public async *iterate(query: Pagination = {}, options?: RequestOptions): AsyncGenerator<Snapshot> {
39
- const limit = query.limit ?? DEFAULT_PAGE_LIMIT;
40
- let page = query.page ?? DEFAULT_PAGE;
41
-
42
- while (true) {
43
- const paginated = await this.list({ ...query, page, limit }, options);
44
-
45
- for (const snapshot of paginated.data) {
46
- yield snapshot;
47
- }
48
-
49
- if (page >= paginated.totalPages || paginated.data.length === 0) {
50
- return;
51
- }
52
-
53
- page += 1;
54
- }
55
- }
56
- }
57
-
58
- export class SnapshotsResource {
59
- private readonly transport: HttpTransport;
60
-
61
- /** @internal Create the global snapshots resource wrapper. */
62
- public constructor(transport: HttpTransport) {
63
- this.transport = transport;
64
- }
65
-
66
- /** List all snapshots owned by the current caller. */
67
- public listAll(query: Pagination = {}, options?: RequestOptions): Promise<Paginated<Snapshot>> {
68
- return this.transport.requestJson<Paginated<Snapshot>>({
69
- endpoint: '/sandboxes/snapshots',
70
- method: 'GET',
71
- query: toPaginationQuery(query),
72
- ...options,
73
- }) as Promise<Paginated<Snapshot>>;
74
- }
75
-
76
- /** Iterate over all snapshots owned by the caller across pages. */
77
- public async *iterateAll(query: Pagination = {}, options?: RequestOptions): AsyncGenerator<Snapshot> {
78
- const limit = query.limit ?? DEFAULT_PAGE_LIMIT;
79
- let page = query.page ?? DEFAULT_PAGE;
80
-
81
- while (true) {
82
- const paginated = await this.listAll({ ...query, page, limit }, options);
83
-
84
- for (const snapshot of paginated.data) {
85
- yield snapshot;
86
- }
87
-
88
- if (page >= paginated.totalPages || paginated.data.length === 0) {
89
- return;
90
- }
91
-
92
- page += 1;
93
- }
94
- }
95
-
96
- /** Delete a snapshot by id. */
97
- public async delete(snapshotId: string, options?: RequestOptions): Promise<void> {
98
- await this.transport.requestJson({
99
- endpoint: `/sandboxes/snapshots/${snapshotId}`,
100
- method: 'DELETE',
101
- ...options,
102
- });
103
- }
104
- }
@@ -1,30 +0,0 @@
1
- import type { Stats, StatsQuery } from '../types';
2
- import type { RequestOptions } from '../transport/http';
3
- import { HttpTransport } from '../transport/http';
4
-
5
- export class StatsResource {
6
- private readonly transport: HttpTransport;
7
- private readonly sandboxId: string;
8
-
9
- /** @internal Create the stats wrapper for one sandbox. */
10
- public constructor(transport: HttpTransport, sandboxId: string) {
11
- this.transport = transport;
12
- this.sandboxId = sandboxId;
13
- }
14
-
15
- /** Fetch sandbox usage stats for a lookback window. */
16
- public stats(query: StatsQuery = {}, options?: RequestOptions): Promise<Stats> {
17
- const params = new URLSearchParams();
18
-
19
- if (query.hoursAgo !== undefined) {
20
- params.set('hoursAgo', String(query.hoursAgo));
21
- }
22
-
23
- return this.transport.requestJson<Stats>({
24
- endpoint: `/sandboxes/${this.sandboxId}/stats`,
25
- method: 'GET',
26
- query: params,
27
- ...options,
28
- }) as Promise<Stats>;
29
- }
30
- }
@@ -1,95 +0,0 @@
1
- import type { RequestOptions } from '../transport/http';
2
- import { HttpTransport } from '../transport/http';
3
- import { toPaginationQuery } from '../transport/pagination';
4
- import { VolumeType } from '../enums';
5
- import { DEFAULT_PAGE, DEFAULT_PAGE_LIMIT, MIN_VOLUME_SIZE_GB } from '../constants';
6
- import type { CreateVolumeInput, Paginated, TeamScopedPagination, Volume } from '../types';
7
-
8
- export class VolumesResource {
9
- private readonly transport: HttpTransport;
10
-
11
- /** @internal Create the volumes resource wrapper. */
12
- public constructor(transport: HttpTransport) {
13
- this.transport = transport;
14
- }
15
-
16
- /** List your volumes with pagination. */
17
- public list(query: TeamScopedPagination = {}, options?: RequestOptions): Promise<Paginated<Volume>> {
18
- const params = toPaginationQuery(query);
19
-
20
- if (query.teamId) {
21
- params.set('teamId', query.teamId);
22
- }
23
-
24
- return this.transport.requestJson<Paginated<Volume>>({
25
- endpoint: '/volumes',
26
- method: 'GET',
27
- query: params,
28
- ...options,
29
- }) as Promise<Paginated<Volume>>;
30
- }
31
-
32
- /** Iterate over all volumes across paginated results. */
33
- public async *iterate(query: TeamScopedPagination = {}, options?: RequestOptions): AsyncGenerator<Volume> {
34
- const limit = query.limit ?? DEFAULT_PAGE_LIMIT;
35
- let page = query.page ?? DEFAULT_PAGE;
36
-
37
- while (true) {
38
- const paginated = await this.list({ ...query, page, limit }, options);
39
-
40
- for (const volume of paginated.data) {
41
- yield volume;
42
- }
43
-
44
- if (page >= paginated.totalPages || paginated.data.length === 0) {
45
- return;
46
- }
47
-
48
- page += 1;
49
- }
50
- }
51
-
52
- /**
53
- * Create a new volume.
54
- * This SDK accepts only `type: "sandbox"` and defaults to it when omitted.
55
- */
56
- public create(input: CreateVolumeInput, options?: RequestOptions): Promise<Volume> {
57
- if (input.type && input.type !== VolumeType.Sandbox) {
58
- throw new Error('Only volume type "sandbox" is supported by this package.');
59
- }
60
-
61
- if (input.sizeGB < MIN_VOLUME_SIZE_GB) {
62
- throw new Error(`Volume size must be at least ${MIN_VOLUME_SIZE_GB}GB.`);
63
- }
64
-
65
- const body: CreateVolumeInput = {
66
- ...input,
67
- type: VolumeType.Sandbox,
68
- };
69
-
70
- return this.transport.requestJson<Volume>({
71
- endpoint: '/volumes',
72
- method: 'POST',
73
- body,
74
- ...options,
75
- }) as Promise<Volume>;
76
- }
77
-
78
- /** Fetch one volume by id. */
79
- public get(volumeId: string, options?: RequestOptions): Promise<Volume> {
80
- return this.transport.requestJson<Volume>({
81
- endpoint: `/volumes/${volumeId}`,
82
- method: 'GET',
83
- ...options,
84
- }) as Promise<Volume>;
85
- }
86
-
87
- /** Delete a volume by id. */
88
- public async delete(volumeId: string, options?: RequestOptions): Promise<void> {
89
- await this.transport.requestJson({
90
- endpoint: `/volumes/${volumeId}`,
91
- method: 'DELETE',
92
- ...options,
93
- });
94
- }
95
- }
@@ -1,4 +0,0 @@
1
- /** Build the header value used by `x-brimble-key`. */
2
- export function buildApiKeyHeader(apiKey: string): string {
3
- return apiKey;
4
- }