import { log } from "@clack/prompts" import { defineCommand } from "../lib/command" import { globalOptions, globalOptionsSchema } from "../lib/global-options" import z from "zod" import { apiClient } from "../lib/api-client" import { ORG_OPT, orgOptsSchema, output, PAGINATION_OPTS, paginationOptsSchema, pluralize, sessionIntro, requireSession, useOrganization, ORG_OPTION_DESCRIPTIONS, PAGINATION_OPTION_DESCRIPTIONS, } from "../utils" import { renderDetailBlock } from "../lib/detail-block" import { accent, dimmed } from "../lib/io" import { clearSpinner, startSpinner } from "../lib/spinner" export const projectListCommand = defineCommand({ name: "list", description: "List projects for an organization", options: { ...globalOptions, ...ORG_OPT, ...PAGINATION_OPTS, }, optionDescriptions: { ...ORG_OPTION_DESCRIPTIONS, ...PAGINATION_OPTION_DESCRIPTIONS, }, schema: globalOptionsSchema.extend({ ...orgOptsSchema.shape, ...paginationOptsSchema.shape, }), run: listProjects, }) /** * Lists projects for the resolved organization. * * @param opts - Validated options containing an optional organization filter. * @throws When the organization cannot be resolved. */ export async function listProjects( opts: z.infer & z.infer, ) { const session = await requireSession() output.normal(() => sessionIntro(session)) const organization = await useOrganization(opts) startSpinner("Fetching projects") const page = await apiClient.project.list({ cursor: opts.cursor, limit: opts.limit, organizationId: organization.id, }) clearSpinner() output .normal(() => { const allProjects = page.items if (allProjects.length === 0) { log.warn( `No projects. Create one with ${accent("automate project create")}`, ) return } log.message( `${accent(String(allProjects.length))} ${pluralize(allProjects.length, "project")}`, ) for (const project of allProjects) { log.info( renderDetailBlock( { [dimmed`Name`]: project.name, [dimmed`ID`]: dimmed(project.id), [dimmed`Organization`]: `${project.org.name} ${dimmed(project.org.id)}`, [dimmed`Created`]: new Date( project.createdAt, ).toLocaleDateString(), [dimmed`Automations`]: project.activeAutomations.length, }, { keyAlignment: "right" }, ), ) } if (page.pageInfo.nextCursor) { log.info(`More results: --cursor ${page.pageInfo.nextCursor}`) } log.message() }) .json(page) }