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.

320 lines (277 loc) 8.97 kB
/** * DatabaseAdapter Interface - Unified API for Appwrite Database Operations * * This interface provides a unified way to interact with both legacy Appwrite * (collections/documents) and new TablesDB (tables/rows) APIs. All internal * code uses TablesDB-style method signatures for consistency. */ import type { Client } from "node-appwrite"; import type { ApiMode } from "../utils/versionDetection.js"; // Base parameter types using TablesDB terminology export interface CreateRowParams { databaseId: string; tableId: string; id: string; data: any; permissions?: string[]; } export interface UpdateRowParams { databaseId: string; tableId: string; id: string; data?: any; permissions?: string[]; } export interface ListRowsParams { databaseId: string; tableId: string; queries?: any[]; } export interface DeleteRowParams { databaseId: string; tableId: string; id: string; } export interface CreateTableParams { databaseId: string; id: string; name: string; permissions?: string[]; documentSecurity?: boolean; rowSecurity?: boolean; enabled?: boolean; } export interface UpdateTableParams { databaseId: string; id: string; name: string; permissions?: string[]; documentSecurity?: boolean; rowSecurity?: boolean; enabled?: boolean; } export interface ListTablesParams { databaseId: string; queries?: any[]; } export interface DeleteTableParams { databaseId: string; tableId: string; } export interface GetTableParams { databaseId: string; tableId: string; } // Bulk operation parameters export interface BulkCreateRowsParams { databaseId: string; tableId: string; rows: any[]; } export interface BulkUpsertRowsParams { databaseId: string; tableId: string; rows: any[]; } export interface BulkDeleteRowsParams { databaseId: string; tableId: string; rowIds: string[]; // Empty array = wipe mode (use Query.limit), otherwise specific IDs to delete batchSize?: number; // Optional batch size for wipe mode (default 250) } // Index operation parameters export interface CreateIndexParams { databaseId: string; tableId: string; key: string; type: string; attributes: string[]; orders?: string[]; lengths?: number[]; } export interface ListIndexesParams { databaseId: string; tableId: string; queries?: any[]; } export interface DeleteIndexParams { databaseId: string; tableId: string; key: string; } // Attribute operation parameters export interface CreateAttributeParams { databaseId: string; tableId: string; key: string; type: string; size?: number; required?: boolean; default?: any; array?: boolean; encrypt?: boolean; // Numeric type parameters min?: number; max?: number; // Enum type parameters elements?: string[]; // Relationship type parameters relatedCollection?: string; relationType?: 'oneToOne' | 'manyToOne' | 'oneToMany' | 'manyToMany'; twoWay?: boolean; twoWayKey?: string; onDelete?: 'setNull' | 'cascade' | 'restrict'; side?: 'parent' | 'child'; // Additional type-specific parameters [key: string]: any; } export interface UpdateAttributeParams { databaseId: string; tableId: string; key: string; type?: string; required?: boolean; default?: any; size?: number; min?: number; max?: number; array?: boolean; encrypt?: boolean; elements?: string[]; relatedCollection?: string; relationType?: string; twoWay?: boolean; twoWayKey?: string; onDelete?: string; } export interface DeleteAttributeParams { databaseId: string; tableId: string; key: string; } // Response types with conditional typing export interface ApiResponse<T = any> { data?: T; total?: number; documents?: T[]; // Legacy compatibility rows?: T[]; // TablesDB format collections?: T[]; // Legacy format tables?: T[]; // TablesDB format errors?: any[]; // For bulk operation errors } // Metadata about the adapter export interface AdapterMetadata { apiMode: ApiMode; terminology: { container: 'collection' | 'table'; item: 'document' | 'row'; service: 'Databases' | 'TablesDB'; }; capabilities: { bulkOperations: boolean; advancedQueries: boolean; realtime: boolean; transactions?: boolean; }; } /** * Main DatabaseAdapter interface - all implementations must support these methods */ export interface DatabaseAdapter { // Row (Document) operations - TablesDB-style signatures listRows(params: ListRowsParams): Promise<ApiResponse>; createRow(params: CreateRowParams): Promise<ApiResponse>; updateRow(params: UpdateRowParams): Promise<ApiResponse>; deleteRow(params: DeleteRowParams): Promise<ApiResponse>; getRow(params: { databaseId: string; tableId: string; id: string }): Promise<ApiResponse>; // Table (Collection) operations - TablesDB-style signatures listTables(params: ListTablesParams): Promise<ApiResponse>; createTable(params: CreateTableParams): Promise<ApiResponse>; updateTable(params: UpdateTableParams): Promise<ApiResponse>; deleteTable(params: DeleteTableParams): Promise<ApiResponse>; getTable(params: GetTableParams): Promise<ApiResponse>; // Index operations listIndexes(params: ListIndexesParams): Promise<ApiResponse>; createIndex(params: CreateIndexParams): Promise<ApiResponse>; deleteIndex(params: DeleteIndexParams): Promise<ApiResponse>; // Attribute operations createAttribute(params: CreateAttributeParams): Promise<ApiResponse>; updateAttribute(params: UpdateAttributeParams): Promise<ApiResponse>; deleteAttribute(params: DeleteAttributeParams): Promise<ApiResponse>; // Bulk operations (when supported) bulkCreateRows?(params: BulkCreateRowsParams): Promise<ApiResponse>; bulkUpsertRows?(params: BulkUpsertRowsParams): Promise<ApiResponse>; bulkDeleteRows?(params: BulkDeleteRowsParams): Promise<ApiResponse>; // Adapter metadata getMetadata(): AdapterMetadata; // Utility methods supportsBulkOperations(): boolean; getApiMode(): ApiMode; getTerminology(): AdapterMetadata['terminology']; // Raw client access for advanced operations getRawClient(): any; } /** * Base adapter class with common functionality */ export abstract class BaseAdapter implements DatabaseAdapter { protected client: Client; protected apiMode: ApiMode; constructor(client: Client, apiMode: ApiMode) { this.client = client; this.apiMode = apiMode; } // Abstract methods that must be implemented by concrete adapters abstract listRows(params: ListRowsParams): Promise<ApiResponse>; abstract createRow(params: CreateRowParams): Promise<ApiResponse>; abstract updateRow(params: UpdateRowParams): Promise<ApiResponse>; abstract deleteRow(params: DeleteRowParams): Promise<ApiResponse>; abstract getRow(params: { databaseId: string; tableId: string; id: string }): Promise<ApiResponse>; abstract listTables(params: ListTablesParams): Promise<ApiResponse>; abstract createTable(params: CreateTableParams): Promise<ApiResponse>; abstract updateTable(params: UpdateTableParams): Promise<ApiResponse>; abstract deleteTable(params: DeleteTableParams): Promise<ApiResponse>; abstract getTable(params: GetTableParams): Promise<ApiResponse>; abstract listIndexes(params: ListIndexesParams): Promise<ApiResponse>; abstract createIndex(params: CreateIndexParams): Promise<ApiResponse>; abstract deleteIndex(params: DeleteIndexParams): Promise<ApiResponse>; abstract createAttribute(params: CreateAttributeParams): Promise<ApiResponse>; abstract updateAttribute(params: UpdateAttributeParams): Promise<ApiResponse>; abstract deleteAttribute(params: DeleteAttributeParams): Promise<ApiResponse>; abstract getMetadata(): AdapterMetadata; // Common implementations getApiMode(): ApiMode { return this.apiMode; } getRawClient(): any { return this.client; } supportsBulkOperations(): boolean { return this.getMetadata().capabilities.bulkOperations; } getTerminology(): AdapterMetadata['terminology'] { return this.getMetadata().terminology; } } /** * Error types for adapter operations */ export class AdapterError extends Error { constructor( message: string, public readonly code: string, public readonly originalError?: Error ) { super(message); this.name = 'AdapterError'; } } export class UnsupportedOperationError extends AdapterError { constructor(operation: string, apiMode: ApiMode) { super( `Operation '${operation}' is not supported in ${apiMode} mode`, 'UNSUPPORTED_OPERATION' ); this.name = 'UnsupportedOperationError'; } }