@phala/cloud 0.2.0 → 0.2.1-beta.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/actions/cvms/commit_cvm_provision.d.ts +69 -21
- package/dist/actions/cvms/get_cvm_list.d.ts +16 -16
- package/dist/actions/cvms/get_cvm_state.d.ts +31 -11
- package/dist/actions/cvms/provision_cvm.d.ts +133 -51
- package/dist/actions/index.d.ts +1 -1
- package/dist/actions/kms/get_kms_list.d.ts +4 -4
- package/dist/actions/list-instance-types.d.ts +295 -90
- package/dist/create-client.d.ts +21 -7
- package/dist/index.js +172 -53
- package/dist/index.mjs +162 -49
- package/dist/utils/errors.d.ts +137 -20
- package/dist/utils/index.d.ts +1 -1
- package/package.json +2 -2
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(
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
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
|
-
|
|
820
|
-
|
|
899
|
+
default_disk_size_gb: z5.number().default(20),
|
|
900
|
+
family: z5.string().nullable()
|
|
821
901
|
}).passthrough();
|
|
822
|
-
var
|
|
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
|
-
|
|
826
|
-
page_size: z5.number(),
|
|
827
|
-
pages: z5.number()
|
|
913
|
+
family: z5.string()
|
|
828
914
|
}).strict();
|
|
829
|
-
var
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
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
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
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
|
|
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()
|
|
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(),
|
|
@@ -1678,12 +1780,15 @@ var { action: updateOsImage, safeAction: safeUpdateOsImage } = defineAction(z29.
|
|
|
1678
1780
|
// src/actions/cvms/get_cvm_state.ts
|
|
1679
1781
|
import { z as z30 } from "zod";
|
|
1680
1782
|
var CvmStateSchema = z30.object({
|
|
1681
|
-
|
|
1682
|
-
derived_status: z30.string().optional(),
|
|
1683
|
-
vm_uuid: z30.string().optional(),
|
|
1783
|
+
id: z30.string().optional(),
|
|
1684
1784
|
instance_id: z30.string().optional(),
|
|
1685
|
-
|
|
1686
|
-
|
|
1785
|
+
name: z30.string(),
|
|
1786
|
+
status: z30.string(),
|
|
1787
|
+
uptime: z30.string().optional(),
|
|
1788
|
+
exited_at: z30.string().optional(),
|
|
1789
|
+
boot_progress: z30.string().optional(),
|
|
1790
|
+
boot_error: z30.string().optional(),
|
|
1791
|
+
shutdown_progress: z30.string().optional()
|
|
1687
1792
|
});
|
|
1688
1793
|
var GetCvmStateRequestSchema = CvmIdSchema;
|
|
1689
1794
|
var { action: getCvmState, safeAction: safeGetCvmState } = defineAction(CvmStateSchema, async (client, request) => {
|
|
@@ -1699,8 +1804,10 @@ function createClient2(config = {}) {
|
|
|
1699
1804
|
safeGetCurrentUser,
|
|
1700
1805
|
getAvailableNodes,
|
|
1701
1806
|
safeGetAvailableNodes,
|
|
1702
|
-
|
|
1703
|
-
|
|
1807
|
+
listAllInstanceTypeFamilies,
|
|
1808
|
+
safeListAllInstanceTypeFamilies,
|
|
1809
|
+
listFamilyInstanceTypes,
|
|
1810
|
+
safeListFamilyInstanceTypes,
|
|
1704
1811
|
listWorkspaces,
|
|
1705
1812
|
safeListWorkspaces,
|
|
1706
1813
|
getWorkspace,
|
|
@@ -3220,6 +3327,7 @@ import { getComposeHash as getComposeHash2 } from "@phala/dstack-sdk/get-compose
|
|
|
3220
3327
|
import { verifyEnvEncryptPublicKey } from "@phala/dstack-sdk/verify-env-encrypt-public-key";
|
|
3221
3328
|
export {
|
|
3222
3329
|
AddComposeHashSchema,
|
|
3330
|
+
AllFamiliesResponseSchema,
|
|
3223
3331
|
ApiErrorSchema,
|
|
3224
3332
|
AuthError,
|
|
3225
3333
|
AvailableNodesSchema,
|
|
@@ -3244,6 +3352,8 @@ export {
|
|
|
3244
3352
|
DeleteCvmRequestSchema,
|
|
3245
3353
|
DeployAppAuthRequestSchema,
|
|
3246
3354
|
DeployAppAuthSchema,
|
|
3355
|
+
FamilyGroupSchema,
|
|
3356
|
+
FamilyInstanceTypesResponseSchema,
|
|
3247
3357
|
GetAppEnvEncryptPubKeyRequestSchema,
|
|
3248
3358
|
GetAppEnvEncryptPubKeySchema,
|
|
3249
3359
|
GetAvailableOSImagesRequestSchema,
|
|
@@ -3263,7 +3373,7 @@ export {
|
|
|
3263
3373
|
GetKmsListSchema,
|
|
3264
3374
|
InstanceTypeSchema,
|
|
3265
3375
|
KmsInfoSchema,
|
|
3266
|
-
|
|
3376
|
+
ListFamilyInstanceTypesRequestSchema,
|
|
3267
3377
|
ListWorkspacesSchema,
|
|
3268
3378
|
ManagedUserSchema,
|
|
3269
3379
|
MaxRetriesExceededError,
|
|
@@ -3271,7 +3381,6 @@ export {
|
|
|
3271
3381
|
NextAppIdsRequestSchema,
|
|
3272
3382
|
NextAppIdsSchema,
|
|
3273
3383
|
OSImageVariantSchema,
|
|
3274
|
-
PaginatedInstanceTypesSchema,
|
|
3275
3384
|
PaginationMetadataSchema,
|
|
3276
3385
|
PhalaCloudError,
|
|
3277
3386
|
ProvisionCvmComposeFileUpdateRequestSchema,
|
|
@@ -3279,6 +3388,7 @@ export {
|
|
|
3279
3388
|
ProvisionCvmRequestSchema,
|
|
3280
3389
|
ProvisionCvmSchema,
|
|
3281
3390
|
RequestError,
|
|
3391
|
+
ResourceError,
|
|
3282
3392
|
RestartCvmRequestSchema,
|
|
3283
3393
|
SUPPORTED_CHAINS,
|
|
3284
3394
|
ServerError,
|
|
@@ -3323,6 +3433,7 @@ export {
|
|
|
3323
3433
|
executeTransactionWithRetry,
|
|
3324
3434
|
extractNetworkClients,
|
|
3325
3435
|
formatErrorMessage,
|
|
3436
|
+
formatStructuredError,
|
|
3326
3437
|
formatValidationErrors,
|
|
3327
3438
|
getAppEnvEncryptPubKey,
|
|
3328
3439
|
getAvailableNodes,
|
|
@@ -3343,7 +3454,8 @@ export {
|
|
|
3343
3454
|
getKmsList,
|
|
3344
3455
|
getValidationFields,
|
|
3345
3456
|
getWorkspace,
|
|
3346
|
-
|
|
3457
|
+
listAllInstanceTypeFamilies,
|
|
3458
|
+
listFamilyInstanceTypes,
|
|
3347
3459
|
listWorkspaces,
|
|
3348
3460
|
nextAppIds,
|
|
3349
3461
|
parseApiError,
|
|
@@ -3375,7 +3487,8 @@ export {
|
|
|
3375
3487
|
safeGetKmsInfo,
|
|
3376
3488
|
safeGetKmsList,
|
|
3377
3489
|
safeGetWorkspace,
|
|
3378
|
-
|
|
3490
|
+
safeListAllInstanceTypeFamilies,
|
|
3491
|
+
safeListFamilyInstanceTypes,
|
|
3379
3492
|
safeListWorkspaces,
|
|
3380
3493
|
safeNextAppIds,
|
|
3381
3494
|
safeProvisionCvm,
|
package/dist/utils/errors.d.ts
CHANGED
|
@@ -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
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
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:
|
|
27
|
-
type
|
|
28
|
-
ctx
|
|
29
|
-
|
|
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:
|
|
35
|
-
type
|
|
36
|
-
ctx
|
|
37
|
-
|
|
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
|
|
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;
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -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.
|
|
3
|
+
"version": "0.2.1-beta.2",
|
|
4
4
|
"description": "TypeScript SDK for Phala Cloud API",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"author": "Leechael Yim",
|
|
39
39
|
"license": "Apache-2.0",
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@phala/dstack-sdk": "0.5.
|
|
41
|
+
"@phala/dstack-sdk": "0.5.7",
|
|
42
42
|
"debug": "^4.4.1",
|
|
43
43
|
"mitt": "^3.0.1",
|
|
44
44
|
"ofetch": "^1.3.3",
|