@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 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.1";
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 ${env$1.POCKETENV_TOKEN || token}`
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
@@ -4,7 +4,7 @@
4
4
  "bin": {
5
5
  "pocketenv": "dist/index.js"
6
6
  },
7
- "version": "0.3.1",
7
+ "version": "0.3.3",
8
8
  "type": "module",
9
9
  "keywords": [
10
10
  "sandbox",
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 ${env.POCKETENV_TOKEN || token}`,
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;