instavm 0.8.1 → 0.11.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/README.md +201 -769
- package/dist/index.d.mts +351 -4
- package/dist/index.d.ts +351 -4
- package/dist/index.js +852 -14
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +843 -13
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -139,7 +139,7 @@ var HTTPClient = class {
|
|
|
139
139
|
timeout: config.timeout,
|
|
140
140
|
headers: {
|
|
141
141
|
"Content-Type": "application/json",
|
|
142
|
-
"User-Agent": "instavm-js-sdk/0.
|
|
142
|
+
"User-Agent": "instavm-js-sdk/0.11.0"
|
|
143
143
|
}
|
|
144
144
|
});
|
|
145
145
|
this.setupInterceptors();
|
|
@@ -160,7 +160,7 @@ var HTTPClient = class {
|
|
|
160
160
|
const axiosError = error;
|
|
161
161
|
const status = axiosError.response?.status;
|
|
162
162
|
const data = axiosError.response?.data;
|
|
163
|
-
const message = data?.message || data?.error || axiosError.message;
|
|
163
|
+
const message = data?.message || data?.error || data?.detail || axiosError.message;
|
|
164
164
|
switch (status) {
|
|
165
165
|
case 401:
|
|
166
166
|
throw new AuthenticationError(message, {
|
|
@@ -172,14 +172,16 @@ var HTTPClient = class {
|
|
|
172
172
|
statusCode: status,
|
|
173
173
|
response: data
|
|
174
174
|
});
|
|
175
|
-
case 429:
|
|
175
|
+
case 429: {
|
|
176
176
|
const retryAfter = parseInt(
|
|
177
177
|
axiosError.response?.headers["retry-after"] || "60"
|
|
178
178
|
);
|
|
179
|
-
|
|
179
|
+
const rateLimitMessage = data?.detail || message;
|
|
180
|
+
throw new RateLimitError(rateLimitMessage, retryAfter, {
|
|
180
181
|
statusCode: status,
|
|
181
182
|
response: data
|
|
182
183
|
});
|
|
184
|
+
}
|
|
183
185
|
case 500:
|
|
184
186
|
case 502:
|
|
185
187
|
case 503:
|
|
@@ -257,6 +259,7 @@ var HTTPClient = class {
|
|
|
257
259
|
*/
|
|
258
260
|
async postFormData(url, formData, headers) {
|
|
259
261
|
const requestHeaders = {
|
|
262
|
+
"X-API-Key": this.config.apiKey,
|
|
260
263
|
...formData.getHeaders(),
|
|
261
264
|
...headers
|
|
262
265
|
};
|
|
@@ -308,6 +311,39 @@ var HTTPClient = class {
|
|
|
308
311
|
headers
|
|
309
312
|
});
|
|
310
313
|
}
|
|
314
|
+
/**
|
|
315
|
+
* PUT request
|
|
316
|
+
*/
|
|
317
|
+
async put(url, data, headers) {
|
|
318
|
+
return this.request({
|
|
319
|
+
method: "PUT",
|
|
320
|
+
url,
|
|
321
|
+
data,
|
|
322
|
+
headers
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* PATCH request
|
|
327
|
+
*/
|
|
328
|
+
async patch(url, data, headers) {
|
|
329
|
+
return this.request({
|
|
330
|
+
method: "PATCH",
|
|
331
|
+
url,
|
|
332
|
+
data,
|
|
333
|
+
headers
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* OPTIONS request
|
|
338
|
+
*/
|
|
339
|
+
async options(url, headers, params) {
|
|
340
|
+
return this.request({
|
|
341
|
+
method: "OPTIONS",
|
|
342
|
+
url,
|
|
343
|
+
headers,
|
|
344
|
+
params
|
|
345
|
+
});
|
|
346
|
+
}
|
|
311
347
|
/**
|
|
312
348
|
* POST request that returns raw binary data (for file downloads)
|
|
313
349
|
*/
|
|
@@ -874,13 +910,525 @@ var BrowserManager = class {
|
|
|
874
910
|
}
|
|
875
911
|
};
|
|
876
912
|
|
|
913
|
+
// src/utils/path.ts
|
|
914
|
+
function encodePathSegment(value) {
|
|
915
|
+
return encodeURIComponent(String(value));
|
|
916
|
+
}
|
|
917
|
+
function encodePathSegments(path) {
|
|
918
|
+
const segments = path.replace(/^\/+/, "").split("/").filter((segment) => segment.length > 0 && segment !== ".");
|
|
919
|
+
if (segments.some((segment) => segment === "..")) {
|
|
920
|
+
throw new Error("Path traversal not allowed in proxy path");
|
|
921
|
+
}
|
|
922
|
+
return segments.map((segment) => encodeURIComponent(segment)).join("/");
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
// src/client/VMsManager.ts
|
|
926
|
+
var VMsManager = class {
|
|
927
|
+
constructor(httpClient, local = false) {
|
|
928
|
+
this.httpClient = httpClient;
|
|
929
|
+
this.local = local;
|
|
930
|
+
}
|
|
931
|
+
ensureCloud(operation) {
|
|
932
|
+
if (this.local) {
|
|
933
|
+
throw new UnsupportedOperationError(
|
|
934
|
+
`${operation} is not supported in local mode.`
|
|
935
|
+
);
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
async create(payload = {}, wait = true) {
|
|
939
|
+
this.ensureCloud("VM creation");
|
|
940
|
+
return this.httpClient.request({
|
|
941
|
+
method: "POST",
|
|
942
|
+
url: "/v1/vms",
|
|
943
|
+
params: { wait },
|
|
944
|
+
data: payload,
|
|
945
|
+
headers: { "X-API-Key": this.httpClient.apiKey }
|
|
946
|
+
});
|
|
947
|
+
}
|
|
948
|
+
async list() {
|
|
949
|
+
this.ensureCloud("VM listing");
|
|
950
|
+
return this.httpClient.get(
|
|
951
|
+
"/v1/vms",
|
|
952
|
+
void 0,
|
|
953
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
954
|
+
);
|
|
955
|
+
}
|
|
956
|
+
async listAll() {
|
|
957
|
+
return this.listAllRecords();
|
|
958
|
+
}
|
|
959
|
+
/**
|
|
960
|
+
* Calls GET /v1/vms/ (trailing slash), a distinct route from GET /v1/vms.
|
|
961
|
+
*/
|
|
962
|
+
async listAllRecords() {
|
|
963
|
+
this.ensureCloud("VM listing");
|
|
964
|
+
return this.httpClient.get(
|
|
965
|
+
"/v1/vms/",
|
|
966
|
+
void 0,
|
|
967
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
968
|
+
);
|
|
969
|
+
}
|
|
970
|
+
async get(itemId) {
|
|
971
|
+
this.ensureCloud("VM lookup");
|
|
972
|
+
const safeItemId = encodePathSegment(itemId);
|
|
973
|
+
return this.httpClient.get(
|
|
974
|
+
`/v1/vms/${safeItemId}`,
|
|
975
|
+
void 0,
|
|
976
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
977
|
+
);
|
|
978
|
+
}
|
|
979
|
+
async update(vmId, payload = {}) {
|
|
980
|
+
this.ensureCloud("VM update");
|
|
981
|
+
const safeVmId = encodePathSegment(vmId);
|
|
982
|
+
return this.httpClient.patch(
|
|
983
|
+
`/v1/vms/${safeVmId}`,
|
|
984
|
+
payload,
|
|
985
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
986
|
+
);
|
|
987
|
+
}
|
|
988
|
+
async delete(vmId) {
|
|
989
|
+
this.ensureCloud("VM deletion");
|
|
990
|
+
const safeVmId = encodePathSegment(vmId);
|
|
991
|
+
return this.httpClient.delete(
|
|
992
|
+
`/v1/vms/${safeVmId}`,
|
|
993
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
994
|
+
);
|
|
995
|
+
}
|
|
996
|
+
async clone(vmId, payload = {}, wait = true) {
|
|
997
|
+
this.ensureCloud("VM clone");
|
|
998
|
+
const safeVmId = encodePathSegment(vmId);
|
|
999
|
+
return this.httpClient.request({
|
|
1000
|
+
method: "POST",
|
|
1001
|
+
url: `/v1/vms/${safeVmId}/clone`,
|
|
1002
|
+
params: { wait },
|
|
1003
|
+
data: payload,
|
|
1004
|
+
headers: { "X-API-Key": this.httpClient.apiKey }
|
|
1005
|
+
});
|
|
1006
|
+
}
|
|
1007
|
+
async snapshot(vmId, payload = {}, wait = true) {
|
|
1008
|
+
this.ensureCloud("VM snapshot");
|
|
1009
|
+
const safeVmId = encodePathSegment(vmId);
|
|
1010
|
+
return this.httpClient.request({
|
|
1011
|
+
method: "POST",
|
|
1012
|
+
url: `/v1/vms/${safeVmId}/snapshot`,
|
|
1013
|
+
params: { wait },
|
|
1014
|
+
data: payload,
|
|
1015
|
+
headers: { "X-API-Key": this.httpClient.apiKey }
|
|
1016
|
+
});
|
|
1017
|
+
}
|
|
1018
|
+
};
|
|
1019
|
+
|
|
1020
|
+
// src/client/SnapshotsManager.ts
|
|
1021
|
+
var SnapshotsManager = class {
|
|
1022
|
+
constructor(httpClient, local = false) {
|
|
1023
|
+
this.httpClient = httpClient;
|
|
1024
|
+
this.local = local;
|
|
1025
|
+
}
|
|
1026
|
+
ensureCloud(operation) {
|
|
1027
|
+
if (this.local) {
|
|
1028
|
+
throw new UnsupportedOperationError(
|
|
1029
|
+
`${operation} is not supported in local mode.`
|
|
1030
|
+
);
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
async create(payload) {
|
|
1034
|
+
this.ensureCloud("Snapshot creation");
|
|
1035
|
+
return this.httpClient.post(
|
|
1036
|
+
"/v1/snapshots",
|
|
1037
|
+
payload,
|
|
1038
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1039
|
+
);
|
|
1040
|
+
}
|
|
1041
|
+
async list(options = {}) {
|
|
1042
|
+
this.ensureCloud("Snapshot listing");
|
|
1043
|
+
return this.httpClient.get(
|
|
1044
|
+
"/v1/snapshots",
|
|
1045
|
+
options,
|
|
1046
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1047
|
+
);
|
|
1048
|
+
}
|
|
1049
|
+
async get(snapshotId) {
|
|
1050
|
+
this.ensureCloud("Snapshot lookup");
|
|
1051
|
+
const safeSnapshotId = encodePathSegment(snapshotId);
|
|
1052
|
+
return this.httpClient.get(
|
|
1053
|
+
`/v1/snapshots/${safeSnapshotId}`,
|
|
1054
|
+
void 0,
|
|
1055
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1056
|
+
);
|
|
1057
|
+
}
|
|
1058
|
+
async delete(snapshotId) {
|
|
1059
|
+
this.ensureCloud("Snapshot deletion");
|
|
1060
|
+
const safeSnapshotId = encodePathSegment(snapshotId);
|
|
1061
|
+
return this.httpClient.delete(
|
|
1062
|
+
`/v1/snapshots/${safeSnapshotId}`,
|
|
1063
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1064
|
+
);
|
|
1065
|
+
}
|
|
1066
|
+
};
|
|
1067
|
+
|
|
1068
|
+
// src/client/SharesManager.ts
|
|
1069
|
+
var SharesManager = class {
|
|
1070
|
+
constructor(httpClient, local = false, getSessionId = () => null) {
|
|
1071
|
+
this.httpClient = httpClient;
|
|
1072
|
+
this.local = local;
|
|
1073
|
+
this.getSessionId = getSessionId;
|
|
1074
|
+
}
|
|
1075
|
+
ensureCloud(operation) {
|
|
1076
|
+
if (this.local) {
|
|
1077
|
+
throw new UnsupportedOperationError(
|
|
1078
|
+
`${operation} is not supported in local mode.`
|
|
1079
|
+
);
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
async create(payload) {
|
|
1083
|
+
this.ensureCloud("Share creation");
|
|
1084
|
+
const body = { ...payload };
|
|
1085
|
+
if (!body.session_id && !body.vm_id) {
|
|
1086
|
+
const sid = this.getSessionId();
|
|
1087
|
+
if (!sid) {
|
|
1088
|
+
throw new SessionError(
|
|
1089
|
+
"Provide session_id/vm_id or create a session before creating a share."
|
|
1090
|
+
);
|
|
1091
|
+
}
|
|
1092
|
+
body.session_id = sid;
|
|
1093
|
+
}
|
|
1094
|
+
return this.httpClient.post(
|
|
1095
|
+
"/v1/shares",
|
|
1096
|
+
body,
|
|
1097
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1098
|
+
);
|
|
1099
|
+
}
|
|
1100
|
+
async update(shareId, payload) {
|
|
1101
|
+
this.ensureCloud("Share update");
|
|
1102
|
+
const safeShareId = encodePathSegment(shareId);
|
|
1103
|
+
return this.httpClient.patch(
|
|
1104
|
+
`/v1/shares/${safeShareId}`,
|
|
1105
|
+
payload,
|
|
1106
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1107
|
+
);
|
|
1108
|
+
}
|
|
1109
|
+
};
|
|
1110
|
+
|
|
1111
|
+
// src/client/CustomDomainsManager.ts
|
|
1112
|
+
var CustomDomainsManager = class {
|
|
1113
|
+
constructor(httpClient, local = false) {
|
|
1114
|
+
this.httpClient = httpClient;
|
|
1115
|
+
this.local = local;
|
|
1116
|
+
}
|
|
1117
|
+
ensureCloud(operation) {
|
|
1118
|
+
if (this.local) {
|
|
1119
|
+
throw new UnsupportedOperationError(
|
|
1120
|
+
`${operation} is not supported in local mode.`
|
|
1121
|
+
);
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
async create(payload) {
|
|
1125
|
+
this.ensureCloud("Custom domain creation");
|
|
1126
|
+
return this.httpClient.post(
|
|
1127
|
+
"/v1/custom-domains",
|
|
1128
|
+
payload,
|
|
1129
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1130
|
+
);
|
|
1131
|
+
}
|
|
1132
|
+
async list() {
|
|
1133
|
+
this.ensureCloud("Custom domain listing");
|
|
1134
|
+
return this.httpClient.get(
|
|
1135
|
+
"/v1/custom-domains",
|
|
1136
|
+
void 0,
|
|
1137
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1138
|
+
);
|
|
1139
|
+
}
|
|
1140
|
+
async health(domainId) {
|
|
1141
|
+
this.ensureCloud("Custom domain health");
|
|
1142
|
+
const safeDomainId = encodePathSegment(domainId);
|
|
1143
|
+
return this.httpClient.get(
|
|
1144
|
+
`/v1/custom-domains/${safeDomainId}/health`,
|
|
1145
|
+
void 0,
|
|
1146
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1147
|
+
);
|
|
1148
|
+
}
|
|
1149
|
+
async verify(domainId) {
|
|
1150
|
+
this.ensureCloud("Custom domain verification");
|
|
1151
|
+
const safeDomainId = encodePathSegment(domainId);
|
|
1152
|
+
return this.httpClient.post(
|
|
1153
|
+
`/v1/custom-domains/${safeDomainId}/verify`,
|
|
1154
|
+
{},
|
|
1155
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1156
|
+
);
|
|
1157
|
+
}
|
|
1158
|
+
async delete(domainId) {
|
|
1159
|
+
this.ensureCloud("Custom domain deletion");
|
|
1160
|
+
const safeDomainId = encodePathSegment(domainId);
|
|
1161
|
+
return this.httpClient.delete(
|
|
1162
|
+
`/v1/custom-domains/${safeDomainId}`,
|
|
1163
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1164
|
+
);
|
|
1165
|
+
}
|
|
1166
|
+
};
|
|
1167
|
+
|
|
1168
|
+
// src/client/ComputerUseManager.ts
|
|
1169
|
+
var ComputerUseManager = class {
|
|
1170
|
+
constructor(httpClient, local = false) {
|
|
1171
|
+
this.httpClient = httpClient;
|
|
1172
|
+
this.local = local;
|
|
1173
|
+
}
|
|
1174
|
+
ensureCloud(operation) {
|
|
1175
|
+
if (this.local) {
|
|
1176
|
+
throw new UnsupportedOperationError(
|
|
1177
|
+
`${operation} is not supported in local mode.`
|
|
1178
|
+
);
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
async viewerUrl(sessionId) {
|
|
1182
|
+
this.ensureCloud("Computer-use viewer URL");
|
|
1183
|
+
const safeSessionId = encodePathSegment(sessionId);
|
|
1184
|
+
return this.httpClient.get(
|
|
1185
|
+
`/v1/computeruse/${safeSessionId}/viewer-url`,
|
|
1186
|
+
void 0,
|
|
1187
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1188
|
+
);
|
|
1189
|
+
}
|
|
1190
|
+
async proxy(sessionId, path, method = "GET", options = {}) {
|
|
1191
|
+
this.ensureCloud("Computer-use proxy");
|
|
1192
|
+
const safeSessionId = encodePathSegment(sessionId);
|
|
1193
|
+
const cleanPath = encodePathSegments(path);
|
|
1194
|
+
return this.httpClient.request({
|
|
1195
|
+
method,
|
|
1196
|
+
url: `/v1/computeruse/${safeSessionId}/${cleanPath}`,
|
|
1197
|
+
params: options.params,
|
|
1198
|
+
data: options.body,
|
|
1199
|
+
headers: { "X-API-Key": this.httpClient.apiKey }
|
|
1200
|
+
});
|
|
1201
|
+
}
|
|
1202
|
+
async get(sessionId, path, params) {
|
|
1203
|
+
return this.proxy(sessionId, path, "GET", { params });
|
|
1204
|
+
}
|
|
1205
|
+
async post(sessionId, path, body) {
|
|
1206
|
+
return this.proxy(sessionId, path, "POST", { body });
|
|
1207
|
+
}
|
|
1208
|
+
async put(sessionId, path, body) {
|
|
1209
|
+
return this.proxy(sessionId, path, "PUT", { body });
|
|
1210
|
+
}
|
|
1211
|
+
async patch(sessionId, path, body) {
|
|
1212
|
+
return this.proxy(sessionId, path, "PATCH", { body });
|
|
1213
|
+
}
|
|
1214
|
+
async delete(sessionId, path, params) {
|
|
1215
|
+
return this.proxy(sessionId, path, "DELETE", { params });
|
|
1216
|
+
}
|
|
1217
|
+
async options(sessionId, path, params) {
|
|
1218
|
+
return this.proxy(sessionId, path, "OPTIONS", { params });
|
|
1219
|
+
}
|
|
1220
|
+
};
|
|
1221
|
+
|
|
1222
|
+
// src/client/APIKeysManager.ts
|
|
1223
|
+
var APIKeysManager = class {
|
|
1224
|
+
constructor(httpClient, local = false) {
|
|
1225
|
+
this.httpClient = httpClient;
|
|
1226
|
+
this.local = local;
|
|
1227
|
+
}
|
|
1228
|
+
ensureCloud(operation) {
|
|
1229
|
+
if (this.local) {
|
|
1230
|
+
throw new UnsupportedOperationError(
|
|
1231
|
+
`${operation} is not supported in local mode.`
|
|
1232
|
+
);
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
async create(payload = {}) {
|
|
1236
|
+
this.ensureCloud("API key creation");
|
|
1237
|
+
return this.httpClient.post(
|
|
1238
|
+
"/v1/api-keys/",
|
|
1239
|
+
payload,
|
|
1240
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1241
|
+
);
|
|
1242
|
+
}
|
|
1243
|
+
async list() {
|
|
1244
|
+
this.ensureCloud("API key listing");
|
|
1245
|
+
return this.httpClient.get(
|
|
1246
|
+
"/v1/api-keys/",
|
|
1247
|
+
void 0,
|
|
1248
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1249
|
+
);
|
|
1250
|
+
}
|
|
1251
|
+
async get(itemId) {
|
|
1252
|
+
this.ensureCloud("API key lookup");
|
|
1253
|
+
const safeItemId = encodePathSegment(itemId);
|
|
1254
|
+
return this.httpClient.get(
|
|
1255
|
+
`/v1/api-keys/${safeItemId}`,
|
|
1256
|
+
void 0,
|
|
1257
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1258
|
+
);
|
|
1259
|
+
}
|
|
1260
|
+
async update(itemId, payload) {
|
|
1261
|
+
this.ensureCloud("API key update");
|
|
1262
|
+
const safeItemId = encodePathSegment(itemId);
|
|
1263
|
+
return this.httpClient.patch(
|
|
1264
|
+
`/v1/api-keys/${safeItemId}`,
|
|
1265
|
+
payload,
|
|
1266
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1267
|
+
);
|
|
1268
|
+
}
|
|
1269
|
+
async delete(itemId) {
|
|
1270
|
+
this.ensureCloud("API key deletion");
|
|
1271
|
+
const safeItemId = encodePathSegment(itemId);
|
|
1272
|
+
return this.httpClient.delete(
|
|
1273
|
+
`/v1/api-keys/${safeItemId}`,
|
|
1274
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1275
|
+
);
|
|
1276
|
+
}
|
|
1277
|
+
};
|
|
1278
|
+
|
|
1279
|
+
// src/client/AuditManager.ts
|
|
1280
|
+
var AuditManager = class {
|
|
1281
|
+
constructor(httpClient, local = false) {
|
|
1282
|
+
this.httpClient = httpClient;
|
|
1283
|
+
this.local = local;
|
|
1284
|
+
}
|
|
1285
|
+
ensureCloud(operation) {
|
|
1286
|
+
if (this.local) {
|
|
1287
|
+
throw new UnsupportedOperationError(
|
|
1288
|
+
`${operation} is not supported in local mode.`
|
|
1289
|
+
);
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
async catalog() {
|
|
1293
|
+
this.ensureCloud("Audit catalog");
|
|
1294
|
+
return this.httpClient.get(
|
|
1295
|
+
"/v1/audit/catalog",
|
|
1296
|
+
void 0,
|
|
1297
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1298
|
+
);
|
|
1299
|
+
}
|
|
1300
|
+
async events(query = {}) {
|
|
1301
|
+
this.ensureCloud("Audit event listing");
|
|
1302
|
+
return this.httpClient.get(
|
|
1303
|
+
"/v1/audit/events",
|
|
1304
|
+
query,
|
|
1305
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1306
|
+
);
|
|
1307
|
+
}
|
|
1308
|
+
async getEvent(eventId) {
|
|
1309
|
+
this.ensureCloud("Audit event lookup");
|
|
1310
|
+
const safeEventId = encodePathSegment(eventId);
|
|
1311
|
+
return this.httpClient.get(
|
|
1312
|
+
`/v1/audit/events/${safeEventId}`,
|
|
1313
|
+
void 0,
|
|
1314
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1315
|
+
);
|
|
1316
|
+
}
|
|
1317
|
+
};
|
|
1318
|
+
|
|
1319
|
+
// src/client/WebhooksManager.ts
|
|
1320
|
+
var WebhooksManager = class {
|
|
1321
|
+
constructor(httpClient, local = false) {
|
|
1322
|
+
this.httpClient = httpClient;
|
|
1323
|
+
this.local = local;
|
|
1324
|
+
}
|
|
1325
|
+
ensureCloud(operation) {
|
|
1326
|
+
if (this.local) {
|
|
1327
|
+
throw new UnsupportedOperationError(
|
|
1328
|
+
`${operation} is not supported in local mode.`
|
|
1329
|
+
);
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
async createEndpoint(payload) {
|
|
1333
|
+
this.ensureCloud("Webhook endpoint creation");
|
|
1334
|
+
return this.httpClient.post(
|
|
1335
|
+
"/v1/webhooks/endpoints",
|
|
1336
|
+
payload,
|
|
1337
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1338
|
+
);
|
|
1339
|
+
}
|
|
1340
|
+
async listEndpoints() {
|
|
1341
|
+
this.ensureCloud("Webhook endpoint listing");
|
|
1342
|
+
return this.httpClient.get(
|
|
1343
|
+
"/v1/webhooks/endpoints",
|
|
1344
|
+
void 0,
|
|
1345
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1346
|
+
);
|
|
1347
|
+
}
|
|
1348
|
+
async getEndpoint(endpointId) {
|
|
1349
|
+
this.ensureCloud("Webhook endpoint lookup");
|
|
1350
|
+
const safeEndpointId = encodePathSegment(endpointId);
|
|
1351
|
+
return this.httpClient.get(
|
|
1352
|
+
`/v1/webhooks/endpoints/${safeEndpointId}`,
|
|
1353
|
+
void 0,
|
|
1354
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1355
|
+
);
|
|
1356
|
+
}
|
|
1357
|
+
async updateEndpoint(endpointId, payload) {
|
|
1358
|
+
this.ensureCloud("Webhook endpoint update");
|
|
1359
|
+
const safeEndpointId = encodePathSegment(endpointId);
|
|
1360
|
+
return this.httpClient.patch(
|
|
1361
|
+
`/v1/webhooks/endpoints/${safeEndpointId}`,
|
|
1362
|
+
payload,
|
|
1363
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1364
|
+
);
|
|
1365
|
+
}
|
|
1366
|
+
async deleteEndpoint(endpointId) {
|
|
1367
|
+
this.ensureCloud("Webhook endpoint deletion");
|
|
1368
|
+
const safeEndpointId = encodePathSegment(endpointId);
|
|
1369
|
+
return this.httpClient.delete(
|
|
1370
|
+
`/v1/webhooks/endpoints/${safeEndpointId}`,
|
|
1371
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1372
|
+
);
|
|
1373
|
+
}
|
|
1374
|
+
async rotateSecret(endpointId) {
|
|
1375
|
+
this.ensureCloud("Webhook secret rotation");
|
|
1376
|
+
const safeEndpointId = encodePathSegment(endpointId);
|
|
1377
|
+
return this.httpClient.post(
|
|
1378
|
+
`/v1/webhooks/endpoints/${safeEndpointId}/rotate-secret`,
|
|
1379
|
+
{},
|
|
1380
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1381
|
+
);
|
|
1382
|
+
}
|
|
1383
|
+
async sendTestEvent(endpointId) {
|
|
1384
|
+
this.ensureCloud("Webhook test event");
|
|
1385
|
+
const safeEndpointId = encodePathSegment(endpointId);
|
|
1386
|
+
return this.httpClient.post(
|
|
1387
|
+
`/v1/webhooks/endpoints/${safeEndpointId}/test`,
|
|
1388
|
+
{},
|
|
1389
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1390
|
+
);
|
|
1391
|
+
}
|
|
1392
|
+
async verifyEndpoint(endpointId) {
|
|
1393
|
+
this.ensureCloud("Webhook endpoint verification");
|
|
1394
|
+
const safeEndpointId = encodePathSegment(endpointId);
|
|
1395
|
+
return this.httpClient.post(
|
|
1396
|
+
`/v1/webhooks/endpoints/${safeEndpointId}/verify`,
|
|
1397
|
+
{},
|
|
1398
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1399
|
+
);
|
|
1400
|
+
}
|
|
1401
|
+
async listDeliveries(query = {}) {
|
|
1402
|
+
this.ensureCloud("Webhook delivery listing");
|
|
1403
|
+
return this.httpClient.get(
|
|
1404
|
+
"/v1/webhooks/deliveries",
|
|
1405
|
+
query,
|
|
1406
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1407
|
+
);
|
|
1408
|
+
}
|
|
1409
|
+
async replayDelivery(deliveryId) {
|
|
1410
|
+
this.ensureCloud("Webhook delivery replay");
|
|
1411
|
+
const safeDeliveryId = encodePathSegment(deliveryId);
|
|
1412
|
+
return this.httpClient.post(
|
|
1413
|
+
`/v1/webhooks/deliveries/${safeDeliveryId}/replay`,
|
|
1414
|
+
{},
|
|
1415
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1416
|
+
);
|
|
1417
|
+
}
|
|
1418
|
+
};
|
|
1419
|
+
|
|
877
1420
|
// src/client/InstaVM.ts
|
|
878
1421
|
import FormData from "form-data";
|
|
879
1422
|
var InstaVM = class {
|
|
880
1423
|
constructor(apiKey, options = {}) {
|
|
881
1424
|
this._sessionId = null;
|
|
1425
|
+
this._vmUsed = false;
|
|
882
1426
|
this.local = options.local || false;
|
|
883
1427
|
this.timeout = options.timeout || 3e5;
|
|
1428
|
+
this.memory_mb = options.memory_mb;
|
|
1429
|
+
this.cpu_count = options.cpu_count;
|
|
1430
|
+
this.metadata = options.metadata;
|
|
1431
|
+
this.env = options.env;
|
|
884
1432
|
if (!this.local && !apiKey) {
|
|
885
1433
|
throw new AuthenticationError("API key is required for cloud mode");
|
|
886
1434
|
}
|
|
@@ -893,6 +1441,14 @@ var InstaVM = class {
|
|
|
893
1441
|
};
|
|
894
1442
|
this.httpClient = new HTTPClient(config);
|
|
895
1443
|
this.browser = new BrowserManager(this.httpClient, this.local);
|
|
1444
|
+
this.vms = new VMsManager(this.httpClient, this.local);
|
|
1445
|
+
this.snapshots = new SnapshotsManager(this.httpClient, this.local);
|
|
1446
|
+
this.shares = new SharesManager(this.httpClient, this.local, () => this._sessionId);
|
|
1447
|
+
this.customDomains = new CustomDomainsManager(this.httpClient, this.local);
|
|
1448
|
+
this.computerUse = new ComputerUseManager(this.httpClient, this.local);
|
|
1449
|
+
this.apiKeys = new APIKeysManager(this.httpClient, this.local);
|
|
1450
|
+
this.audit = new AuditManager(this.httpClient, this.local);
|
|
1451
|
+
this.webhooks = new WebhooksManager(this.httpClient, this.local);
|
|
896
1452
|
}
|
|
897
1453
|
/**
|
|
898
1454
|
* Ensure operation is not called in local mode
|
|
@@ -938,10 +1494,16 @@ var InstaVM = class {
|
|
|
938
1494
|
if (response.session_id) {
|
|
939
1495
|
this._sessionId = response.session_id;
|
|
940
1496
|
}
|
|
1497
|
+
if (!this.local) {
|
|
1498
|
+
this._vmUsed = true;
|
|
1499
|
+
}
|
|
941
1500
|
return {
|
|
942
|
-
|
|
1501
|
+
stdout: response.stdout || "",
|
|
1502
|
+
stderr: response.stderr || "",
|
|
943
1503
|
success: response.success !== false,
|
|
944
|
-
executionTime: response.execution_time
|
|
1504
|
+
executionTime: response.execution_time,
|
|
1505
|
+
cpuTime: response.cpu_time,
|
|
1506
|
+
createdAt: response.created_at,
|
|
945
1507
|
sessionId: response.session_id,
|
|
946
1508
|
error: response.error
|
|
947
1509
|
};
|
|
@@ -978,6 +1540,7 @@ var InstaVM = class {
|
|
|
978
1540
|
if (response.session_id) {
|
|
979
1541
|
this._sessionId = response.session_id;
|
|
980
1542
|
}
|
|
1543
|
+
this._vmUsed = true;
|
|
981
1544
|
return {
|
|
982
1545
|
taskId: response.task_id,
|
|
983
1546
|
status: response.status || "pending",
|
|
@@ -997,11 +1560,58 @@ var InstaVM = class {
|
|
|
997
1560
|
);
|
|
998
1561
|
}
|
|
999
1562
|
}
|
|
1563
|
+
/**
|
|
1564
|
+
* Poll for async task result
|
|
1565
|
+
*
|
|
1566
|
+
* @param taskId - The task ID from executeAsync
|
|
1567
|
+
* @param pollInterval - Seconds between polls (default: 1)
|
|
1568
|
+
* @param timeout - Maximum seconds to wait (default: 60)
|
|
1569
|
+
* @returns Task result with stdout, stderr, execution time, etc.
|
|
1570
|
+
* @throws Error if task doesn't complete within timeout
|
|
1571
|
+
*/
|
|
1572
|
+
async getTaskResult(taskId, pollInterval = 1, timeout = 60) {
|
|
1573
|
+
this.ensureNotLocal("Async task result retrieval");
|
|
1574
|
+
const startTime = Date.now();
|
|
1575
|
+
while (Date.now() - startTime < timeout * 1e3) {
|
|
1576
|
+
try {
|
|
1577
|
+
const response = await this.httpClient.get(
|
|
1578
|
+
`/v1/executions/${taskId}`,
|
|
1579
|
+
void 0,
|
|
1580
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1581
|
+
);
|
|
1582
|
+
if (response.is_complete) {
|
|
1583
|
+
return {
|
|
1584
|
+
stdout: response.serialized_stdout || "",
|
|
1585
|
+
stderr: response.serialized_stderr || "",
|
|
1586
|
+
cpuTime: response.cpu_time,
|
|
1587
|
+
executionTime: response.execution_time,
|
|
1588
|
+
createdAt: response.created_at
|
|
1589
|
+
};
|
|
1590
|
+
}
|
|
1591
|
+
await new Promise((resolve) => setTimeout(resolve, pollInterval * 1e3));
|
|
1592
|
+
} catch (error) {
|
|
1593
|
+
if (error instanceof AuthenticationError || error instanceof RateLimitError || error instanceof NetworkError) {
|
|
1594
|
+
throw error;
|
|
1595
|
+
}
|
|
1596
|
+
if (Date.now() - startTime >= timeout * 1e3) {
|
|
1597
|
+
throw new ExecutionError(
|
|
1598
|
+
`Failed to get task result: ${error instanceof Error ? error.message : String(error)}`
|
|
1599
|
+
);
|
|
1600
|
+
}
|
|
1601
|
+
await new Promise((resolve) => setTimeout(resolve, pollInterval * 1e3));
|
|
1602
|
+
}
|
|
1603
|
+
}
|
|
1604
|
+
throw new ExecutionError(`Task ${taskId} timed out after ${timeout}s`);
|
|
1605
|
+
}
|
|
1000
1606
|
/**
|
|
1001
1607
|
* Upload files to the execution environment
|
|
1002
1608
|
*/
|
|
1003
1609
|
async upload(files, options = {}) {
|
|
1004
1610
|
this.ensureNotLocal("File upload");
|
|
1611
|
+
const sessionId = options.sessionId || this._sessionId;
|
|
1612
|
+
if (!sessionId) {
|
|
1613
|
+
throw new SessionError("Session ID not set. Please create a session first using createSession().");
|
|
1614
|
+
}
|
|
1005
1615
|
const formData = new FormData();
|
|
1006
1616
|
for (const file of files) {
|
|
1007
1617
|
if (Buffer.isBuffer(file.content)) {
|
|
@@ -1013,9 +1623,7 @@ var InstaVM = class {
|
|
|
1013
1623
|
formData.append("paths", file.path);
|
|
1014
1624
|
}
|
|
1015
1625
|
}
|
|
1016
|
-
|
|
1017
|
-
formData.append("session_id", options.sessionId || this._sessionId);
|
|
1018
|
-
}
|
|
1626
|
+
formData.append("session_id", sessionId);
|
|
1019
1627
|
if (options.remotePath) {
|
|
1020
1628
|
formData.append("remote_path", options.remotePath);
|
|
1021
1629
|
}
|
|
@@ -1046,10 +1654,26 @@ var InstaVM = class {
|
|
|
1046
1654
|
async createSession() {
|
|
1047
1655
|
this.ensureNotLocal("Session management");
|
|
1048
1656
|
try {
|
|
1049
|
-
const
|
|
1657
|
+
const requestBody = {
|
|
1050
1658
|
api_key: this.httpClient.apiKey,
|
|
1051
1659
|
vm_lifetime_seconds: Math.floor(this.timeout / 1e3)
|
|
1052
|
-
}
|
|
1660
|
+
};
|
|
1661
|
+
if (this.memory_mb !== void 0) {
|
|
1662
|
+
requestBody.memory_mb = this.memory_mb;
|
|
1663
|
+
}
|
|
1664
|
+
if (this.cpu_count !== void 0) {
|
|
1665
|
+
requestBody.vcpu_count = this.cpu_count;
|
|
1666
|
+
}
|
|
1667
|
+
if (this.metadata !== void 0) {
|
|
1668
|
+
requestBody.metadata = this.metadata;
|
|
1669
|
+
}
|
|
1670
|
+
if (this.env !== void 0) {
|
|
1671
|
+
requestBody.env = this.env;
|
|
1672
|
+
}
|
|
1673
|
+
const response = await this.httpClient.post(
|
|
1674
|
+
"/v1/sessions/session",
|
|
1675
|
+
requestBody
|
|
1676
|
+
);
|
|
1053
1677
|
if (response.session_id) {
|
|
1054
1678
|
this._sessionId = response.session_id;
|
|
1055
1679
|
return response.session_id;
|
|
@@ -1076,6 +1700,30 @@ var InstaVM = class {
|
|
|
1076
1700
|
this._sessionId = null;
|
|
1077
1701
|
}
|
|
1078
1702
|
}
|
|
1703
|
+
/**
|
|
1704
|
+
* Check if current session is still active by checking VM status
|
|
1705
|
+
*
|
|
1706
|
+
* @returns true if session is active, false otherwise
|
|
1707
|
+
*/
|
|
1708
|
+
async isSessionActive(sessionId) {
|
|
1709
|
+
const targetSessionId = sessionId || this._sessionId;
|
|
1710
|
+
if (!targetSessionId) {
|
|
1711
|
+
return false;
|
|
1712
|
+
}
|
|
1713
|
+
try {
|
|
1714
|
+
const response = await this.httpClient.get(
|
|
1715
|
+
`/v1/sessions/status/${targetSessionId}`,
|
|
1716
|
+
void 0,
|
|
1717
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1718
|
+
);
|
|
1719
|
+
return response.vm_status === "active";
|
|
1720
|
+
} catch (error) {
|
|
1721
|
+
if (error instanceof SessionError || error instanceof AuthenticationError || error instanceof NetworkError) {
|
|
1722
|
+
return false;
|
|
1723
|
+
}
|
|
1724
|
+
return false;
|
|
1725
|
+
}
|
|
1726
|
+
}
|
|
1079
1727
|
/**
|
|
1080
1728
|
* Get usage statistics for a session
|
|
1081
1729
|
*/
|
|
@@ -1139,17 +1787,193 @@ var InstaVM = class {
|
|
|
1139
1787
|
get sessionId() {
|
|
1140
1788
|
return this._sessionId;
|
|
1141
1789
|
}
|
|
1790
|
+
/**
|
|
1791
|
+
* Kill the VM associated with a session
|
|
1792
|
+
*
|
|
1793
|
+
* @param sessionId - The session UUID whose VM should be killed. If not provided, uses current sessionId
|
|
1794
|
+
* @returns Result containing success message and killed VM ID
|
|
1795
|
+
*/
|
|
1796
|
+
async kill(sessionId) {
|
|
1797
|
+
this.ensureNotLocal("VM kill operation");
|
|
1798
|
+
const targetSessionId = sessionId || this._sessionId;
|
|
1799
|
+
if (!targetSessionId) {
|
|
1800
|
+
throw new SessionError("Session ID not set. Please provide a sessionId or start a session first.");
|
|
1801
|
+
}
|
|
1802
|
+
try {
|
|
1803
|
+
const response = await this.httpClient.post(
|
|
1804
|
+
"/kill",
|
|
1805
|
+
{ session_id: targetSessionId },
|
|
1806
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1807
|
+
);
|
|
1808
|
+
if (!sessionId && this._sessionId === targetSessionId) {
|
|
1809
|
+
this._sessionId = null;
|
|
1810
|
+
}
|
|
1811
|
+
return response;
|
|
1812
|
+
} catch (error) {
|
|
1813
|
+
if (error instanceof Error && "statusCode" in error) {
|
|
1814
|
+
const statusCode = error.statusCode;
|
|
1815
|
+
if (statusCode === 403) {
|
|
1816
|
+
throw new AuthenticationError("You don't own this session", { cause: error });
|
|
1817
|
+
}
|
|
1818
|
+
if (statusCode === 404) {
|
|
1819
|
+
throw new SessionError("Session not found or no VM assigned to session (has execute() been called?)", { cause: error });
|
|
1820
|
+
}
|
|
1821
|
+
}
|
|
1822
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1823
|
+
throw new SessionError(
|
|
1824
|
+
`Failed to kill VM: ${errorMessage}`,
|
|
1825
|
+
{ cause: error }
|
|
1826
|
+
);
|
|
1827
|
+
}
|
|
1828
|
+
}
|
|
1829
|
+
// --- Egress Policy Methods ---
|
|
1830
|
+
/**
|
|
1831
|
+
* Set egress policy for a session
|
|
1832
|
+
*/
|
|
1833
|
+
async setSessionEgress(options = {}, sessionId) {
|
|
1834
|
+
this.ensureNotLocal("Egress policy management");
|
|
1835
|
+
const targetSessionId = sessionId || this._sessionId;
|
|
1836
|
+
if (!targetSessionId) {
|
|
1837
|
+
throw new SessionError("Session ID not set. Please create a session first.");
|
|
1838
|
+
}
|
|
1839
|
+
const response = await this.httpClient.post(
|
|
1840
|
+
`/v1/egress/session/${targetSessionId}`,
|
|
1841
|
+
{
|
|
1842
|
+
allow_public_repos: options.allowPackageManagers ?? true,
|
|
1843
|
+
allow_http: options.allowHttp ?? true,
|
|
1844
|
+
allow_https: options.allowHttps ?? true,
|
|
1845
|
+
allowed_domains: options.allowedDomains ?? [],
|
|
1846
|
+
allowed_cidrs: options.allowedCidrs ?? []
|
|
1847
|
+
},
|
|
1848
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1849
|
+
);
|
|
1850
|
+
return response;
|
|
1851
|
+
}
|
|
1852
|
+
/**
|
|
1853
|
+
* Get egress policy for a session
|
|
1854
|
+
*/
|
|
1855
|
+
async getSessionEgress(sessionId) {
|
|
1856
|
+
this.ensureNotLocal("Egress policy management");
|
|
1857
|
+
const targetSessionId = sessionId || this._sessionId;
|
|
1858
|
+
if (!targetSessionId) {
|
|
1859
|
+
throw new SessionError("Session ID not set. Please create a session first.");
|
|
1860
|
+
}
|
|
1861
|
+
const response = await this.httpClient.get(
|
|
1862
|
+
`/v1/egress/session/${targetSessionId}`,
|
|
1863
|
+
void 0,
|
|
1864
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1865
|
+
);
|
|
1866
|
+
return {
|
|
1867
|
+
allowPackageManagers: response.allow_public_repos,
|
|
1868
|
+
allowHttp: response.allow_http,
|
|
1869
|
+
allowHttps: response.allow_https,
|
|
1870
|
+
allowedDomains: response.allowed_domains || [],
|
|
1871
|
+
allowedCidrs: response.allowed_cidrs || []
|
|
1872
|
+
};
|
|
1873
|
+
}
|
|
1874
|
+
/**
|
|
1875
|
+
* Set egress policy for a specific VM
|
|
1876
|
+
*/
|
|
1877
|
+
async setVmEgress(vmId, options = {}) {
|
|
1878
|
+
this.ensureNotLocal("Egress policy management");
|
|
1879
|
+
const response = await this.httpClient.post(
|
|
1880
|
+
`/v1/egress/vm/${vmId}`,
|
|
1881
|
+
{
|
|
1882
|
+
allow_public_repos: options.allowPackageManagers ?? true,
|
|
1883
|
+
allow_http: options.allowHttp ?? true,
|
|
1884
|
+
allow_https: options.allowHttps ?? true,
|
|
1885
|
+
allowed_domains: options.allowedDomains ?? [],
|
|
1886
|
+
allowed_cidrs: options.allowedCidrs ?? []
|
|
1887
|
+
},
|
|
1888
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1889
|
+
);
|
|
1890
|
+
return response;
|
|
1891
|
+
}
|
|
1892
|
+
/**
|
|
1893
|
+
* Get egress policy for a specific VM
|
|
1894
|
+
*/
|
|
1895
|
+
async getVmEgress(vmId) {
|
|
1896
|
+
this.ensureNotLocal("Egress policy management");
|
|
1897
|
+
const response = await this.httpClient.get(
|
|
1898
|
+
`/v1/egress/vm/${vmId}`,
|
|
1899
|
+
void 0,
|
|
1900
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1901
|
+
);
|
|
1902
|
+
return {
|
|
1903
|
+
allowPackageManagers: response.allow_public_repos,
|
|
1904
|
+
allowHttp: response.allow_http,
|
|
1905
|
+
allowHttps: response.allow_https,
|
|
1906
|
+
allowedDomains: response.allowed_domains || [],
|
|
1907
|
+
allowedCidrs: response.allowed_cidrs || []
|
|
1908
|
+
};
|
|
1909
|
+
}
|
|
1910
|
+
// --- SSH Key Methods ---
|
|
1911
|
+
/**
|
|
1912
|
+
* Add an SSH public key
|
|
1913
|
+
*/
|
|
1914
|
+
async addSshKey(publicKey) {
|
|
1915
|
+
this.ensureNotLocal("SSH key management");
|
|
1916
|
+
const response = await this.httpClient.post(
|
|
1917
|
+
"/v1/ssh-keys",
|
|
1918
|
+
{ public_key: publicKey },
|
|
1919
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1920
|
+
);
|
|
1921
|
+
return {
|
|
1922
|
+
id: response.id,
|
|
1923
|
+
fingerprint: response.fingerprint,
|
|
1924
|
+
keyType: response.key_type,
|
|
1925
|
+
comment: response.comment ?? null,
|
|
1926
|
+
createdAt: response.created_at
|
|
1927
|
+
};
|
|
1928
|
+
}
|
|
1929
|
+
/**
|
|
1930
|
+
* List all active SSH keys
|
|
1931
|
+
*/
|
|
1932
|
+
async listSshKeys() {
|
|
1933
|
+
this.ensureNotLocal("SSH key management");
|
|
1934
|
+
const response = await this.httpClient.get(
|
|
1935
|
+
"/v1/ssh-keys",
|
|
1936
|
+
void 0,
|
|
1937
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1938
|
+
);
|
|
1939
|
+
const keys = response.keys || [];
|
|
1940
|
+
return keys.map((k) => ({
|
|
1941
|
+
id: k.id,
|
|
1942
|
+
fingerprint: k.fingerprint,
|
|
1943
|
+
keyType: k.key_type,
|
|
1944
|
+
comment: k.comment ?? null,
|
|
1945
|
+
createdAt: k.created_at
|
|
1946
|
+
}));
|
|
1947
|
+
}
|
|
1948
|
+
/**
|
|
1949
|
+
* Delete an SSH key by ID
|
|
1950
|
+
*/
|
|
1951
|
+
async deleteSshKey(keyId) {
|
|
1952
|
+
this.ensureNotLocal("SSH key management");
|
|
1953
|
+
const response = await this.httpClient.delete(
|
|
1954
|
+
`/v1/ssh-keys/${keyId}`,
|
|
1955
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1956
|
+
);
|
|
1957
|
+
return response;
|
|
1958
|
+
}
|
|
1142
1959
|
/**
|
|
1143
1960
|
* Clean up resources
|
|
1144
1961
|
*/
|
|
1145
1962
|
async dispose() {
|
|
1146
|
-
if (this._sessionId) {
|
|
1963
|
+
if (this._sessionId && !this.local && this._vmUsed) {
|
|
1964
|
+
try {
|
|
1965
|
+
await this.kill();
|
|
1966
|
+
} catch (e) {
|
|
1967
|
+
}
|
|
1968
|
+
} else if (this._sessionId) {
|
|
1147
1969
|
await this.closeSession();
|
|
1148
1970
|
}
|
|
1149
1971
|
await this.browser.dispose();
|
|
1150
1972
|
}
|
|
1151
1973
|
};
|
|
1152
1974
|
export {
|
|
1975
|
+
APIKeysManager,
|
|
1976
|
+
AuditManager,
|
|
1153
1977
|
AuthenticationError,
|
|
1154
1978
|
BrowserError,
|
|
1155
1979
|
BrowserInteractionError,
|
|
@@ -1158,6 +1982,8 @@ export {
|
|
|
1158
1982
|
BrowserSession,
|
|
1159
1983
|
BrowserSessionError,
|
|
1160
1984
|
BrowserTimeoutError,
|
|
1985
|
+
ComputerUseManager,
|
|
1986
|
+
CustomDomainsManager,
|
|
1161
1987
|
ElementNotFoundError,
|
|
1162
1988
|
ExecutionError,
|
|
1163
1989
|
InstaVM,
|
|
@@ -1166,6 +1992,10 @@ export {
|
|
|
1166
1992
|
QuotaExceededError,
|
|
1167
1993
|
RateLimitError,
|
|
1168
1994
|
SessionError,
|
|
1169
|
-
|
|
1995
|
+
SharesManager,
|
|
1996
|
+
SnapshotsManager,
|
|
1997
|
+
UnsupportedOperationError,
|
|
1998
|
+
VMsManager,
|
|
1999
|
+
WebhooksManager
|
|
1170
2000
|
};
|
|
1171
2001
|
//# sourceMappingURL=index.mjs.map
|