@phala/cloud 0.1.1 → 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/dist/index.mjs CHANGED
@@ -1,8 +1,9 @@
1
1
  // src/client.ts
2
2
  import { ofetch } from "ofetch";
3
3
  import debug from "debug";
4
+ import mitt from "mitt";
4
5
 
5
- // src/types/client.ts
6
+ // src/utils/errors.ts
6
7
  import { z } from "zod";
7
8
  var ApiErrorSchema = z.object({
8
9
  detail: z.union([
@@ -15,21 +16,34 @@ var ApiErrorSchema = z.object({
15
16
  })
16
17
  ),
17
18
  z.record(z.unknown())
18
- ]),
19
+ ]).optional(),
19
20
  type: z.string().optional(),
20
21
  code: z.string().optional()
21
22
  });
22
- var RequestError = class _RequestError extends Error {
23
- constructor(message, options) {
23
+ var PhalaCloudError = class extends Error {
24
+ constructor(message, data) {
24
25
  super(message);
26
+ this.name = this.constructor.name;
27
+ this.status = data.status;
28
+ this.statusText = data.statusText;
29
+ this.detail = data.detail;
30
+ if (Error.captureStackTrace) {
31
+ Error.captureStackTrace(this, this.constructor);
32
+ }
33
+ }
34
+ };
35
+ var RequestError = class _RequestError extends PhalaCloudError {
36
+ constructor(message, options) {
37
+ super(message, {
38
+ status: options?.status ?? 0,
39
+ statusText: options?.statusText ?? "Unknown Error",
40
+ detail: options?.detail || message
41
+ });
25
42
  this.name = "RequestError";
26
43
  this.isRequestError = true;
27
- this.status = options?.status;
28
- this.statusText = options?.statusText;
29
44
  this.data = options?.data;
30
45
  this.request = options?.request;
31
46
  this.response = options?.response;
32
- this.detail = options?.detail || message;
33
47
  this.code = options?.code;
34
48
  this.type = options?.type;
35
49
  }
@@ -70,9 +84,172 @@ var RequestError = class _RequestError extends Error {
70
84
  });
71
85
  }
72
86
  };
87
+ var ValidationError = class extends PhalaCloudError {
88
+ constructor(message, data) {
89
+ super(message, data);
90
+ this.isValidationError = true;
91
+ this.validationErrors = data.validationErrors;
92
+ }
93
+ };
94
+ var AuthError = class extends PhalaCloudError {
95
+ constructor() {
96
+ super(...arguments);
97
+ this.isAuthError = true;
98
+ }
99
+ };
100
+ var BusinessError = class extends PhalaCloudError {
101
+ constructor() {
102
+ super(...arguments);
103
+ this.isBusinessError = true;
104
+ }
105
+ };
106
+ var ServerError = class extends PhalaCloudError {
107
+ constructor() {
108
+ super(...arguments);
109
+ this.isServerError = true;
110
+ }
111
+ };
112
+ var UnknownError = class extends PhalaCloudError {
113
+ constructor() {
114
+ super(...arguments);
115
+ this.isUnknownError = true;
116
+ }
117
+ };
118
+ function extractFieldPath(loc) {
119
+ const filtered = loc.filter((part) => {
120
+ if (typeof part === "string") {
121
+ return !["body", "query", "path", "header"].includes(part);
122
+ }
123
+ return true;
124
+ });
125
+ return filtered.length > 0 ? filtered.join(".") : "unknown";
126
+ }
127
+ function parseValidationErrors(detail) {
128
+ if (!Array.isArray(detail)) {
129
+ return {
130
+ errors: [],
131
+ message: typeof detail === "string" ? detail : "Validation error"
132
+ };
133
+ }
134
+ const errors = detail.map((item) => ({
135
+ field: extractFieldPath(item.loc),
136
+ message: item.msg,
137
+ type: item.type,
138
+ context: item.ctx
139
+ }));
140
+ const count = errors.length;
141
+ const message = count === 1 ? `Validation failed: ${errors[0].message}` : `Validation failed (${count} issue${count > 1 ? "s" : ""})`;
142
+ return { errors, message };
143
+ }
144
+ function categorizeErrorType(status) {
145
+ if (status === 422) {
146
+ return "validation";
147
+ }
148
+ if (status === 401) {
149
+ return "auth";
150
+ }
151
+ if (status === 403) {
152
+ return "auth";
153
+ }
154
+ if (status >= 400 && status < 500) {
155
+ return "business";
156
+ }
157
+ if (status >= 500) {
158
+ return "server";
159
+ }
160
+ return "unknown";
161
+ }
162
+ function extractPrimaryMessage(status, detail, defaultMessage) {
163
+ if (status === 422 && Array.isArray(detail)) {
164
+ const { message } = parseValidationErrors(detail);
165
+ return message;
166
+ }
167
+ if (typeof detail === "string") {
168
+ return detail;
169
+ }
170
+ if (detail && typeof detail === "object" && "message" in detail) {
171
+ const msg = detail.message;
172
+ if (typeof msg === "string") {
173
+ return msg;
174
+ }
175
+ }
176
+ return defaultMessage;
177
+ }
178
+ function parseApiError(requestError) {
179
+ const status = requestError.status ?? 0;
180
+ const statusText = requestError.statusText ?? "Unknown Error";
181
+ const detail = requestError.detail;
182
+ const errorType = categorizeErrorType(status);
183
+ const message = extractPrimaryMessage(status, detail, requestError.message);
184
+ const commonData = {
185
+ status,
186
+ statusText,
187
+ detail
188
+ };
189
+ if (errorType === "validation" && Array.isArray(detail)) {
190
+ const { errors } = parseValidationErrors(detail);
191
+ return new ValidationError(message, {
192
+ ...commonData,
193
+ validationErrors: errors
194
+ });
195
+ }
196
+ if (errorType === "auth") {
197
+ return new AuthError(message, commonData);
198
+ }
199
+ if (errorType === "business") {
200
+ return new BusinessError(message, commonData);
201
+ }
202
+ if (errorType === "server") {
203
+ return new ServerError(message, commonData);
204
+ }
205
+ return new UnknownError(message, commonData);
206
+ }
207
+ function getValidationFields(error) {
208
+ if (error instanceof ValidationError) {
209
+ return error.validationErrors.map((e) => e.field);
210
+ }
211
+ return [];
212
+ }
213
+ function formatValidationErrors(errors, options) {
214
+ const { numbered = true, indent = 2, showFields = true } = options ?? {};
215
+ const indentStr = " ".repeat(indent);
216
+ return errors.map((error, index) => {
217
+ const prefix = numbered ? `${index + 1}. ` : "\u2022 ";
218
+ const field = showFields ? `${error.field}: ` : "";
219
+ return `${indentStr}${prefix}${field}${error.message}`;
220
+ }).join("\n");
221
+ }
222
+ function formatErrorMessage(error, options) {
223
+ const { showFields = true, showType = false } = options ?? {};
224
+ const parts = [];
225
+ if (showType) {
226
+ parts.push(`[${error.constructor.name.toUpperCase()}]`);
227
+ }
228
+ parts.push(error.message);
229
+ if (error instanceof ValidationError && error.validationErrors.length > 0) {
230
+ parts.push("");
231
+ parts.push(formatValidationErrors(error.validationErrors, { showFields }));
232
+ }
233
+ return parts.join("\n");
234
+ }
235
+ function getErrorMessage(error) {
236
+ if (typeof error.detail === "string") {
237
+ return error.detail;
238
+ }
239
+ if (Array.isArray(error.detail)) {
240
+ if (error.detail.length > 0) {
241
+ return error.detail[0]?.msg || "Validation error";
242
+ }
243
+ return "Validation error";
244
+ }
245
+ if (typeof error.detail === "object" && error.detail !== null) {
246
+ return JSON.stringify(error.detail);
247
+ }
248
+ return "Unknown error occurred";
249
+ }
73
250
 
74
251
  // src/client.ts
75
- var SUPPORTED_API_VERSIONS = ["2025-05-31"];
252
+ var SUPPORTED_API_VERSIONS = ["2025-05-31", "2025-10-28"];
76
253
  var logger = debug("phala::api-client");
77
254
  function formatHeaders(headers) {
78
255
  return Object.entries(headers).map(([key, value]) => ` -H "${key}: ${value}"`).join("\n");
@@ -98,18 +275,14 @@ function formatResponse(status, statusText, headers, body) {
98
275
  }
99
276
  var Client = class {
100
277
  constructor(config = {}) {
278
+ this.emitter = mitt();
101
279
  const resolvedConfig = {
102
280
  ...config,
103
281
  apiKey: config.apiKey || process?.env?.PHALA_CLOUD_API_KEY,
104
282
  baseURL: config.baseURL || process?.env?.PHALA_CLOUD_API_PREFIX || "https://cloud-api.phala.network/api/v1"
105
283
  };
106
- const version = resolvedConfig.version && SUPPORTED_API_VERSIONS.includes(resolvedConfig.version) ? resolvedConfig.version : SUPPORTED_API_VERSIONS[0];
284
+ const version = resolvedConfig.version && SUPPORTED_API_VERSIONS.includes(resolvedConfig.version) ? resolvedConfig.version : SUPPORTED_API_VERSIONS[SUPPORTED_API_VERSIONS.length - 1];
107
285
  this.config = resolvedConfig;
108
- if (!resolvedConfig.useCookieAuth && !resolvedConfig.apiKey) {
109
- throw new Error(
110
- "API key is required. Provide it via config.apiKey or set PHALA_CLOUD_API_KEY environment variable."
111
- );
112
- }
113
286
  const { apiKey, baseURL, timeout, headers, useCookieAuth, onResponseError, ...fetchOptions } = resolvedConfig;
114
287
  const requestHeaders = {
115
288
  "X-Phala-Version": version,
@@ -192,75 +365,137 @@ var Client = class {
192
365
  get raw() {
193
366
  return this.fetchInstance;
194
367
  }
368
+ on(type, handler) {
369
+ this.emitter.on(type, handler);
370
+ }
371
+ off(type, handler) {
372
+ this.emitter.off(type, handler);
373
+ }
374
+ once(type, handler) {
375
+ const wrappedHandler = (event) => {
376
+ handler(event);
377
+ this.emitter.off(type, wrappedHandler);
378
+ };
379
+ this.emitter.on(type, wrappedHandler);
380
+ }
195
381
  // ===== Direct methods (throw on error) =====
196
382
  /**
197
- * Perform GET request (throws on error)
383
+ * Perform GET request (throws PhalaCloudError on error)
198
384
  */
199
385
  async get(request, options) {
200
- return this.fetchInstance(request, {
201
- ...options,
202
- method: "GET"
203
- });
386
+ try {
387
+ return await this.fetchInstance(request, {
388
+ ...options,
389
+ method: "GET"
390
+ });
391
+ } catch (error) {
392
+ const requestError = this.convertToRequestError(error);
393
+ const phalaCloudError = this.emitError(requestError);
394
+ throw phalaCloudError;
395
+ }
204
396
  }
205
397
  /**
206
- * Perform POST request (throws on error)
398
+ * Perform POST request (throws PhalaCloudError on error)
207
399
  */
208
400
  async post(request, body, options) {
209
- return this.fetchInstance(request, {
210
- ...options,
211
- method: "POST",
212
- body
213
- });
401
+ try {
402
+ return await this.fetchInstance(request, {
403
+ ...options,
404
+ method: "POST",
405
+ body
406
+ });
407
+ } catch (error) {
408
+ const requestError = this.convertToRequestError(error);
409
+ const phalaCloudError = this.emitError(requestError);
410
+ throw phalaCloudError;
411
+ }
214
412
  }
215
413
  /**
216
- * Perform PUT request (throws on error)
414
+ * Perform PUT request (throws PhalaCloudError on error)
217
415
  */
218
416
  async put(request, body, options) {
219
- return this.fetchInstance(request, {
220
- ...options,
221
- method: "PUT",
222
- body
223
- });
417
+ try {
418
+ return await this.fetchInstance(request, {
419
+ ...options,
420
+ method: "PUT",
421
+ body
422
+ });
423
+ } catch (error) {
424
+ const requestError = this.convertToRequestError(error);
425
+ const phalaCloudError = this.emitError(requestError);
426
+ throw phalaCloudError;
427
+ }
224
428
  }
225
429
  /**
226
- * Perform PATCH request (throws on error)
430
+ * Perform PATCH request (throws PhalaCloudError on error)
227
431
  */
228
432
  async patch(request, body, options) {
229
- return this.fetchInstance(request, {
230
- ...options,
231
- method: "PATCH",
232
- body
233
- });
433
+ try {
434
+ return await this.fetchInstance(request, {
435
+ ...options,
436
+ method: "PATCH",
437
+ body
438
+ });
439
+ } catch (error) {
440
+ const requestError = this.convertToRequestError(error);
441
+ const phalaCloudError = this.emitError(requestError);
442
+ throw phalaCloudError;
443
+ }
234
444
  }
235
445
  /**
236
- * Perform DELETE request (throws on error)
446
+ * Perform DELETE request (throws PhalaCloudError on error)
237
447
  */
238
448
  async delete(request, options) {
239
- return this.fetchInstance(request, {
240
- ...options,
241
- method: "DELETE"
242
- });
449
+ try {
450
+ return await this.fetchInstance(request, {
451
+ ...options,
452
+ method: "DELETE"
453
+ });
454
+ } catch (error) {
455
+ const requestError = this.convertToRequestError(error);
456
+ const phalaCloudError = this.emitError(requestError);
457
+ throw phalaCloudError;
458
+ }
243
459
  }
244
460
  // ===== Safe methods (return SafeResult) =====
461
+ /**
462
+ * Convert any error to RequestError
463
+ */
464
+ convertToRequestError(error) {
465
+ if (error && typeof error === "object" && "data" in error) {
466
+ return RequestError.fromFetchError(error);
467
+ }
468
+ if (error instanceof Error) {
469
+ return RequestError.fromError(error);
470
+ }
471
+ return new RequestError("Unknown error occurred", {
472
+ detail: "Unknown error occurred"
473
+ });
474
+ }
475
+ /**
476
+ * Broadcast error to event listeners (fire-and-forget)
477
+ * @param requestError - The request error to handle
478
+ * @returns PhalaCloudError instance to throw immediately
479
+ */
480
+ emitError(requestError) {
481
+ const phalaCloudError = parseApiError(requestError);
482
+ this.emitter.emit("error", phalaCloudError);
483
+ return phalaCloudError;
484
+ }
245
485
  /**
246
486
  * Safe wrapper for any request method (zod-style result)
487
+ * Returns PhalaCloudError (all errors extend this base class)
247
488
  */
248
489
  async safeRequest(fn) {
249
490
  try {
250
491
  const data = await fn();
251
492
  return { success: true, data };
252
493
  } catch (error) {
253
- if (error && typeof error === "object" && "data" in error) {
254
- const requestError2 = RequestError.fromFetchError(error);
255
- return { success: false, error: requestError2 };
256
- }
257
- if (error instanceof Error) {
258
- const requestError2 = RequestError.fromError(error);
259
- return { success: false, error: requestError2 };
494
+ if (error instanceof PhalaCloudError) {
495
+ return { success: false, error };
260
496
  }
261
- const requestError = new RequestError("Unknown error occurred", {
262
- detail: "Unknown error occurred"
263
- });
497
+ const requestError = this.convertToRequestError(error);
498
+ this.emitError(requestError);
264
499
  return { success: false, error: requestError };
265
500
  }
266
501
  }
@@ -383,7 +618,7 @@ function defineSimpleAction(schema, fn) {
383
618
  const data = await fn(client);
384
619
  return { success: true, data };
385
620
  } catch (error) {
386
- if (error && typeof error === "object" && "isRequestError" in error) {
621
+ if (error && typeof error === "object" && "status" in error) {
387
622
  return { success: false, error };
388
623
  }
389
624
  if (error && typeof error === "object" && "issues" in error) {
@@ -440,7 +675,7 @@ function defineAction(schema, fn) {
440
675
  const data = await fn(client, params);
441
676
  return { success: true, data };
442
677
  } catch (error) {
443
- if (error && typeof error === "object" && "isRequestError" in error) {
678
+ if (error && typeof error === "object" && "status" in error) {
444
679
  return { success: false, error };
445
680
  }
446
681
  if (error && typeof error === "object" && "issues" in error) {
@@ -1025,12 +1260,13 @@ var ProvisionCvmComposeFileUpdateRequestSchema = z13.object({
1025
1260
  }).refine(
1026
1261
  (data) => !!(data.id || data.uuid || data.app_id || data.instance_id),
1027
1262
  "One of id, uuid, app_id, or instance_id must be provided"
1028
- ).transform((data) => ({
1029
- cvmId: data.id || data.uuid || data.app_id || data.instance_id,
1030
- request: data.app_compose,
1031
- update_env_vars: data.update_env_vars,
1032
- _raw: data
1033
- }));
1263
+ ).transform((data) => {
1264
+ return {
1265
+ cvmId: data.id || data.uuid || data.app_id || data.instance_id,
1266
+ request: { ...data.app_compose, update_env_vars: data.update_env_vars },
1267
+ _raw: data
1268
+ };
1269
+ });
1034
1270
  var ProvisionCvmComposeFileUpdateResultSchema = z13.object({
1035
1271
  app_id: z13.string().nullable(),
1036
1272
  device_id: z13.string().nullable(),
@@ -1133,6 +1369,26 @@ var { action: getAppEnvEncryptPubKey, safeAction: safeGetAppEnvEncryptPubKey } =
1133
1369
  return await client.get(`/kms/${validatedRequest.kms}/pubkey/${validatedRequest.app_id}`);
1134
1370
  });
1135
1371
 
1372
+ // src/actions/kms/next_app_ids.ts
1373
+ import { z as z18 } from "zod";
1374
+ var NextAppIdsRequestSchema = z18.object({
1375
+ counts: z18.number().int().min(1).max(20).optional().default(1)
1376
+ }).strict();
1377
+ var NextAppIdsSchema = z18.object({
1378
+ app_ids: z18.array(
1379
+ z18.object({
1380
+ app_id: z18.string(),
1381
+ nonce: z18.number().int().min(0)
1382
+ })
1383
+ )
1384
+ }).strict();
1385
+ var { action: nextAppIds, safeAction: safeNextAppIds } = defineAction(NextAppIdsSchema, async (client, payload) => {
1386
+ const validatedRequest = NextAppIdsRequestSchema.parse(payload ?? {});
1387
+ const params = new URLSearchParams();
1388
+ params.append("counts", validatedRequest.counts.toString());
1389
+ return await client.get(`/kms/phala/next_app_id?${params.toString()}`);
1390
+ });
1391
+
1136
1392
  // src/actions/cvms/start_cvm.ts
1137
1393
  var StartCvmRequestSchema = CvmIdSchema;
1138
1394
  var { action: startCvm, safeAction: safeStartCvm } = defineAction(VMSchema, async (client, request) => {
@@ -1158,10 +1414,10 @@ var { action: shutdownCvm, safeAction: safeShutdownCvm } = defineAction(VMSchema
1158
1414
  });
1159
1415
 
1160
1416
  // src/actions/cvms/restart_cvm.ts
1161
- import { z as z18 } from "zod";
1417
+ import { z as z19 } from "zod";
1162
1418
  var RestartCvmRequestSchema = refineCvmId(
1163
1419
  CvmIdObjectSchema.extend({
1164
- force: z18.boolean().optional()
1420
+ force: z19.boolean().optional()
1165
1421
  })
1166
1422
  );
1167
1423
  var { action: restartCvm, safeAction: safeRestartCvm } = defineAction(VMSchema, async (client, request) => {
@@ -1172,10 +1428,10 @@ var { action: restartCvm, safeAction: safeRestartCvm } = defineAction(VMSchema,
1172
1428
  });
1173
1429
 
1174
1430
  // src/actions/cvms/delete_cvm.ts
1175
- import { z as z19 } from "zod";
1431
+ import { z as z20 } from "zod";
1176
1432
  var DeleteCvmRequestSchema = CvmIdSchema;
1177
1433
  var { action: deleteCvm, safeAction: safeDeleteCvm } = defineAction(
1178
- z19.void(),
1434
+ z20.void(),
1179
1435
  async (client, request) => {
1180
1436
  const { cvmId } = DeleteCvmRequestSchema.parse(request);
1181
1437
  await client.delete(`/cvms/${cvmId}`);
@@ -1184,41 +1440,41 @@ var { action: deleteCvm, safeAction: safeDeleteCvm } = defineAction(
1184
1440
  );
1185
1441
 
1186
1442
  // src/actions/cvms/get_cvm_stats.ts
1187
- import { z as z20 } from "zod";
1188
- var DiskInfoSchema = z20.object({
1189
- name: z20.string(),
1190
- mount_point: z20.string(),
1191
- total_size: z20.number(),
1192
- free_size: z20.number()
1443
+ import { z as z21 } from "zod";
1444
+ var DiskInfoSchema = z21.object({
1445
+ name: z21.string(),
1446
+ mount_point: z21.string(),
1447
+ total_size: z21.number(),
1448
+ free_size: z21.number()
1193
1449
  });
1194
- var SystemInfoSchema = z20.object({
1195
- os_name: z20.string(),
1196
- os_version: z20.string(),
1197
- kernel_version: z20.string(),
1198
- cpu_model: z20.string(),
1199
- num_cpus: z20.number(),
1200
- total_memory: z20.number(),
1201
- available_memory: z20.number(),
1202
- used_memory: z20.number(),
1203
- free_memory: z20.number(),
1204
- total_swap: z20.number(),
1205
- used_swap: z20.number(),
1206
- free_swap: z20.number(),
1207
- uptime: z20.number(),
1208
- loadavg_one: z20.number(),
1209
- loadavg_five: z20.number(),
1210
- loadavg_fifteen: z20.number(),
1211
- disks: z20.array(DiskInfoSchema)
1450
+ var SystemInfoSchema = z21.object({
1451
+ os_name: z21.string(),
1452
+ os_version: z21.string(),
1453
+ kernel_version: z21.string(),
1454
+ cpu_model: z21.string(),
1455
+ num_cpus: z21.number(),
1456
+ total_memory: z21.number(),
1457
+ available_memory: z21.number(),
1458
+ used_memory: z21.number(),
1459
+ free_memory: z21.number(),
1460
+ total_swap: z21.number(),
1461
+ used_swap: z21.number(),
1462
+ free_swap: z21.number(),
1463
+ uptime: z21.number(),
1464
+ loadavg_one: z21.number(),
1465
+ loadavg_five: z21.number(),
1466
+ loadavg_fifteen: z21.number(),
1467
+ disks: z21.array(DiskInfoSchema)
1212
1468
  });
1213
- var CvmSystemInfoSchema = z20.object({
1214
- is_online: z20.boolean(),
1215
- is_public: z20.boolean().default(false),
1216
- error: z20.string().nullable(),
1469
+ var CvmSystemInfoSchema = z21.object({
1470
+ is_online: z21.boolean(),
1471
+ is_public: z21.boolean().default(false),
1472
+ error: z21.string().nullable(),
1217
1473
  sysinfo: SystemInfoSchema.nullable(),
1218
- status: z20.string().nullable(),
1219
- in_progress: z20.boolean().default(false),
1220
- boot_progress: z20.string().nullable(),
1221
- boot_error: z20.string().nullable()
1474
+ status: z21.string().nullable(),
1475
+ in_progress: z21.boolean().default(false),
1476
+ boot_progress: z21.string().nullable(),
1477
+ boot_error: z21.string().nullable()
1222
1478
  });
1223
1479
  var GetCvmStatsRequestSchema = CvmIdSchema;
1224
1480
  var { action: getCvmStats, safeAction: safeGetCvmStats } = defineAction(CvmSystemInfoSchema, async (client, request) => {
@@ -1227,18 +1483,18 @@ var { action: getCvmStats, safeAction: safeGetCvmStats } = defineAction(CvmSyste
1227
1483
  });
1228
1484
 
1229
1485
  // src/actions/cvms/get_cvm_network.ts
1230
- import { z as z21 } from "zod";
1231
- var CvmNetworkUrlsSchema2 = z21.object({
1232
- app: z21.string(),
1233
- instance: z21.string()
1486
+ import { z as z22 } from "zod";
1487
+ var CvmNetworkUrlsSchema2 = z22.object({
1488
+ app: z22.string(),
1489
+ instance: z22.string()
1234
1490
  });
1235
- var CvmNetworkSchema = z21.object({
1236
- is_online: z21.boolean(),
1237
- is_public: z21.boolean().default(true),
1238
- error: z21.string().nullable(),
1239
- internal_ip: z21.string().nullable(),
1240
- latest_handshake: z21.string().nullable(),
1241
- public_urls: z21.array(CvmNetworkUrlsSchema2).nullable()
1491
+ var CvmNetworkSchema = z22.object({
1492
+ is_online: z22.boolean(),
1493
+ is_public: z22.boolean().default(true),
1494
+ error: z22.string().nullable(),
1495
+ internal_ip: z22.string().nullable(),
1496
+ latest_handshake: z22.string().nullable(),
1497
+ public_urls: z22.array(CvmNetworkUrlsSchema2).nullable()
1242
1498
  });
1243
1499
  var GetCvmNetworkRequestSchema = CvmIdSchema;
1244
1500
  var { action: getCvmNetwork, safeAction: safeGetCvmNetwork } = defineAction(CvmNetworkSchema, async (client, request) => {
@@ -1247,36 +1503,36 @@ var { action: getCvmNetwork, safeAction: safeGetCvmNetwork } = defineAction(CvmN
1247
1503
  });
1248
1504
 
1249
1505
  // src/actions/cvms/get_cvm_docker_compose.ts
1250
- import { z as z22 } from "zod";
1506
+ import { z as z23 } from "zod";
1251
1507
  var GetCvmDockerComposeRequestSchema = CvmIdSchema;
1252
- var { action: getCvmDockerCompose, safeAction: safeGetCvmDockerCompose } = defineAction(z22.string(), async (client, request) => {
1508
+ var { action: getCvmDockerCompose, safeAction: safeGetCvmDockerCompose } = defineAction(z23.string(), async (client, request) => {
1253
1509
  const { cvmId } = GetCvmDockerComposeRequestSchema.parse(request);
1254
1510
  return await client.get(`/cvms/${cvmId}/docker-compose.yml`);
1255
1511
  });
1256
1512
 
1257
1513
  // src/actions/cvms/get_cvm_containers_stats.ts
1258
- import { z as z23 } from "zod";
1259
- var ContainerInfoSchema = z23.object({
1260
- id: z23.string(),
1261
- names: z23.array(z23.string()),
1262
- image: z23.string(),
1263
- image_id: z23.string(),
1264
- command: z23.string().nullable().optional(),
1265
- created: z23.number(),
1266
- state: z23.string(),
1267
- status: z23.string(),
1268
- log_endpoint: z23.string().nullable()
1514
+ import { z as z24 } from "zod";
1515
+ var ContainerInfoSchema = z24.object({
1516
+ id: z24.string(),
1517
+ names: z24.array(z24.string()),
1518
+ image: z24.string(),
1519
+ image_id: z24.string(),
1520
+ command: z24.string().nullable().optional(),
1521
+ created: z24.number(),
1522
+ state: z24.string(),
1523
+ status: z24.string(),
1524
+ log_endpoint: z24.string().nullable()
1269
1525
  });
1270
- var CvmContainersStatsSchema = z23.object({
1271
- is_online: z23.boolean(),
1272
- is_public: z23.boolean().default(true),
1273
- error: z23.string().nullable(),
1274
- docker_compose_file: z23.string().nullable(),
1275
- manifest_version: z23.number().nullable(),
1276
- version: z23.string().nullable(),
1277
- runner: z23.string().nullable(),
1278
- features: z23.array(z23.string()).nullable(),
1279
- containers: z23.array(ContainerInfoSchema).nullable()
1526
+ var CvmContainersStatsSchema = z24.object({
1527
+ is_online: z24.boolean(),
1528
+ is_public: z24.boolean().default(true),
1529
+ error: z24.string().nullable(),
1530
+ docker_compose_file: z24.string().nullable(),
1531
+ manifest_version: z24.number().nullable(),
1532
+ version: z24.string().nullable(),
1533
+ runner: z24.string().nullable(),
1534
+ features: z24.array(z24.string()).nullable(),
1535
+ containers: z24.array(ContainerInfoSchema).nullable()
1280
1536
  });
1281
1537
  var GetCvmContainersStatsRequestSchema = CvmIdSchema;
1282
1538
  var { action: getCvmContainersStats, safeAction: safeGetCvmContainersStats } = defineAction(CvmContainersStatsSchema, async (client, request) => {
@@ -1285,62 +1541,62 @@ var { action: getCvmContainersStats, safeAction: safeGetCvmContainersStats } = d
1285
1541
  });
1286
1542
 
1287
1543
  // src/actions/cvms/get_cvm_attestation.ts
1288
- import { z as z24 } from "zod";
1289
- var CertificateSubjectSchema = z24.object({
1290
- common_name: z24.string().nullable(),
1291
- organization: z24.string().nullable(),
1292
- country: z24.string().nullable(),
1293
- state: z24.string().nullable(),
1294
- locality: z24.string().nullable()
1544
+ import { z as z25 } from "zod";
1545
+ var CertificateSubjectSchema = z25.object({
1546
+ common_name: z25.string().nullable(),
1547
+ organization: z25.string().nullable(),
1548
+ country: z25.string().nullable(),
1549
+ state: z25.string().nullable(),
1550
+ locality: z25.string().nullable()
1295
1551
  });
1296
- var CertificateIssuerSchema = z24.object({
1297
- common_name: z24.string().nullable(),
1298
- organization: z24.string().nullable(),
1299
- country: z24.string().nullable()
1552
+ var CertificateIssuerSchema = z25.object({
1553
+ common_name: z25.string().nullable(),
1554
+ organization: z25.string().nullable(),
1555
+ country: z25.string().nullable()
1300
1556
  });
1301
- var CertificateSchema = z24.object({
1557
+ var CertificateSchema = z25.object({
1302
1558
  subject: CertificateSubjectSchema,
1303
1559
  issuer: CertificateIssuerSchema,
1304
- serial_number: z24.string(),
1305
- not_before: z24.string(),
1560
+ serial_number: z25.string(),
1561
+ not_before: z25.string(),
1306
1562
  // datetime serialized as ISO string
1307
- not_after: z24.string(),
1563
+ not_after: z25.string(),
1308
1564
  // datetime serialized as ISO string
1309
- version: z24.string(),
1310
- fingerprint: z24.string(),
1311
- signature_algorithm: z24.string(),
1312
- sans: z24.array(z24.string()).nullable(),
1313
- is_ca: z24.boolean(),
1314
- position_in_chain: z24.number().nullable(),
1315
- quote: z24.string().nullable(),
1316
- app_id: z24.string().nullable().optional(),
1317
- cert_usage: z24.string().nullable().optional()
1565
+ version: z25.string(),
1566
+ fingerprint: z25.string(),
1567
+ signature_algorithm: z25.string(),
1568
+ sans: z25.array(z25.string()).nullable(),
1569
+ is_ca: z25.boolean(),
1570
+ position_in_chain: z25.number().nullable(),
1571
+ quote: z25.string().nullable(),
1572
+ app_id: z25.string().nullable().optional(),
1573
+ cert_usage: z25.string().nullable().optional()
1318
1574
  });
1319
- var EventLogSchema = z24.object({
1320
- imr: z24.number(),
1321
- event_type: z24.number(),
1322
- digest: z24.string(),
1323
- event: z24.string(),
1324
- event_payload: z24.string()
1575
+ var EventLogSchema = z25.object({
1576
+ imr: z25.number(),
1577
+ event_type: z25.number(),
1578
+ digest: z25.string(),
1579
+ event: z25.string(),
1580
+ event_payload: z25.string()
1325
1581
  });
1326
- var TcbInfoSchema = z24.object({
1327
- mrtd: z24.string(),
1328
- rootfs_hash: z24.string().nullable().optional(),
1329
- rtmr0: z24.string(),
1330
- rtmr1: z24.string(),
1331
- rtmr2: z24.string(),
1332
- rtmr3: z24.string(),
1333
- event_log: z24.array(EventLogSchema),
1334
- app_compose: z24.string()
1582
+ var TcbInfoSchema = z25.object({
1583
+ mrtd: z25.string(),
1584
+ rootfs_hash: z25.string().nullable().optional(),
1585
+ rtmr0: z25.string(),
1586
+ rtmr1: z25.string(),
1587
+ rtmr2: z25.string(),
1588
+ rtmr3: z25.string(),
1589
+ event_log: z25.array(EventLogSchema),
1590
+ app_compose: z25.string()
1335
1591
  });
1336
- var CvmAttestationSchema = z24.object({
1337
- name: z24.string().nullable(),
1338
- is_online: z24.boolean(),
1339
- is_public: z24.boolean().default(true),
1340
- error: z24.string().nullable(),
1341
- app_certificates: z24.array(CertificateSchema).nullable(),
1592
+ var CvmAttestationSchema = z25.object({
1593
+ name: z25.string().nullable(),
1594
+ is_online: z25.boolean(),
1595
+ is_public: z25.boolean().default(true),
1596
+ error: z25.string().nullable(),
1597
+ app_certificates: z25.array(CertificateSchema).nullable(),
1342
1598
  tcb_info: TcbInfoSchema.nullable(),
1343
- compose_file: z24.string().nullable()
1599
+ compose_file: z25.string().nullable()
1344
1600
  });
1345
1601
  var GetCvmAttestationRequestSchema = CvmIdSchema;
1346
1602
  var { action: getCvmAttestation, safeAction: safeGetCvmAttestation } = defineAction(CvmAttestationSchema, async (client, request) => {
@@ -1349,17 +1605,17 @@ var { action: getCvmAttestation, safeAction: safeGetCvmAttestation } = defineAct
1349
1605
  });
1350
1606
 
1351
1607
  // src/actions/cvms/update_cvm_resources.ts
1352
- import { z as z25 } from "zod";
1608
+ import { z as z26 } from "zod";
1353
1609
  var UpdateCvmResourcesRequestSchema = refineCvmId(
1354
1610
  CvmIdObjectSchema.extend({
1355
- vcpu: z25.number().optional(),
1356
- memory: z25.number().optional(),
1357
- disk_size: z25.number().optional(),
1358
- instance_type: z25.string().optional(),
1359
- allow_restart: z25.boolean().optional()
1611
+ vcpu: z26.number().optional(),
1612
+ memory: z26.number().optional(),
1613
+ disk_size: z26.number().optional(),
1614
+ instance_type: z26.string().optional(),
1615
+ allow_restart: z26.boolean().optional()
1360
1616
  })
1361
1617
  );
1362
- var { action: updateCvmResources, safeAction: safeUpdateCvmResources } = defineAction(z25.void(), async (client, request) => {
1618
+ var { action: updateCvmResources, safeAction: safeUpdateCvmResources } = defineAction(z26.void(), async (client, request) => {
1363
1619
  const parsed = UpdateCvmResourcesRequestSchema.parse(request);
1364
1620
  const { cvmId } = CvmIdSchema.parse(parsed);
1365
1621
  const { ...body } = parsed;
@@ -1368,11 +1624,11 @@ var { action: updateCvmResources, safeAction: safeUpdateCvmResources } = defineA
1368
1624
  });
1369
1625
 
1370
1626
  // src/actions/cvms/update_cvm_visibility.ts
1371
- import { z as z26 } from "zod";
1627
+ import { z as z27 } from "zod";
1372
1628
  var UpdateCvmVisibilityRequestSchema = refineCvmId(
1373
1629
  CvmIdObjectSchema.extend({
1374
- public_sysinfo: z26.boolean(),
1375
- public_logs: z26.boolean()
1630
+ public_sysinfo: z27.boolean(),
1631
+ public_logs: z27.boolean()
1376
1632
  })
1377
1633
  );
1378
1634
  var { action: updateCvmVisibility, safeAction: safeUpdateCvmVisibility } = defineAction(CvmLegacyDetailSchema, async (client, request) => {
@@ -1382,6 +1638,59 @@ var { action: updateCvmVisibility, safeAction: safeUpdateCvmVisibility } = defin
1382
1638
  return await client.patch(`/cvms/${cvmId}/visibility`, { public_sysinfo, public_logs });
1383
1639
  });
1384
1640
 
1641
+ // src/actions/cvms/get_available_os_images.ts
1642
+ import { z as z28 } from "zod";
1643
+ var OSImageVariantSchema = z28.object({
1644
+ name: z28.string(),
1645
+ os_image_hash: z28.string().nullable(),
1646
+ is_current: z28.boolean()
1647
+ });
1648
+ var AvailableOSImageSchema2 = z28.object({
1649
+ version: z28.union([
1650
+ z28.tuple([z28.number(), z28.number(), z28.number(), z28.number()]),
1651
+ z28.tuple([z28.number(), z28.number(), z28.number()])
1652
+ ]),
1653
+ prod: OSImageVariantSchema.nullable(),
1654
+ dev: OSImageVariantSchema.nullable()
1655
+ });
1656
+ var GetAvailableOSImagesResponseSchema = z28.array(AvailableOSImageSchema2);
1657
+ var GetAvailableOSImagesRequestSchema = CvmIdSchema;
1658
+ var { action: getAvailableOsImages, safeAction: safeGetAvailableOsImages } = defineAction(GetAvailableOSImagesResponseSchema, async (client, request) => {
1659
+ const { cvmId } = GetAvailableOSImagesRequestSchema.parse(request);
1660
+ return await client.get(`/cvms/${cvmId}/available-os-images`);
1661
+ });
1662
+
1663
+ // src/actions/cvms/update_os_image.ts
1664
+ import { z as z29 } from "zod";
1665
+ var UpdateOsImageRequestSchema = refineCvmId(
1666
+ CvmIdObjectSchema.extend({
1667
+ os_image_name: z29.string().min(1, "OS image name is required")
1668
+ })
1669
+ );
1670
+ var { action: updateOsImage, safeAction: safeUpdateOsImage } = defineAction(z29.void(), async (client, request) => {
1671
+ const parsed = UpdateOsImageRequestSchema.parse(request);
1672
+ const { cvmId } = CvmIdSchema.parse(parsed);
1673
+ const { os_image_name } = parsed;
1674
+ await client.patch(`/cvms/${cvmId}/os-image`, { os_image_name });
1675
+ return void 0;
1676
+ });
1677
+
1678
+ // src/actions/cvms/get_cvm_state.ts
1679
+ import { z as z30 } from "zod";
1680
+ var CvmStateSchema = z30.object({
1681
+ status: z30.string(),
1682
+ derived_status: z30.string().optional(),
1683
+ vm_uuid: z30.string().optional(),
1684
+ instance_id: z30.string().optional(),
1685
+ uptime: z30.string().optional()
1686
+ // Add other state fields as needed
1687
+ });
1688
+ var GetCvmStateRequestSchema = CvmIdSchema;
1689
+ var { action: getCvmState, safeAction: safeGetCvmState } = defineAction(CvmStateSchema, async (client, request) => {
1690
+ const { cvmId } = GetCvmStateRequestSchema.parse(request);
1691
+ return await client.get(`/cvms/${cvmId}/state`);
1692
+ });
1693
+
1385
1694
  // src/create-client.ts
1386
1695
  function createClient2(config = {}) {
1387
1696
  const client = createClient(config);
@@ -1434,18 +1743,26 @@ function createClient2(config = {}) {
1434
1743
  safeUpdateCvmResources,
1435
1744
  updateCvmVisibility,
1436
1745
  safeUpdateCvmVisibility,
1746
+ getAvailableOsImages,
1747
+ safeGetAvailableOsImages,
1748
+ updateOsImage,
1749
+ safeUpdateOsImage,
1437
1750
  getKmsInfo,
1438
1751
  safeGetKmsInfo,
1439
1752
  getKmsList,
1440
1753
  safeGetKmsList,
1441
1754
  getAppEnvEncryptPubKey,
1442
- safeGetAppEnvEncryptPubKey
1755
+ safeGetAppEnvEncryptPubKey,
1756
+ nextAppIds,
1757
+ safeNextAppIds,
1758
+ getCvmState,
1759
+ safeGetCvmState
1443
1760
  };
1444
1761
  return client.extend(allActions);
1445
1762
  }
1446
1763
 
1447
1764
  // src/actions/blockchains/deploy_app_auth.ts
1448
- import { z as z27 } from "zod";
1765
+ import { z as z31 } from "zod";
1449
1766
  import {
1450
1767
  createPublicClient as createPublicClient2,
1451
1768
  createWalletClient as createWalletClient2,
@@ -1458,23 +1775,6 @@ import { privateKeyToAccount as privateKeyToAccount2 } from "viem/accounts";
1458
1775
  // src/utils/index.ts
1459
1776
  import { encryptEnvVars } from "@phala/dstack-sdk/encrypt-env-vars";
1460
1777
 
1461
- // src/utils/get_error_message.ts
1462
- function getErrorMessage(error) {
1463
- if (typeof error.detail === "string") {
1464
- return error.detail;
1465
- }
1466
- if (Array.isArray(error.detail)) {
1467
- if (error.detail.length > 0) {
1468
- return error.detail[0]?.msg || "Validation error";
1469
- }
1470
- return "Validation error";
1471
- }
1472
- if (typeof error.detail === "object" && error.detail !== null) {
1473
- return JSON.stringify(error.detail);
1474
- }
1475
- return "Unknown error occurred";
1476
- }
1477
-
1478
1778
  // src/utils/as-hex.ts
1479
1779
  import { isHex } from "viem";
1480
1780
  function asHex(value) {
@@ -2123,25 +2423,25 @@ var kmsAuthAbi = [
2123
2423
  anonymous: false
2124
2424
  }
2125
2425
  ];
2126
- var DeployAppAuthRequestBaseSchema = z27.object({
2426
+ var DeployAppAuthRequestBaseSchema = z31.object({
2127
2427
  // Chain configuration (conditionally required)
2128
- chain: z27.unknown().optional(),
2129
- rpcUrl: z27.string().optional(),
2428
+ chain: z31.unknown().optional(),
2429
+ rpcUrl: z31.string().optional(),
2130
2430
  // Contract configuration (required)
2131
- kmsContractAddress: z27.string(),
2431
+ kmsContractAddress: z31.string(),
2132
2432
  // Authentication mode: either privateKey OR walletClient (required, mutually exclusive)
2133
- privateKey: z27.string().optional(),
2134
- walletClient: z27.unknown().optional(),
2433
+ privateKey: z31.string().optional(),
2434
+ walletClient: z31.unknown().optional(),
2135
2435
  // Public client (optional, will create default if not provided)
2136
- publicClient: z27.unknown().optional(),
2436
+ publicClient: z31.unknown().optional(),
2137
2437
  // App configuration (optional)
2138
- allowAnyDevice: z27.boolean().optional().default(false),
2139
- deviceId: z27.string().optional().default("0000000000000000000000000000000000000000000000000000000000000000"),
2140
- composeHash: z27.string().optional().default("0000000000000000000000000000000000000000000000000000000000000000"),
2141
- disableUpgrades: z27.boolean().optional().default(false),
2438
+ allowAnyDevice: z31.boolean().optional().default(false),
2439
+ deviceId: z31.string().optional().default("0000000000000000000000000000000000000000000000000000000000000000"),
2440
+ composeHash: z31.string().optional().default("0000000000000000000000000000000000000000000000000000000000000000"),
2441
+ disableUpgrades: z31.boolean().optional().default(false),
2142
2442
  // Validation configuration (optional)
2143
- skipPrerequisiteChecks: z27.boolean().optional().default(false),
2144
- minBalance: z27.string().optional()
2443
+ skipPrerequisiteChecks: z31.boolean().optional().default(false),
2444
+ minBalance: z31.string().optional()
2145
2445
  // ETH amount as string, e.g., "0.01"
2146
2446
  }).passthrough();
2147
2447
  var DeployAppAuthRequestSchema = DeployAppAuthRequestBaseSchema.refine(
@@ -2169,13 +2469,13 @@ var DeployAppAuthRequestSchema = DeployAppAuthRequestBaseSchema.refine(
2169
2469
  path: ["chain"]
2170
2470
  }
2171
2471
  );
2172
- var DeployAppAuthSchema = z27.object({
2173
- appId: z27.string(),
2174
- appAuthAddress: z27.string(),
2175
- deployer: z27.string(),
2176
- transactionHash: z27.string(),
2177
- blockNumber: z27.bigint().optional(),
2178
- gasUsed: z27.bigint().optional()
2472
+ var DeployAppAuthSchema = z31.object({
2473
+ appId: z31.string(),
2474
+ appAuthAddress: z31.string(),
2475
+ deployer: z31.string(),
2476
+ transactionHash: z31.string(),
2477
+ blockNumber: z31.bigint().optional(),
2478
+ gasUsed: z31.bigint().optional()
2179
2479
  }).passthrough();
2180
2480
  function parseDeploymentResult(receipt, deployer, kmsContractAddress) {
2181
2481
  try {
@@ -2421,7 +2721,7 @@ async function safeDeployAppAuth(request, parameters) {
2421
2721
  }
2422
2722
 
2423
2723
  // src/actions/blockchains/add_compose_hash.ts
2424
- import { z as z28 } from "zod";
2724
+ import { z as z32 } from "zod";
2425
2725
  import {
2426
2726
  createPublicClient as createPublicClient3,
2427
2727
  createWalletClient as createWalletClient3,
@@ -2445,29 +2745,29 @@ var appAuthAbi = [
2445
2745
  anonymous: false
2446
2746
  }
2447
2747
  ];
2448
- var AddComposeHashRequestSchema = z28.object({
2748
+ var AddComposeHashRequestSchema = z32.object({
2449
2749
  // Chain configuration (conditionally required)
2450
- chain: z28.unknown().optional(),
2451
- rpcUrl: z28.string().optional(),
2452
- appId: z28.string(),
2453
- composeHash: z28.string(),
2750
+ chain: z32.unknown().optional(),
2751
+ rpcUrl: z32.string().optional(),
2752
+ appId: z32.string(),
2753
+ composeHash: z32.string(),
2454
2754
  // Authentication mode: either privateKey OR walletClient (required, mutually exclusive)
2455
- privateKey: z28.string().optional(),
2456
- walletClient: z28.unknown().optional(),
2755
+ privateKey: z32.string().optional(),
2756
+ walletClient: z32.unknown().optional(),
2457
2757
  // Public client (optional, will create default if not provided)
2458
- publicClient: z28.unknown().optional(),
2758
+ publicClient: z32.unknown().optional(),
2459
2759
  // Validation configuration (optional)
2460
- skipPrerequisiteChecks: z28.boolean().optional().default(false),
2461
- minBalance: z28.string().optional(),
2760
+ skipPrerequisiteChecks: z32.boolean().optional().default(false),
2761
+ minBalance: z32.string().optional(),
2462
2762
  // ETH amount as string, e.g., "0.01"
2463
2763
  // Transaction control options
2464
- timeout: z28.number().optional().default(12e4),
2465
- retryOptions: z28.unknown().optional(),
2466
- signal: z28.unknown().optional(),
2764
+ timeout: z32.number().optional().default(12e4),
2765
+ retryOptions: z32.unknown().optional(),
2766
+ signal: z32.unknown().optional(),
2467
2767
  // Progress callbacks
2468
- onTransactionStateChange: z28.function().optional(),
2469
- onTransactionSubmitted: z28.function().optional(),
2470
- onTransactionConfirmed: z28.function().optional()
2768
+ onTransactionStateChange: z32.function().optional(),
2769
+ onTransactionSubmitted: z32.function().optional(),
2770
+ onTransactionConfirmed: z32.function().optional()
2471
2771
  }).passthrough().refine(
2472
2772
  (data) => {
2473
2773
  const hasPrivateKey = !!data.privateKey;
@@ -2491,12 +2791,12 @@ var AddComposeHashRequestSchema = z28.object({
2491
2791
  path: ["chain"]
2492
2792
  }
2493
2793
  );
2494
- var AddComposeHashSchema = z28.object({
2495
- composeHash: z28.string(),
2496
- appId: z28.string(),
2497
- transactionHash: z28.string(),
2498
- blockNumber: z28.bigint().optional(),
2499
- gasUsed: z28.bigint().optional()
2794
+ var AddComposeHashSchema = z32.object({
2795
+ composeHash: z32.string(),
2796
+ appId: z32.string(),
2797
+ transactionHash: z32.string(),
2798
+ blockNumber: z32.bigint().optional(),
2799
+ gasUsed: z32.bigint().optional()
2500
2800
  }).passthrough();
2501
2801
  function parseComposeHashResult(receipt, composeHash, appAuthAddress, appId) {
2502
2802
  console.log(receipt.logs);
@@ -2687,6 +2987,200 @@ async function safeAddComposeHash(request, parameters) {
2687
2987
  }
2688
2988
  }
2689
2989
 
2990
+ // src/actions/cvms/watch_cvm_state.ts
2991
+ import { z as z33 } from "zod";
2992
+ var WatchCvmStateParamsSchema = z33.object({
2993
+ target: z33.string().describe("Target status to wait for (e.g., 'running', 'stopped')"),
2994
+ interval: z33.number().min(5).max(30).default(5).describe("Polling interval in seconds"),
2995
+ timeout: z33.number().min(10).max(600).default(300).describe("Timeout per attempt in seconds"),
2996
+ maxRetries: z33.number().min(0).default(Number.POSITIVE_INFINITY).describe("Maximum number of retry attempts (Infinity for unlimited)"),
2997
+ retryDelay: z33.number().min(0).default(5e3).describe("Delay between retries in milliseconds")
2998
+ });
2999
+ var WatchCvmStateRequestSchema = WatchCvmStateParamsSchema;
3000
+ var WatchAbortedError = class extends Error {
3001
+ constructor() {
3002
+ super("Watch operation was aborted");
3003
+ this.name = "WatchAbortedError";
3004
+ }
3005
+ };
3006
+ var MaxRetriesExceededError = class extends Error {
3007
+ constructor(attempts) {
3008
+ super(`Maximum retry attempts (${attempts}) exceeded`);
3009
+ this.attempts = attempts;
3010
+ this.name = "MaxRetriesExceededError";
3011
+ }
3012
+ };
3013
+ function parseSSEEvent(eventType, data) {
3014
+ try {
3015
+ const parsed = JSON.parse(data);
3016
+ return { type: eventType, data: parsed };
3017
+ } catch {
3018
+ return { type: "error", data: { error: "Failed to parse SSE event" } };
3019
+ }
3020
+ }
3021
+ async function watchCvmState(client, request, options = {}) {
3022
+ const { cvmId } = CvmIdSchema.parse(request);
3023
+ const { target, interval, timeout, maxRetries, retryDelay } = WatchCvmStateParamsSchema.parse(request);
3024
+ const { signal, onEvent } = options;
3025
+ let attempt = 0;
3026
+ while (attempt < maxRetries) {
3027
+ if (signal?.aborted) {
3028
+ throw new WatchAbortedError();
3029
+ }
3030
+ attempt++;
3031
+ try {
3032
+ const result = await watchSingleAttempt(
3033
+ client,
3034
+ cvmId,
3035
+ target,
3036
+ interval,
3037
+ timeout,
3038
+ signal,
3039
+ onEvent
3040
+ );
3041
+ if (result) {
3042
+ return result;
3043
+ }
3044
+ if (attempt >= maxRetries) {
3045
+ throw new MaxRetriesExceededError(attempt);
3046
+ }
3047
+ await sleep(retryDelay, signal);
3048
+ } catch (error) {
3049
+ if (signal?.aborted) {
3050
+ throw new WatchAbortedError();
3051
+ }
3052
+ if (error instanceof WatchAbortedError || error instanceof MaxRetriesExceededError) {
3053
+ throw error;
3054
+ }
3055
+ if (attempt >= maxRetries) {
3056
+ throw error;
3057
+ }
3058
+ if (onEvent) {
3059
+ onEvent({
3060
+ type: "error",
3061
+ data: { error: error instanceof Error ? error.message : String(error) }
3062
+ });
3063
+ }
3064
+ await sleep(retryDelay, signal);
3065
+ }
3066
+ }
3067
+ throw new MaxRetriesExceededError(attempt);
3068
+ }
3069
+ async function watchSingleAttempt(client, cvmId, target, interval, timeout, signal, onEvent) {
3070
+ const params = new URLSearchParams({
3071
+ target,
3072
+ interval: String(interval),
3073
+ timeout: String(timeout)
3074
+ });
3075
+ const baseURL = client.config.baseURL || "";
3076
+ const fullUrl = `${baseURL}/cvms/${cvmId}/state?${params.toString()}`;
3077
+ const headers = {
3078
+ Accept: "text/event-stream",
3079
+ "Cache-Control": "no-cache"
3080
+ };
3081
+ if (!client.config.useCookieAuth && client.config.apiKey) {
3082
+ headers["X-API-Key"] = client.config.apiKey;
3083
+ }
3084
+ if (client.config.headers) {
3085
+ Object.entries(client.config.headers).forEach(([key, value]) => {
3086
+ if (typeof value === "string") {
3087
+ headers[key] = value;
3088
+ }
3089
+ });
3090
+ }
3091
+ const response = await client.raw.native(fullUrl, {
3092
+ method: "GET",
3093
+ headers,
3094
+ signal,
3095
+ ...client.config.useCookieAuth ? { credentials: "include" } : {}
3096
+ });
3097
+ if (!response.ok) {
3098
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
3099
+ }
3100
+ if (!response.body) {
3101
+ throw new Error("Response body is null");
3102
+ }
3103
+ return parseSSEStream(response.body, signal, onEvent);
3104
+ }
3105
+ async function parseSSEStream(stream, signal, onEvent) {
3106
+ const reader = stream.getReader();
3107
+ const decoder = new TextDecoder();
3108
+ let buffer = "";
3109
+ let finalState = null;
3110
+ let currentEvent = "";
3111
+ let currentData = "";
3112
+ const processLine = (line) => {
3113
+ if (line.startsWith("event:")) {
3114
+ currentEvent = line.slice(6).trim();
3115
+ } else if (line.startsWith("data:")) {
3116
+ currentData = line.slice(5).trim();
3117
+ } else if (line === "") {
3118
+ if (currentEvent && currentData) {
3119
+ const event = parseSSEEvent(currentEvent, currentData);
3120
+ if (event.type === "state") {
3121
+ finalState = event.data;
3122
+ }
3123
+ onEvent?.(event);
3124
+ if (event.type === "complete") {
3125
+ return "complete";
3126
+ }
3127
+ if (event.type === "timeout") {
3128
+ return "timeout";
3129
+ }
3130
+ }
3131
+ currentEvent = "";
3132
+ currentData = "";
3133
+ }
3134
+ return null;
3135
+ };
3136
+ try {
3137
+ while (true) {
3138
+ if (signal?.aborted) {
3139
+ throw new WatchAbortedError();
3140
+ }
3141
+ const { done, value } = await reader.read();
3142
+ if (done) {
3143
+ break;
3144
+ }
3145
+ buffer += decoder.decode(value, { stream: true });
3146
+ const lines = buffer.split("\n");
3147
+ buffer = lines.pop() || "";
3148
+ for (const line of lines) {
3149
+ const result = processLine(line.trim());
3150
+ if (result === "complete") {
3151
+ return finalState;
3152
+ }
3153
+ if (result === "timeout") {
3154
+ return null;
3155
+ }
3156
+ }
3157
+ }
3158
+ return finalState;
3159
+ } catch (error) {
3160
+ if (error instanceof WatchAbortedError) {
3161
+ throw error;
3162
+ }
3163
+ throw new Error(`SSE stream error: ${error instanceof Error ? error.message : String(error)}`);
3164
+ } finally {
3165
+ reader.releaseLock();
3166
+ }
3167
+ }
3168
+ function sleep(ms, signal) {
3169
+ return new Promise((resolve, reject) => {
3170
+ if (signal?.aborted) {
3171
+ reject(new WatchAbortedError());
3172
+ return;
3173
+ }
3174
+ const timer = setTimeout(resolve, ms);
3175
+ if (signal) {
3176
+ signal.addEventListener("abort", () => {
3177
+ clearTimeout(timer);
3178
+ reject(new WatchAbortedError());
3179
+ });
3180
+ }
3181
+ });
3182
+ }
3183
+
2690
3184
  // src/parse_dotenv.ts
2691
3185
  var LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/gm;
2692
3186
  function parseEnv(input) {
@@ -2727,7 +3221,9 @@ import { verifyEnvEncryptPublicKey } from "@phala/dstack-sdk/verify-env-encrypt-
2727
3221
  export {
2728
3222
  AddComposeHashSchema,
2729
3223
  ApiErrorSchema,
3224
+ AuthError,
2730
3225
  AvailableNodesSchema,
3226
+ BusinessError,
2731
3227
  CommitCvmComposeFileUpdateRequestSchema,
2732
3228
  CommitCvmComposeFileUpdateSchema,
2733
3229
  CommitCvmProvisionRequestSchema,
@@ -2743,12 +3239,15 @@ export {
2743
3239
  CvmNetworkSchema,
2744
3240
  CvmNetworkUrlsSchema,
2745
3241
  CvmNodeSchema,
3242
+ CvmStateSchema,
2746
3243
  CvmSystemInfoSchema,
2747
3244
  DeleteCvmRequestSchema,
2748
3245
  DeployAppAuthRequestSchema,
2749
3246
  DeployAppAuthSchema,
2750
3247
  GetAppEnvEncryptPubKeyRequestSchema,
2751
3248
  GetAppEnvEncryptPubKeySchema,
3249
+ GetAvailableOSImagesRequestSchema,
3250
+ GetAvailableOSImagesResponseSchema,
2752
3251
  GetCvmAttestationRequestSchema,
2753
3252
  GetCvmComposeFileRequestSchema,
2754
3253
  GetCvmContainersStatsRequestSchema,
@@ -2757,6 +3256,7 @@ export {
2757
3256
  GetCvmListRequestSchema,
2758
3257
  GetCvmListSchema,
2759
3258
  GetCvmNetworkRequestSchema,
3259
+ GetCvmStateRequestSchema,
2760
3260
  GetCvmStatsRequestSchema,
2761
3261
  GetKmsInfoRequestSchema,
2762
3262
  GetKmsListRequestSchema,
@@ -2766,9 +3266,14 @@ export {
2766
3266
  ListInstanceTypesRequestSchema,
2767
3267
  ListWorkspacesSchema,
2768
3268
  ManagedUserSchema,
3269
+ MaxRetriesExceededError,
2769
3270
  NetworkError,
3271
+ NextAppIdsRequestSchema,
3272
+ NextAppIdsSchema,
3273
+ OSImageVariantSchema,
2770
3274
  PaginatedInstanceTypesSchema,
2771
3275
  PaginationMetadataSchema,
3276
+ PhalaCloudError,
2772
3277
  ProvisionCvmComposeFileUpdateRequestSchema,
2773
3278
  ProvisionCvmComposeFileUpdateResultSchema,
2774
3279
  ProvisionCvmRequestSchema,
@@ -2776,15 +3281,21 @@ export {
2776
3281
  RequestError,
2777
3282
  RestartCvmRequestSchema,
2778
3283
  SUPPORTED_CHAINS,
3284
+ ServerError,
2779
3285
  ShutdownCvmRequestSchema,
2780
3286
  StartCvmRequestSchema,
2781
3287
  StopCvmRequestSchema,
2782
3288
  TransactionError,
3289
+ UnknownError,
2783
3290
  UpdateCvmResourcesRequestSchema,
2784
3291
  UpdateCvmVisibilityRequestSchema,
3292
+ UpdateOsImageRequestSchema,
2785
3293
  VMSchema,
3294
+ ValidationError,
2786
3295
  VmInfoSchema,
2787
3296
  WalletError,
3297
+ WatchAbortedError,
3298
+ WatchCvmStateRequestSchema,
2788
3299
  WorkspaceResponseSchema,
2789
3300
  addComposeHash,
2790
3301
  addNetwork,
@@ -2811,8 +3322,11 @@ export {
2811
3322
  executeTransaction,
2812
3323
  executeTransactionWithRetry,
2813
3324
  extractNetworkClients,
3325
+ formatErrorMessage,
3326
+ formatValidationErrors,
2814
3327
  getAppEnvEncryptPubKey,
2815
3328
  getAvailableNodes,
3329
+ getAvailableOsImages,
2816
3330
  getComposeHash2 as getComposeHash,
2817
3331
  getCurrentUser,
2818
3332
  getCvmAttestation,
@@ -2822,13 +3336,17 @@ export {
2822
3336
  getCvmInfo,
2823
3337
  getCvmList,
2824
3338
  getCvmNetwork,
3339
+ getCvmState,
2825
3340
  getCvmStats,
2826
3341
  getErrorMessage,
2827
3342
  getKmsInfo,
2828
3343
  getKmsList,
3344
+ getValidationFields,
2829
3345
  getWorkspace,
2830
3346
  listInstanceTypes,
2831
3347
  listWorkspaces,
3348
+ nextAppIds,
3349
+ parseApiError,
2832
3350
  parseEnv,
2833
3351
  parseEnvVars,
2834
3352
  preprocessAppCompose,
@@ -2843,6 +3361,7 @@ export {
2843
3361
  safeDeployAppAuth,
2844
3362
  safeGetAppEnvEncryptPubKey,
2845
3363
  safeGetAvailableNodes,
3364
+ safeGetAvailableOsImages,
2846
3365
  safeGetCurrentUser,
2847
3366
  safeGetCvmAttestation,
2848
3367
  safeGetCvmComposeFile,
@@ -2851,12 +3370,14 @@ export {
2851
3370
  safeGetCvmInfo,
2852
3371
  safeGetCvmList,
2853
3372
  safeGetCvmNetwork,
3373
+ safeGetCvmState,
2854
3374
  safeGetCvmStats,
2855
3375
  safeGetKmsInfo,
2856
3376
  safeGetKmsList,
2857
3377
  safeGetWorkspace,
2858
3378
  safeListInstanceTypes,
2859
3379
  safeListWorkspaces,
3380
+ safeNextAppIds,
2860
3381
  safeProvisionCvm,
2861
3382
  safeProvisionCvmComposeFileUpdate,
2862
3383
  safeRestartCvm,
@@ -2865,6 +3386,7 @@ export {
2865
3386
  safeStopCvm,
2866
3387
  safeUpdateCvmResources,
2867
3388
  safeUpdateCvmVisibility,
3389
+ safeUpdateOsImage,
2868
3390
  safeValidateActionParameters,
2869
3391
  shutdownCvm,
2870
3392
  sortObject,
@@ -2873,9 +3395,11 @@ export {
2873
3395
  switchToNetwork,
2874
3396
  updateCvmResources,
2875
3397
  updateCvmVisibility,
3398
+ updateOsImage,
2876
3399
  validateActionParameters,
2877
3400
  validateNetworkPrerequisites,
2878
3401
  verifyEnvEncryptPublicKey,
2879
3402
  waitForTransactionReceipt,
3403
+ watchCvmState,
2880
3404
  withComposeMethods
2881
3405
  };