instavm 0.8.3 → 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/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
- UnsupportedOperationError: () => UnsupportedOperationError
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.1.0"
201
+ "User-Agent": "instavm-js-sdk/0.11.0"
194
202
  }
195
203
  });
196
204
  this.setupInterceptors();
@@ -362,6 +370,39 @@ var HTTPClient = class {
362
370
  headers
363
371
  });
364
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
+ }
365
406
  /**
366
407
  * POST request that returns raw binary data (for file downloads)
367
408
  */
@@ -928,13 +969,525 @@ var BrowserManager = class {
928
969
  }
929
970
  };
930
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
+
931
1479
  // src/client/InstaVM.ts
932
1480
  var import_form_data = __toESM(require("form-data"));
933
1481
  var InstaVM = class {
934
1482
  constructor(apiKey, options = {}) {
935
1483
  this._sessionId = null;
1484
+ this._vmUsed = false;
936
1485
  this.local = options.local || false;
937
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;
938
1491
  if (!this.local && !apiKey) {
939
1492
  throw new AuthenticationError("API key is required for cloud mode");
940
1493
  }
@@ -947,6 +1500,14 @@ var InstaVM = class {
947
1500
  };
948
1501
  this.httpClient = new HTTPClient(config);
949
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);
950
1511
  }
951
1512
  /**
952
1513
  * Ensure operation is not called in local mode
@@ -992,6 +1553,9 @@ var InstaVM = class {
992
1553
  if (response.session_id) {
993
1554
  this._sessionId = response.session_id;
994
1555
  }
1556
+ if (!this.local) {
1557
+ this._vmUsed = true;
1558
+ }
995
1559
  return {
996
1560
  stdout: response.stdout || "",
997
1561
  stderr: response.stderr || "",
@@ -1035,6 +1599,7 @@ var InstaVM = class {
1035
1599
  if (response.session_id) {
1036
1600
  this._sessionId = response.session_id;
1037
1601
  }
1602
+ this._vmUsed = true;
1038
1603
  return {
1039
1604
  taskId: response.task_id,
1040
1605
  status: response.status || "pending",
@@ -1148,10 +1713,26 @@ var InstaVM = class {
1148
1713
  async createSession() {
1149
1714
  this.ensureNotLocal("Session management");
1150
1715
  try {
1151
- const response = await this.httpClient.post("/v1/sessions/session", {
1716
+ const requestBody = {
1152
1717
  api_key: this.httpClient.apiKey,
1153
1718
  vm_lifetime_seconds: Math.floor(this.timeout / 1e3)
1154
- });
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
+ );
1155
1736
  if (response.session_id) {
1156
1737
  this._sessionId = response.session_id;
1157
1738
  return response.session_id;
@@ -1265,11 +1846,185 @@ var InstaVM = class {
1265
1846
  get sessionId() {
1266
1847
  return this._sessionId;
1267
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
+ }
1268
2018
  /**
1269
2019
  * Clean up resources
1270
2020
  */
1271
2021
  async dispose() {
1272
- 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) {
1273
2028
  await this.closeSession();
1274
2029
  }
1275
2030
  await this.browser.dispose();
@@ -1277,6 +2032,8 @@ var InstaVM = class {
1277
2032
  };
1278
2033
  // Annotate the CommonJS export names for ESM import in node:
1279
2034
  0 && (module.exports = {
2035
+ APIKeysManager,
2036
+ AuditManager,
1280
2037
  AuthenticationError,
1281
2038
  BrowserError,
1282
2039
  BrowserInteractionError,
@@ -1285,6 +2042,8 @@ var InstaVM = class {
1285
2042
  BrowserSession,
1286
2043
  BrowserSessionError,
1287
2044
  BrowserTimeoutError,
2045
+ ComputerUseManager,
2046
+ CustomDomainsManager,
1288
2047
  ElementNotFoundError,
1289
2048
  ExecutionError,
1290
2049
  InstaVM,
@@ -1293,6 +2052,10 @@ var InstaVM = class {
1293
2052
  QuotaExceededError,
1294
2053
  RateLimitError,
1295
2054
  SessionError,
1296
- UnsupportedOperationError
2055
+ SharesManager,
2056
+ SnapshotsManager,
2057
+ UnsupportedOperationError,
2058
+ VMsManager,
2059
+ WebhooksManager
1297
2060
  });
1298
2061
  //# sourceMappingURL=index.js.map