/**
 * Shared CLI Helpers
 *
 * Common utilities and types shared across CLI commands.
 * Reduces duplication and ensures consistent behavior.
 */
import { Command } from 'commander';
import type { ManagementClient } from '../client/management/types';
import { type OutputContext } from './output';
import { type CliErrorContext } from './errors';
/**
 * Environment target for CLI operations.
 */
export type EnvTarget = 'local' | 'remote';
/**
 * Result of an operation on a specific environment.
 */
export interface EnvResult<T> {
    success: boolean;
    result?: T;
    error?: Error;
}
/**
 * Global options available on all commands via --json, --quiet, --env flags.
 */
export interface GlobalOptions {
    json?: boolean;
    quiet?: boolean;
    /** @deprecated Use --env=remote instead */
    remote?: boolean;
    /** Target environment: local, remote, or both */
    env?: string;
}
/**
 * Options for commands that accept JSON data via --data or --file.
 */
export interface DataInputOptions {
    data?: string;
    file?: string;
}
/**
 * Options for commands that require confirmation.
 */
export interface ConfirmOptions {
    yes?: boolean;
}
/**
 * Context object provided to command handlers.
 */
export interface CommandContext {
    output: OutputContext;
    client: ManagementClient;
    isRemote: boolean;
    isJsonOutput: boolean;
    /** Environment targets for this operation */
    envTargets: EnvTarget[];
}
/**
 * Pagination options for list commands.
 */
export interface PaginationOptions {
    limit?: string;
    page?: string;
}
/**
 * Parsed pagination values.
 */
export interface ParsedPagination {
    limit: number;
    page: number;
}
/**
 * Type for row formatter functions used in table display.
 * Each formatter takes an entity and returns an array of string values.
 *
 * @example
 * const formatEntryRow: RowFormatter<ManagementEntry> = (entry) => [
 *   entry.identifier,
 *   entry.status,
 *   formatDateShort(entry.updatedAt),
 * ];
 */
export type RowFormatter<T> = (item: T) => string[];
/**
 * Entry format for SDK pull operations.
 * Matches the server-side PulledEntry type.
 */
export interface PulledEntryOutput {
    identifier: string;
    data: Record<string, unknown>;
    status: 'draft' | 'published';
    hasUnpublishedChanges: boolean;
    /** Slug for URL routing - only present for routable content types */
    slug?: string;
    /** Resolved title (routable title when present, otherwise content title) */
    title: string;
}
/**
 * Map an entry from API response to pull output format.
 * Conditionally includes slug only for routable content (when slug is defined).
 */
export declare function mapEntryForOutput<T extends {
    identifier: string;
    data: Record<string, unknown>;
    status: 'draft' | 'published';
    hasUnpublishedChanges: boolean;
    slug?: string;
    title: string;
}>(entry: T): PulledEntryOutput;
/**
 * Parse pagination options from command flags.
 *
 * @param options - Object containing optional limit and page strings
 * @returns Parsed pagination values with defaults
 *
 * @example
 * const { limit, page } = parsePaginationOptions({ limit: '10', page: '2' });
 */
export declare function parsePaginationOptions(options: PaginationOptions): ParsedPagination;
/**
 * Format an ISO date string to a short date (YYYY-MM-DD).
 *
 * @param isoDate - ISO date string (e.g., "2024-01-15T10:30:00Z")
 * @returns Short date string (e.g., "2024-01-15")
 *
 * @example
 * formatDateShort("2024-01-15T10:30:00Z") // "2024-01-15"
 */
export declare function formatDateShort(isoDate: string): string;
/**
 * Parse JSON data from --data flag or --file flag.
 *
 * @param options - Object containing optional data string or file path
 * @returns Parsed JSON object
 * @throws Error if neither data nor file is provided
 * @throws SyntaxError if JSON is invalid
 *
 * @example
 * const data = await parseJsonData({ data: '{"title": "Hello"}' });
 * const data = await parseJsonData({ file: './content.json' });
 */
export declare function parseJsonData(options: DataInputOptions): Promise<Record<string, unknown>>;
/**
 * Parse JSON array from --data flag or --file flag.
 * Handles both direct array format and { items: [...] } wrapper format.
 *
 * @param options - Object containing optional data string or file path
 * @returns Parsed JSON array
 *
 * @example
 * const items = await parseJsonArray({ file: './items.json' });
 */
export declare function parseJsonArray<T>(options: DataInputOptions): Promise<T[]>;
/**
 * Prompt for confirmation unless --yes is provided.
 * Remote operations always require --yes for safety.
 *
 * @param message - Confirmation message to display
 * @param options - Object containing optional yes flag
 * @param isRemote - Whether this is a remote operation
 * @returns True if confirmed, false otherwise
 *
 * @example
 * const confirmed = await confirmAction('Delete entry "post-1"?', { yes: false }, true);
 * if (!confirmed) return;
 */
export declare function confirmAction(message: string, options: ConfirmOptions, isRemote: boolean): Promise<boolean>;
/**
 * Parse the --env flag value into an array of environment targets.
 *
 * @param env - The --env flag value (local, remote, or both)
 * @returns Array of environment targets
 * @throws Error if invalid value
 *
 * @example
 * parseEnvTargets('local')  // ['local']
 * parseEnvTargets('remote') // ['remote']
 * parseEnvTargets('both')   // ['local', 'remote']
 */
export declare function parseEnvTargets(env: string): EnvTarget[];
/**
 * Run an operation for multiple environment targets in parallel.
 * Continues execution even if one environment fails.
 *
 * @param targets - Environment targets to run the operation for
 * @param operation - Async operation to run for each target
 * @param output - Output context for logging
 * @returns Map of results for each environment
 *
 * @example
 * const results = await runForEnvironments(
 *   ['local', 'remote'],
 *   async (target) => {
 *     const client = createClientForEnv(target);
 *     return client.push(content);
 *   },
 *   output
 * );
 */
export declare function runForEnvironments<T>(targets: EnvTarget[], operation: (target: EnvTarget) => Promise<T>, output: OutputContext, options?: {
    /**
     * Optional predicate to determine logical success for fulfilled operations.
     * If omitted, any fulfilled operation is treated as success.
     */
    isResultSuccess?: (result: T) => boolean;
    /**
     * Optional formatter for logical-failure errors in results by environment output.
     */
    formatFailure?: (result: T) => string;
}): Promise<Map<EnvTarget, EnvResult<T>>>;
/**
 * Check if all environments succeeded.
 */
export declare function allEnvSucceeded<T>(results: Map<EnvTarget, EnvResult<T>>): boolean;
/**
 * Create a management client for a specific environment target.
 *
 * @param target - Environment target (local or remote)
 * @returns Management client configured for that environment
 */
export declare function createClientForEnv(target: EnvTarget): ManagementClient;
/**
 * Create command context with output, client, and environment info.
 *
 * @param command - Commander command instance
 * @returns Context object with output, client, environment targets, and flags
 *
 * @example
 * const ctx = createCommandContext(command);
 * ctx.output.info('Starting...');
 * await ctx.client.entries.get('post', 'my-post');
 */
export declare function createCommandContext(command: Command): CommandContext;
/**
 * Get global options and output context without creating a client.
 * Useful when you need to check conditions before creating the client.
 *
 * @param command - Commander command instance
 * @returns Object with output, environment info, and globalOpts
 */
export declare function getOutputContext(command: Command): {
    output: OutputContext;
    isRemote: boolean;
    envTargets: EnvTarget[];
    globalOpts: GlobalOptions;
};
/**
 * Handle errors in a consistent way across all commands.
 *
 * @param error - The error that occurred
 * @param output - Output context for displaying errors
 *
 * @example
 * try {
 *   await doSomething();
 * } catch (error) {
 *   handleCommandError(error, output);
 * }
 */
export declare function handleCommandError(error: unknown, output: OutputContext, ctx?: CliErrorContext): void;
/**
 * Wrap an async command action with standard error handling.
 *
 * @param action - The async action to wrap
 * @returns Wrapped action that handles errors
 *
 * @example
 * .action(withErrorHandling(async (args, options, command) => {
 *   const ctx = createCommandContext(command);
 *   // ... command logic
 * }))
 */
export declare function withErrorHandling<TArgs extends unknown[]>(action: (...args: [...TArgs, Command]) => Promise<void>): (...args: [...TArgs, Command]) => Promise<void>;
/**
 * Wrap a destructive command action with confirmation prompt and error handling.
 *
 * @param getMessage - Function that builds the confirmation message from command args
 * @param action - The async action to perform after confirmation
 * @returns Wrapped action that confirms, then executes with error handling
 *
 * @example
 * .action(withConfirmation(
 *   (type, identifier) => `Delete entry "${type}/${identifier}"?`,
 *   async (ctx, type, identifier) => {
 *     ctx.output.info(`Deleting entry: ${type}/${identifier}`);
 *     await ctx.client.entries.delete(type, identifier);
 *     ctx.output.success(`Entry deleted: ${identifier}`);
 *   }
 * ))
 */
export declare function withConfirmation<TArgs extends unknown[]>(getMessage: (...args: TArgs) => string, action: (ctx: CommandContext, ...args: TArgs) => Promise<void>): (...args: [...TArgs, ConfirmOptions, Command]) => Promise<void>;
/**
 * Configuration for publish/unpublish command factories.
 */
export interface PublishCommandConfig {
    /** Resource name for display (e.g., 'entry', 'page') */
    resourceName: string;
    /** Argument names (e.g., ['type', 'identifier'] or ['identifier']) */
    args: readonly string[];
    /** Function to call the appropriate client method */
    action: (client: ManagementClient, ...args: string[]) => Promise<void>;
}
/**
 * Create a publish command for a resource.
 *
 * @example
 * const publishCommand = createPublishCommand({
 *   resourceName: 'entry',
 *   args: ['type', 'identifier'],
 *   action: (client, type, id) => client.entries.publish(type, id),
 * });
 */
export declare function createPublishCommand(config: PublishCommandConfig): Command;
/**
 * Create an unpublish command for a resource.
 *
 * @example
 * const unpublishCommand = createUnpublishCommand({
 *   resourceName: 'entry',
 *   args: ['type', 'identifier'],
 *   action: (client, type, id) => client.entries.unpublish(type, id),
 * });
 */
export declare function createUnpublishCommand(config: PublishCommandConfig): Command;
/**
 * Configuration for get command factory.
 */
export interface GetCommandConfig<T> {
    /** Resource name for display (e.g., 'entry', 'page') */
    resourceName: string;
    /** Argument names (e.g., ['type', 'identifier'] or ['identifier']) */
    args: readonly string[];
    /** Function to fetch the resource */
    get: (client: ManagementClient, ...args: string[]) => Promise<T | null>;
    /** Function to format the resource for non-JSON output */
    formatOutput: (item: T) => Record<string, unknown>;
}
/**
 * Create a get command for a resource.
 *
 * @example
 * const getCommand = createGetCommand({
 *   resourceName: 'entry',
 *   args: ['type', 'identifier'],
 *   get: (client, type, id) => client.entries.get(type, id),
 *   formatOutput: (entry) => ({
 *     id: entry.id,
 *     status: entry.status,
 *   }),
 * });
 */
export declare function createGetCommand<T>(config: GetCommandConfig<T>): Command;
/**
 * Result type for list operations.
 */
export interface ListResult<T> {
    items: T[];
    pagination?: {
        page: number;
        limit: number;
        total: number;
    };
}
/**
 * Configuration for list command factory.
 */
export interface ListCommandConfig<T> {
    /** Resource name for display (e.g., 'entry', 'page') */
    resourceName: string;
    /** Plural resource name (e.g., 'entries', 'pages') */
    resourceNamePlural: string;
    /** Argument names (e.g., ['type'] for entries, [] for pages) */
    args: readonly string[];
    /** Whether this list supports pagination options */
    hasPagination: boolean;
    /** Function to fetch the list - receives args as array plus optional pagination */
    list: (client: ManagementClient, args: string[], pagination?: ParsedPagination) => Promise<ListResult<T>>;
    /** Table column headers */
    tableHeaders: string[];
    /** Row formatter for table display */
    formatRow: RowFormatter<T>;
}
/**
 * Create a list command for a resource.
 *
 * @example
 * const listCommand = createListCommand({
 *   resourceName: 'entry',
 *   resourceNamePlural: 'entries',
 *   args: ['type'],
 *   hasPagination: true,
 *   list: (client, [type], pagination) => client.entries.list(type, pagination),
 *   tableHeaders: ['Identifier', 'Status', 'Updated'],
 *   formatRow: (entry) => [entry.identifier, entry.status, entry.updatedAt],
 * });
 */
export declare function createListCommand<T>(config: ListCommandConfig<T>): Command;
