@pocketenv/cli 0.3.1 → 0.3.3
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/index.js +33 -2
- package/package.json +1 -1
- package/src/cmd/create.ts +4 -0
- package/src/cmd/start.ts +7 -1
- package/src/lib/expandRepo.ts +9 -0
- package/src/lib/waitUntilRunning.ts +27 -0
package/dist/index.js
CHANGED
|
@@ -22,7 +22,7 @@ import relativeTime from 'dayjs/plugin/relativeTime.js';
|
|
|
22
22
|
import { password, editor, input } from '@inquirer/prompts';
|
|
23
23
|
import sodium from 'libsodium-wrappers';
|
|
24
24
|
|
|
25
|
-
var version = "0.3.
|
|
25
|
+
var version = "0.3.3";
|
|
26
26
|
|
|
27
27
|
async function getAccessToken() {
|
|
28
28
|
const tokenPath = path.join(os.homedir(), ".pocketenv", "token.json");
|
|
@@ -410,9 +410,37 @@ async function ssh(sandboxName) {
|
|
|
410
410
|
}
|
|
411
411
|
}
|
|
412
412
|
|
|
413
|
+
function expandRepo(repo) {
|
|
414
|
+
const githubMatch = repo.match(/^github:([^/]+\/[^/]+)$/);
|
|
415
|
+
if (githubMatch) return `https://github.com/${githubMatch[1]}`;
|
|
416
|
+
const tangledMatch = repo.match(/^tangled:([^/]+\/[^/]+)$/);
|
|
417
|
+
if (tangledMatch) return `https://tangled.org/${tangledMatch[1]}`;
|
|
418
|
+
return repo;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
async function waitUntilRunning(name, authToken, timeoutMs = 6e4, intervalMs = 2e3) {
|
|
422
|
+
const deadline = Date.now() + timeoutMs;
|
|
423
|
+
while (Date.now() < deadline) {
|
|
424
|
+
const response = await client.get(
|
|
425
|
+
"/xrpc/io.pocketenv.sandbox.getSandbox",
|
|
426
|
+
{
|
|
427
|
+
params: { id: name },
|
|
428
|
+
headers: { Authorization: `Bearer ${authToken}` }
|
|
429
|
+
}
|
|
430
|
+
);
|
|
431
|
+
if (response.data.sandbox?.status === "RUNNING") return;
|
|
432
|
+
await new Promise((resolve) => setTimeout(resolve, intervalMs));
|
|
433
|
+
}
|
|
434
|
+
throw new Error(
|
|
435
|
+
`Sandbox ${name} did not reach RUNNING state within ${timeoutMs / 1e3}s`
|
|
436
|
+
);
|
|
437
|
+
}
|
|
438
|
+
|
|
413
439
|
async function start(name, { ssh: ssh$1, repo }) {
|
|
414
440
|
const token = await getAccessToken();
|
|
441
|
+
if (repo) repo = expandRepo(repo);
|
|
415
442
|
try {
|
|
443
|
+
const authToken = env$1.POCKETENV_TOKEN || token;
|
|
416
444
|
await client.post(
|
|
417
445
|
"/xrpc/io.pocketenv.sandbox.startSandbox",
|
|
418
446
|
{
|
|
@@ -423,11 +451,12 @@ async function start(name, { ssh: ssh$1, repo }) {
|
|
|
423
451
|
id: name
|
|
424
452
|
},
|
|
425
453
|
headers: {
|
|
426
|
-
Authorization: `Bearer ${
|
|
454
|
+
Authorization: `Bearer ${authToken}`
|
|
427
455
|
}
|
|
428
456
|
}
|
|
429
457
|
);
|
|
430
458
|
if (ssh$1) {
|
|
459
|
+
await waitUntilRunning(name, authToken);
|
|
431
460
|
await ssh(name);
|
|
432
461
|
return;
|
|
433
462
|
}
|
|
@@ -582,6 +611,7 @@ async function createSandbox(name, {
|
|
|
582
611
|
repo
|
|
583
612
|
}) {
|
|
584
613
|
const token = await getAccessToken();
|
|
614
|
+
if (repo) repo = expandRepo(repo);
|
|
585
615
|
if (["deno", "vercel", "daytona"].includes(provider || "")) {
|
|
586
616
|
consola.error(
|
|
587
617
|
`This Sandbox Runtime is temporarily disabled. ${c.primary(provider ?? "")}`
|
|
@@ -609,6 +639,7 @@ async function createSandbox(name, {
|
|
|
609
639
|
);
|
|
610
640
|
return;
|
|
611
641
|
}
|
|
642
|
+
await waitUntilRunning(sandbox.data.name, token);
|
|
612
643
|
await ssh(sandbox.data.name);
|
|
613
644
|
} catch (error) {
|
|
614
645
|
consola.error(`Failed to create sandbox: ${error}`);
|
package/package.json
CHANGED
package/src/cmd/create.ts
CHANGED
|
@@ -4,6 +4,8 @@ import getAccessToken from "../lib/getAccessToken";
|
|
|
4
4
|
import type { Sandbox } from "../types/sandbox";
|
|
5
5
|
import connectToSandbox from "./ssh";
|
|
6
6
|
import { c } from "../theme";
|
|
7
|
+
import { expandRepo } from "../lib/expandRepo";
|
|
8
|
+
import waitUntilRunning from "../lib/waitUntilRunning";
|
|
7
9
|
|
|
8
10
|
async function createSandbox(
|
|
9
11
|
name: string,
|
|
@@ -20,6 +22,7 @@ async function createSandbox(
|
|
|
20
22
|
},
|
|
21
23
|
) {
|
|
22
24
|
const token = await getAccessToken();
|
|
25
|
+
if (repo) repo = expandRepo(repo);
|
|
23
26
|
|
|
24
27
|
if (["deno", "vercel", "daytona"].includes(provider || "")) {
|
|
25
28
|
consola.error(
|
|
@@ -50,6 +53,7 @@ async function createSandbox(
|
|
|
50
53
|
);
|
|
51
54
|
return;
|
|
52
55
|
}
|
|
56
|
+
await waitUntilRunning(sandbox.data.name, token);
|
|
53
57
|
await connectToSandbox(sandbox.data.name);
|
|
54
58
|
} catch (error) {
|
|
55
59
|
consola.error(`Failed to create sandbox: ${error}`);
|
package/src/cmd/start.ts
CHANGED
|
@@ -4,14 +4,19 @@ import getAccessToken from "../lib/getAccessToken";
|
|
|
4
4
|
import { client } from "../client";
|
|
5
5
|
import { env } from "../lib/env";
|
|
6
6
|
import connectToSandbox from "./ssh";
|
|
7
|
+
import { expandRepo } from "../lib/expandRepo";
|
|
8
|
+
import waitUntilRunning from "../lib/waitUntilRunning";
|
|
7
9
|
|
|
8
10
|
async function start(
|
|
9
11
|
name: string,
|
|
10
12
|
{ ssh, repo }: { ssh?: boolean; repo?: string },
|
|
11
13
|
) {
|
|
12
14
|
const token = await getAccessToken();
|
|
15
|
+
if (repo) repo = expandRepo(repo);
|
|
13
16
|
|
|
14
17
|
try {
|
|
18
|
+
const authToken = env.POCKETENV_TOKEN || token;
|
|
19
|
+
|
|
15
20
|
await client.post(
|
|
16
21
|
"/xrpc/io.pocketenv.sandbox.startSandbox",
|
|
17
22
|
{
|
|
@@ -22,12 +27,13 @@ async function start(
|
|
|
22
27
|
id: name,
|
|
23
28
|
},
|
|
24
29
|
headers: {
|
|
25
|
-
Authorization: `Bearer ${
|
|
30
|
+
Authorization: `Bearer ${authToken}`,
|
|
26
31
|
},
|
|
27
32
|
},
|
|
28
33
|
);
|
|
29
34
|
|
|
30
35
|
if (ssh) {
|
|
36
|
+
await waitUntilRunning(name, authToken);
|
|
31
37
|
await connectToSandbox(name);
|
|
32
38
|
return;
|
|
33
39
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export function expandRepo(repo: string): string {
|
|
2
|
+
const githubMatch = repo.match(/^github:([^/]+\/[^/]+)$/);
|
|
3
|
+
if (githubMatch) return `https://github.com/${githubMatch[1]}`;
|
|
4
|
+
|
|
5
|
+
const tangledMatch = repo.match(/^tangled:([^/]+\/[^/]+)$/);
|
|
6
|
+
if (tangledMatch) return `https://tangled.org/${tangledMatch[1]}`;
|
|
7
|
+
|
|
8
|
+
return repo;
|
|
9
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { client } from "../client";
|
|
2
|
+
import type { Sandbox } from "../types/sandbox";
|
|
3
|
+
|
|
4
|
+
async function waitUntilRunning(
|
|
5
|
+
name: string,
|
|
6
|
+
authToken: string,
|
|
7
|
+
timeoutMs = 60_000,
|
|
8
|
+
intervalMs = 2_000,
|
|
9
|
+
): Promise<void> {
|
|
10
|
+
const deadline = Date.now() + timeoutMs;
|
|
11
|
+
while (Date.now() < deadline) {
|
|
12
|
+
const response = await client.get<{ sandbox: Sandbox | null }>(
|
|
13
|
+
"/xrpc/io.pocketenv.sandbox.getSandbox",
|
|
14
|
+
{
|
|
15
|
+
params: { id: name },
|
|
16
|
+
headers: { Authorization: `Bearer ${authToken}` },
|
|
17
|
+
},
|
|
18
|
+
);
|
|
19
|
+
if (response.data.sandbox?.status === "RUNNING") return;
|
|
20
|
+
await new Promise((resolve) => setTimeout(resolve, intervalMs));
|
|
21
|
+
}
|
|
22
|
+
throw new Error(
|
|
23
|
+
`Sandbox ${name} did not reach RUNNING state within ${timeoutMs / 1000}s`,
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export default waitUntilRunning;
|