Functions for working with explores (data models) and extracting fields, dimensions, and metrics.
Explores represent data models in Lightdash, containing tables with their dimensions and metrics. These utility functions help you extract, filter, and manipulate fields from explores, build field maps for efficient lookups, and work with items (fields, table calculations, and custom dimensions).
Gets all compiled fields (dimensions and metrics) from an explore.
function getFields(explore: Explore): CompiledField[];Returns an array of all compiled dimensions and metrics from all tables in the explore.
Example:
import { getFields } from '@lightdash/common';
const fields = getFields(explore);
// Returns: [CompiledDimension, CompiledDimension, ..., CompiledMetric, CompiledMetric, ...]
fields.forEach(field => {
console.log(`${field.table}.${field.name}: ${field.label}`);
});Gets all compiled dimensions from an explore.
function getDimensions(explore: Explore): CompiledDimension[];Returns an array of all compiled dimensions from all tables in the explore.
Example:
import { getDimensions, DimensionType } from '@lightdash/common';
const dimensions = getDimensions(explore);
// All dimensions across all tables
const stringDimensions = dimensions.filter(d => d.type === DimensionType.STRING);
const dateDimensions = dimensions.filter(d => d.type === DimensionType.DATE);Gets all compiled metrics from an explore.
function getMetrics(explore: Explore): CompiledMetric[];Returns an array of all compiled metrics from all tables in the explore.
Example:
import { getMetrics, MetricType } from '@lightdash/common';
const metrics = getMetrics(explore);
// All metrics across all tables
const countMetrics = metrics.filter(m => m.type === MetricType.COUNT);
const sumMetrics = metrics.filter(m => m.type === MetricType.SUM);Gets all visible fields (non-hidden dimensions and metrics) from an explore.
function getVisibleFields(explore: Explore): CompiledField[];Returns an array of all fields where hidden is not true.
Example:
import { getVisibleFields } from '@lightdash/common';
const visibleFields = getVisibleFields(explore);
// Only fields that should be shown in the UIFinds a specific field by its field ID within an explore.
function findFieldByIdInExplore(
explore: Explore,
id: FieldId
): Field | undefined;Parameters:
explore: The explore to searchid: Field ID in the format "tableName_fieldName" (note: underscore separator, not dot)Returns the field if found, or undefined if not found.
Note: Field IDs use underscores as separators. If a field name itself contains dots, they are replaced with double underscores. For example, a field customer_id in the customers table has ID customers_customer_id, and a field customer.id would have ID customers_customer__id.
Example:
import { findFieldByIdInExplore } from '@lightdash/common';
const field = findFieldByIdInExplore(explore, 'customers_customer_id'); // Note: underscore format
if (field) {
console.log(`Found: ${field.label}`);
}The ItemsMap type is a record mapping field IDs to all queryable items in an explore.
type ItemsMap = Record<
string,
Field | TableCalculation | CustomDimension | Metric
>;
type Item = ItemsMap[string];An ItemsMap contains all items that can be used in queries and visualizations, including regular fields, table calculations, and custom dimensions. Field IDs serve as keys (e.g., "customers_customer_id") and map to their full definitions.
Example:
import { type ItemsMap, getItemMap } from '@lightdash/common';
const itemsMap: ItemsMap = getItemMap(explore, additionalMetrics, tableCalculations, customDimensions);
// Access a specific item
const revenueMetric = itemsMap['customers_total_revenue'];
if (revenueMetric) {
console.log(`${revenueMetric.label}: ${revenueMetric.table}`);
}
// Iterate through all items
Object.entries(itemsMap).forEach(([fieldId, item]) => {
console.log(`${fieldId}: ${getItemLabel(item)}`);
});Creates a mapping of field IDs to fields (dimensions and metrics).
function getFieldMap(
explore: Explore,
additionalMetrics?: AdditionalMetric[]
): Record<string, CompiledField | AdditionalMetric>;Parameters:
explore: The explore containing fieldsadditionalMetrics: Optional array of additional (ad-hoc) metrics to includeReturns a record mapping field IDs (e.g., "customers_total_revenue") to their field definitions.
Example:
import { getFieldMap, isMetric } from '@lightdash/common';
const fieldMap = getFieldMap(explore, additionalMetrics);
const revenueField = fieldMap['customers_total_revenue'];
if (revenueField && isMetric(revenueField)) {
console.log(`${revenueField.label}: ${revenueField.type}`);
}Creates a comprehensive mapping of all queryable items including fields, table calculations, custom dimensions, and additional metrics.
function getItemMap(
explore: Explore,
additionalMetrics?: AdditionalMetric[],
tableCalculations?: TableCalculation[],
customDimensions?: CustomDimension[]
): ItemsMap;Parameters:
explore: The explore containing fieldsadditionalMetrics: Optional array of additional (ad-hoc) metricstableCalculations: Optional array of table calculationscustomDimensions: Optional array of custom dimensionsReturns an ItemsMap containing all queryable items.
Example:
import { getItemMap, formatItemValue } from '@lightdash/common';
const itemsMap = getItemMap(
explore,
metricQuery.additionalMetrics,
metricQuery.tableCalculations,
metricQuery.customDimensions
);
// Use itemsMap for formatting and rendering
Object.entries(row).forEach(([fieldId, value]) => {
const item = itemsMap[fieldId];
const formatted = formatItemValue(item, value);
console.log(`${fieldId}: ${formatted}`);
});function getDimensionsFromItemsMap(itemsMap: ItemsMap): Record<string, Dimension | CustomDimension>;
function getFilterableDimensionsFromItemsMap(itemsMap: ItemsMap): Record<string, FilterableDimension>;
function getMetricsFromItemsMap(itemsMap: ItemsMap, filter?: (value: ItemsMap[string]) => boolean): Record<string, Metric>;
function getTableCalculationsFromItemsMap(itemsMap?: ItemsMap): Record<string, TableCalculation>;Example:
import {
getDimensionsFromItemsMap,
getMetricsFromItemsMap,
getTableCalculationsFromItemsMap
} from '@lightdash/common';
const dimensions = getDimensionsFromItemsMap(itemsMap);
const metrics = getMetricsFromItemsMap(itemsMap);
const tableCalculations = getTableCalculationsFromItemsMap(itemsMap);function convertFieldRefToFieldId(fieldRef: FieldRef): FieldId;
function getFieldRef(fieldId: FieldId): FieldRef;Converts between field reference format (dot notation) and field ID format (underscore).
Important: Field IDs use underscore separators. If field name contains dots, they become double underscores:
customer_id in table customers → 'customers_customer_id'customer.id in table customers → 'customers_customer__id' (note double underscore)Example:
import { convertFieldRefToFieldId, getFieldRef } from '@lightdash/common';
// Convert fieldRef to fieldId
const fieldId = convertFieldRefToFieldId({ table: 'orders', field: 'total_amount' });
// Returns: 'orders_total_amount'
// Convert fieldId to fieldRef
const fieldRef = getFieldRef('orders_total_amount');
// Returns: { table: 'orders', field: 'total_amount' }
// Edge case: field name with dots
const specialId = convertFieldRefToFieldId({ table: 'customers', field: 'id.value' });
// Returns: 'customers_id__value' (double underscore)function getFieldLabel(field: Field): string;
function getItemId(item: Item): string;
function getItemLabel(item: Item): string;
function getItemLabelWithoutTableName(item: Item): string;Example:
import { getFieldLabel, getItemLabel, getItemId } from '@lightdash/common';
const label = getFieldLabel(field); // Returns field.label
const itemLabel = getItemLabel(item); // Works with Field, TableCalculation, CustomDimension, etc.
const itemId = getItemId(item); // Returns field ID for the itemType guards for runtime type checking.
function isField(value: any): value is Field;
function isDimension(field: Field): field is Dimension;
function isMetric(field: Field): field is Metric;
function isCustomDimension(value: any): value is CustomDimension;
function isTableCalculation(value: any): value is TableCalculation;
function isAdditionalMetric(value: any): value is AdditionalMetric;
function isFilterableField(field: Field): field is FilterableField;Example:
import { isDimension, isMetric, isTableCalculation } from '@lightdash/common';
const item = itemsMap['some_field_id'];
if (isDimension(item)) {
console.log(`Dimension: ${item.type}`);
} else if (isMetric(item)) {
console.log(`Metric: ${item.type}`);
} else if (isTableCalculation(item)) {
console.log(`Table calculation: ${item.displayName}`);
}import { getDimensions, DimensionType } from '@lightdash/common';
// Find all date dimensions
const dateDimensions = getDimensions(explore).filter(d =>
d.type === DimensionType.DATE || d.type === DimensionType.TIMESTAMP
);
// Use with time grouping suffix in queries
const query: MetricQuery = {
exploreName: 'orders',
dimensions: [
'orders.created_at_day', // Daily grouping
'orders.created_at_month', // Monthly grouping
],
metrics: ['orders.count'],
// ... rest of query
};
// Available suffixes: _raw, _day, _week, _month, _quarter, _year
// Note: _raw returns timestamp without groupingimport { getItemMap, itemsInMetricQuery } from '@lightdash/common';
function validateQueryFields(query: MetricQuery, explore: Explore): string[] {
// Build complete items map
const itemsMap = getItemMap(
explore,
query.additionalMetrics,
query.tableCalculations,
query.customDimensions
);
// Get all field IDs referenced in query
const referencedFields = itemsInMetricQuery(query);
// Find missing fields
const missingFields = referencedFields.filter(fieldId => !itemsMap[fieldId]);
return missingFields;
}
// Usage
const missing = validateQueryFields(metricQuery, explore);
if (missing.length > 0) {
console.error(`Missing fields: ${missing.join(', ')}`);
}import { getFields, isFilterableField, isNumericItem } from '@lightdash/common';
// Get all numeric, filterable fields
const numericFilterableFields = getFields(explore).filter(field =>
isFilterableField(field) && isNumericItem(field)
);
// Get all visible dimensions
const visibleDimensions = getDimensions(explore).filter(d => !d.hidden);
// Get metrics with specific type
const countMetrics = getMetrics(explore).filter(m => m.type === MetricType.COUNT);| Scenario | Behavior | Solution |
|---|---|---|
| Field name contains dots | Dots replaced with double underscores in field ID | customer.id → customers_customer__id |
| Field not found in explore | findFieldByIdInExplore returns undefined | Always check for undefined before using |
| Hidden fields in getFields | Included in results | Use getVisibleFields() to exclude hidden fields |
| Empty ItemsMap | No validation errors, but formatting will fail | Always populate with getItemMap before formatting |
| Missing additional metrics in ItemsMap | Format functions can't find field definitions | Include additionalMetrics param in getItemMap() |
| Table calculations not in ItemsMap | Won't be accessible for formatting | Include tableCalculations param in getItemMap() |