@cloudflare/sandbox 0.0.0-ee8c772 → 0.0.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 +0 -1
- package/container_src/index.ts +1 -281
- package/dist/chunk-GYEDSCAB.js +1197 -0
- package/dist/chunk-GYEDSCAB.js.map +1 -0
- package/dist/client.d.ts +2 -0
- package/dist/client.js +37 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +170 -0
- package/dist/index.js +74 -0
- package/dist/index.js.map +1 -0
- package/package.json +2 -13
- package/src/client.ts +0 -205
- package/src/index.ts +0 -50
- package/tests/test2.ts +0 -219
- package/CHANGELOG.md +0 -13
package/README.md
CHANGED
|
@@ -56,7 +56,6 @@ export default {
|
|
|
56
56
|
- `gitCheckout(repoUrl: string, options: { branch?: string; targetDir?: string; stream?: boolean })`: Checkout a git repository in the sandbox.
|
|
57
57
|
- `mkdir(path: string, options: { recursive?: boolean; stream?: boolean })`: Create a directory in the sandbox.
|
|
58
58
|
- `writeFile(path: string, content: string, options: { encoding?: string; stream?: boolean })`: Write content to a file in the sandbox.
|
|
59
|
-
- `readFile(path: string, options: { encoding?: string; stream?: boolean })`: Read content from a file in the sandbox.
|
|
60
59
|
- `deleteFile(path: string, options?: { stream?: boolean })`: Delete a file from the sandbox.
|
|
61
60
|
- `renameFile(oldPath: string, newPath: string, options?: { stream?: boolean })`: Rename a file in the sandbox.
|
|
62
61
|
- `moveFile(sourcePath: string, destinationPath: string, options?: { stream?: boolean })`: Move a file from one location to another in the sandbox.
|
package/container_src/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
|
-
import { mkdir,
|
|
2
|
+
import { mkdir, rename, unlink, writeFile } from "node:fs/promises";
|
|
3
3
|
import { dirname } from "node:path";
|
|
4
4
|
import { serve } from "bun";
|
|
5
5
|
|
|
@@ -28,12 +28,6 @@ interface WriteFileRequest {
|
|
|
28
28
|
sessionId?: string;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
interface ReadFileRequest {
|
|
32
|
-
path: string;
|
|
33
|
-
encoding?: string;
|
|
34
|
-
sessionId?: string;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
31
|
interface DeleteFileRequest {
|
|
38
32
|
path: string;
|
|
39
33
|
sessionId?: string;
|
|
@@ -303,18 +297,6 @@ const server = serve({
|
|
|
303
297
|
}
|
|
304
298
|
break;
|
|
305
299
|
|
|
306
|
-
case "/api/read":
|
|
307
|
-
if (req.method === "POST") {
|
|
308
|
-
return handleReadFileRequest(req, corsHeaders);
|
|
309
|
-
}
|
|
310
|
-
break;
|
|
311
|
-
|
|
312
|
-
case "/api/read/stream":
|
|
313
|
-
if (req.method === "POST") {
|
|
314
|
-
return handleStreamingReadFileRequest(req, corsHeaders);
|
|
315
|
-
}
|
|
316
|
-
break;
|
|
317
|
-
|
|
318
300
|
case "/api/delete":
|
|
319
301
|
if (req.method === "POST") {
|
|
320
302
|
return handleDeleteFileRequest(req, corsHeaders);
|
|
@@ -1494,235 +1476,6 @@ async function handleStreamingWriteFileRequest(
|
|
|
1494
1476
|
}
|
|
1495
1477
|
}
|
|
1496
1478
|
|
|
1497
|
-
async function handleReadFileRequest(
|
|
1498
|
-
req: Request,
|
|
1499
|
-
corsHeaders: Record<string, string>
|
|
1500
|
-
): Promise<Response> {
|
|
1501
|
-
try {
|
|
1502
|
-
const body = (await req.json()) as ReadFileRequest;
|
|
1503
|
-
const { path, encoding = "utf-8", sessionId } = body;
|
|
1504
|
-
|
|
1505
|
-
if (!path || typeof path !== "string") {
|
|
1506
|
-
return new Response(
|
|
1507
|
-
JSON.stringify({
|
|
1508
|
-
error: "Path is required and must be a string",
|
|
1509
|
-
}),
|
|
1510
|
-
{
|
|
1511
|
-
headers: {
|
|
1512
|
-
"Content-Type": "application/json",
|
|
1513
|
-
...corsHeaders,
|
|
1514
|
-
},
|
|
1515
|
-
status: 400,
|
|
1516
|
-
}
|
|
1517
|
-
);
|
|
1518
|
-
}
|
|
1519
|
-
|
|
1520
|
-
// Basic safety check - prevent dangerous paths
|
|
1521
|
-
const dangerousPatterns = [
|
|
1522
|
-
/^\/$/, // Root directory
|
|
1523
|
-
/^\/etc/, // System directories
|
|
1524
|
-
/^\/var/, // System directories
|
|
1525
|
-
/^\/usr/, // System directories
|
|
1526
|
-
/^\/bin/, // System directories
|
|
1527
|
-
/^\/sbin/, // System directories
|
|
1528
|
-
/^\/boot/, // System directories
|
|
1529
|
-
/^\/dev/, // System directories
|
|
1530
|
-
/^\/proc/, // System directories
|
|
1531
|
-
/^\/sys/, // System directories
|
|
1532
|
-
/^\/tmp\/\.\./, // Path traversal attempts
|
|
1533
|
-
/\.\./, // Path traversal attempts
|
|
1534
|
-
];
|
|
1535
|
-
|
|
1536
|
-
if (dangerousPatterns.some((pattern) => pattern.test(path))) {
|
|
1537
|
-
return new Response(
|
|
1538
|
-
JSON.stringify({
|
|
1539
|
-
error: "Dangerous path not allowed",
|
|
1540
|
-
}),
|
|
1541
|
-
{
|
|
1542
|
-
headers: {
|
|
1543
|
-
"Content-Type": "application/json",
|
|
1544
|
-
...corsHeaders,
|
|
1545
|
-
},
|
|
1546
|
-
status: 400,
|
|
1547
|
-
}
|
|
1548
|
-
);
|
|
1549
|
-
}
|
|
1550
|
-
|
|
1551
|
-
console.log(`[Server] Reading file: ${path}`);
|
|
1552
|
-
|
|
1553
|
-
const result = await executeReadFile(path, encoding, sessionId);
|
|
1554
|
-
|
|
1555
|
-
return new Response(
|
|
1556
|
-
JSON.stringify({
|
|
1557
|
-
content: result.content,
|
|
1558
|
-
exitCode: result.exitCode,
|
|
1559
|
-
path,
|
|
1560
|
-
success: result.success,
|
|
1561
|
-
timestamp: new Date().toISOString(),
|
|
1562
|
-
}),
|
|
1563
|
-
{
|
|
1564
|
-
headers: {
|
|
1565
|
-
"Content-Type": "application/json",
|
|
1566
|
-
...corsHeaders,
|
|
1567
|
-
},
|
|
1568
|
-
}
|
|
1569
|
-
);
|
|
1570
|
-
} catch (error) {
|
|
1571
|
-
console.error("[Server] Error in handleReadFileRequest:", error);
|
|
1572
|
-
return new Response(
|
|
1573
|
-
JSON.stringify({
|
|
1574
|
-
error: "Failed to read file",
|
|
1575
|
-
message: error instanceof Error ? error.message : "Unknown error",
|
|
1576
|
-
}),
|
|
1577
|
-
{
|
|
1578
|
-
headers: {
|
|
1579
|
-
"Content-Type": "application/json",
|
|
1580
|
-
...corsHeaders,
|
|
1581
|
-
},
|
|
1582
|
-
status: 500,
|
|
1583
|
-
}
|
|
1584
|
-
);
|
|
1585
|
-
}
|
|
1586
|
-
}
|
|
1587
|
-
|
|
1588
|
-
async function handleStreamingReadFileRequest(
|
|
1589
|
-
req: Request,
|
|
1590
|
-
corsHeaders: Record<string, string>
|
|
1591
|
-
): Promise<Response> {
|
|
1592
|
-
try {
|
|
1593
|
-
const body = (await req.json()) as ReadFileRequest;
|
|
1594
|
-
const { path, encoding = "utf-8", sessionId } = body;
|
|
1595
|
-
|
|
1596
|
-
if (!path || typeof path !== "string") {
|
|
1597
|
-
return new Response(
|
|
1598
|
-
JSON.stringify({
|
|
1599
|
-
error: "Path is required and must be a string",
|
|
1600
|
-
}),
|
|
1601
|
-
{
|
|
1602
|
-
headers: {
|
|
1603
|
-
"Content-Type": "application/json",
|
|
1604
|
-
...corsHeaders,
|
|
1605
|
-
},
|
|
1606
|
-
status: 400,
|
|
1607
|
-
}
|
|
1608
|
-
);
|
|
1609
|
-
}
|
|
1610
|
-
|
|
1611
|
-
// Basic safety check - prevent dangerous paths
|
|
1612
|
-
const dangerousPatterns = [
|
|
1613
|
-
/^\/$/, // Root directory
|
|
1614
|
-
/^\/etc/, // System directories
|
|
1615
|
-
/^\/var/, // System directories
|
|
1616
|
-
/^\/usr/, // System directories
|
|
1617
|
-
/^\/bin/, // System directories
|
|
1618
|
-
/^\/sbin/, // System directories
|
|
1619
|
-
/^\/boot/, // System directories
|
|
1620
|
-
/^\/dev/, // System directories
|
|
1621
|
-
/^\/proc/, // System directories
|
|
1622
|
-
/^\/sys/, // System directories
|
|
1623
|
-
/^\/tmp\/\.\./, // Path traversal attempts
|
|
1624
|
-
/\.\./, // Path traversal attempts
|
|
1625
|
-
];
|
|
1626
|
-
|
|
1627
|
-
if (dangerousPatterns.some((pattern) => pattern.test(path))) {
|
|
1628
|
-
return new Response(
|
|
1629
|
-
JSON.stringify({
|
|
1630
|
-
error: "Dangerous path not allowed",
|
|
1631
|
-
}),
|
|
1632
|
-
{
|
|
1633
|
-
headers: {
|
|
1634
|
-
"Content-Type": "application/json",
|
|
1635
|
-
...corsHeaders,
|
|
1636
|
-
},
|
|
1637
|
-
status: 400,
|
|
1638
|
-
}
|
|
1639
|
-
);
|
|
1640
|
-
}
|
|
1641
|
-
|
|
1642
|
-
console.log(`[Server] Reading file (streaming): ${path}`);
|
|
1643
|
-
|
|
1644
|
-
const stream = new ReadableStream({
|
|
1645
|
-
start(controller) {
|
|
1646
|
-
(async () => {
|
|
1647
|
-
try {
|
|
1648
|
-
// Send command start event
|
|
1649
|
-
controller.enqueue(
|
|
1650
|
-
new TextEncoder().encode(
|
|
1651
|
-
`data: ${JSON.stringify({
|
|
1652
|
-
path,
|
|
1653
|
-
timestamp: new Date().toISOString(),
|
|
1654
|
-
type: "command_start",
|
|
1655
|
-
})}\n\n`
|
|
1656
|
-
)
|
|
1657
|
-
);
|
|
1658
|
-
|
|
1659
|
-
// Read the file
|
|
1660
|
-
const content = await readFile(path, {
|
|
1661
|
-
encoding: encoding as BufferEncoding,
|
|
1662
|
-
});
|
|
1663
|
-
|
|
1664
|
-
console.log(`[Server] File read successfully: ${path}`);
|
|
1665
|
-
|
|
1666
|
-
// Send command completion event
|
|
1667
|
-
controller.enqueue(
|
|
1668
|
-
new TextEncoder().encode(
|
|
1669
|
-
`data: ${JSON.stringify({
|
|
1670
|
-
content,
|
|
1671
|
-
path,
|
|
1672
|
-
success: true,
|
|
1673
|
-
timestamp: new Date().toISOString(),
|
|
1674
|
-
type: "command_complete",
|
|
1675
|
-
})}\n\n`
|
|
1676
|
-
)
|
|
1677
|
-
);
|
|
1678
|
-
|
|
1679
|
-
controller.close();
|
|
1680
|
-
} catch (error) {
|
|
1681
|
-
console.error(`[Server] Error reading file: ${path}`, error);
|
|
1682
|
-
|
|
1683
|
-
controller.enqueue(
|
|
1684
|
-
new TextEncoder().encode(
|
|
1685
|
-
`data: ${JSON.stringify({
|
|
1686
|
-
error:
|
|
1687
|
-
error instanceof Error ? error.message : "Unknown error",
|
|
1688
|
-
path,
|
|
1689
|
-
type: "error",
|
|
1690
|
-
})}\n\n`
|
|
1691
|
-
)
|
|
1692
|
-
);
|
|
1693
|
-
|
|
1694
|
-
controller.close();
|
|
1695
|
-
}
|
|
1696
|
-
})();
|
|
1697
|
-
},
|
|
1698
|
-
});
|
|
1699
|
-
|
|
1700
|
-
return new Response(stream, {
|
|
1701
|
-
headers: {
|
|
1702
|
-
"Cache-Control": "no-cache",
|
|
1703
|
-
Connection: "keep-alive",
|
|
1704
|
-
"Content-Type": "text/event-stream",
|
|
1705
|
-
...corsHeaders,
|
|
1706
|
-
},
|
|
1707
|
-
});
|
|
1708
|
-
} catch (error) {
|
|
1709
|
-
console.error("[Server] Error in handleStreamingReadFileRequest:", error);
|
|
1710
|
-
return new Response(
|
|
1711
|
-
JSON.stringify({
|
|
1712
|
-
error: "Failed to read file",
|
|
1713
|
-
message: error instanceof Error ? error.message : "Unknown error",
|
|
1714
|
-
}),
|
|
1715
|
-
{
|
|
1716
|
-
headers: {
|
|
1717
|
-
"Content-Type": "application/json",
|
|
1718
|
-
...corsHeaders,
|
|
1719
|
-
},
|
|
1720
|
-
status: 500,
|
|
1721
|
-
}
|
|
1722
|
-
);
|
|
1723
|
-
}
|
|
1724
|
-
}
|
|
1725
|
-
|
|
1726
1479
|
async function handleDeleteFileRequest(
|
|
1727
1480
|
req: Request,
|
|
1728
1481
|
corsHeaders: Record<string, string>
|
|
@@ -2753,37 +2506,6 @@ function executeWriteFile(
|
|
|
2753
2506
|
});
|
|
2754
2507
|
}
|
|
2755
2508
|
|
|
2756
|
-
function executeReadFile(
|
|
2757
|
-
path: string,
|
|
2758
|
-
encoding: string,
|
|
2759
|
-
sessionId?: string
|
|
2760
|
-
): Promise<{
|
|
2761
|
-
success: boolean;
|
|
2762
|
-
exitCode: number;
|
|
2763
|
-
content: string;
|
|
2764
|
-
}> {
|
|
2765
|
-
return new Promise((resolve, reject) => {
|
|
2766
|
-
(async () => {
|
|
2767
|
-
try {
|
|
2768
|
-
// Read the file
|
|
2769
|
-
const content = await readFile(path, {
|
|
2770
|
-
encoding: encoding as BufferEncoding,
|
|
2771
|
-
});
|
|
2772
|
-
|
|
2773
|
-
console.log(`[Server] File read successfully: ${path}`);
|
|
2774
|
-
resolve({
|
|
2775
|
-
content,
|
|
2776
|
-
exitCode: 0,
|
|
2777
|
-
success: true,
|
|
2778
|
-
});
|
|
2779
|
-
} catch (error) {
|
|
2780
|
-
console.error(`[Server] Error reading file: ${path}`, error);
|
|
2781
|
-
reject(error);
|
|
2782
|
-
}
|
|
2783
|
-
})();
|
|
2784
|
-
});
|
|
2785
|
-
}
|
|
2786
|
-
|
|
2787
2509
|
function executeDeleteFile(
|
|
2788
2510
|
path: string,
|
|
2789
2511
|
sessionId?: string
|
|
@@ -2888,8 +2610,6 @@ console.log(` POST /api/mkdir - Create a directory`);
|
|
|
2888
2610
|
console.log(` POST /api/mkdir/stream - Create a directory (streaming)`);
|
|
2889
2611
|
console.log(` POST /api/write - Write a file`);
|
|
2890
2612
|
console.log(` POST /api/write/stream - Write a file (streaming)`);
|
|
2891
|
-
console.log(` POST /api/read - Read a file`);
|
|
2892
|
-
console.log(` POST /api/read/stream - Read a file (streaming)`);
|
|
2893
2613
|
console.log(` POST /api/delete - Delete a file`);
|
|
2894
2614
|
console.log(` POST /api/delete/stream - Delete a file (streaming)`);
|
|
2895
2615
|
console.log(` POST /api/rename - Rename a file`);
|