sandsnap 0.1.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/LICENSE +21 -0
- package/README.md +287 -0
- package/dist/commands/delete.d.ts +9 -0
- package/dist/commands/delete.d.ts.map +1 -0
- package/dist/commands/delete.js +50 -0
- package/dist/commands/delete.js.map +1 -0
- package/dist/commands/evolve.d.ts +17 -0
- package/dist/commands/evolve.d.ts.map +1 -0
- package/dist/commands/evolve.js +228 -0
- package/dist/commands/evolve.js.map +1 -0
- package/dist/commands/list.d.ts +10 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +47 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/prune.d.ts +13 -0
- package/dist/commands/prune.d.ts.map +1 -0
- package/dist/commands/prune.js +75 -0
- package/dist/commands/prune.js.map +1 -0
- package/dist/commands/run.d.ts +15 -0
- package/dist/commands/run.d.ts.map +1 -0
- package/dist/commands/run.js +132 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/sandboxes.d.ts +11 -0
- package/dist/commands/sandboxes.d.ts.map +1 -0
- package/dist/commands/sandboxes.js +79 -0
- package/dist/commands/sandboxes.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +83 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/client.d.ts +14 -0
- package/dist/lib/client.d.ts.map +1 -0
- package/dist/lib/client.js +30 -0
- package/dist/lib/client.js.map +1 -0
- package/dist/lib/copy.d.ts +14 -0
- package/dist/lib/copy.d.ts.map +1 -0
- package/dist/lib/copy.js +91 -0
- package/dist/lib/copy.js.map +1 -0
- package/dist/lib/output.d.ts +28 -0
- package/dist/lib/output.d.ts.map +1 -0
- package/dist/lib/output.js +69 -0
- package/dist/lib/output.js.map +1 -0
- package/dist/lib/parse.d.ts +23 -0
- package/dist/lib/parse.d.ts.map +1 -0
- package/dist/lib/parse.js +58 -0
- package/dist/lib/parse.js.map +1 -0
- package/dist/lib/parse.test.d.ts +2 -0
- package/dist/lib/parse.test.d.ts.map +1 -0
- package/dist/lib/parse.test.js +139 -0
- package/dist/lib/parse.test.js.map +1 -0
- package/dist/lib/stdin.d.ts +24 -0
- package/dist/lib/stdin.d.ts.map +1 -0
- package/dist/lib/stdin.js +79 -0
- package/dist/lib/stdin.js.map +1 -0
- package/package.json +55 -0
package/dist/lib/copy.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File copy utilities for sandbox operations
|
|
3
|
+
*/
|
|
4
|
+
import * as fs from "node:fs";
|
|
5
|
+
import * as path from "node:path";
|
|
6
|
+
import { info, error } from "./output.js";
|
|
7
|
+
import { parseCopySpec } from "./parse.js";
|
|
8
|
+
/**
|
|
9
|
+
* Copy files from host to sandbox
|
|
10
|
+
*/
|
|
11
|
+
export async function copyToSandbox(sandbox, specs) {
|
|
12
|
+
for (const spec of specs) {
|
|
13
|
+
const { src, dst } = parseCopySpec(spec);
|
|
14
|
+
// Check if source exists
|
|
15
|
+
if (!fs.existsSync(src)) {
|
|
16
|
+
throw new Error(`Source path not found: ${src}`);
|
|
17
|
+
}
|
|
18
|
+
const stat = fs.statSync(src);
|
|
19
|
+
if (stat.isDirectory()) {
|
|
20
|
+
// Upload directory
|
|
21
|
+
// Note: SDK uploads the directory INTO dst, so /tmp/foo -> /app creates /app/foo/*
|
|
22
|
+
info(`Copying directory ${src} → ${dst}`);
|
|
23
|
+
await sandbox.fs.upload(src, dst);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
// Upload file - ensure parent directory exists
|
|
27
|
+
info(`Copying file ${src} → ${dst}`);
|
|
28
|
+
const dstDir = path.dirname(dst);
|
|
29
|
+
if (dstDir && dstDir !== "." && dstDir !== "/") {
|
|
30
|
+
await sandbox.sh `mkdir -p ${dstDir}`.noThrow();
|
|
31
|
+
}
|
|
32
|
+
await sandbox.fs.upload(src, dst);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Copy files from sandbox to host
|
|
38
|
+
*/
|
|
39
|
+
export async function copyFromSandbox(sandbox, specs) {
|
|
40
|
+
for (const spec of specs) {
|
|
41
|
+
const { src, dst } = parseCopySpec(spec);
|
|
42
|
+
try {
|
|
43
|
+
// Check if it's a directory by trying to list it
|
|
44
|
+
const checkResult = await sandbox.sh `test -d ${src} && echo "dir" || echo "file"`.text();
|
|
45
|
+
const isDir = checkResult.trim() === "dir";
|
|
46
|
+
if (isDir) {
|
|
47
|
+
// Use tar to copy directory
|
|
48
|
+
info(`Copying directory ${src} → ${dst}`);
|
|
49
|
+
// Ensure destination directory exists
|
|
50
|
+
fs.mkdirSync(dst, { recursive: true });
|
|
51
|
+
// Create tar on sandbox, pipe to local extraction
|
|
52
|
+
const proc = await sandbox.spawn("tar", {
|
|
53
|
+
args: ["-cf", "-", "-C", path.dirname(src), path.basename(src)],
|
|
54
|
+
stdout: "piped",
|
|
55
|
+
});
|
|
56
|
+
// Collect tar data
|
|
57
|
+
const chunks = [];
|
|
58
|
+
if (proc.stdout) {
|
|
59
|
+
for await (const chunk of proc.stdout) {
|
|
60
|
+
chunks.push(chunk);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
await proc.status;
|
|
64
|
+
// Write to temp file and extract
|
|
65
|
+
const tarData = Buffer.concat(chunks);
|
|
66
|
+
const tempTar = path.join(dst, ".sandsnap-temp.tar");
|
|
67
|
+
fs.writeFileSync(tempTar, tarData);
|
|
68
|
+
// Extract using local tar
|
|
69
|
+
const { execSync } = await import("node:child_process");
|
|
70
|
+
execSync(`tar -xf "${tempTar}" -C "${dst}"`, { stdio: "pipe" });
|
|
71
|
+
fs.unlinkSync(tempTar);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
// Read file directly
|
|
75
|
+
info(`Copying file ${src} → ${dst}`);
|
|
76
|
+
// Ensure destination directory exists
|
|
77
|
+
const dstDir = path.dirname(dst);
|
|
78
|
+
if (dstDir && dstDir !== ".") {
|
|
79
|
+
fs.mkdirSync(dstDir, { recursive: true });
|
|
80
|
+
}
|
|
81
|
+
const content = await sandbox.fs.readFile(src);
|
|
82
|
+
fs.writeFileSync(dst, content);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
error(`Failed to copy ${src}: ${err}`);
|
|
87
|
+
// Continue with other files
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=copy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copy.js","sourceRoot":"","sources":["../../src/lib/copy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output formatting utilities
|
|
3
|
+
*/
|
|
4
|
+
export declare function setVerbose(v: boolean): void;
|
|
5
|
+
export declare function isVerbose(): boolean;
|
|
6
|
+
/** Always shown */
|
|
7
|
+
export declare function success(message: string): void;
|
|
8
|
+
/** Always shown */
|
|
9
|
+
export declare function error(message: string): void;
|
|
10
|
+
/** Only shown in verbose mode */
|
|
11
|
+
export declare function info(message: string): void;
|
|
12
|
+
/** Only shown in verbose mode */
|
|
13
|
+
export declare function warn(message: string): void;
|
|
14
|
+
/** Only shown in verbose mode */
|
|
15
|
+
export declare function step(n: number, total: number, message: string): void;
|
|
16
|
+
/**
|
|
17
|
+
* Format bytes to human readable string
|
|
18
|
+
*/
|
|
19
|
+
export declare function formatBytes(bytes: number): string;
|
|
20
|
+
/**
|
|
21
|
+
* Format date to readable string
|
|
22
|
+
*/
|
|
23
|
+
export declare function formatDate(date: string | Date): string;
|
|
24
|
+
/**
|
|
25
|
+
* Simple table formatter
|
|
26
|
+
*/
|
|
27
|
+
export declare function table(headers: string[], rows: string[][]): string;
|
|
28
|
+
//# sourceMappingURL=output.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/lib/output.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,wBAAgB,UAAU,CAAC,CAAC,EAAE,OAAO,GAAG,IAAI,CAE3C;AAED,wBAAgB,SAAS,IAAI,OAAO,CAEnC;AAED,mBAAmB;AACnB,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE7C;AAED,mBAAmB;AACnB,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE3C;AAED,iCAAiC;AACjC,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAI1C;AAED,iCAAiC;AACjC,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAI1C;AAED,iCAAiC;AACjC,wBAAgB,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAIpE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAWjD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAGtD;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,MAAM,CAYjE"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output formatting utilities
|
|
3
|
+
*/
|
|
4
|
+
let _verbose = false;
|
|
5
|
+
export function setVerbose(v) {
|
|
6
|
+
_verbose = v;
|
|
7
|
+
}
|
|
8
|
+
export function isVerbose() {
|
|
9
|
+
return _verbose;
|
|
10
|
+
}
|
|
11
|
+
/** Always shown */
|
|
12
|
+
export function success(message) {
|
|
13
|
+
console.error(`✓ ${message}`);
|
|
14
|
+
}
|
|
15
|
+
/** Always shown */
|
|
16
|
+
export function error(message) {
|
|
17
|
+
console.error(`✗ ${message}`);
|
|
18
|
+
}
|
|
19
|
+
/** Only shown in verbose mode */
|
|
20
|
+
export function info(message) {
|
|
21
|
+
if (_verbose) {
|
|
22
|
+
console.error(`ℹ ${message}`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/** Only shown in verbose mode */
|
|
26
|
+
export function warn(message) {
|
|
27
|
+
if (_verbose) {
|
|
28
|
+
console.error(`⚠ ${message}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/** Only shown in verbose mode */
|
|
32
|
+
export function step(n, total, message) {
|
|
33
|
+
if (_verbose) {
|
|
34
|
+
console.error(`[${n}/${total}] ${message}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Format bytes to human readable string
|
|
39
|
+
*/
|
|
40
|
+
export function formatBytes(bytes) {
|
|
41
|
+
const units = ["B", "KiB", "MiB", "GiB", "TiB"];
|
|
42
|
+
let unitIndex = 0;
|
|
43
|
+
let value = bytes;
|
|
44
|
+
while (value >= 1024 && unitIndex < units.length - 1) {
|
|
45
|
+
value /= 1024;
|
|
46
|
+
unitIndex++;
|
|
47
|
+
}
|
|
48
|
+
return `${value.toFixed(unitIndex === 0 ? 0 : 2)} ${units[unitIndex]}`;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Format date to readable string
|
|
52
|
+
*/
|
|
53
|
+
export function formatDate(date) {
|
|
54
|
+
const d = typeof date === "string" ? new Date(date) : date;
|
|
55
|
+
return d.toISOString().replace("T", " ").slice(0, 19);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Simple table formatter
|
|
59
|
+
*/
|
|
60
|
+
export function table(headers, rows) {
|
|
61
|
+
const widths = headers.map((h, i) => {
|
|
62
|
+
const maxRow = Math.max(...rows.map((r) => (r[i] || "").length));
|
|
63
|
+
return Math.max(h.length, maxRow);
|
|
64
|
+
});
|
|
65
|
+
const headerLine = headers.map((h, i) => h.padEnd(widths[i])).join(" ");
|
|
66
|
+
const dataLines = rows.map((row) => row.map((cell, i) => (cell || "").padEnd(widths[i])).join(" "));
|
|
67
|
+
return [headerLine, ...dataLines].join("\n");
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/lib/output.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared parsing utilities
|
|
3
|
+
*/
|
|
4
|
+
import type { Region } from "@deno/sandbox";
|
|
5
|
+
export type Capacity = `${number}GiB` | `${number}MiB` | `${number}GB` | `${number}MB`;
|
|
6
|
+
export type Memory = `${number}GiB` | `${number}MiB` | `${number}GB` | `${number}MB`;
|
|
7
|
+
export type Timeout = `${number}m` | `${number}s` | "session";
|
|
8
|
+
export declare function parseCapacity(s: string): Capacity;
|
|
9
|
+
export declare function parseMemory(s: string): Memory;
|
|
10
|
+
export declare function parseTimeout(s: string): Timeout;
|
|
11
|
+
export declare function parseRegion(s: string): Region;
|
|
12
|
+
export interface CopySpec {
|
|
13
|
+
src: string;
|
|
14
|
+
dst: string;
|
|
15
|
+
}
|
|
16
|
+
export declare function parseCopySpec(spec: string): CopySpec;
|
|
17
|
+
export interface EnvVar {
|
|
18
|
+
key: string;
|
|
19
|
+
value: string;
|
|
20
|
+
}
|
|
21
|
+
export declare function parseEnvVar(spec: string): EnvVar;
|
|
22
|
+
export declare function parseEnvVars(specs: string[]): Record<string, string>;
|
|
23
|
+
//# sourceMappingURL=parse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/lib/parse.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAE5C,MAAM,MAAM,QAAQ,GAAG,GAAG,MAAM,KAAK,GAAG,GAAG,MAAM,KAAK,GAAG,GAAG,MAAM,IAAI,GAAG,GAAG,MAAM,IAAI,CAAC;AACvF,MAAM,MAAM,MAAM,GAAG,GAAG,MAAM,KAAK,GAAG,GAAG,MAAM,KAAK,GAAG,GAAG,MAAM,IAAI,GAAG,GAAG,MAAM,IAAI,CAAC;AACrF,MAAM,MAAM,OAAO,GAAG,GAAG,MAAM,GAAG,GAAG,GAAG,MAAM,GAAG,GAAG,SAAS,CAAC;AAE9D,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,QAAQ,CAKjD;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAK7C;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAM/C;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAK7C;AAED,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CASpD;AAED,MAAM,WAAW,MAAM;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAShD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOpE"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared parsing utilities
|
|
3
|
+
*/
|
|
4
|
+
export function parseCapacity(s) {
|
|
5
|
+
if (/^\d+(GiB|MiB|GB|MB)$/.test(s)) {
|
|
6
|
+
return s;
|
|
7
|
+
}
|
|
8
|
+
throw new Error(`Invalid capacity format: ${s}. Use formats like 2GiB, 10GB, 512MiB`);
|
|
9
|
+
}
|
|
10
|
+
export function parseMemory(s) {
|
|
11
|
+
if (/^\d+(GiB|MiB|GB|MB)$/.test(s)) {
|
|
12
|
+
return s;
|
|
13
|
+
}
|
|
14
|
+
throw new Error(`Invalid memory format: ${s}. Use formats like 1GiB, 2GiB, 4GiB (768MiB-4GiB)`);
|
|
15
|
+
}
|
|
16
|
+
export function parseTimeout(s) {
|
|
17
|
+
if (s === "session")
|
|
18
|
+
return "session";
|
|
19
|
+
if (/^\d+[ms]$/.test(s)) {
|
|
20
|
+
return s;
|
|
21
|
+
}
|
|
22
|
+
throw new Error(`Invalid timeout format: ${s}. Use formats like 10m, 600s, or session`);
|
|
23
|
+
}
|
|
24
|
+
export function parseRegion(s) {
|
|
25
|
+
if (s === "ord" || s === "ams") {
|
|
26
|
+
return s;
|
|
27
|
+
}
|
|
28
|
+
throw new Error(`Invalid region: ${s}. Use ord or ams`);
|
|
29
|
+
}
|
|
30
|
+
export function parseCopySpec(spec) {
|
|
31
|
+
const colonIndex = spec.indexOf(":");
|
|
32
|
+
if (colonIndex === -1) {
|
|
33
|
+
throw new Error(`Invalid copy spec "${spec}". Use format "src:dst"`);
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
src: spec.slice(0, colonIndex),
|
|
37
|
+
dst: spec.slice(colonIndex + 1),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
export function parseEnvVar(spec) {
|
|
41
|
+
const eqIndex = spec.indexOf("=");
|
|
42
|
+
if (eqIndex === -1) {
|
|
43
|
+
throw new Error(`Invalid env var "${spec}". Use format "KEY=VALUE"`);
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
key: spec.slice(0, eqIndex),
|
|
47
|
+
value: spec.slice(eqIndex + 1),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
export function parseEnvVars(specs) {
|
|
51
|
+
const env = {};
|
|
52
|
+
for (const spec of specs) {
|
|
53
|
+
const { key, value } = parseEnvVar(spec);
|
|
54
|
+
env[key] = value;
|
|
55
|
+
}
|
|
56
|
+
return env;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=parse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../../src/lib/parse.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,MAAM,UAAU,aAAa,CAAC,CAAS;IACrC,IAAI,sBAAsB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QACnC,OAAO,CAAa,CAAC;IACvB,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,uCAAuC,CAAC,CAAC;AACxF,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,CAAS;IACnC,IAAI,sBAAsB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QACnC,OAAO,CAAW,CAAC;IACrB,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,mDAAmD,CAAC,CAAC;AAClG,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,CAAS;IACpC,IAAI,CAAC,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACtC,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QACxB,OAAO,CAAY,CAAC;IACtB,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,0CAA0C,CAAC,CAAC;AAC1F,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,CAAS;IACnC,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,KAAK,EAAE,CAAC;QAC/B,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,kBAAkB,CAAC,CAAC;AAC1D,CAAC;AAOD,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACrC,IAAI,UAAU,KAAK,CAAC,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,yBAAyB,CAAC,CAAC;IACvE,CAAC;IACD,OAAO;QACL,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC;QAC9B,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC;KAChC,CAAC;AACJ,CAAC;AAOD,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,OAAO,KAAK,CAAC,CAAC,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,oBAAoB,IAAI,2BAA2B,CAAC,CAAC;IACvE,CAAC;IACD,OAAO;QACL,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC;QAC3B,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC;KAC/B,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAe;IAC1C,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QACzC,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACnB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.test.d.ts","sourceRoot":"","sources":["../../src/lib/parse.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { describe, it } from "node:test";
|
|
2
|
+
import assert from "node:assert";
|
|
3
|
+
import { parseCapacity, parseMemory, parseTimeout, parseRegion, parseCopySpec, parseEnvVar, parseEnvVars, } from "./parse.js";
|
|
4
|
+
describe("parseCapacity", () => {
|
|
5
|
+
it("parses valid GiB format", () => {
|
|
6
|
+
assert.strictEqual(parseCapacity("10GiB"), "10GiB");
|
|
7
|
+
assert.strictEqual(parseCapacity("2GiB"), "2GiB");
|
|
8
|
+
});
|
|
9
|
+
it("parses valid MiB format", () => {
|
|
10
|
+
assert.strictEqual(parseCapacity("512MiB"), "512MiB");
|
|
11
|
+
});
|
|
12
|
+
it("parses valid GB format", () => {
|
|
13
|
+
assert.strictEqual(parseCapacity("10GB"), "10GB");
|
|
14
|
+
});
|
|
15
|
+
it("parses valid MB format", () => {
|
|
16
|
+
assert.strictEqual(parseCapacity("500MB"), "500MB");
|
|
17
|
+
});
|
|
18
|
+
it("throws on invalid format", () => {
|
|
19
|
+
assert.throws(() => parseCapacity("10"), /Invalid capacity format/);
|
|
20
|
+
assert.throws(() => parseCapacity("10g"), /Invalid capacity format/);
|
|
21
|
+
assert.throws(() => parseCapacity("abc"), /Invalid capacity format/);
|
|
22
|
+
assert.throws(() => parseCapacity("10 GiB"), /Invalid capacity format/);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
describe("parseMemory", () => {
|
|
26
|
+
it("parses valid GiB format", () => {
|
|
27
|
+
assert.strictEqual(parseMemory("1GiB"), "1GiB");
|
|
28
|
+
assert.strictEqual(parseMemory("4GiB"), "4GiB");
|
|
29
|
+
});
|
|
30
|
+
it("parses valid MiB format", () => {
|
|
31
|
+
assert.strictEqual(parseMemory("1280MiB"), "1280MiB");
|
|
32
|
+
assert.strictEqual(parseMemory("768MiB"), "768MiB");
|
|
33
|
+
});
|
|
34
|
+
it("throws on invalid format", () => {
|
|
35
|
+
assert.throws(() => parseMemory("1"), /Invalid memory format/);
|
|
36
|
+
assert.throws(() => parseMemory("1g"), /Invalid memory format/);
|
|
37
|
+
assert.throws(() => parseMemory("lots"), /Invalid memory format/);
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
describe("parseTimeout", () => {
|
|
41
|
+
it("parses session timeout", () => {
|
|
42
|
+
assert.strictEqual(parseTimeout("session"), "session");
|
|
43
|
+
});
|
|
44
|
+
it("parses minutes format", () => {
|
|
45
|
+
assert.strictEqual(parseTimeout("10m"), "10m");
|
|
46
|
+
assert.strictEqual(parseTimeout("30m"), "30m");
|
|
47
|
+
});
|
|
48
|
+
it("parses seconds format", () => {
|
|
49
|
+
assert.strictEqual(parseTimeout("600s"), "600s");
|
|
50
|
+
assert.strictEqual(parseTimeout("30s"), "30s");
|
|
51
|
+
});
|
|
52
|
+
it("throws on invalid format", () => {
|
|
53
|
+
assert.throws(() => parseTimeout("10"), /Invalid timeout format/);
|
|
54
|
+
assert.throws(() => parseTimeout("10h"), /Invalid timeout format/);
|
|
55
|
+
assert.throws(() => parseTimeout("forever"), /Invalid timeout format/);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
describe("parseRegion", () => {
|
|
59
|
+
it("parses ord region", () => {
|
|
60
|
+
assert.strictEqual(parseRegion("ord"), "ord");
|
|
61
|
+
});
|
|
62
|
+
it("parses ams region", () => {
|
|
63
|
+
assert.strictEqual(parseRegion("ams"), "ams");
|
|
64
|
+
});
|
|
65
|
+
it("throws on invalid region", () => {
|
|
66
|
+
assert.throws(() => parseRegion("us-east"), /Invalid region/);
|
|
67
|
+
assert.throws(() => parseRegion(""), /Invalid region/);
|
|
68
|
+
assert.throws(() => parseRegion("ORD"), /Invalid region/);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
describe("parseCopySpec", () => {
|
|
72
|
+
it("parses simple file copy spec", () => {
|
|
73
|
+
const result = parseCopySpec("./local.txt:/remote.txt");
|
|
74
|
+
assert.deepStrictEqual(result, {
|
|
75
|
+
src: "./local.txt",
|
|
76
|
+
dst: "/remote.txt",
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
it("parses directory copy spec", () => {
|
|
80
|
+
const result = parseCopySpec("/tmp/mydir:/app");
|
|
81
|
+
assert.deepStrictEqual(result, {
|
|
82
|
+
src: "/tmp/mydir",
|
|
83
|
+
dst: "/app",
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
it("handles paths with multiple colons (Windows-style or URLs)", () => {
|
|
87
|
+
// Only first colon is the separator
|
|
88
|
+
const result = parseCopySpec("C:/Users/file.txt:/app/file.txt");
|
|
89
|
+
assert.deepStrictEqual(result, {
|
|
90
|
+
src: "C",
|
|
91
|
+
dst: "/Users/file.txt:/app/file.txt",
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
it("throws on missing colon", () => {
|
|
95
|
+
assert.throws(() => parseCopySpec("./local.txt"), /Invalid copy spec/);
|
|
96
|
+
assert.throws(() => parseCopySpec("nocolon"), /Invalid copy spec/);
|
|
97
|
+
});
|
|
98
|
+
it("handles empty src or dst", () => {
|
|
99
|
+
const result1 = parseCopySpec(":/dst");
|
|
100
|
+
assert.deepStrictEqual(result1, { src: "", dst: "/dst" });
|
|
101
|
+
const result2 = parseCopySpec("src:");
|
|
102
|
+
assert.deepStrictEqual(result2, { src: "src", dst: "" });
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
describe("parseEnvVar", () => {
|
|
106
|
+
it("parses simple env var", () => {
|
|
107
|
+
const result = parseEnvVar("FOO=bar");
|
|
108
|
+
assert.deepStrictEqual(result, { key: "FOO", value: "bar" });
|
|
109
|
+
});
|
|
110
|
+
it("parses env var with equals in value", () => {
|
|
111
|
+
const result = parseEnvVar("CONNECTION=host=localhost;port=5432");
|
|
112
|
+
assert.deepStrictEqual(result, {
|
|
113
|
+
key: "CONNECTION",
|
|
114
|
+
value: "host=localhost;port=5432",
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
it("parses empty value", () => {
|
|
118
|
+
const result = parseEnvVar("EMPTY=");
|
|
119
|
+
assert.deepStrictEqual(result, { key: "EMPTY", value: "" });
|
|
120
|
+
});
|
|
121
|
+
it("throws on missing equals", () => {
|
|
122
|
+
assert.throws(() => parseEnvVar("NOEQUALS"), /Invalid env var/);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
describe("parseEnvVars", () => {
|
|
126
|
+
it("parses multiple env vars", () => {
|
|
127
|
+
const result = parseEnvVars(["FOO=bar", "BAZ=qux"]);
|
|
128
|
+
assert.deepStrictEqual(result, { FOO: "bar", BAZ: "qux" });
|
|
129
|
+
});
|
|
130
|
+
it("returns empty object for empty array", () => {
|
|
131
|
+
const result = parseEnvVars([]);
|
|
132
|
+
assert.deepStrictEqual(result, {});
|
|
133
|
+
});
|
|
134
|
+
it("later values override earlier ones", () => {
|
|
135
|
+
const result = parseEnvVars(["FOO=first", "FOO=second"]);
|
|
136
|
+
assert.deepStrictEqual(result, { FOO: "second" });
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
//# sourceMappingURL=parse.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.test.js","sourceRoot":"","sources":["../../src/lib/parse.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utilities for reading from stdin
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Check if stdin is interactive (TTY) or piped
|
|
6
|
+
*/
|
|
7
|
+
export declare function isInteractive(): boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Read all content from stdin (for piped input / heredoc)
|
|
10
|
+
*/
|
|
11
|
+
export declare function readStdin(): Promise<string>;
|
|
12
|
+
/**
|
|
13
|
+
* Read script from file
|
|
14
|
+
*/
|
|
15
|
+
export declare function readScriptFile(path: string): Promise<string>;
|
|
16
|
+
/**
|
|
17
|
+
* Prompt user for confirmation
|
|
18
|
+
*/
|
|
19
|
+
export declare function confirm(message: string): Promise<boolean>;
|
|
20
|
+
/**
|
|
21
|
+
* Prompt user for choice after command failure
|
|
22
|
+
*/
|
|
23
|
+
export declare function promptOnFailure(): Promise<"save" | "discard" | "shell">;
|
|
24
|
+
//# sourceMappingURL=stdin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stdin.d.ts","sourceRoot":"","sources":["../../src/lib/stdin.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH;;GAEG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAED;;GAEG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAgBjD;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAElE;AAED;;GAEG;AACH,wBAAsB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAgB/D;AAED;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,CAuB7E"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utilities for reading from stdin
|
|
3
|
+
*/
|
|
4
|
+
import * as fs from "node:fs";
|
|
5
|
+
import * as readline from "node:readline";
|
|
6
|
+
/**
|
|
7
|
+
* Check if stdin is interactive (TTY) or piped
|
|
8
|
+
*/
|
|
9
|
+
export function isInteractive() {
|
|
10
|
+
return process.stdin.isTTY === true;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Read all content from stdin (for piped input / heredoc)
|
|
14
|
+
*/
|
|
15
|
+
export async function readStdin() {
|
|
16
|
+
return new Promise((resolve, reject) => {
|
|
17
|
+
let data = "";
|
|
18
|
+
process.stdin.setEncoding("utf8");
|
|
19
|
+
process.stdin.on("data", (chunk) => {
|
|
20
|
+
data += chunk;
|
|
21
|
+
});
|
|
22
|
+
process.stdin.on("end", () => {
|
|
23
|
+
resolve(data);
|
|
24
|
+
});
|
|
25
|
+
process.stdin.on("error", reject);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Read script from file
|
|
30
|
+
*/
|
|
31
|
+
export async function readScriptFile(path) {
|
|
32
|
+
return fs.promises.readFile(path, "utf8");
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Prompt user for confirmation
|
|
36
|
+
*/
|
|
37
|
+
export async function confirm(message) {
|
|
38
|
+
if (!isInteractive()) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
const rl = readline.createInterface({
|
|
42
|
+
input: process.stdin,
|
|
43
|
+
output: process.stdout,
|
|
44
|
+
});
|
|
45
|
+
return new Promise((resolve) => {
|
|
46
|
+
rl.question(`${message} [y/N] `, (answer) => {
|
|
47
|
+
rl.close();
|
|
48
|
+
resolve(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Prompt user for choice after command failure
|
|
54
|
+
*/
|
|
55
|
+
export async function promptOnFailure() {
|
|
56
|
+
if (!isInteractive()) {
|
|
57
|
+
return "discard";
|
|
58
|
+
}
|
|
59
|
+
const rl = readline.createInterface({
|
|
60
|
+
input: process.stdin,
|
|
61
|
+
output: process.stdout,
|
|
62
|
+
});
|
|
63
|
+
return new Promise((resolve) => {
|
|
64
|
+
rl.question("Command failed. [s]ave anyway, [d]iscard, [o]pen shell? ", (answer) => {
|
|
65
|
+
rl.close();
|
|
66
|
+
const a = answer.toLowerCase();
|
|
67
|
+
if (a === "s" || a === "save") {
|
|
68
|
+
resolve("save");
|
|
69
|
+
}
|
|
70
|
+
else if (a === "o" || a === "shell") {
|
|
71
|
+
resolve("shell");
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
resolve("discard");
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=stdin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stdin.js","sourceRoot":"","sources":["../../src/lib/stdin.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "sandsnap",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "CLI for managing Deno Sandbox environments with snapshot-based workflows",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"sandsnap": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"README.md",
|
|
12
|
+
"LICENSE"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc",
|
|
16
|
+
"dev": "tsx src/index.ts",
|
|
17
|
+
"prepublishOnly": "npm run build",
|
|
18
|
+
"test": "npm run build && node --test dist/lib/*.test.js",
|
|
19
|
+
"test:unit": "npm run build && node --test dist/lib/*.test.js",
|
|
20
|
+
"test:integration": "npm run build && node --test test/integration/*.test.ts",
|
|
21
|
+
"test:all": "npm run test:unit && npm run test:integration"
|
|
22
|
+
},
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+https://github.com/LiboShen/sandsnap.git"
|
|
26
|
+
},
|
|
27
|
+
"homepage": "https://github.com/LiboShen/sandsnap#readme",
|
|
28
|
+
"bugs": {
|
|
29
|
+
"url": "https://github.com/LiboShen/sandsnap/issues"
|
|
30
|
+
},
|
|
31
|
+
"author": "Libo Shen",
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=24.0.0"
|
|
34
|
+
},
|
|
35
|
+
"keywords": [
|
|
36
|
+
"deno",
|
|
37
|
+
"sandbox",
|
|
38
|
+
"cli",
|
|
39
|
+
"container",
|
|
40
|
+
"isolation",
|
|
41
|
+
"snapshot",
|
|
42
|
+
"microvm",
|
|
43
|
+
"linux"
|
|
44
|
+
],
|
|
45
|
+
"license": "MIT",
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"@deno/sandbox": "^0.13.2",
|
|
48
|
+
"commander": "^13.1.0"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@types/node": "^22.15.2",
|
|
52
|
+
"tsx": "^4.19.4",
|
|
53
|
+
"typescript": "^5.8.3"
|
|
54
|
+
}
|
|
55
|
+
}
|