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.

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

// Required: Called when extension is activated
export function activate(context: ExtensionContext): void | Promise<void> {
  console.log('Extension activated');
}

// Optional: Called when extension is deactivated
export function deactivate(): void | Promise<void> {
  console.log('Extension deactivated');
}

SQL Lab APIs

The sqlLab namespace provides APIs specific to SQL Lab functionality.

Query Management

// 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<Schema[]>

// Get tables for a schema
sqlLab.getTables(databaseId: number, schema: string): Promise<Table[]>

// Insert text at cursor position
sqlLab.insertText(text: string): void

// Replace entire query
sqlLab.replaceQuery(query: string): void

// Execute current query
sqlLab.executeQuery(): Promise<QueryResult>

// Stop query execution
sqlLab.stopQuery(queryId: string): Promise<void>

Event Subscriptions

// 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

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

interface CommandHandler {
  execute(...args: any[]): any | Promise<any>;
  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

// Execute a command
commands.executeCommand<T>(
  commandId: string,
  ...args: any[]
): Promise<T>

// Get all registered commands
commands.getCommands(): Promise<string[]>

// Check if command exists
commands.hasCommand(commandId: string): boolean

Built-in Commands

// 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

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

import {
  Table,
  List,
  Card,
  Collapse,
  Tabs,
  Tag,
  Badge,
  Statistic,
  Timeline,
  Tree,
  Empty,
  Result
} from '@apache-superset/core';

Form Components

import {
  Form,
  FormItem,
  FormList,
  InputNumber,
  TextArea,
  Upload,
  Rate,
  Cascader,
  AutoComplete,
  Mentions
} from '@apache-superset/core';

Authentication API

Access authentication and user information.

// 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<string>

// Check permissions
authentication.hasPermission(
  permission: string,
  resource?: string
): boolean

// Get user preferences
authentication.getPreferences(): UserPreferences

// Update preferences
authentication.setPreference(
  key: string,
  value: any
): Promise<void>

Storage API

Persist data across sessions.

Global Storage

// Shared across all workspaces
const globalState = context.globalState;

// Get value
const value = globalState.get<T>(key: string): T | undefined

// Set value
await globalState.update(key: string, value: any): Promise<void>

// Get all keys
globalState.keys(): readonly string[]

Workspace Storage

// Specific to current workspace
const workspaceState = context.workspaceState;

// Same API as globalState
workspaceState.get<T>(key: string): T | undefined
workspaceState.update(key: string, value: any): Promise<void>
workspaceState.keys(): readonly string[]

Secrets Storage

// Secure storage for sensitive data
secrets.store(key: string, value: string): Promise<void>
secrets.get(key: string): Promise<string | undefined>
secrets.delete(key: string): Promise<void>

Events API

Subscribe to and emit custom events.

// Create an event emitter
const onDidChange = new EventEmitter<ChangeEvent>();

// 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

// Show info message
window.showInformationMessage(
  message: string,
  ...items: string[]
): Promise<string | undefined>

// Show warning
window.showWarningMessage(
  message: string,
  ...items: string[]
): Promise<string | undefined>

// Show error
window.showErrorMessage(
  message: string,
  ...items: string[]
): Promise<string | undefined>

// Show with options
window.showInformationMessage(
  message: string,
  options: MessageOptions,
  ...items: MessageItem[]
): Promise<MessageItem | undefined>

interface MessageOptions {
  modal?: boolean;
  detail?: string;
}

Input Dialogs

// Show input box
window.showInputBox(
  options?: InputBoxOptions
): Promise<string | undefined>

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<string | QuickPickItem | undefined>

interface QuickPickOptions {
  title?: string;
  placeHolder?: string;
  canPickMany?: boolean;
  matchOnDescription?: boolean;
  matchOnDetail?: boolean;
}

Progress

// Show progress
window.withProgress<T>(
  options: ProgressOptions,
  task: (progress: Progress<{message?: string}>) => Promise<T>
): Promise<T>

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.

// 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<Uint8Array>
workspace.fs.writeFile(uri: Uri, content: Uint8Array): Promise<void>
workspace.fs.delete(uri: Uri): Promise<void>
workspace.fs.rename(oldUri: Uri, newUri: Uri): Promise<void>
workspace.fs.copy(source: Uri, destination: Uri): Promise<void>
workspace.fs.createDirectory(uri: Uri): Promise<void>
workspace.fs.readDirectory(uri: Uri): Promise<[string, FileType][]>
workspace.fs.stat(uri: Uri): Promise<FileStat>

HTTP Client API

Make HTTP requests from extensions.

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.

// 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.

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:

import type {
  ExtensionContext,
  Disposable,
  Event,
  EventEmitter,
  Uri,
  Command,
  QuickPickItem,
  InputBoxOptions,
  Progress,
  CancellationToken
} from '@apache-superset/core';

Version Compatibility

The API follows semantic versioning:

// 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

// 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

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

// 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

// Use type guards
function isDatabase(obj: any): obj is Database {
  return obj && typeof obj.id === 'number' && typeof obj.name === 'string';
}

// Use generics
function getValue<T>(key: string, defaultValue: T): T {
  return context.globalState.get(key) ?? defaultValue;
}