import { parseProjectRepoUrl } from "../shared/project-fields.ts"; import { isProjectType, type ProjectType } from "../shared/project-type.ts"; export type ProjectFieldCommand = | { kind: "name"; projectId: string; name: string } | { kind: "type"; projectId: string; type: ProjectType } | { kind: "repoAdd"; projectId: string; url: string } | { kind: "repoRemove"; projectId: string; url: string; yes: boolean } | { kind: "memberAdd"; projectId: string; memberId: string } | { kind: "memberRemove"; projectId: string; memberId: string; yes: boolean }; export const PROJECT_NAME_USAGE = "Usage: raidiant-hub project name "; export const PROJECT_TYPE_USAGE = "Usage: raidiant-hub project type "; export const PROJECT_REPO_USAGE = "Usage: raidiant-hub project repo add | project repo remove [--yes]"; export const PROJECT_MEMBER_USAGE = "Usage: raidiant-hub project member add | project member remove [--yes]"; /** Parse `project name|type|repo|member …` from CLI positional args. */ export const parseProjectFieldArgs = ( positional: ReadonlyArray, ): ProjectFieldCommand | { error: string } | undefined => { if (positional[0] !== "project") return undefined; const subcommand = positional[1]; if ( subcommand !== "name" && subcommand !== "type" && subcommand !== "repo" && subcommand !== "member" ) { return undefined; } const flags = positional.filter((value) => value.startsWith("--")); const unknown = flags.find((value) => value !== "--yes"); if (unknown) return { error: `Unknown project ${subcommand} option: ${unknown}` }; const yes = flags.includes("--yes"); const values = positional.filter((value) => !value.startsWith("--")); const projectId = values[2]; if (subcommand === "name") { const name = values.slice(3).join(" ").trim(); if (!projectId || !name) return { error: PROJECT_NAME_USAGE }; return { kind: "name", projectId, name }; } if (subcommand === "type") { if (!projectId || !values[3]) return { error: PROJECT_TYPE_USAGE }; if (!isProjectType(values[3])) return { error: "Project type must be product or tool." }; return { kind: "type", projectId, type: values[3] }; } if (subcommand === "repo") { const action = values[2]; const repoProjectId = values[3]; const url = values[4]; if ((action !== "add" && action !== "remove") || !repoProjectId || !url) { return { error: PROJECT_REPO_USAGE }; } const parsed = parseProjectRepoUrl(url); if ("error" in parsed) return { error: parsed.error }; return action === "add" ? { kind: "repoAdd", projectId: repoProjectId, url: parsed.url } : { kind: "repoRemove", projectId: repoProjectId, url: parsed.url, yes }; } const action = values[2]; const memberProjectId = values[3]; const memberId = values[4]; if ((action !== "add" && action !== "remove") || !memberProjectId || !memberId) { return { error: PROJECT_MEMBER_USAGE }; } return action === "add" ? { kind: "memberAdd", projectId: memberProjectId, memberId } : { kind: "memberRemove", projectId: memberProjectId, memberId, yes }; };