--- title: Frontend API Reference sidebar_position: 1 --- # Frontend Extension API Reference The `@apache-superset/core` package provides comprehensive APIs for frontend extensions to interact with Apache Superset. All APIs are versioned and follow semantic versioning principles. ## Core APIs ### Extension Context Every extension receives a context object during activation that provides access to the extension system. ```typescript interface ExtensionContext { // Unique extension identifier extensionId: string; // Extension metadata extensionPath: string; extensionUri: Uri; // Storage paths globalStorageUri: Uri; workspaceStorageUri: Uri; // Subscription management subscriptions: Disposable[]; // State management globalState: Memento; workspaceState: Memento; // Extension-specific APIs registerView(viewId: string, component: React.Component): Disposable; registerCommand(commandId: string, handler: CommandHandler): Disposable; } ``` ### Lifecycle Methods ```typescript // Required: Called when extension is activated export function activate(context: ExtensionContext): void | Promise { console.log('Extension activated'); } // Optional: Called when extension is deactivated export function deactivate(): void | Promise { console.log('Extension deactivated'); } ``` ## SQL Lab APIs The `sqlLab` namespace provides APIs specific to SQL Lab functionality. ### Query Management ```typescript // Get current query editor content sqlLab.getCurrentQuery(): string | undefined // Get active tab information sqlLab.getCurrentTab(): Tab | undefined // Get all open tabs sqlLab.getTabs(): Tab[] // Get available databases sqlLab.getDatabases(): Database[] // Get schemas for a database sqlLab.getSchemas(databaseId: number): Promise // Get tables for a schema sqlLab.getTables(databaseId: number, schema: string): Promise // Insert text at cursor position sqlLab.insertText(text: string): void // Replace entire query sqlLab.replaceQuery(query: string): void // Execute current query sqlLab.executeQuery(): Promise // Stop query execution sqlLab.stopQuery(queryId: string): Promise ``` ### Event Subscriptions ```typescript // Query execution events sqlLab.onDidQueryRun( listener: (event: QueryRunEvent) => void ): Disposable sqlLab.onDidQueryComplete( listener: (event: QueryCompleteEvent) => void ): Disposable sqlLab.onDidQueryFail( listener: (event: QueryFailEvent) => void ): Disposable // Editor events sqlLab.onDidChangeEditorContent( listener: (content: string) => void ): Disposable sqlLab.onDidChangeActiveTab( listener: (tab: Tab) => void ): Disposable // Panel events sqlLab.onDidOpenPanel( listener: (panel: Panel) => void ): Disposable sqlLab.onDidClosePanel( listener: (panel: Panel) => void ): Disposable ``` ### Types ```typescript interface Tab { id: string; title: string; query: string; database: Database; schema?: string; isActive: boolean; queryId?: string; status?: 'pending' | 'running' | 'success' | 'error'; } interface Database { id: number; name: string; backend: string; allows_subquery: boolean; allows_ctas: boolean; allows_cvas: boolean; } interface QueryResult { queryId: string; status: 'success' | 'error'; data?: any[]; columns?: Column[]; error?: string; startTime: number; endTime: number; rows: number; } ``` ## Commands API Register and execute commands within Superset. ### Registration ```typescript interface CommandHandler { execute(...args: any[]): any | Promise; isEnabled?(): boolean; isVisible?(): boolean; } // Register a command commands.registerCommand( commandId: string, handler: CommandHandler ): Disposable // Register with metadata commands.registerCommand( commandId: string, metadata: CommandMetadata, handler: (...args: any[]) => any ): Disposable interface CommandMetadata { title: string; category?: string; icon?: string; enablement?: string; when?: string; } ``` ### Execution ```typescript // Execute a command commands.executeCommand( commandId: string, ...args: any[] ): Promise // Get all registered commands commands.getCommands(): Promise // Check if command exists commands.hasCommand(commandId: string): boolean ``` ### Built-in Commands ```typescript // SQL Lab commands 'sqllab.executeQuery' 'sqllab.formatQuery' 'sqllab.saveQuery' 'sqllab.shareQuery' 'sqllab.downloadResults' // Editor commands 'editor.action.formatDocument' 'editor.action.commentLine' 'editor.action.findReferences' // Extension commands 'extensions.installExtension' 'extensions.uninstallExtension' 'extensions.enableExtension' 'extensions.disableExtension' ``` ## UI Components Pre-built components from `@apache-superset/core` for consistent UI. ### Basic Components ```typescript import { Button, Input, Select, Checkbox, Radio, Switch, Slider, DatePicker, TimePicker, Tooltip, Popover, Modal, Drawer, Alert, Message, Notification, Spin, Progress } from '@apache-superset/core'; ``` ### Data Display ```typescript import { Table, List, Card, Collapse, Tabs, Tag, Badge, Statistic, Timeline, Tree, Empty, Result } from '@apache-superset/core'; ``` ### Form Components ```typescript import { Form, FormItem, FormList, InputNumber, TextArea, Upload, Rate, Cascader, AutoComplete, Mentions } from '@apache-superset/core'; ``` ## Authentication API Access authentication and user information. ```typescript // Get current user authentication.getCurrentUser(): User | undefined interface User { id: number; username: string; email: string; firstName: string; lastName: string; roles: Role[]; isActive: boolean; isAnonymous: boolean; } // Get CSRF token for API requests authentication.getCSRFToken(): Promise // Check permissions authentication.hasPermission( permission: string, resource?: string ): boolean // Get user preferences authentication.getPreferences(): UserPreferences // Update preferences authentication.setPreference( key: string, value: any ): Promise ``` ## Storage API Persist data across sessions. ### Global Storage ```typescript // Shared across all workspaces const globalState = context.globalState; // Get value const value = globalState.get(key: string): T | undefined // Set value await globalState.update(key: string, value: any): Promise // Get all keys globalState.keys(): readonly string[] ``` ### Workspace Storage ```typescript // Specific to current workspace const workspaceState = context.workspaceState; // Same API as globalState workspaceState.get(key: string): T | undefined workspaceState.update(key: string, value: any): Promise workspaceState.keys(): readonly string[] ``` ### Secrets Storage ```typescript // Secure storage for sensitive data secrets.store(key: string, value: string): Promise secrets.get(key: string): Promise secrets.delete(key: string): Promise ``` ## Events API Subscribe to and emit custom events. ```typescript // Create an event emitter const onDidChange = new EventEmitter(); // Expose as event export const onChange = onDidChange.event; // Fire event onDidChange.fire({ type: 'update', data: newData }); // Subscribe to event const disposable = onChange((event) => { console.log('Changed:', event); }); // Cleanup disposable.dispose(); ``` ## Window API Interact with the UI window. ### Notifications ```typescript // Show info message window.showInformationMessage( message: string, ...items: string[] ): Promise // Show warning window.showWarningMessage( message: string, ...items: string[] ): Promise // Show error window.showErrorMessage( message: string, ...items: string[] ): Promise // Show with options window.showInformationMessage( message: string, options: MessageOptions, ...items: MessageItem[] ): Promise interface MessageOptions { modal?: boolean; detail?: string; } ``` ### Input Dialogs ```typescript // Show input box window.showInputBox( options?: InputBoxOptions ): Promise interface InputBoxOptions { title?: string; prompt?: string; placeHolder?: string; value?: string; password?: boolean; validateInput?(value: string): string | null; } // Show quick pick window.showQuickPick( items: string[] | QuickPickItem[], options?: QuickPickOptions ): Promise interface QuickPickOptions { title?: string; placeHolder?: string; canPickMany?: boolean; matchOnDescription?: boolean; matchOnDetail?: boolean; } ``` ### Progress ```typescript // Show progress window.withProgress( options: ProgressOptions, task: (progress: Progress<{message?: string}>) => Promise ): Promise interface ProgressOptions { location: ProgressLocation; title?: string; cancellable?: boolean; } // Example usage await window.withProgress( { location: ProgressLocation.Notification, title: "Processing", cancellable: true }, async (progress) => { progress.report({ message: 'Step 1...' }); await step1(); progress.report({ message: 'Step 2...' }); await step2(); } ); ``` ## Workspace API Access workspace information and configuration. ```typescript // Get workspace folders workspace.workspaceFolders: readonly WorkspaceFolder[] // Get configuration workspace.getConfiguration( section?: string ): WorkspaceConfiguration // Update configuration workspace.getConfiguration('myExtension') .update('setting', value, ConfigurationTarget.Workspace) // Watch for configuration changes workspace.onDidChangeConfiguration( listener: (e: ConfigurationChangeEvent) => void ): Disposable // File system operations workspace.fs.readFile(uri: Uri): Promise workspace.fs.writeFile(uri: Uri, content: Uint8Array): Promise workspace.fs.delete(uri: Uri): Promise workspace.fs.rename(oldUri: Uri, newUri: Uri): Promise workspace.fs.copy(source: Uri, destination: Uri): Promise workspace.fs.createDirectory(uri: Uri): Promise workspace.fs.readDirectory(uri: Uri): Promise<[string, FileType][]> workspace.fs.stat(uri: Uri): Promise ``` ## HTTP Client API Make HTTP requests from extensions. ```typescript import { api } from '@apache-superset/core'; // GET request const response = await api.get('/api/v1/chart/'); // POST request const response = await api.post('/api/v1/chart/', { data: chartData }); // PUT request const response = await api.put('/api/v1/chart/123', { data: updatedData }); // DELETE request const response = await api.delete('/api/v1/chart/123'); // Custom headers const response = await api.get('/api/v1/chart/', { headers: { 'X-Custom-Header': 'value' } }); // Query parameters const response = await api.get('/api/v1/chart/', { params: { page: 1, page_size: 20 } }); ``` ## Theming API Access and customize theme settings. ```typescript // Get current theme theme.getActiveTheme(): Theme interface Theme { name: string; isDark: boolean; colors: ThemeColors; typography: Typography; spacing: Spacing; } // Listen for theme changes theme.onDidChangeTheme( listener: (theme: Theme) => void ): Disposable // Get theme colors const colors = theme.colors; colors.primary colors.success colors.warning colors.error colors.info colors.text colors.background colors.border ``` ## Disposable Pattern Manage resource cleanup consistently. ```typescript interface Disposable { dispose(): void; } // Create a disposable class MyDisposable implements Disposable { dispose() { // Cleanup logic } } // Combine disposables const composite = Disposable.from( disposable1, disposable2, disposable3 ); // Dispose all at once composite.dispose(); // Use in extension export function activate(context: ExtensionContext) { // All disposables added here are cleaned up on deactivation context.subscriptions.push( registerCommand(...), registerView(...), onDidChange(...) ); } ``` ## Type Definitions Complete TypeScript definitions are available: ```typescript import type { ExtensionContext, Disposable, Event, EventEmitter, Uri, Command, QuickPickItem, InputBoxOptions, Progress, CancellationToken } from '@apache-superset/core'; ``` ## Version Compatibility The API follows semantic versioning: ```typescript // Check API version const version = superset.version; // Version components version.major // Breaking changes version.minor // New features version.patch // Bug fixes // Check minimum version if (version.major < 1) { throw new Error('Requires Superset API v1.0.0 or higher'); } ``` ## Migration Guide ### From v0.x to v1.0 ```typescript // Before (v0.x) sqlLab.runQuery(query); // After (v1.0) sqlLab.executeQuery(); // Before (v0.x) core.registerPanel(id, component); // After (v1.0) context.registerView(id, component); ``` ## Best Practices ### Error Handling ```typescript export async function activate(context: ExtensionContext) { try { await initializeExtension(); } catch (error) { console.error('Failed to initialize:', error); window.showErrorMessage( `Extension failed to activate: ${error.message}` ); } } ``` ### Resource Management ```typescript // Always use disposables const disposables: Disposable[] = []; disposables.push( commands.registerCommand(...), sqlLab.onDidQueryRun(...), workspace.onDidChangeConfiguration(...) ); // Cleanup in deactivate export function deactivate() { disposables.forEach(d => d.dispose()); } ``` ### Type Safety ```typescript // Use type guards function isDatabase(obj: any): obj is Database { return obj && typeof obj.id === 'number' && typeof obj.name === 'string'; } // Use generics function getValue(key: string, defaultValue: T): T { return context.globalState.get(key) ?? defaultValue; } ```