@daytonaio/sdk 0.19.0-alpha.3 → 0.19.0-alpha.4

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.
@@ -0,0 +1,497 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright 2025 Daytona Platforms Inc.
4
+ * SPDX-License-Identifier: AGPL-3.0
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || (function () {
23
+ var ownKeys = function(o) {
24
+ ownKeys = Object.getOwnPropertyNames || function (o) {
25
+ var ar = [];
26
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
27
+ return ar;
28
+ };
29
+ return ownKeys(o);
30
+ };
31
+ return function (mod) {
32
+ if (mod && mod.__esModule) return mod;
33
+ var result = {};
34
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
35
+ __setModuleDefault(result, mod);
36
+ return result;
37
+ };
38
+ })();
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.Daytona = exports.CodeLanguage = void 0;
41
+ const api_client_1 = require("@daytonaio/api-client");
42
+ const axios_1 = __importStar(require("axios"));
43
+ const dotenv = __importStar(require("dotenv"));
44
+ const SandboxPythonCodeToolbox_1 = require("./code-toolbox/SandboxPythonCodeToolbox");
45
+ const SandboxTsCodeToolbox_1 = require("./code-toolbox/SandboxTsCodeToolbox");
46
+ const DaytonaError_1 = require("./errors/DaytonaError");
47
+ const Image_1 = require("./Image");
48
+ const ObjectStorage_1 = require("./ObjectStorage");
49
+ const Sandbox_1 = require("./Sandbox");
50
+ const Stream_1 = require("./utils/Stream");
51
+ const Volume_1 = require("./Volume");
52
+ /**
53
+ * Supported programming languages for code execution
54
+ */
55
+ var CodeLanguage;
56
+ (function (CodeLanguage) {
57
+ CodeLanguage["PYTHON"] = "python";
58
+ CodeLanguage["TYPESCRIPT"] = "typescript";
59
+ CodeLanguage["JAVASCRIPT"] = "javascript";
60
+ })(CodeLanguage || (exports.CodeLanguage = CodeLanguage = {}));
61
+ /**
62
+ * Main class for interacting with the Daytona API.
63
+ * Provides methods for creating, managing, and interacting with Daytona Sandboxes.
64
+ * Can be initialized either with explicit configuration or using environment variables.
65
+ *
66
+ * @property {VolumeService} volume - Service for managing Daytona Volumes
67
+ *
68
+ * @example
69
+ * // Using environment variables
70
+ * // Uses DAYTONA_API_KEY, DAYTONA_API_URL, DAYTONA_TARGET
71
+ * const daytona = new Daytona();
72
+ * const sandbox = await daytona.create();
73
+ *
74
+ * @example
75
+ * // Using explicit configuration
76
+ * const config: DaytonaConfig = {
77
+ * apiKey: "your-api-key",
78
+ * apiUrl: "https://your-api.com",
79
+ * target: "us"
80
+ * };
81
+ * const daytona = new Daytona(config);
82
+ *
83
+ * @class
84
+ */
85
+ class Daytona {
86
+ /**
87
+ * Creates a new Daytona client instance.
88
+ *
89
+ * @param {DaytonaConfig} [config] - Configuration options
90
+ * @throws {DaytonaError} - `DaytonaError` - When API key is missing
91
+ */
92
+ constructor(config) {
93
+ this.remove = this.delete.bind(this);
94
+ dotenv.config();
95
+ dotenv.config({ path: '.env.local', override: true });
96
+ const apiKey = !(config === null || config === void 0 ? void 0 : config.apiKey) && (config === null || config === void 0 ? void 0 : config.jwtToken) ? undefined : (config === null || config === void 0 ? void 0 : config.apiKey) || (process === null || process === void 0 ? void 0 : process.env['DAYTONA_API_KEY']);
97
+ const jwtToken = (config === null || config === void 0 ? void 0 : config.jwtToken) || (process === null || process === void 0 ? void 0 : process.env['DAYTONA_JWT_TOKEN']);
98
+ const organizationId = (config === null || config === void 0 ? void 0 : config.organizationId) || (process === null || process === void 0 ? void 0 : process.env['DAYTONA_ORGANIZATION_ID']);
99
+ if (!apiKey && !jwtToken) {
100
+ throw new DaytonaError_1.DaytonaError('API key or JWT token is required');
101
+ }
102
+ const apiUrl = (config === null || config === void 0 ? void 0 : config.apiUrl) ||
103
+ (config === null || config === void 0 ? void 0 : config.serverUrl) ||
104
+ (process === null || process === void 0 ? void 0 : process.env['DAYTONA_API_URL']) ||
105
+ (process === null || process === void 0 ? void 0 : process.env['DAYTONA_SERVER_URL']) ||
106
+ 'https://app.daytona.io/api';
107
+ const envTarget = process === null || process === void 0 ? void 0 : process.env['DAYTONA_TARGET'];
108
+ const target = (config === null || config === void 0 ? void 0 : config.target) || envTarget || api_client_1.CreateWorkspaceTargetEnum.US;
109
+ if ((process === null || process === void 0 ? void 0 : process.env['DAYTONA_SERVER_URL']) && !(process === null || process === void 0 ? void 0 : process.env['DAYTONA_API_URL'])) {
110
+ console.warn('[Deprecation Warning] Environment variable `DAYTONA_SERVER_URL` is deprecated and will be removed in future versions. Use `DAYTONA_API_URL` instead.');
111
+ }
112
+ this.apiKey = apiKey;
113
+ this.jwtToken = jwtToken;
114
+ this.organizationId = organizationId;
115
+ this.apiUrl = apiUrl;
116
+ this.target = target;
117
+ const orgHeader = {};
118
+ if (!this.apiKey) {
119
+ if (!this.organizationId) {
120
+ throw new DaytonaError_1.DaytonaError('Organization ID is required when using JWT token');
121
+ }
122
+ orgHeader['X-Daytona-Organization-ID'] = this.organizationId;
123
+ }
124
+ const configuration = new api_client_1.Configuration({
125
+ basePath: this.apiUrl,
126
+ baseOptions: {
127
+ headers: {
128
+ Authorization: `Bearer ${this.apiKey || this.jwtToken}`,
129
+ 'X-Daytona-Source': 'typescript-sdk',
130
+ ...orgHeader,
131
+ },
132
+ },
133
+ });
134
+ const axiosInstance = axios_1.default.create({
135
+ timeout: 24 * 60 * 60 * 1000, // 24 hours
136
+ });
137
+ axiosInstance.interceptors.response.use((response) => {
138
+ return response;
139
+ }, (error) => {
140
+ var _a, _b, _c, _d, _e;
141
+ let errorMessage;
142
+ if (error instanceof axios_1.AxiosError && error.message.includes('timeout of')) {
143
+ errorMessage = 'Operation timed out';
144
+ }
145
+ else {
146
+ errorMessage = ((_b = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.message) || ((_c = error.response) === null || _c === void 0 ? void 0 : _c.data) || error.message || String(error);
147
+ }
148
+ try {
149
+ errorMessage = JSON.stringify(errorMessage);
150
+ }
151
+ catch (_f) {
152
+ errorMessage = String(errorMessage);
153
+ }
154
+ switch ((_e = (_d = error.response) === null || _d === void 0 ? void 0 : _d.data) === null || _e === void 0 ? void 0 : _e.statusCode) {
155
+ case 404:
156
+ throw new DaytonaError_1.DaytonaNotFoundError(errorMessage);
157
+ default:
158
+ throw new DaytonaError_1.DaytonaError(errorMessage);
159
+ }
160
+ });
161
+ this.sandboxApi = new api_client_1.WorkspaceApi(configuration, '', axiosInstance);
162
+ this.toolboxApi = new api_client_1.ToolboxApi(configuration, '', axiosInstance);
163
+ this.volume = new Volume_1.VolumeService(new api_client_1.VolumesApi(configuration, '', axiosInstance));
164
+ this.imagesApi = new api_client_1.ImagesApi(configuration, '', axiosInstance);
165
+ this.objectStorageApi = new api_client_1.ObjectStorageApi(configuration, '', axiosInstance);
166
+ }
167
+ async create(params, options = { timeout: 60 }) {
168
+ var _a, _b, _c, _d;
169
+ const startTime = Date.now();
170
+ options = typeof options === 'number' ? { timeout: options } : { ...options };
171
+ if (options.timeout == undefined || options.timeout == null) {
172
+ options.timeout = 60;
173
+ }
174
+ if (params == null) {
175
+ params = { language: 'python' };
176
+ }
177
+ const labels = params.labels || {};
178
+ if (params.language) {
179
+ labels['code-toolbox-language'] = params.language;
180
+ }
181
+ // remove this when params.timeout is removed
182
+ const effectiveTimeout = params.timeout || options.timeout;
183
+ if (effectiveTimeout < 0) {
184
+ throw new DaytonaError_1.DaytonaError('Timeout must be a non-negative number');
185
+ }
186
+ if (params.autoStopInterval !== undefined &&
187
+ (!Number.isInteger(params.autoStopInterval) || params.autoStopInterval < 0)) {
188
+ throw new DaytonaError_1.DaytonaError('autoStopInterval must be a non-negative integer');
189
+ }
190
+ const codeToolbox = this.getCodeToolbox(params.language);
191
+ try {
192
+ // Handle Image instance if provided
193
+ let imageStr;
194
+ let buildInfo;
195
+ if (typeof params.image === 'string') {
196
+ imageStr = params.image;
197
+ }
198
+ else if (params.image instanceof Image_1.Image) {
199
+ const contextHashes = await this.processImageContext(params.image);
200
+ buildInfo = {
201
+ contextHashes,
202
+ dockerfileContent: params.image.dockerfile,
203
+ };
204
+ }
205
+ const response = await this.sandboxApi.createWorkspace({
206
+ image: imageStr,
207
+ buildInfo,
208
+ user: params.user,
209
+ env: params.envVars || {},
210
+ labels: params.labels,
211
+ public: params.public,
212
+ target: this.target,
213
+ cpu: (_a = params.resources) === null || _a === void 0 ? void 0 : _a.cpu,
214
+ gpu: (_b = params.resources) === null || _b === void 0 ? void 0 : _b.gpu,
215
+ memory: (_c = params.resources) === null || _c === void 0 ? void 0 : _c.memory,
216
+ disk: (_d = params.resources) === null || _d === void 0 ? void 0 : _d.disk,
217
+ autoStopInterval: params.autoStopInterval,
218
+ volumes: params.volumes,
219
+ }, undefined, {
220
+ timeout: effectiveTimeout * 1000,
221
+ });
222
+ let sandboxInstance = response.data;
223
+ if (sandboxInstance.state === api_client_1.WorkspaceState.PENDING_BUILD && options.onImageBuildLogs) {
224
+ const terminalStates = [api_client_1.WorkspaceState.STARTED, api_client_1.WorkspaceState.STARTING, api_client_1.WorkspaceState.ERROR];
225
+ while (sandboxInstance.state === api_client_1.WorkspaceState.PENDING_BUILD) {
226
+ await new Promise((resolve) => setTimeout(resolve, 1000));
227
+ sandboxInstance = (await this.sandboxApi.getWorkspace(sandboxInstance.id)).data;
228
+ }
229
+ await (0, Stream_1.processStreamingResponse)(() => this.sandboxApi.getBuildLogs(sandboxInstance.id, undefined, true, { responseType: 'stream' }), options.onImageBuildLogs, async () => {
230
+ sandboxInstance = (await this.sandboxApi.getWorkspace(sandboxInstance.id)).data;
231
+ return sandboxInstance.state !== undefined && terminalStates.includes(sandboxInstance.state);
232
+ });
233
+ }
234
+ const sandboxInfo = Sandbox_1.Sandbox.toSandboxInfo(sandboxInstance);
235
+ sandboxInstance.info = {
236
+ ...sandboxInfo,
237
+ name: '',
238
+ };
239
+ const sandbox = new Sandbox_1.Sandbox(sandboxInstance.id, sandboxInstance, this.sandboxApi, this.toolboxApi, codeToolbox);
240
+ if (!params.async && sandbox.instance.state !== 'started') {
241
+ const timeElapsed = Date.now() - startTime;
242
+ await sandbox.waitUntilStarted(effectiveTimeout ? effectiveTimeout - timeElapsed / 1000 : 0);
243
+ }
244
+ return sandbox;
245
+ }
246
+ catch (error) {
247
+ if (error instanceof DaytonaError_1.DaytonaError && error.message.includes('Operation timed out')) {
248
+ throw new DaytonaError_1.DaytonaError(`Failed to create and start sandbox within ${effectiveTimeout} seconds. Operation timed out.`);
249
+ }
250
+ throw error;
251
+ }
252
+ }
253
+ /**
254
+ * Gets a Sandbox by its ID.
255
+ *
256
+ * @param {string} sandboxId - The ID of the Sandbox to retrieve
257
+ * @returns {Promise<Sandbox>} The Sandbox
258
+ *
259
+ * @example
260
+ * const sandbox = await daytona.get('my-sandbox-id');
261
+ * console.log(`Sandbox state: ${sandbox.instance.state}`);
262
+ */
263
+ async get(sandboxId) {
264
+ const response = await this.sandboxApi.getWorkspace(sandboxId);
265
+ const sandboxInstance = response.data;
266
+ const language = sandboxInstance.labels && sandboxInstance.labels['code-toolbox-language'];
267
+ const codeToolbox = this.getCodeToolbox(language);
268
+ const sandboxInfo = Sandbox_1.Sandbox.toSandboxInfo(sandboxInstance);
269
+ sandboxInstance.info = {
270
+ ...sandboxInfo,
271
+ name: '',
272
+ };
273
+ return new Sandbox_1.Sandbox(sandboxId, sandboxInstance, this.sandboxApi, this.toolboxApi, codeToolbox);
274
+ }
275
+ /**
276
+ * Finds a Sandbox by its ID or labels.
277
+ *
278
+ * @param {SandboxFilter} filter - Filter for Sandboxes
279
+ * @returns {Promise<Sandbox>} First Sandbox that matches the ID or labels.
280
+ *
281
+ * @example
282
+ * const sandbox = await daytona.findOne({ labels: { 'my-label': 'my-value' } });
283
+ * console.log(`Sandbox: ${await sandbox.info()}`);
284
+ */
285
+ async findOne(filter) {
286
+ if (filter.id) {
287
+ return this.get(filter.id);
288
+ }
289
+ const sandboxes = await this.list(filter.labels);
290
+ if (sandboxes.length === 0) {
291
+ throw new DaytonaError_1.DaytonaError(`No sandbox found with labels ${JSON.stringify(filter.labels)}`);
292
+ }
293
+ return sandboxes[0];
294
+ }
295
+ /**
296
+ * Lists all Sandboxes filtered by labels.
297
+ *
298
+ * @param {Record<string, string>} [labels] - Labels to filter Sandboxes
299
+ * @returns {Promise<Sandbox[]>} Array of Sandboxes that match the labels.
300
+ *
301
+ * @example
302
+ * const sandboxes = await daytona.list({ 'my-label': 'my-value' });
303
+ * for (const sandbox of sandboxes) {
304
+ * console.log(`${sandbox.id}: ${sandbox.instance.state}`);
305
+ * }
306
+ */
307
+ async list(labels) {
308
+ const response = await this.sandboxApi.listWorkspaces(undefined, undefined, labels ? JSON.stringify(labels) : undefined);
309
+ return response.data.map((sandbox) => {
310
+ var _a;
311
+ const language = (_a = sandbox.labels) === null || _a === void 0 ? void 0 : _a['code-toolbox-language'];
312
+ const sandboxInfo = Sandbox_1.Sandbox.toSandboxInfo(sandbox);
313
+ sandbox.info = {
314
+ ...sandboxInfo,
315
+ name: '',
316
+ };
317
+ return new Sandbox_1.Sandbox(sandbox.id, sandbox, this.sandboxApi, this.toolboxApi, this.getCodeToolbox(language));
318
+ });
319
+ }
320
+ /**
321
+ * Starts a Sandbox and waits for it to be ready.
322
+ *
323
+ * @param {Sandbox} sandbox - The Sandbox to start
324
+ * @param {number} [timeout] - Optional timeout in seconds (0 means no timeout)
325
+ * @returns {Promise<void>}
326
+ *
327
+ * @example
328
+ * const sandbox = await daytona.get('my-sandbox-id');
329
+ * // Wait up to 60 seconds for the sandbox to start
330
+ * await daytona.start(sandbox, 60);
331
+ */
332
+ async start(sandbox, timeout) {
333
+ await sandbox.start(timeout);
334
+ }
335
+ /**
336
+ * Stops a Sandbox.
337
+ *
338
+ * @param {Sandbox} sandbox - The Sandbox to stop
339
+ * @returns {Promise<void>}
340
+ *
341
+ * @example
342
+ * const sandbox = await daytona.get('my-sandbox-id');
343
+ * await daytona.stop(sandbox);
344
+ */
345
+ async stop(sandbox) {
346
+ await sandbox.stop();
347
+ }
348
+ /**
349
+ * Deletes a Sandbox.
350
+ *
351
+ * @param {Sandbox} sandbox - The Sandbox to delete
352
+ * @param {number} timeout - Timeout in seconds (0 means no timeout, default is 60)
353
+ * @returns {Promise<void>}
354
+ *
355
+ * @example
356
+ * const sandbox = await daytona.get('my-sandbox-id');
357
+ * await daytona.delete(sandbox);
358
+ */
359
+ async delete(sandbox, timeout = 60) {
360
+ await this.sandboxApi.deleteWorkspace(sandbox.id, true, undefined, { timeout: timeout * 1000 });
361
+ }
362
+ /**
363
+ * Gets the Sandbox by ID.
364
+ *
365
+ * @param {string} workspaceId - The ID of the Sandbox to retrieve
366
+ * @returns {Promise<Workspace>} The Sandbox
367
+ *
368
+ * @deprecated Use `getCurrentSandbox` instead. This method will be removed in a future version.
369
+ */
370
+ async getCurrentWorkspace(workspaceId) {
371
+ return await this.getCurrentSandbox(workspaceId);
372
+ }
373
+ /**
374
+ * Gets the Sandbox by ID.
375
+ *
376
+ * @param {string} sandboxId - The ID of the Sandbox to retrieve
377
+ * @returns {Promise<Sandbox>} The Sandbox
378
+ *
379
+ * @example
380
+ * const sandbox = await daytona.getCurrentSandbox('my-sandbox-id');
381
+ * console.log(`Current sandbox state: ${sandbox.instance.state}`);
382
+ */
383
+ async getCurrentSandbox(sandboxId) {
384
+ return await this.get(sandboxId);
385
+ }
386
+ /**
387
+ * Creates and registers a new image from the given Image definition.
388
+ *
389
+ * @param {string} name - The name of the image to create.
390
+ * @param {Image} image - The Image instance.
391
+ * @param {object} options - Options for the create operation.
392
+ * @param {boolean} options.verbose - Default is false. Whether to log progress information upon each state change of the image.
393
+ * @param {number} options.timeout - Default is no timeout. Timeout in seconds (0 means no timeout).
394
+ * @returns {Promise<void>}
395
+ *
396
+ * @example
397
+ * const image = Image.debianSlim('3.12').pipInstall('numpy');
398
+ * await daytona.createImage('my-python-image', image);
399
+ */
400
+ async createImage(name, image, options = {}) {
401
+ const contextHashes = await this.processImageContext(image);
402
+ let builtImage = (await this.imagesApi.buildImage({
403
+ name,
404
+ buildInfo: {
405
+ contextHashes,
406
+ dockerfileContent: image.dockerfile,
407
+ },
408
+ }, undefined, {
409
+ timeout: (options.timeout || 0) * 1000,
410
+ })).data;
411
+ const terminalStates = [api_client_1.ImageState.ACTIVE, api_client_1.ImageState.ERROR];
412
+ const imageRef = { builtImage };
413
+ let streamPromise;
414
+ const startLogStreaming = async () => {
415
+ if (!streamPromise) {
416
+ streamPromise = (0, Stream_1.processStreamingResponse)(() => this.imagesApi.getImageBuildLogs(builtImage.id, undefined, true, { responseType: 'stream' }), options.onLogs, async () => terminalStates.includes(imageRef.builtImage.state));
417
+ }
418
+ };
419
+ if (options.onLogs) {
420
+ options.onLogs(`Building image ${builtImage.name} (${builtImage.state})`);
421
+ if (builtImage.state !== api_client_1.ImageState.BUILD_PENDING) {
422
+ await startLogStreaming();
423
+ }
424
+ }
425
+ let previousState = builtImage.state;
426
+ while (!terminalStates.includes(builtImage.state)) {
427
+ if (options.onLogs && previousState !== builtImage.state) {
428
+ if (builtImage.state !== api_client_1.ImageState.BUILD_PENDING && !streamPromise) {
429
+ await startLogStreaming();
430
+ }
431
+ options.onLogs(`Building image ${builtImage.name} (${builtImage.state})`);
432
+ previousState = builtImage.state;
433
+ }
434
+ await new Promise((resolve) => setTimeout(resolve, 1000));
435
+ builtImage = (await this.imagesApi.getImage(builtImage.id)).data;
436
+ imageRef.builtImage = builtImage;
437
+ }
438
+ if (options.onLogs) {
439
+ if (streamPromise) {
440
+ await streamPromise;
441
+ }
442
+ if (builtImage.state === api_client_1.ImageState.ACTIVE) {
443
+ options.onLogs(`Built image ${builtImage.name} (${builtImage.state})`);
444
+ }
445
+ }
446
+ if (builtImage.state === api_client_1.ImageState.ERROR) {
447
+ throw new DaytonaError_1.DaytonaError(`Failed to build image. Image ended in the ERROR state. name: ${builtImage.name}; error reason: ${builtImage.errorReason}`);
448
+ }
449
+ }
450
+ /**
451
+ * Gets the appropriate code toolbox based on language.
452
+ *
453
+ * @private
454
+ * @param {CodeLanguage} [language] - Programming language for the toolbox
455
+ * @returns {SandboxCodeToolbox} The appropriate code toolbox instance
456
+ * @throws {DaytonaError} - `DaytonaError` - When an unsupported language is specified
457
+ */
458
+ getCodeToolbox(language) {
459
+ switch (language) {
460
+ case CodeLanguage.JAVASCRIPT:
461
+ case CodeLanguage.TYPESCRIPT:
462
+ return new SandboxTsCodeToolbox_1.SandboxTsCodeToolbox();
463
+ case CodeLanguage.PYTHON:
464
+ case undefined:
465
+ return new SandboxPythonCodeToolbox_1.SandboxPythonCodeToolbox();
466
+ default:
467
+ throw new DaytonaError_1.DaytonaError(`Unsupported language: ${language}, supported languages: ${Object.values(CodeLanguage).join(', ')}`);
468
+ }
469
+ }
470
+ /**
471
+ * Processes the image contexts by uploading them to object storage
472
+ *
473
+ * @private
474
+ * @param {Image} image - The Image instance.
475
+ * @returns {Promise<string[]>} The list of context hashes stored in object storage.
476
+ */
477
+ async processImageContext(image) {
478
+ if (!image.contextList || !image.contextList.length) {
479
+ return [];
480
+ }
481
+ const pushAccessCreds = (await this.objectStorageApi.getPushAccess()).data;
482
+ const objectStorage = new ObjectStorage_1.ObjectStorage({
483
+ endpointUrl: pushAccessCreds.storageUrl,
484
+ accessKeyId: pushAccessCreds.accessKey,
485
+ secretAccessKey: pushAccessCreds.secret,
486
+ sessionToken: pushAccessCreds.sessionToken,
487
+ bucketName: pushAccessCreds.bucket,
488
+ });
489
+ const contextHashes = [];
490
+ for (const context of image.contextList) {
491
+ const contextHash = await objectStorage.upload(context.sourcePath, pushAccessCreds.organizationId, context.archivePath);
492
+ contextHashes.push(contextHash);
493
+ }
494
+ return contextHashes;
495
+ }
496
+ }
497
+ exports.Daytona = Daytona;