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 { accent, dimmed } from "../lib/io" import { clearSpinner, startSpinner } from "../lib/spinner" import { ORG_OPT, orgOptsSchema, output, promptableOption, REASONABLE_NAME_SCHEMA, requireSession, safelyPromptTextWithValidation, sessionIntro, useOrganization, ORG_OPTION_DESCRIPTIONS, } from "../utils" /** Validates options before an API key secret can be issued. */ const createApiKeyOptsSchema = orgOptsSchema.extend({ name: promptableOption(REASONABLE_NAME_SCHEMA, "--name"), }) export const orgApiKeyCreateCommand = defineCommand({ name: "create", description: "Create an organization API key", options: { ...globalOptions, ...ORG_OPT, name: { type: "string", short: "n", }, }, optionDescriptions: { ...ORG_OPTION_DESCRIPTIONS, name: "Name for the API key", }, schema: globalOptionsSchema.extend(createApiKeyOptsSchema.shape), run: createOrganizationApiKey, }) /** * Creates an organization API key and prints its one-time secret. * * @param opts - Organization selector and API key name. */ export async function createOrganizationApiKey( opts: z.infer, ) { const session = await requireSession("create an organization API key") output.normal(() => sessionIntro(session)) const organization = await useOrganization(opts) const name = opts.name ?? (await safelyPromptTextWithValidation( { message: "What should we name the API key?" }, REASONABLE_NAME_SCHEMA, "--name", )) startSpinner("Creating API key") const apiKey = await apiClient.apiKey.create({ name, organizationId: organization.id, }) clearSpinner() output .normal(() => { log.success(`Created ${accent(name)} ${dimmed(apiKey.id)}`) log.warn("Copy this API key now. It will not be shown again.") log.message(accent(apiKey.key)) }) .json(apiKey) }