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.js
CHANGED
|
@@ -31,6 +31,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
// src/index.ts
|
|
32
32
|
var index_exports = {};
|
|
33
33
|
__export(index_exports, {
|
|
34
|
+
APIKeysManager: () => APIKeysManager,
|
|
35
|
+
AuditManager: () => AuditManager,
|
|
34
36
|
AuthenticationError: () => AuthenticationError,
|
|
35
37
|
BrowserError: () => BrowserError,
|
|
36
38
|
BrowserInteractionError: () => BrowserInteractionError,
|
|
@@ -39,6 +41,8 @@ __export(index_exports, {
|
|
|
39
41
|
BrowserSession: () => BrowserSession,
|
|
40
42
|
BrowserSessionError: () => BrowserSessionError,
|
|
41
43
|
BrowserTimeoutError: () => BrowserTimeoutError,
|
|
44
|
+
ComputerUseManager: () => ComputerUseManager,
|
|
45
|
+
CustomDomainsManager: () => CustomDomainsManager,
|
|
42
46
|
ElementNotFoundError: () => ElementNotFoundError,
|
|
43
47
|
ExecutionError: () => ExecutionError,
|
|
44
48
|
InstaVM: () => InstaVM,
|
|
@@ -47,7 +51,11 @@ __export(index_exports, {
|
|
|
47
51
|
QuotaExceededError: () => QuotaExceededError,
|
|
48
52
|
RateLimitError: () => RateLimitError,
|
|
49
53
|
SessionError: () => SessionError,
|
|
50
|
-
|
|
54
|
+
SharesManager: () => SharesManager,
|
|
55
|
+
SnapshotsManager: () => SnapshotsManager,
|
|
56
|
+
UnsupportedOperationError: () => UnsupportedOperationError,
|
|
57
|
+
VMsManager: () => VMsManager,
|
|
58
|
+
WebhooksManager: () => WebhooksManager
|
|
51
59
|
});
|
|
52
60
|
module.exports = __toCommonJS(index_exports);
|
|
53
61
|
|
|
@@ -190,7 +198,7 @@ var HTTPClient = class {
|
|
|
190
198
|
timeout: config.timeout,
|
|
191
199
|
headers: {
|
|
192
200
|
"Content-Type": "application/json",
|
|
193
|
-
"User-Agent": "instavm-js-sdk/0.
|
|
201
|
+
"User-Agent": "instavm-js-sdk/0.11.0"
|
|
194
202
|
}
|
|
195
203
|
});
|
|
196
204
|
this.setupInterceptors();
|
|
@@ -211,7 +219,7 @@ var HTTPClient = class {
|
|
|
211
219
|
const axiosError = error;
|
|
212
220
|
const status = axiosError.response?.status;
|
|
213
221
|
const data = axiosError.response?.data;
|
|
214
|
-
const message = data?.message || data?.error || axiosError.message;
|
|
222
|
+
const message = data?.message || data?.error || data?.detail || axiosError.message;
|
|
215
223
|
switch (status) {
|
|
216
224
|
case 401:
|
|
217
225
|
throw new AuthenticationError(message, {
|
|
@@ -223,14 +231,16 @@ var HTTPClient = class {
|
|
|
223
231
|
statusCode: status,
|
|
224
232
|
response: data
|
|
225
233
|
});
|
|
226
|
-
case 429:
|
|
234
|
+
case 429: {
|
|
227
235
|
const retryAfter = parseInt(
|
|
228
236
|
axiosError.response?.headers["retry-after"] || "60"
|
|
229
237
|
);
|
|
230
|
-
|
|
238
|
+
const rateLimitMessage = data?.detail || message;
|
|
239
|
+
throw new RateLimitError(rateLimitMessage, retryAfter, {
|
|
231
240
|
statusCode: status,
|
|
232
241
|
response: data
|
|
233
242
|
});
|
|
243
|
+
}
|
|
234
244
|
case 500:
|
|
235
245
|
case 502:
|
|
236
246
|
case 503:
|
|
@@ -308,6 +318,7 @@ var HTTPClient = class {
|
|
|
308
318
|
*/
|
|
309
319
|
async postFormData(url, formData, headers) {
|
|
310
320
|
const requestHeaders = {
|
|
321
|
+
"X-API-Key": this.config.apiKey,
|
|
311
322
|
...formData.getHeaders(),
|
|
312
323
|
...headers
|
|
313
324
|
};
|
|
@@ -359,6 +370,39 @@ var HTTPClient = class {
|
|
|
359
370
|
headers
|
|
360
371
|
});
|
|
361
372
|
}
|
|
373
|
+
/**
|
|
374
|
+
* PUT request
|
|
375
|
+
*/
|
|
376
|
+
async put(url, data, headers) {
|
|
377
|
+
return this.request({
|
|
378
|
+
method: "PUT",
|
|
379
|
+
url,
|
|
380
|
+
data,
|
|
381
|
+
headers
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* PATCH request
|
|
386
|
+
*/
|
|
387
|
+
async patch(url, data, headers) {
|
|
388
|
+
return this.request({
|
|
389
|
+
method: "PATCH",
|
|
390
|
+
url,
|
|
391
|
+
data,
|
|
392
|
+
headers
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* OPTIONS request
|
|
397
|
+
*/
|
|
398
|
+
async options(url, headers, params) {
|
|
399
|
+
return this.request({
|
|
400
|
+
method: "OPTIONS",
|
|
401
|
+
url,
|
|
402
|
+
headers,
|
|
403
|
+
params
|
|
404
|
+
});
|
|
405
|
+
}
|
|
362
406
|
/**
|
|
363
407
|
* POST request that returns raw binary data (for file downloads)
|
|
364
408
|
*/
|
|
@@ -925,13 +969,525 @@ var BrowserManager = class {
|
|
|
925
969
|
}
|
|
926
970
|
};
|
|
927
971
|
|
|
972
|
+
// src/utils/path.ts
|
|
973
|
+
function encodePathSegment(value) {
|
|
974
|
+
return encodeURIComponent(String(value));
|
|
975
|
+
}
|
|
976
|
+
function encodePathSegments(path) {
|
|
977
|
+
const segments = path.replace(/^\/+/, "").split("/").filter((segment) => segment.length > 0 && segment !== ".");
|
|
978
|
+
if (segments.some((segment) => segment === "..")) {
|
|
979
|
+
throw new Error("Path traversal not allowed in proxy path");
|
|
980
|
+
}
|
|
981
|
+
return segments.map((segment) => encodeURIComponent(segment)).join("/");
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
// src/client/VMsManager.ts
|
|
985
|
+
var VMsManager = class {
|
|
986
|
+
constructor(httpClient, local = false) {
|
|
987
|
+
this.httpClient = httpClient;
|
|
988
|
+
this.local = local;
|
|
989
|
+
}
|
|
990
|
+
ensureCloud(operation) {
|
|
991
|
+
if (this.local) {
|
|
992
|
+
throw new UnsupportedOperationError(
|
|
993
|
+
`${operation} is not supported in local mode.`
|
|
994
|
+
);
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
async create(payload = {}, wait = true) {
|
|
998
|
+
this.ensureCloud("VM creation");
|
|
999
|
+
return this.httpClient.request({
|
|
1000
|
+
method: "POST",
|
|
1001
|
+
url: "/v1/vms",
|
|
1002
|
+
params: { wait },
|
|
1003
|
+
data: payload,
|
|
1004
|
+
headers: { "X-API-Key": this.httpClient.apiKey }
|
|
1005
|
+
});
|
|
1006
|
+
}
|
|
1007
|
+
async list() {
|
|
1008
|
+
this.ensureCloud("VM listing");
|
|
1009
|
+
return this.httpClient.get(
|
|
1010
|
+
"/v1/vms",
|
|
1011
|
+
void 0,
|
|
1012
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1013
|
+
);
|
|
1014
|
+
}
|
|
1015
|
+
async listAll() {
|
|
1016
|
+
return this.listAllRecords();
|
|
1017
|
+
}
|
|
1018
|
+
/**
|
|
1019
|
+
* Calls GET /v1/vms/ (trailing slash), a distinct route from GET /v1/vms.
|
|
1020
|
+
*/
|
|
1021
|
+
async listAllRecords() {
|
|
1022
|
+
this.ensureCloud("VM listing");
|
|
1023
|
+
return this.httpClient.get(
|
|
1024
|
+
"/v1/vms/",
|
|
1025
|
+
void 0,
|
|
1026
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1027
|
+
);
|
|
1028
|
+
}
|
|
1029
|
+
async get(itemId) {
|
|
1030
|
+
this.ensureCloud("VM lookup");
|
|
1031
|
+
const safeItemId = encodePathSegment(itemId);
|
|
1032
|
+
return this.httpClient.get(
|
|
1033
|
+
`/v1/vms/${safeItemId}`,
|
|
1034
|
+
void 0,
|
|
1035
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1036
|
+
);
|
|
1037
|
+
}
|
|
1038
|
+
async update(vmId, payload = {}) {
|
|
1039
|
+
this.ensureCloud("VM update");
|
|
1040
|
+
const safeVmId = encodePathSegment(vmId);
|
|
1041
|
+
return this.httpClient.patch(
|
|
1042
|
+
`/v1/vms/${safeVmId}`,
|
|
1043
|
+
payload,
|
|
1044
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1045
|
+
);
|
|
1046
|
+
}
|
|
1047
|
+
async delete(vmId) {
|
|
1048
|
+
this.ensureCloud("VM deletion");
|
|
1049
|
+
const safeVmId = encodePathSegment(vmId);
|
|
1050
|
+
return this.httpClient.delete(
|
|
1051
|
+
`/v1/vms/${safeVmId}`,
|
|
1052
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1053
|
+
);
|
|
1054
|
+
}
|
|
1055
|
+
async clone(vmId, payload = {}, wait = true) {
|
|
1056
|
+
this.ensureCloud("VM clone");
|
|
1057
|
+
const safeVmId = encodePathSegment(vmId);
|
|
1058
|
+
return this.httpClient.request({
|
|
1059
|
+
method: "POST",
|
|
1060
|
+
url: `/v1/vms/${safeVmId}/clone`,
|
|
1061
|
+
params: { wait },
|
|
1062
|
+
data: payload,
|
|
1063
|
+
headers: { "X-API-Key": this.httpClient.apiKey }
|
|
1064
|
+
});
|
|
1065
|
+
}
|
|
1066
|
+
async snapshot(vmId, payload = {}, wait = true) {
|
|
1067
|
+
this.ensureCloud("VM snapshot");
|
|
1068
|
+
const safeVmId = encodePathSegment(vmId);
|
|
1069
|
+
return this.httpClient.request({
|
|
1070
|
+
method: "POST",
|
|
1071
|
+
url: `/v1/vms/${safeVmId}/snapshot`,
|
|
1072
|
+
params: { wait },
|
|
1073
|
+
data: payload,
|
|
1074
|
+
headers: { "X-API-Key": this.httpClient.apiKey }
|
|
1075
|
+
});
|
|
1076
|
+
}
|
|
1077
|
+
};
|
|
1078
|
+
|
|
1079
|
+
// src/client/SnapshotsManager.ts
|
|
1080
|
+
var SnapshotsManager = class {
|
|
1081
|
+
constructor(httpClient, local = false) {
|
|
1082
|
+
this.httpClient = httpClient;
|
|
1083
|
+
this.local = local;
|
|
1084
|
+
}
|
|
1085
|
+
ensureCloud(operation) {
|
|
1086
|
+
if (this.local) {
|
|
1087
|
+
throw new UnsupportedOperationError(
|
|
1088
|
+
`${operation} is not supported in local mode.`
|
|
1089
|
+
);
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
async create(payload) {
|
|
1093
|
+
this.ensureCloud("Snapshot creation");
|
|
1094
|
+
return this.httpClient.post(
|
|
1095
|
+
"/v1/snapshots",
|
|
1096
|
+
payload,
|
|
1097
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1098
|
+
);
|
|
1099
|
+
}
|
|
1100
|
+
async list(options = {}) {
|
|
1101
|
+
this.ensureCloud("Snapshot listing");
|
|
1102
|
+
return this.httpClient.get(
|
|
1103
|
+
"/v1/snapshots",
|
|
1104
|
+
options,
|
|
1105
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1106
|
+
);
|
|
1107
|
+
}
|
|
1108
|
+
async get(snapshotId) {
|
|
1109
|
+
this.ensureCloud("Snapshot lookup");
|
|
1110
|
+
const safeSnapshotId = encodePathSegment(snapshotId);
|
|
1111
|
+
return this.httpClient.get(
|
|
1112
|
+
`/v1/snapshots/${safeSnapshotId}`,
|
|
1113
|
+
void 0,
|
|
1114
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1115
|
+
);
|
|
1116
|
+
}
|
|
1117
|
+
async delete(snapshotId) {
|
|
1118
|
+
this.ensureCloud("Snapshot deletion");
|
|
1119
|
+
const safeSnapshotId = encodePathSegment(snapshotId);
|
|
1120
|
+
return this.httpClient.delete(
|
|
1121
|
+
`/v1/snapshots/${safeSnapshotId}`,
|
|
1122
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1123
|
+
);
|
|
1124
|
+
}
|
|
1125
|
+
};
|
|
1126
|
+
|
|
1127
|
+
// src/client/SharesManager.ts
|
|
1128
|
+
var SharesManager = class {
|
|
1129
|
+
constructor(httpClient, local = false, getSessionId = () => null) {
|
|
1130
|
+
this.httpClient = httpClient;
|
|
1131
|
+
this.local = local;
|
|
1132
|
+
this.getSessionId = getSessionId;
|
|
1133
|
+
}
|
|
1134
|
+
ensureCloud(operation) {
|
|
1135
|
+
if (this.local) {
|
|
1136
|
+
throw new UnsupportedOperationError(
|
|
1137
|
+
`${operation} is not supported in local mode.`
|
|
1138
|
+
);
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
async create(payload) {
|
|
1142
|
+
this.ensureCloud("Share creation");
|
|
1143
|
+
const body = { ...payload };
|
|
1144
|
+
if (!body.session_id && !body.vm_id) {
|
|
1145
|
+
const sid = this.getSessionId();
|
|
1146
|
+
if (!sid) {
|
|
1147
|
+
throw new SessionError(
|
|
1148
|
+
"Provide session_id/vm_id or create a session before creating a share."
|
|
1149
|
+
);
|
|
1150
|
+
}
|
|
1151
|
+
body.session_id = sid;
|
|
1152
|
+
}
|
|
1153
|
+
return this.httpClient.post(
|
|
1154
|
+
"/v1/shares",
|
|
1155
|
+
body,
|
|
1156
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1157
|
+
);
|
|
1158
|
+
}
|
|
1159
|
+
async update(shareId, payload) {
|
|
1160
|
+
this.ensureCloud("Share update");
|
|
1161
|
+
const safeShareId = encodePathSegment(shareId);
|
|
1162
|
+
return this.httpClient.patch(
|
|
1163
|
+
`/v1/shares/${safeShareId}`,
|
|
1164
|
+
payload,
|
|
1165
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1166
|
+
);
|
|
1167
|
+
}
|
|
1168
|
+
};
|
|
1169
|
+
|
|
1170
|
+
// src/client/CustomDomainsManager.ts
|
|
1171
|
+
var CustomDomainsManager = class {
|
|
1172
|
+
constructor(httpClient, local = false) {
|
|
1173
|
+
this.httpClient = httpClient;
|
|
1174
|
+
this.local = local;
|
|
1175
|
+
}
|
|
1176
|
+
ensureCloud(operation) {
|
|
1177
|
+
if (this.local) {
|
|
1178
|
+
throw new UnsupportedOperationError(
|
|
1179
|
+
`${operation} is not supported in local mode.`
|
|
1180
|
+
);
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
async create(payload) {
|
|
1184
|
+
this.ensureCloud("Custom domain creation");
|
|
1185
|
+
return this.httpClient.post(
|
|
1186
|
+
"/v1/custom-domains",
|
|
1187
|
+
payload,
|
|
1188
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1189
|
+
);
|
|
1190
|
+
}
|
|
1191
|
+
async list() {
|
|
1192
|
+
this.ensureCloud("Custom domain listing");
|
|
1193
|
+
return this.httpClient.get(
|
|
1194
|
+
"/v1/custom-domains",
|
|
1195
|
+
void 0,
|
|
1196
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1197
|
+
);
|
|
1198
|
+
}
|
|
1199
|
+
async health(domainId) {
|
|
1200
|
+
this.ensureCloud("Custom domain health");
|
|
1201
|
+
const safeDomainId = encodePathSegment(domainId);
|
|
1202
|
+
return this.httpClient.get(
|
|
1203
|
+
`/v1/custom-domains/${safeDomainId}/health`,
|
|
1204
|
+
void 0,
|
|
1205
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1206
|
+
);
|
|
1207
|
+
}
|
|
1208
|
+
async verify(domainId) {
|
|
1209
|
+
this.ensureCloud("Custom domain verification");
|
|
1210
|
+
const safeDomainId = encodePathSegment(domainId);
|
|
1211
|
+
return this.httpClient.post(
|
|
1212
|
+
`/v1/custom-domains/${safeDomainId}/verify`,
|
|
1213
|
+
{},
|
|
1214
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1215
|
+
);
|
|
1216
|
+
}
|
|
1217
|
+
async delete(domainId) {
|
|
1218
|
+
this.ensureCloud("Custom domain deletion");
|
|
1219
|
+
const safeDomainId = encodePathSegment(domainId);
|
|
1220
|
+
return this.httpClient.delete(
|
|
1221
|
+
`/v1/custom-domains/${safeDomainId}`,
|
|
1222
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1223
|
+
);
|
|
1224
|
+
}
|
|
1225
|
+
};
|
|
1226
|
+
|
|
1227
|
+
// src/client/ComputerUseManager.ts
|
|
1228
|
+
var ComputerUseManager = class {
|
|
1229
|
+
constructor(httpClient, local = false) {
|
|
1230
|
+
this.httpClient = httpClient;
|
|
1231
|
+
this.local = local;
|
|
1232
|
+
}
|
|
1233
|
+
ensureCloud(operation) {
|
|
1234
|
+
if (this.local) {
|
|
1235
|
+
throw new UnsupportedOperationError(
|
|
1236
|
+
`${operation} is not supported in local mode.`
|
|
1237
|
+
);
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
async viewerUrl(sessionId) {
|
|
1241
|
+
this.ensureCloud("Computer-use viewer URL");
|
|
1242
|
+
const safeSessionId = encodePathSegment(sessionId);
|
|
1243
|
+
return this.httpClient.get(
|
|
1244
|
+
`/v1/computeruse/${safeSessionId}/viewer-url`,
|
|
1245
|
+
void 0,
|
|
1246
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1247
|
+
);
|
|
1248
|
+
}
|
|
1249
|
+
async proxy(sessionId, path, method = "GET", options = {}) {
|
|
1250
|
+
this.ensureCloud("Computer-use proxy");
|
|
1251
|
+
const safeSessionId = encodePathSegment(sessionId);
|
|
1252
|
+
const cleanPath = encodePathSegments(path);
|
|
1253
|
+
return this.httpClient.request({
|
|
1254
|
+
method,
|
|
1255
|
+
url: `/v1/computeruse/${safeSessionId}/${cleanPath}`,
|
|
1256
|
+
params: options.params,
|
|
1257
|
+
data: options.body,
|
|
1258
|
+
headers: { "X-API-Key": this.httpClient.apiKey }
|
|
1259
|
+
});
|
|
1260
|
+
}
|
|
1261
|
+
async get(sessionId, path, params) {
|
|
1262
|
+
return this.proxy(sessionId, path, "GET", { params });
|
|
1263
|
+
}
|
|
1264
|
+
async post(sessionId, path, body) {
|
|
1265
|
+
return this.proxy(sessionId, path, "POST", { body });
|
|
1266
|
+
}
|
|
1267
|
+
async put(sessionId, path, body) {
|
|
1268
|
+
return this.proxy(sessionId, path, "PUT", { body });
|
|
1269
|
+
}
|
|
1270
|
+
async patch(sessionId, path, body) {
|
|
1271
|
+
return this.proxy(sessionId, path, "PATCH", { body });
|
|
1272
|
+
}
|
|
1273
|
+
async delete(sessionId, path, params) {
|
|
1274
|
+
return this.proxy(sessionId, path, "DELETE", { params });
|
|
1275
|
+
}
|
|
1276
|
+
async options(sessionId, path, params) {
|
|
1277
|
+
return this.proxy(sessionId, path, "OPTIONS", { params });
|
|
1278
|
+
}
|
|
1279
|
+
};
|
|
1280
|
+
|
|
1281
|
+
// src/client/APIKeysManager.ts
|
|
1282
|
+
var APIKeysManager = class {
|
|
1283
|
+
constructor(httpClient, local = false) {
|
|
1284
|
+
this.httpClient = httpClient;
|
|
1285
|
+
this.local = local;
|
|
1286
|
+
}
|
|
1287
|
+
ensureCloud(operation) {
|
|
1288
|
+
if (this.local) {
|
|
1289
|
+
throw new UnsupportedOperationError(
|
|
1290
|
+
`${operation} is not supported in local mode.`
|
|
1291
|
+
);
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
async create(payload = {}) {
|
|
1295
|
+
this.ensureCloud("API key creation");
|
|
1296
|
+
return this.httpClient.post(
|
|
1297
|
+
"/v1/api-keys/",
|
|
1298
|
+
payload,
|
|
1299
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1300
|
+
);
|
|
1301
|
+
}
|
|
1302
|
+
async list() {
|
|
1303
|
+
this.ensureCloud("API key listing");
|
|
1304
|
+
return this.httpClient.get(
|
|
1305
|
+
"/v1/api-keys/",
|
|
1306
|
+
void 0,
|
|
1307
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1308
|
+
);
|
|
1309
|
+
}
|
|
1310
|
+
async get(itemId) {
|
|
1311
|
+
this.ensureCloud("API key lookup");
|
|
1312
|
+
const safeItemId = encodePathSegment(itemId);
|
|
1313
|
+
return this.httpClient.get(
|
|
1314
|
+
`/v1/api-keys/${safeItemId}`,
|
|
1315
|
+
void 0,
|
|
1316
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1317
|
+
);
|
|
1318
|
+
}
|
|
1319
|
+
async update(itemId, payload) {
|
|
1320
|
+
this.ensureCloud("API key update");
|
|
1321
|
+
const safeItemId = encodePathSegment(itemId);
|
|
1322
|
+
return this.httpClient.patch(
|
|
1323
|
+
`/v1/api-keys/${safeItemId}`,
|
|
1324
|
+
payload,
|
|
1325
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1326
|
+
);
|
|
1327
|
+
}
|
|
1328
|
+
async delete(itemId) {
|
|
1329
|
+
this.ensureCloud("API key deletion");
|
|
1330
|
+
const safeItemId = encodePathSegment(itemId);
|
|
1331
|
+
return this.httpClient.delete(
|
|
1332
|
+
`/v1/api-keys/${safeItemId}`,
|
|
1333
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1334
|
+
);
|
|
1335
|
+
}
|
|
1336
|
+
};
|
|
1337
|
+
|
|
1338
|
+
// src/client/AuditManager.ts
|
|
1339
|
+
var AuditManager = class {
|
|
1340
|
+
constructor(httpClient, local = false) {
|
|
1341
|
+
this.httpClient = httpClient;
|
|
1342
|
+
this.local = local;
|
|
1343
|
+
}
|
|
1344
|
+
ensureCloud(operation) {
|
|
1345
|
+
if (this.local) {
|
|
1346
|
+
throw new UnsupportedOperationError(
|
|
1347
|
+
`${operation} is not supported in local mode.`
|
|
1348
|
+
);
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1351
|
+
async catalog() {
|
|
1352
|
+
this.ensureCloud("Audit catalog");
|
|
1353
|
+
return this.httpClient.get(
|
|
1354
|
+
"/v1/audit/catalog",
|
|
1355
|
+
void 0,
|
|
1356
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1357
|
+
);
|
|
1358
|
+
}
|
|
1359
|
+
async events(query = {}) {
|
|
1360
|
+
this.ensureCloud("Audit event listing");
|
|
1361
|
+
return this.httpClient.get(
|
|
1362
|
+
"/v1/audit/events",
|
|
1363
|
+
query,
|
|
1364
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1365
|
+
);
|
|
1366
|
+
}
|
|
1367
|
+
async getEvent(eventId) {
|
|
1368
|
+
this.ensureCloud("Audit event lookup");
|
|
1369
|
+
const safeEventId = encodePathSegment(eventId);
|
|
1370
|
+
return this.httpClient.get(
|
|
1371
|
+
`/v1/audit/events/${safeEventId}`,
|
|
1372
|
+
void 0,
|
|
1373
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1374
|
+
);
|
|
1375
|
+
}
|
|
1376
|
+
};
|
|
1377
|
+
|
|
1378
|
+
// src/client/WebhooksManager.ts
|
|
1379
|
+
var WebhooksManager = class {
|
|
1380
|
+
constructor(httpClient, local = false) {
|
|
1381
|
+
this.httpClient = httpClient;
|
|
1382
|
+
this.local = local;
|
|
1383
|
+
}
|
|
1384
|
+
ensureCloud(operation) {
|
|
1385
|
+
if (this.local) {
|
|
1386
|
+
throw new UnsupportedOperationError(
|
|
1387
|
+
`${operation} is not supported in local mode.`
|
|
1388
|
+
);
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
async createEndpoint(payload) {
|
|
1392
|
+
this.ensureCloud("Webhook endpoint creation");
|
|
1393
|
+
return this.httpClient.post(
|
|
1394
|
+
"/v1/webhooks/endpoints",
|
|
1395
|
+
payload,
|
|
1396
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1397
|
+
);
|
|
1398
|
+
}
|
|
1399
|
+
async listEndpoints() {
|
|
1400
|
+
this.ensureCloud("Webhook endpoint listing");
|
|
1401
|
+
return this.httpClient.get(
|
|
1402
|
+
"/v1/webhooks/endpoints",
|
|
1403
|
+
void 0,
|
|
1404
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1405
|
+
);
|
|
1406
|
+
}
|
|
1407
|
+
async getEndpoint(endpointId) {
|
|
1408
|
+
this.ensureCloud("Webhook endpoint lookup");
|
|
1409
|
+
const safeEndpointId = encodePathSegment(endpointId);
|
|
1410
|
+
return this.httpClient.get(
|
|
1411
|
+
`/v1/webhooks/endpoints/${safeEndpointId}`,
|
|
1412
|
+
void 0,
|
|
1413
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1414
|
+
);
|
|
1415
|
+
}
|
|
1416
|
+
async updateEndpoint(endpointId, payload) {
|
|
1417
|
+
this.ensureCloud("Webhook endpoint update");
|
|
1418
|
+
const safeEndpointId = encodePathSegment(endpointId);
|
|
1419
|
+
return this.httpClient.patch(
|
|
1420
|
+
`/v1/webhooks/endpoints/${safeEndpointId}`,
|
|
1421
|
+
payload,
|
|
1422
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1423
|
+
);
|
|
1424
|
+
}
|
|
1425
|
+
async deleteEndpoint(endpointId) {
|
|
1426
|
+
this.ensureCloud("Webhook endpoint deletion");
|
|
1427
|
+
const safeEndpointId = encodePathSegment(endpointId);
|
|
1428
|
+
return this.httpClient.delete(
|
|
1429
|
+
`/v1/webhooks/endpoints/${safeEndpointId}`,
|
|
1430
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1431
|
+
);
|
|
1432
|
+
}
|
|
1433
|
+
async rotateSecret(endpointId) {
|
|
1434
|
+
this.ensureCloud("Webhook secret rotation");
|
|
1435
|
+
const safeEndpointId = encodePathSegment(endpointId);
|
|
1436
|
+
return this.httpClient.post(
|
|
1437
|
+
`/v1/webhooks/endpoints/${safeEndpointId}/rotate-secret`,
|
|
1438
|
+
{},
|
|
1439
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1440
|
+
);
|
|
1441
|
+
}
|
|
1442
|
+
async sendTestEvent(endpointId) {
|
|
1443
|
+
this.ensureCloud("Webhook test event");
|
|
1444
|
+
const safeEndpointId = encodePathSegment(endpointId);
|
|
1445
|
+
return this.httpClient.post(
|
|
1446
|
+
`/v1/webhooks/endpoints/${safeEndpointId}/test`,
|
|
1447
|
+
{},
|
|
1448
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1449
|
+
);
|
|
1450
|
+
}
|
|
1451
|
+
async verifyEndpoint(endpointId) {
|
|
1452
|
+
this.ensureCloud("Webhook endpoint verification");
|
|
1453
|
+
const safeEndpointId = encodePathSegment(endpointId);
|
|
1454
|
+
return this.httpClient.post(
|
|
1455
|
+
`/v1/webhooks/endpoints/${safeEndpointId}/verify`,
|
|
1456
|
+
{},
|
|
1457
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1458
|
+
);
|
|
1459
|
+
}
|
|
1460
|
+
async listDeliveries(query = {}) {
|
|
1461
|
+
this.ensureCloud("Webhook delivery listing");
|
|
1462
|
+
return this.httpClient.get(
|
|
1463
|
+
"/v1/webhooks/deliveries",
|
|
1464
|
+
query,
|
|
1465
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1466
|
+
);
|
|
1467
|
+
}
|
|
1468
|
+
async replayDelivery(deliveryId) {
|
|
1469
|
+
this.ensureCloud("Webhook delivery replay");
|
|
1470
|
+
const safeDeliveryId = encodePathSegment(deliveryId);
|
|
1471
|
+
return this.httpClient.post(
|
|
1472
|
+
`/v1/webhooks/deliveries/${safeDeliveryId}/replay`,
|
|
1473
|
+
{},
|
|
1474
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1475
|
+
);
|
|
1476
|
+
}
|
|
1477
|
+
};
|
|
1478
|
+
|
|
928
1479
|
// src/client/InstaVM.ts
|
|
929
1480
|
var import_form_data = __toESM(require("form-data"));
|
|
930
1481
|
var InstaVM = class {
|
|
931
1482
|
constructor(apiKey, options = {}) {
|
|
932
1483
|
this._sessionId = null;
|
|
1484
|
+
this._vmUsed = false;
|
|
933
1485
|
this.local = options.local || false;
|
|
934
1486
|
this.timeout = options.timeout || 3e5;
|
|
1487
|
+
this.memory_mb = options.memory_mb;
|
|
1488
|
+
this.cpu_count = options.cpu_count;
|
|
1489
|
+
this.metadata = options.metadata;
|
|
1490
|
+
this.env = options.env;
|
|
935
1491
|
if (!this.local && !apiKey) {
|
|
936
1492
|
throw new AuthenticationError("API key is required for cloud mode");
|
|
937
1493
|
}
|
|
@@ -944,6 +1500,14 @@ var InstaVM = class {
|
|
|
944
1500
|
};
|
|
945
1501
|
this.httpClient = new HTTPClient(config);
|
|
946
1502
|
this.browser = new BrowserManager(this.httpClient, this.local);
|
|
1503
|
+
this.vms = new VMsManager(this.httpClient, this.local);
|
|
1504
|
+
this.snapshots = new SnapshotsManager(this.httpClient, this.local);
|
|
1505
|
+
this.shares = new SharesManager(this.httpClient, this.local, () => this._sessionId);
|
|
1506
|
+
this.customDomains = new CustomDomainsManager(this.httpClient, this.local);
|
|
1507
|
+
this.computerUse = new ComputerUseManager(this.httpClient, this.local);
|
|
1508
|
+
this.apiKeys = new APIKeysManager(this.httpClient, this.local);
|
|
1509
|
+
this.audit = new AuditManager(this.httpClient, this.local);
|
|
1510
|
+
this.webhooks = new WebhooksManager(this.httpClient, this.local);
|
|
947
1511
|
}
|
|
948
1512
|
/**
|
|
949
1513
|
* Ensure operation is not called in local mode
|
|
@@ -989,10 +1553,16 @@ var InstaVM = class {
|
|
|
989
1553
|
if (response.session_id) {
|
|
990
1554
|
this._sessionId = response.session_id;
|
|
991
1555
|
}
|
|
1556
|
+
if (!this.local) {
|
|
1557
|
+
this._vmUsed = true;
|
|
1558
|
+
}
|
|
992
1559
|
return {
|
|
993
|
-
|
|
1560
|
+
stdout: response.stdout || "",
|
|
1561
|
+
stderr: response.stderr || "",
|
|
994
1562
|
success: response.success !== false,
|
|
995
|
-
executionTime: response.execution_time
|
|
1563
|
+
executionTime: response.execution_time,
|
|
1564
|
+
cpuTime: response.cpu_time,
|
|
1565
|
+
createdAt: response.created_at,
|
|
996
1566
|
sessionId: response.session_id,
|
|
997
1567
|
error: response.error
|
|
998
1568
|
};
|
|
@@ -1029,6 +1599,7 @@ var InstaVM = class {
|
|
|
1029
1599
|
if (response.session_id) {
|
|
1030
1600
|
this._sessionId = response.session_id;
|
|
1031
1601
|
}
|
|
1602
|
+
this._vmUsed = true;
|
|
1032
1603
|
return {
|
|
1033
1604
|
taskId: response.task_id,
|
|
1034
1605
|
status: response.status || "pending",
|
|
@@ -1048,11 +1619,58 @@ var InstaVM = class {
|
|
|
1048
1619
|
);
|
|
1049
1620
|
}
|
|
1050
1621
|
}
|
|
1622
|
+
/**
|
|
1623
|
+
* Poll for async task result
|
|
1624
|
+
*
|
|
1625
|
+
* @param taskId - The task ID from executeAsync
|
|
1626
|
+
* @param pollInterval - Seconds between polls (default: 1)
|
|
1627
|
+
* @param timeout - Maximum seconds to wait (default: 60)
|
|
1628
|
+
* @returns Task result with stdout, stderr, execution time, etc.
|
|
1629
|
+
* @throws Error if task doesn't complete within timeout
|
|
1630
|
+
*/
|
|
1631
|
+
async getTaskResult(taskId, pollInterval = 1, timeout = 60) {
|
|
1632
|
+
this.ensureNotLocal("Async task result retrieval");
|
|
1633
|
+
const startTime = Date.now();
|
|
1634
|
+
while (Date.now() - startTime < timeout * 1e3) {
|
|
1635
|
+
try {
|
|
1636
|
+
const response = await this.httpClient.get(
|
|
1637
|
+
`/v1/executions/${taskId}`,
|
|
1638
|
+
void 0,
|
|
1639
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1640
|
+
);
|
|
1641
|
+
if (response.is_complete) {
|
|
1642
|
+
return {
|
|
1643
|
+
stdout: response.serialized_stdout || "",
|
|
1644
|
+
stderr: response.serialized_stderr || "",
|
|
1645
|
+
cpuTime: response.cpu_time,
|
|
1646
|
+
executionTime: response.execution_time,
|
|
1647
|
+
createdAt: response.created_at
|
|
1648
|
+
};
|
|
1649
|
+
}
|
|
1650
|
+
await new Promise((resolve) => setTimeout(resolve, pollInterval * 1e3));
|
|
1651
|
+
} catch (error) {
|
|
1652
|
+
if (error instanceof AuthenticationError || error instanceof RateLimitError || error instanceof NetworkError) {
|
|
1653
|
+
throw error;
|
|
1654
|
+
}
|
|
1655
|
+
if (Date.now() - startTime >= timeout * 1e3) {
|
|
1656
|
+
throw new ExecutionError(
|
|
1657
|
+
`Failed to get task result: ${error instanceof Error ? error.message : String(error)}`
|
|
1658
|
+
);
|
|
1659
|
+
}
|
|
1660
|
+
await new Promise((resolve) => setTimeout(resolve, pollInterval * 1e3));
|
|
1661
|
+
}
|
|
1662
|
+
}
|
|
1663
|
+
throw new ExecutionError(`Task ${taskId} timed out after ${timeout}s`);
|
|
1664
|
+
}
|
|
1051
1665
|
/**
|
|
1052
1666
|
* Upload files to the execution environment
|
|
1053
1667
|
*/
|
|
1054
1668
|
async upload(files, options = {}) {
|
|
1055
1669
|
this.ensureNotLocal("File upload");
|
|
1670
|
+
const sessionId = options.sessionId || this._sessionId;
|
|
1671
|
+
if (!sessionId) {
|
|
1672
|
+
throw new SessionError("Session ID not set. Please create a session first using createSession().");
|
|
1673
|
+
}
|
|
1056
1674
|
const formData = new import_form_data.default();
|
|
1057
1675
|
for (const file of files) {
|
|
1058
1676
|
if (Buffer.isBuffer(file.content)) {
|
|
@@ -1064,9 +1682,7 @@ var InstaVM = class {
|
|
|
1064
1682
|
formData.append("paths", file.path);
|
|
1065
1683
|
}
|
|
1066
1684
|
}
|
|
1067
|
-
|
|
1068
|
-
formData.append("session_id", options.sessionId || this._sessionId);
|
|
1069
|
-
}
|
|
1685
|
+
formData.append("session_id", sessionId);
|
|
1070
1686
|
if (options.remotePath) {
|
|
1071
1687
|
formData.append("remote_path", options.remotePath);
|
|
1072
1688
|
}
|
|
@@ -1097,10 +1713,26 @@ var InstaVM = class {
|
|
|
1097
1713
|
async createSession() {
|
|
1098
1714
|
this.ensureNotLocal("Session management");
|
|
1099
1715
|
try {
|
|
1100
|
-
const
|
|
1716
|
+
const requestBody = {
|
|
1101
1717
|
api_key: this.httpClient.apiKey,
|
|
1102
1718
|
vm_lifetime_seconds: Math.floor(this.timeout / 1e3)
|
|
1103
|
-
}
|
|
1719
|
+
};
|
|
1720
|
+
if (this.memory_mb !== void 0) {
|
|
1721
|
+
requestBody.memory_mb = this.memory_mb;
|
|
1722
|
+
}
|
|
1723
|
+
if (this.cpu_count !== void 0) {
|
|
1724
|
+
requestBody.vcpu_count = this.cpu_count;
|
|
1725
|
+
}
|
|
1726
|
+
if (this.metadata !== void 0) {
|
|
1727
|
+
requestBody.metadata = this.metadata;
|
|
1728
|
+
}
|
|
1729
|
+
if (this.env !== void 0) {
|
|
1730
|
+
requestBody.env = this.env;
|
|
1731
|
+
}
|
|
1732
|
+
const response = await this.httpClient.post(
|
|
1733
|
+
"/v1/sessions/session",
|
|
1734
|
+
requestBody
|
|
1735
|
+
);
|
|
1104
1736
|
if (response.session_id) {
|
|
1105
1737
|
this._sessionId = response.session_id;
|
|
1106
1738
|
return response.session_id;
|
|
@@ -1127,6 +1759,30 @@ var InstaVM = class {
|
|
|
1127
1759
|
this._sessionId = null;
|
|
1128
1760
|
}
|
|
1129
1761
|
}
|
|
1762
|
+
/**
|
|
1763
|
+
* Check if current session is still active by checking VM status
|
|
1764
|
+
*
|
|
1765
|
+
* @returns true if session is active, false otherwise
|
|
1766
|
+
*/
|
|
1767
|
+
async isSessionActive(sessionId) {
|
|
1768
|
+
const targetSessionId = sessionId || this._sessionId;
|
|
1769
|
+
if (!targetSessionId) {
|
|
1770
|
+
return false;
|
|
1771
|
+
}
|
|
1772
|
+
try {
|
|
1773
|
+
const response = await this.httpClient.get(
|
|
1774
|
+
`/v1/sessions/status/${targetSessionId}`,
|
|
1775
|
+
void 0,
|
|
1776
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1777
|
+
);
|
|
1778
|
+
return response.vm_status === "active";
|
|
1779
|
+
} catch (error) {
|
|
1780
|
+
if (error instanceof SessionError || error instanceof AuthenticationError || error instanceof NetworkError) {
|
|
1781
|
+
return false;
|
|
1782
|
+
}
|
|
1783
|
+
return false;
|
|
1784
|
+
}
|
|
1785
|
+
}
|
|
1130
1786
|
/**
|
|
1131
1787
|
* Get usage statistics for a session
|
|
1132
1788
|
*/
|
|
@@ -1190,11 +1846,185 @@ var InstaVM = class {
|
|
|
1190
1846
|
get sessionId() {
|
|
1191
1847
|
return this._sessionId;
|
|
1192
1848
|
}
|
|
1849
|
+
/**
|
|
1850
|
+
* Kill the VM associated with a session
|
|
1851
|
+
*
|
|
1852
|
+
* @param sessionId - The session UUID whose VM should be killed. If not provided, uses current sessionId
|
|
1853
|
+
* @returns Result containing success message and killed VM ID
|
|
1854
|
+
*/
|
|
1855
|
+
async kill(sessionId) {
|
|
1856
|
+
this.ensureNotLocal("VM kill operation");
|
|
1857
|
+
const targetSessionId = sessionId || this._sessionId;
|
|
1858
|
+
if (!targetSessionId) {
|
|
1859
|
+
throw new SessionError("Session ID not set. Please provide a sessionId or start a session first.");
|
|
1860
|
+
}
|
|
1861
|
+
try {
|
|
1862
|
+
const response = await this.httpClient.post(
|
|
1863
|
+
"/kill",
|
|
1864
|
+
{ session_id: targetSessionId },
|
|
1865
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1866
|
+
);
|
|
1867
|
+
if (!sessionId && this._sessionId === targetSessionId) {
|
|
1868
|
+
this._sessionId = null;
|
|
1869
|
+
}
|
|
1870
|
+
return response;
|
|
1871
|
+
} catch (error) {
|
|
1872
|
+
if (error instanceof Error && "statusCode" in error) {
|
|
1873
|
+
const statusCode = error.statusCode;
|
|
1874
|
+
if (statusCode === 403) {
|
|
1875
|
+
throw new AuthenticationError("You don't own this session", { cause: error });
|
|
1876
|
+
}
|
|
1877
|
+
if (statusCode === 404) {
|
|
1878
|
+
throw new SessionError("Session not found or no VM assigned to session (has execute() been called?)", { cause: error });
|
|
1879
|
+
}
|
|
1880
|
+
}
|
|
1881
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1882
|
+
throw new SessionError(
|
|
1883
|
+
`Failed to kill VM: ${errorMessage}`,
|
|
1884
|
+
{ cause: error }
|
|
1885
|
+
);
|
|
1886
|
+
}
|
|
1887
|
+
}
|
|
1888
|
+
// --- Egress Policy Methods ---
|
|
1889
|
+
/**
|
|
1890
|
+
* Set egress policy for a session
|
|
1891
|
+
*/
|
|
1892
|
+
async setSessionEgress(options = {}, sessionId) {
|
|
1893
|
+
this.ensureNotLocal("Egress policy management");
|
|
1894
|
+
const targetSessionId = sessionId || this._sessionId;
|
|
1895
|
+
if (!targetSessionId) {
|
|
1896
|
+
throw new SessionError("Session ID not set. Please create a session first.");
|
|
1897
|
+
}
|
|
1898
|
+
const response = await this.httpClient.post(
|
|
1899
|
+
`/v1/egress/session/${targetSessionId}`,
|
|
1900
|
+
{
|
|
1901
|
+
allow_public_repos: options.allowPackageManagers ?? true,
|
|
1902
|
+
allow_http: options.allowHttp ?? true,
|
|
1903
|
+
allow_https: options.allowHttps ?? true,
|
|
1904
|
+
allowed_domains: options.allowedDomains ?? [],
|
|
1905
|
+
allowed_cidrs: options.allowedCidrs ?? []
|
|
1906
|
+
},
|
|
1907
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1908
|
+
);
|
|
1909
|
+
return response;
|
|
1910
|
+
}
|
|
1911
|
+
/**
|
|
1912
|
+
* Get egress policy for a session
|
|
1913
|
+
*/
|
|
1914
|
+
async getSessionEgress(sessionId) {
|
|
1915
|
+
this.ensureNotLocal("Egress policy management");
|
|
1916
|
+
const targetSessionId = sessionId || this._sessionId;
|
|
1917
|
+
if (!targetSessionId) {
|
|
1918
|
+
throw new SessionError("Session ID not set. Please create a session first.");
|
|
1919
|
+
}
|
|
1920
|
+
const response = await this.httpClient.get(
|
|
1921
|
+
`/v1/egress/session/${targetSessionId}`,
|
|
1922
|
+
void 0,
|
|
1923
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1924
|
+
);
|
|
1925
|
+
return {
|
|
1926
|
+
allowPackageManagers: response.allow_public_repos,
|
|
1927
|
+
allowHttp: response.allow_http,
|
|
1928
|
+
allowHttps: response.allow_https,
|
|
1929
|
+
allowedDomains: response.allowed_domains || [],
|
|
1930
|
+
allowedCidrs: response.allowed_cidrs || []
|
|
1931
|
+
};
|
|
1932
|
+
}
|
|
1933
|
+
/**
|
|
1934
|
+
* Set egress policy for a specific VM
|
|
1935
|
+
*/
|
|
1936
|
+
async setVmEgress(vmId, options = {}) {
|
|
1937
|
+
this.ensureNotLocal("Egress policy management");
|
|
1938
|
+
const response = await this.httpClient.post(
|
|
1939
|
+
`/v1/egress/vm/${vmId}`,
|
|
1940
|
+
{
|
|
1941
|
+
allow_public_repos: options.allowPackageManagers ?? true,
|
|
1942
|
+
allow_http: options.allowHttp ?? true,
|
|
1943
|
+
allow_https: options.allowHttps ?? true,
|
|
1944
|
+
allowed_domains: options.allowedDomains ?? [],
|
|
1945
|
+
allowed_cidrs: options.allowedCidrs ?? []
|
|
1946
|
+
},
|
|
1947
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1948
|
+
);
|
|
1949
|
+
return response;
|
|
1950
|
+
}
|
|
1951
|
+
/**
|
|
1952
|
+
* Get egress policy for a specific VM
|
|
1953
|
+
*/
|
|
1954
|
+
async getVmEgress(vmId) {
|
|
1955
|
+
this.ensureNotLocal("Egress policy management");
|
|
1956
|
+
const response = await this.httpClient.get(
|
|
1957
|
+
`/v1/egress/vm/${vmId}`,
|
|
1958
|
+
void 0,
|
|
1959
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1960
|
+
);
|
|
1961
|
+
return {
|
|
1962
|
+
allowPackageManagers: response.allow_public_repos,
|
|
1963
|
+
allowHttp: response.allow_http,
|
|
1964
|
+
allowHttps: response.allow_https,
|
|
1965
|
+
allowedDomains: response.allowed_domains || [],
|
|
1966
|
+
allowedCidrs: response.allowed_cidrs || []
|
|
1967
|
+
};
|
|
1968
|
+
}
|
|
1969
|
+
// --- SSH Key Methods ---
|
|
1970
|
+
/**
|
|
1971
|
+
* Add an SSH public key
|
|
1972
|
+
*/
|
|
1973
|
+
async addSshKey(publicKey) {
|
|
1974
|
+
this.ensureNotLocal("SSH key management");
|
|
1975
|
+
const response = await this.httpClient.post(
|
|
1976
|
+
"/v1/ssh-keys",
|
|
1977
|
+
{ public_key: publicKey },
|
|
1978
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1979
|
+
);
|
|
1980
|
+
return {
|
|
1981
|
+
id: response.id,
|
|
1982
|
+
fingerprint: response.fingerprint,
|
|
1983
|
+
keyType: response.key_type,
|
|
1984
|
+
comment: response.comment ?? null,
|
|
1985
|
+
createdAt: response.created_at
|
|
1986
|
+
};
|
|
1987
|
+
}
|
|
1988
|
+
/**
|
|
1989
|
+
* List all active SSH keys
|
|
1990
|
+
*/
|
|
1991
|
+
async listSshKeys() {
|
|
1992
|
+
this.ensureNotLocal("SSH key management");
|
|
1993
|
+
const response = await this.httpClient.get(
|
|
1994
|
+
"/v1/ssh-keys",
|
|
1995
|
+
void 0,
|
|
1996
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1997
|
+
);
|
|
1998
|
+
const keys = response.keys || [];
|
|
1999
|
+
return keys.map((k) => ({
|
|
2000
|
+
id: k.id,
|
|
2001
|
+
fingerprint: k.fingerprint,
|
|
2002
|
+
keyType: k.key_type,
|
|
2003
|
+
comment: k.comment ?? null,
|
|
2004
|
+
createdAt: k.created_at
|
|
2005
|
+
}));
|
|
2006
|
+
}
|
|
2007
|
+
/**
|
|
2008
|
+
* Delete an SSH key by ID
|
|
2009
|
+
*/
|
|
2010
|
+
async deleteSshKey(keyId) {
|
|
2011
|
+
this.ensureNotLocal("SSH key management");
|
|
2012
|
+
const response = await this.httpClient.delete(
|
|
2013
|
+
`/v1/ssh-keys/${keyId}`,
|
|
2014
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
2015
|
+
);
|
|
2016
|
+
return response;
|
|
2017
|
+
}
|
|
1193
2018
|
/**
|
|
1194
2019
|
* Clean up resources
|
|
1195
2020
|
*/
|
|
1196
2021
|
async dispose() {
|
|
1197
|
-
if (this._sessionId) {
|
|
2022
|
+
if (this._sessionId && !this.local && this._vmUsed) {
|
|
2023
|
+
try {
|
|
2024
|
+
await this.kill();
|
|
2025
|
+
} catch (e) {
|
|
2026
|
+
}
|
|
2027
|
+
} else if (this._sessionId) {
|
|
1198
2028
|
await this.closeSession();
|
|
1199
2029
|
}
|
|
1200
2030
|
await this.browser.dispose();
|
|
@@ -1202,6 +2032,8 @@ var InstaVM = class {
|
|
|
1202
2032
|
};
|
|
1203
2033
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1204
2034
|
0 && (module.exports = {
|
|
2035
|
+
APIKeysManager,
|
|
2036
|
+
AuditManager,
|
|
1205
2037
|
AuthenticationError,
|
|
1206
2038
|
BrowserError,
|
|
1207
2039
|
BrowserInteractionError,
|
|
@@ -1210,6 +2042,8 @@ var InstaVM = class {
|
|
|
1210
2042
|
BrowserSession,
|
|
1211
2043
|
BrowserSessionError,
|
|
1212
2044
|
BrowserTimeoutError,
|
|
2045
|
+
ComputerUseManager,
|
|
2046
|
+
CustomDomainsManager,
|
|
1213
2047
|
ElementNotFoundError,
|
|
1214
2048
|
ExecutionError,
|
|
1215
2049
|
InstaVM,
|
|
@@ -1218,6 +2052,10 @@ var InstaVM = class {
|
|
|
1218
2052
|
QuotaExceededError,
|
|
1219
2053
|
RateLimitError,
|
|
1220
2054
|
SessionError,
|
|
1221
|
-
|
|
2055
|
+
SharesManager,
|
|
2056
|
+
SnapshotsManager,
|
|
2057
|
+
UnsupportedOperationError,
|
|
2058
|
+
VMsManager,
|
|
2059
|
+
WebhooksManager
|
|
1222
2060
|
});
|
|
1223
2061
|
//# sourceMappingURL=index.js.map
|