Shared TypeScript library for the Lightdash platform containing common types, utilities, and business logic for analytics workflows
npx @tessl/cli install tessl/npm-lightdash--common@0.2231.0TypeScript library for the Lightdash analytics platform. Core types, utilities, and business logic for dbt-based BI applications with 7 data warehouse integrations.
Package: @lightdash/common | Type: npm | Language: TypeScript
npm install @lightdash/commonimport {
// Query & Data
type MetricQuery, type Explore, type Field,
type Dimension, type Metric, type Filters,
// Compiler & Execution
ExploreCompiler,
// Utilities
getFields, getDimensions, getMetrics,
formatItemValue, getItemMap,
// Authorization
defineUserAbility,
// Visualization
CartesianChartDataModel,
} from '@lightdash/common';For CommonJS:
const {
ExploreCompiler,
getFields,
getDimensions,
getMetrics,
formatItemValue,
getItemMap,
} = require('@lightdash/common');Architecture Context:
import {
type Explore,
type MetricQuery,
FilterOperator,
UnitOfTime,
getFields,
getDimensions,
getMetrics,
formatItemValue,
} from '@lightdash/common';
// Working with explores (data models)
const fields = getFields(explore);
const dimensions = getDimensions(explore);
const metrics = getMetrics(explore);
// Building a metric query
const query: MetricQuery = {
exploreName: 'customers',
dimensions: ['customers.customer_id', 'customers.name'],
metrics: ['customers.total_orders', 'customers.revenue'],
filters: {
dimensions: {
id: 'filter_1',
and: [
{
id: 'rule_1',
target: { fieldId: 'customers.created_at' },
operator: FilterOperator.IN_THE_PAST,
values: [30],
settings: { unitOfTime: UnitOfTime.DAYS },
},
],
},
},
sorts: [{ fieldId: 'customers.revenue', descending: true }],
limit: 100,
tableCalculations: [],
};
// Formatting values
const formattedValue = formatItemValue(field, rawValue);See filters.md for complete FilterRule interface and nested AND/OR groups.
| Operator | Types | Description | Values | Settings |
|---|---|---|---|---|
NULL, NOT_NULL | All | Null checks | None | - |
EQUALS, NOT_EQUALS | All | Exact match | Single value | - |
STARTS_WITH, ENDS_WITH, INCLUDE, NOT_INCLUDE | String | Pattern matching | String | - |
LESS_THAN, GREATER_THAN, LESS_THAN_OR_EQUAL, GREATER_THAN_OR_EQUAL | Number, Date | Comparisons | Single value | - |
IN_BETWEEN, NOT_IN_BETWEEN | Number, Date | Range | [min, max] | - |
IN_THE_PAST, NOT_IN_THE_PAST | Date | Past range | [number] | {unitOfTime: UnitOfTime} |
IN_THE_NEXT | Date | Future range | [number] | {unitOfTime: UnitOfTime} |
IN_THE_CURRENT, NOT_IN_THE_CURRENT | Date | Current period | [number] | {unitOfTime: UnitOfTime, completed?: boolean} |
See explore-fields.md for CompiledDimension interface and field operations.
| Type | Usage | Supported Metrics | SQL Examples |
|---|---|---|---|
STRING | Text data | COUNT, COUNT_DISTINCT, MIN, MAX | customer_name, order_status |
NUMBER | Numeric values | All aggregations | quantity, price, revenue |
TIMESTAMP, DATE | Temporal data | All aggregations + time grouping | created_at, order_date |
BOOLEAN | True/false | COUNT, COUNT_DISTINCT | is_active, has_discount |
See metric-queries.md for AdditionalMetric creation and MetricQuery building.
| Type | Description | Requires Dimension | SQL Function |
|---|---|---|---|
COUNT | Row count | No | COUNT(*) |
COUNT_DISTINCT | Unique values | Yes | COUNT(DISTINCT field) |
SUM | Total | Yes (numeric) | SUM(field) |
AVERAGE | Mean | Yes (numeric) | AVG(field) |
MIN, MAX | Extremes | Yes | MIN/MAX(field) |
PERCENTILE | Nth percentile | Yes (numeric) | PERCENTILE_CONT(field, p) |
MEDIAN | 50th percentile | Yes (numeric) | MEDIAN(field) |
See charts.md for ChartConfig interfaces and visualizations.md for data models.
| ChartKind | Category | Use Case | Data Model |
|---|---|---|---|
LINE, AREA | Cartesian | Trends over time | CartesianChartDataModel |
VERTICAL_BAR, HORIZONTAL_BAR | Cartesian | Category comparison | CartesianChartDataModel |
SCATTER, MIXED | Cartesian | Relationships | CartesianChartDataModel |
PIE | Pie | Part-to-whole | PieChartDataModel |
TABLE | Table | Detailed data | TableChartDataModel |
BIG_NUMBER | Big Number | KPI display | BigNumberDataModel |
FUNNEL | Specialized | Conversion funnel | FunnelChartDataModel |
GAUGE, TREEMAP, MAP | Specialized | Specific analyses | Custom models |
| Topic | Description | File |
|---|---|---|
| Types | Type definitions, interfaces, enums | types.md |
| Metric Queries | Building and executing queries | metric-queries.md |
| Filters | Filter system with AND/OR logic | filters.md |
| Explore & Fields | Working with data models | explore-fields.md |
| Topic | Description | File |
|---|---|---|
| Compiler | DBT model compilation | compiler.md |
| Formatting | Value formatting and display | formatting.md |
| Parameters | SQL parameterization | parameters.md |
| Utilities | Helper functions | utilities.md |
| Topic | Description | File |
|---|---|---|
| Charts | Chart configuration (14 types) | charts.md |
| Visualizations | Data models for rendering | visualizations.md |
| Conditional Formatting | Visual formatting rules | conditional-formatting.md |
| Pivot | Pivot table configuration | pivot.md |
| Topic | Description | File |
|---|---|---|
| Dashboards | Dashboard management | dashboards.md |
| Authorization | CASL-based permissions | authorization.md |
| Templating | URL templating for drilldown | templating.md |
| SQL Runner | Custom SQL queries | sql-runner.md |
| Topic | Description | File |
|---|---|---|
| Warehouse | 7 warehouse types | warehouse.md |
| DBT | DBT integration | dbt.md |
| Projects & Spaces | Organization | projects-spaces.md |
| EE Features | Enterprise capabilities | ee-features.md |
See metric-queries.md for complete MetricQuery interface and filters.md for filter operators.
import { type MetricQuery, FilterOperator, UnitOfTime } from '@lightdash/common';
const query: MetricQuery = {
exploreName: 'orders',
dimensions: ['orders.customer_id', 'orders.created_at_day'], // Use _day/_week/_month for date grouping
metrics: ['orders.count', 'orders.revenue'],
filters: {
dimensions: {
id: 'root',
and: [{
id: 'filter_1',
target: { fieldId: 'orders.created_at' },
operator: FilterOperator.IN_THE_PAST,
values: [30],
settings: { unitOfTime: UnitOfTime.DAYS },
}],
},
},
sorts: [{ fieldId: 'orders.revenue', descending: true }],
limit: 100,
tableCalculations: [], // See metric-queries.md for TableCalculation examples
};See explore-fields.md for field operations and ItemsMap structure.
import { getFields, getDimensions, getMetrics, getItemMap } from '@lightdash/common';
const allFields = getFields(explore); // All dimensions + metrics
const dimensions = getDimensions(explore); // Only dimensions
const metrics = getMetrics(explore); // Only metrics
// ItemsMap: unified structure for all field types (dimensions, metrics, tableCalculations, customDimensions)
const itemsMap = getItemMap(explore, additionalMetrics, tableCalculations, customDimensions);
// Use itemsMap for formatting and renderingSee formatting.md for complete formatting options and custom formats.
import { formatItemValue, formatDate, formatNumberValue, TimeFrames, NumberSeparator } from '@lightdash/common';
// Format with field metadata (handles type-specific formatting)
const formatted = formatItemValue(field, rawValue);
// Format dates with time granularity
const formattedDate = formatDate(date, TimeFrames.DAY); // 2024-01-15
const formattedMonth = formatDate(date, TimeFrames.MONTH); // January 2024
// Format numbers with locale and precision
const formattedNumber = formatNumberValue(1234.56, {
separator: NumberSeparator.COMMA_PERIOD, // 1,234.56
round: 2,
currency: 'USD', // Optional currency formatting
});See dashboards.md for dashboard filters that apply across multiple tiles.
import { type DashboardFilterRule, FilterOperator, UnitOfTime } from '@lightdash/common';
const dashboardFilter: DashboardFilterRule = {
id: 'filter_1',
label: 'Date Range',
target: { fieldId: 'orders.created_at', tableName: 'orders' },
operator: FilterOperator.IN_THE_PAST,
values: [30],
settings: { unitOfTime: UnitOfTime.DAYS },
tileTargets: { // Maps filter to different fields in different tiles
'tile-1': { fieldId: 'orders.created_at', tableName: 'orders' },
'tile-2': { fieldId: 'revenue.date', tableName: 'revenue' },
},
};See charts.md for all 14 chart types and visualizations.md for data model usage.
import {
type SavedChart,
type CartesianChartConfig,
ChartType,
CartesianSeriesType,
CartesianChartKind,
CartesianChartDataModel
} from '@lightdash/common';
// Create chart config
const chartConfig: CartesianChartConfig = {
type: ChartType.CARTESIAN,
config: {
layout: {
xField: 'orders.created_at_day', // Date dimension with grouping
yField: ['orders.count', 'orders.revenue'], // Multiple metrics
},
eChartsConfig: {
series: [
{ type: CartesianSeriesType.LINE, yAxisIndex: 0 }, // Line for first metric
{ type: CartesianSeriesType.BAR, yAxisIndex: 1 }, // Bar for second metric
],
},
},
};
// Use data model for rendering (converts ResultRows to ECharts config)
const dataModel = new CartesianChartDataModel({
resultsRunner, // ResultsRunner with formatted ResultRows
fieldConfig, // Field configurations from itemsMap
type: CartesianChartKind.LINE,
});
// Get ECharts spec
const echartsSpec = dataModel.getEchartsSpec();Explore
├── tables: Record<string, CompiledTable>
│ ├── dimensions: Record<string, CompiledDimension>
│ └── metrics: Record<string, CompiledMetric>
└── joinedTables: CompiledExploreJoin[]
MetricQuery
├── exploreName: string
├── dimensions: FieldId[]
├── metrics: FieldId[]
├── filters: Filters
│ ├── dimensions?: FilterGroup
│ ├── metrics?: FilterGroup
│ └── tableCalculations?: FilterGroup
├── sorts: SortField[]
├── additionalMetrics?: AdditionalMetric[]
├── tableCalculations?: TableCalculation[]
└── customDimensions?: CustomDimension[]
Dashboard
├── tiles: DashboardTile[]
├── filters: DashboardFilters
│ ├── dimensions: DashboardFilterRule[]
│ ├── metrics: DashboardFilterRule[]
│ └── tableCalculations: DashboardFilterRule[]
└── tabs?: DashboardTab[]
SavedChart
├── metricQuery: MetricQuery
├── chartConfig: ChartConfig
├── tableConfig: TableChart
└── pivotConfig?: PivotConfigComplete interfaces for key types. See types.md for all 90+ type modules.
// Filter Rule - See filters.md
interface FilterRule<O = FilterOperator, T = FieldTarget> {
id: string; // Unique identifier
target: T; // {fieldId: string} - field being filtered
operator: O; // FilterOperator enum value
values?: any[]; // Values to filter by (operator-dependent)
settings?: DateFilterSettings; // {unitOfTime?: UnitOfTime, completed?: boolean}
disabled?: boolean; // If true, filter not applied
required?: boolean; // If true, cannot be removed by users
}
// Filter Group - Nested AND/OR
interface FilterGroup {
id: string;
and?: (FilterGroup | FilterRule)[]; // All conditions must match
or?: (FilterGroup | FilterRule)[]; // Any condition must match
}
// Filters - Applied to dimensions, metrics, and table calculations
interface Filters {
dimensions?: FilterGroup;
metrics?: FilterGroup;
tableCalculations?: FilterGroup;
}
// Metric Query - See metric-queries.md
interface MetricQuery {
exploreName: string; // Name of explore to query
dimensions: string[]; // Dimension field IDs (e.g., 'customers.id')
metrics: string[]; // Metric field IDs (e.g., 'orders.count')
filters?: Filters; // Optional filters
sorts: SortField[]; // [{fieldId: string, descending: boolean}]
limit?: number; // Row limit (default: 500)
tableCalculations?: TableCalculation[]; // Calculated fields
additionalMetrics?: AdditionalMetric[]; // Ad-hoc metrics
customDimensions?: CustomDimension[]; // Custom binned/SQL dimensions
timezone?: string; // Timezone for date operations
parameters?: Record<string, unknown>; // SQL parameter values
}
// Compiled Dimension - See explore-fields.md
interface CompiledDimension extends Dimension {
compiledSql: string; // Compiled SQL expression
tablesReferences: string[]; // Tables referenced in SQL
type: DimensionType; // STRING | NUMBER | TIMESTAMP | DATE | BOOLEAN
timeIntervals?: TimeFrames[]; // For date/timestamp: RAW, DAY, WEEK, MONTH, QUARTER, YEAR
}
// Compiled Metric - See explore-fields.md
interface CompiledMetric extends Metric {
compiledSql: string; // Compiled SQL expression
tablesReferences: string[]; // Tables referenced in SQL
type: MetricType; // COUNT | COUNT_DISTINCT | SUM | AVERAGE | MIN | MAX | etc.
}
// Explore - Data model with joins. See explore-fields.md
interface Explore {
name: string; // Explore name (matches DBT model)
label: string; // Display label
tags: string[]; // Tags for organization
baseTable: string; // Base table name
joinedTables: CompiledExploreJoin[]; // Joined tables
tables: Record<string, CompiledTable>; // All tables (base + joined)
targetDatabase: SupportedDbtAdapter; // Warehouse type
warehouse?: WarehouseTypes; // Warehouse connection
ymlPath?: string; // Path to DBT YAML file
}
// Dashboard - See dashboards.md
interface Dashboard {
organizationUuid: string;
projectUuid: string;
uuid: string;
name: string;
description?: string;
updatedAt: Date;
tiles: DashboardTile[]; // Chart, markdown, loom, or SQL tiles
filters: DashboardFilters; // Dashboard-level filters
tabs?: DashboardTab[]; // Optional dashboard tabs
spaceUuid: string; // Parent space
views: number; // View count
firstViewedAt: Date | null;
pinnedListUuid: string | null;
pinnedListOrder: number | null;
}
// Chart Config - See charts.md
type ChartConfig =
| CartesianChartConfig // Line, bar, area, scatter, mixed
| PieChartConfig // Pie chart
| TableChartConfig // Table
| BigNumberConfig // Big number KPI
| FunnelChartConfig // Funnel
| CustomVizConfig; // Custom visualizations
// Saved Chart - See charts.md
interface SavedChart {
uuid: string;
projectUuid: string;
name: string;
description?: string;
tableName: string; // Base table name
metricQuery: MetricQuery; // Query definition
chartConfig: ChartConfig; // Chart configuration
tableConfig: TableChart; // Table view config
pivotConfig?: PivotConfig; // Optional pivot config
updatedAt: Date;
updatedByUser?: LightdashUser;
spaceUuid: string;
dashboardUuid: string | null;
slug: string; // URL-safe identifier
}| Issue | Solution | Reference |
|---|---|---|
| Field ID format mismatch | Use underscore format (orders_total) not dot (orders.total) in MetricQuery dimensions/metrics | filters.md |
| Null/undefined handling in formatItemValue | Returns '∅' for null, '-' for undefined, '' for empty string | formatting.md |
| Missing required MetricQuery fields | Always provide filters, sorts, tableCalculations (can be empty) | metric-queries.md |
| Date dimension grouping | Append suffix: _day, _week, _month to dimension ID for time grouping | explore-fields.md |
| Filter vs MetricFilterRule format | FilterRule uses fieldId (underscore), MetricFilterRule uses fieldRef (dot) | filters.md |
| ItemsMap for formatting | Build with getItemMap() including all additional metrics/calculations | explore-fields.md |
| Limit for "unlimited" results | Use 500 or 5000 as practical limit, or 2147483647 (MAX_SAFE_INTEGER) | metric-queries.md |
import {
type MetricQuery, type AdditionalMetric, FilterOperator,
MetricType, CustomFormatType, UnitOfTime, getItemMap, formatItemValue
} from '@lightdash/common';
// Create ad-hoc metric with filter
const highValueRevenue: AdditionalMetric = {
label: 'High Value Revenue',
type: MetricType.SUM,
table: 'orders',
baseDimensionName: 'total_amount',
filters: [{
id: 'high_val',
target: { fieldRef: 'orders.total_amount' }, // Note: fieldRef not fieldId
operator: FilterOperator.GREATER_THAN,
values: [500],
}],
formatOptions: {
type: CustomFormatType.CURRENCY,
currency: 'USD',
round: 2,
},
};
// Query with nested filters and ad-hoc metrics
const query: MetricQuery = {
exploreName: 'orders',
dimensions: ['orders.customer_id', 'orders.created_at_month'], // Note: _month suffix
metrics: ['orders.count'],
additionalMetrics: [highValueRevenue],
filters: {
dimensions: {
id: 'root',
and: [
{
id: 'date_range',
target: { fieldId: 'orders.created_at' }, // Note: fieldId not fieldRef
operator: FilterOperator.IN_THE_PAST,
values: [90],
settings: { unitOfTime: UnitOfTime.DAYS, completed: true },
},
{
id: 'status',
or: [
{
id: 'completed',
target: { fieldId: 'orders.status' },
operator: FilterOperator.EQUALS,
values: ['completed'],
},
{
id: 'shipped',
target: { fieldId: 'orders.status' },
operator: FilterOperator.EQUALS,
values: ['shipped'],
},
],
},
],
},
},
sorts: [
{ fieldId: 'orders.created_at_month', descending: false },
{ fieldId: highValueRevenue.name || 'high_value_revenue', descending: true },
],
limit: 500,
tableCalculations: [],
timezone: 'America/New_York',
};
// Format results using ItemsMap
const itemsMap = getItemMap(explore, query.additionalMetrics, query.tableCalculations);
results.rows.forEach(row => {
Object.entries(row).forEach(([fieldId, value]) => {
const formatted = formatItemValue(itemsMap[fieldId], value);
console.log(`${fieldId}: ${formatted}`);
});
});Supported types: BigQuery, Snowflake, Redshift, Databricks, PostgreSQL, Trino, ClickHouse