drizzle-cube
Version:
Drizzle ORM-first semantic layer with Cube.js compatibility. Type-safe analytics and dashboards with SQL injection protection.
204 lines (203 loc) • 9.33 kB
TypeScript
import { ColorPalette } from '../utils/colorPalettes';
import { CubeQuery, MultiQueryConfig, ChartType, ChartAxisConfig, ChartDisplayConfig, Filter, QueryMergeStrategy, FunnelBindingKey, AnalysisType, FunnelStepState } from '../types';
import { AnalysisBuilderState, MetricItem, BreakdownItem, ExecutionStatus, QueryPanelTab } from '../components/AnalysisBuilder/types';
import { ChartAvailabilityMap } from '../shared/chartDefaults';
import { DebugDataEntry } from './queries';
import { MultiQueryValidationResult } from '../utils/multiQueryValidation';
import { MetaField } from '../shared/types';
import { ValidationResult } from '../adapters/modeAdapter';
export interface UseAnalysisBuilderOptions {
/** External color palette (overrides local) */
externalColorPalette?: string[] | ColorPalette;
/** Initial data (skip first fetch) */
initialData?: unknown[];
/** Callback when query changes */
onQueryChange?: (query: CubeQuery) => void;
/** Callback when chart config changes */
onChartConfigChange?: (config: {
chartType: ChartType;
chartConfig: ChartAxisConfig;
displayConfig: ChartDisplayConfig;
}) => void;
}
export interface UseAnalysisBuilderResult {
queryState: AnalysisBuilderState;
queryStates: AnalysisBuilderState[];
activeQueryIndex: number;
mergeStrategy: QueryMergeStrategy;
isMultiQueryMode: boolean;
mergeKeys: string[] | undefined;
currentQuery: CubeQuery;
allQueries: CubeQuery[];
multiQueryConfig: MultiQueryConfig | null;
multiQueryValidation: MultiQueryValidationResult | null;
funnelBindingKey: FunnelBindingKey | null;
/** Whether funnel mode is properly configured and ready for execution */
isFunnelModeEnabled: boolean;
/** Current analysis type (query, multi, funnel) */
analysisType: AnalysisType;
/** Selected cube for funnel mode (all steps use this cube) */
funnelCube: string | null;
/** Dedicated funnel steps (when analysisType === 'funnel') */
funnelSteps: FunnelStepState[];
/** Index of currently active funnel step */
activeFunnelStepIndex: number;
/** Time dimension for funnel temporal ordering */
funnelTimeDimension: string | null;
/** Chart type for funnel mode (separate from query mode) */
funnelChartType: ChartType;
/** Chart config for funnel mode (separate from query mode) */
funnelChartConfig: ChartAxisConfig;
/** Display config for funnel mode (separate from query mode) */
funnelDisplayConfig: ChartDisplayConfig;
/** Selected cube for flow mode */
flowCube: string | null;
/** Binding key for flow mode (entity linking) */
flowBindingKey: FunnelBindingKey | null;
/** Time dimension for flow mode (event ordering) */
flowTimeDimension: string | null;
/** Event dimension for flow mode (node labels in Sankey) */
eventDimension: string | null;
/** Starting step configuration */
startingStep: import('../types/flow').FlowStartingStep;
/** Number of steps to explore before starting step */
stepsBefore: number;
/** Number of steps to explore after starting step */
stepsAfter: number;
/** Join strategy for flow execution */
joinStrategy: 'auto' | 'lateral' | 'window';
/** Display config for flow mode */
flowDisplayConfig: ChartDisplayConfig;
executionStatus: ExecutionStatus;
executionResults: unknown[] | null;
perQueryResults: (unknown[] | null)[] | null;
isLoading: boolean;
isFetching: boolean;
error: Error | null;
isValidQuery: boolean;
debugDataPerQuery: DebugDataEntry[];
/** In funnel mode, the actually executed queries with binding key dimension and IN filters */
funnelExecutedQueries: CubeQuery[] | null;
/** In funnel mode, the actual server query { funnel: {...} } sent to the API */
funnelServerQuery: unknown | null;
/** In funnel mode, unified debug data (SQL, analysis, funnel metadata) */
funnelDebugData: {
sql: {
sql: string;
params: unknown[];
} | null;
analysis: unknown | null;
loading: boolean;
error: Error | null;
funnelMetadata?: unknown;
} | null;
/** In flow mode, the actual server query { flow: {...} } sent to the API */
flowServerQuery: unknown | null;
/** In flow mode, unified debug data (SQL, analysis, flow metadata) */
flowDebugData: {
sql: {
sql: string;
params: unknown[];
} | null;
analysis: unknown | null;
loading: boolean;
error: Error | null;
flowMetadata?: unknown;
} | null;
chartType: ChartType;
chartConfig: ChartAxisConfig;
displayConfig: ChartDisplayConfig;
colorPalette: ColorPalette;
localPaletteName: string;
chartAvailability: ChartAvailabilityMap;
combinedMetrics: MetricItem[];
combinedBreakdowns: BreakdownItem[];
effectiveBreakdowns: BreakdownItem[];
activeTab: QueryPanelTab;
activeView: 'table' | 'chart';
displayLimit: number;
showFieldModal: boolean;
fieldModalMode: 'metrics' | 'breakdown';
activeTableIndex: number;
userManuallySelectedChart: boolean;
aiState: {
isOpen: boolean;
userPrompt: string;
isGenerating: boolean;
error: string | null;
hasGeneratedQuery: boolean;
};
shareButtonState: 'idle' | 'copied' | 'copied-no-chart';
canShare: boolean;
/** Validation result from the adapter for the current analysis type */
adapterValidation: ValidationResult;
actions: {
setActiveQueryIndex: (index: number) => void;
setMergeStrategy: (strategy: QueryMergeStrategy) => void;
openMetricsModal: () => void;
addMetric: (field: string, label?: string) => void;
removeMetric: (id: string) => void;
toggleMetric: (fieldName: string) => void;
reorderMetrics: (fromIndex: number, toIndex: number) => void;
openBreakdownsModal: () => void;
addBreakdown: (field: string, isTimeDimension: boolean, granularity?: string) => void;
removeBreakdown: (id: string) => void;
toggleBreakdown: (fieldName: string, isTimeDimension: boolean, granularity?: string) => void;
setBreakdownGranularity: (id: string, granularity: string) => void;
toggleBreakdownComparison: (id: string) => void;
reorderBreakdowns: (fromIndex: number, toIndex: number) => void;
setFilters: (filters: Filter[]) => void;
dropFieldToFilter: (field: string) => void;
setOrder: (fieldName: string, direction: 'asc' | 'desc' | null) => void;
addQuery: () => void;
removeQuery: (index: number) => void;
setFunnelBindingKey: (bindingKey: FunnelBindingKey | null) => void;
setAnalysisType: (type: AnalysisType) => void;
setFunnelCube: (cube: string | null) => void;
addFunnelStep: () => void;
removeFunnelStep: (index: number) => void;
updateFunnelStep: (index: number, updates: Partial<FunnelStepState>) => void;
setActiveFunnelStepIndex: (index: number) => void;
reorderFunnelSteps: (fromIndex: number, toIndex: number) => void;
setFunnelTimeDimension: (dimension: string | null) => void;
setFunnelDisplayConfig: (config: ChartDisplayConfig) => void;
setFlowCube: (cube: string | null) => void;
setFlowBindingKey: (key: FunnelBindingKey | null) => void;
setFlowTimeDimension: (dim: string | null) => void;
setEventDimension: (dim: string | null) => void;
setStartingStepName: (name: string) => void;
setStartingStepFilters: (filters: Filter[]) => void;
setStepsBefore: (count: number) => void;
setStepsAfter: (count: number) => void;
setJoinStrategy: (strategy: 'auto' | 'lateral' | 'window') => void;
setFlowDisplayConfig: (config: ChartDisplayConfig) => void;
setChartType: (type: ChartType) => void;
setChartConfig: (config: ChartAxisConfig) => void;
setDisplayConfig: (config: ChartDisplayConfig) => void;
setLocalPaletteName: (name: string) => void;
setActiveTab: (tab: QueryPanelTab) => void;
setActiveView: (view: 'table' | 'chart') => void;
setDisplayLimit: (limit: number) => void;
closeFieldModal: () => void;
setActiveTableIndex: (index: number) => void;
openAI: () => void;
closeAI: () => void;
setAIPrompt: (prompt: string) => void;
generateAI: () => Promise<void>;
acceptAI: () => void;
cancelAI: () => void;
share: () => Promise<void>;
clearQuery: () => void;
clearCurrentMode: () => void;
refetch: () => void;
handleFieldSelected: (field: MetaField, fieldType: 'measure' | 'dimension' | 'timeDimension', cubeName: string, keepOpen?: boolean) => void;
};
getQueryConfig: () => CubeQuery | MultiQueryConfig | import('../types/funnel').ServerFunnelQuery;
getChartConfig: () => {
chartType: ChartType;
chartConfig: ChartAxisConfig;
displayConfig: ChartDisplayConfig;
};
getAnalysisType: () => AnalysisType;
}
export declare function useAnalysisBuilder(options?: UseAnalysisBuilderOptions): UseAnalysisBuilderResult;