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.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.11.0"
|
|
143
143
|
}
|
|
144
144
|
});
|
|
145
145
|
this.setupInterceptors();
|
|
@@ -311,6 +311,39 @@ var HTTPClient = class {
|
|
|
311
311
|
headers
|
|
312
312
|
});
|
|
313
313
|
}
|
|
314
|
+
/**
|
|
315
|
+
* PUT request
|
|
316
|
+
*/
|
|
317
|
+
async put(url, data, headers) {
|
|
318
|
+
return this.request({
|
|
319
|
+
method: "PUT",
|
|
320
|
+
url,
|
|
321
|
+
data,
|
|
322
|
+
headers
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* PATCH request
|
|
327
|
+
*/
|
|
328
|
+
async patch(url, data, headers) {
|
|
329
|
+
return this.request({
|
|
330
|
+
method: "PATCH",
|
|
331
|
+
url,
|
|
332
|
+
data,
|
|
333
|
+
headers
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* OPTIONS request
|
|
338
|
+
*/
|
|
339
|
+
async options(url, headers, params) {
|
|
340
|
+
return this.request({
|
|
341
|
+
method: "OPTIONS",
|
|
342
|
+
url,
|
|
343
|
+
headers,
|
|
344
|
+
params
|
|
345
|
+
});
|
|
346
|
+
}
|
|
314
347
|
/**
|
|
315
348
|
* POST request that returns raw binary data (for file downloads)
|
|
316
349
|
*/
|
|
@@ -877,13 +910,525 @@ var BrowserManager = class {
|
|
|
877
910
|
}
|
|
878
911
|
};
|
|
879
912
|
|
|
913
|
+
// src/utils/path.ts
|
|
914
|
+
function encodePathSegment(value) {
|
|
915
|
+
return encodeURIComponent(String(value));
|
|
916
|
+
}
|
|
917
|
+
function encodePathSegments(path) {
|
|
918
|
+
const segments = path.replace(/^\/+/, "").split("/").filter((segment) => segment.length > 0 && segment !== ".");
|
|
919
|
+
if (segments.some((segment) => segment === "..")) {
|
|
920
|
+
throw new Error("Path traversal not allowed in proxy path");
|
|
921
|
+
}
|
|
922
|
+
return segments.map((segment) => encodeURIComponent(segment)).join("/");
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
// src/client/VMsManager.ts
|
|
926
|
+
var VMsManager = class {
|
|
927
|
+
constructor(httpClient, local = false) {
|
|
928
|
+
this.httpClient = httpClient;
|
|
929
|
+
this.local = local;
|
|
930
|
+
}
|
|
931
|
+
ensureCloud(operation) {
|
|
932
|
+
if (this.local) {
|
|
933
|
+
throw new UnsupportedOperationError(
|
|
934
|
+
`${operation} is not supported in local mode.`
|
|
935
|
+
);
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
async create(payload = {}, wait = true) {
|
|
939
|
+
this.ensureCloud("VM creation");
|
|
940
|
+
return this.httpClient.request({
|
|
941
|
+
method: "POST",
|
|
942
|
+
url: "/v1/vms",
|
|
943
|
+
params: { wait },
|
|
944
|
+
data: payload,
|
|
945
|
+
headers: { "X-API-Key": this.httpClient.apiKey }
|
|
946
|
+
});
|
|
947
|
+
}
|
|
948
|
+
async list() {
|
|
949
|
+
this.ensureCloud("VM listing");
|
|
950
|
+
return this.httpClient.get(
|
|
951
|
+
"/v1/vms",
|
|
952
|
+
void 0,
|
|
953
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
954
|
+
);
|
|
955
|
+
}
|
|
956
|
+
async listAll() {
|
|
957
|
+
return this.listAllRecords();
|
|
958
|
+
}
|
|
959
|
+
/**
|
|
960
|
+
* Calls GET /v1/vms/ (trailing slash), a distinct route from GET /v1/vms.
|
|
961
|
+
*/
|
|
962
|
+
async listAllRecords() {
|
|
963
|
+
this.ensureCloud("VM listing");
|
|
964
|
+
return this.httpClient.get(
|
|
965
|
+
"/v1/vms/",
|
|
966
|
+
void 0,
|
|
967
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
968
|
+
);
|
|
969
|
+
}
|
|
970
|
+
async get(itemId) {
|
|
971
|
+
this.ensureCloud("VM lookup");
|
|
972
|
+
const safeItemId = encodePathSegment(itemId);
|
|
973
|
+
return this.httpClient.get(
|
|
974
|
+
`/v1/vms/${safeItemId}`,
|
|
975
|
+
void 0,
|
|
976
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
977
|
+
);
|
|
978
|
+
}
|
|
979
|
+
async update(vmId, payload = {}) {
|
|
980
|
+
this.ensureCloud("VM update");
|
|
981
|
+
const safeVmId = encodePathSegment(vmId);
|
|
982
|
+
return this.httpClient.patch(
|
|
983
|
+
`/v1/vms/${safeVmId}`,
|
|
984
|
+
payload,
|
|
985
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
986
|
+
);
|
|
987
|
+
}
|
|
988
|
+
async delete(vmId) {
|
|
989
|
+
this.ensureCloud("VM deletion");
|
|
990
|
+
const safeVmId = encodePathSegment(vmId);
|
|
991
|
+
return this.httpClient.delete(
|
|
992
|
+
`/v1/vms/${safeVmId}`,
|
|
993
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
994
|
+
);
|
|
995
|
+
}
|
|
996
|
+
async clone(vmId, payload = {}, wait = true) {
|
|
997
|
+
this.ensureCloud("VM clone");
|
|
998
|
+
const safeVmId = encodePathSegment(vmId);
|
|
999
|
+
return this.httpClient.request({
|
|
1000
|
+
method: "POST",
|
|
1001
|
+
url: `/v1/vms/${safeVmId}/clone`,
|
|
1002
|
+
params: { wait },
|
|
1003
|
+
data: payload,
|
|
1004
|
+
headers: { "X-API-Key": this.httpClient.apiKey }
|
|
1005
|
+
});
|
|
1006
|
+
}
|
|
1007
|
+
async snapshot(vmId, payload = {}, wait = true) {
|
|
1008
|
+
this.ensureCloud("VM snapshot");
|
|
1009
|
+
const safeVmId = encodePathSegment(vmId);
|
|
1010
|
+
return this.httpClient.request({
|
|
1011
|
+
method: "POST",
|
|
1012
|
+
url: `/v1/vms/${safeVmId}/snapshot`,
|
|
1013
|
+
params: { wait },
|
|
1014
|
+
data: payload,
|
|
1015
|
+
headers: { "X-API-Key": this.httpClient.apiKey }
|
|
1016
|
+
});
|
|
1017
|
+
}
|
|
1018
|
+
};
|
|
1019
|
+
|
|
1020
|
+
// src/client/SnapshotsManager.ts
|
|
1021
|
+
var SnapshotsManager = class {
|
|
1022
|
+
constructor(httpClient, local = false) {
|
|
1023
|
+
this.httpClient = httpClient;
|
|
1024
|
+
this.local = local;
|
|
1025
|
+
}
|
|
1026
|
+
ensureCloud(operation) {
|
|
1027
|
+
if (this.local) {
|
|
1028
|
+
throw new UnsupportedOperationError(
|
|
1029
|
+
`${operation} is not supported in local mode.`
|
|
1030
|
+
);
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
async create(payload) {
|
|
1034
|
+
this.ensureCloud("Snapshot creation");
|
|
1035
|
+
return this.httpClient.post(
|
|
1036
|
+
"/v1/snapshots",
|
|
1037
|
+
payload,
|
|
1038
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1039
|
+
);
|
|
1040
|
+
}
|
|
1041
|
+
async list(options = {}) {
|
|
1042
|
+
this.ensureCloud("Snapshot listing");
|
|
1043
|
+
return this.httpClient.get(
|
|
1044
|
+
"/v1/snapshots",
|
|
1045
|
+
options,
|
|
1046
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1047
|
+
);
|
|
1048
|
+
}
|
|
1049
|
+
async get(snapshotId) {
|
|
1050
|
+
this.ensureCloud("Snapshot lookup");
|
|
1051
|
+
const safeSnapshotId = encodePathSegment(snapshotId);
|
|
1052
|
+
return this.httpClient.get(
|
|
1053
|
+
`/v1/snapshots/${safeSnapshotId}`,
|
|
1054
|
+
void 0,
|
|
1055
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1056
|
+
);
|
|
1057
|
+
}
|
|
1058
|
+
async delete(snapshotId) {
|
|
1059
|
+
this.ensureCloud("Snapshot deletion");
|
|
1060
|
+
const safeSnapshotId = encodePathSegment(snapshotId);
|
|
1061
|
+
return this.httpClient.delete(
|
|
1062
|
+
`/v1/snapshots/${safeSnapshotId}`,
|
|
1063
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1064
|
+
);
|
|
1065
|
+
}
|
|
1066
|
+
};
|
|
1067
|
+
|
|
1068
|
+
// src/client/SharesManager.ts
|
|
1069
|
+
var SharesManager = class {
|
|
1070
|
+
constructor(httpClient, local = false, getSessionId = () => null) {
|
|
1071
|
+
this.httpClient = httpClient;
|
|
1072
|
+
this.local = local;
|
|
1073
|
+
this.getSessionId = getSessionId;
|
|
1074
|
+
}
|
|
1075
|
+
ensureCloud(operation) {
|
|
1076
|
+
if (this.local) {
|
|
1077
|
+
throw new UnsupportedOperationError(
|
|
1078
|
+
`${operation} is not supported in local mode.`
|
|
1079
|
+
);
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
async create(payload) {
|
|
1083
|
+
this.ensureCloud("Share creation");
|
|
1084
|
+
const body = { ...payload };
|
|
1085
|
+
if (!body.session_id && !body.vm_id) {
|
|
1086
|
+
const sid = this.getSessionId();
|
|
1087
|
+
if (!sid) {
|
|
1088
|
+
throw new SessionError(
|
|
1089
|
+
"Provide session_id/vm_id or create a session before creating a share."
|
|
1090
|
+
);
|
|
1091
|
+
}
|
|
1092
|
+
body.session_id = sid;
|
|
1093
|
+
}
|
|
1094
|
+
return this.httpClient.post(
|
|
1095
|
+
"/v1/shares",
|
|
1096
|
+
body,
|
|
1097
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1098
|
+
);
|
|
1099
|
+
}
|
|
1100
|
+
async update(shareId, payload) {
|
|
1101
|
+
this.ensureCloud("Share update");
|
|
1102
|
+
const safeShareId = encodePathSegment(shareId);
|
|
1103
|
+
return this.httpClient.patch(
|
|
1104
|
+
`/v1/shares/${safeShareId}`,
|
|
1105
|
+
payload,
|
|
1106
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1107
|
+
);
|
|
1108
|
+
}
|
|
1109
|
+
};
|
|
1110
|
+
|
|
1111
|
+
// src/client/CustomDomainsManager.ts
|
|
1112
|
+
var CustomDomainsManager = class {
|
|
1113
|
+
constructor(httpClient, local = false) {
|
|
1114
|
+
this.httpClient = httpClient;
|
|
1115
|
+
this.local = local;
|
|
1116
|
+
}
|
|
1117
|
+
ensureCloud(operation) {
|
|
1118
|
+
if (this.local) {
|
|
1119
|
+
throw new UnsupportedOperationError(
|
|
1120
|
+
`${operation} is not supported in local mode.`
|
|
1121
|
+
);
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
async create(payload) {
|
|
1125
|
+
this.ensureCloud("Custom domain creation");
|
|
1126
|
+
return this.httpClient.post(
|
|
1127
|
+
"/v1/custom-domains",
|
|
1128
|
+
payload,
|
|
1129
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1130
|
+
);
|
|
1131
|
+
}
|
|
1132
|
+
async list() {
|
|
1133
|
+
this.ensureCloud("Custom domain listing");
|
|
1134
|
+
return this.httpClient.get(
|
|
1135
|
+
"/v1/custom-domains",
|
|
1136
|
+
void 0,
|
|
1137
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1138
|
+
);
|
|
1139
|
+
}
|
|
1140
|
+
async health(domainId) {
|
|
1141
|
+
this.ensureCloud("Custom domain health");
|
|
1142
|
+
const safeDomainId = encodePathSegment(domainId);
|
|
1143
|
+
return this.httpClient.get(
|
|
1144
|
+
`/v1/custom-domains/${safeDomainId}/health`,
|
|
1145
|
+
void 0,
|
|
1146
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1147
|
+
);
|
|
1148
|
+
}
|
|
1149
|
+
async verify(domainId) {
|
|
1150
|
+
this.ensureCloud("Custom domain verification");
|
|
1151
|
+
const safeDomainId = encodePathSegment(domainId);
|
|
1152
|
+
return this.httpClient.post(
|
|
1153
|
+
`/v1/custom-domains/${safeDomainId}/verify`,
|
|
1154
|
+
{},
|
|
1155
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1156
|
+
);
|
|
1157
|
+
}
|
|
1158
|
+
async delete(domainId) {
|
|
1159
|
+
this.ensureCloud("Custom domain deletion");
|
|
1160
|
+
const safeDomainId = encodePathSegment(domainId);
|
|
1161
|
+
return this.httpClient.delete(
|
|
1162
|
+
`/v1/custom-domains/${safeDomainId}`,
|
|
1163
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1164
|
+
);
|
|
1165
|
+
}
|
|
1166
|
+
};
|
|
1167
|
+
|
|
1168
|
+
// src/client/ComputerUseManager.ts
|
|
1169
|
+
var ComputerUseManager = class {
|
|
1170
|
+
constructor(httpClient, local = false) {
|
|
1171
|
+
this.httpClient = httpClient;
|
|
1172
|
+
this.local = local;
|
|
1173
|
+
}
|
|
1174
|
+
ensureCloud(operation) {
|
|
1175
|
+
if (this.local) {
|
|
1176
|
+
throw new UnsupportedOperationError(
|
|
1177
|
+
`${operation} is not supported in local mode.`
|
|
1178
|
+
);
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
async viewerUrl(sessionId) {
|
|
1182
|
+
this.ensureCloud("Computer-use viewer URL");
|
|
1183
|
+
const safeSessionId = encodePathSegment(sessionId);
|
|
1184
|
+
return this.httpClient.get(
|
|
1185
|
+
`/v1/computeruse/${safeSessionId}/viewer-url`,
|
|
1186
|
+
void 0,
|
|
1187
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1188
|
+
);
|
|
1189
|
+
}
|
|
1190
|
+
async proxy(sessionId, path, method = "GET", options = {}) {
|
|
1191
|
+
this.ensureCloud("Computer-use proxy");
|
|
1192
|
+
const safeSessionId = encodePathSegment(sessionId);
|
|
1193
|
+
const cleanPath = encodePathSegments(path);
|
|
1194
|
+
return this.httpClient.request({
|
|
1195
|
+
method,
|
|
1196
|
+
url: `/v1/computeruse/${safeSessionId}/${cleanPath}`,
|
|
1197
|
+
params: options.params,
|
|
1198
|
+
data: options.body,
|
|
1199
|
+
headers: { "X-API-Key": this.httpClient.apiKey }
|
|
1200
|
+
});
|
|
1201
|
+
}
|
|
1202
|
+
async get(sessionId, path, params) {
|
|
1203
|
+
return this.proxy(sessionId, path, "GET", { params });
|
|
1204
|
+
}
|
|
1205
|
+
async post(sessionId, path, body) {
|
|
1206
|
+
return this.proxy(sessionId, path, "POST", { body });
|
|
1207
|
+
}
|
|
1208
|
+
async put(sessionId, path, body) {
|
|
1209
|
+
return this.proxy(sessionId, path, "PUT", { body });
|
|
1210
|
+
}
|
|
1211
|
+
async patch(sessionId, path, body) {
|
|
1212
|
+
return this.proxy(sessionId, path, "PATCH", { body });
|
|
1213
|
+
}
|
|
1214
|
+
async delete(sessionId, path, params) {
|
|
1215
|
+
return this.proxy(sessionId, path, "DELETE", { params });
|
|
1216
|
+
}
|
|
1217
|
+
async options(sessionId, path, params) {
|
|
1218
|
+
return this.proxy(sessionId, path, "OPTIONS", { params });
|
|
1219
|
+
}
|
|
1220
|
+
};
|
|
1221
|
+
|
|
1222
|
+
// src/client/APIKeysManager.ts
|
|
1223
|
+
var APIKeysManager = class {
|
|
1224
|
+
constructor(httpClient, local = false) {
|
|
1225
|
+
this.httpClient = httpClient;
|
|
1226
|
+
this.local = local;
|
|
1227
|
+
}
|
|
1228
|
+
ensureCloud(operation) {
|
|
1229
|
+
if (this.local) {
|
|
1230
|
+
throw new UnsupportedOperationError(
|
|
1231
|
+
`${operation} is not supported in local mode.`
|
|
1232
|
+
);
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
async create(payload = {}) {
|
|
1236
|
+
this.ensureCloud("API key creation");
|
|
1237
|
+
return this.httpClient.post(
|
|
1238
|
+
"/v1/api-keys/",
|
|
1239
|
+
payload,
|
|
1240
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1241
|
+
);
|
|
1242
|
+
}
|
|
1243
|
+
async list() {
|
|
1244
|
+
this.ensureCloud("API key listing");
|
|
1245
|
+
return this.httpClient.get(
|
|
1246
|
+
"/v1/api-keys/",
|
|
1247
|
+
void 0,
|
|
1248
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1249
|
+
);
|
|
1250
|
+
}
|
|
1251
|
+
async get(itemId) {
|
|
1252
|
+
this.ensureCloud("API key lookup");
|
|
1253
|
+
const safeItemId = encodePathSegment(itemId);
|
|
1254
|
+
return this.httpClient.get(
|
|
1255
|
+
`/v1/api-keys/${safeItemId}`,
|
|
1256
|
+
void 0,
|
|
1257
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1258
|
+
);
|
|
1259
|
+
}
|
|
1260
|
+
async update(itemId, payload) {
|
|
1261
|
+
this.ensureCloud("API key update");
|
|
1262
|
+
const safeItemId = encodePathSegment(itemId);
|
|
1263
|
+
return this.httpClient.patch(
|
|
1264
|
+
`/v1/api-keys/${safeItemId}`,
|
|
1265
|
+
payload,
|
|
1266
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1267
|
+
);
|
|
1268
|
+
}
|
|
1269
|
+
async delete(itemId) {
|
|
1270
|
+
this.ensureCloud("API key deletion");
|
|
1271
|
+
const safeItemId = encodePathSegment(itemId);
|
|
1272
|
+
return this.httpClient.delete(
|
|
1273
|
+
`/v1/api-keys/${safeItemId}`,
|
|
1274
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1275
|
+
);
|
|
1276
|
+
}
|
|
1277
|
+
};
|
|
1278
|
+
|
|
1279
|
+
// src/client/AuditManager.ts
|
|
1280
|
+
var AuditManager = class {
|
|
1281
|
+
constructor(httpClient, local = false) {
|
|
1282
|
+
this.httpClient = httpClient;
|
|
1283
|
+
this.local = local;
|
|
1284
|
+
}
|
|
1285
|
+
ensureCloud(operation) {
|
|
1286
|
+
if (this.local) {
|
|
1287
|
+
throw new UnsupportedOperationError(
|
|
1288
|
+
`${operation} is not supported in local mode.`
|
|
1289
|
+
);
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
async catalog() {
|
|
1293
|
+
this.ensureCloud("Audit catalog");
|
|
1294
|
+
return this.httpClient.get(
|
|
1295
|
+
"/v1/audit/catalog",
|
|
1296
|
+
void 0,
|
|
1297
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1298
|
+
);
|
|
1299
|
+
}
|
|
1300
|
+
async events(query = {}) {
|
|
1301
|
+
this.ensureCloud("Audit event listing");
|
|
1302
|
+
return this.httpClient.get(
|
|
1303
|
+
"/v1/audit/events",
|
|
1304
|
+
query,
|
|
1305
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1306
|
+
);
|
|
1307
|
+
}
|
|
1308
|
+
async getEvent(eventId) {
|
|
1309
|
+
this.ensureCloud("Audit event lookup");
|
|
1310
|
+
const safeEventId = encodePathSegment(eventId);
|
|
1311
|
+
return this.httpClient.get(
|
|
1312
|
+
`/v1/audit/events/${safeEventId}`,
|
|
1313
|
+
void 0,
|
|
1314
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1315
|
+
);
|
|
1316
|
+
}
|
|
1317
|
+
};
|
|
1318
|
+
|
|
1319
|
+
// src/client/WebhooksManager.ts
|
|
1320
|
+
var WebhooksManager = class {
|
|
1321
|
+
constructor(httpClient, local = false) {
|
|
1322
|
+
this.httpClient = httpClient;
|
|
1323
|
+
this.local = local;
|
|
1324
|
+
}
|
|
1325
|
+
ensureCloud(operation) {
|
|
1326
|
+
if (this.local) {
|
|
1327
|
+
throw new UnsupportedOperationError(
|
|
1328
|
+
`${operation} is not supported in local mode.`
|
|
1329
|
+
);
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
async createEndpoint(payload) {
|
|
1333
|
+
this.ensureCloud("Webhook endpoint creation");
|
|
1334
|
+
return this.httpClient.post(
|
|
1335
|
+
"/v1/webhooks/endpoints",
|
|
1336
|
+
payload,
|
|
1337
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1338
|
+
);
|
|
1339
|
+
}
|
|
1340
|
+
async listEndpoints() {
|
|
1341
|
+
this.ensureCloud("Webhook endpoint listing");
|
|
1342
|
+
return this.httpClient.get(
|
|
1343
|
+
"/v1/webhooks/endpoints",
|
|
1344
|
+
void 0,
|
|
1345
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1346
|
+
);
|
|
1347
|
+
}
|
|
1348
|
+
async getEndpoint(endpointId) {
|
|
1349
|
+
this.ensureCloud("Webhook endpoint lookup");
|
|
1350
|
+
const safeEndpointId = encodePathSegment(endpointId);
|
|
1351
|
+
return this.httpClient.get(
|
|
1352
|
+
`/v1/webhooks/endpoints/${safeEndpointId}`,
|
|
1353
|
+
void 0,
|
|
1354
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1355
|
+
);
|
|
1356
|
+
}
|
|
1357
|
+
async updateEndpoint(endpointId, payload) {
|
|
1358
|
+
this.ensureCloud("Webhook endpoint update");
|
|
1359
|
+
const safeEndpointId = encodePathSegment(endpointId);
|
|
1360
|
+
return this.httpClient.patch(
|
|
1361
|
+
`/v1/webhooks/endpoints/${safeEndpointId}`,
|
|
1362
|
+
payload,
|
|
1363
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1364
|
+
);
|
|
1365
|
+
}
|
|
1366
|
+
async deleteEndpoint(endpointId) {
|
|
1367
|
+
this.ensureCloud("Webhook endpoint deletion");
|
|
1368
|
+
const safeEndpointId = encodePathSegment(endpointId);
|
|
1369
|
+
return this.httpClient.delete(
|
|
1370
|
+
`/v1/webhooks/endpoints/${safeEndpointId}`,
|
|
1371
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1372
|
+
);
|
|
1373
|
+
}
|
|
1374
|
+
async rotateSecret(endpointId) {
|
|
1375
|
+
this.ensureCloud("Webhook secret rotation");
|
|
1376
|
+
const safeEndpointId = encodePathSegment(endpointId);
|
|
1377
|
+
return this.httpClient.post(
|
|
1378
|
+
`/v1/webhooks/endpoints/${safeEndpointId}/rotate-secret`,
|
|
1379
|
+
{},
|
|
1380
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1381
|
+
);
|
|
1382
|
+
}
|
|
1383
|
+
async sendTestEvent(endpointId) {
|
|
1384
|
+
this.ensureCloud("Webhook test event");
|
|
1385
|
+
const safeEndpointId = encodePathSegment(endpointId);
|
|
1386
|
+
return this.httpClient.post(
|
|
1387
|
+
`/v1/webhooks/endpoints/${safeEndpointId}/test`,
|
|
1388
|
+
{},
|
|
1389
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1390
|
+
);
|
|
1391
|
+
}
|
|
1392
|
+
async verifyEndpoint(endpointId) {
|
|
1393
|
+
this.ensureCloud("Webhook endpoint verification");
|
|
1394
|
+
const safeEndpointId = encodePathSegment(endpointId);
|
|
1395
|
+
return this.httpClient.post(
|
|
1396
|
+
`/v1/webhooks/endpoints/${safeEndpointId}/verify`,
|
|
1397
|
+
{},
|
|
1398
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1399
|
+
);
|
|
1400
|
+
}
|
|
1401
|
+
async listDeliveries(query = {}) {
|
|
1402
|
+
this.ensureCloud("Webhook delivery listing");
|
|
1403
|
+
return this.httpClient.get(
|
|
1404
|
+
"/v1/webhooks/deliveries",
|
|
1405
|
+
query,
|
|
1406
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1407
|
+
);
|
|
1408
|
+
}
|
|
1409
|
+
async replayDelivery(deliveryId) {
|
|
1410
|
+
this.ensureCloud("Webhook delivery replay");
|
|
1411
|
+
const safeDeliveryId = encodePathSegment(deliveryId);
|
|
1412
|
+
return this.httpClient.post(
|
|
1413
|
+
`/v1/webhooks/deliveries/${safeDeliveryId}/replay`,
|
|
1414
|
+
{},
|
|
1415
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1416
|
+
);
|
|
1417
|
+
}
|
|
1418
|
+
};
|
|
1419
|
+
|
|
880
1420
|
// src/client/InstaVM.ts
|
|
881
1421
|
import FormData from "form-data";
|
|
882
1422
|
var InstaVM = class {
|
|
883
1423
|
constructor(apiKey, options = {}) {
|
|
884
1424
|
this._sessionId = null;
|
|
1425
|
+
this._vmUsed = false;
|
|
885
1426
|
this.local = options.local || false;
|
|
886
1427
|
this.timeout = options.timeout || 3e5;
|
|
1428
|
+
this.memory_mb = options.memory_mb;
|
|
1429
|
+
this.cpu_count = options.cpu_count;
|
|
1430
|
+
this.metadata = options.metadata;
|
|
1431
|
+
this.env = options.env;
|
|
887
1432
|
if (!this.local && !apiKey) {
|
|
888
1433
|
throw new AuthenticationError("API key is required for cloud mode");
|
|
889
1434
|
}
|
|
@@ -896,6 +1441,14 @@ var InstaVM = class {
|
|
|
896
1441
|
};
|
|
897
1442
|
this.httpClient = new HTTPClient(config);
|
|
898
1443
|
this.browser = new BrowserManager(this.httpClient, this.local);
|
|
1444
|
+
this.vms = new VMsManager(this.httpClient, this.local);
|
|
1445
|
+
this.snapshots = new SnapshotsManager(this.httpClient, this.local);
|
|
1446
|
+
this.shares = new SharesManager(this.httpClient, this.local, () => this._sessionId);
|
|
1447
|
+
this.customDomains = new CustomDomainsManager(this.httpClient, this.local);
|
|
1448
|
+
this.computerUse = new ComputerUseManager(this.httpClient, this.local);
|
|
1449
|
+
this.apiKeys = new APIKeysManager(this.httpClient, this.local);
|
|
1450
|
+
this.audit = new AuditManager(this.httpClient, this.local);
|
|
1451
|
+
this.webhooks = new WebhooksManager(this.httpClient, this.local);
|
|
899
1452
|
}
|
|
900
1453
|
/**
|
|
901
1454
|
* Ensure operation is not called in local mode
|
|
@@ -941,6 +1494,9 @@ var InstaVM = class {
|
|
|
941
1494
|
if (response.session_id) {
|
|
942
1495
|
this._sessionId = response.session_id;
|
|
943
1496
|
}
|
|
1497
|
+
if (!this.local) {
|
|
1498
|
+
this._vmUsed = true;
|
|
1499
|
+
}
|
|
944
1500
|
return {
|
|
945
1501
|
stdout: response.stdout || "",
|
|
946
1502
|
stderr: response.stderr || "",
|
|
@@ -984,6 +1540,7 @@ var InstaVM = class {
|
|
|
984
1540
|
if (response.session_id) {
|
|
985
1541
|
this._sessionId = response.session_id;
|
|
986
1542
|
}
|
|
1543
|
+
this._vmUsed = true;
|
|
987
1544
|
return {
|
|
988
1545
|
taskId: response.task_id,
|
|
989
1546
|
status: response.status || "pending",
|
|
@@ -1097,10 +1654,26 @@ var InstaVM = class {
|
|
|
1097
1654
|
async createSession() {
|
|
1098
1655
|
this.ensureNotLocal("Session management");
|
|
1099
1656
|
try {
|
|
1100
|
-
const
|
|
1657
|
+
const requestBody = {
|
|
1101
1658
|
api_key: this.httpClient.apiKey,
|
|
1102
1659
|
vm_lifetime_seconds: Math.floor(this.timeout / 1e3)
|
|
1103
|
-
}
|
|
1660
|
+
};
|
|
1661
|
+
if (this.memory_mb !== void 0) {
|
|
1662
|
+
requestBody.memory_mb = this.memory_mb;
|
|
1663
|
+
}
|
|
1664
|
+
if (this.cpu_count !== void 0) {
|
|
1665
|
+
requestBody.vcpu_count = this.cpu_count;
|
|
1666
|
+
}
|
|
1667
|
+
if (this.metadata !== void 0) {
|
|
1668
|
+
requestBody.metadata = this.metadata;
|
|
1669
|
+
}
|
|
1670
|
+
if (this.env !== void 0) {
|
|
1671
|
+
requestBody.env = this.env;
|
|
1672
|
+
}
|
|
1673
|
+
const response = await this.httpClient.post(
|
|
1674
|
+
"/v1/sessions/session",
|
|
1675
|
+
requestBody
|
|
1676
|
+
);
|
|
1104
1677
|
if (response.session_id) {
|
|
1105
1678
|
this._sessionId = response.session_id;
|
|
1106
1679
|
return response.session_id;
|
|
@@ -1214,17 +1787,193 @@ var InstaVM = class {
|
|
|
1214
1787
|
get sessionId() {
|
|
1215
1788
|
return this._sessionId;
|
|
1216
1789
|
}
|
|
1790
|
+
/**
|
|
1791
|
+
* Kill the VM associated with a session
|
|
1792
|
+
*
|
|
1793
|
+
* @param sessionId - The session UUID whose VM should be killed. If not provided, uses current sessionId
|
|
1794
|
+
* @returns Result containing success message and killed VM ID
|
|
1795
|
+
*/
|
|
1796
|
+
async kill(sessionId) {
|
|
1797
|
+
this.ensureNotLocal("VM kill operation");
|
|
1798
|
+
const targetSessionId = sessionId || this._sessionId;
|
|
1799
|
+
if (!targetSessionId) {
|
|
1800
|
+
throw new SessionError("Session ID not set. Please provide a sessionId or start a session first.");
|
|
1801
|
+
}
|
|
1802
|
+
try {
|
|
1803
|
+
const response = await this.httpClient.post(
|
|
1804
|
+
"/kill",
|
|
1805
|
+
{ session_id: targetSessionId },
|
|
1806
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1807
|
+
);
|
|
1808
|
+
if (!sessionId && this._sessionId === targetSessionId) {
|
|
1809
|
+
this._sessionId = null;
|
|
1810
|
+
}
|
|
1811
|
+
return response;
|
|
1812
|
+
} catch (error) {
|
|
1813
|
+
if (error instanceof Error && "statusCode" in error) {
|
|
1814
|
+
const statusCode = error.statusCode;
|
|
1815
|
+
if (statusCode === 403) {
|
|
1816
|
+
throw new AuthenticationError("You don't own this session", { cause: error });
|
|
1817
|
+
}
|
|
1818
|
+
if (statusCode === 404) {
|
|
1819
|
+
throw new SessionError("Session not found or no VM assigned to session (has execute() been called?)", { cause: error });
|
|
1820
|
+
}
|
|
1821
|
+
}
|
|
1822
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1823
|
+
throw new SessionError(
|
|
1824
|
+
`Failed to kill VM: ${errorMessage}`,
|
|
1825
|
+
{ cause: error }
|
|
1826
|
+
);
|
|
1827
|
+
}
|
|
1828
|
+
}
|
|
1829
|
+
// --- Egress Policy Methods ---
|
|
1830
|
+
/**
|
|
1831
|
+
* Set egress policy for a session
|
|
1832
|
+
*/
|
|
1833
|
+
async setSessionEgress(options = {}, sessionId) {
|
|
1834
|
+
this.ensureNotLocal("Egress policy management");
|
|
1835
|
+
const targetSessionId = sessionId || this._sessionId;
|
|
1836
|
+
if (!targetSessionId) {
|
|
1837
|
+
throw new SessionError("Session ID not set. Please create a session first.");
|
|
1838
|
+
}
|
|
1839
|
+
const response = await this.httpClient.post(
|
|
1840
|
+
`/v1/egress/session/${targetSessionId}`,
|
|
1841
|
+
{
|
|
1842
|
+
allow_public_repos: options.allowPackageManagers ?? true,
|
|
1843
|
+
allow_http: options.allowHttp ?? true,
|
|
1844
|
+
allow_https: options.allowHttps ?? true,
|
|
1845
|
+
allowed_domains: options.allowedDomains ?? [],
|
|
1846
|
+
allowed_cidrs: options.allowedCidrs ?? []
|
|
1847
|
+
},
|
|
1848
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1849
|
+
);
|
|
1850
|
+
return response;
|
|
1851
|
+
}
|
|
1852
|
+
/**
|
|
1853
|
+
* Get egress policy for a session
|
|
1854
|
+
*/
|
|
1855
|
+
async getSessionEgress(sessionId) {
|
|
1856
|
+
this.ensureNotLocal("Egress policy management");
|
|
1857
|
+
const targetSessionId = sessionId || this._sessionId;
|
|
1858
|
+
if (!targetSessionId) {
|
|
1859
|
+
throw new SessionError("Session ID not set. Please create a session first.");
|
|
1860
|
+
}
|
|
1861
|
+
const response = await this.httpClient.get(
|
|
1862
|
+
`/v1/egress/session/${targetSessionId}`,
|
|
1863
|
+
void 0,
|
|
1864
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1865
|
+
);
|
|
1866
|
+
return {
|
|
1867
|
+
allowPackageManagers: response.allow_public_repos,
|
|
1868
|
+
allowHttp: response.allow_http,
|
|
1869
|
+
allowHttps: response.allow_https,
|
|
1870
|
+
allowedDomains: response.allowed_domains || [],
|
|
1871
|
+
allowedCidrs: response.allowed_cidrs || []
|
|
1872
|
+
};
|
|
1873
|
+
}
|
|
1874
|
+
/**
|
|
1875
|
+
* Set egress policy for a specific VM
|
|
1876
|
+
*/
|
|
1877
|
+
async setVmEgress(vmId, options = {}) {
|
|
1878
|
+
this.ensureNotLocal("Egress policy management");
|
|
1879
|
+
const response = await this.httpClient.post(
|
|
1880
|
+
`/v1/egress/vm/${vmId}`,
|
|
1881
|
+
{
|
|
1882
|
+
allow_public_repos: options.allowPackageManagers ?? true,
|
|
1883
|
+
allow_http: options.allowHttp ?? true,
|
|
1884
|
+
allow_https: options.allowHttps ?? true,
|
|
1885
|
+
allowed_domains: options.allowedDomains ?? [],
|
|
1886
|
+
allowed_cidrs: options.allowedCidrs ?? []
|
|
1887
|
+
},
|
|
1888
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1889
|
+
);
|
|
1890
|
+
return response;
|
|
1891
|
+
}
|
|
1892
|
+
/**
|
|
1893
|
+
* Get egress policy for a specific VM
|
|
1894
|
+
*/
|
|
1895
|
+
async getVmEgress(vmId) {
|
|
1896
|
+
this.ensureNotLocal("Egress policy management");
|
|
1897
|
+
const response = await this.httpClient.get(
|
|
1898
|
+
`/v1/egress/vm/${vmId}`,
|
|
1899
|
+
void 0,
|
|
1900
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1901
|
+
);
|
|
1902
|
+
return {
|
|
1903
|
+
allowPackageManagers: response.allow_public_repos,
|
|
1904
|
+
allowHttp: response.allow_http,
|
|
1905
|
+
allowHttps: response.allow_https,
|
|
1906
|
+
allowedDomains: response.allowed_domains || [],
|
|
1907
|
+
allowedCidrs: response.allowed_cidrs || []
|
|
1908
|
+
};
|
|
1909
|
+
}
|
|
1910
|
+
// --- SSH Key Methods ---
|
|
1911
|
+
/**
|
|
1912
|
+
* Add an SSH public key
|
|
1913
|
+
*/
|
|
1914
|
+
async addSshKey(publicKey) {
|
|
1915
|
+
this.ensureNotLocal("SSH key management");
|
|
1916
|
+
const response = await this.httpClient.post(
|
|
1917
|
+
"/v1/ssh-keys",
|
|
1918
|
+
{ public_key: publicKey },
|
|
1919
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1920
|
+
);
|
|
1921
|
+
return {
|
|
1922
|
+
id: response.id,
|
|
1923
|
+
fingerprint: response.fingerprint,
|
|
1924
|
+
keyType: response.key_type,
|
|
1925
|
+
comment: response.comment ?? null,
|
|
1926
|
+
createdAt: response.created_at
|
|
1927
|
+
};
|
|
1928
|
+
}
|
|
1929
|
+
/**
|
|
1930
|
+
* List all active SSH keys
|
|
1931
|
+
*/
|
|
1932
|
+
async listSshKeys() {
|
|
1933
|
+
this.ensureNotLocal("SSH key management");
|
|
1934
|
+
const response = await this.httpClient.get(
|
|
1935
|
+
"/v1/ssh-keys",
|
|
1936
|
+
void 0,
|
|
1937
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1938
|
+
);
|
|
1939
|
+
const keys = response.keys || [];
|
|
1940
|
+
return keys.map((k) => ({
|
|
1941
|
+
id: k.id,
|
|
1942
|
+
fingerprint: k.fingerprint,
|
|
1943
|
+
keyType: k.key_type,
|
|
1944
|
+
comment: k.comment ?? null,
|
|
1945
|
+
createdAt: k.created_at
|
|
1946
|
+
}));
|
|
1947
|
+
}
|
|
1948
|
+
/**
|
|
1949
|
+
* Delete an SSH key by ID
|
|
1950
|
+
*/
|
|
1951
|
+
async deleteSshKey(keyId) {
|
|
1952
|
+
this.ensureNotLocal("SSH key management");
|
|
1953
|
+
const response = await this.httpClient.delete(
|
|
1954
|
+
`/v1/ssh-keys/${keyId}`,
|
|
1955
|
+
{ "X-API-Key": this.httpClient.apiKey }
|
|
1956
|
+
);
|
|
1957
|
+
return response;
|
|
1958
|
+
}
|
|
1217
1959
|
/**
|
|
1218
1960
|
* Clean up resources
|
|
1219
1961
|
*/
|
|
1220
1962
|
async dispose() {
|
|
1221
|
-
if (this._sessionId) {
|
|
1963
|
+
if (this._sessionId && !this.local && this._vmUsed) {
|
|
1964
|
+
try {
|
|
1965
|
+
await this.kill();
|
|
1966
|
+
} catch (e) {
|
|
1967
|
+
}
|
|
1968
|
+
} else if (this._sessionId) {
|
|
1222
1969
|
await this.closeSession();
|
|
1223
1970
|
}
|
|
1224
1971
|
await this.browser.dispose();
|
|
1225
1972
|
}
|
|
1226
1973
|
};
|
|
1227
1974
|
export {
|
|
1975
|
+
APIKeysManager,
|
|
1976
|
+
AuditManager,
|
|
1228
1977
|
AuthenticationError,
|
|
1229
1978
|
BrowserError,
|
|
1230
1979
|
BrowserInteractionError,
|
|
@@ -1233,6 +1982,8 @@ export {
|
|
|
1233
1982
|
BrowserSession,
|
|
1234
1983
|
BrowserSessionError,
|
|
1235
1984
|
BrowserTimeoutError,
|
|
1985
|
+
ComputerUseManager,
|
|
1986
|
+
CustomDomainsManager,
|
|
1236
1987
|
ElementNotFoundError,
|
|
1237
1988
|
ExecutionError,
|
|
1238
1989
|
InstaVM,
|
|
@@ -1241,6 +1992,10 @@ export {
|
|
|
1241
1992
|
QuotaExceededError,
|
|
1242
1993
|
RateLimitError,
|
|
1243
1994
|
SessionError,
|
|
1244
|
-
|
|
1995
|
+
SharesManager,
|
|
1996
|
+
SnapshotsManager,
|
|
1997
|
+
UnsupportedOperationError,
|
|
1998
|
+
VMsManager,
|
|
1999
|
+
WebhooksManager
|
|
1245
2000
|
};
|
|
1246
2001
|
//# sourceMappingURL=index.mjs.map
|