Select the types of activity you want to include in your feed.
Add backup commands to CLI
Implement create, list and restore backup functions using @pocketenv/sdk. Validate TTL with zod and format output with cli-table3/dayjs. Bump @pocketenv/sdk to v0.2.10 and set the default backup TTL to 3d
···11-export function createBackup() {
11+import { Sandbox } from '@pocketenv/sdk';
22+import consola from 'consola';
33+import z from 'zod';
44+import { c } from '../theme';
55+import process from "node:process";
66+import Table from "cli-table3";
77+import dayjs from "dayjs";
88+import relativeTime from "dayjs/plugin/relativeTime";
99+1010+dayjs.extend(relativeTime);
1111+1212+const ttlSchema = z
1313+ .string()
1414+ .regex(/^\d+(m|h|d)$/, 'Invalid TTL format (e.g. 10m, 2h, 7d)')
1515+ .transform((value) => {
1616+ const amount = parseInt(value.slice(0, -1), 10);
1717+ const unit = value.slice(-1);
1818+1919+ switch (unit) {
2020+ case 'm':
2121+ return amount * 60;
2222+ case 'h':
2323+ return amount * 60 * 60;
2424+ case 'd':
2525+ return amount * 60 * 60 * 24;
2626+ default:
2727+ throw new Error('Invalid TTL unit');
2828+ }
2929+ });
3030+3131+const backupOptionsSchema = z.object({
3232+ description: z.string().optional(),
3333+ ttl: ttlSchema.optional(),
3434+});
3535+3636+export type BackupOptions = z.infer<typeof backupOptionsSchema>;
3737+3838+export async function createBackup(sandboxId: string, directory: string, options: BackupOptions) {
3939+ try {
4040+ const { data, error } = backupOptionsSchema.safeParse(options);
4141+ if (error) {
4242+ consola.error(`Invalid backup options: ${error.issues[0]?.message}`);
4343+ process.exit(1);
4444+ }
4545+4646+ const sandbox = await Sandbox.get(sandboxId);
4747+ const { description, ttl } = data;
2484949+ await sandbox.backup.create(
5050+ directory,
5151+ description,
5252+ ttl,
5353+ );
5454+ consola.success(`Backup request for sandbox ${c.primary(sandboxId)} at directory ${c.primary(directory)} created successfully`);
5555+ consola.log(` This may take a few moments to complete.\n Run ${c.primary(`pocketenv backup ls ${sandboxId}`)} to check the status of your backup.`);
5656+ } catch (e) {
5757+ consola.error(`Failed to create backup for sandbox`, e);
5858+ process.exit(1);
5959+ }
360}
46155-export function restoreBackup() {
6262+export async function restoreBackup(backupId: string) {
6363+ try {
6464+ await Sandbox.restoreBackup(backupId);
6565+ consola.success(`Backup ${c.primary(backupId)} restored successfully`);
6666+ } catch {
6767+ consola.error(`Failed to restore backup ${c.primary(backupId)}`);
6868+ process.exit(1);
6969+ }
670}
77188-export function listBackups() {
7272+export async function listBackups(sandboxId: string) {
7373+ const sandbox = await Sandbox.get(sandboxId);
7474+ try {
7575+ const { backups } = await sandbox.backup.list();
7676+7777+ const table = new Table({
7878+ head: [
7979+ c.primary("BACKUP ID"),
8080+ c.primary("DIRECTORY"),
8181+ c.primary("CREATED AT"),
8282+ c.primary("EXPIRES AT"),
8383+ ],
8484+ chars: {
8585+ top: "",
8686+ "top-mid": "",
8787+ "top-left": "",
8888+ "top-right": "",
8989+ bottom: "",
9090+ "bottom-mid": "",
9191+ "bottom-left": "",
9292+ "bottom-right": "",
9393+ left: "",
9494+ "left-mid": "",
9595+ mid: "",
9696+ "mid-mid": "",
9797+ right: "",
9898+ "right-mid": "",
9999+ middle: " ",
100100+ },
101101+ style: {
102102+ border: [],
103103+ head: [],
104104+ },
105105+ });
106106+107107+ for (const backup of backups) {
108108+ table.push([
109109+ c.secondary(backup.id),
110110+ backup.directory,
111111+ dayjs(backup.createdAt).fromNow(),
112112+ backup.expiresAt ? dayjs(backup.expiresAt).fromNow() : "Never",
113113+ ]);
114114+ }
115115+116116+ consola.log(table.toString());
117117+ } catch {
118118+ consola.error(`Failed to list backups for sandbox ${c.primary(sandboxId)}`);
119119+ process.exit(1);
120120+ }
9121}
+1-1
apps/cli/src/index.ts
···206206 .argument("<sandbox>", "the sandbox to create a backup for")
207207 .argument("<directory>", "the directory to backup")
208208 .option("--description, -d <description>", "an optional description for the backup")
209209- .option("--ttl, -t <ttl>", "time to live for the backup (e.g., 24h, 7d)", "7d")
209209+ .option("--ttl, -t <ttl>", "time to live for the backup (e.g., 24h, 7d)", "3d")
210210 .description("create a backup for the given sandbox")
211211 .action(createBackup);
212212