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.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.1.0"
142
+ "User-Agent": "instavm-js-sdk/0.11.0"
143
143
  }
144
144
  });
145
145
  this.setupInterceptors();
@@ -311,6 +311,39 @@ var HTTPClient = class {
311
311
  headers
312
312
  });
313
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
+ }
314
347
  /**
315
348
  * POST request that returns raw binary data (for file downloads)
316
349
  */
@@ -877,13 +910,525 @@ var BrowserManager = class {
877
910
  }
878
911
  };
879
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
+
880
1420
  // src/client/InstaVM.ts
881
1421
  import FormData from "form-data";
882
1422
  var InstaVM = class {
883
1423
  constructor(apiKey, options = {}) {
884
1424
  this._sessionId = null;
1425
+ this._vmUsed = false;
885
1426
  this.local = options.local || false;
886
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;
887
1432
  if (!this.local && !apiKey) {
888
1433
  throw new AuthenticationError("API key is required for cloud mode");
889
1434
  }
@@ -896,6 +1441,14 @@ var InstaVM = class {
896
1441
  };
897
1442
  this.httpClient = new HTTPClient(config);
898
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);
899
1452
  }
900
1453
  /**
901
1454
  * Ensure operation is not called in local mode
@@ -941,6 +1494,9 @@ var InstaVM = class {
941
1494
  if (response.session_id) {
942
1495
  this._sessionId = response.session_id;
943
1496
  }
1497
+ if (!this.local) {
1498
+ this._vmUsed = true;
1499
+ }
944
1500
  return {
945
1501
  stdout: response.stdout || "",
946
1502
  stderr: response.stderr || "",
@@ -984,6 +1540,7 @@ var InstaVM = class {
984
1540
  if (response.session_id) {
985
1541
  this._sessionId = response.session_id;
986
1542
  }
1543
+ this._vmUsed = true;
987
1544
  return {
988
1545
  taskId: response.task_id,
989
1546
  status: response.status || "pending",
@@ -1097,10 +1654,26 @@ var InstaVM = class {
1097
1654
  async createSession() {
1098
1655
  this.ensureNotLocal("Session management");
1099
1656
  try {
1100
- const response = await this.httpClient.post("/v1/sessions/session", {
1657
+ const requestBody = {
1101
1658
  api_key: this.httpClient.apiKey,
1102
1659
  vm_lifetime_seconds: Math.floor(this.timeout / 1e3)
1103
- });
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
+ );
1104
1677
  if (response.session_id) {
1105
1678
  this._sessionId = response.session_id;
1106
1679
  return response.session_id;
@@ -1214,17 +1787,193 @@ var InstaVM = class {
1214
1787
  get sessionId() {
1215
1788
  return this._sessionId;
1216
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
+ }
1217
1959
  /**
1218
1960
  * Clean up resources
1219
1961
  */
1220
1962
  async dispose() {
1221
- 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) {
1222
1969
  await this.closeSession();
1223
1970
  }
1224
1971
  await this.browser.dispose();
1225
1972
  }
1226
1973
  };
1227
1974
  export {
1975
+ APIKeysManager,
1976
+ AuditManager,
1228
1977
  AuthenticationError,
1229
1978
  BrowserError,
1230
1979
  BrowserInteractionError,
@@ -1233,6 +1982,8 @@ export {
1233
1982
  BrowserSession,
1234
1983
  BrowserSessionError,
1235
1984
  BrowserTimeoutError,
1985
+ ComputerUseManager,
1986
+ CustomDomainsManager,
1236
1987
  ElementNotFoundError,
1237
1988
  ExecutionError,
1238
1989
  InstaVM,
@@ -1241,6 +1992,10 @@ export {
1241
1992
  QuotaExceededError,
1242
1993
  RateLimitError,
1243
1994
  SessionError,
1244
- UnsupportedOperationError
1995
+ SharesManager,
1996
+ SnapshotsManager,
1997
+ UnsupportedOperationError,
1998
+ VMsManager,
1999
+ WebhooksManager
1245
2000
  };
1246
2001
  //# sourceMappingURL=index.mjs.map