// server/cli/createApiClient.ts import { pathToFileURL } from "node:url"; import type { ApiClientScope } from "@shared/types.js"; import { runMigrations } from "../db/migrate.js"; import { createApiClient } from "../services/apiClients.js"; export interface CreateApiClientCliOptions { name: string; scopes: ApiClientScope[]; } const ALLOWED_SCOPES: ApiClientScope[] = ["read", "operate", "admin", "debug"]; export function parseCreateApiClientArgs(args: string[]): CreateApiClientCliOptions { let name = ""; let scopes: ApiClientScope[] = ["read"]; for (let i = 0; i < args.length; i += 1) { const arg = args[i]; if (arg === "--name") { i += 1; name = args[i] ?? ""; } else if (arg === "--scopes") { i += 1; scopes = parseScopes(args[i] ?? ""); } else if (arg === "--help" || arg === "-h") { throw new Error(helpText()); } else { throw new Error(`Argument inconnu: ${arg}\n\n${helpText()}`); } } if (!name.trim()) throw new Error(`--name est obligatoire\n\n${helpText()}`); return { name: name.trim(), scopes }; } function parseScopes(raw: string): ApiClientScope[] { const scopes = raw .split(",") .map((scope) => scope.trim()) .filter(Boolean) as ApiClientScope[]; if (scopes.length === 0) return ["read"]; for (const scope of scopes) { if (!ALLOWED_SCOPES.includes(scope)) { throw new Error(`Scope invalide: ${scope}. Scopes valides: ${ALLOWED_SCOPES.join(", ")}`); } } return [...new Set(scopes)]; } function helpText(): string { return [ "Usage:", " pnpm api-client:create -- --name \"App Rust\" --scopes read,operate", "", "Variables requises:", " SU_MASTER_KEY clé hex 64 caractères", " SU_DB_PATH chemin SQLite optionnel", ].join("\n"); } async function main(): Promise { const options = parseCreateApiClientArgs(process.argv.slice(2)); runMigrations(); const created = createApiClient(options); console.log(JSON.stringify(created, null, 2)); } const entrypoint = process.argv[1] ? pathToFileURL(process.argv[1]).href : ""; if (import.meta.url === entrypoint) { main().catch((err) => { console.error((err as Error).message); process.exitCode = 1; }); } export const createApiClientCliInternals = { parseScopes, helpText };