or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

api

features

charts

charts.mdconditional-formatting.mdvisualizations.md
authorization.mdchangesets.mdcharts-as-code.mdcompiler.mddashboards.mddbt.mdee-features.mdformatting.mdparameters.mdpivot.mdprojects-spaces.mdsql-runner.mdtemplating.mdwarehouse.md
index.md
tile.json

getting-started-full.mddocs/reference/

Getting Started

This guide provides a comprehensive introduction to @lightdash/common, a TypeScript library for building dbt-based BI applications. It covers common patterns, essential workflows, and best practices to help you get started quickly.

API Quick Reference

Note: The Quick Reference below shows abbreviated function signatures for easy scanning. For complete parameter descriptions, type details, and usage examples, refer to the detailed documentation linked in the Reference Documentation section.

Core Exports by Category

// === DATA MODELING TYPES ===
type Explore, CompiledTable, ExploreType, SummaryExplore, ExploreError
type Field, Dimension, Metric, CompiledDimension, CompiledMetric, CompiledField
type DimensionType, MetricType, FieldType, FieldId, FieldUrl
type Table, LineageGraph, Set
type CustomDimension, AdditionalMetric, TableCalculation
type ItemsMap, Item, FilterableItem
type ArgumentsOf<F> (Utility type extracting function arguments)

// === QUERY TYPES ===
type MetricQuery, MetricQueryRequest, CompiledMetricQuery
type Filters, FilterGroup, FilterRule, FilterGroupItem, MetricFilterRule
FilterOperator (19 operators: equals, greaterThan, inThePast, etc.)
type SortField, FieldValueSearchResult
type DateZoom

// === CORE API TYPES ===
type UUID, Email, ApiSuccess<T>, ApiSuccessEmpty
type ApiSort, ApiSortDirection

// === DASHBOARD & CHART TYPES ===
type Dashboard, DashboardTile, DashboardFilters, DashboardTab
type SavedChart, ChartConfig, ChartType, ChartKind
type CartesianChartConfig, PieChartConfig, TableChartConfig
type PivotConfig, PivotData, ConditionalFormattingConfig

// === WAREHOUSE TYPES ===
type WarehouseClient, WarehouseCredentials, WarehouseResults, WarehouseCatalog
WarehouseTypes (bigquery, postgres, snowflake, redshift, databricks, trino, clickhouse)
type Project, ProjectType, DbtProjectConfig

// === USER & AUTH TYPES ===
type LightdashUser, SessionUser, UserProfile, SerializedAccount
type Role, Group, ProjectMemberProfile, OrganizationMemberProfile
type PersonalAccessToken, OpenIdIdentity, LightdashOAuthToken
type ApiGetAccountResponse
type CompleteUserArgs
const CompleteUserSchema (Zod schema for user completion)

// === BACKGROUND JOBS ===
type Job, CompileJob, CreateProjectJob, JobStep, DbtLog
enum JobType, JobStatusType, JobStepStatusType, JobStepType
isCompileJob(value): value is CompileJob
isCreateProjectJob(value): value is CreateProjectJob

// === FEATURE FLAGS ===
enum FeatureFlags (UserGroupsEnabled, DashboardComments, AiCustomViz, Maps, DarkMode, etc.)
type FeatureFlag
isFeatureFlags(value): value is FeatureFlags

// === QUERY HISTORY ===
type QueryHistory, WarehouseQueryMetadata, BigQueryWarehouseQueryMetadata
enum QueryHistoryStatus (pending, ready, error, cancelled)

// === TAGS ===
type Tag, ApiGetTagsResponse, ApiCreateTagResponse

// === CONTENT PROMOTION ===
type PromotionChanges, PromotedSpace, PromotedDashboard, PromotedChart
enum PromotionAction (no changes, create, update, delete)

// === COMPILER & DBT ===
class ExploreCompiler { compileExplore(explore): Explore }
type UncompiledExplore, DbtManifestVersion, DbtModelNode, DbtMetric

// === FIELD & EXPLORE UTILITIES ===
getFields(explore): CompiledField[]
getDimensions(explore): CompiledDimension[]
getMetrics(explore): CompiledMetric[]
getVisibleFields(explore): CompiledField[]
findFieldByIdInExplore(explore, id): Field | undefined
getFieldMap(explore, additionalMetrics = []): Record<string, Field>
getItemMap(explore, additionalMetrics = [], tableCalculations = [], customDimensions = []): ItemsMap
getDimensionsFromItemsMap(itemsMap): Record<string, Dimension>
getFilterableDimensionsFromItemsMap(itemsMap): Record<string, FilterableDimension>
getMetricsFromItemsMap(itemsMap, filter?): Record<string, Metric>
getTableCalculationsFromItemsMap(itemsMap?): Record<string, TableCalculation>

// === FORMATTING UTILITIES ===
formatItemValue(item, value, convertToUTC?, parameters?): string
formatDate(date, timeInterval?, convertToUTC?): string
formatTimestamp(value, timeInterval?, convertToUTC?): string
formatNumberValue(value, format?): string
applyCustomFormat(item, value, customFormat): string
formatRawValue(field, value): unknown  // Format raw value with UTC timezone handling
formatRawRows(rows, itemsMap): Record<string, unknown>[]  // Format multiple raw rows
friendlyName(text): string
capitalize(word): string
isHexCodeColor(color): boolean
getInvalidHexColors(colors): string[]
cleanColorArray(colors): string[]
getReadableTextColor(backgroundColor): 'white' | 'black'

// === QUERY UTILITIES ===
itemsInMetricQuery(metricQuery): string[]
formatRows(rows, itemsMap, pivotValuesColumns?, parameters?): ResultRow[]
getResultValueArray(rows, preferRaw?, calculateMinAndMax?, excludeNulls?): { results, minsAndMaxes? }
getDateGroupLabel(axisItem): string | undefined  // Get label for date-grouped dimensions
getAxisName({...}): string | undefined  // Determine axis name for chart configuration

// === AUTHORIZATION ===
defineUserAbility(user, projectProfiles, customRoleScopes?): MemberAbility
getUserAbilityBuilder(args): AbilityBuilder<MemberAbility>
getScopes(options?): Scope[]

// === VISUALIZATION DATA MODELS ===
class CartesianChartDataModel { getChartOptions(), getPivotedChartData(), getTransformedData() }
class PieChartDataModel { constructor(args) }
class TableDataModel { constructor(args) }

// === VALIDATION UTILITIES ===
validateEmail(email): boolean
validatePassword(password): boolean
getEmailSchema(): ZodSchema  // Returns Zod schema for email validation
getPasswordSchema(): ZodSchema  // Returns Zod schema for password validation
isExploreError(explore): explore is ExploreError
isField(item): item is Field
isDimension(item): item is Dimension
isMetric(item): item is Metric
isCustomDimension(item): item is CustomDimension
isTableCalculation(item): item is TableCalculation

// === DATA UTILITIES ===
hasIntersection(arr1, arr2): boolean
toggleArrayValue(array, value): T[]
replaceStringInArray(array, valueToReplace, newValue): string[]
removeEmptyProperties(obj): Record<string, unknown>
deepEqual(obj1, obj2): boolean
getItemId(item): string
getItemLabel(item): string
snakeCaseName(text): string
hasSpecialCharacters(text): boolean
hexToRGB(hex, alpha: number | undefined): string
isNotNull<T>(arg): arg is Exclude<T, null>
getProjectDirectory(dbtConnection?): string | undefined

// === FILTER UTILITIES ===
isFilterGroup(item): item is FilterGroup

// === SQL RUNNER TYPES ===
type SqlRunnerQuery, SqlRunnerField, SqlRunnerTimeDimension
type SqlChart, SqlRunnerFilter, SqlRunnerPivot
type SqlResultsRow, SqlResultsField, SqlQueryResults

// === SPACE & CONTENT TYPES ===
type Space, SpaceDashboard, SpaceQuery, SpaceShare
type ContentType, Content, ContentAction
type TreeCreateSpace (Hierarchical space structure with children)

// === PARAMETER SYSTEM ===
type ParameterValue, ParametersValuesMap, LightdashProjectParameter
getParameterReferences(sql): string[]
validateParameterReferences(tableName, refs, available): void
getAvailableParameterNames(projectParams, exploreParams): string[]

// === CONDITIONAL FORMATTING ===
type ConditionalFormattingConfig, ConditionalFormattingColorRange
createConditionalFormattingConfigWithSingleColor(color, target?): Config
createConditionalFormattingConfigWithColorRange(color, target?): Config

// === PIVOT TABLES ===
getPivotConfig(savedChart): PivotConfig | undefined
pivotQueryResults(args): PivotData
derivePivotConfigurationFromChart(chart, query, itemsMap): PivotConfiguration | undefined

// === CHARTS-AS-CODE ===
type ChartAsCode, DashboardAsCode, DashboardTileAsCode

// === CHANGESETS ===
type Changeset, Change, ChangePayload

// === ENTERPRISE EDITION (EE) ===
type AiAgent, AiConversation, AiPrompt, AiAgentTool
type EmbedJwt, EmbedContent, FilterInteractivityValues
enum CommercialFeatureFlags (Embedding, Scim, AiCopilot, ServiceAccounts, OrganizationWarehouseCredentials, AgentReasoning)
type ScimUser, ScimGroup, ServiceAccount

// === CONSTANTS ===
UnitOfTime, TimeFrames, Format, Compact
JWT_HEADER_NAME, LightdashParameters, OrderFieldsByStrategy
enum LightdashInstallType (DOCKER_IMAGE, BASH_INSTALL, HEROKU, UNKNOWN)

// === JSON SCHEMAS ===
chartAsCodeSchema, dashboardAsCodeSchema, modelAsCodeSchema
lightdashDbtYamlSchema, lightdashProjectConfigSchema

// === TEST SEED DATA ===
SEED_ORG_1, SEED_ORG_2, SEED_PROJECT, SEED_SPACE, SEED_GROUP, SEED_GROUP_2, SEED_EMBED_SECRET
SEED_ORG_1_ADMIN, SEED_ORG_1_EDITOR, SEED_ORG_1_VIEWER, SEED_ORG_2_ADMIN
SPACE_TREE_1, SPACE_TREE_2 (Hierarchical space structures for testing)

// === TIMEZONE ===
enum TimeZone (29 timezones: UTC, America/New_York, Europe/London, Asia/Tokyo, etc.)
isTimeZone(timezone): timezone is TimeZone

// === SLACK INTEGRATION ===
type SlackSettings (OAuth scopes, channels, AI features, notification settings)

// === EMAIL VERIFICATION ===
type EmailStatus, EmailStatusExpiring, ApiEmailStatusResponse

// === CSV DOWNLOADS ===
type DownloadMetricCsv (CSV export configuration with formatting options)

Common Import Patterns

// Pattern 1: Query Building
import {
  type MetricQuery,
  type Explore,
  FilterOperator,
  UnitOfTime,
  getFields,
  getDimensions,
  getMetrics,
} from "@lightdash/common";

// Pattern 2: Dashboard & Charts
import {
  type Dashboard,
  type SavedChart,
  ChartKind,
  type ChartConfig,
  type DashboardTile,
} from "@lightdash/common";

// Pattern 3: Data Formatting
import {
  formatItemValue,
  formatDate,
  formatTimestamp,
  formatNumberValue,
  type CustomFormat,
} from "@lightdash/common";

// Pattern 4: Authorization
import {
  defineUserAbility,
  type LightdashUser,
  type ProjectMemberProfile,
  type MemberAbility,
} from "@lightdash/common";

// Pattern 5: Compilation
import { ExploreCompiler, type UncompiledExplore, type Explore } from "@lightdash/common";

// Pattern 6: Warehouse Integration
import {
  type WarehouseClient,
  WarehouseTypes,
  type WarehouseCredentials,
  type Project,
} from "@lightdash/common";

// Pattern 7: Visualization
import {
  CartesianChartDataModel,
  PieChartDataModel,
  ChartKind,
  type VizCartesianChartOptions,
} from "@lightdash/common";

// Pattern 8: Filtering
import {
  type Filters,
  type FilterGroup,
  type FilterRule,
  FilterOperator,
  isFilterGroup,
} from "@lightdash/common";

// Pattern 9: Field Operations
import {
  getItemMap,
  getFieldMap,
  findFieldByIdInExplore,
  getItemId,
  type ItemsMap,
} from "@lightdash/common";

// Pattern 10: Validation & Type Guards
import { validateEmail, validatePassword, isDimension, isMetric, isField } from "@lightdash/common";

Core Imports

// === TYPES ===
import {
  // Data Modeling
  type Explore,
  type MetricQuery,
  type Field,
  type Dimension,
  type Metric,
  type CompiledField,
  type CompiledDimension,
  type CompiledMetric,
  type Table,
  type CompiledTable,

  // Filtering
  type Filters,
  type FilterGroup,
  type FilterRule,
  FilterOperator,

  // Dashboards & Charts
  type Dashboard,
  type SavedChart,
  type ChartConfig,
  ChartKind,

  // Warehouses
  type WarehouseClient,
  type WarehouseCredentials,
  WarehouseTypes,

  // Projects
  type Project,
  type Space,
  ProjectType,
} from "@lightdash/common";

// === COMPILER ===
import { ExploreCompiler } from "@lightdash/common";

// === UTILITIES ===
import {
  // Explore/Field Operations
  getFields,
  getDimensions,
  getMetrics,
  getVisibleFields,
  findFieldByIdInExplore,
  getFieldMap,
  getItemMap,

  // Formatting
  formatItemValue,
  formatDate,
  formatTimestamp,
  formatNumberValue,

  // Validation
  validateEmail,
  validatePassword,
  validateOrganizationName,

  // JSON Schemas
  chartAsCodeSchema,
  dashboardAsCodeSchema,
  lightdashDbtYamlSchema,
  lightdashProjectConfigSchema,
  modelAsCodeSchema,

  // Authorization
  defineUserAbility,

  // Visualization
  CartesianChartDataModel,
  PieChartDataModel,
  TableDataModel,
} from "@lightdash/common";

CommonJS Imports

For CommonJS environments (Node.js with require):

// Note: TypeScript type imports are not available in CommonJS
// Use JSDoc comments for type hints if needed

const {
  // Compiler
  ExploreCompiler,

  // Utilities
  getFields,
  getDimensions,
  getMetrics,
  formatItemValue,
  validateEmail,
  defineUserAbility,

  // Data Models
  CartesianChartDataModel,
  PieChartDataModel,
  TableDataModel,

  // Enums
  FilterOperator,
  WarehouseTypes,
  ChartKind,

  // JSON Schemas
  chartAsCodeSchema,
  dashboardAsCodeSchema,

  // Constants
  JWT_HEADER_NAME,
} = require("@lightdash/common");

Note: Type definitions are only available when using TypeScript or ESM imports. In CommonJS, types must be specified through JSDoc comments or TypeScript declaration files.

Common Workflows

Workflow 1: Building and Executing a Query

import {
  type Explore,
  type MetricQuery,
  FilterOperator,
  getFields,
  getDimensions,
  getMetrics,
} from '@lightdash/common';

// 1. Inspect available fields
const explore: Explore = /* ... */;
const allFields = getFields(explore);
const dimensions = getDimensions(explore);
const metrics = getMetrics(explore);

console.log(`Available: ${dimensions.length} dimensions, ${metrics.length} metrics`);

// 2. Build query
const query: MetricQuery = {
  exploreName: explore.name,
  dimensions: dimensions.slice(0, 2).map(d => d.name), // Select first 2 dimensions
  metrics: metrics.slice(0, 3).map(m => m.name),       // Select first 3 metrics
  filters: {
    dimensions: {
      id: 'root',
      and: [
        {
          id: 'date_filter',
          target: { fieldId: 'orders.created_date' },
          operator: FilterOperator.IN_THE_PAST,
          values: [7],
          settings: { unitOfTime: 'days' },
        },
      ],
    },
  },
  sorts: [{ fieldId: metrics[0].name, descending: true }],
  limit: 100,
  tableCalculations: [],
};

// 3. Execute query (requires warehouse client)
// See warehouse.md for execution details

Workflow 2: Creating a Dashboard with Charts

import {
  type Dashboard,
  type DashboardTile,
  type SavedChart,
  ChartKind,
  type MetricQuery,
} from "@lightdash/common";

// 1. Create saved chart
const savedChart: SavedChart = {
  uuid: "chart-uuid-1",
  projectUuid: "project-uuid",
  name: "Revenue by Month",
  description: "Monthly revenue trend",
  tableName: "orders",
  metricQuery: {
    exploreName: "orders",
    dimensions: ["orders.created_month"],
    metrics: ["orders.total_revenue"],
    filters: {},
    sorts: [{ fieldId: "orders.created_month", descending: false }],
    limit: 12,
    tableCalculations: [],
  },
  chartConfig: {
    type: ChartKind.VERTICAL_BAR,
    config: {
      layout: {
        xField: "orders.created_month",
        yField: ["orders.total_revenue"],
      },
      eChartsConfig: {},
    },
  },
  tableConfig: {
    columnOrder: [],
  },
  updatedAt: new Date(),
  spaceUuid: "space-uuid",
  dashboardUuid: null,
  dashboardName: null,
};

// 2. Create dashboard with chart tile
const dashboard: Dashboard = {
  organizationUuid: "org-uuid",
  projectUuid: "project-uuid",
  uuid: "dashboard-uuid",
  name: "Sales Dashboard",
  description: "Key sales metrics",
  updatedAt: new Date(),
  tiles: [
    {
      uuid: "tile-uuid-1",
      type: "saved_chart",
      properties: {
        savedChartUuid: "chart-uuid-1",
        title: "Revenue Trend",
        hideTitle: false,
      },
      x: 0,
      y: 0,
      h: 10,
      w: 12,
    },
  ],
  filters: {
    dimensions: [],
    metrics: [],
    tableCalculations: [],
  },
  spaceUuid: "space-uuid",
  views: 0,
  firstViewedAt: null,
  pinnedListUuid: null,
  pinnedListOrder: null,
};

Workflow 3: User Authorization Check

import {
  defineUserAbility,
  type LightdashUser,
  type ProjectMemberProfile,
} from "@lightdash/common";

// Define user with project memberships
const user: LightdashUser = {
  userUuid: "user-uuid",
  organizationUuid: "org-uuid",
  role: "member",
  roleUuid: "role-uuid",
  /* ...other user properties */
};

const projectProfiles: ProjectMemberProfile[] = [
  {
    projectUuid: "project-1",
    userUuid: "user-uuid",
    role: "editor",
    roleUuid: "editor-role-uuid",
  },
];

// Get user abilities
const ability = defineUserAbility(user, projectProfiles);

// Check permissions
if (ability.can("view", "Dashboard")) {
  console.log("User can view dashboards");
}

if (ability.can("update", "SavedChart")) {
  console.log("User can edit charts");
}

// Check project-specific permissions
if (ability.can("view", { type: "Project", uuid: "project-1" })) {
  console.log("User has access to project-1");
}

Workflow 4: Rendering a Visualization

import {
  CartesianChartDataModel,
  ChartKind,
  type MetricQuery,
  type Explore,
} from '@lightdash/common';

// Given: query results and configuration
const resultsRunner = /* IResultsRunner implementation */;

// Create data model
const dataModel = new CartesianChartDataModel({
  resultsRunner,
  fieldConfig: {
    x: {
      reference: 'orders.created_month',
      type: 'category',
    },
    y: [
      {
        reference: 'orders.total_revenue',
        aggregation: 'sum',
      },
    ],
    groupBy: undefined,
  },
  type: ChartKind.VERTICAL_BAR,
});

// Get ECharts options
const echartsOptions = dataModel.getChartOptions();

// Use with ECharts library (in frontend code)
// const chart = echarts.init(document.getElementById('chart'));
// chart.setOption(echartsOptions);

Workflow 5: Compiling DBT Model to Explore

import {
  ExploreCompiler,
  type UncompiledExplore,
  type Explore,
  type WarehouseSqlBuilder,
} from '@lightdash/common';

// Warehouse SQL builder (specific to your warehouse type)
const warehouseSqlBuilder: WarehouseSqlBuilder = /* ... */;

// Create compiler
const compiler = new ExploreCompiler(warehouseSqlBuilder);

// Uncompiled explore from DBT
const uncompiledExplore: UncompiledExplore = {
  name: 'customers',
  label: 'Customers',
  tags: [],
  baseTable: 'customers',
  joinedTables: [],
  tables: {
    customers: {
      name: 'customers',
      label: 'Customers',
      database: 'analytics',
      schema: 'public',
      sqlTable: 'customers',
      dimensions: {
        customer_id: {
          name: 'customer_id',
          label: 'Customer ID',
          type: 'string',
          sql: '${TABLE}.customer_id',
        },
        created_at: {
          name: 'created_at',
          label: 'Created At',
          type: 'timestamp',
          sql: '${TABLE}.created_at',
        },
      },
      metrics: {
        count: {
          name: 'count',
          label: 'Count',
          type: 'count',
          sql: '${TABLE}.customer_id',
        },
      },
    },
  },
  /* ...other explore properties */
};

// Compile to executable explore
const explore: Explore = compiler.compileExplore(uncompiledExplore);

// Now explore has compiled SQL and can be queried
console.log(`Compiled explore: ${explore.name}`);
console.log(`Fields: ${Object.keys(explore.tables[explore.baseTable].dimensions).length} dimensions`);
console.log(`Metrics: ${Object.keys(explore.tables[explore.baseTable].metrics).length} metrics`);

Error Handling Patterns

Handling Compilation Errors

import { ExploreCompiler, type UncompiledExplore } from "@lightdash/common";

try {
  const compiler = new ExploreCompiler(warehouseSqlBuilder);
  const explore = compiler.compileExplore(uncompiledExplore);
  console.log("Compilation successful");
} catch (error) {
  if (error instanceof Error) {
    // Compilation errors include details about what failed
    console.error("Compilation failed:", error.message);
    // Check for specific error types
    if (error.message.includes("Circular dependency")) {
      console.error("Found circular dependency in model");
    } else if (error.message.includes("Unknown field reference")) {
      console.error("Invalid field reference in SQL");
    }
  }
}

Handling Validation Errors

import {
  validateParameterReferences,
  getParameterReferences,
  getAvailableParameterNames,
} from "@lightdash/common";

const sql = "SELECT * FROM orders WHERE status = ${lightdash.parameters.order_status}";

try {
  const references = getParameterReferences(sql);
  const available = getAvailableParameterNames(projectParams, exploreParams);

  validateParameterReferences("orders", references, available);
  console.log("All parameters are valid");
} catch (error) {
  if (error instanceof Error) {
    console.error("Parameter validation failed:", error.message);
    // Error message will indicate which parameters are missing
  }
}

Handling Filter Errors

import { FilterOperator, type MetricQuery, type FilterRule } from "@lightdash/common";

function createDateFilter(fieldId: string, days: number): FilterRule {
  // Validate inputs
  if (days <= 0) {
    throw new Error("Days must be positive");
  }

  if (!fieldId.includes(".")) {
    throw new Error('Field ID must be in format "table.field"');
  }

  return {
    id: crypto.randomUUID(),
    target: { fieldId },
    operator: FilterOperator.IN_THE_PAST,
    values: [days],
    settings: { unitOfTime: "days" },
  };
}

// Usage with error handling
try {
  const filter = createDateFilter("orders.created_date", 30);
  console.log("Filter created successfully");
} catch (error) {
  console.error("Filter creation failed:", error.message);
}

Performance Considerations

Efficient Field Access

import { getFieldMap, getItemMap, type Explore } from "@lightdash/common";

// Instead of repeatedly calling getFields(), create a map once
const fieldMap = getFieldMap(explore);
const itemsMap = getItemMap(explore, additionalMetrics, tableCalculations);

// O(1) field lookup
const field = fieldMap["orders.customer_id"];
const item = itemsMap["orders.total_revenue"];

Caching Compiled Explores

import { ExploreCompiler, type Explore } from "@lightdash/common";

const exploreCache = new Map<string, Explore>();

function getCompiledExplore(
  exploreName: string,
  uncompiledExplore: UncompiledExplore,
  compiler: ExploreCompiler
): Explore {
  // Check cache first
  if (exploreCache.has(exploreName)) {
    return exploreCache.get(exploreName)!;
  }

  // Compile and cache
  const explore = compiler.compileExplore(uncompiledExplore);
  exploreCache.set(exploreName, explore);
  return explore;
}

TypeScript Tips

Type Guards for Safety

import {
  isCartesianChartConfig,
  isPieChartConfig,
  isTableChartConfig,
  type ChartConfig,
} from "@lightdash/common";

function renderChart(chartConfig: ChartConfig) {
  if (isCartesianChartConfig(chartConfig)) {
    // TypeScript knows this is a CartesianChartConfig
    console.log("Rendering cartesian chart:", chartConfig.type);
  } else if (isPieChartConfig(chartConfig)) {
    // TypeScript knows this is a PieChartConfig
    console.log("Rendering pie chart");
  } else if (isTableChartConfig(chartConfig)) {
    // TypeScript knows this is a TableChartConfig
    console.log("Rendering table");
  }
}

Discriminated Unions

import { type WarehouseCredentials, WarehouseTypes } from "@lightdash/common";

function getConnectionString(credentials: WarehouseCredentials): string {
  switch (credentials.type) {
    case WarehouseTypes.BIGQUERY:
      // TypeScript knows this is BigqueryCredentials
      return `bigquery://${credentials.project}`;

    case WarehouseTypes.POSTGRES:
      // TypeScript knows this is PostgresCredentials
      return `postgres://${credentials.host}:${credentials.port}/${credentials.dbname}`;

    case WarehouseTypes.SNOWFLAKE:
      // TypeScript knows this is SnowflakeCredentials
      return `snowflake://${credentials.account}.snowflakecomputing.com`;

    // ... other warehouse types

    default:
      throw new Error(`Unsupported warehouse type`);
  }
}

Migration Guides

Deprecated Functions

// DEPRECATED: getFieldQuoteChar()
// ❌ Old way (deprecated)
import { getFieldQuoteChar } from "@lightdash/common";
const quoteChar = getFieldQuoteChar(warehouseType);

// ✅ New way (recommended)
import { type WarehouseSqlBuilder } from "@lightdash/common";
const quoteChar = warehouseSqlBuilder.getFieldQuoteChar();