UNPKG

drizzle-cube

Version:

Drizzle ORM-first semantic layer with Cube.js compatibility. Type-safe analytics and dashboards with SQL injection protection.

266 lines (265 loc) 8.2 kB
import { ReactNode } from 'react'; import { ColorPalette } from './utils/colorPalettes'; export type { CubeMeta, CubeMetaCube, CubeMetaField, CubeMetaRelationship, FieldLabelMap } from './hooks/useCubeMeta'; export type { ColorPalette } from './utils/colorPalettes'; export type ChartType = 'line' | 'bar' | 'pie' | 'table' | 'area' | 'scatter' | 'radar' | 'radialBar' | 'treemap' | 'bubble' | 'activityGrid' | 'kpiNumber' | 'kpiDelta' | 'kpiText' | 'markdown'; export interface AxisFormatConfig { label?: string; unit?: 'currency' | 'percent' | 'number' | 'custom'; abbreviate?: boolean; decimals?: number; customPrefix?: string; customSuffix?: string; } export interface ChartAxisConfig { xAxis?: string[]; yAxis?: string[]; series?: string[]; sizeField?: string; colorField?: string; dateField?: string[]; valueField?: string[]; x?: string; y?: string[]; yAxisAssignment?: Record<string, 'left' | 'right'>; } export interface ChartDisplayConfig { showLegend?: boolean; showGrid?: boolean; showTooltip?: boolean; colors?: string[]; orientation?: 'horizontal' | 'vertical'; stacked?: boolean; stackType?: 'none' | 'normal' | 'percent'; connectNulls?: boolean; hideHeader?: boolean; minBubbleSize?: number; maxBubbleSize?: number; bubbleOpacity?: number; showLabels?: boolean; fitToWidth?: boolean; pivotTimeDimension?: boolean; target?: string; template?: string; prefix?: string; suffix?: string; decimals?: number; formatValue?: (value: number | null | undefined) => string; valueColor?: string; valueColorIndex?: number; positiveColorIndex?: number; negativeColorIndex?: number; showHistogram?: boolean; useLastCompletePeriod?: boolean; skipLastPeriod?: boolean; content?: string; accentColorIndex?: number; fontSize?: 'small' | 'medium' | 'large'; alignment?: 'left' | 'center' | 'right'; xAxisFormat?: AxisFormatConfig; leftYAxisFormat?: AxisFormatConfig; rightYAxisFormat?: AxisFormatConfig; /** * How to display compared periods: * - 'separate': Each period as distinct series with different colors (default) * - 'overlay': Periods aligned by day-of-period index with ghost styling for prior periods */ comparisonMode?: 'separate' | 'overlay'; /** Line style for prior periods in overlay mode */ priorPeriodStyle?: 'solid' | 'dashed' | 'dotted'; /** Opacity for prior period lines (0-1), default: 0.5 */ priorPeriodOpacity?: number; /** Include period labels in legend */ showPeriodLabels?: boolean; } export interface PortletConfig { id: string; title: string; query: string; chartType: ChartType; chartConfig?: ChartAxisConfig; displayConfig?: ChartDisplayConfig; dashboardFilterMapping?: string[]; eagerLoad?: boolean; w: number; h: number; x: number; y: number; } export type DashboardLayoutMode = 'grid' | 'rows'; export interface DashboardGridSettings { cols: number; rowHeight: number; minW: number; minH: number; } export interface RowLayoutColumn { portletId: string; w: number; } export interface RowLayout { id: string; h: number; columns: RowLayoutColumn[]; } export interface DashboardConfig { portlets: PortletConfig[]; layoutMode?: DashboardLayoutMode; grid?: DashboardGridSettings; rows?: RowLayout[]; layouts?: { [key: string]: any; }; colorPalette?: string; filters?: DashboardFilter[]; eagerLoad?: boolean; } export type FilterOperator = 'equals' | 'notEquals' | 'contains' | 'notContains' | 'startsWith' | 'notStartsWith' | 'endsWith' | 'notEndsWith' | 'like' | 'notLike' | 'ilike' | 'gt' | 'gte' | 'lt' | 'lte' | 'between' | 'notBetween' | 'in' | 'notIn' | 'arrayContains' | 'arrayOverlaps' | 'arrayContained' | 'set' | 'notSet' | 'isEmpty' | 'isNotEmpty' | 'inDateRange' | 'beforeDate' | 'afterDate' | 'regex' | 'notRegex'; export interface SimpleFilter { member: string; operator: FilterOperator; values: any[]; dateRange?: string | string[]; } export interface GroupFilter { type: 'and' | 'or'; filters: Filter[]; } export type Filter = SimpleFilter | GroupFilter; export interface DashboardFilter { id: string; label: string; filter: Filter; isUniversalTime?: boolean; } export interface CubeQuery { measures?: string[]; dimensions?: string[]; timeDimensions?: Array<{ dimension: string; granularity?: string; dateRange?: string[] | string; fillMissingDates?: boolean; /** * Array of date ranges for period-over-period comparison. * When specified, queries are executed for each period and results are merged. */ compareDateRange?: (string | [string, string])[]; }>; filters?: Filter[]; order?: { [key: string]: 'asc' | 'desc'; }; limit?: number; offset?: number; segments?: string[]; } /** * Merge strategy for combining multiple query results * - 'concat': Append rows with __queryIndex marker (for separate series per query) * - 'merge': Align data by common dimension key (for combined visualization) */ export type QueryMergeStrategy = 'concat' | 'merge'; /** * Configuration for multi-query portlets * Detected by presence of 'queries' array property */ export interface MultiQueryConfig { queries: CubeQuery[]; mergeStrategy: QueryMergeStrategy; mergeKeys?: string[]; queryLabels?: string[]; } /** * Type guard to detect multi-query configuration */ export declare function isMultiQueryConfig(obj: unknown): obj is MultiQueryConfig; export interface CubeQueryOptions { skip?: boolean; resetResultSetOnChange?: boolean; subscribe?: boolean; } export interface CubeApiOptions { apiUrl?: string; token?: string; headers?: Record<string, string>; credentials?: 'include' | 'omit' | 'same-origin'; } export interface CubeResultSet { rawData(): any[]; tablePivot(): any[]; series(): any[]; annotation(): any; loadResponse?: any; cacheInfo?(): { hit: true; cachedAt: string; ttlMs: number; ttlRemainingMs: number; } | undefined; } export interface AnalyticsPortletProps { query: string; chartType: ChartType; chartConfig?: ChartAxisConfig; displayConfig?: ChartDisplayConfig; dashboardFilters?: DashboardFilter[]; dashboardFilterMapping?: string[]; eagerLoad?: boolean; isVisible?: boolean; height?: string | number; title?: string; colorPalette?: ColorPalette; loadingComponent?: ReactNode; onDebugDataReady?: (debugData: { chartConfig: ChartAxisConfig; displayConfig: ChartDisplayConfig; queryObject: any; data: any[]; chartType: ChartType; cacheInfo?: { hit: true; cachedAt: string; ttlMs: number; ttlRemainingMs: number; }; }) => void; } export interface AnalyticsDashboardProps { config: DashboardConfig; editable?: boolean; dashboardFilters?: DashboardFilter[]; loadingComponent?: ReactNode; onConfigChange?: (config: DashboardConfig) => void; onSave?: (config: DashboardConfig) => Promise<void> | void; onDirtyStateChange?: (isDirty: boolean) => void; } export interface ChartProps { data: any[]; chartConfig?: ChartAxisConfig; displayConfig?: ChartDisplayConfig; queryObject?: CubeQuery; height?: string | number; colorPalette?: ColorPalette; } export interface FeaturesConfig { enableAI?: boolean; aiEndpoint?: string; showSchemaDiagram?: boolean; useAnalysisBuilder?: boolean; editToolbar?: 'floating' | 'top' | 'both'; floatingToolbarPosition?: 'left' | 'right'; } export interface GridLayout { i: string; x: number; y: number; w: number; h: number; minW?: number; minH?: number; } export interface ResponsiveLayout { [breakpoint: string]: GridLayout[]; } export type DashboardDisplayMode = 'desktop' | 'scaled' | 'mobile';