A Docker-like CLI and HTTP API for managing headless VMs
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 94 lines 2.4 kB view raw
1import { Table } from "@cliffy/table"; 2import dayjs from "dayjs"; 3import relativeTime from "dayjs/plugin/relativeTime.js"; 4import utc from "dayjs/plugin/utc.js"; 5import { Effect, pipe } from "effect"; 6import type { Volume } from "../db.ts"; 7import type { DbError } from "../errors.ts"; 8import { deleteVolume, getVolume, listVolumes } from "../volumes.ts"; 9 10dayjs.extend(relativeTime); 11dayjs.extend(utc); 12 13const createTable = () => 14 Effect.succeed(new Table(["NAME", "VOLUME ID", "CREATED"])); 15 16const populateTable = (table: Table, volumes: Volume[]) => 17 Effect.sync(() => { 18 for (const volume of volumes) { 19 table.push([ 20 volume.name, 21 volume.id, 22 dayjs.utc(volume.createdAt).local().fromNow(), 23 ]); 24 } 25 return table; 26 }); 27 28const displayTable = (table: Table) => 29 Effect.sync(() => { 30 console.log(table.padding(2).toString()); 31 }); 32 33const handleError = (error: DbError | Error) => 34 Effect.sync(() => { 35 console.error(`Failed to fetch volumes: ${error}`); 36 Deno.exit(1); 37 }); 38 39const lsEffect = () => 40 pipe( 41 Effect.all([listVolumes(), createTable()]), 42 Effect.flatMap(([volumes, table]) => populateTable(table, volumes)), 43 Effect.flatMap(displayTable), 44 Effect.catchAll(handleError), 45 ); 46 47export async function list() { 48 await Effect.runPromise(lsEffect()); 49} 50 51export async function remove(name: string) { 52 await Effect.runPromise( 53 pipe( 54 getVolume(name), 55 Effect.flatMap((volume) => 56 volume 57 ? deleteVolume(volume.id) 58 : Effect.fail(new Error(`Volume with name or ID ${name} not found.`)) 59 ), 60 Effect.tap(() => 61 Effect.sync(() => { 62 console.log(`Volume ${name} deleted successfully.`); 63 }) 64 ), 65 Effect.catchAll((error) => 66 Effect.sync(() => { 67 console.error(`An error occurred: ${error}`); 68 Deno.exit(1); 69 }) 70 ), 71 ), 72 ); 73} 74 75export async function inspect(name: string) { 76 await Effect.runPromise( 77 pipe( 78 getVolume(name), 79 Effect.flatMap((volume) => 80 volume 81 ? Effect.sync(() => { 82 console.log(volume); 83 }) 84 : Effect.fail(new Error(`Volume with name or ID ${name} not found.`)) 85 ), 86 Effect.catchAll((error) => 87 Effect.sync(() => { 88 console.error(`An error occurred: ${error}`); 89 Deno.exit(1); 90 }) 91 ), 92 ), 93 ); 94}