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
TypeScript
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 {};