UNPKG

appwrite-utils-cli

Version:

Appwrite Utility Functions to help with database management, data conversion, data import, migrations, and much more. Meant to be used as a CLI tool, I do not recommend installing this in frontend environments.

451 lines (450 loc) 13.5 kB
import type { AppwriteConfig, Collection, CollectionCreate, AppwriteFunction } from "appwrite-utils"; import { type ConfigOverrides, type SessionAuthInfo, type AuthenticationStatus, type ValidationResult } from "./services/index.js"; /** * Database type from AppwriteConfig */ type Database = { $id: string; name: string; bucket?: any; }; /** * Bucket type from AppwriteConfig */ type Bucket = { $id: string; name: string; $permissions?: any[]; [key: string]: any; }; /** * Options for loading configuration */ export interface ConfigLoadOptions { /** * Directory to start searching for config files * @default process.cwd() */ configDir?: string; /** * Force reload configuration even if cached * @default false */ forceReload?: boolean; /** * Validate configuration after loading * @default false */ validate?: boolean; /** * Use strict validation mode (warnings as errors) * @default false */ strictMode?: boolean; /** * Report validation results to console * @default false */ reportValidation?: boolean; /** * Override configuration values */ overrides?: ConfigOverrides; /** * Override session authentication (used for preserving session on reload) */ sessionOverride?: SessionAuthInfo; /** * Prefer loading from appwrite.config.json over config.yaml * @default false */ preferJson?: boolean; } /** * Filter function for collections (accepts both Collection and CollectionCreate) */ export type CollectionFilter = (collection: Collection | CollectionCreate) => boolean; /** * Centralized configuration manager with intelligent caching and session management. * * This singleton provides a unified interface for: * - Configuration discovery and loading (YAML, TypeScript, JSON) * - Session authentication with automatic caching * - Configuration validation and merging * - Session preservation across reloads * - File watching for configuration changes * * @example * ```typescript * const configManager = ConfigManager.getInstance(); * * // Load configuration (cached after first call) * const config = await configManager.loadConfig({ * validate: true, * reportValidation: true, * }); * * // Get cached config synchronously * const cachedConfig = configManager.getConfig(); * * // Reload with session preservation * const reloadedConfig = await configManager.reloadConfig(); * * // Watch for config changes * const unwatch = configManager.watchConfig(async (config) => { * console.log("Config changed:", config); * }); * ``` */ export declare class ConfigManager { private static instance; /** * Get the ConfigManager singleton instance * * @returns The singleton ConfigManager instance * * @example * ```typescript * const configManager = ConfigManager.getInstance(); * ``` */ static getInstance(): ConfigManager; /** * Reset the singleton instance (useful for testing) * * @example * ```typescript * ConfigManager.resetInstance(); * const newInstance = ConfigManager.getInstance(); * ``` */ static resetInstance(): void; private cachedConfig; private cachedConfigPath; private cachedSession; private lastLoadTimestamp; private isInitialized; private discoveryService; private loaderService; private validationService; private sessionService; private mergeService; /** * Private constructor to enforce singleton pattern. * Use ConfigManager.getInstance() instead. */ private constructor(); /** * Load configuration with intelligent caching and session management. * * This method orchestrates the entire configuration loading flow: * 1. Returns cached config if available (unless forceReload is true) * 2. Discovers config file using ConfigDiscoveryService * 3. Loads config from file using ConfigLoaderService * 4. Loads and merges session authentication using SessionAuthService * 5. Applies CLI/environment overrides using ConfigMergeService * 6. Validates configuration if requested * 7. Caches the result for future calls * * @param options - Configuration loading options * @returns The loaded and processed configuration * @throws Error if no configuration file is found * @throws Error if validation fails in strict mode * * @example * ```typescript * const config = await configManager.loadConfig({ * configDir: process.cwd(), * validate: true, * strictMode: true, * reportValidation: true, * overrides: { * appwriteEndpoint: "https://custom.endpoint.com/v1" * } * }); * ``` */ loadConfig(options?: ConfigLoadOptions): Promise<AppwriteConfig>; /** * Get the cached configuration synchronously. * * @returns The cached configuration * @throws Error if configuration has not been loaded yet * * @example * ```typescript * const config = configManager.getConfig(); * ``` */ getConfig(): AppwriteConfig; /** * Get the path to the loaded configuration file. * * @returns The configuration file path, or null if not loaded * * @example * ```typescript * const configPath = configManager.getConfigPath(); * console.log(`Config loaded from: ${configPath}`); * ``` */ getConfigPath(): string | null; /** * Check if configuration has been loaded. * * @returns True if configuration is loaded and cached * * @example * ```typescript * if (!configManager.hasConfig()) { * await configManager.loadConfig(); * } * ``` */ hasConfig(): boolean; /** * Check if the ConfigManager has been initialized. * * @returns True if initialized (config loaded at least once) * * @example * ```typescript * if (configManager.isConfigInitialized()) { * console.log("Config ready"); * } * ``` */ isConfigInitialized(): boolean; /** * Invalidate the configuration cache. * Next call to loadConfig() will reload from disk. * * @example * ```typescript * configManager.invalidateCache(); * const freshConfig = await configManager.loadConfig(); * ``` */ invalidateCache(): void; /** * Reload configuration from disk, preserving current session. * * This is a convenience method that combines invalidation and reloading * while automatically preserving the current session authentication. * * @param options - Configuration loading options (forceReload is automatically set) * @returns The reloaded configuration * * @example * ```typescript * // Reload config after manual file changes * const config = await configManager.reloadConfig({ * validate: true, * reportValidation: true * }); * ``` */ reloadConfig(options?: Omit<ConfigLoadOptions, "forceReload">): Promise<AppwriteConfig>; /** * Get the current session information. * * @returns The cached session info, or null if no session * * @example * ```typescript * const session = configManager.getSession(); * if (session) { * console.log(`Authenticated as: ${session.email}`); * } * ``` */ getSession(): SessionAuthInfo | null; /** * Check if a session is available. * * @returns True if a session is cached * * @example * ```typescript * if (configManager.hasSession()) { * console.log("Using session authentication"); * } else { * console.log("Using API key authentication"); * } * ``` */ hasSession(): boolean; /** * Refresh session from disk (bypasses session cache). * * This forces SessionAuthService to reload from ~/.appwrite/prefs.json * and update the cached session. * * @returns The refreshed session, or null if no session found * * @example * ```typescript * // After logging in via appwrite CLI * const session = await configManager.refreshSession(); * if (session) { * console.log("Session refreshed successfully"); * } * ``` */ refreshSession(): Promise<SessionAuthInfo | null>; /** * Get authentication status for the current configuration. * * @returns Authentication status object with details about current auth method * @throws Error if configuration has not been loaded * * @example * ```typescript * const authStatus = await configManager.getAuthStatus(); * console.log(`Auth method: ${authStatus.authMethod}`); * console.log(`Has valid session: ${authStatus.hasValidSession}`); * ``` */ getAuthStatus(): Promise<AuthenticationStatus>; /** * Clear the cached session. * Next load will attempt to find a new session. * * @example * ```typescript * configManager.clearSession(); * const config = await configManager.reloadConfig(); * ``` */ clearSession(): void; /** * Validate the current configuration (warnings allowed). * * @param reportResults - Whether to report validation results to console * @returns Validation result with errors and warnings * @throws Error if configuration has not been loaded * * @example * ```typescript * const validation = configManager.validateConfig(true); * if (!validation.isValid) { * console.log(`Found ${validation.errors.length} errors`); * } * ``` */ validateConfig(reportResults?: boolean): ValidationResult; /** * Validate the current configuration in strict mode (warnings as errors). * * @param reportResults - Whether to report validation results to console * @returns Validation result with errors and warnings (warnings treated as errors) * @throws Error if configuration has not been loaded * * @example * ```typescript * const validation = configManager.validateConfigStrict(true); * if (!validation.isValid) { * console.log("Config validation failed (strict mode)"); * } * ``` */ validateConfigStrict(reportResults?: boolean): ValidationResult; /** * Watch configuration file for changes and reload automatically. * * Returns a function to stop watching. * * @param callback - Function to call when config changes * @returns Function to stop watching * * @example * ```typescript * const unwatch = configManager.watchConfig(async (config) => { * console.log("Config changed, reloading..."); * // Handle config change * }); * * // Later, stop watching * unwatch(); * ``` */ watchConfig(callback: (config: AppwriteConfig) => void | Promise<void>): () => void; /** * Merge overrides into the current configuration without persisting. * * This creates a new config object with overrides applied, without * affecting the cached configuration. * * @param overrides - Configuration overrides to apply * @returns New configuration with overrides applied * @throws Error if configuration has not been loaded * * @example * ```typescript * const customConfig = configManager.mergeOverrides({ * appwriteEndpoint: "https://test.endpoint.com/v1" * }); * ``` */ mergeOverrides(overrides: ConfigOverrides): AppwriteConfig; /** * Get collections from the configuration, optionally filtered. * * @param filter - Optional filter function for collections * @returns Array of collections (or tables, depending on API mode) * * @example * ```typescript * // Get all collections * const allCollections = configManager.getCollections(); * * // Get enabled collections only * const enabledCollections = configManager.getCollections( * (c) => c.enabled !== false * ); * ``` */ getCollections(filter?: CollectionFilter): (Collection | CollectionCreate)[]; /** * Get databases from the configuration. * * @returns Array of databases * * @example * ```typescript * const databases = configManager.getDatabases(); * console.log(`Found ${databases.length} databases`); * ``` */ getDatabases(): Database[]; /** * Get buckets from the configuration. * * @returns Array of buckets * * @example * ```typescript * const buckets = configManager.getBuckets(); * console.log(`Found ${buckets.length} buckets`); * ``` */ getBuckets(): Bucket[]; /** * Get functions from the configuration. * * @returns Array of functions * * @example * ```typescript * const functions = configManager.getFunctions(); * console.log(`Found ${functions.length} functions`); * ``` */ getFunctions(): AppwriteFunction[]; /** * Get cached config with optional overrides applied. * Used internally to avoid reloading when only overrides change. */ private getCachedConfigWithOverrides; } export {};