@phala/cloud 0.1.1-beta.3 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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) {
@@ -855,18 +1090,6 @@ var ProvisionCvmRequestSchema = z10.object({
855
1090
  kms_id: z10.string().optional(),
856
1091
  env_keys: z10.array(z10.string()).optional()
857
1092
  }).passthrough();
858
- function autofillComposeFileName(appCompose) {
859
- if (appCompose.compose_file && !appCompose.compose_file.name) {
860
- return {
861
- ...appCompose,
862
- compose_file: {
863
- ...appCompose.compose_file,
864
- name: appCompose.name
865
- }
866
- };
867
- }
868
- return appCompose;
869
- }
870
1093
  function handleGatewayCompatibility(appCompose) {
871
1094
  if (!appCompose.compose_file) {
872
1095
  return appCompose;
@@ -889,7 +1112,7 @@ function handleGatewayCompatibility(appCompose) {
889
1112
  };
890
1113
  }
891
1114
  var { action: provisionCvm, safeAction: safeProvisionCvm } = defineAction(ProvisionCvmSchema, async (client, appCompose) => {
892
- const body = handleGatewayCompatibility(autofillComposeFileName(appCompose));
1115
+ const body = handleGatewayCompatibility(appCompose);
893
1116
  let requestBody = { ...body };
894
1117
  if (typeof body.node_id === "number") {
895
1118
  requestBody = { ...body, teepod_id: body.node_id };
@@ -960,9 +1183,61 @@ var LooseAppComposeSchema = z12.object({
960
1183
  salt: z12.string().optional().nullable()
961
1184
  }).passthrough();
962
1185
 
1186
+ // src/utils/get_compose_hash.ts
1187
+ import crypto from "crypto";
1188
+ function sortObject(obj) {
1189
+ if (obj === void 0 || obj === null) {
1190
+ return obj;
1191
+ }
1192
+ if (Array.isArray(obj)) {
1193
+ return obj.map(sortObject);
1194
+ } else if (obj && typeof obj === "object" && obj.constructor === Object) {
1195
+ return Object.keys(obj).sort().reduce((result, key) => {
1196
+ const value = obj[key];
1197
+ result[key] = sortObject(value);
1198
+ return result;
1199
+ }, {});
1200
+ }
1201
+ return obj;
1202
+ }
1203
+ function preprocessAppCompose(dic) {
1204
+ const obj = { ...dic };
1205
+ if (obj.runner === "bash" && "docker_compose_file" in obj) {
1206
+ delete obj.docker_compose_file;
1207
+ } else if (obj.runner === "docker-compose" && "bash_script" in obj) {
1208
+ delete obj.bash_script;
1209
+ }
1210
+ if ("pre_launch_script" in obj && !obj.pre_launch_script) {
1211
+ delete obj.pre_launch_script;
1212
+ }
1213
+ return obj;
1214
+ }
1215
+ function dumpAppCompose(dic) {
1216
+ const ordered = sortObject(dic);
1217
+ let json = JSON.stringify(ordered, null, 4);
1218
+ json = json.replace(/": /g, '":');
1219
+ return json;
1220
+ }
1221
+ function getComposeHash(app_compose) {
1222
+ const preprocessed = preprocessAppCompose(app_compose);
1223
+ const manifest_str = dumpAppCompose(preprocessed);
1224
+ return crypto.createHash("sha256").update(manifest_str, "utf8").digest("hex");
1225
+ }
1226
+ function withComposeMethods(compose) {
1227
+ const appCompose = compose;
1228
+ return {
1229
+ ...compose,
1230
+ getHash: () => getComposeHash(appCompose),
1231
+ toString: () => dumpAppCompose(preprocessAppCompose(appCompose))
1232
+ };
1233
+ }
1234
+
963
1235
  // src/actions/cvms/get_cvm_compose_file.ts
1236
+ var GetCvmComposeFileResultSchema = LooseAppComposeSchema.transform(
1237
+ (data) => withComposeMethods(data)
1238
+ );
964
1239
  var GetCvmComposeFileRequestSchema = CvmIdSchema;
965
- var { action: getCvmComposeFile, safeAction: safeGetCvmComposeFile } = defineAction(LooseAppComposeSchema, async (client, request) => {
1240
+ var { action: getCvmComposeFile, safeAction: safeGetCvmComposeFile } = defineAction(GetCvmComposeFileResultSchema, async (client, request) => {
966
1241
  const { cvmId } = GetCvmComposeFileRequestSchema.parse(request);
967
1242
  return await client.get(`/cvms/${cvmId}/compose_file`);
968
1243
  });
@@ -985,12 +1260,13 @@ var ProvisionCvmComposeFileUpdateRequestSchema = z13.object({
985
1260
  }).refine(
986
1261
  (data) => !!(data.id || data.uuid || data.app_id || data.instance_id),
987
1262
  "One of id, uuid, app_id, or instance_id must be provided"
988
- ).transform((data) => ({
989
- cvmId: data.id || data.uuid || data.app_id || data.instance_id,
990
- request: data.app_compose,
991
- update_env_vars: data.update_env_vars,
992
- _raw: data
993
- }));
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
+ });
994
1270
  var ProvisionCvmComposeFileUpdateResultSchema = z13.object({
995
1271
  app_id: z13.string().nullable(),
996
1272
  device_id: z13.string().nullable(),
@@ -1418,23 +1694,6 @@ import { privateKeyToAccount as privateKeyToAccount2 } from "viem/accounts";
1418
1694
  // src/utils/index.ts
1419
1695
  import { encryptEnvVars } from "@phala/dstack-sdk/encrypt-env-vars";
1420
1696
 
1421
- // src/utils/get_error_message.ts
1422
- function getErrorMessage(error) {
1423
- if (typeof error.detail === "string") {
1424
- return error.detail;
1425
- }
1426
- if (Array.isArray(error.detail)) {
1427
- if (error.detail.length > 0) {
1428
- return error.detail[0]?.msg || "Validation error";
1429
- }
1430
- return "Validation error";
1431
- }
1432
- if (typeof error.detail === "object" && error.detail !== null) {
1433
- return JSON.stringify(error.detail);
1434
- }
1435
- return "Unknown error occurred";
1436
- }
1437
-
1438
1697
  // src/utils/as-hex.ts
1439
1698
  import { isHex } from "viem";
1440
1699
  function asHex(value) {
@@ -2687,7 +2946,9 @@ import { verifyEnvEncryptPublicKey } from "@phala/dstack-sdk/verify-env-encrypt-
2687
2946
  export {
2688
2947
  AddComposeHashSchema,
2689
2948
  ApiErrorSchema,
2949
+ AuthError,
2690
2950
  AvailableNodesSchema,
2951
+ BusinessError,
2691
2952
  CommitCvmComposeFileUpdateRequestSchema,
2692
2953
  CommitCvmComposeFileUpdateSchema,
2693
2954
  CommitCvmProvisionRequestSchema,
@@ -2729,6 +2990,7 @@ export {
2729
2990
  NetworkError,
2730
2991
  PaginatedInstanceTypesSchema,
2731
2992
  PaginationMetadataSchema,
2993
+ PhalaCloudError,
2732
2994
  ProvisionCvmComposeFileUpdateRequestSchema,
2733
2995
  ProvisionCvmComposeFileUpdateResultSchema,
2734
2996
  ProvisionCvmRequestSchema,
@@ -2736,13 +2998,16 @@ export {
2736
2998
  RequestError,
2737
2999
  RestartCvmRequestSchema,
2738
3000
  SUPPORTED_CHAINS,
3001
+ ServerError,
2739
3002
  ShutdownCvmRequestSchema,
2740
3003
  StartCvmRequestSchema,
2741
3004
  StopCvmRequestSchema,
2742
3005
  TransactionError,
3006
+ UnknownError,
2743
3007
  UpdateCvmResourcesRequestSchema,
2744
3008
  UpdateCvmVisibilityRequestSchema,
2745
3009
  VMSchema,
3010
+ ValidationError,
2746
3011
  VmInfoSchema,
2747
3012
  WalletError,
2748
3013
  WorkspaceResponseSchema,
@@ -2764,12 +3029,15 @@ export {
2764
3029
  defineSimpleAction,
2765
3030
  deleteCvm,
2766
3031
  deployAppAuth,
3032
+ dumpAppCompose,
2767
3033
  encryptEnvVars2 as encryptEnvVars,
2768
3034
  estimateTransactionGas,
2769
3035
  executeBatchTransactions,
2770
3036
  executeTransaction,
2771
3037
  executeTransactionWithRetry,
2772
3038
  extractNetworkClients,
3039
+ formatErrorMessage,
3040
+ formatValidationErrors,
2773
3041
  getAppEnvEncryptPubKey,
2774
3042
  getAvailableNodes,
2775
3043
  getComposeHash2 as getComposeHash,
@@ -2785,11 +3053,14 @@ export {
2785
3053
  getErrorMessage,
2786
3054
  getKmsInfo,
2787
3055
  getKmsList,
3056
+ getValidationFields,
2788
3057
  getWorkspace,
2789
3058
  listInstanceTypes,
2790
3059
  listWorkspaces,
3060
+ parseApiError,
2791
3061
  parseEnv,
2792
3062
  parseEnvVars,
3063
+ preprocessAppCompose,
2793
3064
  provisionCvm,
2794
3065
  provisionCvmComposeFileUpdate,
2795
3066
  refineCvmId,
@@ -2825,6 +3096,7 @@ export {
2825
3096
  safeUpdateCvmVisibility,
2826
3097
  safeValidateActionParameters,
2827
3098
  shutdownCvm,
3099
+ sortObject,
2828
3100
  startCvm,
2829
3101
  stopCvm,
2830
3102
  switchToNetwork,
@@ -2833,5 +3105,6 @@ export {
2833
3105
  validateActionParameters,
2834
3106
  validateNetworkPrerequisites,
2835
3107
  verifyEnvEncryptPublicKey,
2836
- waitForTransactionReceipt
3108
+ waitForTransactionReceipt,
3109
+ withComposeMethods
2837
3110
  };