@voidrun/sdk 0.0.1
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/dist/FS.d.ts +193 -0
- package/dist/FS.d.ts.map +1 -0
- package/dist/FS.js +488 -0
- package/dist/FS.js.map +1 -0
- package/dist/Sandbox.d.ts +23 -0
- package/dist/Sandbox.d.ts.map +1 -0
- package/dist/Sandbox.js +72 -0
- package/dist/Sandbox.js.map +1 -0
- package/dist/api-client/apis/AuthenticationApi.d.ts +32 -0
- package/dist/api-client/apis/AuthenticationApi.d.ts.map +1 -0
- package/dist/api-client/apis/AuthenticationApi.js +50 -0
- package/dist/api-client/apis/AuthenticationApi.js.map +1 -0
- package/dist/api-client/apis/ExecutionApi.d.ts +132 -0
- package/dist/api-client/apis/ExecutionApi.d.ts.map +1 -0
- package/dist/api-client/apis/ExecutionApi.js +305 -0
- package/dist/api-client/apis/ExecutionApi.js.map +1 -0
- package/dist/api-client/apis/FileSystemApi.d.ts +250 -0
- package/dist/api-client/apis/FileSystemApi.d.ts.map +1 -0
- package/dist/api-client/apis/FileSystemApi.js +634 -0
- package/dist/api-client/apis/FileSystemApi.js.map +1 -0
- package/dist/api-client/apis/ImagesApi.d.ts +81 -0
- package/dist/api-client/apis/ImagesApi.d.ts.map +1 -0
- package/dist/api-client/apis/ImagesApi.js +173 -0
- package/dist/api-client/apis/ImagesApi.js.map +1 -0
- package/dist/api-client/apis/OrganizationsApi.d.ts +70 -0
- package/dist/api-client/apis/OrganizationsApi.d.ts.map +1 -0
- package/dist/api-client/apis/OrganizationsApi.js +150 -0
- package/dist/api-client/apis/OrganizationsApi.js.map +1 -0
- package/dist/api-client/apis/SandboxesApi.d.ts +150 -0
- package/dist/api-client/apis/SandboxesApi.d.ts.map +1 -0
- package/dist/api-client/apis/SandboxesApi.js +335 -0
- package/dist/api-client/apis/SandboxesApi.js.map +1 -0
- package/dist/api-client/apis/index.d.ts +7 -0
- package/dist/api-client/apis/index.d.ts.map +1 -0
- package/dist/api-client/apis/index.js +9 -0
- package/dist/api-client/apis/index.js.map +1 -0
- package/dist/api-client/index.d.ts +4 -0
- package/dist/api-client/index.d.ts.map +1 -0
- package/dist/api-client/index.js +6 -0
- package/dist/api-client/index.js.map +1 -0
- package/dist/api-client/models/APIKeyResponse.d.ts +75 -0
- package/dist/api-client/models/APIKeyResponse.d.ts.map +1 -0
- package/dist/api-client/models/APIKeyResponse.js +56 -0
- package/dist/api-client/models/APIKeyResponse.js.map +1 -0
- package/dist/api-client/models/ApiResponseSandbox.d.ts +46 -0
- package/dist/api-client/models/ApiResponseSandbox.d.ts.map +1 -0
- package/dist/api-client/models/ApiResponseSandbox.js +47 -0
- package/dist/api-client/models/ApiResponseSandbox.js.map +1 -0
- package/dist/api-client/models/ApiResponseSandboxesList.d.ts +53 -0
- package/dist/api-client/models/ApiResponseSandboxesList.d.ts.map +1 -0
- package/dist/api-client/models/ApiResponseSandboxesList.js +50 -0
- package/dist/api-client/models/ApiResponseSandboxesList.js.map +1 -0
- package/dist/api-client/models/ApiResponseSandboxesListMeta.d.ts +51 -0
- package/dist/api-client/models/ApiResponseSandboxesListMeta.d.ts.map +1 -0
- package/dist/api-client/models/ApiResponseSandboxesListMeta.js +48 -0
- package/dist/api-client/models/ApiResponseSandboxesListMeta.js.map +1 -0
- package/dist/api-client/models/CompressRequest.d.ts +49 -0
- package/dist/api-client/models/CompressRequest.d.ts.map +1 -0
- package/dist/api-client/models/CompressRequest.js +55 -0
- package/dist/api-client/models/CompressRequest.js.map +1 -0
- package/dist/api-client/models/CreateFileRequest.d.ts +33 -0
- package/dist/api-client/models/CreateFileRequest.d.ts.map +1 -0
- package/dist/api-client/models/CreateFileRequest.js +42 -0
- package/dist/api-client/models/CreateFileRequest.js.map +1 -0
- package/dist/api-client/models/CreateImageRequest.d.ts +45 -0
- package/dist/api-client/models/CreateImageRequest.d.ts.map +1 -0
- package/dist/api-client/models/CreateImageRequest.js +48 -0
- package/dist/api-client/models/CreateImageRequest.js.map +1 -0
- package/dist/api-client/models/CreatePTYSessionRequest.d.ts +39 -0
- package/dist/api-client/models/CreatePTYSessionRequest.d.ts.map +1 -0
- package/dist/api-client/models/CreatePTYSessionRequest.js +44 -0
- package/dist/api-client/models/CreatePTYSessionRequest.js.map +1 -0
- package/dist/api-client/models/CreateSandbox201Response.d.ts +46 -0
- package/dist/api-client/models/CreateSandbox201Response.d.ts.map +1 -0
- package/dist/api-client/models/CreateSandbox201Response.js +47 -0
- package/dist/api-client/models/CreateSandbox201Response.js.map +1 -0
- package/dist/api-client/models/CreateSandboxRequest.d.ts +63 -0
- package/dist/api-client/models/CreateSandboxRequest.d.ts.map +1 -0
- package/dist/api-client/models/CreateSandboxRequest.js +54 -0
- package/dist/api-client/models/CreateSandboxRequest.js.map +1 -0
- package/dist/api-client/models/DiskUsage.d.ts +45 -0
- package/dist/api-client/models/DiskUsage.d.ts.map +1 -0
- package/dist/api-client/models/DiskUsage.js +46 -0
- package/dist/api-client/models/DiskUsage.js.map +1 -0
- package/dist/api-client/models/ErrorResponse.d.ts +39 -0
- package/dist/api-client/models/ErrorResponse.d.ts.map +1 -0
- package/dist/api-client/models/ErrorResponse.js +44 -0
- package/dist/api-client/models/ErrorResponse.js.map +1 -0
- package/dist/api-client/models/ExecRequest.d.ts +59 -0
- package/dist/api-client/models/ExecRequest.d.ts.map +1 -0
- package/dist/api-client/models/ExecRequest.js +52 -0
- package/dist/api-client/models/ExecRequest.js.map +1 -0
- package/dist/api-client/models/ExecResponse.d.ts +46 -0
- package/dist/api-client/models/ExecResponse.d.ts.map +1 -0
- package/dist/api-client/models/ExecResponse.js +47 -0
- package/dist/api-client/models/ExecResponse.js.map +1 -0
- package/dist/api-client/models/ExecResponseData.d.ts +45 -0
- package/dist/api-client/models/ExecResponseData.d.ts.map +1 -0
- package/dist/api-client/models/ExecResponseData.js +46 -0
- package/dist/api-client/models/ExecResponseData.js.map +1 -0
- package/dist/api-client/models/ExecuteInSessionRequest.d.ts +33 -0
- package/dist/api-client/models/ExecuteInSessionRequest.d.ts.map +1 -0
- package/dist/api-client/models/ExecuteInSessionRequest.js +44 -0
- package/dist/api-client/models/ExecuteInSessionRequest.js.map +1 -0
- package/dist/api-client/models/ExtractRequest.d.ts +39 -0
- package/dist/api-client/models/ExtractRequest.d.ts.map +1 -0
- package/dist/api-client/models/ExtractRequest.js +48 -0
- package/dist/api-client/models/ExtractRequest.js.map +1 -0
- package/dist/api-client/models/FileInfo.d.ts +63 -0
- package/dist/api-client/models/FileInfo.d.ts.map +1 -0
- package/dist/api-client/models/FileInfo.js +52 -0
- package/dist/api-client/models/FileInfo.js.map +1 -0
- package/dist/api-client/models/FileStats.d.ts +75 -0
- package/dist/api-client/models/FileStats.d.ts.map +1 -0
- package/dist/api-client/models/FileStats.js +56 -0
- package/dist/api-client/models/FileStats.js.map +1 -0
- package/dist/api-client/models/GenerateAPIKeyRequest.d.ts +39 -0
- package/dist/api-client/models/GenerateAPIKeyRequest.d.ts.map +1 -0
- package/dist/api-client/models/GenerateAPIKeyRequest.js +48 -0
- package/dist/api-client/models/GenerateAPIKeyRequest.js.map +1 -0
- package/dist/api-client/models/GeneratedAPIKeyResponse.d.ts +63 -0
- package/dist/api-client/models/GeneratedAPIKeyResponse.d.ts.map +1 -0
- package/dist/api-client/models/GeneratedAPIKeyResponse.js +52 -0
- package/dist/api-client/models/GeneratedAPIKeyResponse.js.map +1 -0
- package/dist/api-client/models/GetPTYBuffer200Response.d.ts +33 -0
- package/dist/api-client/models/GetPTYBuffer200Response.d.ts.map +1 -0
- package/dist/api-client/models/GetPTYBuffer200Response.js +42 -0
- package/dist/api-client/models/GetPTYBuffer200Response.js.map +1 -0
- package/dist/api-client/models/Image.d.ts +69 -0
- package/dist/api-client/models/Image.d.ts.map +1 -0
- package/dist/api-client/models/Image.js +54 -0
- package/dist/api-client/models/Image.js.map +1 -0
- package/dist/api-client/models/ListFiles200Response.d.ts +46 -0
- package/dist/api-client/models/ListFiles200Response.d.ts.map +1 -0
- package/dist/api-client/models/ListFiles200Response.js +47 -0
- package/dist/api-client/models/ListFiles200Response.js.map +1 -0
- package/dist/api-client/models/ListFiles200ResponseData.d.ts +40 -0
- package/dist/api-client/models/ListFiles200ResponseData.d.ts.map +1 -0
- package/dist/api-client/models/ListFiles200ResponseData.js +45 -0
- package/dist/api-client/models/ListFiles200ResponseData.js.map +1 -0
- package/dist/api-client/models/Organization.d.ts +81 -0
- package/dist/api-client/models/Organization.d.ts.map +1 -0
- package/dist/api-client/models/Organization.js +58 -0
- package/dist/api-client/models/Organization.js.map +1 -0
- package/dist/api-client/models/PTYSessionResponse.d.ts +51 -0
- package/dist/api-client/models/PTYSessionResponse.d.ts.map +1 -0
- package/dist/api-client/models/PTYSessionResponse.js +48 -0
- package/dist/api-client/models/PTYSessionResponse.js.map +1 -0
- package/dist/api-client/models/RegisterRequest.d.ts +39 -0
- package/dist/api-client/models/RegisterRequest.d.ts.map +1 -0
- package/dist/api-client/models/RegisterRequest.js +48 -0
- package/dist/api-client/models/RegisterRequest.js.map +1 -0
- package/dist/api-client/models/RegisterResponse.d.ts +40 -0
- package/dist/api-client/models/RegisterResponse.d.ts.map +1 -0
- package/dist/api-client/models/RegisterResponse.js +45 -0
- package/dist/api-client/models/RegisterResponse.js.map +1 -0
- package/dist/api-client/models/RegisterResponseData.d.ts +39 -0
- package/dist/api-client/models/RegisterResponseData.d.ts.map +1 -0
- package/dist/api-client/models/RegisterResponseData.js +44 -0
- package/dist/api-client/models/RegisterResponseData.js.map +1 -0
- package/dist/api-client/models/ResizeTerminalRequest.d.ts +39 -0
- package/dist/api-client/models/ResizeTerminalRequest.d.ts.map +1 -0
- package/dist/api-client/models/ResizeTerminalRequest.js +48 -0
- package/dist/api-client/models/ResizeTerminalRequest.js.map +1 -0
- package/dist/api-client/models/RestoreSandboxRequest.d.ts +75 -0
- package/dist/api-client/models/RestoreSandboxRequest.d.ts.map +1 -0
- package/dist/api-client/models/RestoreSandboxRequest.js +62 -0
- package/dist/api-client/models/RestoreSandboxRequest.js.map +1 -0
- package/dist/api-client/models/Sandbox.d.ts +97 -0
- package/dist/api-client/models/Sandbox.d.ts.map +1 -0
- package/dist/api-client/models/Sandbox.js +69 -0
- package/dist/api-client/models/Sandbox.js.map +1 -0
- package/dist/api-client/models/SessionExecResponse.d.ts +57 -0
- package/dist/api-client/models/SessionExecResponse.d.ts.map +1 -0
- package/dist/api-client/models/SessionExecResponse.js +50 -0
- package/dist/api-client/models/SessionExecResponse.js.map +1 -0
- package/dist/api-client/models/Snapshot.d.ts +45 -0
- package/dist/api-client/models/Snapshot.d.ts.map +1 -0
- package/dist/api-client/models/Snapshot.js +46 -0
- package/dist/api-client/models/Snapshot.js.map +1 -0
- package/dist/api-client/models/SuccessResponse.d.ts +45 -0
- package/dist/api-client/models/SuccessResponse.d.ts.map +1 -0
- package/dist/api-client/models/SuccessResponse.js +46 -0
- package/dist/api-client/models/SuccessResponse.js.map +1 -0
- package/dist/api-client/models/index.d.ts +37 -0
- package/dist/api-client/models/index.d.ts.map +1 -0
- package/dist/api-client/models/index.js +39 -0
- package/dist/api-client/models/index.js.map +1 -0
- package/dist/api-client/runtime.d.ts +185 -0
- package/dist/api-client/runtime.d.ts.map +1 -0
- package/dist/api-client/runtime.js +334 -0
- package/dist/api-client/runtime.js.map +1 -0
- package/dist/constants.d.ts +8 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +9 -0
- package/dist/constants.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +62 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +47 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/runtime.d.ts +2 -0
- package/dist/utils/runtime.d.ts.map +1 -0
- package/dist/utils/runtime.js +23 -0
- package/dist/utils/runtime.js.map +1 -0
- package/package.json +23 -0
package/dist/FS.d.ts
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { Configuration, ExecResponse } from "./api-client/index";
|
|
2
|
+
import { FolderSizeResponse, StatFileResponse } from "./types";
|
|
3
|
+
export declare class FS {
|
|
4
|
+
private readonly sandboxId;
|
|
5
|
+
private readonly config;
|
|
6
|
+
private readonly fsApi;
|
|
7
|
+
constructor(sandboxId: string, config: Configuration);
|
|
8
|
+
listFiles(path: string): Promise<import("./api-client/index").ListFiles200Response>;
|
|
9
|
+
/**
|
|
10
|
+
* Download a file and return the full response (non-streaming)
|
|
11
|
+
*/
|
|
12
|
+
downloadFile(path: string): Promise<Buffer<ArrayBuffer>>;
|
|
13
|
+
/**
|
|
14
|
+
* Download a file as a streaming ReadableStream
|
|
15
|
+
* Works across browser, Node.js, Deno, Bun, and serverless environments
|
|
16
|
+
*
|
|
17
|
+
* @param path - Path to the file to download
|
|
18
|
+
* @returns A ReadableStream that can be consumed progressively
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* const stream = await fs.downloadFileStream('/path/to/file.txt');
|
|
23
|
+
* const reader = stream.getReader();
|
|
24
|
+
* while (true) {
|
|
25
|
+
* const { done, value } = await reader.read();
|
|
26
|
+
* if (done) break;
|
|
27
|
+
* // Process chunk: value is a Uint8Array
|
|
28
|
+
* }
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
downloadFileStream(path: string): Promise<ReadableStream<Uint8Array>>;
|
|
32
|
+
/**
|
|
33
|
+
* Upload a file (non-streaming, accepts string content)
|
|
34
|
+
* For streaming support, use uploadFileStream() or uploadFileFromSource()
|
|
35
|
+
*/
|
|
36
|
+
uploadFile(path: string, content: string): Promise<{
|
|
37
|
+
status: string;
|
|
38
|
+
message: string;
|
|
39
|
+
}>;
|
|
40
|
+
/**
|
|
41
|
+
* Upload a file with true streaming support (ReadableStream)
|
|
42
|
+
* Works across browser, Node.js, Deno, Bun, and serverless environments
|
|
43
|
+
*
|
|
44
|
+
* This method streams data directly without buffering the entire file in memory,
|
|
45
|
+
* making it suitable for large files.
|
|
46
|
+
*
|
|
47
|
+
* @param path - Destination path for the file
|
|
48
|
+
* @param stream - ReadableStream to upload
|
|
49
|
+
* @param contentType - Optional MIME type (defaults to 'application/octet-stream')
|
|
50
|
+
* @returns Upload response
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```ts
|
|
54
|
+
* // Create a streaming source
|
|
55
|
+
* const stream = new ReadableStream({
|
|
56
|
+
* start(controller) {
|
|
57
|
+
* // Enqueue chunks as they become available
|
|
58
|
+
* controller.enqueue(new Uint8Array([1, 2, 3]));
|
|
59
|
+
* controller.close();
|
|
60
|
+
* }
|
|
61
|
+
* });
|
|
62
|
+
* await fs.uploadFileStream('/path/to/file.txt', stream);
|
|
63
|
+
*
|
|
64
|
+
* // From a File.stream() (browser)
|
|
65
|
+
* const fileInput = document.querySelector('input[type="file"]');
|
|
66
|
+
* const fileStream = fileInput.files[0].stream();
|
|
67
|
+
* await fs.uploadFileStream('/path/to/file.txt', fileStream);
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
uploadFileStream(path: string, stream: ReadableStream<Uint8Array>, contentType?: string): Promise<{
|
|
71
|
+
status: string;
|
|
72
|
+
message: string;
|
|
73
|
+
}>;
|
|
74
|
+
/**
|
|
75
|
+
* Upload a file from a local file path (Node.js, Deno, Bun, Serverless)
|
|
76
|
+
* Streams the file directly without loading it into memory, suitable for large files.
|
|
77
|
+
*
|
|
78
|
+
* Supported runtimes:
|
|
79
|
+
* - Node.js: Uses fs.createReadStream()
|
|
80
|
+
* - Deno: Uses Deno.open().readable
|
|
81
|
+
* - Bun: Uses Bun.file().stream()
|
|
82
|
+
* - Serverless (Node.js-based): Works with files in /tmp directory
|
|
83
|
+
*
|
|
84
|
+
* Serverless limitations:
|
|
85
|
+
* - AWS Lambda: Only /tmp directory is writable (512 MB default, up to 10 GB)
|
|
86
|
+
* - Vercel Functions: Only /tmp directory is writable
|
|
87
|
+
* - Cloudflare Workers: Not supported (no file system access)
|
|
88
|
+
* - Edge runtimes: Not supported (no file system access)
|
|
89
|
+
*
|
|
90
|
+
* Note: In serverless environments, files must be in /tmp or the function
|
|
91
|
+
* will fail with permission errors. Files in /tmp are ephemeral and only
|
|
92
|
+
* available during the function execution.
|
|
93
|
+
*
|
|
94
|
+
* @param remotePath - Destination path on the remote sandbox
|
|
95
|
+
* @param localPath - Local file system path to the file to upload
|
|
96
|
+
* @param contentType - Optional MIME type (defaults to 'application/octet-stream')
|
|
97
|
+
* @returns Upload response
|
|
98
|
+
*
|
|
99
|
+
* @throws Error if not running in a supported runtime (Node.js, Deno, or Bun)
|
|
100
|
+
* @throws Error if file is not found or not accessible
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```ts
|
|
104
|
+
* // Upload a large file from local filesystem (works in Node.js, Deno, Bun)
|
|
105
|
+
* await fs.uploadFileFromPath('/remote/path/to/file.txt', './local/file.txt');
|
|
106
|
+
*
|
|
107
|
+
* // Upload with specific content type
|
|
108
|
+
* await fs.uploadFileFromPath('/remote/image.png', './local/image.png', 'image/png');
|
|
109
|
+
*
|
|
110
|
+
* // Serverless example (AWS Lambda / Vercel) - file must be in /tmp
|
|
111
|
+
* await fs.uploadFileFromPath('/remote/data.json', '/tmp/data.json');
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
uploadFileFromPath(remotePath: string, localPath: string, contentType?: string): Promise<{
|
|
115
|
+
status: string;
|
|
116
|
+
message: string;
|
|
117
|
+
}>;
|
|
118
|
+
/**
|
|
119
|
+
* Upload a file from various source types (convenience method)
|
|
120
|
+
* Works across browser, Node.js, Deno, Bun, and serverless environments
|
|
121
|
+
*
|
|
122
|
+
* Note: For large files, prefer uploadFileStream() with a ReadableStream
|
|
123
|
+
* to avoid loading the entire file into memory.
|
|
124
|
+
*
|
|
125
|
+
* @param path - Destination path for the file
|
|
126
|
+
* @param source - Source data: File, Blob, ArrayBuffer, Uint8Array, or string
|
|
127
|
+
* @param contentType - Optional MIME type
|
|
128
|
+
* @returns Upload response
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```ts
|
|
132
|
+
* // From a File (browser)
|
|
133
|
+
* const fileInput = document.querySelector('input[type="file"]');
|
|
134
|
+
* await fs.uploadFile('/path/to/file.txt', fileInput.files[0]);
|
|
135
|
+
*
|
|
136
|
+
* // From a Blob
|
|
137
|
+
* const blob = new Blob(['content']);
|
|
138
|
+
* await fs.uploadFile('/path/to/file.txt', blob);
|
|
139
|
+
*
|
|
140
|
+
* // From a Uint8Array
|
|
141
|
+
* const data = new Uint8Array([1, 2, 3]);
|
|
142
|
+
* await fs.uploadFile('/path/to/file.txt', data);
|
|
143
|
+
*
|
|
144
|
+
* // From a string
|
|
145
|
+
* await fs.uploadFile('/path/to/file.txt', 'content');
|
|
146
|
+
* ```
|
|
147
|
+
*/
|
|
148
|
+
uploadFileFromSource(path: string, source: File | Blob | ArrayBuffer | Uint8Array | string, contentType?: string): Promise<{
|
|
149
|
+
status: string;
|
|
150
|
+
message: string;
|
|
151
|
+
}>;
|
|
152
|
+
deleteFile(path: string): Promise<ExecResponse>;
|
|
153
|
+
createDirectory(path: string): Promise<ExecResponse>;
|
|
154
|
+
createFile(path: string): Promise<ExecResponse>;
|
|
155
|
+
moveFile(from: string, to: string): Promise<ExecResponse>;
|
|
156
|
+
copyFile(from: string, to: string): Promise<ExecResponse>;
|
|
157
|
+
changePermissions(path: string, mode: string): Promise<ExecResponse>;
|
|
158
|
+
compressFile(path: string, format?: 'tar' | 'tar.gz' | 'tar.bz2' | 'zip'): Promise<{
|
|
159
|
+
status?: string;
|
|
160
|
+
message?: string;
|
|
161
|
+
data?: import("./api-client/index").ExecResponseData;
|
|
162
|
+
archivePath: string;
|
|
163
|
+
}>;
|
|
164
|
+
statFile(path: string): Promise<{
|
|
165
|
+
status?: string;
|
|
166
|
+
message?: string;
|
|
167
|
+
data?: import("./api-client/index").ExecResponseData;
|
|
168
|
+
info: StatFileResponse;
|
|
169
|
+
}>;
|
|
170
|
+
searchFiles(path: string, pattern?: string): Promise<{
|
|
171
|
+
status?: string;
|
|
172
|
+
message?: string;
|
|
173
|
+
data?: import("./api-client/index").ExecResponseData;
|
|
174
|
+
paths: string[];
|
|
175
|
+
}>;
|
|
176
|
+
headTail(path: string, options?: {
|
|
177
|
+
lines?: number;
|
|
178
|
+
head?: boolean;
|
|
179
|
+
}): Promise<{
|
|
180
|
+
status?: string;
|
|
181
|
+
message?: string;
|
|
182
|
+
data?: import("./api-client/index").ExecResponseData;
|
|
183
|
+
content: string[];
|
|
184
|
+
}>;
|
|
185
|
+
extractArchive(archivePath: string, destPath?: string): Promise<ExecResponse>;
|
|
186
|
+
folderSize(path: string): Promise<{
|
|
187
|
+
status?: string;
|
|
188
|
+
message?: string;
|
|
189
|
+
data?: import("./api-client/index").ExecResponseData;
|
|
190
|
+
info: FolderSizeResponse;
|
|
191
|
+
}>;
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=FS.d.ts.map
|
package/dist/FS.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FS.d.ts","sourceRoot":"","sources":["../src/FS.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAiB,MAAM,oBAAoB,CAAC;AAEhF,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AA6B/D,qBAAa,EAAE;IAGC,OAAO,CAAC,QAAQ,CAAC,SAAS;IAAU,OAAO,CAAC,QAAQ,CAAC,MAAM;IAFvE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgB;gBAET,SAAS,EAAE,MAAM,EAAmB,MAAM,EAAE,aAAa;IAIhF,SAAS,CAAC,IAAI,EAAE,MAAM;IAW5B;;OAEG;IACG,YAAY,CAAC,IAAI,EAAE,MAAM;IAW/B;;;;;;;;;;;;;;;;;OAiBG;IACG,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;IAiB3E;;;OAGG;IACG,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;;;;IAI9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;IACG,gBAAgB,CAClB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,EAClC,WAAW,GAAE,MAAmC;;;;IAsCpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAuCG;IACG,kBAAkB,CACpB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,WAAW,GAAE,MAAmC;;;;IAiFpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;IACG,oBAAoB,CACtB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,IAAI,GAAG,IAAI,GAAG,WAAW,GAAG,UAAU,GAAG,MAAM,EACvD,WAAW,CAAC,EAAE,MAAM;;;;IA4ClB,UAAU,CAAC,IAAI,EAAE,MAAM;IAOvB,eAAe,CAAC,IAAI,EAAE,MAAM;IAO5B,UAAU,CAAC,IAAI,EAAE,MAAM;IAOvB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;IAQjC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;IAQjC,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAQ5C,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,KAAK,GAAG,QAAQ,GAAG,SAAS,GAAG,KAAgB;;;;;;IAkClF,QAAQ,CAAC,IAAI,EAAE,MAAM;;;;;;IAkBrB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,MAAY;;;;;;IAmB/C,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE;;;;;;IAwBnE,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM;IAQrD,UAAU,CAAC,IAAI,EAAE,MAAM;;;;;;CAyBhC"}
|
package/dist/FS.js
ADDED
|
@@ -0,0 +1,488 @@
|
|
|
1
|
+
import { FileSystemApi } from "./api-client/index";
|
|
2
|
+
import { wrapRequest } from "./utils/runtime";
|
|
3
|
+
/**
|
|
4
|
+
* Detect the JavaScript runtime environment
|
|
5
|
+
*/
|
|
6
|
+
function detectRuntime() {
|
|
7
|
+
const globalThisAny = globalThis;
|
|
8
|
+
// Deno
|
|
9
|
+
if (typeof globalThisAny.Deno !== 'undefined' && globalThisAny.Deno?.version) {
|
|
10
|
+
return 'deno';
|
|
11
|
+
}
|
|
12
|
+
// Bun
|
|
13
|
+
if (typeof globalThisAny.Bun !== 'undefined') {
|
|
14
|
+
return 'bun';
|
|
15
|
+
}
|
|
16
|
+
// Node.js
|
|
17
|
+
if (typeof process !== 'undefined' &&
|
|
18
|
+
process.versions != null &&
|
|
19
|
+
process.versions.node != null) {
|
|
20
|
+
return 'node';
|
|
21
|
+
}
|
|
22
|
+
return 'unknown';
|
|
23
|
+
}
|
|
24
|
+
export class FS {
|
|
25
|
+
sandboxId;
|
|
26
|
+
config;
|
|
27
|
+
fsApi;
|
|
28
|
+
constructor(sandboxId, config) {
|
|
29
|
+
this.sandboxId = sandboxId;
|
|
30
|
+
this.config = config;
|
|
31
|
+
this.fsApi = new FileSystemApi(config);
|
|
32
|
+
}
|
|
33
|
+
async listFiles(path) {
|
|
34
|
+
// Use raw API to handle non-standard response format
|
|
35
|
+
const result = await wrapRequest(this.fsApi.listFiles({
|
|
36
|
+
id: this.sandboxId,
|
|
37
|
+
path
|
|
38
|
+
}));
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Download a file and return the full response (non-streaming)
|
|
43
|
+
*/
|
|
44
|
+
async downloadFile(path) {
|
|
45
|
+
const response = await wrapRequest(this.fsApi.downloadFile({
|
|
46
|
+
id: this.sandboxId,
|
|
47
|
+
path
|
|
48
|
+
}));
|
|
49
|
+
// save blob to file must be compatible with all platforms
|
|
50
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
51
|
+
const buffer = Buffer.from(arrayBuffer);
|
|
52
|
+
return buffer;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Download a file as a streaming ReadableStream
|
|
56
|
+
* Works across browser, Node.js, Deno, Bun, and serverless environments
|
|
57
|
+
*
|
|
58
|
+
* @param path - Path to the file to download
|
|
59
|
+
* @returns A ReadableStream that can be consumed progressively
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* const stream = await fs.downloadFileStream('/path/to/file.txt');
|
|
64
|
+
* const reader = stream.getReader();
|
|
65
|
+
* while (true) {
|
|
66
|
+
* const { done, value } = await reader.read();
|
|
67
|
+
* if (done) break;
|
|
68
|
+
* // Process chunk: value is a Uint8Array
|
|
69
|
+
* }
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
async downloadFileStream(path) {
|
|
73
|
+
const apiResponse = await this.fsApi.downloadFileRaw({
|
|
74
|
+
id: this.sandboxId,
|
|
75
|
+
path
|
|
76
|
+
});
|
|
77
|
+
// Access the raw Response from BlobApiResponse
|
|
78
|
+
const response = apiResponse.raw;
|
|
79
|
+
// Response.body is a ReadableStream in all modern runtimes
|
|
80
|
+
if (!response.body) {
|
|
81
|
+
throw new Error('Response body is null');
|
|
82
|
+
}
|
|
83
|
+
return response.body;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Upload a file (non-streaming, accepts string content)
|
|
87
|
+
* For streaming support, use uploadFileStream() or uploadFileFromSource()
|
|
88
|
+
*/
|
|
89
|
+
async uploadFile(path, content) {
|
|
90
|
+
return this.uploadFileFromSource(path, content);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Upload a file with true streaming support (ReadableStream)
|
|
94
|
+
* Works across browser, Node.js, Deno, Bun, and serverless environments
|
|
95
|
+
*
|
|
96
|
+
* This method streams data directly without buffering the entire file in memory,
|
|
97
|
+
* making it suitable for large files.
|
|
98
|
+
*
|
|
99
|
+
* @param path - Destination path for the file
|
|
100
|
+
* @param stream - ReadableStream to upload
|
|
101
|
+
* @param contentType - Optional MIME type (defaults to 'application/octet-stream')
|
|
102
|
+
* @returns Upload response
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* ```ts
|
|
106
|
+
* // Create a streaming source
|
|
107
|
+
* const stream = new ReadableStream({
|
|
108
|
+
* start(controller) {
|
|
109
|
+
* // Enqueue chunks as they become available
|
|
110
|
+
* controller.enqueue(new Uint8Array([1, 2, 3]));
|
|
111
|
+
* controller.close();
|
|
112
|
+
* }
|
|
113
|
+
* });
|
|
114
|
+
* await fs.uploadFileStream('/path/to/file.txt', stream);
|
|
115
|
+
*
|
|
116
|
+
* // From a File.stream() (browser)
|
|
117
|
+
* const fileInput = document.querySelector('input[type="file"]');
|
|
118
|
+
* const fileStream = fileInput.files[0].stream();
|
|
119
|
+
* await fs.uploadFileStream('/path/to/file.txt', fileStream);
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
async uploadFileStream(path, stream, contentType = 'application/octet-stream') {
|
|
123
|
+
// Use uploadFileRaw with initOverrides to pass the ReadableStream directly
|
|
124
|
+
// This enables true streaming without buffering
|
|
125
|
+
const response = await this.fsApi.uploadFileRaw({
|
|
126
|
+
id: this.sandboxId,
|
|
127
|
+
path,
|
|
128
|
+
body: new Blob([]) // Dummy blob to satisfy type requirement
|
|
129
|
+
}, async (requestContext) => {
|
|
130
|
+
return {
|
|
131
|
+
...requestContext.init,
|
|
132
|
+
body: stream, // Override with the actual stream
|
|
133
|
+
// @ts-ignore - duplex is required for streaming in Node.js fetch
|
|
134
|
+
duplex: 'half', // Required for Node.js fetch API with streams
|
|
135
|
+
headers: {
|
|
136
|
+
...requestContext.init.headers,
|
|
137
|
+
'Content-Type': contentType
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
});
|
|
141
|
+
// Extract the raw Response object and handle text response
|
|
142
|
+
const rawResponse = response.raw;
|
|
143
|
+
if (!rawResponse.ok) {
|
|
144
|
+
const errorText = await rawResponse.text();
|
|
145
|
+
throw new Error(`Upload stream failed: ${errorText}`);
|
|
146
|
+
}
|
|
147
|
+
const responseText = await rawResponse.text();
|
|
148
|
+
return {
|
|
149
|
+
status: 'success',
|
|
150
|
+
message: responseText || 'File uploaded successfully'
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Upload a file from a local file path (Node.js, Deno, Bun, Serverless)
|
|
155
|
+
* Streams the file directly without loading it into memory, suitable for large files.
|
|
156
|
+
*
|
|
157
|
+
* Supported runtimes:
|
|
158
|
+
* - Node.js: Uses fs.createReadStream()
|
|
159
|
+
* - Deno: Uses Deno.open().readable
|
|
160
|
+
* - Bun: Uses Bun.file().stream()
|
|
161
|
+
* - Serverless (Node.js-based): Works with files in /tmp directory
|
|
162
|
+
*
|
|
163
|
+
* Serverless limitations:
|
|
164
|
+
* - AWS Lambda: Only /tmp directory is writable (512 MB default, up to 10 GB)
|
|
165
|
+
* - Vercel Functions: Only /tmp directory is writable
|
|
166
|
+
* - Cloudflare Workers: Not supported (no file system access)
|
|
167
|
+
* - Edge runtimes: Not supported (no file system access)
|
|
168
|
+
*
|
|
169
|
+
* Note: In serverless environments, files must be in /tmp or the function
|
|
170
|
+
* will fail with permission errors. Files in /tmp are ephemeral and only
|
|
171
|
+
* available during the function execution.
|
|
172
|
+
*
|
|
173
|
+
* @param remotePath - Destination path on the remote sandbox
|
|
174
|
+
* @param localPath - Local file system path to the file to upload
|
|
175
|
+
* @param contentType - Optional MIME type (defaults to 'application/octet-stream')
|
|
176
|
+
* @returns Upload response
|
|
177
|
+
*
|
|
178
|
+
* @throws Error if not running in a supported runtime (Node.js, Deno, or Bun)
|
|
179
|
+
* @throws Error if file is not found or not accessible
|
|
180
|
+
*
|
|
181
|
+
* @example
|
|
182
|
+
* ```ts
|
|
183
|
+
* // Upload a large file from local filesystem (works in Node.js, Deno, Bun)
|
|
184
|
+
* await fs.uploadFileFromPath('/remote/path/to/file.txt', './local/file.txt');
|
|
185
|
+
*
|
|
186
|
+
* // Upload with specific content type
|
|
187
|
+
* await fs.uploadFileFromPath('/remote/image.png', './local/image.png', 'image/png');
|
|
188
|
+
*
|
|
189
|
+
* // Serverless example (AWS Lambda / Vercel) - file must be in /tmp
|
|
190
|
+
* await fs.uploadFileFromPath('/remote/data.json', '/tmp/data.json');
|
|
191
|
+
* ```
|
|
192
|
+
*/
|
|
193
|
+
async uploadFileFromPath(remotePath, localPath, contentType = 'application/octet-stream') {
|
|
194
|
+
const runtime = detectRuntime();
|
|
195
|
+
let webStream;
|
|
196
|
+
switch (runtime) {
|
|
197
|
+
case 'node': {
|
|
198
|
+
// Node.js: Use fs.createReadStream and convert to Web Stream
|
|
199
|
+
const { createReadStream } = await import('fs');
|
|
200
|
+
const { Readable } = await import('stream');
|
|
201
|
+
const { stat } = await import('fs/promises');
|
|
202
|
+
// Check if file exists
|
|
203
|
+
try {
|
|
204
|
+
await stat(localPath);
|
|
205
|
+
}
|
|
206
|
+
catch (error) {
|
|
207
|
+
if (error.code === 'ENOENT') {
|
|
208
|
+
throw new Error(`File not found: ${localPath}`);
|
|
209
|
+
}
|
|
210
|
+
throw error;
|
|
211
|
+
}
|
|
212
|
+
// Create Node.js readable stream from file
|
|
213
|
+
const nodeStream = createReadStream(localPath);
|
|
214
|
+
// Convert Node.js stream to Web ReadableStream (Node.js 17+)
|
|
215
|
+
webStream = Readable.toWeb(nodeStream);
|
|
216
|
+
break;
|
|
217
|
+
}
|
|
218
|
+
case 'deno': {
|
|
219
|
+
// Deno: Use Deno.open() to get a readable stream
|
|
220
|
+
const globalThisAny = globalThis;
|
|
221
|
+
const Deno = globalThisAny.Deno;
|
|
222
|
+
try {
|
|
223
|
+
// Open file and get readable stream
|
|
224
|
+
const file = await Deno.open(localPath, { read: true });
|
|
225
|
+
webStream = file.readable;
|
|
226
|
+
}
|
|
227
|
+
catch (error) {
|
|
228
|
+
if (error.name === 'NotFound') {
|
|
229
|
+
throw new Error(`File not found: ${localPath}`);
|
|
230
|
+
}
|
|
231
|
+
throw error;
|
|
232
|
+
}
|
|
233
|
+
break;
|
|
234
|
+
}
|
|
235
|
+
case 'bun': {
|
|
236
|
+
// Bun: Use Bun.file() to get a stream
|
|
237
|
+
const globalThisAny = globalThis;
|
|
238
|
+
const Bun = globalThisAny.Bun;
|
|
239
|
+
try {
|
|
240
|
+
const file = Bun.file(localPath);
|
|
241
|
+
// Check if file exists by trying to get its size
|
|
242
|
+
const exists = await file.exists();
|
|
243
|
+
if (!exists) {
|
|
244
|
+
throw new Error(`File not found: ${localPath}`);
|
|
245
|
+
}
|
|
246
|
+
// Get the stream
|
|
247
|
+
webStream = await file.stream();
|
|
248
|
+
}
|
|
249
|
+
catch (error) {
|
|
250
|
+
if (error.message?.includes('not found') || error.message?.includes('ENOENT')) {
|
|
251
|
+
throw new Error(`File not found: ${localPath}`);
|
|
252
|
+
}
|
|
253
|
+
throw error;
|
|
254
|
+
}
|
|
255
|
+
break;
|
|
256
|
+
}
|
|
257
|
+
default:
|
|
258
|
+
throw new Error('uploadFileFromPath() is only available in Node.js, Deno, or Bun runtimes. ' +
|
|
259
|
+
'Use uploadFileStream() with a ReadableStream in other runtimes (e.g., browser).');
|
|
260
|
+
}
|
|
261
|
+
// Use the existing streaming upload method
|
|
262
|
+
return this.uploadFileStream(remotePath, webStream, contentType);
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Upload a file from various source types (convenience method)
|
|
266
|
+
* Works across browser, Node.js, Deno, Bun, and serverless environments
|
|
267
|
+
*
|
|
268
|
+
* Note: For large files, prefer uploadFileStream() with a ReadableStream
|
|
269
|
+
* to avoid loading the entire file into memory.
|
|
270
|
+
*
|
|
271
|
+
* @param path - Destination path for the file
|
|
272
|
+
* @param source - Source data: File, Blob, ArrayBuffer, Uint8Array, or string
|
|
273
|
+
* @param contentType - Optional MIME type
|
|
274
|
+
* @returns Upload response
|
|
275
|
+
*
|
|
276
|
+
* @example
|
|
277
|
+
* ```ts
|
|
278
|
+
* // From a File (browser)
|
|
279
|
+
* const fileInput = document.querySelector('input[type="file"]');
|
|
280
|
+
* await fs.uploadFile('/path/to/file.txt', fileInput.files[0]);
|
|
281
|
+
*
|
|
282
|
+
* // From a Blob
|
|
283
|
+
* const blob = new Blob(['content']);
|
|
284
|
+
* await fs.uploadFile('/path/to/file.txt', blob);
|
|
285
|
+
*
|
|
286
|
+
* // From a Uint8Array
|
|
287
|
+
* const data = new Uint8Array([1, 2, 3]);
|
|
288
|
+
* await fs.uploadFile('/path/to/file.txt', data);
|
|
289
|
+
*
|
|
290
|
+
* // From a string
|
|
291
|
+
* await fs.uploadFile('/path/to/file.txt', 'content');
|
|
292
|
+
* ```
|
|
293
|
+
*/
|
|
294
|
+
async uploadFileFromSource(path, source, contentType) {
|
|
295
|
+
let body;
|
|
296
|
+
if (source instanceof File) {
|
|
297
|
+
// File is a subclass of Blob, use directly
|
|
298
|
+
body = source;
|
|
299
|
+
}
|
|
300
|
+
else if (source instanceof Blob) {
|
|
301
|
+
body = source;
|
|
302
|
+
}
|
|
303
|
+
else if (source instanceof ArrayBuffer) {
|
|
304
|
+
body = new Blob([source], { type: contentType || 'application/octet-stream' });
|
|
305
|
+
}
|
|
306
|
+
else if (source instanceof Uint8Array) {
|
|
307
|
+
// Uint8Array is compatible with Blob constructor in all runtimes
|
|
308
|
+
// Cast to any to avoid strict type checking issues with ArrayBufferLike vs ArrayBuffer
|
|
309
|
+
body = new Blob([source], { type: contentType || 'application/octet-stream' });
|
|
310
|
+
}
|
|
311
|
+
else if (typeof source === 'string') {
|
|
312
|
+
body = new Blob([source], { type: contentType || 'text/plain' });
|
|
313
|
+
}
|
|
314
|
+
else {
|
|
315
|
+
throw new Error(`Unsupported source type: ${typeof source}`);
|
|
316
|
+
}
|
|
317
|
+
// uploadFile returns plain text response, use Raw API
|
|
318
|
+
const rawResponse = await this.fsApi.uploadFileRaw({
|
|
319
|
+
id: this.sandboxId,
|
|
320
|
+
path,
|
|
321
|
+
body
|
|
322
|
+
});
|
|
323
|
+
// Extract the raw Response object
|
|
324
|
+
const response = rawResponse.raw;
|
|
325
|
+
if (!response.ok) {
|
|
326
|
+
const errorText = await response.text();
|
|
327
|
+
throw new Error(`Upload failed: ${errorText}`);
|
|
328
|
+
}
|
|
329
|
+
// Return a normalized success response
|
|
330
|
+
const responseText = await response.text();
|
|
331
|
+
return {
|
|
332
|
+
status: 'success',
|
|
333
|
+
message: responseText || 'File uploaded successfully'
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
async deleteFile(path) {
|
|
337
|
+
return wrapRequest(this.fsApi.deleteFile({
|
|
338
|
+
id: this.sandboxId,
|
|
339
|
+
path
|
|
340
|
+
}));
|
|
341
|
+
}
|
|
342
|
+
async createDirectory(path) {
|
|
343
|
+
return wrapRequest(this.fsApi.createDirectory({
|
|
344
|
+
id: this.sandboxId,
|
|
345
|
+
path
|
|
346
|
+
}));
|
|
347
|
+
}
|
|
348
|
+
async createFile(path) {
|
|
349
|
+
return wrapRequest(this.fsApi.createFile({
|
|
350
|
+
id: this.sandboxId,
|
|
351
|
+
path
|
|
352
|
+
}));
|
|
353
|
+
}
|
|
354
|
+
async moveFile(from, to) {
|
|
355
|
+
return wrapRequest(this.fsApi.moveFile({
|
|
356
|
+
id: this.sandboxId,
|
|
357
|
+
from,
|
|
358
|
+
to
|
|
359
|
+
}));
|
|
360
|
+
}
|
|
361
|
+
async copyFile(from, to) {
|
|
362
|
+
return wrapRequest(this.fsApi.copyFile({
|
|
363
|
+
id: this.sandboxId,
|
|
364
|
+
from,
|
|
365
|
+
to
|
|
366
|
+
}));
|
|
367
|
+
}
|
|
368
|
+
async changePermissions(path, mode) {
|
|
369
|
+
return wrapRequest(this.fsApi.changePermissions({
|
|
370
|
+
id: this.sandboxId,
|
|
371
|
+
path,
|
|
372
|
+
mode
|
|
373
|
+
}));
|
|
374
|
+
}
|
|
375
|
+
async compressFile(path, format = 'tar.gz') {
|
|
376
|
+
const response = await wrapRequest(this.fsApi.compressFile({
|
|
377
|
+
id: this.sandboxId,
|
|
378
|
+
path,
|
|
379
|
+
format
|
|
380
|
+
}));
|
|
381
|
+
// Backend executes tar/zip command but doesn't return the archive path
|
|
382
|
+
// Construct it based on the source path and format
|
|
383
|
+
const cleanPath = path.startsWith('/') ? path : '/' + path;
|
|
384
|
+
let archivePath;
|
|
385
|
+
switch (format) {
|
|
386
|
+
case 'tar':
|
|
387
|
+
archivePath = `${cleanPath}.tar`;
|
|
388
|
+
break;
|
|
389
|
+
case 'tar.gz':
|
|
390
|
+
archivePath = `${cleanPath}.tar.gz`;
|
|
391
|
+
break;
|
|
392
|
+
case 'tar.bz2':
|
|
393
|
+
archivePath = `${cleanPath}.tar.bz2`;
|
|
394
|
+
break;
|
|
395
|
+
case 'zip':
|
|
396
|
+
archivePath = `${cleanPath}.zip`;
|
|
397
|
+
break;
|
|
398
|
+
default:
|
|
399
|
+
archivePath = `${cleanPath}.tar.gz`;
|
|
400
|
+
}
|
|
401
|
+
return { archivePath, ...response };
|
|
402
|
+
}
|
|
403
|
+
async statFile(path) {
|
|
404
|
+
const result = await wrapRequest(this.fsApi.statFile({
|
|
405
|
+
id: this.sandboxId,
|
|
406
|
+
path
|
|
407
|
+
}));
|
|
408
|
+
let info = {};
|
|
409
|
+
if (result?.data?.stdout) {
|
|
410
|
+
try {
|
|
411
|
+
info = JSON.parse(result.data.stdout.trim());
|
|
412
|
+
}
|
|
413
|
+
catch (e) {
|
|
414
|
+
info = {};
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
return { info, ...result };
|
|
418
|
+
}
|
|
419
|
+
async searchFiles(path, pattern = "*") {
|
|
420
|
+
const result = await wrapRequest(this.fsApi.searchFiles({
|
|
421
|
+
id: this.sandboxId,
|
|
422
|
+
path,
|
|
423
|
+
pattern
|
|
424
|
+
}));
|
|
425
|
+
let paths = [];
|
|
426
|
+
if (result?.data?.stdout) {
|
|
427
|
+
paths = result.data.stdout
|
|
428
|
+
.split(/\r?\n/)
|
|
429
|
+
.map((line) => line.trim())
|
|
430
|
+
.filter((line) => line.length > 0);
|
|
431
|
+
}
|
|
432
|
+
return { paths, ...result };
|
|
433
|
+
}
|
|
434
|
+
async headTail(path, options) {
|
|
435
|
+
const lines = options?.lines ?? 10;
|
|
436
|
+
const head = options?.head ?? true;
|
|
437
|
+
const result = await wrapRequest(this.fsApi.headTail({
|
|
438
|
+
id: this.sandboxId,
|
|
439
|
+
path,
|
|
440
|
+
lines,
|
|
441
|
+
head
|
|
442
|
+
}));
|
|
443
|
+
// Backend returns {status, message, data: {stdout: "...", exitCode: 0}}
|
|
444
|
+
let content = [];
|
|
445
|
+
if (result?.data?.stdout) {
|
|
446
|
+
const text = String(result.data.stdout);
|
|
447
|
+
content = text
|
|
448
|
+
.split(/\r?\n/)
|
|
449
|
+
.map((l) => l.trimEnd())
|
|
450
|
+
.filter((l) => l.length > 0);
|
|
451
|
+
}
|
|
452
|
+
return { content, ...result };
|
|
453
|
+
}
|
|
454
|
+
async extractArchive(archivePath, destPath) {
|
|
455
|
+
return wrapRequest(this.fsApi.extractArchive({
|
|
456
|
+
id: this.sandboxId,
|
|
457
|
+
archive: archivePath,
|
|
458
|
+
dest: destPath || "/tmp"
|
|
459
|
+
}));
|
|
460
|
+
}
|
|
461
|
+
async folderSize(path) {
|
|
462
|
+
const result = await wrapRequest(this.fsApi.diskUsage({
|
|
463
|
+
id: this.sandboxId,
|
|
464
|
+
path
|
|
465
|
+
}));
|
|
466
|
+
// Backend returns {status, message, data: {stdout: "4.0K\t/tmp/fs-e2e", exitCode: 0}}
|
|
467
|
+
// Parse the du output from stdout (format: "SIZE\tPATH")
|
|
468
|
+
let info = {};
|
|
469
|
+
if (result?.data?.stdout) {
|
|
470
|
+
const output = result.data.stdout.trim();
|
|
471
|
+
const parts = output.split(/\s+/);
|
|
472
|
+
if (parts.length >= 2) {
|
|
473
|
+
const rawSize = parts[0];
|
|
474
|
+
info.size = Number(rawSize.replace(/[KMG]$/, ''));
|
|
475
|
+
if (rawSize.endsWith('K'))
|
|
476
|
+
info.unit = 'KB';
|
|
477
|
+
else if (rawSize.endsWith('M'))
|
|
478
|
+
info.unit = 'MB';
|
|
479
|
+
else if (rawSize.endsWith('G'))
|
|
480
|
+
info.unit = 'GB';
|
|
481
|
+
else
|
|
482
|
+
info.unit = 'KB'; // Default to KB if no suffix (du -h usually adds it)
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
return { info, ...result };
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
//# sourceMappingURL=FS.js.map
|