CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-lightdash--common

Shared TypeScript library for the Lightdash platform containing common types, utilities, and business logic for analytics workflows

Overall
score

72%

Evaluation72%

1.09x

Agent success when using this tile

Overview
Eval results
Files

api.mddocs/api/types/

API and Error Types

This document contains types for SQL Runner functionality, error classes, and installation configuration.

SQL Runner Types

SQL Runner provides custom SQL query execution with full visualization support, including custom metrics, time granularity controls, filtering, sorting, and pivoting capabilities.

SQL Runner Field Types

enum SqlRunnerFieldType {
  TIME = 'time',
  NUMBER = 'number',
  STRING = 'string',
  BOOLEAN = 'boolean',
}

type SqlRunnerField = {
  name: string;
  label: string;
  type: SqlRunnerFieldType;
  kind: FieldType;
  description?: string;
  visible: boolean;
  aggType?: VizAggregationOptions;
  availableGranularities: SqlRunnerTimeGranularityValue[];
  availableOperators: SqlRunnerFilter['operator'][];
};

type SqlRunnerTimeDimension = SqlRunnerField & {
  granularity?: SqlRunnerTimeGranularityValue;
};

SQL Runner Query

type SqlRunnerQuery = {
  dimensions: Pick<SqlRunnerField, 'name'>[];
  timeDimensions: Pick<SqlRunnerTimeDimension, 'name' | 'granularity'>[];
  metrics: Pick<SqlRunnerField, 'name'>[];
  sortBy: SqlRunnerSortBy[];
  limit?: number;
  timezone?: string;
  pivot?: SqlRunnerPivot;
  filters: SqlRunnerFilter[];
  sql?: string;
  customMetrics?: (Pick<SqlRunnerField, 'name' | 'aggType'> & {
    baseDimension?: string;
  })[];
};

type SqlRunnerSortBy = Pick<SqlRunnerField, 'name' | 'kind'> & {
  direction: SortByDirection;
};

type SqlRunnerPivot = {
  on: string[];
  index: string[];
  values: string[];
};

type SqlRunnerBody = {
  sql: string;
  limit?: number;
};

SQL Runner Filters

enum SqlRunnerFilterBaseOperator {
  IS = 'IS',
  IS_NOT = 'IS_NOT',
}

enum SqlRunnerFilterRelativeTimeValue {
  TODAY = 'TODAY',
  YESTERDAY = 'YESTERDAY',
  LAST_7_DAYS = 'LAST_7_DAYS',
  LAST_30_DAYS = 'LAST_30_DAYS',
}

type SqlRunnerFilterBase = {
  uuid: string;
  fieldRef: string;
  fieldKind: FieldType;
  fieldType: SqlRunnerFieldType;
};

type SqlRunnerStringFilter = SqlRunnerFilterBase & {
  fieldType: SqlRunnerFieldType.STRING;
  operator: SqlRunnerFilterBaseOperator;
  values: string[];
};

type SqlRunnerExactTimeFilter = SqlRunnerFilterBase & {
  fieldType: SqlRunnerFieldType.TIME;
  operator: SqlRunnerFilterBaseOperator;
  values: { time: string };
};

type SqlRunnerRelativeTimeFilter = SqlRunnerFilterBase & {
  fieldType: SqlRunnerFieldType.TIME;
  operator: SqlRunnerFilterBaseOperator;
  values: { relativeTime: SqlRunnerFilterRelativeTimeValue };
};

type SqlRunnerTimeFilter =
  | SqlRunnerExactTimeFilter
  | SqlRunnerRelativeTimeFilter;

type SqlRunnerFilter = (SqlRunnerStringFilter | SqlRunnerTimeFilter) & {
  and?: SqlRunnerFilter[];
  or?: SqlRunnerFilter[];
};

SQL Chart Configuration

type SqlChart = {
  savedSqlUuid: string;
  name: string;
  description: string | null;
  slug: string;
  sql: string;
  limit: number;
  config: VizBaseConfig & (VizCartesianChartConfig | VizPieChartConfig | VizTableConfig);
  chartKind: ChartKind;
  createdAt: Date;
  createdBy: Pick<LightdashUser, 'userUuid' | 'firstName' | 'lastName'> | null;
  lastUpdatedAt: Date;
  lastUpdatedBy: Pick<LightdashUser, 'userUuid' | 'firstName' | 'lastName'> | null;
  space: Pick<SpaceSummary, 'uuid' | 'name' | 'isPrivate' | 'userAccess'>;
  dashboard: Pick<Dashboard, 'uuid' | 'name'> | null;
  project: Pick<Project, 'projectUuid'>;
  organization: Pick<Organization, 'organizationUuid'>;
};

SQL Runner Results

type SqlRunnerResults = RawResultRow[];

function isErrorDetails(
  results?: ApiSqlRunnerJobStatusResponse['results']['details']
): results is SqlRunnerJobStatusErrorDetails;

function isApiSqlRunnerJobSuccessResponse(
  response: ApiSqlRunnerJobStatusResponse['results'] | ApiError
): response is ApiSqlRunnerJobSuccessResponse['results'];

function isApiSqlRunnerJobErrorResponse(
  response: ApiSqlRunnerJobStatusResponse['results'] | ApiError
): response is ApiError;

Extended SQL Runner Types

Types for the SQL Runner feature including custom SQL queries, field definitions, filters, sorting, pivoting, and visualization configuration.

enum SqlRunnerFieldType {
  TIME = 'time',
  NUMBER = 'number',
  STRING = 'string',
  BOOLEAN = 'boolean',
}

// Note: SqlRunnerTimeGranularity is NOT exported - use string literals
type SqlRunnerTimeGranularityValue =
  | 'NANOSECOND'
  | 'MICROSECOND'
  | 'MILLISECOND'
  | 'SECOND'
  | 'MINUTE'
  | 'HOUR'
  | 'DAY'
  | 'WEEK'
  | 'MONTH'
  | 'QUARTER'
  | 'YEAR';

interface SqlRunnerField {
  name: string;
  label: string;
  type: SqlRunnerFieldType;
  kind: FieldType;
  description?: string;
  visible: boolean;
  aggType?: VizAggregationOptions;
  availableGranularities: SqlRunnerTimeGranularityValue[];
  availableOperators: SqlRunnerFilter['operator'][];
}

type SqlRunnerTimeDimension = SqlRunnerField & {
  granularity?: SqlRunnerTimeGranularityValue;
};

interface SqlRunnerSortBy extends Pick<SqlRunnerField, 'name' | 'kind'> {
  direction: SortByDirection;
}

type SqlRunnerPivot = {
  on: string[];
  index: string[];
  values: string[];
};

interface SqlRunnerQuery {
  dimensions: Pick<SqlRunnerField, 'name'>[];
  timeDimensions: Pick<SqlRunnerTimeDimension, 'name' | 'granularity'>[];
  metrics: Pick<SqlRunnerField, 'name'>[];
  sortBy: SqlRunnerSortBy[];
  limit?: number;
  timezone?: string;
  pivot?: SqlRunnerPivot;
  filters: SqlRunnerFilter[];
  sql?: string;
  customMetrics?: (Pick<SqlRunnerField, 'name' | 'aggType'> & {
    baseDimension?: string;
  })[];
}

enum SqlRunnerFilterBaseOperator {
  IS = 'IS',
  IS_NOT = 'IS_NOT',
}

enum SqlRunnerFilterRelativeTimeValue {
  TODAY = 'TODAY',
  YESTERDAY = 'YESTERDAY',
  LAST_7_DAYS = 'LAST_7_DAYS',
  LAST_30_DAYS = 'LAST_30_DAYS',
}

interface SqlRunnerFilterBase {
  uuid: string;
  fieldRef: string;
  fieldKind: FieldType;
  fieldType: SqlRunnerFieldType;
}

interface SqlRunnerStringFilter extends SqlRunnerFilterBase {
  fieldType: SqlRunnerFieldType.STRING;
  operator: SqlRunnerFilterBaseOperator;
  values: string[];
}

interface SqlRunnerExactTimeFilter extends SqlRunnerFilterBase {
  fieldType: SqlRunnerFieldType.TIME;
  operator: SqlRunnerFilterBaseOperator;
  values: { time: string };
}

interface SqlRunnerRelativeTimeFilter extends SqlRunnerFilterBase {
  fieldType: SqlRunnerFieldType.TIME;
  operator: SqlRunnerFilterBaseOperator;
  values: { relativeTime: SqlRunnerFilterRelativeTimeValue };
}

type SqlRunnerTimeFilter =
  | SqlRunnerExactTimeFilter
  | SqlRunnerRelativeTimeFilter;

type SqlRunnerFilter = (SqlRunnerStringFilter | SqlRunnerTimeFilter) & {
  and?: SqlRunnerFilter[];
  or?: SqlRunnerFilter[];
};

interface SqlRunnerBody {
  sql: string;
  limit?: number;
}

interface SqlRunnerPayload extends TraceTaskBase, SqlRunnerBody {
  sqlChartUuid?: string;
  context: QueryExecutionContext;
}

interface ValuesColumn {
  reference: string;
  aggregation: VizAggregationOptions;
}

interface GroupByColumn {
  reference: string;
}

interface SqlRunnerPivotQueryPayload extends SqlRunnerPayload, PivotConfiguration {
  savedSqlUuid?: string;
}

interface SqlRunnerPivotQueryBody extends SqlRunnerBody, PivotConfiguration {
  savedSqlUuid?: string;
}

type SqlRunnerResults = RawResultRow[];

type SqlRunnerJobStatusSuccessDetails = {
  fileUrl: string;
  columns: VizColumn[];
};

type SqlRunnerPivotQueryJobStatusSuccessDetails =
  SqlRunnerJobStatusSuccessDetails & Omit<PivotChartData, 'results'>;

type SqlRunnerJobStatusErrorDetails = {
  error: string;
  charNumber?: number;
  lineNumber?: number;
  createdByUserUuid: string;
};

interface ApiSqlRunnerJobStatusResponse {
  status: 'ok';
  results: {
    status: SchedulerJobStatus;
    details:
      | SqlRunnerJobStatusSuccessDetails
      | SqlRunnerJobStatusErrorDetails;
  };
}

interface ApiSqlRunnerJobSuccessResponse extends ApiSqlRunnerJobStatusResponse {
  results: {
    status: SchedulerJobStatus.COMPLETED;
    details: SqlRunnerJobStatusSuccessDetails;
  };
}

function isApiSqlRunnerJobSuccessResponse(
  response: ApiSqlRunnerJobStatusResponse['results'] | ApiError
): response is ApiSqlRunnerJobSuccessResponse['results'];

function isApiSqlRunnerJobErrorResponse(
  response: ApiSqlRunnerJobStatusResponse['results'] | ApiError
): response is ApiError;

interface ApiSqlRunnerJobPivotQuerySuccessResponse {
  results: {
    status: SchedulerJobStatus.COMPLETED;
    details: SqlRunnerPivotQueryJobStatusSuccessDetails;
  };
}

function isApiSqlRunnerJobPivotQuerySuccessResponse(
  response: ApiSqlRunnerJobStatusResponse['results'] | ApiError
): response is ApiSqlRunnerJobPivotQuerySuccessResponse['results'];

function isErrorDetails(
  results?: ApiSqlRunnerJobStatusResponse['results']['details']
): results is SqlRunnerJobStatusErrorDetails;

interface SqlChart {
  savedSqlUuid: string;
  name: string;
  description: string | null;
  slug: string;
  sql: string;
  limit: number;
  config: VizBaseConfig &
    (VizCartesianChartConfig | VizPieChartConfig | VizTableConfig);
  chartKind: ChartKind;
  createdAt: Date;
  createdBy: Pick<
    LightdashUser,
    'userUuid' | 'firstName' | 'lastName'
  > | null;
  lastUpdatedAt: Date;
  lastUpdatedBy: Pick<
    LightdashUser,
    'userUuid' | 'firstName' | 'lastName'
  > | null;
  space: Pick<SpaceSummary, 'uuid' | 'name' | 'isPrivate' | 'userAccess'>;
  dashboard: Pick<Dashboard, 'uuid' | 'name'> | null;
  project: Pick<Project, 'projectUuid'>;
  organization: Pick<Organization, 'organizationUuid'>;
  views: number;
  firstViewedAt: Date;
  lastViewedAt: Date;
}

interface CreateSqlChart {
  name: string;
  description: string | null;
  sql: string;
  limit: number;
  config: AllVizChartConfig;
  spaceUuid: string;
}

interface UpdateUnversionedSqlChart {
  name: string;
  description: string | null;
  spaceUuid: string;
}

interface UpdateVersionedSqlChart {
  sql: string;
  limit: number;
  config: AllVizChartConfig;
}

interface UpdateSqlChart {
  unversionedData?: UpdateUnversionedSqlChart;
  versionedData?: UpdateVersionedSqlChart;
}

interface ApiSqlChart {
  status: 'ok';
  results: SqlChart;
}

interface ApiCreateSqlChart {
  status: 'ok';
  results: {
    savedSqlUuid: string;
    slug: string;
  };
}

interface ApiUpdateSqlChart {
  status: 'ok';
  results: {
    savedSqlUuid: string;
    savedSqlVersionUuid: string | null;
  };
}

interface ApiCreateVirtualView {
  status: 'ok';
  results: Pick<Explore, 'name'>;
}

interface CreateVirtualViewPayload {
  name: string;
  sql: string;
  columns: VizColumn[];
}

type UpdateVirtualViewPayload = CreateVirtualViewPayload;

interface ApiGithubDbtWriteBack {
  status: 'ok';
  results: PullRequestCreated;
}

interface ApiGithubDbtWritePreview {
  status: 'ok';
  results: {
    url: string;
    repo: string;
    path: string;
    files: string[];
    owner: string;
  };
}

Error Classes

All error classes extend from the base LightdashError class and include an HTTP status code, error name, message, and optional data object with additional context.

Base Error Class

type LightdashErrorData = {
  documentationUrl?: string;
  [key: string]: any;
};

class LightdashError extends Error {
  statusCode: number;
  data: LightdashErrorData;

  constructor(params: {
    message: string;
    name: string;
    statusCode: number;
    data: LightdashErrorData;
  });
}

Authentication & Authorization Errors (401, 403)

class ForbiddenError extends LightdashError {
  constructor(
    message?: string,  // Default: "You don't have access to this resource or action"
    data?: { [key: string]: any }
  );
}

class DeactivatedAccountError extends LightdashError {
  constructor(
    message?: string,  // Default: "Your account has been deactivated..."
    data?: { [key: string]: any }
  );
}

class AuthorizationError extends LightdashError {
  constructor(
    message?: string,  // Default: "You don't have authorization to perform this action"
    data?: { [key: string]: any }
  );
}

class SnowflakeTokenError extends LightdashError {
  constructor(message: string);
}

class OauthAuthenticationError extends LightdashError {
  constructor(
    message?: string,  // Default: "OAuth authentication error"
    data?: { [key: string]: any }
  );
}

class CustomSqlQueryForbiddenError extends LightdashError {
  constructor(message?: string);  // Default: "User cannot run queries with custom SQL dimensions"
}

Not Found Errors (404)

class NotExistsError extends LightdashError {
  constructor(message: string);
}

class NotFoundError extends LightdashError {
  constructor(message: string);
}

class InvalidUser extends LightdashError {
  constructor(message: string);
}

class SlackInstallationNotFoundError extends LightdashError {
  constructor(message?: string);  // Default: "Could not find slack installation"
}

class ReadFileError extends LightdashError {
  constructor(message: string, data?: { [key: string]: any });
}

Bad Request Errors (400)

class ParameterError extends LightdashError {
  constructor(
    message?: string,  // Default: "Incorrect parameters"
    data?: Record<string, any>
  );
}

class NonCompiledModelError extends LightdashError {
  constructor(message: string, data?: { [key: string]: any });
}

class MissingCatalogEntryError extends LightdashError {
  constructor(message: string, data: { [key: string]: any });
}

class MissingWarehouseCredentialsError extends LightdashError {
  constructor(message: string);
}

class UnexpectedGitError extends LightdashError {
  constructor(
    message?: string,  // Default: "Unexpected error in Git adapter"
    data?: { [key: string]: any }
  );
}

class ParseError extends LightdashError {
  constructor(
    message?: string,  // Default: "Error parsing dbt project and lightdash metadata"
    data?: { [key: string]: any }
  );
}

class CompileError extends LightdashError {
  constructor(
    message?: string,  // Default: "Error compiling sql from Lightdash configuration"
    data?: Record<string, any>
  );
}

class FieldReferenceError extends LightdashError {
  constructor(
    message?: string,  // Default: "Failed to reference field in dbt project"
    data?: Record<string, any>
  );
}

class DbtError extends LightdashError {
  logs: DbtLog[];

  constructor(
    message?: string,  // Default: "Dbt raised an error"
    logs?: DbtLog[]
  );
}

class NotSupportedError extends LightdashError {
  constructor(message: string);
}

class WarehouseConnectionError extends LightdashError {
  constructor(message: string);
}

class WarehouseQueryError extends LightdashError {
  constructor(message: string, data?: { [key: string]: any });
}

class TimeoutError extends LightdashError {
  constructor(message: string);
}

class SlackError extends LightdashError {
  constructor(
    message?: string,  // Default: "Slack API error occurred"
    data?: { [key: string]: any }
  );
}

class MsTeamsError extends LightdashError {
  constructor(
    message?: string,  // Default: "Microsoft Teams API error occurred"
    data?: { [key: string]: any }
  );
}

class UnexpectedGoogleSheetsError extends LightdashError {
  constructor(
    message?: string,  // Default: "Unexpected error in Google sheets client"
    data?: { [key: string]: any }
  );
}

class SshTunnelError extends LightdashError {
  constructor(message: string);
}

class AiDuplicateSlackPromptError extends LightdashError {
  constructor(message: string);
}

class AiSlackMappingNotFoundError extends LightdashError {
  constructor(message: string);
}

class AiAgentNotFoundError extends LightdashError {
  constructor(message: string);
}

class LightdashProjectConfigError extends LightdashError {
  constructor(
    message?: string,  // Default: "Invalid lightdash.config.yml"
    data?: Record<string, any>
  );
}

Not Acceptable Errors (406)

class ExpiredError extends LightdashError {
  constructor(message: string);
}

class NotEnoughResults extends LightdashError {
  constructor(message: string);
}

Conflict Errors (409)

class AlreadyProcessingError extends LightdashError {
  constructor(message: string);
}

class AlreadyExistsError extends LightdashError {
  constructor(message: string);
}

Unprocessable Entity Errors (422)

class MissingConfigError extends LightdashError {
  constructor(message: string);
}

class PaginationError extends LightdashError {
  constructor(message: string);
}

Server Errors (500, 501)

class UnexpectedServerError extends LightdashError {
  constructor(
    message?: string,  // Default: "Something went wrong."
    data?: { [key: string]: any }
  );
}

class UnexpectedIndexError extends LightdashError {
  constructor(
    message?: string,  // Default: "Invalid index in array."
    data?: { [key: string]: any }
  );
}

class UnexpectedDatabaseError extends LightdashError {
  constructor(
    message?: string,  // Default: "Unexpected error in Lightdash database."
    data?: { [key: string]: any }
  );
}

class SmptError extends LightdashError {
  constructor(message: string, data?: { [key: string]: any });
}

class GoogleSheetsTransientError extends LightdashError {
  constructor(
    message?: string,  // Default: "Unexpected error in Google Sheets API"
    data?: { [key: string]: any }
  );
}

class NotImplementedError extends LightdashError {
  constructor(message?: string);  // Default: "Not implemented"
}

class ScreenshotError extends LightdashError {
  constructor(
    message?: string,  // Default: "Error capturing screenshot"
    data?: { [key: string]: any }
  );
}

class S3Error extends LightdashError {
  constructor(
    message?: string,  // Default: "Error occurred while interacting with S3"
    data?: { [key: string]: any }
  );
}

class GenerateDailySchedulerJobError extends LightdashError {
  schedulerUuid: string;

  constructor(
    message: string,
    schedulerUuid: string,
    originalError?: unknown
  );
}

class CorruptedExploreError extends LightdashError {
  constructor(
    message?: string,  // Default: "Explore has corrupted or missing data"
    data?: Record<string, any>
  );
}

class ConditionalFormattingError extends LightdashError {
  constructor(
    message?: string,  // Default: "Error applying conditional formatting"
    data?: { [key: string]: any }
  );
}

SCIM Error

class ScimError extends Error {
  statusCode: number;
  scimType?: string;

  constructor(
    statusCode: number,
    detail: string,
    scimType?: string
  );
}

Error Utility Function

function getErrorMessage(e: unknown): string;

Extracts error message from Error objects or returns a generic message for other types.

Installation Types

enum LightdashInstallType {
  DOCKER_IMAGE = 'docker_image',
  BASH_INSTALL = 'bash_install',
  HEROKU = 'heroku',
  UNKNOWN = 'unknown',
}

enum LightdashMode {
  DEFAULT = 'default',
  DEMO = 'demo',
  PR = 'pr',
  CLOUD_BETA = 'cloud_beta',
  DEV = 'development',
}

function isLightdashMode(x: string): x is LightdashMode;

Types and type guards for Lightdash installation and mode detection.

Share URL Types

/**
 * A ShareUrl maps a short shareable id to a full URL
 * in the Lightdash UI. This allows very long URLs
 * to be represented by short ids.
 */
type ShareUrl = {
  /**
   * Unique shareable id
   */
  nanoid: string;
  /**
   * The URL path of the full URL
   */
  path: string;
  params: string;
  /**
   * @format uuid
   */
  createdByUserUuid?: string;
  /**
   * @format uuid
   */
  organizationUuid?: string;
  shareUrl?: string;
  url?: string;
  host?: string;
};

/**
 * Contains the detail of a full URL to generate a short URL id
 */
type CreateShareUrl = Pick<ShareUrl, 'path' | 'params'>;

Types for creating and managing short shareable URLs that map to full Lightdash application URLs.

Pagination Types

/**
 * Default page size for paginated query results
 */
const DEFAULT_RESULTS_PAGE_SIZE = 500;

/**
 * Arguments for paginated Knex queries
 */
type KnexPaginateArgs = {
  /** Number of items per page */
  pageSize: number;
  /** Current page number (1-indexed) */
  page: number;
};

/**
 * Generic paginated data wrapper for Knex query results
 */
type KnexPaginatedData<T> = {
  /** The actual data returned for the current page */
  data: T;
  /** Optional pagination metadata */
  pagination?: KnexPaginateArgs & {
    /** Total number of pages available */
    totalPageCount: number;
    /** Total number of results across all pages */
    totalResults: number;
  };
};

/**
 * Partial Knex pagination arguments for flexible pagination control
 */
type ResultsPaginationArgs = Partial<KnexPaginateArgs>;

/**
 * Extended pagination metadata with previous/next page helpers
 */
type ResultsPaginationMetadata<T> = KnexPaginatedData<T[]>['pagination'] & {
  nextPage: number | undefined;
  previousPage: number | undefined;
};

These types are used throughout the API for paginated list endpoints, providing consistent pagination metadata including page size, current page number, total pages, and total results count. The ResultsPaginationMetadata type extends the base pagination with helper fields for navigating between pages.

Notification Types

Types for managing user notifications within the Lightdash platform.

/**
 * Available notification resource types
 */
enum ApiNotificationResourceType {
  DashboardComments = 'dashboardComments',
}

/**
 * Base notification type with common fields
 */
type NotificationBase = {
  /** Unique identifier for the notification */
  notificationId: string;
  /** Timestamp when notification was created */
  createdAt: Date;
  /** Whether user has viewed the notification */
  viewed: boolean;
  /** UUID of the related resource (optional) */
  resourceUuid: string | undefined;
  /** Notification message text (optional) */
  message: string | undefined;
  /** URL to navigate to when clicking notification (optional) */
  url: string | undefined;
};

/**
 * Notification for dashboard tile comments
 */
type NotificationDashboardComment = NotificationBase & {
  resourceType: ApiNotificationResourceType.DashboardComments;
  metadata: {
    dashboardUuid: string;
    dashboardName: string;
    dashboardTileUuid: string;
    dashboardTileName: string;
  } | undefined;
};

/**
 * Union type of all notification types
 */
type Notification = NotificationDashboardComment;

/**
 * Parameters for updating notification status
 */
type ApiNotificationUpdateParams = Pick<Notification, 'viewed'>;

/**
 * Array of notifications
 */
type ApiNotificationsResults = Notification[];

/**
 * API response for fetching notifications
 */
type ApiGetNotifications = {
  status: 'ok';
  results: ApiNotificationsResults;
};

Tag Types

Types for managing tags on charts and dashboards.

/**
 * Tag for organizing and categorizing content
 */
type Tag = {
  /** Unique identifier for the tag */
  tagUuid: string;
  /** Project this tag belongs to */
  projectUuid: string;
  /** Display name for the tag */
  name: string;
  /** Color hex code for the tag (e.g., "#FF5733") */
  color: string;
  /** When the tag was created */
  createdAt: Date;
  /** Optional YAML reference for tags defined in code */
  yamlReference: string | null;
  /** User who created the tag (null for system tags) */
  createdBy: Pick<
    LightdashUser,
    'userUuid' | 'firstName' | 'lastName'
  > | null;
};

/**
 * API response for fetching tags
 */
type ApiGetTagsResponse = {
  status: 'ok';
  results: Tag[];
};

/**
 * API response for creating a tag
 */
type ApiCreateTagResponse = {
  status: 'ok';
  results: { tagUuid: string };
};

/**
 * API response for replacing YAML-defined tags
 */
type ApiReplaceYamlTagsResponse = {
  status: 'ok';
  results: undefined;
};

SQL Query Result Types

Generic types for SQL query results, used across warehouse integrations and SQL runner features.

/**
 * A single row from a SQL query result
 * Each column name maps to its value
 */
type SqlResultsRow = { [columnName: string]: unknown };

/**
 * Metadata for a field (column) in SQL query results
 */
type SqlResultsField = {
  /** Column name */
  name: string;
  /** Database-specific type (e.g., "VARCHAR", "INTEGER") */
  type: string;
};

/**
 * Complete SQL query results including field metadata and row data
 */
type SqlQueryResults = {
  /** Array of field/column metadata */
  fields: SqlResultsField[];
  /** Array of result rows */
  rows: SqlResultsRow[];
};

Usage Example:

import { type SqlQueryResults } from '@lightdash/common';

// Process SQL query results
function processSqlResults(results: SqlQueryResults) {
  console.log(`Found ${results.fields.length} columns`);
  console.log(`Field names: ${results.fields.map(f => f.name).join(', ')}`);
  console.log(`Returned ${results.rows.length} rows`);

  // Access row data
  results.rows.forEach(row => {
    results.fields.forEach(field => {
      console.log(`${field.name}: ${row[field.name]}`);
    });
  });
}

API Error Types

API Error Payload

The standard error response format returned by all API endpoints when an error occurs.

import { type AnyType } from '@lightdash/common';

/**
 * The Error object is returned from the API any time there is an error.
 */
type ApiErrorPayload = {
  status: 'error';
  error: {
    /** HTTP status code */
    statusCode: number;
    /** Unique name for the type of error */
    name: string;
    /** A friendly message summarizing the error */
    message?: string;
    /** Optional data containing details of the error */
    data?: AnyType;
  };
};

Usage Example:

import { type ApiErrorPayload } from '@lightdash/common';

// Handle API error responses
function handleApiResponse(response: unknown) {
  if (isErrorResponse(response)) {
    const error = response as ApiErrorPayload;
    console.error(`Error ${error.error.statusCode}: ${error.error.name}`);
    console.error(error.error.message);

    if (error.error.data) {
      console.error('Additional error details:', error.error.data);
    }
  }
}

function isErrorResponse(response: unknown): response is ApiErrorPayload {
  return (
    typeof response === 'object' &&
    response !== null &&
    'status' in response &&
    response.status === 'error'
  );
}

Comment API Types

Types for dashboard comment functionality.

Comment API Response Types

import { type Comment } from '@lightdash/common';

/** Response for creating a new comment */
type ApiCreateComment = {
  status: 'ok';
  /** The ID of the newly created comment */
  results: Comment['commentId'];
};

/** Response for fetching comments */
type ApiGetComments = {
  status: 'ok';
  /** Map of dashboard tile UUIDs to their comments */
  results: {
    [dashboardTileUuid: string]: Comment[];
  };
};

/** Response for resolving a comment */
type ApiResolveComment = {
  status: 'ok';
};

/** Response for deleting a comment (same as resolve) */
type ApiDeleteComment = ApiResolveComment;

Usage Example:

import {
  type ApiCreateComment,
  type ApiGetComments,
  type ApiResolveComment,
} from '@lightdash/common';

// Create a comment on a dashboard tile
async function createComment(
  dashboardTileUuid: string,
  text: string,
): Promise<string> {
  const response: ApiCreateComment = await api.post('/comments', {
    dashboardTileUuid,
    text,
  });
  return response.results; // Returns comment ID
}

// Fetch all comments for a dashboard
async function getCommentsForDashboard(dashboardUuid: string) {
  const response: ApiGetComments = await api.get(
    `/dashboards/${dashboardUuid}/comments`,
  );

  // Access comments by tile UUID
  Object.entries(response.results).forEach(([tileUuid, comments]) => {
    console.log(`Tile ${tileUuid} has ${comments.length} comments`);
  });

  return response.results;
}

// Resolve a comment
async function resolveComment(commentId: string): Promise<void> {
  const response: ApiResolveComment = await api.patch(
    `/comments/${commentId}/resolve`,
  );
  console.log('Comment resolved successfully');
}

Async Query Execution Types

Types for executing queries asynchronously with support for metric queries, saved charts, SQL charts, and underlying data queries.

Common Async Query Parameters

/** Common parameters for all async query requests */
type CommonExecuteQueryRequestParams = {
  /** Query execution context for tracking */
  context?: QueryExecutionContext;
  /** Force cache invalidation */
  invalidateCache?: boolean;
  /** Parameter values for SQL parameterization */
  parameters?: ParametersValuesMap;
};

/** Date zoom configuration for time-series queries */
type DateZoom = {
  /** Time granularity for grouping */
  granularity?: DateGranularity;
  /** X-axis field ID for the date dimension */
  xAxisFieldId?: string;
};

Metric Query Execution Parameters

/** Parameters for executing async metric queries */
type ExecuteAsyncMetricQueryRequestParams = CommonExecuteQueryRequestParams & {
  /** Metric query definition */
  query: Omit<MetricQueryRequest, 'csvLimit'>;
  /** Date zoom configuration */
  dateZoom?: DateZoom;
  /** Pivot configuration */
  pivotConfiguration?: PivotConfiguration;
  /** Period-over-period comparison settings */
  periodOverPeriod?: PeriodOverPeriodComparison;
};

Saved Chart Execution Parameters

/** Parameters for executing async saved chart queries */
type ExecuteAsyncSavedChartRequestParams = CommonExecuteQueryRequestParams & {
  /** UUID of the saved chart */
  chartUuid: string;
  /** Optional version UUID to execute a specific chart version */
  versionUuid?: string;
  /** Row limit override */
  limit?: number | null | undefined;
  /** Enable pivot table transformation */
  pivotResults?: boolean;
};

/** Parameters for executing saved charts within a dashboard context */
type ExecuteAsyncDashboardChartRequestParams = CommonExecuteQueryRequestParams & {
  /** UUID of the saved chart */
  chartUuid: string;
  /** Dashboard tile UUID */
  tileUuid: string;
  /** Dashboard UUID */
  dashboardUuid: string;
  /** Dashboard-level filters */
  dashboardFilters: DashboardFilters;
  /** Dashboard-level sorts */
  dashboardSorts: SortField[];
  /** Date zoom configuration */
  dateZoom?: DateZoom;
  /** Row limit override */
  limit?: number | null | undefined;
  /** Enable pivot table transformation */
  pivotResults?: boolean;
};

SQL Query Execution Parameters

/** Parameters for executing async SQL queries */
type ExecuteAsyncSqlQueryRequestParams = CommonExecuteQueryRequestParams & {
  /** SQL query string to execute */
  sql: string;
  /** Optional row limit for results */
  limit?: number;
  /** Pivot configuration */
  pivotConfiguration?: PivotConfiguration;
};

/** Parameters for executing SQL chart queries by UUID */
type ExecuteAsyncSqlChartByUuidRequestParams = CommonExecuteQueryRequestParams & {
  /** UUID of the SQL chart to execute */
  savedSqlUuid: string;
  /** Optional row limit */
  limit?: number;
};

/** Parameters for executing SQL chart queries by slug */
type ExecuteAsyncSqlChartBySlugRequestParams = CommonExecuteQueryRequestParams & {
  /** Slug identifier of the SQL chart */
  slug: string;
  /** Optional row limit */
  limit?: number;
};

/** Union type for SQL chart execution (by UUID or slug) */
type ExecuteAsyncSqlChartRequestParams =
  | ExecuteAsyncSqlChartByUuidRequestParams
  | ExecuteAsyncSqlChartBySlugRequestParams;

/** Parameters for executing SQL charts within a dashboard by UUID */
type ExecuteAsyncDashboardSqlChartByUuidRequestParams = CommonExecuteQueryRequestParams & {
  /** Dashboard UUID */
  dashboardUuid: string;
  /** Dashboard tile UUID */
  tileUuid: string;
  /** UUID of the SQL chart */
  savedSqlUuid: string;
  /** Dashboard-level filters */
  dashboardFilters: DashboardFilters;
  /** Dashboard-level sorts */
  dashboardSorts: SortField[];
  /** Optional row limit */
  limit?: number;
};

/** Parameters for executing SQL charts within a dashboard by slug */
type ExecuteAsyncDashboardSqlChartBySlugRequestParams = CommonExecuteQueryRequestParams & {
  /** Dashboard UUID */
  dashboardUuid: string;
  /** Dashboard tile UUID */
  tileUuid: string;
  /** Slug identifier of the SQL chart */
  slug: string;
  /** Dashboard-level filters */
  dashboardFilters: DashboardFilters;
  /** Dashboard-level sorts */
  dashboardSorts: SortField[];
  /** Optional row limit */
  limit?: number;
};

/** Union type for dashboard SQL chart execution (by UUID or slug) */
type ExecuteAsyncDashboardSqlChartRequestParams =
  | ExecuteAsyncDashboardSqlChartByUuidRequestParams
  | ExecuteAsyncDashboardSqlChartBySlugRequestParams;

/** Type guard for SQL chart execution by UUID */
function isExecuteAsyncSqlChartByUuidParams(
  params: ExecuteAsyncSqlChartRequestParams,
): params is ExecuteAsyncSqlChartByUuidRequestParams;

/** Type guard for dashboard SQL chart execution by UUID */
function isExecuteAsyncDashboardSqlChartByUuidParams(
  params: ExecuteAsyncDashboardSqlChartRequestParams,
): params is ExecuteAsyncDashboardSqlChartByUuidRequestParams;

Underlying Data Query Parameters

/** Parameters for executing async underlying data queries */
type ExecuteAsyncUnderlyingDataRequestParams = {
  /** Metric query to execute */
  metricQuery: MetricQuery;
  /** Explore name */
  exploreName: string;
  /** Optional CSV export settings */
  csvSettings?: {
    formatted: boolean;
    columnSeparator: string;
  };
};

Download Types

/** Supported file types for downloads */
enum DownloadFileType {
  CSV = 'csv',
  IMAGE = 'image',
  JSONL = 'jsonl',
  S3_JSONL = 's3_jsonl',
  XLSX = 'xlsx',
}

/** Download file metadata */
type DownloadFile = {
  /** Unique nanoid identifier */
  nanoid: string;
  /** File path or URL */
  path: string;
  /** Timestamp when file was created */
  createdAt: Date;
  /** File type */
  type: DownloadFileType;
};

/** Backwards compatible options for downloading query results */
type DownloadOptions = {
  /** File type for the download */
  fileType?: DownloadFileType;
  /** Download only raw values (no formatting) */
  onlyRaw?: boolean;
  /** Include table names in column headers */
  showTableNames?: boolean;
  /** Custom labels for columns */
  customLabels?: Record<string, string>;
  /** Custom column ordering */
  columnOrder?: string[];
  /** Fields to exclude from download */
  hiddenFields?: string[];
  /** Pivot configuration for pivot table downloads */
  pivotConfig?: PivotConfig;
  /** Custom filename for the download */
  attachmentDownloadName?: string;
};

/** Parameters for downloading async query results */
type DownloadAsyncQueryResultsRequestParams = {
  /** UUID of the async query */
  queryUuid: string;
  /** File type for download */
  type?: DownloadFileType;
  /** Download only raw values */
  onlyRaw?: boolean;
  /** Include table names in headers */
  showTableNames?: boolean;
  /** Custom column labels */
  customLabels?: Record<string, string>;
  /** Column order */
  columnOrder?: string[];
  /** Hidden fields */
  hiddenFields?: string[];
  /** Pivot configuration */
  pivotConfig?: PivotConfig;
  /** Custom download filename */
  attachmentDownloadName?: string;
};

Usage Example:

import {
  type ExecuteAsyncSqlQueryRequestParams,
  type ExecuteAsyncSqlChartRequestParams,
  type DownloadAsyncQueryResultsRequestParams,
} from '@lightdash/common';

// Execute a custom SQL query asynchronously
async function executeCustomSql(sql: string) {
  const params: ExecuteAsyncSqlQueryRequestParams = {
    sql,
    limit: 5000,
    timezone: 'UTC',
  };

  const response = await api.post('/sql/execute-async', params);
  return response.results.jobId;
}

// Execute a saved SQL chart
async function executeSqlChart(chartUuid: string) {
  const params: ExecuteAsyncSqlChartRequestParams = {
    chartUuid,
    overrides: {
      limit: 100,
    },
  };

  const response = await api.post('/charts/sql/execute-async', params);
  return response.results.jobId;
}

// Download query results
async function downloadResults(jobId: string) {
  const params: DownloadAsyncQueryResultsRequestParams = {
    jobId,
    format: 'csv',
    filename: 'query-results.csv',
  };

  await api.get('/query-results/download', { params });
}

Project Parameter API Types

Types for managing project-level parameters.

/** Summary information for a project parameter */
type ProjectParameterSummary = {
  /** Parameter UUID */
  uuid: string;
  /** Parameter name */
  name: string;
  /** Parameter label for display */
  label: string;
  /** Parameter type */
  type: 'string' | 'number' | 'date';
  /** Default value */
  defaultValue: string | number | Date;
  /** Description of the parameter */
  description?: string;
};

/** Response for getting project parameters */
type ApiGetProjectParametersResults = {
  status: 'ok';
  results: ProjectParameterSummary[];
};

/** Response for getting project parameters list (alias) */
type ApiGetProjectParametersListResults = ApiGetProjectParametersResults;

Usage Example:

import {
  type ApiGetProjectParametersResults,
  type ProjectParameterSummary,
} from '@lightdash/common';

// Fetch all parameters for a project
async function getProjectParameters(projectUuid: string) {
  const response: ApiGetProjectParametersResults = await api.get(
    `/projects/${projectUuid}/parameters`,
  );

  return response.results;
}

// Use parameters in a query
function applyParameters(
  sql: string,
  parameters: ProjectParameterSummary[],
): string {
  let parameterizedSql = sql;

  parameters.forEach(param => {
    const placeholder = `\${${param.name}}`;
    parameterizedSql = parameterizedSql.replace(
      placeholder,
      String(param.defaultValue),
    );
  });

  return parameterizedSql;
}

Core API Types

Fundamental types used throughout the API for standardization and type safety.

UUID and Email Types

/** UUID type for entity identification (RFC 4122 compliant) */
type UUID = string; // Pattern: [0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-4[0-9A-Fa-f]{3}-[89ABab][0-9A-Fa-f]{3}-[0-9A-Fa-f]{12}

/** Email type with validation pattern */
type Email = string; // Pattern: ^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$

API Response Wrappers

Generic success response types for consistent API responses.

/** Generic success response wrapper */
type ApiSuccess<T> = {
  status: 'ok';
  results: T;
};

/** Success response with no data */
type ApiSuccessEmpty = {
  status: 'ok';
  results: undefined;
};

Sorting Types

Types for API sorting parameters.

/** Sort direction for API queries */
type ApiSortDirection = 'asc' | 'desc';

/** Sort configuration for API requests */
type ApiSort = {
  sort: string;
  order?: ApiSortDirection;
};

Date Zoom Configuration

Date zooming controls for time-based queries and visualizations.

/** Date zoom configuration for time-based queries */
type DateZoom = {
  /** Time granularity for zooming (day, week, month, etc.) */
  granularity?: DateGranularity;
  /** Field ID for the x-axis when zooming */
  xAxisFieldId?: string;
};

Usage Example:

import {
  type UUID,
  type Email,
  type ApiSuccess,
  type ApiSuccessEmpty,
  type ApiSort,
  type DateZoom,
} from '@lightdash/common';

// Using UUID type
function getChartByUuid(chartUuid: UUID) {
  return api.get(`/charts/${chartUuid}`);
}

// Using Email type
function sendInvite(email: Email) {
  return api.post('/invites', { email });
}

// Using ApiSuccess wrapper
async function fetchUsers(): Promise<ApiSuccess<User[]>> {
  return api.get('/users');
}

// Using ApiSuccessEmpty for operations with no return data
async function deleteChart(uuid: UUID): Promise<ApiSuccessEmpty> {
  return api.delete(`/charts/${uuid}`);
}

// Using ApiSort for sorting
const sortConfig: ApiSort = {
  sort: 'created_at',
  order: 'desc',
};

// Using DateZoom for time-based filtering
const dateZoom: DateZoom = {
  granularity: DateGranularity.DAY,
  xAxisFieldId: 'orders.created_date',
};

Email Verification Types

Types for email address verification and one-time password (OTP) functionality.

/**
 * Email verification status with optional OTP information
 */
type EmailStatus = {
  /** Email address being verified */
  email: string;
  /** Whether the email has been successfully verified */
  isVerified: boolean;
  /** One-time password information (if active) */
  otp?: {
    /** Time that the passcode was created */
    createdAt: Date;
    /** Number of times the passcode has been attempted */
    numberOfAttempts: number;
  };
};

/**
 * Email verification status with expiration information
 * Extends EmailStatus with OTP expiry details
 */
type EmailStatusExpiring = EmailStatus & {
  /** Enhanced OTP information including expiration */
  otp?: {
    /** Time that the passcode was created */
    createdAt: Date;
    /** Number of times the passcode has been attempted */
    numberOfAttempts: number;
    /** When the OTP expires */
    expiresAt: Date;
    /** Whether the OTP has expired */
    isExpired: boolean;
    /** Whether maximum attempts have been reached */
    isMaxAttempts: boolean;
  };
};

/**
 * API response for email verification status endpoint
 */
type ApiEmailStatusResponse = {
  status: 'ok';
  results: EmailStatusExpiring;
};

Usage Example:

import {
  type EmailStatus,
  type EmailStatusExpiring,
  type ApiEmailStatusResponse,
} from '@lightdash/common';

// Check email verification status
async function checkEmailStatus(email: string): Promise<EmailStatusExpiring> {
  const response: ApiEmailStatusResponse = await api.get(`/email-status/${email}`);
  return response.results;
}

// Verify OTP is valid
function isOtpValid(status: EmailStatusExpiring): boolean {
  if (!status.otp) return false;

  return (
    !status.otp.isExpired &&
    !status.otp.isMaxAttempts &&
    status.otp.numberOfAttempts < 5
  );
}

// Handle email verification flow
async function verifyEmail(email: string, otp: string): Promise<boolean> {
  const status = await checkEmailStatus(email);

  if (status.isVerified) {
    console.log('Email already verified');
    return true;
  }

  if (!isOtpValid(status)) {
    throw new Error('OTP expired or max attempts reached');
  }

  // Verify OTP code
  const result = await api.post('/verify-email', { email, otp });
  return result.status === 'ok';
}

CSV Download Types

Configuration for exporting metric query results to CSV format.

/**
 * Configuration for downloading metric query results as CSV
 * Includes formatting options, field selection, and pivot support
 */
type DownloadMetricCsv = {
  /** UUID of the user requesting the download */
  userUuid: string;
  /** UUID of the project containing the explore */
  projectUuid: string;
  /** Name/ID of the explore being queried */
  exploreId: string;
  /** The metric query to execute */
  metricQuery: MetricQuery;
  /** If true, export only raw values without formatting */
  onlyRaw: boolean;
  /** Maximum number of rows to include (null for unlimited) */
  csvLimit: number | null | undefined;
  /** Whether to include table names in column headers */
  showTableNames: boolean;
  /** Custom column labels (fieldId -> label) */
  customLabels: Record<string, string> | undefined;
  /** Order of columns in the CSV */
  columnOrder: string[];
  /** Fields to exclude from the CSV */
  hiddenFields: string[] | undefined;
  /** Name of the chart (for metadata/naming) */
  chartName: string | undefined;
  /** Whether this download is from a saved chart */
  fromSavedChart: boolean;
  /** Optional pivot configuration for pivoted results */
  pivotConfig?: PivotConfig;
};

Usage Example:

import { type DownloadMetricCsv, type MetricQuery } from '@lightdash/common';

// Configure CSV download
const csvConfig: DownloadMetricCsv = {
  userUuid: 'user-123',
  projectUuid: 'project-456',
  exploreId: 'orders',
  metricQuery: {
    exploreName: 'orders',
    dimensions: ['orders.customer_id', 'orders.created_date'],
    metrics: ['orders.total_revenue', 'orders.order_count'],
    filters: {},
    sorts: [],
    limit: 1000,
    tableCalculations: [],
  },
  onlyRaw: false, // Include formatted values
  csvLimit: 10000, // Limit to 10k rows
  showTableNames: true,
  customLabels: {
    'orders.customer_id': 'Customer',
    'orders.total_revenue': 'Revenue ($)',
  },
  columnOrder: [
    'orders.customer_id',
    'orders.created_date',
    'orders.order_count',
    'orders.total_revenue',
  ],
  hiddenFields: [], // Show all fields
  chartName: 'Revenue Analysis',
  fromSavedChart: true,
};

// Generate CSV download
async function downloadResults(config: DownloadMetricCsv): Promise<Blob> {
  const response = await api.post('/downloads/csv', config);
  return response.blob();
}

// Configure CSV for raw data export (no formatting)
const rawCsvConfig: DownloadMetricCsv = {
  ...csvConfig,
  onlyRaw: true, // Export raw values only
  csvLimit: null, // No limit
  showTableNames: false,
  customLabels: undefined,
};

Validation Types

Lightdash provides a comprehensive validation system that scans charts, dashboards, and tables within projects to detect broken references to metrics, dimensions, or other data model elements. The validation system helps maintain content quality by identifying issues like missing fields, broken filters, or invalid references.

Import

import {
  type ValidationResponse,
  type ValidationErrorChartResponse,
  type ValidationErrorDashboardResponse,
  type ValidationErrorTableResponse,
  type CreateValidation,
  type ApiValidateResponse,
  ValidationErrorType,
  DashboardFilterValidationErrorType,
  ValidationSourceType,
  ValidationTarget,
  isTableValidationError,
  isChartValidationError,
  isDashboardValidationError,
  isValidationTargetValid,
} from '@lightdash/common';

Validation Response Types

type ValidationResponseBase = {
  validationId: number;
  createdAt: Date;
  name: string;
  error: string;
  errorType: ValidationErrorType;
  projectUuid: string;
  spaceUuid?: string;
  source?: ValidationSourceType;
};

type ValidationErrorChartResponse = ValidationResponseBase & {
  chartUuid: string | undefined;
  chartKind?: ChartKind;
  fieldName?: string;
  lastUpdatedBy?: string;
  lastUpdatedAt?: Date;
  chartViews: number;
  chartName?: string;
};

type ValidationErrorDashboardResponse = ValidationResponseBase & {
  dashboardUuid: string | undefined;
  chartName?: string;
  fieldName?: string;
  tableName?: string;
  dashboardFilterErrorType?: DashboardFilterValidationErrorType;
  lastUpdatedBy?: string;
  lastUpdatedAt?: Date;
  dashboardViews: number;
};

type ValidationErrorTableResponse = Omit<ValidationResponseBase, 'name'> & {
  name: string | undefined;
};

type ValidationResponse =
  | ValidationErrorChartResponse
  | ValidationErrorDashboardResponse
  | ValidationErrorTableResponse;

Description:

  • ValidationResponseBase - Core properties shared across all validation error types
  • ValidationErrorChartResponse - Validation errors specific to saved charts with metadata and view counts
  • ValidationErrorDashboardResponse - Validation errors specific to dashboards with filter-specific error types
  • ValidationErrorTableResponse - Validation errors specific to data model tables
  • ValidationResponse - Union type representing any validation error response

Note: chartUuid and dashboardUuid can be undefined when the content is private.

Create Validation Types

type CreateTableValidation = Pick<
  ValidationErrorTableResponse,
  'error' | 'errorType' | 'projectUuid' | 'name' | 'source'
> & {
  modelName: string;
};

type CreateChartValidation = Pick<
  ValidationErrorChartResponse,
  | 'error'
  | 'errorType'
  | 'fieldName'
  | 'name'
  | 'projectUuid'
  | 'chartUuid'
  | 'source'
  | 'chartName'
>;

type CreateDashboardValidation = Pick<
  ValidationErrorDashboardResponse,
  | 'error'
  | 'errorType'
  | 'fieldName'
  | 'name'
  | 'projectUuid'
  | 'dashboardUuid'
  | 'chartName'
  | 'source'
>;

type CreateValidation =
  | CreateTableValidation
  | CreateChartValidation
  | CreateDashboardValidation;

Types for creating new validation errors, omitting server-generated fields.

API Response Types

type ApiValidateResponse = {
  status: 'ok';
  results: ValidationResponse[];
};

Response from GET /api/v1/projects/{projectUuid}/validate containing all validation errors.

Validation Enums

enum ValidationErrorType {
  Chart = 'chart',
  Sorting = 'sorting',
  Filter = 'filter',
  Metric = 'metric',
  Model = 'model',
  Dimension = 'dimension',
  CustomMetric = 'custom metric',
}

enum DashboardFilterValidationErrorType {
  FieldDoesNotExist = 'field_does_not_exist',
  TableNotUsedByAnyChart = 'table_not_used_by_any_chart',
  TableDoesNotExist = 'table_does_not_exist',
}

enum ValidationSourceType {
  Chart = 'chart',
  Dashboard = 'dashboard',
  Table = 'table',
}

enum ValidationTarget {
  CHARTS = 'charts',
  DASHBOARDS = 'dashboards',
  TABLES = 'tables',
}

Description:

  • ValidationErrorType - Categories of validation errors
  • DashboardFilterValidationErrorType - Specific error types for dashboard filters
  • ValidationSourceType - The source content type where the error originated
  • ValidationTarget - Target types for validation operations

Validation Type Guards

function isTableValidationError(
  error: ValidationResponse | CreateValidation,
): error is ValidationErrorTableResponse | CreateTableValidation;

function isChartValidationError(
  error: ValidationResponse | CreateValidation,
): error is ValidationErrorChartResponse | CreateChartValidation;

function isDashboardValidationError(
  error: ValidationResponse | CreateValidation,
): error is ValidationErrorDashboardResponse | CreateDashboardValidation;

function isValidationTargetValid(validationTarget: string): boolean;

Type guard functions for narrowing validation error types.

Usage Example:

const validationErrors: ValidationResponse[] = await getValidationErrors();

validationErrors.forEach((error) => {
  if (isChartValidationError(error)) {
    console.log(`Chart ${error.chartName} has error: ${error.error}`);
    console.log(`Views: ${error.chartViews}`);
  } else if (isDashboardValidationError(error)) {
    console.log(`Dashboard error: ${error.error}`);
    if (error.dashboardFilterErrorType) {
      console.log(`Filter error type: ${error.dashboardFilterErrorType}`);
    }
  } else if (isTableValidationError(error)) {
    console.log(`Table validation error: ${error.error}`);
  }
});

Install with Tessl CLI

npx tessl i tessl/npm-lightdash--common

docs

api

index.md

tile.json