oblien 1.0.7 → 1.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.
@@ -0,0 +1,225 @@
1
+ /**
2
+ * Namespaces Module
3
+ * Manages namespaces, service configurations, and usage tracking
4
+ */
5
+
6
+ import { Namespace } from './namespace.js';
7
+
8
+ export class OblienNamespaces {
9
+ /**
10
+ * @param {import('../client.js').OblienClient} client - Oblien client instance
11
+ */
12
+ constructor(client) {
13
+ if (!client) {
14
+ throw new Error('Oblien client is required');
15
+ }
16
+
17
+ this.client = client;
18
+ }
19
+
20
+ /**
21
+ * Create a new namespace
22
+ * @param {Object} options - Namespace options
23
+ * @param {string} options.name - Namespace name (required)
24
+ * @param {string} [options.slug] - URL-friendly slug
25
+ * @param {string} [options.description] - Description
26
+ * @param {string} [options.type] - Type: 'default', 'production', 'testing', 'development'
27
+ * @param {boolean} [options.isDefault] - Is default namespace
28
+ * @param {Object} [options.metadata] - Custom metadata
29
+ * @param {Array<string>} [options.tags] - Tags
30
+ * @param {string} [options.endUserId] - End user ID
31
+ * @returns {Promise<Object>} Created namespace data
32
+ */
33
+ async create(options) {
34
+ const namespace = new Namespace({ client: this.client });
35
+ return await namespace.create(options);
36
+ }
37
+
38
+ /**
39
+ * Get namespace by ID or slug
40
+ * @param {string} identifier - Namespace ID or slug
41
+ * @returns {Promise<Object>} Namespace data
42
+ */
43
+ async get(identifier) {
44
+ const namespace = new Namespace({ client: this.client });
45
+ return await namespace.get(identifier);
46
+ }
47
+
48
+ /**
49
+ * List all namespaces with filtering and pagination
50
+ * @param {Object} [options] - Query options
51
+ * @param {number} [options.limit] - Max results (default: 50, max: 100)
52
+ * @param {number} [options.offset] - Offset for pagination
53
+ * @param {string} [options.status] - Filter by status: 'active', 'inactive', 'suspended', 'archived'
54
+ * @param {string} [options.type] - Filter by type: 'default', 'production', 'testing', 'development'
55
+ * @param {string} [options.search] - Search in name, slug, description
56
+ * @param {string} [options.sortBy] - Sort by: 'name', 'created_at', 'updated_at', 'last_active_at'
57
+ * @param {string} [options.sortOrder] - Sort order: 'ASC', 'DESC'
58
+ * @returns {Promise<Object>} Namespaces data with pagination info
59
+ */
60
+ async list(options = {}) {
61
+ const response = await this.client.get('namespaces', options);
62
+ return response;
63
+ }
64
+
65
+ /**
66
+ * Update namespace
67
+ * @param {string} namespaceId - Namespace ID
68
+ * @param {Object} updates - Fields to update
69
+ * @returns {Promise<Object>} Updated namespace data
70
+ */
71
+ async update(namespaceId, updates) {
72
+ const namespace = new Namespace({ client: this.client, namespaceId });
73
+ return await namespace.update(updates);
74
+ }
75
+
76
+ /**
77
+ * Delete (archive) namespace
78
+ * @param {string} namespaceId - Namespace ID
79
+ * @returns {Promise<Object>} Deletion result
80
+ */
81
+ async delete(namespaceId) {
82
+ const namespace = new Namespace({ client: this.client, namespaceId });
83
+ return await namespace.delete();
84
+ }
85
+
86
+ /**
87
+ * Get namespace activity log
88
+ * @param {string} namespaceId - Namespace ID
89
+ * @param {Object} [options] - Query options
90
+ * @param {number} [options.limit] - Number of activities (default: 50)
91
+ * @param {number} [options.offset] - Offset for pagination
92
+ * @returns {Promise<Array>} Array of activity logs
93
+ */
94
+ async getActivity(namespaceId, options = {}) {
95
+ const namespace = new Namespace({ client: this.client, namespaceId });
96
+ return await namespace.getActivity(options);
97
+ }
98
+
99
+ /**
100
+ * Get namespace usage statistics
101
+ * @param {string} namespaceId - Namespace ID
102
+ * @param {Object} [options] - Query options
103
+ * @param {string} [options.service] - Filter by service
104
+ * @param {number} [options.days] - Number of days (default: 30)
105
+ * @returns {Promise<Object>} Usage statistics
106
+ */
107
+ async getUsage(namespaceId, options = {}) {
108
+ const namespace = new Namespace({ client: this.client, namespaceId });
109
+ return await namespace.getUsage(options);
110
+ }
111
+
112
+ /**
113
+ * Get available services
114
+ * @returns {Promise<Array>} Array of available services
115
+ */
116
+ async getAvailableServices() {
117
+ const response = await this.client.get('namespaces/services/available');
118
+ return response.data || response;
119
+ }
120
+
121
+ /**
122
+ * Configure a service for a namespace
123
+ * @param {string} namespaceId - Namespace ID
124
+ * @param {Object} options - Service configuration
125
+ * @param {string} options.service - Service name (required)
126
+ * @param {boolean} [options.enabled] - Enable/disable service
127
+ * @param {Object} [options.config] - Service-specific configuration
128
+ * @param {number} [options.rateLimitRequests] - Rate limit requests
129
+ * @param {string} [options.rateLimitPeriod] - Rate limit period
130
+ * @param {Array<string>} [options.features] - Enabled features
131
+ * @returns {Promise<Object>} Service configuration
132
+ */
133
+ async configureService(namespaceId, options) {
134
+ const namespace = new Namespace({ client: this.client, namespaceId });
135
+ return await namespace.configureService(options);
136
+ }
137
+
138
+ /**
139
+ * List all services for a namespace
140
+ * @param {string} namespaceId - Namespace ID
141
+ * @returns {Promise<Array>} Array of service configurations
142
+ */
143
+ async listServices(namespaceId) {
144
+ const namespace = new Namespace({ client: this.client, namespaceId });
145
+ return await namespace.listServices();
146
+ }
147
+
148
+ /**
149
+ * Get specific service configuration
150
+ * @param {string} namespaceId - Namespace ID
151
+ * @param {string} service - Service name
152
+ * @returns {Promise<Object>} Service configuration
153
+ */
154
+ async getServiceConfig(namespaceId, service) {
155
+ const namespace = new Namespace({ client: this.client, namespaceId });
156
+ return await namespace.getServiceConfig(service);
157
+ }
158
+
159
+ /**
160
+ * Toggle service enabled/disabled
161
+ * @param {string} namespaceId - Namespace ID
162
+ * @param {string} service - Service name
163
+ * @param {boolean} enabled - Enable or disable
164
+ * @returns {Promise<Object>} Updated service configuration
165
+ */
166
+ async toggleService(namespaceId, service, enabled) {
167
+ const namespace = new Namespace({ client: this.client, namespaceId });
168
+ return await namespace.toggleService(service, enabled);
169
+ }
170
+
171
+ /**
172
+ * Enable a service for a namespace
173
+ * @param {string} namespaceId - Namespace ID
174
+ * @param {string} service - Service name
175
+ * @returns {Promise<Object>} Updated service configuration
176
+ */
177
+ async enableService(namespaceId, service) {
178
+ return await this.toggleService(namespaceId, service, true);
179
+ }
180
+
181
+ /**
182
+ * Disable a service for a namespace
183
+ * @param {string} namespaceId - Namespace ID
184
+ * @param {string} service - Service name
185
+ * @returns {Promise<Object>} Updated service configuration
186
+ */
187
+ async disableService(namespaceId, service) {
188
+ return await this.toggleService(namespaceId, service, false);
189
+ }
190
+
191
+ /**
192
+ * Delete service configuration
193
+ * @param {string} namespaceId - Namespace ID
194
+ * @param {string} service - Service name
195
+ * @returns {Promise<Object>} Deletion result
196
+ */
197
+ async deleteService(namespaceId, service) {
198
+ const namespace = new Namespace({ client: this.client, namespaceId });
199
+ return await namespace.deleteService(service);
200
+ }
201
+
202
+ /**
203
+ * Bulk configure multiple services
204
+ * @param {string} namespaceId - Namespace ID
205
+ * @param {Array<Object>} services - Array of service configurations
206
+ * @returns {Promise<Array>} Array of configured services
207
+ */
208
+ async bulkConfigureServices(namespaceId, services) {
209
+ const namespace = new Namespace({ client: this.client, namespaceId });
210
+ return await namespace.bulkConfigureServices(services);
211
+ }
212
+
213
+ /**
214
+ * Create a Namespace instance for chaining operations
215
+ * @param {string} [namespaceId] - Namespace ID
216
+ * @returns {Namespace} Namespace instance
217
+ */
218
+ namespace(namespaceId) {
219
+ return new Namespace({ client: this.client, namespaceId });
220
+ }
221
+ }
222
+
223
+ export { Namespace };
224
+ export default OblienNamespaces;
225
+
@@ -0,0 +1,274 @@
1
+ /**
2
+ * Namespace Entity Manager
3
+ * Manages individual namespace operations
4
+ */
5
+
6
+ export class Namespace {
7
+ /**
8
+ * @param {Object} options - Namespace options
9
+ * @param {import('../client.js').OblienClient} options.client - Oblien client instance
10
+ * @param {string} [options.namespaceId] - Existing namespace ID
11
+ * @param {Object} [options.data] - Namespace data
12
+ */
13
+ constructor(options) {
14
+ if (!options.client) {
15
+ throw new Error('Oblien client is required');
16
+ }
17
+
18
+ this.client = options.client;
19
+ this.namespaceId = options.namespaceId || null;
20
+ this.data = options.data || null;
21
+ }
22
+
23
+ /**
24
+ * Create a new namespace
25
+ * @param {Object} options - Namespace options
26
+ * @param {string} options.name - Namespace name (required)
27
+ * @param {string} [options.slug] - URL-friendly slug (auto-generated from name if not provided)
28
+ * @param {string} [options.description] - Namespace description
29
+ * @param {string} [options.type] - Type: 'default', 'production', 'testing', 'development'
30
+ * @param {boolean} [options.isDefault] - Is this the default namespace
31
+ * @param {Object} [options.metadata] - Custom metadata object
32
+ * @param {Array<string>} [options.tags] - Array of tags
33
+ * @param {string} [options.endUserId] - End user ID (creator)
34
+ * @returns {Promise<Object>} Created namespace data
35
+ */
36
+ async create(options) {
37
+ if (!options.name) {
38
+ throw new Error('Namespace name is required');
39
+ }
40
+
41
+ const payload = {
42
+ name: options.name,
43
+ slug: options.slug,
44
+ description: options.description,
45
+ type: options.type || 'default',
46
+ isDefault: options.isDefault || false,
47
+ metadata: options.metadata || {},
48
+ tags: options.tags || [],
49
+ endUserId: options.endUserId,
50
+ };
51
+
52
+ const response = await this.client.post('namespaces', payload);
53
+ this.data = response.data;
54
+ this.namespaceId = this.data.id;
55
+
56
+ return this.data;
57
+ }
58
+
59
+ /**
60
+ * Get namespace details
61
+ * @param {string} [identifier] - Namespace ID or slug (uses instance namespaceId if not provided)
62
+ * @returns {Promise<Object>} Namespace data
63
+ */
64
+ async get(identifier) {
65
+ const id = identifier || this.namespaceId;
66
+ if (!id) {
67
+ throw new Error('Namespace ID or slug is required');
68
+ }
69
+
70
+ const response = await this.client.get(`namespaces/${id}`);
71
+ this.data = response.data;
72
+ this.namespaceId = this.data.id;
73
+
74
+ return this.data;
75
+ }
76
+
77
+ /**
78
+ * Update namespace
79
+ * @param {Object} updates - Fields to update
80
+ * @param {string} [updates.name] - New name
81
+ * @param {string} [updates.description] - New description
82
+ * @param {string} [updates.status] - New status: 'active', 'inactive', 'suspended', 'archived'
83
+ * @param {string} [updates.type] - New type
84
+ * @param {Object} [updates.metadata] - New metadata
85
+ * @param {Array<string>} [updates.tags] - New tags
86
+ * @param {string} [namespaceId] - Namespace ID (uses instance namespaceId if not provided)
87
+ * @returns {Promise<Object>} Updated namespace data
88
+ */
89
+ async update(updates, namespaceId) {
90
+ const id = namespaceId || this.namespaceId;
91
+ if (!id) {
92
+ throw new Error('Namespace ID is required');
93
+ }
94
+
95
+ const response = await this.client.put(`namespaces/${id}`, updates);
96
+ this.data = response.data;
97
+
98
+ return this.data;
99
+ }
100
+
101
+ /**
102
+ * Delete (archive) namespace
103
+ * @param {string} [namespaceId] - Namespace ID (uses instance namespaceId if not provided)
104
+ * @returns {Promise<Object>} Deletion result
105
+ */
106
+ async delete(namespaceId) {
107
+ const id = namespaceId || this.namespaceId;
108
+ if (!id) {
109
+ throw new Error('Namespace ID is required');
110
+ }
111
+
112
+ return await this.client.delete(`namespaces/${id}`);
113
+ }
114
+
115
+ /**
116
+ * Get namespace activity log
117
+ * @param {Object} [options] - Query options
118
+ * @param {number} [options.limit] - Number of activities to return (default: 50)
119
+ * @param {number} [options.offset] - Offset for pagination
120
+ * @param {string} [namespaceId] - Namespace ID (uses instance namespaceId if not provided)
121
+ * @returns {Promise<Array>} Array of activity logs
122
+ */
123
+ async getActivity(options = {}, namespaceId) {
124
+ const id = namespaceId || this.namespaceId;
125
+ if (!id) {
126
+ throw new Error('Namespace ID is required');
127
+ }
128
+
129
+ const response = await this.client.get(`namespaces/${id}/activity`, options);
130
+ return response.data || response;
131
+ }
132
+
133
+ /**
134
+ * Get namespace usage statistics
135
+ * @param {Object} [options] - Query options
136
+ * @param {string} [options.service] - Filter by specific service
137
+ * @param {number} [options.days] - Number of days to include (default: 30)
138
+ * @param {string} [namespaceId] - Namespace ID (uses instance namespaceId if not provided)
139
+ * @returns {Promise<Object>} Usage statistics
140
+ */
141
+ async getUsage(options = {}, namespaceId) {
142
+ const id = namespaceId || this.namespaceId;
143
+ if (!id) {
144
+ throw new Error('Namespace ID is required');
145
+ }
146
+
147
+ const response = await this.client.get(`namespaces/${id}/usage`, options);
148
+ return response.data || response;
149
+ }
150
+
151
+ /**
152
+ * Configure a service for this namespace
153
+ * @param {Object} options - Service configuration
154
+ * @param {string} options.service - Service name (required)
155
+ * @param {boolean} [options.enabled] - Enable/disable service
156
+ * @param {Object} [options.config] - Service-specific configuration
157
+ * @param {number} [options.rateLimitRequests] - Rate limit requests per period
158
+ * @param {string} [options.rateLimitPeriod] - Rate limit period: 'minute', 'hour', 'day'
159
+ * @param {Array<string>} [options.features] - Enabled features
160
+ * @param {string} [namespaceId] - Namespace ID (uses instance namespaceId if not provided)
161
+ * @returns {Promise<Object>} Service configuration
162
+ */
163
+ async configureService(options, namespaceId) {
164
+ const id = namespaceId || this.namespaceId;
165
+ if (!id) {
166
+ throw new Error('Namespace ID is required');
167
+ }
168
+
169
+ if (!options.service) {
170
+ throw new Error('Service name is required');
171
+ }
172
+
173
+ const response = await this.client.post(`namespaces/${id}/services`, options);
174
+ return response.data || response;
175
+ }
176
+
177
+ /**
178
+ * List all services for this namespace
179
+ * @param {string} [namespaceId] - Namespace ID (uses instance namespaceId if not provided)
180
+ * @returns {Promise<Array>} Array of service configurations
181
+ */
182
+ async listServices(namespaceId) {
183
+ const id = namespaceId || this.namespaceId;
184
+ if (!id) {
185
+ throw new Error('Namespace ID is required');
186
+ }
187
+
188
+ const response = await this.client.get(`namespaces/${id}/services`);
189
+ return response.data || response;
190
+ }
191
+
192
+ /**
193
+ * Get specific service configuration
194
+ * @param {string} service - Service name
195
+ * @param {string} [namespaceId] - Namespace ID (uses instance namespaceId if not provided)
196
+ * @returns {Promise<Object>} Service configuration
197
+ */
198
+ async getServiceConfig(service, namespaceId) {
199
+ const id = namespaceId || this.namespaceId;
200
+ if (!id) {
201
+ throw new Error('Namespace ID is required');
202
+ }
203
+
204
+ if (!service) {
205
+ throw new Error('Service name is required');
206
+ }
207
+
208
+ const response = await this.client.get(`namespaces/${id}/services/${service}`);
209
+ return response.data || response;
210
+ }
211
+
212
+ /**
213
+ * Toggle service enabled/disabled
214
+ * @param {string} service - Service name
215
+ * @param {boolean} enabled - Enable or disable
216
+ * @param {string} [namespaceId] - Namespace ID (uses instance namespaceId if not provided)
217
+ * @returns {Promise<Object>} Updated service configuration
218
+ */
219
+ async toggleService(service, enabled, namespaceId) {
220
+ const id = namespaceId || this.namespaceId;
221
+ if (!id) {
222
+ throw new Error('Namespace ID is required');
223
+ }
224
+
225
+ if (!service) {
226
+ throw new Error('Service name is required');
227
+ }
228
+
229
+ const response = await this.client.patch(`namespaces/${id}/services/${service}/toggle`, { enabled });
230
+ return response.data || response;
231
+ }
232
+
233
+ /**
234
+ * Delete service configuration
235
+ * @param {string} service - Service name
236
+ * @param {string} [namespaceId] - Namespace ID (uses instance namespaceId if not provided)
237
+ * @returns {Promise<Object>} Deletion result
238
+ */
239
+ async deleteService(service, namespaceId) {
240
+ const id = namespaceId || this.namespaceId;
241
+ if (!id) {
242
+ throw new Error('Namespace ID is required');
243
+ }
244
+
245
+ if (!service) {
246
+ throw new Error('Service name is required');
247
+ }
248
+
249
+ return await this.client.delete(`namespaces/${id}/services/${service}`);
250
+ }
251
+
252
+ /**
253
+ * Bulk configure multiple services
254
+ * @param {Array<Object>} services - Array of service configurations
255
+ * @param {string} [namespaceId] - Namespace ID (uses instance namespaceId if not provided)
256
+ * @returns {Promise<Array>} Array of service configurations
257
+ */
258
+ async bulkConfigureServices(services, namespaceId) {
259
+ const id = namespaceId || this.namespaceId;
260
+ if (!id) {
261
+ throw new Error('Namespace ID is required');
262
+ }
263
+
264
+ if (!Array.isArray(services)) {
265
+ throw new Error('Services must be an array');
266
+ }
267
+
268
+ const response = await this.client.post(`namespaces/${id}/services/bulk`, { services });
269
+ return response.data || response;
270
+ }
271
+ }
272
+
273
+ export default Namespace;
274
+
@@ -0,0 +1,185 @@
1
+ /**
2
+ * Sandboxes Module
3
+ * Manages cloud sandboxes - create, control, monitor
4
+ */
5
+
6
+ import { Sandbox } from './sandbox.js';
7
+
8
+ export class OblienSandboxes {
9
+ /**
10
+ * @param {import('../client.js').OblienClient} client - Oblien client instance
11
+ */
12
+ constructor(client) {
13
+ if (!client) {
14
+ throw new Error('Oblien client is required');
15
+ }
16
+
17
+ this.client = client;
18
+ }
19
+
20
+ /**
21
+ * Create a new sandbox
22
+ * @param {Object} options - Sandbox options
23
+ * @param {string} [options.name] - Sandbox name
24
+ * @param {string} [options.region='us-east-1'] - Region: 'us-east-1' | 'us-west-1' | 'eu-west-1'
25
+ * @param {string} [options.template='node-20'] - Template: 'node-20' | 'python-3' | 'blank' | custom
26
+ * @param {Object} [options.config] - Custom configuration
27
+ * @param {boolean} [options.autoStart=true] - Auto-start sandbox after creation
28
+ * @returns {Promise<Object>} Created sandbox data with token
29
+ */
30
+ async create(options = {}) {
31
+ const {
32
+ name,
33
+ region = 'us-east-1',
34
+ template = 'node-20',
35
+ config,
36
+ autoStart = true
37
+ } = options;
38
+
39
+ const response = await this.client.post('sandbox', {
40
+ name,
41
+ region,
42
+ template,
43
+ config,
44
+ autoStart
45
+ });
46
+
47
+ return response;
48
+ }
49
+
50
+ /**
51
+ * List all sandboxes with pagination and filtering
52
+ * @param {Object} [options] - Query options
53
+ * @param {number} [options.page=1] - Page number
54
+ * @param {number} [options.limit=20] - Results per page
55
+ * @param {string} [options.status] - Filter by status: 'active' | 'stopped' | 'suspended' | 'deleted'
56
+ * @returns {Promise<Object>} Sandboxes data with pagination info
57
+ */
58
+ async list(options = {}) {
59
+ const params = {
60
+ page: options.page || 1,
61
+ limit: options.limit || 20
62
+ };
63
+
64
+ if (options.status) {
65
+ params.status = options.status;
66
+ }
67
+
68
+ const response = await this.client.get('sandbox', params);
69
+ return response;
70
+ }
71
+
72
+ /**
73
+ * Get sandbox by ID
74
+ * @param {string} sandboxId - Sandbox ID
75
+ * @returns {Promise<Object>} Sandbox data
76
+ */
77
+ async get(sandboxId) {
78
+ if (!sandboxId) {
79
+ throw new Error('Sandbox ID is required');
80
+ }
81
+
82
+ const sandbox = new Sandbox({ client: this.client, sandboxId });
83
+ return await sandbox.get();
84
+ }
85
+
86
+ /**
87
+ * Update sandbox
88
+ * @param {string} sandboxId - Sandbox ID
89
+ * @param {Object} updates - Fields to update
90
+ * @returns {Promise<Object>} Update result
91
+ */
92
+ async update(sandboxId, updates) {
93
+ const sandbox = new Sandbox({ client: this.client, sandboxId });
94
+ return await sandbox.update(updates);
95
+ }
96
+
97
+ /**
98
+ * Delete sandbox
99
+ * @param {string} sandboxId - Sandbox ID
100
+ * @returns {Promise<Object>} Delete result
101
+ */
102
+ async delete(sandboxId) {
103
+ const sandbox = new Sandbox({ client: this.client, sandboxId });
104
+ return await sandbox.delete();
105
+ }
106
+
107
+ /**
108
+ * Start sandbox
109
+ * @param {string} sandboxId - Sandbox ID
110
+ * @returns {Promise<Object>} Start result with new token
111
+ */
112
+ async start(sandboxId) {
113
+ const sandbox = new Sandbox({ client: this.client, sandboxId });
114
+ return await sandbox.start();
115
+ }
116
+
117
+ /**
118
+ * Stop sandbox
119
+ * @param {string} sandboxId - Sandbox ID
120
+ * @returns {Promise<Object>} Stop result
121
+ */
122
+ async stop(sandboxId) {
123
+ const sandbox = new Sandbox({ client: this.client, sandboxId });
124
+ return await sandbox.stop();
125
+ }
126
+
127
+ /**
128
+ * Restart sandbox
129
+ * @param {string} sandboxId - Sandbox ID
130
+ * @returns {Promise<Object>} Restart result with new token
131
+ */
132
+ async restart(sandboxId) {
133
+ const sandbox = new Sandbox({ client: this.client, sandboxId });
134
+ return await sandbox.restart();
135
+ }
136
+
137
+ /**
138
+ * Regenerate sandbox token
139
+ * @param {string} sandboxId - Sandbox ID
140
+ * @returns {Promise<Object>} New token (1h expiry)
141
+ */
142
+ async regenerateToken(sandboxId) {
143
+ const sandbox = new Sandbox({ client: this.client, sandboxId });
144
+ return await sandbox.regenerateToken();
145
+ }
146
+
147
+ /**
148
+ * Get sandbox metrics
149
+ * @param {string} sandboxId - Sandbox ID
150
+ * @returns {Promise<Object>} Sandbox metrics
151
+ */
152
+ async getMetrics(sandboxId) {
153
+ const sandbox = new Sandbox({ client: this.client, sandboxId });
154
+ return await sandbox.getMetrics();
155
+ }
156
+
157
+ /**
158
+ * Get sandbox stats (overall statistics)
159
+ * @returns {Promise<Object>} Sandbox statistics
160
+ */
161
+ async getStats() {
162
+ return await this.client.get('sandbox/stats');
163
+ }
164
+
165
+ /**
166
+ * Get sandbox activity
167
+ * @returns {Promise<Object>} Sandbox activity logs
168
+ */
169
+ async getActivity() {
170
+ return await this.client.get('sandbox/activity');
171
+ }
172
+
173
+ /**
174
+ * Create a Sandbox instance for chaining operations
175
+ * @param {string} sandboxId - Sandbox ID
176
+ * @returns {Sandbox} Sandbox instance
177
+ */
178
+ sandbox(sandboxId) {
179
+ return new Sandbox({ client: this.client, sandboxId });
180
+ }
181
+ }
182
+
183
+ export { Sandbox };
184
+ export default OblienSandboxes;
185
+