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.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,12 @@ __export(index_exports, {
|
|
|
47
51
|
QuotaExceededError: () => QuotaExceededError,
|
|
48
52
|
RateLimitError: () => RateLimitError,
|
|
49
53
|
SessionError: () => SessionError,
|
|
50
|
-
|
|
54
|
+
SharesManager: () => SharesManager,
|
|
55
|
+
SnapshotsManager: () => SnapshotsManager,
|
|
56
|
+
UnsupportedOperationError: () => UnsupportedOperationError,
|
|
57
|
+
VMsManager: () => VMsManager,
|
|
58
|
+
VolumesManager: () => VolumesManager,
|
|
59
|
+
WebhooksManager: () => WebhooksManager
|
|
51
60
|
});
|
|
52
61
|
module.exports = __toCommonJS(index_exports);
|
|
53
62
|
|
|
@@ -190,7 +199,7 @@ var HTTPClient = class {
|
|
|
190
199
|
timeout: config.timeout,
|
|
191
200
|
headers: {
|
|
192
201
|
"Content-Type": "application/json",
|
|
193
|
-
"User-Agent": "instavm-js-sdk/0.
|
|
202
|
+
"User-Agent": "instavm-js-sdk/0.12.0"
|
|
194
203
|
}
|
|
195
204
|
});
|
|
196
205
|
this.setupInterceptors();
|
|
@@ -362,6 +371,39 @@ var HTTPClient = class {
|
|
|
362
371
|
headers
|
|
363
372
|
});
|
|
364
373
|
}
|
|
374
|
+
/**
|
|
375
|
+
* PUT request
|
|
376
|
+
*/
|
|
377
|
+
async put(url, data, headers) {
|
|
378
|
+
return this.request({
|
|
379
|
+
method: "PUT",
|
|
380
|
+
url,
|
|
381
|
+
data,
|
|
382
|
+
headers
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* PATCH request
|
|
387
|
+
*/
|
|
388
|
+
async patch(url, data, headers) {
|
|
389
|
+
return this.request({
|
|
390
|
+
method: "PATCH",
|
|
391
|
+
url,
|
|
392
|
+
data,
|
|
393
|
+
headers
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* OPTIONS request
|
|
398
|
+
*/
|
|
399
|
+
async options(url, headers, params) {
|
|
400
|
+
return this.request({
|
|
401
|
+
method: "OPTIONS",
|
|
402
|
+
url,
|
|
403
|
+
headers,
|
|
404
|
+
params
|
|
405
|
+
});
|
|
406
|
+
}
|
|
365
407
|
/**
|
|
366
408
|
* POST request that returns raw binary data (for file downloads)
|
|
367
409
|
*/
|
|
@@ -928,13 +970,732 @@ var BrowserManager = class {
|
|
|
928
970
|
}
|
|
929
971
|
};
|
|
930
972
|
|
|
931
|
-
// src/
|
|
973
|
+
// src/utils/path.ts
|
|
974
|
+
function encodePathSegment(value) {
|
|
975
|
+
const segment = String(value);
|
|
976
|
+
if (segment === "." || segment === "..") {
|
|
977
|
+
throw new Error("Path traversal not allowed in path segment");
|
|
978
|
+
}
|
|
979
|
+
return encodeURIComponent(segment);
|
|
980
|
+
}
|
|
981
|
+
function encodePathSegments(path2) {
|
|
982
|
+
const segments = path2.replace(/^\/+/, "").split("/").filter((segment) => segment.length > 0 && segment !== ".");
|
|
983
|
+
if (segments.some((segment) => segment === "..")) {
|
|
984
|
+
throw new Error("Path traversal not allowed in proxy path");
|
|
985
|
+
}
|
|
986
|
+
return segments.map((segment) => encodeURIComponent(segment)).join("/");
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
// src/client/VMsManager.ts
|
|
990
|
+
var VMsManager = class {
|
|
991
|
+
constructor(httpClient, local = false) {
|
|
992
|
+
this.httpClient = httpClient;
|
|
993
|
+
this.local = local;
|
|
994
|
+
}
|
|
995
|
+
ensureCloud(operation) {
|
|
996
|
+
if (this.local) {
|
|
997
|
+
throw new UnsupportedOperationError(
|
|
998
|
+
`${operation} is not supported in local mode.`
|
|
999
|
+
);
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
async create(payload = {}, wait = true) {
|
|
1003
|
+
this.ensureCloud("VM creation");
|
|
1004
|
+
return this.httpClient.request({
|
|
1005
|
+
method: "POST",
|
|
1006
|
+
url: "/v1/vms",
|
|
1007
|
+
params: { wait },
|
|
1008
|
+
data: payload,
|
|
1009
|
+
headers: { "X-API-Key": this.httpClient.apiKey }
|
|
1010
|
+
});
|
|
1011
|
+
}
|
|
1012
|
+
async list() {
|
|
1013
|
+
this.ensureCloud("VM listing");
|
|
1014
|
+
return this.httpClient.get(
|
|
1015
|
+
"/v1/vms",
|
|
1016
|
+
void 0,
|
|
1017
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1018
|
+
);
|
|
1019
|
+
}
|
|
1020
|
+
async listAll() {
|
|
1021
|
+
return this.listAllRecords();
|
|
1022
|
+
}
|
|
1023
|
+
/**
|
|
1024
|
+
* Calls GET /v1/vms/ (trailing slash), a distinct route from GET /v1/vms.
|
|
1025
|
+
*/
|
|
1026
|
+
async listAllRecords() {
|
|
1027
|
+
this.ensureCloud("VM listing");
|
|
1028
|
+
return this.httpClient.get(
|
|
1029
|
+
"/v1/vms/",
|
|
1030
|
+
void 0,
|
|
1031
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1032
|
+
);
|
|
1033
|
+
}
|
|
1034
|
+
async get(itemId) {
|
|
1035
|
+
this.ensureCloud("VM lookup");
|
|
1036
|
+
const safeItemId = encodePathSegment(itemId);
|
|
1037
|
+
return this.httpClient.get(
|
|
1038
|
+
`/v1/vms/${safeItemId}`,
|
|
1039
|
+
void 0,
|
|
1040
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1041
|
+
);
|
|
1042
|
+
}
|
|
1043
|
+
async update(vmId, payload = {}) {
|
|
1044
|
+
this.ensureCloud("VM update");
|
|
1045
|
+
const safeVmId = encodePathSegment(vmId);
|
|
1046
|
+
return this.httpClient.patch(
|
|
1047
|
+
`/v1/vms/${safeVmId}`,
|
|
1048
|
+
payload,
|
|
1049
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1050
|
+
);
|
|
1051
|
+
}
|
|
1052
|
+
async delete(vmId) {
|
|
1053
|
+
this.ensureCloud("VM deletion");
|
|
1054
|
+
const safeVmId = encodePathSegment(vmId);
|
|
1055
|
+
return this.httpClient.delete(
|
|
1056
|
+
`/v1/vms/${safeVmId}`,
|
|
1057
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1058
|
+
);
|
|
1059
|
+
}
|
|
1060
|
+
async clone(vmId, payload = {}, wait = true) {
|
|
1061
|
+
this.ensureCloud("VM clone");
|
|
1062
|
+
const safeVmId = encodePathSegment(vmId);
|
|
1063
|
+
return this.httpClient.request({
|
|
1064
|
+
method: "POST",
|
|
1065
|
+
url: `/v1/vms/${safeVmId}/clone`,
|
|
1066
|
+
params: { wait },
|
|
1067
|
+
data: payload,
|
|
1068
|
+
headers: { "X-API-Key": this.httpClient.apiKey }
|
|
1069
|
+
});
|
|
1070
|
+
}
|
|
1071
|
+
async snapshot(vmId, payload = {}, wait = true) {
|
|
1072
|
+
this.ensureCloud("VM snapshot");
|
|
1073
|
+
const safeVmId = encodePathSegment(vmId);
|
|
1074
|
+
return this.httpClient.request({
|
|
1075
|
+
method: "POST",
|
|
1076
|
+
url: `/v1/vms/${safeVmId}/snapshot`,
|
|
1077
|
+
params: { wait },
|
|
1078
|
+
data: payload,
|
|
1079
|
+
headers: { "X-API-Key": this.httpClient.apiKey }
|
|
1080
|
+
});
|
|
1081
|
+
}
|
|
1082
|
+
async mountVolume(vmId, payload, wait = true) {
|
|
1083
|
+
this.ensureCloud("VM volume mount");
|
|
1084
|
+
const safeVmId = encodePathSegment(vmId);
|
|
1085
|
+
return this.httpClient.request({
|
|
1086
|
+
method: "POST",
|
|
1087
|
+
url: `/v1/vms/${safeVmId}/volumes`,
|
|
1088
|
+
params: { wait },
|
|
1089
|
+
data: payload,
|
|
1090
|
+
headers: { "X-API-Key": this.httpClient.apiKey }
|
|
1091
|
+
});
|
|
1092
|
+
}
|
|
1093
|
+
async listVolumes(vmId) {
|
|
1094
|
+
this.ensureCloud("VM volume listing");
|
|
1095
|
+
const safeVmId = encodePathSegment(vmId);
|
|
1096
|
+
return this.httpClient.get(
|
|
1097
|
+
`/v1/vms/${safeVmId}/volumes`,
|
|
1098
|
+
void 0,
|
|
1099
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1100
|
+
);
|
|
1101
|
+
}
|
|
1102
|
+
async unmountVolume(vmId, volumeId, mountPath, wait = true) {
|
|
1103
|
+
this.ensureCloud("VM volume unmount");
|
|
1104
|
+
const safeVmId = encodePathSegment(vmId);
|
|
1105
|
+
const safeVolumeId = encodePathSegment(volumeId);
|
|
1106
|
+
return this.httpClient.request({
|
|
1107
|
+
method: "DELETE",
|
|
1108
|
+
url: `/v1/vms/${safeVmId}/volumes/${safeVolumeId}`,
|
|
1109
|
+
params: { mount_path: mountPath, wait },
|
|
1110
|
+
headers: { "X-API-Key": this.httpClient.apiKey }
|
|
1111
|
+
});
|
|
1112
|
+
}
|
|
1113
|
+
};
|
|
1114
|
+
|
|
1115
|
+
// src/client/SnapshotsManager.ts
|
|
1116
|
+
var SnapshotsManager = class {
|
|
1117
|
+
constructor(httpClient, local = false) {
|
|
1118
|
+
this.httpClient = httpClient;
|
|
1119
|
+
this.local = local;
|
|
1120
|
+
}
|
|
1121
|
+
ensureCloud(operation) {
|
|
1122
|
+
if (this.local) {
|
|
1123
|
+
throw new UnsupportedOperationError(
|
|
1124
|
+
`${operation} is not supported in local mode.`
|
|
1125
|
+
);
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1128
|
+
async create(payload) {
|
|
1129
|
+
this.ensureCloud("Snapshot creation");
|
|
1130
|
+
return this.httpClient.post(
|
|
1131
|
+
"/v1/snapshots",
|
|
1132
|
+
payload,
|
|
1133
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1134
|
+
);
|
|
1135
|
+
}
|
|
1136
|
+
async list(options = {}) {
|
|
1137
|
+
this.ensureCloud("Snapshot listing");
|
|
1138
|
+
return this.httpClient.get(
|
|
1139
|
+
"/v1/snapshots",
|
|
1140
|
+
options,
|
|
1141
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1142
|
+
);
|
|
1143
|
+
}
|
|
1144
|
+
async get(snapshotId) {
|
|
1145
|
+
this.ensureCloud("Snapshot lookup");
|
|
1146
|
+
const safeSnapshotId = encodePathSegment(snapshotId);
|
|
1147
|
+
return this.httpClient.get(
|
|
1148
|
+
`/v1/snapshots/${safeSnapshotId}`,
|
|
1149
|
+
void 0,
|
|
1150
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1151
|
+
);
|
|
1152
|
+
}
|
|
1153
|
+
async delete(snapshotId) {
|
|
1154
|
+
this.ensureCloud("Snapshot deletion");
|
|
1155
|
+
const safeSnapshotId = encodePathSegment(snapshotId);
|
|
1156
|
+
return this.httpClient.delete(
|
|
1157
|
+
`/v1/snapshots/${safeSnapshotId}`,
|
|
1158
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1159
|
+
);
|
|
1160
|
+
}
|
|
1161
|
+
};
|
|
1162
|
+
|
|
1163
|
+
// src/client/SharesManager.ts
|
|
1164
|
+
var SharesManager = class {
|
|
1165
|
+
constructor(httpClient, local = false, getSessionId = () => null) {
|
|
1166
|
+
this.httpClient = httpClient;
|
|
1167
|
+
this.local = local;
|
|
1168
|
+
this.getSessionId = getSessionId;
|
|
1169
|
+
}
|
|
1170
|
+
ensureCloud(operation) {
|
|
1171
|
+
if (this.local) {
|
|
1172
|
+
throw new UnsupportedOperationError(
|
|
1173
|
+
`${operation} is not supported in local mode.`
|
|
1174
|
+
);
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
async create(payload) {
|
|
1178
|
+
this.ensureCloud("Share creation");
|
|
1179
|
+
const body = { ...payload };
|
|
1180
|
+
if (!body.session_id && !body.vm_id) {
|
|
1181
|
+
const sid = this.getSessionId();
|
|
1182
|
+
if (!sid) {
|
|
1183
|
+
throw new SessionError(
|
|
1184
|
+
"Provide session_id/vm_id or create a session before creating a share."
|
|
1185
|
+
);
|
|
1186
|
+
}
|
|
1187
|
+
body.session_id = sid;
|
|
1188
|
+
}
|
|
1189
|
+
return this.httpClient.post(
|
|
1190
|
+
"/v1/shares",
|
|
1191
|
+
body,
|
|
1192
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1193
|
+
);
|
|
1194
|
+
}
|
|
1195
|
+
async update(shareId, payload) {
|
|
1196
|
+
this.ensureCloud("Share update");
|
|
1197
|
+
const safeShareId = encodePathSegment(shareId);
|
|
1198
|
+
return this.httpClient.patch(
|
|
1199
|
+
`/v1/shares/${safeShareId}`,
|
|
1200
|
+
payload,
|
|
1201
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1202
|
+
);
|
|
1203
|
+
}
|
|
1204
|
+
};
|
|
1205
|
+
|
|
1206
|
+
// src/client/CustomDomainsManager.ts
|
|
1207
|
+
var CustomDomainsManager = class {
|
|
1208
|
+
constructor(httpClient, local = false) {
|
|
1209
|
+
this.httpClient = httpClient;
|
|
1210
|
+
this.local = local;
|
|
1211
|
+
}
|
|
1212
|
+
ensureCloud(operation) {
|
|
1213
|
+
if (this.local) {
|
|
1214
|
+
throw new UnsupportedOperationError(
|
|
1215
|
+
`${operation} is not supported in local mode.`
|
|
1216
|
+
);
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1219
|
+
async create(payload) {
|
|
1220
|
+
this.ensureCloud("Custom domain creation");
|
|
1221
|
+
return this.httpClient.post(
|
|
1222
|
+
"/v1/custom-domains",
|
|
1223
|
+
payload,
|
|
1224
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1225
|
+
);
|
|
1226
|
+
}
|
|
1227
|
+
async list() {
|
|
1228
|
+
this.ensureCloud("Custom domain listing");
|
|
1229
|
+
return this.httpClient.get(
|
|
1230
|
+
"/v1/custom-domains",
|
|
1231
|
+
void 0,
|
|
1232
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1233
|
+
);
|
|
1234
|
+
}
|
|
1235
|
+
async health(domainId) {
|
|
1236
|
+
this.ensureCloud("Custom domain health");
|
|
1237
|
+
const safeDomainId = encodePathSegment(domainId);
|
|
1238
|
+
return this.httpClient.get(
|
|
1239
|
+
`/v1/custom-domains/${safeDomainId}/health`,
|
|
1240
|
+
void 0,
|
|
1241
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1242
|
+
);
|
|
1243
|
+
}
|
|
1244
|
+
async verify(domainId) {
|
|
1245
|
+
this.ensureCloud("Custom domain verification");
|
|
1246
|
+
const safeDomainId = encodePathSegment(domainId);
|
|
1247
|
+
return this.httpClient.post(
|
|
1248
|
+
`/v1/custom-domains/${safeDomainId}/verify`,
|
|
1249
|
+
{},
|
|
1250
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1251
|
+
);
|
|
1252
|
+
}
|
|
1253
|
+
async delete(domainId) {
|
|
1254
|
+
this.ensureCloud("Custom domain deletion");
|
|
1255
|
+
const safeDomainId = encodePathSegment(domainId);
|
|
1256
|
+
return this.httpClient.delete(
|
|
1257
|
+
`/v1/custom-domains/${safeDomainId}`,
|
|
1258
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1259
|
+
);
|
|
1260
|
+
}
|
|
1261
|
+
};
|
|
1262
|
+
|
|
1263
|
+
// src/client/ComputerUseManager.ts
|
|
1264
|
+
var ComputerUseManager = class {
|
|
1265
|
+
constructor(httpClient, local = false) {
|
|
1266
|
+
this.httpClient = httpClient;
|
|
1267
|
+
this.local = local;
|
|
1268
|
+
}
|
|
1269
|
+
ensureCloud(operation) {
|
|
1270
|
+
if (this.local) {
|
|
1271
|
+
throw new UnsupportedOperationError(
|
|
1272
|
+
`${operation} is not supported in local mode.`
|
|
1273
|
+
);
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
async viewerUrl(sessionId) {
|
|
1277
|
+
this.ensureCloud("Computer-use viewer URL");
|
|
1278
|
+
const safeSessionId = encodePathSegment(sessionId);
|
|
1279
|
+
return this.httpClient.get(
|
|
1280
|
+
`/v1/computeruse/${safeSessionId}/viewer-url`,
|
|
1281
|
+
void 0,
|
|
1282
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1283
|
+
);
|
|
1284
|
+
}
|
|
1285
|
+
async proxy(sessionId, path2, method = "GET", options = {}) {
|
|
1286
|
+
this.ensureCloud("Computer-use proxy");
|
|
1287
|
+
const safeSessionId = encodePathSegment(sessionId);
|
|
1288
|
+
const cleanPath = encodePathSegments(path2);
|
|
1289
|
+
return this.httpClient.request({
|
|
1290
|
+
method,
|
|
1291
|
+
url: `/v1/computeruse/${safeSessionId}/${cleanPath}`,
|
|
1292
|
+
params: options.params,
|
|
1293
|
+
data: options.body,
|
|
1294
|
+
headers: { "X-API-Key": this.httpClient.apiKey }
|
|
1295
|
+
});
|
|
1296
|
+
}
|
|
1297
|
+
async get(sessionId, path2, params) {
|
|
1298
|
+
return this.proxy(sessionId, path2, "GET", { params });
|
|
1299
|
+
}
|
|
1300
|
+
async post(sessionId, path2, body) {
|
|
1301
|
+
return this.proxy(sessionId, path2, "POST", { body });
|
|
1302
|
+
}
|
|
1303
|
+
async put(sessionId, path2, body) {
|
|
1304
|
+
return this.proxy(sessionId, path2, "PUT", { body });
|
|
1305
|
+
}
|
|
1306
|
+
async patch(sessionId, path2, body) {
|
|
1307
|
+
return this.proxy(sessionId, path2, "PATCH", { body });
|
|
1308
|
+
}
|
|
1309
|
+
async delete(sessionId, path2, params) {
|
|
1310
|
+
return this.proxy(sessionId, path2, "DELETE", { params });
|
|
1311
|
+
}
|
|
1312
|
+
async options(sessionId, path2, params) {
|
|
1313
|
+
return this.proxy(sessionId, path2, "OPTIONS", { params });
|
|
1314
|
+
}
|
|
1315
|
+
async head(sessionId, path2, params) {
|
|
1316
|
+
return this.proxy(sessionId, path2, "HEAD", { params });
|
|
1317
|
+
}
|
|
1318
|
+
/**
|
|
1319
|
+
* Get the VNC WebSocket URL for a computer-use session.
|
|
1320
|
+
* Returns the URL to connect to; the actual connection requires a WebSocket client.
|
|
1321
|
+
*/
|
|
1322
|
+
async vncWebsockify(sessionId) {
|
|
1323
|
+
this.ensureCloud("Computer-use VNC websockify");
|
|
1324
|
+
const safeSessionId = encodePathSegment(sessionId);
|
|
1325
|
+
return this.httpClient.get(
|
|
1326
|
+
`/v1/computeruse/${safeSessionId}/vnc/websockify`,
|
|
1327
|
+
void 0,
|
|
1328
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1329
|
+
);
|
|
1330
|
+
}
|
|
1331
|
+
};
|
|
1332
|
+
|
|
1333
|
+
// src/client/APIKeysManager.ts
|
|
1334
|
+
var APIKeysManager = class {
|
|
1335
|
+
constructor(httpClient, local = false) {
|
|
1336
|
+
this.httpClient = httpClient;
|
|
1337
|
+
this.local = local;
|
|
1338
|
+
}
|
|
1339
|
+
ensureCloud(operation) {
|
|
1340
|
+
if (this.local) {
|
|
1341
|
+
throw new UnsupportedOperationError(
|
|
1342
|
+
`${operation} is not supported in local mode.`
|
|
1343
|
+
);
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1346
|
+
async create(payload = {}) {
|
|
1347
|
+
this.ensureCloud("API key creation");
|
|
1348
|
+
return this.httpClient.post(
|
|
1349
|
+
"/v1/api-keys/",
|
|
1350
|
+
payload,
|
|
1351
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1352
|
+
);
|
|
1353
|
+
}
|
|
1354
|
+
async list() {
|
|
1355
|
+
this.ensureCloud("API key listing");
|
|
1356
|
+
return this.httpClient.get(
|
|
1357
|
+
"/v1/api-keys/",
|
|
1358
|
+
void 0,
|
|
1359
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1360
|
+
);
|
|
1361
|
+
}
|
|
1362
|
+
async get(itemId) {
|
|
1363
|
+
this.ensureCloud("API key lookup");
|
|
1364
|
+
const safeItemId = encodePathSegment(itemId);
|
|
1365
|
+
return this.httpClient.get(
|
|
1366
|
+
`/v1/api-keys/${safeItemId}`,
|
|
1367
|
+
void 0,
|
|
1368
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1369
|
+
);
|
|
1370
|
+
}
|
|
1371
|
+
async update(itemId, payload) {
|
|
1372
|
+
this.ensureCloud("API key update");
|
|
1373
|
+
const safeItemId = encodePathSegment(itemId);
|
|
1374
|
+
return this.httpClient.patch(
|
|
1375
|
+
`/v1/api-keys/${safeItemId}`,
|
|
1376
|
+
payload,
|
|
1377
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1378
|
+
);
|
|
1379
|
+
}
|
|
1380
|
+
async delete(itemId) {
|
|
1381
|
+
this.ensureCloud("API key deletion");
|
|
1382
|
+
const safeItemId = encodePathSegment(itemId);
|
|
1383
|
+
return this.httpClient.delete(
|
|
1384
|
+
`/v1/api-keys/${safeItemId}`,
|
|
1385
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1386
|
+
);
|
|
1387
|
+
}
|
|
1388
|
+
};
|
|
1389
|
+
|
|
1390
|
+
// src/client/AuditManager.ts
|
|
1391
|
+
var AuditManager = class {
|
|
1392
|
+
constructor(httpClient, local = false) {
|
|
1393
|
+
this.httpClient = httpClient;
|
|
1394
|
+
this.local = local;
|
|
1395
|
+
}
|
|
1396
|
+
ensureCloud(operation) {
|
|
1397
|
+
if (this.local) {
|
|
1398
|
+
throw new UnsupportedOperationError(
|
|
1399
|
+
`${operation} is not supported in local mode.`
|
|
1400
|
+
);
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
async catalog() {
|
|
1404
|
+
this.ensureCloud("Audit catalog");
|
|
1405
|
+
return this.httpClient.get(
|
|
1406
|
+
"/v1/audit/catalog",
|
|
1407
|
+
void 0,
|
|
1408
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1409
|
+
);
|
|
1410
|
+
}
|
|
1411
|
+
async events(query = {}) {
|
|
1412
|
+
this.ensureCloud("Audit event listing");
|
|
1413
|
+
return this.httpClient.get(
|
|
1414
|
+
"/v1/audit/events",
|
|
1415
|
+
query,
|
|
1416
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1417
|
+
);
|
|
1418
|
+
}
|
|
1419
|
+
async getEvent(eventId) {
|
|
1420
|
+
this.ensureCloud("Audit event lookup");
|
|
1421
|
+
const safeEventId = encodePathSegment(eventId);
|
|
1422
|
+
return this.httpClient.get(
|
|
1423
|
+
`/v1/audit/events/${safeEventId}`,
|
|
1424
|
+
void 0,
|
|
1425
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1426
|
+
);
|
|
1427
|
+
}
|
|
1428
|
+
};
|
|
1429
|
+
|
|
1430
|
+
// src/client/WebhooksManager.ts
|
|
1431
|
+
var WebhooksManager = class {
|
|
1432
|
+
constructor(httpClient, local = false) {
|
|
1433
|
+
this.httpClient = httpClient;
|
|
1434
|
+
this.local = local;
|
|
1435
|
+
}
|
|
1436
|
+
ensureCloud(operation) {
|
|
1437
|
+
if (this.local) {
|
|
1438
|
+
throw new UnsupportedOperationError(
|
|
1439
|
+
`${operation} is not supported in local mode.`
|
|
1440
|
+
);
|
|
1441
|
+
}
|
|
1442
|
+
}
|
|
1443
|
+
async createEndpoint(payload) {
|
|
1444
|
+
this.ensureCloud("Webhook endpoint creation");
|
|
1445
|
+
return this.httpClient.post(
|
|
1446
|
+
"/v1/webhooks/endpoints",
|
|
1447
|
+
payload,
|
|
1448
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1449
|
+
);
|
|
1450
|
+
}
|
|
1451
|
+
async listEndpoints() {
|
|
1452
|
+
this.ensureCloud("Webhook endpoint listing");
|
|
1453
|
+
return this.httpClient.get(
|
|
1454
|
+
"/v1/webhooks/endpoints",
|
|
1455
|
+
void 0,
|
|
1456
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1457
|
+
);
|
|
1458
|
+
}
|
|
1459
|
+
async getEndpoint(endpointId) {
|
|
1460
|
+
this.ensureCloud("Webhook endpoint lookup");
|
|
1461
|
+
const safeEndpointId = encodePathSegment(endpointId);
|
|
1462
|
+
return this.httpClient.get(
|
|
1463
|
+
`/v1/webhooks/endpoints/${safeEndpointId}`,
|
|
1464
|
+
void 0,
|
|
1465
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1466
|
+
);
|
|
1467
|
+
}
|
|
1468
|
+
async updateEndpoint(endpointId, payload) {
|
|
1469
|
+
this.ensureCloud("Webhook endpoint update");
|
|
1470
|
+
const safeEndpointId = encodePathSegment(endpointId);
|
|
1471
|
+
return this.httpClient.patch(
|
|
1472
|
+
`/v1/webhooks/endpoints/${safeEndpointId}`,
|
|
1473
|
+
payload,
|
|
1474
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1475
|
+
);
|
|
1476
|
+
}
|
|
1477
|
+
async deleteEndpoint(endpointId) {
|
|
1478
|
+
this.ensureCloud("Webhook endpoint deletion");
|
|
1479
|
+
const safeEndpointId = encodePathSegment(endpointId);
|
|
1480
|
+
return this.httpClient.delete(
|
|
1481
|
+
`/v1/webhooks/endpoints/${safeEndpointId}`,
|
|
1482
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1483
|
+
);
|
|
1484
|
+
}
|
|
1485
|
+
async rotateSecret(endpointId) {
|
|
1486
|
+
this.ensureCloud("Webhook secret rotation");
|
|
1487
|
+
const safeEndpointId = encodePathSegment(endpointId);
|
|
1488
|
+
return this.httpClient.post(
|
|
1489
|
+
`/v1/webhooks/endpoints/${safeEndpointId}/rotate-secret`,
|
|
1490
|
+
{},
|
|
1491
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1492
|
+
);
|
|
1493
|
+
}
|
|
1494
|
+
async sendTestEvent(endpointId) {
|
|
1495
|
+
this.ensureCloud("Webhook test event");
|
|
1496
|
+
const safeEndpointId = encodePathSegment(endpointId);
|
|
1497
|
+
return this.httpClient.post(
|
|
1498
|
+
`/v1/webhooks/endpoints/${safeEndpointId}/test`,
|
|
1499
|
+
{},
|
|
1500
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1501
|
+
);
|
|
1502
|
+
}
|
|
1503
|
+
async verifyEndpoint(endpointId) {
|
|
1504
|
+
this.ensureCloud("Webhook endpoint verification");
|
|
1505
|
+
const safeEndpointId = encodePathSegment(endpointId);
|
|
1506
|
+
return this.httpClient.post(
|
|
1507
|
+
`/v1/webhooks/endpoints/${safeEndpointId}/verify`,
|
|
1508
|
+
{},
|
|
1509
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1510
|
+
);
|
|
1511
|
+
}
|
|
1512
|
+
async listDeliveries(query = {}) {
|
|
1513
|
+
this.ensureCloud("Webhook delivery listing");
|
|
1514
|
+
return this.httpClient.get(
|
|
1515
|
+
"/v1/webhooks/deliveries",
|
|
1516
|
+
query,
|
|
1517
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1518
|
+
);
|
|
1519
|
+
}
|
|
1520
|
+
async replayDelivery(deliveryId) {
|
|
1521
|
+
this.ensureCloud("Webhook delivery replay");
|
|
1522
|
+
const safeDeliveryId = encodePathSegment(deliveryId);
|
|
1523
|
+
return this.httpClient.post(
|
|
1524
|
+
`/v1/webhooks/deliveries/${safeDeliveryId}/replay`,
|
|
1525
|
+
{},
|
|
1526
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1527
|
+
);
|
|
1528
|
+
}
|
|
1529
|
+
};
|
|
1530
|
+
|
|
1531
|
+
// src/client/VolumesManager.ts
|
|
1532
|
+
var import_fs = __toESM(require("fs"));
|
|
1533
|
+
var import_path9 = __toESM(require("path"));
|
|
932
1534
|
var import_form_data = __toESM(require("form-data"));
|
|
1535
|
+
var VolumesManager = class {
|
|
1536
|
+
constructor(httpClient, local = false) {
|
|
1537
|
+
this.httpClient = httpClient;
|
|
1538
|
+
this.local = local;
|
|
1539
|
+
}
|
|
1540
|
+
ensureCloud(operation) {
|
|
1541
|
+
if (this.local) {
|
|
1542
|
+
throw new UnsupportedOperationError(
|
|
1543
|
+
`${operation} is not supported in local mode.`
|
|
1544
|
+
);
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1547
|
+
async create(payload) {
|
|
1548
|
+
this.ensureCloud("Volume creation");
|
|
1549
|
+
return this.httpClient.post(
|
|
1550
|
+
"/v1/volumes",
|
|
1551
|
+
payload,
|
|
1552
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1553
|
+
);
|
|
1554
|
+
}
|
|
1555
|
+
async list(refreshUsage = false) {
|
|
1556
|
+
this.ensureCloud("Volume listing");
|
|
1557
|
+
return this.httpClient.get(
|
|
1558
|
+
"/v1/volumes",
|
|
1559
|
+
{ refresh_usage: refreshUsage },
|
|
1560
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1561
|
+
);
|
|
1562
|
+
}
|
|
1563
|
+
async get(volumeId, refreshUsage = false) {
|
|
1564
|
+
this.ensureCloud("Volume lookup");
|
|
1565
|
+
const safeVolumeId = encodePathSegment(volumeId);
|
|
1566
|
+
return this.httpClient.get(
|
|
1567
|
+
`/v1/volumes/${safeVolumeId}`,
|
|
1568
|
+
{ refresh_usage: refreshUsage },
|
|
1569
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1570
|
+
);
|
|
1571
|
+
}
|
|
1572
|
+
async update(volumeId, payload) {
|
|
1573
|
+
this.ensureCloud("Volume update");
|
|
1574
|
+
const safeVolumeId = encodePathSegment(volumeId);
|
|
1575
|
+
return this.httpClient.patch(
|
|
1576
|
+
`/v1/volumes/${safeVolumeId}`,
|
|
1577
|
+
payload,
|
|
1578
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1579
|
+
);
|
|
1580
|
+
}
|
|
1581
|
+
async delete(volumeId) {
|
|
1582
|
+
this.ensureCloud("Volume deletion");
|
|
1583
|
+
const safeVolumeId = encodePathSegment(volumeId);
|
|
1584
|
+
return this.httpClient.delete(
|
|
1585
|
+
`/v1/volumes/${safeVolumeId}`,
|
|
1586
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1587
|
+
);
|
|
1588
|
+
}
|
|
1589
|
+
async createCheckpoint(volumeId, payload = {}) {
|
|
1590
|
+
this.ensureCloud("Volume checkpoint creation");
|
|
1591
|
+
const safeVolumeId = encodePathSegment(volumeId);
|
|
1592
|
+
return this.httpClient.post(
|
|
1593
|
+
`/v1/volumes/${safeVolumeId}/checkpoints`,
|
|
1594
|
+
payload,
|
|
1595
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1596
|
+
);
|
|
1597
|
+
}
|
|
1598
|
+
async listCheckpoints(volumeId) {
|
|
1599
|
+
this.ensureCloud("Volume checkpoint listing");
|
|
1600
|
+
const safeVolumeId = encodePathSegment(volumeId);
|
|
1601
|
+
return this.httpClient.get(
|
|
1602
|
+
`/v1/volumes/${safeVolumeId}/checkpoints`,
|
|
1603
|
+
void 0,
|
|
1604
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1605
|
+
);
|
|
1606
|
+
}
|
|
1607
|
+
async deleteCheckpoint(volumeId, checkpointId) {
|
|
1608
|
+
this.ensureCloud("Volume checkpoint deletion");
|
|
1609
|
+
const safeVolumeId = encodePathSegment(volumeId);
|
|
1610
|
+
const safeCheckpointId = encodePathSegment(checkpointId);
|
|
1611
|
+
return this.httpClient.delete(
|
|
1612
|
+
`/v1/volumes/${safeVolumeId}/checkpoints/${safeCheckpointId}`,
|
|
1613
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1614
|
+
);
|
|
1615
|
+
}
|
|
1616
|
+
async uploadFile(volumeId, payload) {
|
|
1617
|
+
this.ensureCloud("Volume file upload");
|
|
1618
|
+
if (!payload.path || payload.path.trim().length === 0) {
|
|
1619
|
+
throw new Error("payload.path is required");
|
|
1620
|
+
}
|
|
1621
|
+
const hasFilePath = typeof payload.filePath === "string" && payload.filePath.length > 0;
|
|
1622
|
+
const hasFileContent = payload.fileContent !== void 0;
|
|
1623
|
+
if (hasFilePath === hasFileContent) {
|
|
1624
|
+
throw new Error("Provide exactly one of payload.filePath or payload.fileContent");
|
|
1625
|
+
}
|
|
1626
|
+
const safeVolumeId = encodePathSegment(volumeId);
|
|
1627
|
+
const formData = new import_form_data.default();
|
|
1628
|
+
if (hasFilePath) {
|
|
1629
|
+
const sourcePath = payload.filePath;
|
|
1630
|
+
const filename = payload.filename || import_path9.default.basename(sourcePath);
|
|
1631
|
+
formData.append("file", import_fs.default.createReadStream(sourcePath), { filename });
|
|
1632
|
+
} else {
|
|
1633
|
+
const filename = payload.filename || "upload.bin";
|
|
1634
|
+
const raw = payload.fileContent;
|
|
1635
|
+
const buffer = Buffer.isBuffer(raw) ? raw : Buffer.from(raw);
|
|
1636
|
+
formData.append("file", buffer, { filename });
|
|
1637
|
+
}
|
|
1638
|
+
formData.append("path", payload.path);
|
|
1639
|
+
if (payload.overwrite !== void 0) {
|
|
1640
|
+
formData.append("overwrite", String(payload.overwrite));
|
|
1641
|
+
}
|
|
1642
|
+
return this.httpClient.postFormData(
|
|
1643
|
+
`/v1/volumes/${safeVolumeId}/files/upload`,
|
|
1644
|
+
formData
|
|
1645
|
+
);
|
|
1646
|
+
}
|
|
1647
|
+
async downloadFile(volumeId, path2) {
|
|
1648
|
+
this.ensureCloud("Volume file download");
|
|
1649
|
+
const safeVolumeId = encodePathSegment(volumeId);
|
|
1650
|
+
const response = await this.httpClient.post(
|
|
1651
|
+
`/v1/volumes/${safeVolumeId}/files/download`,
|
|
1652
|
+
{ path: path2 },
|
|
1653
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1654
|
+
);
|
|
1655
|
+
return {
|
|
1656
|
+
path: response.path,
|
|
1657
|
+
filename: response.filename,
|
|
1658
|
+
size: response.size,
|
|
1659
|
+
content: Buffer.from(response.content || "", "base64")
|
|
1660
|
+
};
|
|
1661
|
+
}
|
|
1662
|
+
async listFiles(volumeId, options = {}) {
|
|
1663
|
+
this.ensureCloud("Volume file listing");
|
|
1664
|
+
const safeVolumeId = encodePathSegment(volumeId);
|
|
1665
|
+
return this.httpClient.get(
|
|
1666
|
+
`/v1/volumes/${safeVolumeId}/files`,
|
|
1667
|
+
{
|
|
1668
|
+
prefix: options.prefix ?? "",
|
|
1669
|
+
recursive: options.recursive ?? true,
|
|
1670
|
+
limit: options.limit ?? 1e3
|
|
1671
|
+
},
|
|
1672
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1673
|
+
);
|
|
1674
|
+
}
|
|
1675
|
+
async deleteFile(volumeId, targetPath) {
|
|
1676
|
+
this.ensureCloud("Volume file deletion");
|
|
1677
|
+
const safeVolumeId = encodePathSegment(volumeId);
|
|
1678
|
+
return this.httpClient.request({
|
|
1679
|
+
method: "DELETE",
|
|
1680
|
+
url: `/v1/volumes/${safeVolumeId}/files`,
|
|
1681
|
+
params: { path: targetPath },
|
|
1682
|
+
headers: { "X-API-Key": this.httpClient.apiKey }
|
|
1683
|
+
});
|
|
1684
|
+
}
|
|
1685
|
+
};
|
|
1686
|
+
|
|
1687
|
+
// src/client/InstaVM.ts
|
|
1688
|
+
var import_form_data2 = __toESM(require("form-data"));
|
|
933
1689
|
var InstaVM = class {
|
|
934
1690
|
constructor(apiKey, options = {}) {
|
|
935
1691
|
this._sessionId = null;
|
|
1692
|
+
this._vmUsed = false;
|
|
936
1693
|
this.local = options.local || false;
|
|
937
1694
|
this.timeout = options.timeout || 3e5;
|
|
1695
|
+
this.memory_mb = options.memory_mb;
|
|
1696
|
+
this.cpu_count = options.cpu_count;
|
|
1697
|
+
this.metadata = options.metadata;
|
|
1698
|
+
this.env = options.env;
|
|
938
1699
|
if (!this.local && !apiKey) {
|
|
939
1700
|
throw new AuthenticationError("API key is required for cloud mode");
|
|
940
1701
|
}
|
|
@@ -947,6 +1708,15 @@ var InstaVM = class {
|
|
|
947
1708
|
};
|
|
948
1709
|
this.httpClient = new HTTPClient(config);
|
|
949
1710
|
this.browser = new BrowserManager(this.httpClient, this.local);
|
|
1711
|
+
this.vms = new VMsManager(this.httpClient, this.local);
|
|
1712
|
+
this.snapshots = new SnapshotsManager(this.httpClient, this.local);
|
|
1713
|
+
this.shares = new SharesManager(this.httpClient, this.local, () => this._sessionId);
|
|
1714
|
+
this.customDomains = new CustomDomainsManager(this.httpClient, this.local);
|
|
1715
|
+
this.computerUse = new ComputerUseManager(this.httpClient, this.local);
|
|
1716
|
+
this.apiKeys = new APIKeysManager(this.httpClient, this.local);
|
|
1717
|
+
this.audit = new AuditManager(this.httpClient, this.local);
|
|
1718
|
+
this.webhooks = new WebhooksManager(this.httpClient, this.local);
|
|
1719
|
+
this.volumes = new VolumesManager(this.httpClient, this.local);
|
|
950
1720
|
}
|
|
951
1721
|
/**
|
|
952
1722
|
* Ensure operation is not called in local mode
|
|
@@ -992,6 +1762,9 @@ var InstaVM = class {
|
|
|
992
1762
|
if (response.session_id) {
|
|
993
1763
|
this._sessionId = response.session_id;
|
|
994
1764
|
}
|
|
1765
|
+
if (!this.local) {
|
|
1766
|
+
this._vmUsed = true;
|
|
1767
|
+
}
|
|
995
1768
|
return {
|
|
996
1769
|
stdout: response.stdout || "",
|
|
997
1770
|
stderr: response.stderr || "",
|
|
@@ -1035,6 +1808,7 @@ var InstaVM = class {
|
|
|
1035
1808
|
if (response.session_id) {
|
|
1036
1809
|
this._sessionId = response.session_id;
|
|
1037
1810
|
}
|
|
1811
|
+
this._vmUsed = true;
|
|
1038
1812
|
return {
|
|
1039
1813
|
taskId: response.task_id,
|
|
1040
1814
|
status: response.status || "pending",
|
|
@@ -1106,7 +1880,7 @@ var InstaVM = class {
|
|
|
1106
1880
|
if (!sessionId) {
|
|
1107
1881
|
throw new SessionError("Session ID not set. Please create a session first using createSession().");
|
|
1108
1882
|
}
|
|
1109
|
-
const formData = new
|
|
1883
|
+
const formData = new import_form_data2.default();
|
|
1110
1884
|
for (const file of files) {
|
|
1111
1885
|
if (Buffer.isBuffer(file.content)) {
|
|
1112
1886
|
formData.append("files", file.content, file.name);
|
|
@@ -1148,10 +1922,26 @@ var InstaVM = class {
|
|
|
1148
1922
|
async createSession() {
|
|
1149
1923
|
this.ensureNotLocal("Session management");
|
|
1150
1924
|
try {
|
|
1151
|
-
const
|
|
1925
|
+
const requestBody = {
|
|
1152
1926
|
api_key: this.httpClient.apiKey,
|
|
1153
1927
|
vm_lifetime_seconds: Math.floor(this.timeout / 1e3)
|
|
1154
|
-
}
|
|
1928
|
+
};
|
|
1929
|
+
if (this.memory_mb !== void 0) {
|
|
1930
|
+
requestBody.memory_mb = this.memory_mb;
|
|
1931
|
+
}
|
|
1932
|
+
if (this.cpu_count !== void 0) {
|
|
1933
|
+
requestBody.vcpu_count = this.cpu_count;
|
|
1934
|
+
}
|
|
1935
|
+
if (this.metadata !== void 0) {
|
|
1936
|
+
requestBody.metadata = this.metadata;
|
|
1937
|
+
}
|
|
1938
|
+
if (this.env !== void 0) {
|
|
1939
|
+
requestBody.env = this.env;
|
|
1940
|
+
}
|
|
1941
|
+
const response = await this.httpClient.post(
|
|
1942
|
+
"/v1/sessions/session",
|
|
1943
|
+
requestBody
|
|
1944
|
+
);
|
|
1155
1945
|
if (response.session_id) {
|
|
1156
1946
|
this._sessionId = response.session_id;
|
|
1157
1947
|
return response.session_id;
|
|
@@ -1202,6 +1992,49 @@ var InstaVM = class {
|
|
|
1202
1992
|
return false;
|
|
1203
1993
|
}
|
|
1204
1994
|
}
|
|
1995
|
+
/**
|
|
1996
|
+
* Get the app URL for a session
|
|
1997
|
+
*
|
|
1998
|
+
* @param sessionId - Session ID (uses current session if not provided)
|
|
1999
|
+
* @param port - Port to expose (1-65535, default: 80)
|
|
2000
|
+
*/
|
|
2001
|
+
async getSessionAppUrl(sessionId, port) {
|
|
2002
|
+
this.ensureNotLocal("Session app URL");
|
|
2003
|
+
const targetSessionId = sessionId || this._sessionId;
|
|
2004
|
+
if (!targetSessionId) {
|
|
2005
|
+
throw new SessionError("Session ID not set. Please create a session first.");
|
|
2006
|
+
}
|
|
2007
|
+
const params = {};
|
|
2008
|
+
if (port !== void 0) {
|
|
2009
|
+
params.port = port;
|
|
2010
|
+
}
|
|
2011
|
+
return this.httpClient.get(
|
|
2012
|
+
`/v1/sessions/app-url/${targetSessionId}`,
|
|
2013
|
+
params,
|
|
2014
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
2015
|
+
);
|
|
2016
|
+
}
|
|
2017
|
+
/**
|
|
2018
|
+
* List sandbox records with optional filtering
|
|
2019
|
+
*
|
|
2020
|
+
* @param options.metadata - JSON-serializable metadata filters
|
|
2021
|
+
* @param options.limit - Maximum number of results (1-1000, default: 100)
|
|
2022
|
+
*/
|
|
2023
|
+
async listSandboxes(options = {}) {
|
|
2024
|
+
this.ensureNotLocal("Sandbox listing");
|
|
2025
|
+
const params = {};
|
|
2026
|
+
if (options.metadata !== void 0) {
|
|
2027
|
+
params.metadata = JSON.stringify(options.metadata);
|
|
2028
|
+
}
|
|
2029
|
+
if (options.limit !== void 0) {
|
|
2030
|
+
params.limit = options.limit;
|
|
2031
|
+
}
|
|
2032
|
+
return this.httpClient.get(
|
|
2033
|
+
"/v1/sessions/sandboxes",
|
|
2034
|
+
params,
|
|
2035
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
2036
|
+
);
|
|
2037
|
+
}
|
|
1205
2038
|
/**
|
|
1206
2039
|
* Get usage statistics for a session
|
|
1207
2040
|
*/
|
|
@@ -1265,11 +2098,185 @@ var InstaVM = class {
|
|
|
1265
2098
|
get sessionId() {
|
|
1266
2099
|
return this._sessionId;
|
|
1267
2100
|
}
|
|
2101
|
+
/**
|
|
2102
|
+
* Kill the VM associated with a session
|
|
2103
|
+
*
|
|
2104
|
+
* @param sessionId - The session UUID whose VM should be killed. If not provided, uses current sessionId
|
|
2105
|
+
* @returns Result containing success message and killed VM ID
|
|
2106
|
+
*/
|
|
2107
|
+
async kill(sessionId) {
|
|
2108
|
+
this.ensureNotLocal("VM kill operation");
|
|
2109
|
+
const targetSessionId = sessionId || this._sessionId;
|
|
2110
|
+
if (!targetSessionId) {
|
|
2111
|
+
throw new SessionError("Session ID not set. Please provide a sessionId or start a session first.");
|
|
2112
|
+
}
|
|
2113
|
+
try {
|
|
2114
|
+
const response = await this.httpClient.post(
|
|
2115
|
+
"/kill",
|
|
2116
|
+
{ session_id: targetSessionId },
|
|
2117
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
2118
|
+
);
|
|
2119
|
+
if (!sessionId && this._sessionId === targetSessionId) {
|
|
2120
|
+
this._sessionId = null;
|
|
2121
|
+
}
|
|
2122
|
+
return response;
|
|
2123
|
+
} catch (error) {
|
|
2124
|
+
if (error instanceof Error && "statusCode" in error) {
|
|
2125
|
+
const statusCode = error.statusCode;
|
|
2126
|
+
if (statusCode === 403) {
|
|
2127
|
+
throw new AuthenticationError("You don't own this session", { cause: error });
|
|
2128
|
+
}
|
|
2129
|
+
if (statusCode === 404) {
|
|
2130
|
+
throw new SessionError("Session not found or no VM assigned to session (has execute() been called?)", { cause: error });
|
|
2131
|
+
}
|
|
2132
|
+
}
|
|
2133
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
2134
|
+
throw new SessionError(
|
|
2135
|
+
`Failed to kill VM: ${errorMessage}`,
|
|
2136
|
+
{ cause: error }
|
|
2137
|
+
);
|
|
2138
|
+
}
|
|
2139
|
+
}
|
|
2140
|
+
// --- Egress Policy Methods ---
|
|
2141
|
+
/**
|
|
2142
|
+
* Set egress policy for a session
|
|
2143
|
+
*/
|
|
2144
|
+
async setSessionEgress(options = {}, sessionId) {
|
|
2145
|
+
this.ensureNotLocal("Egress policy management");
|
|
2146
|
+
const targetSessionId = sessionId || this._sessionId;
|
|
2147
|
+
if (!targetSessionId) {
|
|
2148
|
+
throw new SessionError("Session ID not set. Please create a session first.");
|
|
2149
|
+
}
|
|
2150
|
+
const response = await this.httpClient.post(
|
|
2151
|
+
`/v1/egress/session/${targetSessionId}`,
|
|
2152
|
+
{
|
|
2153
|
+
allow_public_repos: options.allowPackageManagers ?? true,
|
|
2154
|
+
allow_http: options.allowHttp ?? true,
|
|
2155
|
+
allow_https: options.allowHttps ?? true,
|
|
2156
|
+
allowed_domains: options.allowedDomains ?? [],
|
|
2157
|
+
allowed_cidrs: options.allowedCidrs ?? []
|
|
2158
|
+
},
|
|
2159
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
2160
|
+
);
|
|
2161
|
+
return response;
|
|
2162
|
+
}
|
|
2163
|
+
/**
|
|
2164
|
+
* Get egress policy for a session
|
|
2165
|
+
*/
|
|
2166
|
+
async getSessionEgress(sessionId) {
|
|
2167
|
+
this.ensureNotLocal("Egress policy management");
|
|
2168
|
+
const targetSessionId = sessionId || this._sessionId;
|
|
2169
|
+
if (!targetSessionId) {
|
|
2170
|
+
throw new SessionError("Session ID not set. Please create a session first.");
|
|
2171
|
+
}
|
|
2172
|
+
const response = await this.httpClient.get(
|
|
2173
|
+
`/v1/egress/session/${targetSessionId}`,
|
|
2174
|
+
void 0,
|
|
2175
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
2176
|
+
);
|
|
2177
|
+
return {
|
|
2178
|
+
allowPackageManagers: response.allow_public_repos,
|
|
2179
|
+
allowHttp: response.allow_http,
|
|
2180
|
+
allowHttps: response.allow_https,
|
|
2181
|
+
allowedDomains: response.allowed_domains || [],
|
|
2182
|
+
allowedCidrs: response.allowed_cidrs || []
|
|
2183
|
+
};
|
|
2184
|
+
}
|
|
2185
|
+
/**
|
|
2186
|
+
* Set egress policy for a specific VM
|
|
2187
|
+
*/
|
|
2188
|
+
async setVmEgress(vmId, options = {}) {
|
|
2189
|
+
this.ensureNotLocal("Egress policy management");
|
|
2190
|
+
const response = await this.httpClient.post(
|
|
2191
|
+
`/v1/egress/vm/${vmId}`,
|
|
2192
|
+
{
|
|
2193
|
+
allow_public_repos: options.allowPackageManagers ?? true,
|
|
2194
|
+
allow_http: options.allowHttp ?? true,
|
|
2195
|
+
allow_https: options.allowHttps ?? true,
|
|
2196
|
+
allowed_domains: options.allowedDomains ?? [],
|
|
2197
|
+
allowed_cidrs: options.allowedCidrs ?? []
|
|
2198
|
+
},
|
|
2199
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
2200
|
+
);
|
|
2201
|
+
return response;
|
|
2202
|
+
}
|
|
2203
|
+
/**
|
|
2204
|
+
* Get egress policy for a specific VM
|
|
2205
|
+
*/
|
|
2206
|
+
async getVmEgress(vmId) {
|
|
2207
|
+
this.ensureNotLocal("Egress policy management");
|
|
2208
|
+
const response = await this.httpClient.get(
|
|
2209
|
+
`/v1/egress/vm/${vmId}`,
|
|
2210
|
+
void 0,
|
|
2211
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
2212
|
+
);
|
|
2213
|
+
return {
|
|
2214
|
+
allowPackageManagers: response.allow_public_repos,
|
|
2215
|
+
allowHttp: response.allow_http,
|
|
2216
|
+
allowHttps: response.allow_https,
|
|
2217
|
+
allowedDomains: response.allowed_domains || [],
|
|
2218
|
+
allowedCidrs: response.allowed_cidrs || []
|
|
2219
|
+
};
|
|
2220
|
+
}
|
|
2221
|
+
// --- SSH Key Methods ---
|
|
2222
|
+
/**
|
|
2223
|
+
* Add an SSH public key
|
|
2224
|
+
*/
|
|
2225
|
+
async addSshKey(publicKey) {
|
|
2226
|
+
this.ensureNotLocal("SSH key management");
|
|
2227
|
+
const response = await this.httpClient.post(
|
|
2228
|
+
"/v1/ssh-keys",
|
|
2229
|
+
{ public_key: publicKey },
|
|
2230
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
2231
|
+
);
|
|
2232
|
+
return {
|
|
2233
|
+
id: response.id,
|
|
2234
|
+
fingerprint: response.fingerprint,
|
|
2235
|
+
keyType: response.key_type,
|
|
2236
|
+
comment: response.comment ?? null,
|
|
2237
|
+
createdAt: response.created_at
|
|
2238
|
+
};
|
|
2239
|
+
}
|
|
2240
|
+
/**
|
|
2241
|
+
* List all active SSH keys
|
|
2242
|
+
*/
|
|
2243
|
+
async listSshKeys() {
|
|
2244
|
+
this.ensureNotLocal("SSH key management");
|
|
2245
|
+
const response = await this.httpClient.get(
|
|
2246
|
+
"/v1/ssh-keys",
|
|
2247
|
+
void 0,
|
|
2248
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
2249
|
+
);
|
|
2250
|
+
const keys = response.keys || [];
|
|
2251
|
+
return keys.map((k) => ({
|
|
2252
|
+
id: k.id,
|
|
2253
|
+
fingerprint: k.fingerprint,
|
|
2254
|
+
keyType: k.key_type,
|
|
2255
|
+
comment: k.comment ?? null,
|
|
2256
|
+
createdAt: k.created_at
|
|
2257
|
+
}));
|
|
2258
|
+
}
|
|
2259
|
+
/**
|
|
2260
|
+
* Delete an SSH key by ID
|
|
2261
|
+
*/
|
|
2262
|
+
async deleteSshKey(keyId) {
|
|
2263
|
+
this.ensureNotLocal("SSH key management");
|
|
2264
|
+
const response = await this.httpClient.delete(
|
|
2265
|
+
`/v1/ssh-keys/${keyId}`,
|
|
2266
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
2267
|
+
);
|
|
2268
|
+
return response;
|
|
2269
|
+
}
|
|
1268
2270
|
/**
|
|
1269
2271
|
* Clean up resources
|
|
1270
2272
|
*/
|
|
1271
2273
|
async dispose() {
|
|
1272
|
-
if (this._sessionId) {
|
|
2274
|
+
if (this._sessionId && !this.local && this._vmUsed) {
|
|
2275
|
+
try {
|
|
2276
|
+
await this.kill();
|
|
2277
|
+
} catch (e) {
|
|
2278
|
+
}
|
|
2279
|
+
} else if (this._sessionId) {
|
|
1273
2280
|
await this.closeSession();
|
|
1274
2281
|
}
|
|
1275
2282
|
await this.browser.dispose();
|
|
@@ -1277,6 +2284,8 @@ var InstaVM = class {
|
|
|
1277
2284
|
};
|
|
1278
2285
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1279
2286
|
0 && (module.exports = {
|
|
2287
|
+
APIKeysManager,
|
|
2288
|
+
AuditManager,
|
|
1280
2289
|
AuthenticationError,
|
|
1281
2290
|
BrowserError,
|
|
1282
2291
|
BrowserInteractionError,
|
|
@@ -1285,6 +2294,8 @@ var InstaVM = class {
|
|
|
1285
2294
|
BrowserSession,
|
|
1286
2295
|
BrowserSessionError,
|
|
1287
2296
|
BrowserTimeoutError,
|
|
2297
|
+
ComputerUseManager,
|
|
2298
|
+
CustomDomainsManager,
|
|
1288
2299
|
ElementNotFoundError,
|
|
1289
2300
|
ExecutionError,
|
|
1290
2301
|
InstaVM,
|
|
@@ -1293,6 +2304,11 @@ var InstaVM = class {
|
|
|
1293
2304
|
QuotaExceededError,
|
|
1294
2305
|
RateLimitError,
|
|
1295
2306
|
SessionError,
|
|
1296
|
-
|
|
2307
|
+
SharesManager,
|
|
2308
|
+
SnapshotsManager,
|
|
2309
|
+
UnsupportedOperationError,
|
|
2310
|
+
VMsManager,
|
|
2311
|
+
VolumesManager,
|
|
2312
|
+
WebhooksManager
|
|
1297
2313
|
});
|
|
1298
2314
|
//# sourceMappingURL=index.js.map
|