instavm 0.8.3 → 0.13.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/LICENSE +21 -0
- package/README.md +285 -810
- package/dist/index.d.mts +436 -2
- package/dist/index.d.ts +436 -2
- package/dist/index.js +1024 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1014 -7
- package/dist/index.mjs.map +1 -1
- package/package.json +12 -7
package/dist/index.mjs
CHANGED
|
@@ -139,7 +139,7 @@ var HTTPClient = class {
|
|
|
139
139
|
timeout: config.timeout,
|
|
140
140
|
headers: {
|
|
141
141
|
"Content-Type": "application/json",
|
|
142
|
-
"User-Agent": "instavm-js-sdk/0.
|
|
142
|
+
"User-Agent": "instavm-js-sdk/0.12.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,732 @@ var BrowserManager = class {
|
|
|
877
910
|
}
|
|
878
911
|
};
|
|
879
912
|
|
|
880
|
-
// src/
|
|
913
|
+
// src/utils/path.ts
|
|
914
|
+
function encodePathSegment(value) {
|
|
915
|
+
const segment = String(value);
|
|
916
|
+
if (segment === "." || segment === "..") {
|
|
917
|
+
throw new Error("Path traversal not allowed in path segment");
|
|
918
|
+
}
|
|
919
|
+
return encodeURIComponent(segment);
|
|
920
|
+
}
|
|
921
|
+
function encodePathSegments(path2) {
|
|
922
|
+
const segments = path2.replace(/^\/+/, "").split("/").filter((segment) => segment.length > 0 && segment !== ".");
|
|
923
|
+
if (segments.some((segment) => segment === "..")) {
|
|
924
|
+
throw new Error("Path traversal not allowed in proxy path");
|
|
925
|
+
}
|
|
926
|
+
return segments.map((segment) => encodeURIComponent(segment)).join("/");
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
// src/client/VMsManager.ts
|
|
930
|
+
var VMsManager = class {
|
|
931
|
+
constructor(httpClient, local = false) {
|
|
932
|
+
this.httpClient = httpClient;
|
|
933
|
+
this.local = local;
|
|
934
|
+
}
|
|
935
|
+
ensureCloud(operation) {
|
|
936
|
+
if (this.local) {
|
|
937
|
+
throw new UnsupportedOperationError(
|
|
938
|
+
`${operation} is not supported in local mode.`
|
|
939
|
+
);
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
async create(payload = {}, wait = true) {
|
|
943
|
+
this.ensureCloud("VM creation");
|
|
944
|
+
return this.httpClient.request({
|
|
945
|
+
method: "POST",
|
|
946
|
+
url: "/v1/vms",
|
|
947
|
+
params: { wait },
|
|
948
|
+
data: payload,
|
|
949
|
+
headers: { "X-API-Key": this.httpClient.apiKey }
|
|
950
|
+
});
|
|
951
|
+
}
|
|
952
|
+
async list() {
|
|
953
|
+
this.ensureCloud("VM listing");
|
|
954
|
+
return this.httpClient.get(
|
|
955
|
+
"/v1/vms",
|
|
956
|
+
void 0,
|
|
957
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
958
|
+
);
|
|
959
|
+
}
|
|
960
|
+
async listAll() {
|
|
961
|
+
return this.listAllRecords();
|
|
962
|
+
}
|
|
963
|
+
/**
|
|
964
|
+
* Calls GET /v1/vms/ (trailing slash), a distinct route from GET /v1/vms.
|
|
965
|
+
*/
|
|
966
|
+
async listAllRecords() {
|
|
967
|
+
this.ensureCloud("VM listing");
|
|
968
|
+
return this.httpClient.get(
|
|
969
|
+
"/v1/vms/",
|
|
970
|
+
void 0,
|
|
971
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
972
|
+
);
|
|
973
|
+
}
|
|
974
|
+
async get(itemId) {
|
|
975
|
+
this.ensureCloud("VM lookup");
|
|
976
|
+
const safeItemId = encodePathSegment(itemId);
|
|
977
|
+
return this.httpClient.get(
|
|
978
|
+
`/v1/vms/${safeItemId}`,
|
|
979
|
+
void 0,
|
|
980
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
981
|
+
);
|
|
982
|
+
}
|
|
983
|
+
async update(vmId, payload = {}) {
|
|
984
|
+
this.ensureCloud("VM update");
|
|
985
|
+
const safeVmId = encodePathSegment(vmId);
|
|
986
|
+
return this.httpClient.patch(
|
|
987
|
+
`/v1/vms/${safeVmId}`,
|
|
988
|
+
payload,
|
|
989
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
990
|
+
);
|
|
991
|
+
}
|
|
992
|
+
async delete(vmId) {
|
|
993
|
+
this.ensureCloud("VM deletion");
|
|
994
|
+
const safeVmId = encodePathSegment(vmId);
|
|
995
|
+
return this.httpClient.delete(
|
|
996
|
+
`/v1/vms/${safeVmId}`,
|
|
997
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
998
|
+
);
|
|
999
|
+
}
|
|
1000
|
+
async clone(vmId, payload = {}, wait = true) {
|
|
1001
|
+
this.ensureCloud("VM clone");
|
|
1002
|
+
const safeVmId = encodePathSegment(vmId);
|
|
1003
|
+
return this.httpClient.request({
|
|
1004
|
+
method: "POST",
|
|
1005
|
+
url: `/v1/vms/${safeVmId}/clone`,
|
|
1006
|
+
params: { wait },
|
|
1007
|
+
data: payload,
|
|
1008
|
+
headers: { "X-API-Key": this.httpClient.apiKey }
|
|
1009
|
+
});
|
|
1010
|
+
}
|
|
1011
|
+
async snapshot(vmId, payload = {}, wait = true) {
|
|
1012
|
+
this.ensureCloud("VM snapshot");
|
|
1013
|
+
const safeVmId = encodePathSegment(vmId);
|
|
1014
|
+
return this.httpClient.request({
|
|
1015
|
+
method: "POST",
|
|
1016
|
+
url: `/v1/vms/${safeVmId}/snapshot`,
|
|
1017
|
+
params: { wait },
|
|
1018
|
+
data: payload,
|
|
1019
|
+
headers: { "X-API-Key": this.httpClient.apiKey }
|
|
1020
|
+
});
|
|
1021
|
+
}
|
|
1022
|
+
async mountVolume(vmId, payload, wait = true) {
|
|
1023
|
+
this.ensureCloud("VM volume mount");
|
|
1024
|
+
const safeVmId = encodePathSegment(vmId);
|
|
1025
|
+
return this.httpClient.request({
|
|
1026
|
+
method: "POST",
|
|
1027
|
+
url: `/v1/vms/${safeVmId}/volumes`,
|
|
1028
|
+
params: { wait },
|
|
1029
|
+
data: payload,
|
|
1030
|
+
headers: { "X-API-Key": this.httpClient.apiKey }
|
|
1031
|
+
});
|
|
1032
|
+
}
|
|
1033
|
+
async listVolumes(vmId) {
|
|
1034
|
+
this.ensureCloud("VM volume listing");
|
|
1035
|
+
const safeVmId = encodePathSegment(vmId);
|
|
1036
|
+
return this.httpClient.get(
|
|
1037
|
+
`/v1/vms/${safeVmId}/volumes`,
|
|
1038
|
+
void 0,
|
|
1039
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1040
|
+
);
|
|
1041
|
+
}
|
|
1042
|
+
async unmountVolume(vmId, volumeId, mountPath, wait = true) {
|
|
1043
|
+
this.ensureCloud("VM volume unmount");
|
|
1044
|
+
const safeVmId = encodePathSegment(vmId);
|
|
1045
|
+
const safeVolumeId = encodePathSegment(volumeId);
|
|
1046
|
+
return this.httpClient.request({
|
|
1047
|
+
method: "DELETE",
|
|
1048
|
+
url: `/v1/vms/${safeVmId}/volumes/${safeVolumeId}`,
|
|
1049
|
+
params: { mount_path: mountPath, wait },
|
|
1050
|
+
headers: { "X-API-Key": this.httpClient.apiKey }
|
|
1051
|
+
});
|
|
1052
|
+
}
|
|
1053
|
+
};
|
|
1054
|
+
|
|
1055
|
+
// src/client/SnapshotsManager.ts
|
|
1056
|
+
var SnapshotsManager = class {
|
|
1057
|
+
constructor(httpClient, local = false) {
|
|
1058
|
+
this.httpClient = httpClient;
|
|
1059
|
+
this.local = local;
|
|
1060
|
+
}
|
|
1061
|
+
ensureCloud(operation) {
|
|
1062
|
+
if (this.local) {
|
|
1063
|
+
throw new UnsupportedOperationError(
|
|
1064
|
+
`${operation} is not supported in local mode.`
|
|
1065
|
+
);
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
async create(payload) {
|
|
1069
|
+
this.ensureCloud("Snapshot creation");
|
|
1070
|
+
return this.httpClient.post(
|
|
1071
|
+
"/v1/snapshots",
|
|
1072
|
+
payload,
|
|
1073
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1074
|
+
);
|
|
1075
|
+
}
|
|
1076
|
+
async list(options = {}) {
|
|
1077
|
+
this.ensureCloud("Snapshot listing");
|
|
1078
|
+
return this.httpClient.get(
|
|
1079
|
+
"/v1/snapshots",
|
|
1080
|
+
options,
|
|
1081
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1082
|
+
);
|
|
1083
|
+
}
|
|
1084
|
+
async get(snapshotId) {
|
|
1085
|
+
this.ensureCloud("Snapshot lookup");
|
|
1086
|
+
const safeSnapshotId = encodePathSegment(snapshotId);
|
|
1087
|
+
return this.httpClient.get(
|
|
1088
|
+
`/v1/snapshots/${safeSnapshotId}`,
|
|
1089
|
+
void 0,
|
|
1090
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1091
|
+
);
|
|
1092
|
+
}
|
|
1093
|
+
async delete(snapshotId) {
|
|
1094
|
+
this.ensureCloud("Snapshot deletion");
|
|
1095
|
+
const safeSnapshotId = encodePathSegment(snapshotId);
|
|
1096
|
+
return this.httpClient.delete(
|
|
1097
|
+
`/v1/snapshots/${safeSnapshotId}`,
|
|
1098
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1099
|
+
);
|
|
1100
|
+
}
|
|
1101
|
+
};
|
|
1102
|
+
|
|
1103
|
+
// src/client/SharesManager.ts
|
|
1104
|
+
var SharesManager = class {
|
|
1105
|
+
constructor(httpClient, local = false, getSessionId = () => null) {
|
|
1106
|
+
this.httpClient = httpClient;
|
|
1107
|
+
this.local = local;
|
|
1108
|
+
this.getSessionId = getSessionId;
|
|
1109
|
+
}
|
|
1110
|
+
ensureCloud(operation) {
|
|
1111
|
+
if (this.local) {
|
|
1112
|
+
throw new UnsupportedOperationError(
|
|
1113
|
+
`${operation} is not supported in local mode.`
|
|
1114
|
+
);
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
async create(payload) {
|
|
1118
|
+
this.ensureCloud("Share creation");
|
|
1119
|
+
const body = { ...payload };
|
|
1120
|
+
if (!body.session_id && !body.vm_id) {
|
|
1121
|
+
const sid = this.getSessionId();
|
|
1122
|
+
if (!sid) {
|
|
1123
|
+
throw new SessionError(
|
|
1124
|
+
"Provide session_id/vm_id or create a session before creating a share."
|
|
1125
|
+
);
|
|
1126
|
+
}
|
|
1127
|
+
body.session_id = sid;
|
|
1128
|
+
}
|
|
1129
|
+
return this.httpClient.post(
|
|
1130
|
+
"/v1/shares",
|
|
1131
|
+
body,
|
|
1132
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1133
|
+
);
|
|
1134
|
+
}
|
|
1135
|
+
async update(shareId, payload) {
|
|
1136
|
+
this.ensureCloud("Share update");
|
|
1137
|
+
const safeShareId = encodePathSegment(shareId);
|
|
1138
|
+
return this.httpClient.patch(
|
|
1139
|
+
`/v1/shares/${safeShareId}`,
|
|
1140
|
+
payload,
|
|
1141
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1142
|
+
);
|
|
1143
|
+
}
|
|
1144
|
+
};
|
|
1145
|
+
|
|
1146
|
+
// src/client/CustomDomainsManager.ts
|
|
1147
|
+
var CustomDomainsManager = class {
|
|
1148
|
+
constructor(httpClient, local = false) {
|
|
1149
|
+
this.httpClient = httpClient;
|
|
1150
|
+
this.local = local;
|
|
1151
|
+
}
|
|
1152
|
+
ensureCloud(operation) {
|
|
1153
|
+
if (this.local) {
|
|
1154
|
+
throw new UnsupportedOperationError(
|
|
1155
|
+
`${operation} is not supported in local mode.`
|
|
1156
|
+
);
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
async create(payload) {
|
|
1160
|
+
this.ensureCloud("Custom domain creation");
|
|
1161
|
+
return this.httpClient.post(
|
|
1162
|
+
"/v1/custom-domains",
|
|
1163
|
+
payload,
|
|
1164
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1165
|
+
);
|
|
1166
|
+
}
|
|
1167
|
+
async list() {
|
|
1168
|
+
this.ensureCloud("Custom domain listing");
|
|
1169
|
+
return this.httpClient.get(
|
|
1170
|
+
"/v1/custom-domains",
|
|
1171
|
+
void 0,
|
|
1172
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1173
|
+
);
|
|
1174
|
+
}
|
|
1175
|
+
async health(domainId) {
|
|
1176
|
+
this.ensureCloud("Custom domain health");
|
|
1177
|
+
const safeDomainId = encodePathSegment(domainId);
|
|
1178
|
+
return this.httpClient.get(
|
|
1179
|
+
`/v1/custom-domains/${safeDomainId}/health`,
|
|
1180
|
+
void 0,
|
|
1181
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1182
|
+
);
|
|
1183
|
+
}
|
|
1184
|
+
async verify(domainId) {
|
|
1185
|
+
this.ensureCloud("Custom domain verification");
|
|
1186
|
+
const safeDomainId = encodePathSegment(domainId);
|
|
1187
|
+
return this.httpClient.post(
|
|
1188
|
+
`/v1/custom-domains/${safeDomainId}/verify`,
|
|
1189
|
+
{},
|
|
1190
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1191
|
+
);
|
|
1192
|
+
}
|
|
1193
|
+
async delete(domainId) {
|
|
1194
|
+
this.ensureCloud("Custom domain deletion");
|
|
1195
|
+
const safeDomainId = encodePathSegment(domainId);
|
|
1196
|
+
return this.httpClient.delete(
|
|
1197
|
+
`/v1/custom-domains/${safeDomainId}`,
|
|
1198
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1199
|
+
);
|
|
1200
|
+
}
|
|
1201
|
+
};
|
|
1202
|
+
|
|
1203
|
+
// src/client/ComputerUseManager.ts
|
|
1204
|
+
var ComputerUseManager = class {
|
|
1205
|
+
constructor(httpClient, local = false) {
|
|
1206
|
+
this.httpClient = httpClient;
|
|
1207
|
+
this.local = local;
|
|
1208
|
+
}
|
|
1209
|
+
ensureCloud(operation) {
|
|
1210
|
+
if (this.local) {
|
|
1211
|
+
throw new UnsupportedOperationError(
|
|
1212
|
+
`${operation} is not supported in local mode.`
|
|
1213
|
+
);
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
async viewerUrl(sessionId) {
|
|
1217
|
+
this.ensureCloud("Computer-use viewer URL");
|
|
1218
|
+
const safeSessionId = encodePathSegment(sessionId);
|
|
1219
|
+
return this.httpClient.get(
|
|
1220
|
+
`/v1/computeruse/${safeSessionId}/viewer-url`,
|
|
1221
|
+
void 0,
|
|
1222
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1223
|
+
);
|
|
1224
|
+
}
|
|
1225
|
+
async proxy(sessionId, path2, method = "GET", options = {}) {
|
|
1226
|
+
this.ensureCloud("Computer-use proxy");
|
|
1227
|
+
const safeSessionId = encodePathSegment(sessionId);
|
|
1228
|
+
const cleanPath = encodePathSegments(path2);
|
|
1229
|
+
return this.httpClient.request({
|
|
1230
|
+
method,
|
|
1231
|
+
url: `/v1/computeruse/${safeSessionId}/${cleanPath}`,
|
|
1232
|
+
params: options.params,
|
|
1233
|
+
data: options.body,
|
|
1234
|
+
headers: { "X-API-Key": this.httpClient.apiKey }
|
|
1235
|
+
});
|
|
1236
|
+
}
|
|
1237
|
+
async get(sessionId, path2, params) {
|
|
1238
|
+
return this.proxy(sessionId, path2, "GET", { params });
|
|
1239
|
+
}
|
|
1240
|
+
async post(sessionId, path2, body) {
|
|
1241
|
+
return this.proxy(sessionId, path2, "POST", { body });
|
|
1242
|
+
}
|
|
1243
|
+
async put(sessionId, path2, body) {
|
|
1244
|
+
return this.proxy(sessionId, path2, "PUT", { body });
|
|
1245
|
+
}
|
|
1246
|
+
async patch(sessionId, path2, body) {
|
|
1247
|
+
return this.proxy(sessionId, path2, "PATCH", { body });
|
|
1248
|
+
}
|
|
1249
|
+
async delete(sessionId, path2, params) {
|
|
1250
|
+
return this.proxy(sessionId, path2, "DELETE", { params });
|
|
1251
|
+
}
|
|
1252
|
+
async options(sessionId, path2, params) {
|
|
1253
|
+
return this.proxy(sessionId, path2, "OPTIONS", { params });
|
|
1254
|
+
}
|
|
1255
|
+
async head(sessionId, path2, params) {
|
|
1256
|
+
return this.proxy(sessionId, path2, "HEAD", { params });
|
|
1257
|
+
}
|
|
1258
|
+
/**
|
|
1259
|
+
* Get the VNC WebSocket URL for a computer-use session.
|
|
1260
|
+
* Returns the URL to connect to; the actual connection requires a WebSocket client.
|
|
1261
|
+
*/
|
|
1262
|
+
async vncWebsockify(sessionId) {
|
|
1263
|
+
this.ensureCloud("Computer-use VNC websockify");
|
|
1264
|
+
const safeSessionId = encodePathSegment(sessionId);
|
|
1265
|
+
return this.httpClient.get(
|
|
1266
|
+
`/v1/computeruse/${safeSessionId}/vnc/websockify`,
|
|
1267
|
+
void 0,
|
|
1268
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1269
|
+
);
|
|
1270
|
+
}
|
|
1271
|
+
};
|
|
1272
|
+
|
|
1273
|
+
// src/client/APIKeysManager.ts
|
|
1274
|
+
var APIKeysManager = class {
|
|
1275
|
+
constructor(httpClient, local = false) {
|
|
1276
|
+
this.httpClient = httpClient;
|
|
1277
|
+
this.local = local;
|
|
1278
|
+
}
|
|
1279
|
+
ensureCloud(operation) {
|
|
1280
|
+
if (this.local) {
|
|
1281
|
+
throw new UnsupportedOperationError(
|
|
1282
|
+
`${operation} is not supported in local mode.`
|
|
1283
|
+
);
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
async create(payload = {}) {
|
|
1287
|
+
this.ensureCloud("API key creation");
|
|
1288
|
+
return this.httpClient.post(
|
|
1289
|
+
"/v1/api-keys/",
|
|
1290
|
+
payload,
|
|
1291
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1292
|
+
);
|
|
1293
|
+
}
|
|
1294
|
+
async list() {
|
|
1295
|
+
this.ensureCloud("API key listing");
|
|
1296
|
+
return this.httpClient.get(
|
|
1297
|
+
"/v1/api-keys/",
|
|
1298
|
+
void 0,
|
|
1299
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1300
|
+
);
|
|
1301
|
+
}
|
|
1302
|
+
async get(itemId) {
|
|
1303
|
+
this.ensureCloud("API key lookup");
|
|
1304
|
+
const safeItemId = encodePathSegment(itemId);
|
|
1305
|
+
return this.httpClient.get(
|
|
1306
|
+
`/v1/api-keys/${safeItemId}`,
|
|
1307
|
+
void 0,
|
|
1308
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1309
|
+
);
|
|
1310
|
+
}
|
|
1311
|
+
async update(itemId, payload) {
|
|
1312
|
+
this.ensureCloud("API key update");
|
|
1313
|
+
const safeItemId = encodePathSegment(itemId);
|
|
1314
|
+
return this.httpClient.patch(
|
|
1315
|
+
`/v1/api-keys/${safeItemId}`,
|
|
1316
|
+
payload,
|
|
1317
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1318
|
+
);
|
|
1319
|
+
}
|
|
1320
|
+
async delete(itemId) {
|
|
1321
|
+
this.ensureCloud("API key deletion");
|
|
1322
|
+
const safeItemId = encodePathSegment(itemId);
|
|
1323
|
+
return this.httpClient.delete(
|
|
1324
|
+
`/v1/api-keys/${safeItemId}`,
|
|
1325
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1326
|
+
);
|
|
1327
|
+
}
|
|
1328
|
+
};
|
|
1329
|
+
|
|
1330
|
+
// src/client/AuditManager.ts
|
|
1331
|
+
var AuditManager = class {
|
|
1332
|
+
constructor(httpClient, local = false) {
|
|
1333
|
+
this.httpClient = httpClient;
|
|
1334
|
+
this.local = local;
|
|
1335
|
+
}
|
|
1336
|
+
ensureCloud(operation) {
|
|
1337
|
+
if (this.local) {
|
|
1338
|
+
throw new UnsupportedOperationError(
|
|
1339
|
+
`${operation} is not supported in local mode.`
|
|
1340
|
+
);
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
async catalog() {
|
|
1344
|
+
this.ensureCloud("Audit catalog");
|
|
1345
|
+
return this.httpClient.get(
|
|
1346
|
+
"/v1/audit/catalog",
|
|
1347
|
+
void 0,
|
|
1348
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1349
|
+
);
|
|
1350
|
+
}
|
|
1351
|
+
async events(query = {}) {
|
|
1352
|
+
this.ensureCloud("Audit event listing");
|
|
1353
|
+
return this.httpClient.get(
|
|
1354
|
+
"/v1/audit/events",
|
|
1355
|
+
query,
|
|
1356
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1357
|
+
);
|
|
1358
|
+
}
|
|
1359
|
+
async getEvent(eventId) {
|
|
1360
|
+
this.ensureCloud("Audit event lookup");
|
|
1361
|
+
const safeEventId = encodePathSegment(eventId);
|
|
1362
|
+
return this.httpClient.get(
|
|
1363
|
+
`/v1/audit/events/${safeEventId}`,
|
|
1364
|
+
void 0,
|
|
1365
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1366
|
+
);
|
|
1367
|
+
}
|
|
1368
|
+
};
|
|
1369
|
+
|
|
1370
|
+
// src/client/WebhooksManager.ts
|
|
1371
|
+
var WebhooksManager = class {
|
|
1372
|
+
constructor(httpClient, local = false) {
|
|
1373
|
+
this.httpClient = httpClient;
|
|
1374
|
+
this.local = local;
|
|
1375
|
+
}
|
|
1376
|
+
ensureCloud(operation) {
|
|
1377
|
+
if (this.local) {
|
|
1378
|
+
throw new UnsupportedOperationError(
|
|
1379
|
+
`${operation} is not supported in local mode.`
|
|
1380
|
+
);
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1383
|
+
async createEndpoint(payload) {
|
|
1384
|
+
this.ensureCloud("Webhook endpoint creation");
|
|
1385
|
+
return this.httpClient.post(
|
|
1386
|
+
"/v1/webhooks/endpoints",
|
|
1387
|
+
payload,
|
|
1388
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1389
|
+
);
|
|
1390
|
+
}
|
|
1391
|
+
async listEndpoints() {
|
|
1392
|
+
this.ensureCloud("Webhook endpoint listing");
|
|
1393
|
+
return this.httpClient.get(
|
|
1394
|
+
"/v1/webhooks/endpoints",
|
|
1395
|
+
void 0,
|
|
1396
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1397
|
+
);
|
|
1398
|
+
}
|
|
1399
|
+
async getEndpoint(endpointId) {
|
|
1400
|
+
this.ensureCloud("Webhook endpoint lookup");
|
|
1401
|
+
const safeEndpointId = encodePathSegment(endpointId);
|
|
1402
|
+
return this.httpClient.get(
|
|
1403
|
+
`/v1/webhooks/endpoints/${safeEndpointId}`,
|
|
1404
|
+
void 0,
|
|
1405
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1406
|
+
);
|
|
1407
|
+
}
|
|
1408
|
+
async updateEndpoint(endpointId, payload) {
|
|
1409
|
+
this.ensureCloud("Webhook endpoint update");
|
|
1410
|
+
const safeEndpointId = encodePathSegment(endpointId);
|
|
1411
|
+
return this.httpClient.patch(
|
|
1412
|
+
`/v1/webhooks/endpoints/${safeEndpointId}`,
|
|
1413
|
+
payload,
|
|
1414
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1415
|
+
);
|
|
1416
|
+
}
|
|
1417
|
+
async deleteEndpoint(endpointId) {
|
|
1418
|
+
this.ensureCloud("Webhook endpoint deletion");
|
|
1419
|
+
const safeEndpointId = encodePathSegment(endpointId);
|
|
1420
|
+
return this.httpClient.delete(
|
|
1421
|
+
`/v1/webhooks/endpoints/${safeEndpointId}`,
|
|
1422
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1423
|
+
);
|
|
1424
|
+
}
|
|
1425
|
+
async rotateSecret(endpointId) {
|
|
1426
|
+
this.ensureCloud("Webhook secret rotation");
|
|
1427
|
+
const safeEndpointId = encodePathSegment(endpointId);
|
|
1428
|
+
return this.httpClient.post(
|
|
1429
|
+
`/v1/webhooks/endpoints/${safeEndpointId}/rotate-secret`,
|
|
1430
|
+
{},
|
|
1431
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1432
|
+
);
|
|
1433
|
+
}
|
|
1434
|
+
async sendTestEvent(endpointId) {
|
|
1435
|
+
this.ensureCloud("Webhook test event");
|
|
1436
|
+
const safeEndpointId = encodePathSegment(endpointId);
|
|
1437
|
+
return this.httpClient.post(
|
|
1438
|
+
`/v1/webhooks/endpoints/${safeEndpointId}/test`,
|
|
1439
|
+
{},
|
|
1440
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1441
|
+
);
|
|
1442
|
+
}
|
|
1443
|
+
async verifyEndpoint(endpointId) {
|
|
1444
|
+
this.ensureCloud("Webhook endpoint verification");
|
|
1445
|
+
const safeEndpointId = encodePathSegment(endpointId);
|
|
1446
|
+
return this.httpClient.post(
|
|
1447
|
+
`/v1/webhooks/endpoints/${safeEndpointId}/verify`,
|
|
1448
|
+
{},
|
|
1449
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1450
|
+
);
|
|
1451
|
+
}
|
|
1452
|
+
async listDeliveries(query = {}) {
|
|
1453
|
+
this.ensureCloud("Webhook delivery listing");
|
|
1454
|
+
return this.httpClient.get(
|
|
1455
|
+
"/v1/webhooks/deliveries",
|
|
1456
|
+
query,
|
|
1457
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1458
|
+
);
|
|
1459
|
+
}
|
|
1460
|
+
async replayDelivery(deliveryId) {
|
|
1461
|
+
this.ensureCloud("Webhook delivery replay");
|
|
1462
|
+
const safeDeliveryId = encodePathSegment(deliveryId);
|
|
1463
|
+
return this.httpClient.post(
|
|
1464
|
+
`/v1/webhooks/deliveries/${safeDeliveryId}/replay`,
|
|
1465
|
+
{},
|
|
1466
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1467
|
+
);
|
|
1468
|
+
}
|
|
1469
|
+
};
|
|
1470
|
+
|
|
1471
|
+
// src/client/VolumesManager.ts
|
|
1472
|
+
import fs from "fs";
|
|
1473
|
+
import path from "path";
|
|
881
1474
|
import FormData from "form-data";
|
|
1475
|
+
var VolumesManager = class {
|
|
1476
|
+
constructor(httpClient, local = false) {
|
|
1477
|
+
this.httpClient = httpClient;
|
|
1478
|
+
this.local = local;
|
|
1479
|
+
}
|
|
1480
|
+
ensureCloud(operation) {
|
|
1481
|
+
if (this.local) {
|
|
1482
|
+
throw new UnsupportedOperationError(
|
|
1483
|
+
`${operation} is not supported in local mode.`
|
|
1484
|
+
);
|
|
1485
|
+
}
|
|
1486
|
+
}
|
|
1487
|
+
async create(payload) {
|
|
1488
|
+
this.ensureCloud("Volume creation");
|
|
1489
|
+
return this.httpClient.post(
|
|
1490
|
+
"/v1/volumes",
|
|
1491
|
+
payload,
|
|
1492
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1493
|
+
);
|
|
1494
|
+
}
|
|
1495
|
+
async list(refreshUsage = false) {
|
|
1496
|
+
this.ensureCloud("Volume listing");
|
|
1497
|
+
return this.httpClient.get(
|
|
1498
|
+
"/v1/volumes",
|
|
1499
|
+
{ refresh_usage: refreshUsage },
|
|
1500
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1501
|
+
);
|
|
1502
|
+
}
|
|
1503
|
+
async get(volumeId, refreshUsage = false) {
|
|
1504
|
+
this.ensureCloud("Volume lookup");
|
|
1505
|
+
const safeVolumeId = encodePathSegment(volumeId);
|
|
1506
|
+
return this.httpClient.get(
|
|
1507
|
+
`/v1/volumes/${safeVolumeId}`,
|
|
1508
|
+
{ refresh_usage: refreshUsage },
|
|
1509
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1510
|
+
);
|
|
1511
|
+
}
|
|
1512
|
+
async update(volumeId, payload) {
|
|
1513
|
+
this.ensureCloud("Volume update");
|
|
1514
|
+
const safeVolumeId = encodePathSegment(volumeId);
|
|
1515
|
+
return this.httpClient.patch(
|
|
1516
|
+
`/v1/volumes/${safeVolumeId}`,
|
|
1517
|
+
payload,
|
|
1518
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1519
|
+
);
|
|
1520
|
+
}
|
|
1521
|
+
async delete(volumeId) {
|
|
1522
|
+
this.ensureCloud("Volume deletion");
|
|
1523
|
+
const safeVolumeId = encodePathSegment(volumeId);
|
|
1524
|
+
return this.httpClient.delete(
|
|
1525
|
+
`/v1/volumes/${safeVolumeId}`,
|
|
1526
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1527
|
+
);
|
|
1528
|
+
}
|
|
1529
|
+
async createCheckpoint(volumeId, payload = {}) {
|
|
1530
|
+
this.ensureCloud("Volume checkpoint creation");
|
|
1531
|
+
const safeVolumeId = encodePathSegment(volumeId);
|
|
1532
|
+
return this.httpClient.post(
|
|
1533
|
+
`/v1/volumes/${safeVolumeId}/checkpoints`,
|
|
1534
|
+
payload,
|
|
1535
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1536
|
+
);
|
|
1537
|
+
}
|
|
1538
|
+
async listCheckpoints(volumeId) {
|
|
1539
|
+
this.ensureCloud("Volume checkpoint listing");
|
|
1540
|
+
const safeVolumeId = encodePathSegment(volumeId);
|
|
1541
|
+
return this.httpClient.get(
|
|
1542
|
+
`/v1/volumes/${safeVolumeId}/checkpoints`,
|
|
1543
|
+
void 0,
|
|
1544
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1545
|
+
);
|
|
1546
|
+
}
|
|
1547
|
+
async deleteCheckpoint(volumeId, checkpointId) {
|
|
1548
|
+
this.ensureCloud("Volume checkpoint deletion");
|
|
1549
|
+
const safeVolumeId = encodePathSegment(volumeId);
|
|
1550
|
+
const safeCheckpointId = encodePathSegment(checkpointId);
|
|
1551
|
+
return this.httpClient.delete(
|
|
1552
|
+
`/v1/volumes/${safeVolumeId}/checkpoints/${safeCheckpointId}`,
|
|
1553
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1554
|
+
);
|
|
1555
|
+
}
|
|
1556
|
+
async uploadFile(volumeId, payload) {
|
|
1557
|
+
this.ensureCloud("Volume file upload");
|
|
1558
|
+
if (!payload.path || payload.path.trim().length === 0) {
|
|
1559
|
+
throw new Error("payload.path is required");
|
|
1560
|
+
}
|
|
1561
|
+
const hasFilePath = typeof payload.filePath === "string" && payload.filePath.length > 0;
|
|
1562
|
+
const hasFileContent = payload.fileContent !== void 0;
|
|
1563
|
+
if (hasFilePath === hasFileContent) {
|
|
1564
|
+
throw new Error("Provide exactly one of payload.filePath or payload.fileContent");
|
|
1565
|
+
}
|
|
1566
|
+
const safeVolumeId = encodePathSegment(volumeId);
|
|
1567
|
+
const formData = new FormData();
|
|
1568
|
+
if (hasFilePath) {
|
|
1569
|
+
const sourcePath = payload.filePath;
|
|
1570
|
+
const filename = payload.filename || path.basename(sourcePath);
|
|
1571
|
+
formData.append("file", fs.createReadStream(sourcePath), { filename });
|
|
1572
|
+
} else {
|
|
1573
|
+
const filename = payload.filename || "upload.bin";
|
|
1574
|
+
const raw = payload.fileContent;
|
|
1575
|
+
const buffer = Buffer.isBuffer(raw) ? raw : Buffer.from(raw);
|
|
1576
|
+
formData.append("file", buffer, { filename });
|
|
1577
|
+
}
|
|
1578
|
+
formData.append("path", payload.path);
|
|
1579
|
+
if (payload.overwrite !== void 0) {
|
|
1580
|
+
formData.append("overwrite", String(payload.overwrite));
|
|
1581
|
+
}
|
|
1582
|
+
return this.httpClient.postFormData(
|
|
1583
|
+
`/v1/volumes/${safeVolumeId}/files/upload`,
|
|
1584
|
+
formData
|
|
1585
|
+
);
|
|
1586
|
+
}
|
|
1587
|
+
async downloadFile(volumeId, path2) {
|
|
1588
|
+
this.ensureCloud("Volume file download");
|
|
1589
|
+
const safeVolumeId = encodePathSegment(volumeId);
|
|
1590
|
+
const response = await this.httpClient.post(
|
|
1591
|
+
`/v1/volumes/${safeVolumeId}/files/download`,
|
|
1592
|
+
{ path: path2 },
|
|
1593
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1594
|
+
);
|
|
1595
|
+
return {
|
|
1596
|
+
path: response.path,
|
|
1597
|
+
filename: response.filename,
|
|
1598
|
+
size: response.size,
|
|
1599
|
+
content: Buffer.from(response.content || "", "base64")
|
|
1600
|
+
};
|
|
1601
|
+
}
|
|
1602
|
+
async listFiles(volumeId, options = {}) {
|
|
1603
|
+
this.ensureCloud("Volume file listing");
|
|
1604
|
+
const safeVolumeId = encodePathSegment(volumeId);
|
|
1605
|
+
return this.httpClient.get(
|
|
1606
|
+
`/v1/volumes/${safeVolumeId}/files`,
|
|
1607
|
+
{
|
|
1608
|
+
prefix: options.prefix ?? "",
|
|
1609
|
+
recursive: options.recursive ?? true,
|
|
1610
|
+
limit: options.limit ?? 1e3
|
|
1611
|
+
},
|
|
1612
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1613
|
+
);
|
|
1614
|
+
}
|
|
1615
|
+
async deleteFile(volumeId, targetPath) {
|
|
1616
|
+
this.ensureCloud("Volume file deletion");
|
|
1617
|
+
const safeVolumeId = encodePathSegment(volumeId);
|
|
1618
|
+
return this.httpClient.request({
|
|
1619
|
+
method: "DELETE",
|
|
1620
|
+
url: `/v1/volumes/${safeVolumeId}/files`,
|
|
1621
|
+
params: { path: targetPath },
|
|
1622
|
+
headers: { "X-API-Key": this.httpClient.apiKey }
|
|
1623
|
+
});
|
|
1624
|
+
}
|
|
1625
|
+
};
|
|
1626
|
+
|
|
1627
|
+
// src/client/InstaVM.ts
|
|
1628
|
+
import FormData2 from "form-data";
|
|
882
1629
|
var InstaVM = class {
|
|
883
1630
|
constructor(apiKey, options = {}) {
|
|
884
1631
|
this._sessionId = null;
|
|
1632
|
+
this._vmUsed = false;
|
|
885
1633
|
this.local = options.local || false;
|
|
886
1634
|
this.timeout = options.timeout || 3e5;
|
|
1635
|
+
this.memory_mb = options.memory_mb;
|
|
1636
|
+
this.cpu_count = options.cpu_count;
|
|
1637
|
+
this.metadata = options.metadata;
|
|
1638
|
+
this.env = options.env;
|
|
887
1639
|
if (!this.local && !apiKey) {
|
|
888
1640
|
throw new AuthenticationError("API key is required for cloud mode");
|
|
889
1641
|
}
|
|
@@ -896,6 +1648,15 @@ var InstaVM = class {
|
|
|
896
1648
|
};
|
|
897
1649
|
this.httpClient = new HTTPClient(config);
|
|
898
1650
|
this.browser = new BrowserManager(this.httpClient, this.local);
|
|
1651
|
+
this.vms = new VMsManager(this.httpClient, this.local);
|
|
1652
|
+
this.snapshots = new SnapshotsManager(this.httpClient, this.local);
|
|
1653
|
+
this.shares = new SharesManager(this.httpClient, this.local, () => this._sessionId);
|
|
1654
|
+
this.customDomains = new CustomDomainsManager(this.httpClient, this.local);
|
|
1655
|
+
this.computerUse = new ComputerUseManager(this.httpClient, this.local);
|
|
1656
|
+
this.apiKeys = new APIKeysManager(this.httpClient, this.local);
|
|
1657
|
+
this.audit = new AuditManager(this.httpClient, this.local);
|
|
1658
|
+
this.webhooks = new WebhooksManager(this.httpClient, this.local);
|
|
1659
|
+
this.volumes = new VolumesManager(this.httpClient, this.local);
|
|
899
1660
|
}
|
|
900
1661
|
/**
|
|
901
1662
|
* Ensure operation is not called in local mode
|
|
@@ -941,6 +1702,9 @@ var InstaVM = class {
|
|
|
941
1702
|
if (response.session_id) {
|
|
942
1703
|
this._sessionId = response.session_id;
|
|
943
1704
|
}
|
|
1705
|
+
if (!this.local) {
|
|
1706
|
+
this._vmUsed = true;
|
|
1707
|
+
}
|
|
944
1708
|
return {
|
|
945
1709
|
stdout: response.stdout || "",
|
|
946
1710
|
stderr: response.stderr || "",
|
|
@@ -984,6 +1748,7 @@ var InstaVM = class {
|
|
|
984
1748
|
if (response.session_id) {
|
|
985
1749
|
this._sessionId = response.session_id;
|
|
986
1750
|
}
|
|
1751
|
+
this._vmUsed = true;
|
|
987
1752
|
return {
|
|
988
1753
|
taskId: response.task_id,
|
|
989
1754
|
status: response.status || "pending",
|
|
@@ -1055,7 +1820,7 @@ var InstaVM = class {
|
|
|
1055
1820
|
if (!sessionId) {
|
|
1056
1821
|
throw new SessionError("Session ID not set. Please create a session first using createSession().");
|
|
1057
1822
|
}
|
|
1058
|
-
const formData = new
|
|
1823
|
+
const formData = new FormData2();
|
|
1059
1824
|
for (const file of files) {
|
|
1060
1825
|
if (Buffer.isBuffer(file.content)) {
|
|
1061
1826
|
formData.append("files", file.content, file.name);
|
|
@@ -1097,10 +1862,26 @@ var InstaVM = class {
|
|
|
1097
1862
|
async createSession() {
|
|
1098
1863
|
this.ensureNotLocal("Session management");
|
|
1099
1864
|
try {
|
|
1100
|
-
const
|
|
1865
|
+
const requestBody = {
|
|
1101
1866
|
api_key: this.httpClient.apiKey,
|
|
1102
1867
|
vm_lifetime_seconds: Math.floor(this.timeout / 1e3)
|
|
1103
|
-
}
|
|
1868
|
+
};
|
|
1869
|
+
if (this.memory_mb !== void 0) {
|
|
1870
|
+
requestBody.memory_mb = this.memory_mb;
|
|
1871
|
+
}
|
|
1872
|
+
if (this.cpu_count !== void 0) {
|
|
1873
|
+
requestBody.vcpu_count = this.cpu_count;
|
|
1874
|
+
}
|
|
1875
|
+
if (this.metadata !== void 0) {
|
|
1876
|
+
requestBody.metadata = this.metadata;
|
|
1877
|
+
}
|
|
1878
|
+
if (this.env !== void 0) {
|
|
1879
|
+
requestBody.env = this.env;
|
|
1880
|
+
}
|
|
1881
|
+
const response = await this.httpClient.post(
|
|
1882
|
+
"/v1/sessions/session",
|
|
1883
|
+
requestBody
|
|
1884
|
+
);
|
|
1104
1885
|
if (response.session_id) {
|
|
1105
1886
|
this._sessionId = response.session_id;
|
|
1106
1887
|
return response.session_id;
|
|
@@ -1151,6 +1932,49 @@ var InstaVM = class {
|
|
|
1151
1932
|
return false;
|
|
1152
1933
|
}
|
|
1153
1934
|
}
|
|
1935
|
+
/**
|
|
1936
|
+
* Get the app URL for a session
|
|
1937
|
+
*
|
|
1938
|
+
* @param sessionId - Session ID (uses current session if not provided)
|
|
1939
|
+
* @param port - Port to expose (1-65535, default: 80)
|
|
1940
|
+
*/
|
|
1941
|
+
async getSessionAppUrl(sessionId, port) {
|
|
1942
|
+
this.ensureNotLocal("Session app URL");
|
|
1943
|
+
const targetSessionId = sessionId || this._sessionId;
|
|
1944
|
+
if (!targetSessionId) {
|
|
1945
|
+
throw new SessionError("Session ID not set. Please create a session first.");
|
|
1946
|
+
}
|
|
1947
|
+
const params = {};
|
|
1948
|
+
if (port !== void 0) {
|
|
1949
|
+
params.port = port;
|
|
1950
|
+
}
|
|
1951
|
+
return this.httpClient.get(
|
|
1952
|
+
`/v1/sessions/app-url/${targetSessionId}`,
|
|
1953
|
+
params,
|
|
1954
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1955
|
+
);
|
|
1956
|
+
}
|
|
1957
|
+
/**
|
|
1958
|
+
* List sandbox records with optional filtering
|
|
1959
|
+
*
|
|
1960
|
+
* @param options.metadata - JSON-serializable metadata filters
|
|
1961
|
+
* @param options.limit - Maximum number of results (1-1000, default: 100)
|
|
1962
|
+
*/
|
|
1963
|
+
async listSandboxes(options = {}) {
|
|
1964
|
+
this.ensureNotLocal("Sandbox listing");
|
|
1965
|
+
const params = {};
|
|
1966
|
+
if (options.metadata !== void 0) {
|
|
1967
|
+
params.metadata = JSON.stringify(options.metadata);
|
|
1968
|
+
}
|
|
1969
|
+
if (options.limit !== void 0) {
|
|
1970
|
+
params.limit = options.limit;
|
|
1971
|
+
}
|
|
1972
|
+
return this.httpClient.get(
|
|
1973
|
+
"/v1/sessions/sandboxes",
|
|
1974
|
+
params,
|
|
1975
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1976
|
+
);
|
|
1977
|
+
}
|
|
1154
1978
|
/**
|
|
1155
1979
|
* Get usage statistics for a session
|
|
1156
1980
|
*/
|
|
@@ -1214,17 +2038,193 @@ var InstaVM = class {
|
|
|
1214
2038
|
get sessionId() {
|
|
1215
2039
|
return this._sessionId;
|
|
1216
2040
|
}
|
|
2041
|
+
/**
|
|
2042
|
+
* Kill the VM associated with a session
|
|
2043
|
+
*
|
|
2044
|
+
* @param sessionId - The session UUID whose VM should be killed. If not provided, uses current sessionId
|
|
2045
|
+
* @returns Result containing success message and killed VM ID
|
|
2046
|
+
*/
|
|
2047
|
+
async kill(sessionId) {
|
|
2048
|
+
this.ensureNotLocal("VM kill operation");
|
|
2049
|
+
const targetSessionId = sessionId || this._sessionId;
|
|
2050
|
+
if (!targetSessionId) {
|
|
2051
|
+
throw new SessionError("Session ID not set. Please provide a sessionId or start a session first.");
|
|
2052
|
+
}
|
|
2053
|
+
try {
|
|
2054
|
+
const response = await this.httpClient.post(
|
|
2055
|
+
"/kill",
|
|
2056
|
+
{ session_id: targetSessionId },
|
|
2057
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
2058
|
+
);
|
|
2059
|
+
if (!sessionId && this._sessionId === targetSessionId) {
|
|
2060
|
+
this._sessionId = null;
|
|
2061
|
+
}
|
|
2062
|
+
return response;
|
|
2063
|
+
} catch (error) {
|
|
2064
|
+
if (error instanceof Error && "statusCode" in error) {
|
|
2065
|
+
const statusCode = error.statusCode;
|
|
2066
|
+
if (statusCode === 403) {
|
|
2067
|
+
throw new AuthenticationError("You don't own this session", { cause: error });
|
|
2068
|
+
}
|
|
2069
|
+
if (statusCode === 404) {
|
|
2070
|
+
throw new SessionError("Session not found or no VM assigned to session (has execute() been called?)", { cause: error });
|
|
2071
|
+
}
|
|
2072
|
+
}
|
|
2073
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
2074
|
+
throw new SessionError(
|
|
2075
|
+
`Failed to kill VM: ${errorMessage}`,
|
|
2076
|
+
{ cause: error }
|
|
2077
|
+
);
|
|
2078
|
+
}
|
|
2079
|
+
}
|
|
2080
|
+
// --- Egress Policy Methods ---
|
|
2081
|
+
/**
|
|
2082
|
+
* Set egress policy for a session
|
|
2083
|
+
*/
|
|
2084
|
+
async setSessionEgress(options = {}, sessionId) {
|
|
2085
|
+
this.ensureNotLocal("Egress policy management");
|
|
2086
|
+
const targetSessionId = sessionId || this._sessionId;
|
|
2087
|
+
if (!targetSessionId) {
|
|
2088
|
+
throw new SessionError("Session ID not set. Please create a session first.");
|
|
2089
|
+
}
|
|
2090
|
+
const response = await this.httpClient.post(
|
|
2091
|
+
`/v1/egress/session/${targetSessionId}`,
|
|
2092
|
+
{
|
|
2093
|
+
allow_public_repos: options.allowPackageManagers ?? true,
|
|
2094
|
+
allow_http: options.allowHttp ?? true,
|
|
2095
|
+
allow_https: options.allowHttps ?? true,
|
|
2096
|
+
allowed_domains: options.allowedDomains ?? [],
|
|
2097
|
+
allowed_cidrs: options.allowedCidrs ?? []
|
|
2098
|
+
},
|
|
2099
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
2100
|
+
);
|
|
2101
|
+
return response;
|
|
2102
|
+
}
|
|
2103
|
+
/**
|
|
2104
|
+
* Get egress policy for a session
|
|
2105
|
+
*/
|
|
2106
|
+
async getSessionEgress(sessionId) {
|
|
2107
|
+
this.ensureNotLocal("Egress policy management");
|
|
2108
|
+
const targetSessionId = sessionId || this._sessionId;
|
|
2109
|
+
if (!targetSessionId) {
|
|
2110
|
+
throw new SessionError("Session ID not set. Please create a session first.");
|
|
2111
|
+
}
|
|
2112
|
+
const response = await this.httpClient.get(
|
|
2113
|
+
`/v1/egress/session/${targetSessionId}`,
|
|
2114
|
+
void 0,
|
|
2115
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
2116
|
+
);
|
|
2117
|
+
return {
|
|
2118
|
+
allowPackageManagers: response.allow_public_repos,
|
|
2119
|
+
allowHttp: response.allow_http,
|
|
2120
|
+
allowHttps: response.allow_https,
|
|
2121
|
+
allowedDomains: response.allowed_domains || [],
|
|
2122
|
+
allowedCidrs: response.allowed_cidrs || []
|
|
2123
|
+
};
|
|
2124
|
+
}
|
|
2125
|
+
/**
|
|
2126
|
+
* Set egress policy for a specific VM
|
|
2127
|
+
*/
|
|
2128
|
+
async setVmEgress(vmId, options = {}) {
|
|
2129
|
+
this.ensureNotLocal("Egress policy management");
|
|
2130
|
+
const response = await this.httpClient.post(
|
|
2131
|
+
`/v1/egress/vm/${vmId}`,
|
|
2132
|
+
{
|
|
2133
|
+
allow_public_repos: options.allowPackageManagers ?? true,
|
|
2134
|
+
allow_http: options.allowHttp ?? true,
|
|
2135
|
+
allow_https: options.allowHttps ?? true,
|
|
2136
|
+
allowed_domains: options.allowedDomains ?? [],
|
|
2137
|
+
allowed_cidrs: options.allowedCidrs ?? []
|
|
2138
|
+
},
|
|
2139
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
2140
|
+
);
|
|
2141
|
+
return response;
|
|
2142
|
+
}
|
|
2143
|
+
/**
|
|
2144
|
+
* Get egress policy for a specific VM
|
|
2145
|
+
*/
|
|
2146
|
+
async getVmEgress(vmId) {
|
|
2147
|
+
this.ensureNotLocal("Egress policy management");
|
|
2148
|
+
const response = await this.httpClient.get(
|
|
2149
|
+
`/v1/egress/vm/${vmId}`,
|
|
2150
|
+
void 0,
|
|
2151
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
2152
|
+
);
|
|
2153
|
+
return {
|
|
2154
|
+
allowPackageManagers: response.allow_public_repos,
|
|
2155
|
+
allowHttp: response.allow_http,
|
|
2156
|
+
allowHttps: response.allow_https,
|
|
2157
|
+
allowedDomains: response.allowed_domains || [],
|
|
2158
|
+
allowedCidrs: response.allowed_cidrs || []
|
|
2159
|
+
};
|
|
2160
|
+
}
|
|
2161
|
+
// --- SSH Key Methods ---
|
|
2162
|
+
/**
|
|
2163
|
+
* Add an SSH public key
|
|
2164
|
+
*/
|
|
2165
|
+
async addSshKey(publicKey) {
|
|
2166
|
+
this.ensureNotLocal("SSH key management");
|
|
2167
|
+
const response = await this.httpClient.post(
|
|
2168
|
+
"/v1/ssh-keys",
|
|
2169
|
+
{ public_key: publicKey },
|
|
2170
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
2171
|
+
);
|
|
2172
|
+
return {
|
|
2173
|
+
id: response.id,
|
|
2174
|
+
fingerprint: response.fingerprint,
|
|
2175
|
+
keyType: response.key_type,
|
|
2176
|
+
comment: response.comment ?? null,
|
|
2177
|
+
createdAt: response.created_at
|
|
2178
|
+
};
|
|
2179
|
+
}
|
|
2180
|
+
/**
|
|
2181
|
+
* List all active SSH keys
|
|
2182
|
+
*/
|
|
2183
|
+
async listSshKeys() {
|
|
2184
|
+
this.ensureNotLocal("SSH key management");
|
|
2185
|
+
const response = await this.httpClient.get(
|
|
2186
|
+
"/v1/ssh-keys",
|
|
2187
|
+
void 0,
|
|
2188
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
2189
|
+
);
|
|
2190
|
+
const keys = response.keys || [];
|
|
2191
|
+
return keys.map((k) => ({
|
|
2192
|
+
id: k.id,
|
|
2193
|
+
fingerprint: k.fingerprint,
|
|
2194
|
+
keyType: k.key_type,
|
|
2195
|
+
comment: k.comment ?? null,
|
|
2196
|
+
createdAt: k.created_at
|
|
2197
|
+
}));
|
|
2198
|
+
}
|
|
2199
|
+
/**
|
|
2200
|
+
* Delete an SSH key by ID
|
|
2201
|
+
*/
|
|
2202
|
+
async deleteSshKey(keyId) {
|
|
2203
|
+
this.ensureNotLocal("SSH key management");
|
|
2204
|
+
const response = await this.httpClient.delete(
|
|
2205
|
+
`/v1/ssh-keys/${keyId}`,
|
|
2206
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
2207
|
+
);
|
|
2208
|
+
return response;
|
|
2209
|
+
}
|
|
1217
2210
|
/**
|
|
1218
2211
|
* Clean up resources
|
|
1219
2212
|
*/
|
|
1220
2213
|
async dispose() {
|
|
1221
|
-
if (this._sessionId) {
|
|
2214
|
+
if (this._sessionId && !this.local && this._vmUsed) {
|
|
2215
|
+
try {
|
|
2216
|
+
await this.kill();
|
|
2217
|
+
} catch (e) {
|
|
2218
|
+
}
|
|
2219
|
+
} else if (this._sessionId) {
|
|
1222
2220
|
await this.closeSession();
|
|
1223
2221
|
}
|
|
1224
2222
|
await this.browser.dispose();
|
|
1225
2223
|
}
|
|
1226
2224
|
};
|
|
1227
2225
|
export {
|
|
2226
|
+
APIKeysManager,
|
|
2227
|
+
AuditManager,
|
|
1228
2228
|
AuthenticationError,
|
|
1229
2229
|
BrowserError,
|
|
1230
2230
|
BrowserInteractionError,
|
|
@@ -1233,6 +2233,8 @@ export {
|
|
|
1233
2233
|
BrowserSession,
|
|
1234
2234
|
BrowserSessionError,
|
|
1235
2235
|
BrowserTimeoutError,
|
|
2236
|
+
ComputerUseManager,
|
|
2237
|
+
CustomDomainsManager,
|
|
1236
2238
|
ElementNotFoundError,
|
|
1237
2239
|
ExecutionError,
|
|
1238
2240
|
InstaVM,
|
|
@@ -1241,6 +2243,11 @@ export {
|
|
|
1241
2243
|
QuotaExceededError,
|
|
1242
2244
|
RateLimitError,
|
|
1243
2245
|
SessionError,
|
|
1244
|
-
|
|
2246
|
+
SharesManager,
|
|
2247
|
+
SnapshotsManager,
|
|
2248
|
+
UnsupportedOperationError,
|
|
2249
|
+
VMsManager,
|
|
2250
|
+
VolumesManager,
|
|
2251
|
+
WebhooksManager
|
|
1245
2252
|
};
|
|
1246
2253
|
//# sourceMappingURL=index.mjs.map
|