import ora from 'ora' import { getCliClient } from '../cli-client.js' import { assetSearchResultLine, searchSummary } from '../output.js' import type { AssetType } from '../schemas.js' const SEARCH_LIMIT = 5 export interface SearchCommandOptions { type: AssetType unapproved?: boolean baseUrl?: string limit?: number /** Emit a machine-readable JSON array instead of the human-readable lines. */ json?: boolean } export async function searchCommand(query: string, opts: SearchCommandOptions): Promise { const { client } = await getCliClient({ baseUrl: opts.baseUrl }) const spinner = ora({ text: `Searching "${query}"`, isEnabled: Boolean(process.stderr.isTTY) && !opts.json, isSilent: !process.stderr.isTTY || Boolean(opts.json), }).start() const results = await client.asset .search({ query, type: opts.type, includeUnapproved: opts.unapproved ?? false, limit: opts.limit ?? SEARCH_LIMIT, page: 1, }) .finally(() => spinner.stop()) // The collection read is a union (search | refs); this call always searches. if (!('items' in results)) throw new Error('Search unexpectedly returned a refs result.') if (opts.json) { // Stable machine-readable shape for scripts; the human-readable lines below may change freely. console.log( JSON.stringify( results.items.map((item) => ({ name: item.name, version: item.latestVersion, type: item.type, approved: item.approved, access: item.access, description: item.description, })), ), ) return } console.log( searchSummary({ query, type: opts.type, includeUnapproved: opts.unapproved ?? false, count: results.items.length, total: results.total, }), ) if (results.items.length === 0) { return } for (const item of results.items) { console.log(assetSearchResultLine(item)) } }