instavm 0.2.2 → 0.4.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 +149 -21
- package/dist/index.d.mts +97 -3
- package/dist/index.d.ts +97 -3
- package/dist/index.js +227 -112
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +225 -112
- package/dist/index.mjs.map +1 -1
- package/dist/integrations/openai/index.d.mts +2 -1
- package/dist/integrations/openai/index.d.ts +2 -1
- package/dist/integrations/openai/index.js +5 -0
- package/dist/integrations/openai/index.js.map +1 -1
- package/dist/integrations/openai/index.mjs +4 -0
- package/dist/integrations/openai/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -6,9 +6,6 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
6
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
7
|
var __getProtoOf = Object.getPrototypeOf;
|
|
8
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
-
var __commonJS = (cb, mod) => function __require() {
|
|
10
|
-
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
11
|
-
};
|
|
12
9
|
var __export = (target, all) => {
|
|
13
10
|
for (var name in all)
|
|
14
11
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -31,92 +28,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
31
28
|
));
|
|
32
29
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
33
30
|
|
|
34
|
-
// package.json
|
|
35
|
-
var require_package = __commonJS({
|
|
36
|
-
"package.json"(exports2, module2) {
|
|
37
|
-
module2.exports = {
|
|
38
|
-
name: "instavm",
|
|
39
|
-
version: "0.2.2",
|
|
40
|
-
description: "Official JavaScript SDK for InstaVM API",
|
|
41
|
-
main: "dist/index.js",
|
|
42
|
-
module: "dist/index.mjs",
|
|
43
|
-
types: "dist/index.d.ts",
|
|
44
|
-
exports: {
|
|
45
|
-
".": {
|
|
46
|
-
types: "./dist/index.d.ts",
|
|
47
|
-
import: "./dist/index.mjs",
|
|
48
|
-
require: "./dist/index.js"
|
|
49
|
-
},
|
|
50
|
-
"./integrations/openai": {
|
|
51
|
-
types: "./dist/integrations/openai.d.ts",
|
|
52
|
-
import: "./dist/integrations/openai.mjs",
|
|
53
|
-
require: "./dist/integrations/openai.js"
|
|
54
|
-
}
|
|
55
|
-
},
|
|
56
|
-
files: [
|
|
57
|
-
"dist"
|
|
58
|
-
],
|
|
59
|
-
scripts: {
|
|
60
|
-
dev: "tsup --watch",
|
|
61
|
-
build: "tsup",
|
|
62
|
-
"type-check": "tsc --noEmit",
|
|
63
|
-
test: "vitest",
|
|
64
|
-
"test:unit": "vitest run tests/unit",
|
|
65
|
-
"test:integration": "vitest run tests/integration",
|
|
66
|
-
"test:watch": "vitest --watch",
|
|
67
|
-
"test:coverage": "vitest --coverage",
|
|
68
|
-
lint: "eslint src --ext .ts,.tsx",
|
|
69
|
-
"lint:fix": "eslint src --ext .ts,.tsx --fix",
|
|
70
|
-
format: "prettier --write src/**/*.ts",
|
|
71
|
-
prepublishOnly: "npm run build && npm run test:unit",
|
|
72
|
-
clean: "rm -rf dist"
|
|
73
|
-
},
|
|
74
|
-
keywords: [
|
|
75
|
-
"instavm",
|
|
76
|
-
"api",
|
|
77
|
-
"sdk",
|
|
78
|
-
"browser-automation",
|
|
79
|
-
"code-execution",
|
|
80
|
-
"microvm",
|
|
81
|
-
"cloud"
|
|
82
|
-
],
|
|
83
|
-
author: "InstaVM",
|
|
84
|
-
license: "UNLICENSED",
|
|
85
|
-
repository: {
|
|
86
|
-
type: "git",
|
|
87
|
-
url: "https://github.com/instavm/js.git"
|
|
88
|
-
},
|
|
89
|
-
bugs: {
|
|
90
|
-
url: "https://github.com/instavm/js/issues"
|
|
91
|
-
},
|
|
92
|
-
homepage: "https://github.com/instavm/js#readme",
|
|
93
|
-
engines: {
|
|
94
|
-
node: ">=16.0.0"
|
|
95
|
-
},
|
|
96
|
-
dependencies: {
|
|
97
|
-
axios: "^1.7.9",
|
|
98
|
-
eventemitter3: "^5.0.1",
|
|
99
|
-
"form-data": "^4.0.1",
|
|
100
|
-
ws: "^8.18.0"
|
|
101
|
-
},
|
|
102
|
-
devDependencies: {
|
|
103
|
-
"@types/node": "^22.10.5",
|
|
104
|
-
"@types/ws": "^8.5.13",
|
|
105
|
-
"@typescript-eslint/eslint-plugin": "^8.18.2",
|
|
106
|
-
"@typescript-eslint/parser": "^8.18.2",
|
|
107
|
-
"@vitest/coverage-v8": "^2.1.8",
|
|
108
|
-
eslint: "^9.18.0",
|
|
109
|
-
"eslint-config-prettier": "^9.1.0",
|
|
110
|
-
"eslint-plugin-prettier": "^5.2.1",
|
|
111
|
-
prettier: "^3.4.2",
|
|
112
|
-
tsup: "^8.3.5",
|
|
113
|
-
typescript: "^5.7.2",
|
|
114
|
-
vitest: "^2.1.8"
|
|
115
|
-
}
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
});
|
|
119
|
-
|
|
120
31
|
// src/index.ts
|
|
121
32
|
var index_exports = {};
|
|
122
33
|
__export(index_exports, {
|
|
@@ -135,7 +46,8 @@ __export(index_exports, {
|
|
|
135
46
|
NetworkError: () => NetworkError,
|
|
136
47
|
QuotaExceededError: () => QuotaExceededError,
|
|
137
48
|
RateLimitError: () => RateLimitError,
|
|
138
|
-
SessionError: () => SessionError
|
|
49
|
+
SessionError: () => SessionError,
|
|
50
|
+
UnsupportedOperationError: () => UnsupportedOperationError
|
|
139
51
|
});
|
|
140
52
|
module.exports = __toCommonJS(index_exports);
|
|
141
53
|
|
|
@@ -220,6 +132,11 @@ var ElementNotFoundError = class extends BrowserError {
|
|
|
220
132
|
this.selector = selector;
|
|
221
133
|
}
|
|
222
134
|
};
|
|
135
|
+
var UnsupportedOperationError = class extends InstaVMError {
|
|
136
|
+
constructor(message = "Operation not supported", options) {
|
|
137
|
+
super(message, options);
|
|
138
|
+
}
|
|
139
|
+
};
|
|
223
140
|
|
|
224
141
|
// src/utils/retry.ts
|
|
225
142
|
function defaultRetryCondition(error) {
|
|
@@ -262,14 +179,6 @@ async function withRetry(fn, options) {
|
|
|
262
179
|
}
|
|
263
180
|
|
|
264
181
|
// src/client/HTTPClient.ts
|
|
265
|
-
function getPackageVersion() {
|
|
266
|
-
try {
|
|
267
|
-
const packageJson = require_package();
|
|
268
|
-
return packageJson.version || "0.1.0";
|
|
269
|
-
} catch {
|
|
270
|
-
return "0.1.0";
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
182
|
var HTTPClient = class {
|
|
274
183
|
get apiKey() {
|
|
275
184
|
return this.config.apiKey;
|
|
@@ -281,7 +190,7 @@ var HTTPClient = class {
|
|
|
281
190
|
timeout: config.timeout,
|
|
282
191
|
headers: {
|
|
283
192
|
"Content-Type": "application/json",
|
|
284
|
-
"User-Agent":
|
|
193
|
+
"User-Agent": "instavm-js-sdk/0.1.0"
|
|
285
194
|
}
|
|
286
195
|
});
|
|
287
196
|
this.setupInterceptors();
|
|
@@ -289,7 +198,7 @@ var HTTPClient = class {
|
|
|
289
198
|
setupInterceptors() {
|
|
290
199
|
this.client.interceptors.request.use(
|
|
291
200
|
(config) => {
|
|
292
|
-
if (
|
|
201
|
+
if (config.url?.includes("/browser/")) {
|
|
293
202
|
config.headers["X-API-Key"] = this.config.apiKey;
|
|
294
203
|
}
|
|
295
204
|
return config;
|
|
@@ -378,14 +287,18 @@ var HTTPClient = class {
|
|
|
378
287
|
});
|
|
379
288
|
}
|
|
380
289
|
/**
|
|
381
|
-
* POST request for code execution (X-API-Key header
|
|
290
|
+
* POST request for code execution (uses X-API-Key header like Python client)
|
|
382
291
|
*/
|
|
383
292
|
async postExecution(url, data, headers) {
|
|
293
|
+
const requestHeaders = {
|
|
294
|
+
"X-API-Key": this.config.apiKey,
|
|
295
|
+
...headers
|
|
296
|
+
};
|
|
384
297
|
return this.request({
|
|
385
298
|
method: "POST",
|
|
386
299
|
url,
|
|
387
300
|
data,
|
|
388
|
-
headers
|
|
301
|
+
headers: requestHeaders
|
|
389
302
|
});
|
|
390
303
|
}
|
|
391
304
|
/**
|
|
@@ -424,6 +337,31 @@ var HTTPClient = class {
|
|
|
424
337
|
headers
|
|
425
338
|
});
|
|
426
339
|
}
|
|
340
|
+
/**
|
|
341
|
+
* POST request that returns raw binary data (for file downloads)
|
|
342
|
+
*/
|
|
343
|
+
async postRaw(url, data, headers) {
|
|
344
|
+
const requestHeaders = {
|
|
345
|
+
"X-API-Key": this.config.apiKey,
|
|
346
|
+
...headers
|
|
347
|
+
};
|
|
348
|
+
const axiosConfig = {
|
|
349
|
+
method: "POST",
|
|
350
|
+
url,
|
|
351
|
+
data,
|
|
352
|
+
headers: requestHeaders,
|
|
353
|
+
responseType: "arraybuffer",
|
|
354
|
+
timeout: this.config.timeout
|
|
355
|
+
};
|
|
356
|
+
const makeRequest = async () => {
|
|
357
|
+
const response = await this.client.request(axiosConfig);
|
|
358
|
+
return response.data;
|
|
359
|
+
};
|
|
360
|
+
return withRetry(makeRequest, {
|
|
361
|
+
retries: this.config.maxRetries,
|
|
362
|
+
retryDelay: this.config.retryDelay
|
|
363
|
+
});
|
|
364
|
+
}
|
|
427
365
|
};
|
|
428
366
|
|
|
429
367
|
// src/client/BrowserSession.ts
|
|
@@ -650,6 +588,59 @@ var BrowserSession = class extends import_eventemitter3.EventEmitter {
|
|
|
650
588
|
);
|
|
651
589
|
}
|
|
652
590
|
}
|
|
591
|
+
/**
|
|
592
|
+
* Extract LLM-friendly content from the current page
|
|
593
|
+
*
|
|
594
|
+
* Returns clean article content, interactive elements, and content anchors
|
|
595
|
+
* for intelligent browser automation with LLMs.
|
|
596
|
+
*
|
|
597
|
+
* @param options - Content extraction options
|
|
598
|
+
* @returns Extracted content with readable text, interactive elements, and content anchors
|
|
599
|
+
*
|
|
600
|
+
* @example
|
|
601
|
+
* ```typescript
|
|
602
|
+
* const content = await session.extractContent();
|
|
603
|
+
*
|
|
604
|
+
* // LLM reads clean content
|
|
605
|
+
* const article = content.readableContent.content;
|
|
606
|
+
*
|
|
607
|
+
* // LLM finds "Sign Up" in content and uses anchors to get selector
|
|
608
|
+
* const signUpAnchor = content.contentAnchors?.find(
|
|
609
|
+
* anchor => anchor.text.toLowerCase().includes('sign up')
|
|
610
|
+
* );
|
|
611
|
+
* if (signUpAnchor) {
|
|
612
|
+
* await session.click(signUpAnchor.selector);
|
|
613
|
+
* }
|
|
614
|
+
* ```
|
|
615
|
+
*/
|
|
616
|
+
async extractContent(options = {}) {
|
|
617
|
+
this.ensureActive();
|
|
618
|
+
const requestData = {
|
|
619
|
+
session_id: this.sessionId,
|
|
620
|
+
include_interactive: options.includeInteractive !== false,
|
|
621
|
+
include_anchors: options.includeAnchors !== false,
|
|
622
|
+
max_anchors: options.maxAnchors ?? 50
|
|
623
|
+
};
|
|
624
|
+
try {
|
|
625
|
+
const response = await this.httpClient.post(
|
|
626
|
+
"/v1/browser/interactions/content",
|
|
627
|
+
requestData
|
|
628
|
+
);
|
|
629
|
+
return {
|
|
630
|
+
readableContent: {
|
|
631
|
+
...response.readable_content || {},
|
|
632
|
+
content: response.readable_content?.content || ""
|
|
633
|
+
},
|
|
634
|
+
interactiveElements: response.interactive_elements,
|
|
635
|
+
contentAnchors: response.content_anchors
|
|
636
|
+
};
|
|
637
|
+
} catch (error) {
|
|
638
|
+
throw new BrowserInteractionError(
|
|
639
|
+
`Content extraction failed: ${getErrorMessage(error)}`,
|
|
640
|
+
{ cause: error }
|
|
641
|
+
);
|
|
642
|
+
}
|
|
643
|
+
}
|
|
653
644
|
/**
|
|
654
645
|
* Wait for a condition
|
|
655
646
|
*/
|
|
@@ -721,14 +712,20 @@ var BrowserSession = class extends import_eventemitter3.EventEmitter {
|
|
|
721
712
|
|
|
722
713
|
// src/client/BrowserManager.ts
|
|
723
714
|
var BrowserManager = class {
|
|
724
|
-
constructor(httpClient) {
|
|
715
|
+
constructor(httpClient, local = false) {
|
|
725
716
|
this.activeSessions = /* @__PURE__ */ new Map();
|
|
726
717
|
this.httpClient = httpClient;
|
|
718
|
+
this.local = local;
|
|
727
719
|
}
|
|
728
720
|
/**
|
|
729
721
|
* Create a new browser session
|
|
730
722
|
*/
|
|
731
723
|
async createSession(options = {}) {
|
|
724
|
+
if (this.local) {
|
|
725
|
+
throw new UnsupportedOperationError(
|
|
726
|
+
"Browser session management is not supported in local mode. Use navigate() or extractContent() with URL directly."
|
|
727
|
+
);
|
|
728
|
+
}
|
|
732
729
|
const requestData = {
|
|
733
730
|
viewport_width: options.viewportWidth || 1920,
|
|
734
731
|
viewport_height: options.viewportHeight || 1080,
|
|
@@ -827,6 +824,77 @@ var BrowserManager = class {
|
|
|
827
824
|
);
|
|
828
825
|
this.activeSessions.clear();
|
|
829
826
|
}
|
|
827
|
+
/**
|
|
828
|
+
* Navigate to a URL (local mode support - no session required)
|
|
829
|
+
*/
|
|
830
|
+
async navigate(url, options = {}) {
|
|
831
|
+
if (!this.local) {
|
|
832
|
+
throw new UnsupportedOperationError(
|
|
833
|
+
"navigate() without session is only supported in local mode. In cloud mode, create a session first."
|
|
834
|
+
);
|
|
835
|
+
}
|
|
836
|
+
const requestData = {
|
|
837
|
+
url,
|
|
838
|
+
wait_timeout: options.waitTimeout || 3e4
|
|
839
|
+
};
|
|
840
|
+
try {
|
|
841
|
+
const response = await this.httpClient.post(
|
|
842
|
+
"/v1/browser/interactions/navigate",
|
|
843
|
+
requestData
|
|
844
|
+
);
|
|
845
|
+
return {
|
|
846
|
+
success: response.success !== false,
|
|
847
|
+
url: response.url || url,
|
|
848
|
+
title: response.title,
|
|
849
|
+
status: response.status
|
|
850
|
+
};
|
|
851
|
+
} catch (error) {
|
|
852
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
853
|
+
throw new BrowserNavigationError(
|
|
854
|
+
`Navigation failed: ${errorMessage}`,
|
|
855
|
+
{ cause: error }
|
|
856
|
+
);
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
/**
|
|
860
|
+
* Extract LLM-friendly content (local mode support - no session required)
|
|
861
|
+
*/
|
|
862
|
+
async extractContent(options = {}) {
|
|
863
|
+
if (!this.local) {
|
|
864
|
+
throw new UnsupportedOperationError(
|
|
865
|
+
"extractContent() without session is only supported in local mode. In cloud mode, create a session first."
|
|
866
|
+
);
|
|
867
|
+
}
|
|
868
|
+
if (!options.url) {
|
|
869
|
+
throw new BrowserInteractionError("url is required in local mode");
|
|
870
|
+
}
|
|
871
|
+
const requestData = {
|
|
872
|
+
url: options.url,
|
|
873
|
+
include_interactive: options.includeInteractive !== false,
|
|
874
|
+
include_anchors: options.includeAnchors !== false,
|
|
875
|
+
max_anchors: options.maxAnchors ?? 50
|
|
876
|
+
};
|
|
877
|
+
try {
|
|
878
|
+
const response = await this.httpClient.post(
|
|
879
|
+
"/v1/browser/interactions/content",
|
|
880
|
+
requestData
|
|
881
|
+
);
|
|
882
|
+
return {
|
|
883
|
+
readableContent: {
|
|
884
|
+
...response.readable_content || {},
|
|
885
|
+
content: response.readable_content?.content || ""
|
|
886
|
+
},
|
|
887
|
+
interactiveElements: response.interactive_elements,
|
|
888
|
+
contentAnchors: response.content_anchors
|
|
889
|
+
};
|
|
890
|
+
} catch (error) {
|
|
891
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
892
|
+
throw new BrowserInteractionError(
|
|
893
|
+
`Content extraction failed: ${errorMessage}`,
|
|
894
|
+
{ cause: error }
|
|
895
|
+
);
|
|
896
|
+
}
|
|
897
|
+
}
|
|
830
898
|
/**
|
|
831
899
|
* Clean up resources
|
|
832
900
|
*/
|
|
@@ -840,34 +908,47 @@ var import_form_data = __toESM(require("form-data"));
|
|
|
840
908
|
var InstaVM = class {
|
|
841
909
|
constructor(apiKey, options = {}) {
|
|
842
910
|
this._sessionId = null;
|
|
843
|
-
|
|
844
|
-
|
|
911
|
+
this.local = options.local || false;
|
|
912
|
+
if (!this.local && !apiKey) {
|
|
913
|
+
throw new AuthenticationError("API key is required for cloud mode");
|
|
845
914
|
}
|
|
846
915
|
const config = {
|
|
847
|
-
baseURL: options.baseURL || "https://api.instavm.io",
|
|
916
|
+
baseURL: this.local ? options.localURL || "http://coderunner.local:8222" : options.baseURL || "https://api.instavm.io",
|
|
848
917
|
timeout: options.timeout || 3e5,
|
|
849
918
|
// 5 minutes
|
|
850
919
|
maxRetries: options.maxRetries || 3,
|
|
851
920
|
retryDelay: options.retryDelay || 1e3,
|
|
852
|
-
apiKey
|
|
921
|
+
apiKey: apiKey || ""
|
|
853
922
|
};
|
|
854
923
|
this.httpClient = new HTTPClient(config);
|
|
855
|
-
this.browser = new BrowserManager(this.httpClient);
|
|
924
|
+
this.browser = new BrowserManager(this.httpClient, this.local);
|
|
925
|
+
}
|
|
926
|
+
/**
|
|
927
|
+
* Ensure operation is not called in local mode
|
|
928
|
+
*/
|
|
929
|
+
ensureNotLocal(operationName) {
|
|
930
|
+
if (this.local) {
|
|
931
|
+
throw new UnsupportedOperationError(
|
|
932
|
+
`${operationName} is not supported in local mode. This operation is only available when using the cloud API.`
|
|
933
|
+
);
|
|
934
|
+
}
|
|
856
935
|
}
|
|
857
936
|
/**
|
|
858
937
|
* Execute code synchronously
|
|
859
938
|
*/
|
|
860
939
|
async execute(command, options = {}) {
|
|
861
940
|
let sessionId = options.sessionId || this._sessionId;
|
|
862
|
-
if (!sessionId) {
|
|
941
|
+
if (!this.local && !sessionId) {
|
|
863
942
|
sessionId = await this.createSession();
|
|
864
943
|
}
|
|
865
944
|
const requestData = {
|
|
866
945
|
command,
|
|
867
946
|
language: options.language || "python",
|
|
868
|
-
timeout: options.timeout || 15
|
|
869
|
-
session_id: sessionId
|
|
947
|
+
timeout: options.timeout || 15
|
|
870
948
|
};
|
|
949
|
+
if (!this.local && sessionId) {
|
|
950
|
+
requestData.session_id = sessionId;
|
|
951
|
+
}
|
|
871
952
|
try {
|
|
872
953
|
const response = await this.httpClient.postExecution(
|
|
873
954
|
"/execute",
|
|
@@ -897,6 +978,7 @@ var InstaVM = class {
|
|
|
897
978
|
* Execute code asynchronously
|
|
898
979
|
*/
|
|
899
980
|
async executeAsync(command, options = {}) {
|
|
981
|
+
this.ensureNotLocal("Async execution");
|
|
900
982
|
let sessionId = options.sessionId || this._sessionId;
|
|
901
983
|
if (!sessionId) {
|
|
902
984
|
sessionId = await this.createSession();
|
|
@@ -938,6 +1020,7 @@ var InstaVM = class {
|
|
|
938
1020
|
* Upload files to the execution environment
|
|
939
1021
|
*/
|
|
940
1022
|
async upload(files, options = {}) {
|
|
1023
|
+
this.ensureNotLocal("File upload");
|
|
941
1024
|
const formData = new import_form_data.default();
|
|
942
1025
|
for (const file of files) {
|
|
943
1026
|
if (Buffer.isBuffer(file.content)) {
|
|
@@ -980,6 +1063,7 @@ var InstaVM = class {
|
|
|
980
1063
|
* Create a new execution session
|
|
981
1064
|
*/
|
|
982
1065
|
async createSession() {
|
|
1066
|
+
this.ensureNotLocal("Session management");
|
|
983
1067
|
try {
|
|
984
1068
|
const response = await this.httpClient.post("/v1/sessions/session", {
|
|
985
1069
|
api_key: this.httpClient.apiKey
|
|
@@ -1019,6 +1103,7 @@ var InstaVM = class {
|
|
|
1019
1103
|
* Get usage statistics for a session
|
|
1020
1104
|
*/
|
|
1021
1105
|
async getUsage(sessionId) {
|
|
1106
|
+
this.ensureNotLocal("Usage tracking");
|
|
1022
1107
|
const targetSessionId = sessionId || this._sessionId;
|
|
1023
1108
|
if (!targetSessionId) {
|
|
1024
1109
|
throw new SessionError("No active session to get usage for");
|
|
@@ -1041,6 +1126,35 @@ var InstaVM = class {
|
|
|
1041
1126
|
);
|
|
1042
1127
|
}
|
|
1043
1128
|
}
|
|
1129
|
+
/**
|
|
1130
|
+
* Download a file from the remote VM
|
|
1131
|
+
*/
|
|
1132
|
+
async download(filename, options = {}) {
|
|
1133
|
+
this.ensureNotLocal("File download");
|
|
1134
|
+
const targetSessionId = options.sessionId || this._sessionId;
|
|
1135
|
+
if (!targetSessionId) {
|
|
1136
|
+
throw new SessionError("No active session to download from");
|
|
1137
|
+
}
|
|
1138
|
+
try {
|
|
1139
|
+
const response = await this.httpClient.postRaw("/download", {
|
|
1140
|
+
filename,
|
|
1141
|
+
session_id: targetSessionId
|
|
1142
|
+
});
|
|
1143
|
+
const content = Buffer.from(response);
|
|
1144
|
+
return {
|
|
1145
|
+
success: true,
|
|
1146
|
+
filename,
|
|
1147
|
+
content,
|
|
1148
|
+
size: content.length
|
|
1149
|
+
};
|
|
1150
|
+
} catch (error) {
|
|
1151
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1152
|
+
throw new SessionError(
|
|
1153
|
+
`File download failed: ${errorMessage}`,
|
|
1154
|
+
{ cause: error }
|
|
1155
|
+
);
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1044
1158
|
/**
|
|
1045
1159
|
* Get the current session ID
|
|
1046
1160
|
*/
|
|
@@ -1074,6 +1188,7 @@ var InstaVM = class {
|
|
|
1074
1188
|
NetworkError,
|
|
1075
1189
|
QuotaExceededError,
|
|
1076
1190
|
RateLimitError,
|
|
1077
|
-
SessionError
|
|
1191
|
+
SessionError,
|
|
1192
|
+
UnsupportedOperationError
|
|
1078
1193
|
});
|
|
1079
1194
|
//# sourceMappingURL=index.js.map
|