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