@phala/cloud 0.2.0 → 0.2.1-beta.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.
package/dist/index.mjs CHANGED
@@ -12,8 +12,11 @@ var ApiErrorSchema = z.object({
12
12
  z.object({
13
13
  msg: z.string(),
14
14
  type: z.string().optional(),
15
- ctx: z.record(z.unknown()).optional()
16
- })
15
+ ctx: z.record(z.unknown()).optional(),
16
+ loc: z.array(z.union([z.string(), z.number()])).optional(),
17
+ input: z.unknown().optional()
18
+ }).passthrough()
19
+ // Allow additional fields
17
20
  ),
18
21
  z.record(z.unknown())
19
22
  ]).optional(),
@@ -116,6 +119,9 @@ var UnknownError = class extends PhalaCloudError {
116
119
  }
117
120
  };
118
121
  function extractFieldPath(loc) {
122
+ if (!loc || !Array.isArray(loc)) {
123
+ return "unknown";
124
+ }
119
125
  const filtered = loc.filter((part) => {
120
126
  if (typeof part === "string") {
121
127
  return !["body", "query", "path", "header"].includes(part);
@@ -131,12 +137,21 @@ function parseValidationErrors(detail) {
131
137
  message: typeof detail === "string" ? detail : "Validation error"
132
138
  };
133
139
  }
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 errors = detail.map(
141
+ (item, index) => {
142
+ const field = extractFieldPath(item.loc);
143
+ let displayField = field;
144
+ if (field === "unknown" && item.type) {
145
+ displayField = item.type === "missing" ? "required field" : item.type;
146
+ }
147
+ return {
148
+ field: displayField,
149
+ message: item.msg,
150
+ type: item.type,
151
+ context: item.ctx
152
+ };
153
+ }
154
+ );
140
155
  const count = errors.length;
141
156
  const message = count === 1 ? `Validation failed: ${errors[0].message}` : `Validation failed (${count} issue${count > 1 ? "s" : ""})`;
142
157
  return { errors, message };
@@ -179,13 +194,21 @@ function parseApiError(requestError) {
179
194
  const status = requestError.status ?? 0;
180
195
  const statusText = requestError.statusText ?? "Unknown Error";
181
196
  const detail = requestError.detail;
197
+ const structured = parseStructuredError(detail);
198
+ if (structured) {
199
+ return new ResourceError(structured.message, {
200
+ status,
201
+ statusText,
202
+ detail,
203
+ errorCode: structured.error_code,
204
+ structuredDetails: structured.details,
205
+ suggestions: structured.suggestions,
206
+ links: structured.links
207
+ });
208
+ }
182
209
  const errorType = categorizeErrorType(status);
183
210
  const message = extractPrimaryMessage(status, detail, requestError.message);
184
- const commonData = {
185
- status,
186
- statusText,
187
- detail
188
- };
211
+ const commonData = { status, statusText, detail };
189
212
  if (errorType === "validation" && Array.isArray(detail)) {
190
213
  const { errors } = parseValidationErrors(detail);
191
214
  return new ValidationError(message, {
@@ -247,6 +270,67 @@ function getErrorMessage(error) {
247
270
  }
248
271
  return "Unknown error occurred";
249
272
  }
273
+ var ResourceError = class extends BusinessError {
274
+ constructor(message, data) {
275
+ super(message, data);
276
+ this.isResourceError = true;
277
+ this.errorCode = data.errorCode;
278
+ this.structuredDetails = data.structuredDetails;
279
+ this.suggestions = data.suggestions;
280
+ this.links = data.links;
281
+ }
282
+ };
283
+ function parseStructuredError(detail) {
284
+ if (!detail || typeof detail !== "object") {
285
+ return null;
286
+ }
287
+ const obj = detail;
288
+ if (obj.error_code && typeof obj.error_code === "string" && obj.message && typeof obj.message === "string") {
289
+ return {
290
+ error_code: obj.error_code,
291
+ message: obj.message,
292
+ details: obj.details,
293
+ suggestions: obj.suggestions,
294
+ links: obj.links
295
+ };
296
+ }
297
+ return null;
298
+ }
299
+ function formatStructuredError(error, options) {
300
+ const { showErrorCode = true, showSuggestions = true, showLinks = true } = options ?? {};
301
+ const parts = [];
302
+ if (showErrorCode && error.errorCode) {
303
+ parts.push(`Error [${error.errorCode}]: ${error.message}`);
304
+ } else {
305
+ parts.push(error.message);
306
+ }
307
+ if (error.structuredDetails && error.structuredDetails.length > 0) {
308
+ parts.push("");
309
+ parts.push("Details:");
310
+ error.structuredDetails.forEach((d) => {
311
+ if (d.message) {
312
+ parts.push(` - ${d.message}`);
313
+ } else if (d.field && d.value !== void 0) {
314
+ parts.push(` - ${d.field}: ${d.value}`);
315
+ }
316
+ });
317
+ }
318
+ if (showSuggestions && error.suggestions && error.suggestions.length > 0) {
319
+ parts.push("");
320
+ parts.push("Suggestions:");
321
+ error.suggestions.forEach((s) => {
322
+ parts.push(` - ${s}`);
323
+ });
324
+ }
325
+ if (showLinks && error.links && error.links.length > 0) {
326
+ parts.push("");
327
+ parts.push("Learn more:");
328
+ error.links.forEach((link) => {
329
+ parts.push(` - ${link.label}: ${link.url}`);
330
+ });
331
+ }
332
+ return parts.join("\n");
333
+ }
250
334
 
251
335
  // src/client.ts
252
336
  var SUPPORTED_API_VERSIONS = ["2025-05-31", "2025-10-28"];
@@ -804,10 +888,6 @@ var { action: getAvailableNodes, safeAction: safeGetAvailableNodes } = defineSim
804
888
 
805
889
  // src/actions/list-instance-types.ts
806
890
  import { z as z5 } from "zod";
807
- var ListInstanceTypesRequestSchema = z5.object({
808
- page: z5.number().int().min(1).optional().default(1),
809
- page_size: z5.number().int().min(1).max(1e3).optional().default(100)
810
- }).strict();
811
891
  var InstanceTypeSchema = z5.object({
812
892
  id: z5.string(),
813
893
  name: z5.string(),
@@ -816,22 +896,34 @@ var InstanceTypeSchema = z5.object({
816
896
  memory_mb: z5.number(),
817
897
  hourly_rate: z5.string(),
818
898
  requires_gpu: z5.boolean(),
819
- public: z5.boolean(),
820
- enabled: z5.boolean()
899
+ default_disk_size_gb: z5.number().default(20),
900
+ family: z5.string().nullable()
821
901
  }).passthrough();
822
- var PaginatedInstanceTypesSchema = z5.object({
902
+ var FamilyGroupSchema = z5.object({
903
+ name: z5.string(),
904
+ items: z5.array(InstanceTypeSchema),
905
+ total: z5.number()
906
+ }).strict();
907
+ var AllFamiliesResponseSchema = z5.object({
908
+ result: z5.array(FamilyGroupSchema)
909
+ }).strict();
910
+ var FamilyInstanceTypesResponseSchema = z5.object({
823
911
  items: z5.array(InstanceTypeSchema),
824
912
  total: z5.number(),
825
- page: z5.number(),
826
- page_size: z5.number(),
827
- pages: z5.number()
913
+ family: z5.string()
828
914
  }).strict();
829
- var { action: listInstanceTypes, safeAction: safeListInstanceTypes } = defineAction(PaginatedInstanceTypesSchema, async (client, request) => {
830
- const validatedRequest = ListInstanceTypesRequestSchema.parse(request ?? {});
831
- const queryParams = new URLSearchParams();
832
- queryParams.append("page", validatedRequest.page.toString());
833
- queryParams.append("page_size", validatedRequest.page_size.toString());
834
- return await client.get(`/api/instance-types?${queryParams.toString()}`);
915
+ var ListFamilyInstanceTypesRequestSchema = z5.object({
916
+ family: z5.string()
917
+ }).strict();
918
+ var { action: listAllInstanceTypeFamilies, safeAction: safeListAllInstanceTypeFamilies } = defineAction(
919
+ AllFamiliesResponseSchema,
920
+ async (client) => {
921
+ return await client.get("/instance-types");
922
+ }
923
+ );
924
+ var { action: listFamilyInstanceTypes, safeAction: safeListFamilyInstanceTypes } = defineAction(FamilyInstanceTypesResponseSchema, async (client, request) => {
925
+ const validated = ListFamilyInstanceTypesRequestSchema.parse(request);
926
+ return await client.get(`/instance-types/${validated.family}`);
835
927
  });
836
928
 
837
929
  // src/actions/workspaces/list_workspaces.ts
@@ -1051,6 +1143,7 @@ var ProvisionCvmSchema = z10.object({
1051
1143
  fmspc: z10.string().nullable().optional(),
1052
1144
  device_id: z10.string().nullable().optional(),
1053
1145
  os_image_hash: z10.string().nullable().optional(),
1146
+ instance_type: z10.string().nullable().optional(),
1054
1147
  teepod_id: z10.number().nullable().optional(),
1055
1148
  // Will be transformed to node_id
1056
1149
  node_id: z10.number().nullable().optional(),
@@ -1064,19 +1157,24 @@ var ProvisionCvmSchema = z10.object({
1064
1157
  });
1065
1158
  var ProvisionCvmRequestSchema = z10.object({
1066
1159
  node_id: z10.number().optional(),
1067
- // recommended
1160
+ // recommended - optional, system auto-selects if not specified
1068
1161
  teepod_id: z10.number().optional(),
1069
1162
  // deprecated, for compatibility
1163
+ region: z10.string().optional(),
1164
+ // optional - region filter for auto-selection
1070
1165
  name: z10.string(),
1071
- image: z10.string(),
1072
- vcpu: z10.number(),
1073
- memory: z10.number(),
1074
- disk_size: z10.number(),
1166
+ instance_type: z10.string().default("tdx.small"),
1167
+ // defaults to "tdx.small"
1168
+ image: z10.string().optional(),
1169
+ vcpu: z10.number().optional(),
1170
+ memory: z10.number().optional(),
1171
+ disk_size: z10.number().optional(),
1075
1172
  compose_file: z10.object({
1076
1173
  allowed_envs: z10.array(z10.string()).optional(),
1077
1174
  pre_launch_script: z10.string().optional(),
1078
1175
  docker_compose_file: z10.string().optional(),
1079
- name: z10.string().optional(),
1176
+ name: z10.string().optional().default(""),
1177
+ // optional with default empty string
1080
1178
  kms_enabled: z10.boolean().optional(),
1081
1179
  public_logs: z10.boolean().optional(),
1082
1180
  public_sysinfo: z10.boolean().optional(),
@@ -1086,8 +1184,11 @@ var ProvisionCvmRequestSchema = z10.object({
1086
1184
  // deprecated, for compatibility
1087
1185
  }),
1088
1186
  listed: z10.boolean().optional(),
1089
- instance_type: z10.string().nullable().optional(),
1090
1187
  kms_id: z10.string().optional(),
1188
+ kms: z10.enum(["PHALA", "ETHEREUM", "BASE"]).optional(),
1189
+ // KMS type selection (defaults to PHALA)
1190
+ kms_contract: z10.string().optional(),
1191
+ // KMS contract address for on-chain KMS
1091
1192
  env_keys: z10.array(z10.string()).optional()
1092
1193
  }).passthrough();
1093
1194
  function handleGatewayCompatibility(appCompose) {
@@ -1112,7 +1213,8 @@ function handleGatewayCompatibility(appCompose) {
1112
1213
  };
1113
1214
  }
1114
1215
  var { action: provisionCvm, safeAction: safeProvisionCvm } = defineAction(ProvisionCvmSchema, async (client, appCompose) => {
1115
- const body = handleGatewayCompatibility(appCompose);
1216
+ const validated = ProvisionCvmRequestSchema.parse(appCompose);
1217
+ const body = handleGatewayCompatibility(validated);
1116
1218
  let requestBody = { ...body };
1117
1219
  if (typeof body.node_id === "number") {
1118
1220
  requestBody = { ...body, teepod_id: body.node_id };
@@ -1156,7 +1258,7 @@ var CommitCvmProvisionSchema = z11.object({
1156
1258
  var CommitCvmProvisionRequestSchema = z11.object({
1157
1259
  encrypted_env: z11.string().optional().nullable(),
1158
1260
  app_id: z11.string(),
1159
- compose_hash: z11.string().optional(),
1261
+ compose_hash: z11.string(),
1160
1262
  kms_id: z11.string().optional(),
1161
1263
  contract_address: z11.string().optional(),
1162
1264
  deployer_address: z11.string().optional(),
@@ -1699,8 +1801,10 @@ function createClient2(config = {}) {
1699
1801
  safeGetCurrentUser,
1700
1802
  getAvailableNodes,
1701
1803
  safeGetAvailableNodes,
1702
- listInstanceTypes,
1703
- safeListInstanceTypes,
1804
+ listAllInstanceTypeFamilies,
1805
+ safeListAllInstanceTypeFamilies,
1806
+ listFamilyInstanceTypes,
1807
+ safeListFamilyInstanceTypes,
1704
1808
  listWorkspaces,
1705
1809
  safeListWorkspaces,
1706
1810
  getWorkspace,
@@ -3220,6 +3324,7 @@ import { getComposeHash as getComposeHash2 } from "@phala/dstack-sdk/get-compose
3220
3324
  import { verifyEnvEncryptPublicKey } from "@phala/dstack-sdk/verify-env-encrypt-public-key";
3221
3325
  export {
3222
3326
  AddComposeHashSchema,
3327
+ AllFamiliesResponseSchema,
3223
3328
  ApiErrorSchema,
3224
3329
  AuthError,
3225
3330
  AvailableNodesSchema,
@@ -3244,6 +3349,8 @@ export {
3244
3349
  DeleteCvmRequestSchema,
3245
3350
  DeployAppAuthRequestSchema,
3246
3351
  DeployAppAuthSchema,
3352
+ FamilyGroupSchema,
3353
+ FamilyInstanceTypesResponseSchema,
3247
3354
  GetAppEnvEncryptPubKeyRequestSchema,
3248
3355
  GetAppEnvEncryptPubKeySchema,
3249
3356
  GetAvailableOSImagesRequestSchema,
@@ -3263,7 +3370,7 @@ export {
3263
3370
  GetKmsListSchema,
3264
3371
  InstanceTypeSchema,
3265
3372
  KmsInfoSchema,
3266
- ListInstanceTypesRequestSchema,
3373
+ ListFamilyInstanceTypesRequestSchema,
3267
3374
  ListWorkspacesSchema,
3268
3375
  ManagedUserSchema,
3269
3376
  MaxRetriesExceededError,
@@ -3271,7 +3378,6 @@ export {
3271
3378
  NextAppIdsRequestSchema,
3272
3379
  NextAppIdsSchema,
3273
3380
  OSImageVariantSchema,
3274
- PaginatedInstanceTypesSchema,
3275
3381
  PaginationMetadataSchema,
3276
3382
  PhalaCloudError,
3277
3383
  ProvisionCvmComposeFileUpdateRequestSchema,
@@ -3279,6 +3385,7 @@ export {
3279
3385
  ProvisionCvmRequestSchema,
3280
3386
  ProvisionCvmSchema,
3281
3387
  RequestError,
3388
+ ResourceError,
3282
3389
  RestartCvmRequestSchema,
3283
3390
  SUPPORTED_CHAINS,
3284
3391
  ServerError,
@@ -3323,6 +3430,7 @@ export {
3323
3430
  executeTransactionWithRetry,
3324
3431
  extractNetworkClients,
3325
3432
  formatErrorMessage,
3433
+ formatStructuredError,
3326
3434
  formatValidationErrors,
3327
3435
  getAppEnvEncryptPubKey,
3328
3436
  getAvailableNodes,
@@ -3343,7 +3451,8 @@ export {
3343
3451
  getKmsList,
3344
3452
  getValidationFields,
3345
3453
  getWorkspace,
3346
- listInstanceTypes,
3454
+ listAllInstanceTypeFamilies,
3455
+ listFamilyInstanceTypes,
3347
3456
  listWorkspaces,
3348
3457
  nextAppIds,
3349
3458
  parseApiError,
@@ -3375,7 +3484,8 @@ export {
3375
3484
  safeGetKmsInfo,
3376
3485
  safeGetKmsList,
3377
3486
  safeGetWorkspace,
3378
- safeListInstanceTypes,
3487
+ safeListAllInstanceTypeFamilies,
3488
+ safeListFamilyInstanceTypes,
3379
3489
  safeListWorkspaces,
3380
3490
  safeNextAppIds,
3381
3491
  safeProvisionCvm,
@@ -8,33 +8,43 @@ export declare const ApiErrorSchema: z.ZodObject<{
8
8
  msg: z.ZodString;
9
9
  type: z.ZodOptional<z.ZodString>;
10
10
  ctx: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
11
- }, "strip", z.ZodTypeAny, {
12
- msg: string;
13
- type?: string | undefined;
14
- ctx?: Record<string, unknown> | undefined;
15
- }, {
16
- msg: string;
17
- type?: string | undefined;
18
- ctx?: Record<string, unknown> | undefined;
19
- }>, "many">, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
11
+ loc: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodNumber]>, "many">>;
12
+ input: z.ZodOptional<z.ZodUnknown>;
13
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
14
+ msg: z.ZodString;
15
+ type: z.ZodOptional<z.ZodString>;
16
+ ctx: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
17
+ loc: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodNumber]>, "many">>;
18
+ input: z.ZodOptional<z.ZodUnknown>;
19
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
20
+ msg: z.ZodString;
21
+ type: z.ZodOptional<z.ZodString>;
22
+ ctx: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
23
+ loc: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodNumber]>, "many">>;
24
+ input: z.ZodOptional<z.ZodUnknown>;
25
+ }, z.ZodTypeAny, "passthrough">>, "many">, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
20
26
  type: z.ZodOptional<z.ZodString>;
21
27
  code: z.ZodOptional<z.ZodString>;
22
28
  }, "strip", z.ZodTypeAny, {
23
29
  code?: string | undefined;
24
30
  type?: string | undefined;
25
- detail?: string | Record<string, unknown> | {
26
- msg: string;
27
- type?: string | undefined;
28
- ctx?: Record<string, unknown> | undefined;
29
- }[] | undefined;
31
+ detail?: string | Record<string, unknown> | z.objectOutputType<{
32
+ msg: z.ZodString;
33
+ type: z.ZodOptional<z.ZodString>;
34
+ ctx: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
35
+ loc: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodNumber]>, "many">>;
36
+ input: z.ZodOptional<z.ZodUnknown>;
37
+ }, z.ZodTypeAny, "passthrough">[] | undefined;
30
38
  }, {
31
39
  code?: string | undefined;
32
40
  type?: string | undefined;
33
- detail?: string | Record<string, unknown> | {
34
- msg: string;
35
- type?: string | undefined;
36
- ctx?: Record<string, unknown> | undefined;
37
- }[] | undefined;
41
+ detail?: string | Record<string, unknown> | z.objectInputType<{
42
+ msg: z.ZodString;
43
+ type: z.ZodOptional<z.ZodString>;
44
+ ctx: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
45
+ loc: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodNumber]>, "many">>;
46
+ input: z.ZodOptional<z.ZodUnknown>;
47
+ }, z.ZodTypeAny, "passthrough">[] | undefined;
38
48
  }>;
39
49
  export type ApiError = z.infer<typeof ApiErrorSchema>;
40
50
  /**
@@ -94,6 +104,9 @@ export declare class RequestError extends PhalaCloudError implements ApiError {
94
104
  msg: string;
95
105
  type?: string;
96
106
  ctx?: Record<string, unknown>;
107
+ loc?: (string | number)[];
108
+ input?: unknown;
109
+ [key: string]: unknown;
97
110
  }>;
98
111
  code?: string | undefined;
99
112
  type?: string | undefined;
@@ -122,6 +135,9 @@ export declare class ValidationError extends PhalaCloudError {
122
135
  msg: string;
123
136
  type?: string;
124
137
  ctx?: Record<string, unknown>;
138
+ loc?: (string | number)[];
139
+ input?: unknown;
140
+ [key: string]: unknown;
125
141
  }>;
126
142
  validationErrors: ValidationErrorItem[];
127
143
  });
@@ -162,6 +178,7 @@ export declare class UnknownError extends PhalaCloudError {
162
178
  * Parse RequestError into PhalaCloudError instance
163
179
  *
164
180
  * Returns the appropriate error subclass based on status code:
181
+ * - New structured errors (with error_code) → ResourceError
165
182
  * - 422 → ValidationError (with validationErrors array)
166
183
  * - 401, 403 → AuthError
167
184
  * - 400, 409, etc. → BusinessError
@@ -176,7 +193,13 @@ export declare class UnknownError extends PhalaCloudError {
176
193
  * try {
177
194
  * await client.post('/cvms', data);
178
195
  * } catch (error) {
179
- * if (error instanceof ValidationError) {
196
+ * if (error instanceof ResourceError) {
197
+ * // New structured error with error code
198
+ * console.error(`Error [${error.errorCode}]: ${error.message}`);
199
+ * if (error.suggestions) {
200
+ * error.suggestions.forEach(s => console.log(s));
201
+ * }
202
+ * } else if (error instanceof ValidationError) {
180
203
  * // TypeScript knows error.validationErrors exists
181
204
  * error.validationErrors.forEach(e => {
182
205
  * console.error(`${e.field}: ${e.message}`);
@@ -259,3 +282,97 @@ export declare function formatErrorMessage(error: PhalaCloudError, options?: {
259
282
  * @returns Error message string
260
283
  */
261
284
  export declare function getErrorMessage(error: ApiError): string;
285
+ /**
286
+ * Structured error detail from new error format (ERR-xxxx codes)
287
+ */
288
+ export interface StructuredErrorDetail {
289
+ field?: string;
290
+ value?: unknown;
291
+ message?: string;
292
+ }
293
+ /**
294
+ * Error link from structured error response
295
+ */
296
+ export interface ErrorLink {
297
+ url: string;
298
+ label: string;
299
+ }
300
+ /**
301
+ * New structured error response format with unique error codes
302
+ */
303
+ export interface StructuredErrorResponse {
304
+ error_code: string;
305
+ message: string;
306
+ details?: StructuredErrorDetail[];
307
+ suggestions?: string[];
308
+ links?: ErrorLink[];
309
+ }
310
+ /**
311
+ * Resource provisioning error with structured details
312
+ * Extends BusinessError to handle new error format from backend
313
+ *
314
+ * Use instanceof to check: if (error instanceof ResourceError) { ... }
315
+ * Or use property: if (error.isResourceError) { ... }
316
+ */
317
+ export declare class ResourceError extends BusinessError {
318
+ readonly isResourceError: true;
319
+ readonly errorCode?: string;
320
+ readonly structuredDetails?: StructuredErrorDetail[];
321
+ readonly suggestions?: string[];
322
+ readonly links?: ErrorLink[];
323
+ constructor(message: string, data: {
324
+ status: number;
325
+ statusText: string;
326
+ detail?: string | Record<string, unknown> | Array<{
327
+ msg: string;
328
+ type?: string;
329
+ ctx?: Record<string, unknown>;
330
+ loc?: (string | number)[];
331
+ input?: unknown;
332
+ [key: string]: unknown;
333
+ }>;
334
+ errorCode?: string;
335
+ structuredDetails?: StructuredErrorDetail[];
336
+ suggestions?: string[];
337
+ links?: ErrorLink[];
338
+ });
339
+ }
340
+ /**
341
+ * Format structured error for display
342
+ *
343
+ * @param error - Resource error with structured details
344
+ * @param options - Formatting options
345
+ * @returns Formatted error message
346
+ *
347
+ * @example
348
+ * ```typescript
349
+ * try {
350
+ * await client.provisionCvm(payload);
351
+ * } catch (error) {
352
+ * if (error instanceof ResourceError) {
353
+ * console.error(formatStructuredError(error));
354
+ * }
355
+ * }
356
+ * // Output:
357
+ * // Error [ERR-01-001]: The requested instance type does not exist
358
+ * //
359
+ * // Details:
360
+ * // - Instance type 'invalid' is not recognized
361
+ * //
362
+ * // Suggestions:
363
+ * // - Use a valid instance type: tdx.small, tdx.medium, or tdx.large
364
+ * // - Alternatively, specify CPU and memory requirements manually
365
+ * //
366
+ * // Learn more:
367
+ * // - View available instance types: https://cloud.phala.network/instances
368
+ * // - Contact support: https://cloud.phala.network/support
369
+ * ```
370
+ */
371
+ export declare function formatStructuredError(error: ResourceError, options?: {
372
+ /** Show error code in output (default: true) */
373
+ showErrorCode?: boolean;
374
+ /** Show suggestions (default: true) */
375
+ showSuggestions?: boolean;
376
+ /** Show links (default: true) */
377
+ showLinks?: boolean;
378
+ }): string;
@@ -2,7 +2,7 @@ export { encryptEnvVars } from "@phala/dstack-sdk/encrypt-env-vars";
2
2
  export { getComposeHash, dumpAppCompose, preprocessAppCompose, sortObject, withComposeMethods, type AppCompose, type AppComposeWithMethods, type SortableValue, type SortableObject, type SortableArray, } from "./get_compose_hash";
3
3
  export { asHex } from "./as-hex";
4
4
  export { validateActionParameters, safeValidateActionParameters } from "./validate-parameters";
5
- export { parseApiError, PhalaCloudError, RequestError, ValidationError, AuthError, BusinessError, ServerError, UnknownError, formatValidationErrors, formatErrorMessage, getErrorMessage, getValidationFields, type ValidationErrorItem, ApiErrorSchema, type ApiError, } from "./errors";
5
+ export { parseApiError, PhalaCloudError, RequestError, ValidationError, AuthError, BusinessError, ServerError, UnknownError, ResourceError, formatValidationErrors, formatErrorMessage, formatStructuredError, getErrorMessage, getValidationFields, type ValidationErrorItem, type StructuredErrorDetail, type ErrorLink, type StructuredErrorResponse, ApiErrorSchema, type ApiError, } from "./errors";
6
6
  export { createNetworkClients, extractNetworkClients, checkNetworkStatus, checkBalance, validateNetworkPrerequisites, waitForTransactionReceipt, executeTransaction, NetworkError, WalletError, TransactionError, type NetworkConfig, type WalletConnection, type NetworkClients, type BalanceCheckResult, type TransactionOptions, type TransactionResult, } from "./network";
7
7
  export { createTransactionTracker, executeBatchTransactions, executeTransactionWithRetry, estimateTransactionGas, type TransactionState, type TransactionStatus, type TransactionTracker, type BatchTransactionOptions, type BatchTransactionResult, type RetryOptions, type GasEstimationOptions, } from "./transaction";
8
8
  export { createClientsFromPrivateKey, createClientsFromBrowser, autoCreateClients, switchToNetwork, addNetwork, } from "./client-factories";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@phala/cloud",
3
- "version": "0.2.0",
3
+ "version": "0.2.1-beta.1",
4
4
  "description": "TypeScript SDK for Phala Cloud API",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",