@ably/cli
Version:
Ably CLI for Pub/Sub, Chat and Spaces
193 lines (192 loc) • 9.2 kB
TypeScript
import { InteractiveBaseCommand } from "./interactive-base-command.js";
import * as Ably from "ably";
import { ConfigManager } from "./services/config-manager.js";
import { InteractiveHelper } from "./services/interactive-helper.js";
import { BaseFlags, CommandConfig, ErrorDetails } from "./types/cli.js";
export declare const WEB_CLI_RESTRICTED_COMMANDS: string[];
export declare const WEB_CLI_ANONYMOUS_RESTRICTED_COMMANDS: string[];
export declare const INTERACTIVE_UNSUITABLE_COMMANDS: string[];
export declare abstract class AblyBaseCommand extends InteractiveBaseCommand {
protected _authInfoShown: boolean;
static globalFlags: {
"access-token": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
"api-key": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
"client-id": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
"control-host": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
env: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
endpoint: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
host: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
port: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
tlsPort: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
tls: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
"pretty-json": import("@oclif/core/interfaces").BooleanFlag<boolean>;
token: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
"web-cli-help": import("@oclif/core/interfaces").BooleanFlag<boolean>;
};
protected configManager: ConfigManager;
protected interactiveHelper: InteractiveHelper;
protected isWebCliMode: boolean;
constructor(argv: string[], config: CommandConfig);
/**
* Check if we're running in test mode
* @returns true if running in test mode
*/
protected isTestMode(): boolean;
protected isAnonymousWebMode(): boolean;
/**
* Check if command matches a pattern (supports wildcards)
*/
protected matchesCommandPattern(commandId: string, pattern: string): boolean;
/**
* Check if command is restricted in anonymous web CLI mode
*/
protected isRestrictedInAnonymousMode(commandId: string): boolean;
/**
* Check if terminal updates (like carriage returns and line clearing) should be used.
* Returns true only when:
* - Output is to a TTY (interactive terminal)
* - Not in test mode
* - Not in CI environment
*/
protected shouldUseTerminalUpdates(): boolean;
/**
* Get test mocks if in test mode
* @returns Test mocks object or undefined if not in test mode
*/
protected getMockAblyRest(): Ably.Rest | undefined;
/**
* Check if this is a web CLI version and return a consistent error message
* for commands that are not allowed in web CLI mode
*/
protected checkWebCliRestrictions(): void;
/**
* Create an Ably REST client with automatic auth info display
*/
protected createAblyRestClient(flags: BaseFlags, options?: {
skipAuthInfo?: boolean;
}): Promise<Ably.Rest | null>;
/**
* Create an Ably Realtime client with automatic auth info display
*/
protected createAblyRealtimeClient(flags: BaseFlags, options?: {
skipAuthInfo?: boolean;
}): Promise<Ably.Realtime | null>;
/**
* @deprecated Use createAblyRestClient or createAblyRealtimeClient instead
*/
protected createAblyClient(flags: BaseFlags, options?: {
type?: 'rest' | 'realtime';
skipAuthInfo?: boolean;
}): Promise<Ably.Rest | Ably.Realtime | null>;
/**
* Internal method that creates either REST or Realtime client
* Shared functionality for both client types
*/
private createAblyClientInternal;
/**
* Display the current account, app, and authentication information
* This provides context to the user about which resources they're working with
*
* @param flags Command flags that may contain auth overrides
* @param showAppInfo Whether to show app info (for data plane commands)
*/
protected displayAuthInfo(flags: BaseFlags, showAppInfo?: boolean): void;
/**
* Display information for control plane commands
* Shows only account information
*/
protected displayControlPlaneInfo(flags: BaseFlags): void;
/**
* Display information for data plane (product API) commands
* Shows account, app, and authentication information
*/
protected displayDataPlaneInfo(flags: BaseFlags): void;
protected ensureAppAndKey(flags: BaseFlags): Promise<{
apiKey: string;
appId: string;
} | null>;
/**
* This hook runs before command execution
* It's the oclif standard hook that runs before the run() method
*/
finally(err: Error | undefined): Promise<void>;
protected formatJsonOutput(data: Record<string, unknown>, flags: BaseFlags): string;
protected getClientOptions(flags: BaseFlags): Ably.ClientOptions;
init(): Promise<void>;
/**
* Checks if a command is allowed to run in web CLI mode
* This should be called by commands that are restricted in web CLI mode
*
* @returns True if command can run, false if it's restricted
*/
protected isAllowedInWebCliMode(command?: string): boolean;
protected isPrettyJsonOutput(flags: BaseFlags): boolean;
/**
* Logs a CLI event.
* If --verbose is enabled:
* - If --json or --pretty-json is also enabled, outputs the event as structured JSON.
* - Otherwise (normal mode), outputs the human-readable message prefixed with the component.
* Does nothing if --verbose is not enabled.
*/
protected logCliEvent(flags: BaseFlags, component: string, event: string, message: string, data?: Record<string, unknown>): void;
/** Helper to output errors in JSON format */
protected outputJsonError(message: string, errorDetails?: ErrorDetails): void;
/**
* Helper method to parse and validate an API key
* Returns null if invalid, or the parsed components if valid
*/
protected parseApiKey(apiKey: string): {
appId: string;
keyId: string;
keySecret: string;
} | null;
protected shouldOutputJson(flags: BaseFlags): boolean;
/**
* Determine if this command should show account/app info
* Based on a centralized list of exceptions
*/
protected shouldShowAuthInfo(): boolean;
protected shouldSuppressOutput(flags: BaseFlags): boolean;
/**
* Display auth info at the beginning of command execution
* This should be called at the start of run() in command implementations
*/
protected showAuthInfoIfNeeded(flags?: BaseFlags): void;
private handleInvalidKey;
private setClientId;
/**
* Centralized handler for cleaning up resources like Ably connections
* Includes a timeout to prevent hanging if cleanup takes too long
* @param cleanupFunction The async function to perform cleanup
* @param timeoutMs Timeout duration in milliseconds (default 5000)
*/
protected setupCleanupHandler(cleanupFunction: () => Promise<void>, timeoutMs?: number): Promise<void>;
/**
* Check if account information should be hidden for this command execution
* This is the case when:
* 1. No account is configured
* 2. Explicit API key or token is provided
* 3. Explicit access token is provided
* 4. Environment variables are used for auth
*/
protected shouldHideAccountInfo(flags: BaseFlags): boolean;
/**
* Set up connection state logging for a Realtime client
* This should be called after creating a Realtime client for long-running commands
*/
protected setupConnectionStateLogging(client: Ably.Realtime, flags: BaseFlags, options?: {
component?: string;
includeUserFriendlyMessages?: boolean;
}): (() => void);
/**
* Set up channel state logging for a channel
* This should be called after creating/getting a channel for long-running commands
*/
protected setupChannelStateLogging(channel: Ably.RealtimeChannel, flags: BaseFlags, options?: {
component?: string;
includeUserFriendlyMessages?: boolean;
}): (() => void);
}
export { BaseFlags } from "./types/cli.js";