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

specialized.mddocs/api/types/

Specialized Types

This document contains utility types, conditional formatting, parameters, Google Drive integration, comments, and AI Agent types.

Capabilities

This module provides the following functionality:

Utility Types

type ArgumentsOf<F extends Function> = F extends (...args: infer A) => unknown
  ? A
  : never;

Generic utility type for extracting function argument types.

Conditional Formatting Types

Visual formatting rules for charts and tables with single color rules, color gradients, field comparisons, and automatic min/max calculation.

type ConditionalFormattingMinMax<T = number> = {
  min: T;
  max: T;
};

type ConditionalFormattingColorRange = {
  start: string;
  end: string;
};

type ConditionalFormattingWithValues<T = number | string> =
  BaseFilterRule<FilterOperator, T> & {
    values: T[];
  };

type ConditionalFormattingWithCompareTarget<T = number | string> =
  BaseFilterRule<FilterOperator, T> & {
    compareTarget: FieldTarget | null;
    values?: T[];
  };

type ConditionalFormattingWithFilterOperator<T = number | string> =
  | ConditionalFormattingWithValues<T>
  | ConditionalFormattingWithCompareTarget<T>;

type ConditionalFormattingConfigWithSingleColor = {
  target: FieldTarget | null;
  color: string;
  rules: ConditionalFormattingWithFilterOperator[];
};

type ConditionalFormattingConfigWithColorRange = {
  target: FieldTarget | null;
  color: ConditionalFormattingColorRange;
  rule: ConditionalFormattingMinMax<number | 'auto'>;
};

type ConditionalFormattingConfig =
  | ConditionalFormattingConfigWithSingleColor
  | ConditionalFormattingConfigWithColorRange;

enum ConditionalFormattingConfigType {
  Single = 'single',
  Range = 'range',
}

function isConditionalFormattingWithValues(
  rule: ConditionalFormattingWithFilterOperator
): rule is ConditionalFormattingWithValues;

function isConditionalFormattingWithCompareTarget(
  rule: ConditionalFormattingWithFilterOperator
): rule is ConditionalFormattingWithCompareTarget;

function isConditionalFormattingConfigWithSingleColor(
  rule: ConditionalFormattingConfig
): rule is ConditionalFormattingConfigWithSingleColor;

function isConditionalFormattingConfigWithColorRange(
  config: ConditionalFormattingConfig
): config is ConditionalFormattingConfigWithColorRange;

function getConditionalFormattingConfigType(
  rule: ConditionalFormattingConfig
): ConditionalFormattingConfigType;

Parameters Types

Types for parameterized queries and dashboards enabling dynamic SQL and dashboard filters.

/** Base type for parameter values - can be extended later for new types (dates, booleans, etc.) */
type ParameterValue = string | number | string[] | number[];

/** Used anywhere we have parameters */
type ParametersValuesMap = Record<string, ParameterValue>;

type ParameterDefinitions = Record<string, LightdashProjectParameter>;

/** Used in dashboards where we may have properties specific to dashboard tiles */
interface DashboardParameterValue {
  parameterName: string;
  value: ParameterValue;
}

type DashboardParameters = Record<string, DashboardParameterValue>;

Google Drive Integration Types

Types for exporting metrics and query results to Google Sheets and Google Drive.

/** API response for Google Drive access token */
interface ApiGdriveAccessTokenResponse {
  status: 'ok';
  results: string;
}

/** Custom labels mapping for columns in Google Sheets export */
type CustomLabel = {
  [key: string]: string;
};

/** Configuration for uploading metrics to Google Sheets */
interface UploadMetricGsheet {
  projectUuid: string;
  exploreId: string;
  metricQuery: MetricQueryResponse;
  showTableNames: boolean;
  columnOrder: string[];
  customLabels?: CustomLabel;
  hiddenFields?: string[];
  pivotConfig?: PivotConfig;
}

/** Payload for uploading metrics to Google Sheets with task tracking */
type UploadMetricGsheetPayload = TraceTaskBase & UploadMetricGsheet;

Comments Types

Types for the commenting and collaboration features on dashboards and charts.

/** A comment on a dashboard or chart with support for replies and mentions */
interface Comment {
  commentId: string;
  text: string;
  textHtml: string;
  createdAt: Date;
  user: {
    name: string;
  };
  replyTo: string | undefined;
  replies?: Comment[];
  resolved: boolean;
  canRemove: boolean;
  mentions: string[];
}

Pinning Types

Types for pinning dashboards, charts, and spaces to project home pages for quick access.

/**
 * A pinned list that belongs to a project
 */
interface PinnedList {
  /** UUID of the pinned list */
  pinnedListUuid: string;
  /** UUID of the project this list belongs to */
  projectUuid: string;
}

/**
 * An item pinned to a list
 */
interface PinnedItem {
  /** UUID of the pinned item */
  pinnedItemUuid: string;
  /** UUID of the pinned list this item belongs to */
  pinnedListUuid: string;
  /** UUID of the saved chart (if this is a chart) */
  savedChartUuid?: string;
  /** UUID of the dashboard (if this is a dashboard) */
  dashboardUuid?: string;
  /** UUID of the space (if this is a space) */
  spaceUuid?: string;
  /** Timestamp when the item was pinned */
  createdAt: Date;
}

/**
 * A pinned list with its items
 */
interface PinnedListAndItems extends PinnedList {
  /** Array of pinned items */
  items: PinnedItem[];
}

/**
 * Data required to pin a chart
 */
interface CreateChartPinnedItem {
  /** UUID of the project */
  projectUuid: string;
  /** UUID of the chart to pin */
  savedChartUuid: string;
}

/**
 * Data required to pin a dashboard
 */
interface CreateDashboardPinnedItem {
  /** UUID of the project */
  projectUuid: string;
  /** UUID of the dashboard to pin */
  dashboardUuid: string;
}

/**
 * Data required to pin a space
 */
interface CreateSpacePinnedItem {
  /** UUID of the project */
  projectUuid: string;
  /** UUID of the space to pin */
  spaceUuid: string;
}

/**
 * Data required to delete a pinned chart
 */
interface DeleteChartPinnedItem {
  /** UUID of the pinned list */
  pinnedListUuid: string;
  /** UUID of the chart to unpin */
  savedChartUuid: string;
}

/**
 * Data required to delete a pinned dashboard
 */
interface DeleteDashboardPinnedItem {
  /** UUID of the pinned list */
  pinnedListUuid: string;
  /** UUID of the dashboard to unpin */
  dashboardUuid: string;
}

/**
 * Data required to delete a pinned space
 */
interface DeleteSpacePinnedItem {
  /** UUID of the pinned list */
  pinnedListUuid: string;
  /** UUID of the space to unpin */
  spaceUuid: string;
}

/**
 * Union type for deleting any pinned item
 */
type DeletePinnedItem =
  | DeleteChartPinnedItem
  | DeleteDashboardPinnedItem
  | DeleteSpacePinnedItem;

/**
 * Union type for creating any pinned item
 */
type CreatePinnedItem =
  | CreateChartPinnedItem
  | CreateDashboardPinnedItem
  | CreateSpacePinnedItem;

/**
 * Data for updating the order of a pinned item
 */
interface UpdatePinnedItemOrder {
  /** Type of the resource being reordered */
  type: ResourceViewItemType;
  /** Data containing uuid and pinnedListOrder */
  data: Pick<ResourceViewItem['data'], 'uuid' | 'pinnedListOrder'>;
}

/**
 * Type guard to check if item is a pinned chart
 */
function isCreateChartPinnedItem(
  item: CreatePinnedItem
): item is CreateChartPinnedItem;

/**
 * Type guard to check if delete target is a chart
 */
function isDeleteChartPinnedItem(
  item: DeletePinnedItem
): item is DeleteChartPinnedItem;

/**
 * Type guard to check if item is a pinned space
 */
function isCreateSpacePinnedItem(
  item: CreatePinnedItem
): item is CreateSpacePinnedItem;

/**
 * Type guard to check if delete target is a space
 */
function isDeleteSpacePinnedItem(
  item: DeletePinnedItem
): item is DeleteSpacePinnedItem;

/**
 * API response for pinned items
 */
interface ApiPinnedItems {
  status: 'ok';
  results: PinnedItems;
}

/**
 * Array of pinned items with full resource details
 */
type PinnedItems = Array<
  ResourceViewDashboardItem | ResourceViewChartItem | ResourceViewSpaceItem
>;

/**
 * Information returned when toggling pin status
 */
interface TogglePinnedItemInfo {
  /** UUID of the pinned list */
  pinnedListUuid: string;
  /** UUID of the project */
  projectUuid: string;
  /** UUID of the space */
  spaceUuid: string;
  /** Whether the item is currently pinned */
  isPinned: boolean;
}

/**
 * API response for toggling pin status
 */
interface ApiTogglePinnedItem {
  status: 'ok';
  results: TogglePinnedItemInfo;
}

AI Agent Types (Enterprise Edition)

Types for the AI Agent system including agent configuration, threads, messages, tool calls, evaluations, and artifacts.

// Base Agent Types
interface BaseAiAgent {
  uuid: string;
  projectUuid: string;
  organizationUuid: string;
  name: string;
  description: string | null;
  imageUrl: string | null;
  tags: string[] | null;
  integrations: Array<{
    type: 'slack';
    channelId: string;
  }>;
  createdAt: Date;
  updatedAt: Date;
  instruction: string | null;
  provider: string;
  model: string;
  groupAccess: string[];
  userAccess: string[];
  spaceAccess: string[];
  enableDataAccess: boolean;
  enableSelfImprovement: boolean;
  enableReasoning: boolean;
  version: number;
}

type AiAgent = Pick<
  BaseAiAgent,
  | 'uuid'
  | 'projectUuid'
  | 'organizationUuid'
  | 'integrations'
  | 'tags'
  | 'name'
  | 'description'
  | 'createdAt'
  | 'updatedAt'
  | 'instruction'
  | 'imageUrl'
  | 'groupAccess'
  | 'userAccess'
  | 'spaceAccess'
  | 'enableDataAccess'
  | 'enableSelfImprovement'
  | 'enableReasoning'
  | 'version'
>;

type AiAgentSummary = Pick<
  AiAgent,
  | 'uuid'
  | 'name'
  | 'description'
  | 'integrations'
  | 'tags'
  | 'projectUuid'
  | 'organizationUuid'
  | 'createdAt'
  | 'updatedAt'
  | 'instruction'
  | 'imageUrl'
  | 'groupAccess'
  | 'userAccess'
  | 'spaceAccess'
  | 'enableDataAccess'
  | 'enableSelfImprovement'
  | 'enableReasoning'
  | 'version'
>;

// Agent User and Message Types
interface AiAgentUser {
  uuid: string;
  name: string;
}

interface AiAgentMessageUser<TUser extends AiAgentUser = AiAgentUser> {
  role: 'user';
  uuid: string;
  threadUuid: string;
  message: string;
  createdAt: string;
  user: TUser;
}

interface AiAgentMessageAssistantArtifact {
  artifactUuid: string;
  versionNumber: number;
  versionUuid: string;
  title: string | null;
  description: string | null;
  artifactType: 'chart' | 'dashboard';
}

interface AiAgentMessageAssistant {
  role: 'assistant';
  status: 'idle' | 'pending' | 'error';
  uuid: string;
  threadUuid: string;
  message: string | null;
  createdAt: string;
  humanScore: number | null;
  humanFeedback?: string | null;
  toolCalls: AiAgentToolCall[];
  toolResults: AiAgentToolResult[];
  reasoning: AiAgentReasoning[];
  savedQueryUuid: string | null;
  artifacts: AiAgentMessageAssistantArtifact[] | null;
  referencedArtifacts: AiAgentMessageAssistantArtifact[] | null;
  modelConfig: {
    modelName: string;
    modelProvider: string;
    reasoning?: boolean;
  } | null;
}

type AiAgentMessage<TUser extends AiAgentUser = AiAgentUser> =
  | AiAgentMessageUser<TUser>
  | AiAgentMessageAssistant;

// Thread Types
interface AiAgentThreadSummary<TUser extends AiAgentUser = AiAgentUser> {
  uuid: string;
  agentUuid: string;
  createdAt: string;
  createdFrom: string;
  title: string | null;
  titleGeneratedAt: string | null;
  firstMessage: {
    uuid: string;
    message: string;
  };
  user: TUser;
}

type AiAgentThread<TUser extends AiAgentUser = AiAgentUser> = AiAgentThreadSummary<TUser> & {
  messages: AiAgentMessage<TUser>[];
};

// Tool Call and Result Types
interface AiAgentToolCall {
  uuid: string;
  promptUuid: string;
  toolCallId: string;
  createdAt: Date;
  toolName: string;
  toolArgs: object;
}

type AiAgentToolResult = {
  uuid: string;
  promptUuid: string;
  result: string;
  createdAt: Date;
  toolCallId: string;
} & (
  | {
      toolName: 'proposeChange';
      metadata: object;
    }
  | {
      toolName: string;
      metadata: object;
    }
);

interface AiAgentReasoning {
  uuid: string;
  promptUuid: string;
  reasoningId: string;
  text: string;
  createdAt: Date;
}

// Artifact Types
interface AiArtifact {
  artifactUuid: string;
  threadUuid: string;
  promptUuid: string | null;
  artifactType: 'chart' | 'dashboard';
  savedQueryUuid: string | null;
  savedDashboardUuid: string | null;
  createdAt: Date;
  versionNumber: number;
  versionUuid: string;
  title: string | null;
  description: string | null;
  chartConfig: Record<string, unknown> | null;
  dashboardConfig: Record<string, unknown> | null;
  versionCreatedAt: Date;
  verifiedByUserUuid: string | null;
  verifiedAt: Date | null;
}

interface AiAgentVerifiedArtifact {
  artifactUuid: string;
  versionUuid: string;
  artifactType: 'chart' | 'dashboard';
  title: string | null;
  description: string | null;
  verifiedAt: Date;
  verifiedBy: {
    userUuid: string;
    firstName: string;
    lastName: string;
  };
  referenceCount: number;
  threadUuid: string;
  promptUuid: string | null;
}

// Evaluation Types
type AiAgentEvaluationPrompt = {
  evalPromptUuid: string;
  createdAt: Date;
} & (
  | {
      type: 'string';
      prompt: string;
      expectedResponse: string | null;
    }
  | {
      type: 'thread';
      promptUuid: string;
      threadUuid: string;
      expectedResponse: string | null;
    }
);

interface AiAgentEvaluation {
  evalUuid: string;
  agentUuid: string;
  title: string;
  description: string | null;
  createdAt: Date;
  updatedAt: Date;
  prompts: AiAgentEvaluationPrompt[];
}

interface AiAgentEvaluationSummary {
  evalUuid: string;
  agentUuid: string;
  title: string;
  description: string | null;
  createdAt: Date;
  updatedAt: Date;
}

interface AiAgentEvaluationRunSummary {
  runUuid: string;
  evalUuid: string;
  status: 'pending' | 'running' | 'completed' | 'failed';
  completedAt: Date | null;
  createdAt: Date;
  passedAssessments: number;
  failedAssessments: number;
}

type AiAgentEvaluationRun = AiAgentEvaluationRunSummary & {
  results: AiAgentEvaluationRunResult[];
};

interface AiAgentEvaluationRunResult {
  resultUuid: string;
  evalPromptUuid: string | null;
  threadUuid: string | null;
  status: 'pending' | 'running' | 'completed' | 'assessing' | 'failed';
  errorMessage: string | null;
  completedAt: Date | null;
  createdAt: Date;
  assessment: object | null;
  prompt: string | null;
  expectedResponse: string | null;
}

type CreateEvaluationPrompt =
  | { prompt: string; expectedResponse: string | null }
  | {
      promptUuid: string;
      threadUuid: string;
      expectedResponse: string | null;
    };

function isStringPrompt(
  prompt: CreateEvaluationPrompt
): prompt is { prompt: string; expectedResponse: string | null };

function isThreadPrompt(
  prompt: CreateEvaluationPrompt
): prompt is {
  promptUuid: string;
  threadUuid: string;
  expectedResponse: string | null;
};

// Agent Configuration Types
interface AiAgentUserPreferences {
  defaultAgentUuid: string;
}

interface AiModelOption {
  name: string;
  displayName: string;
  description: string;
  provider: string;
  default: boolean;
  supportsReasoning: boolean;
}

interface AiAgentExploreAccessSummary {
  exploreName: string;
  joinedTables: string[];
  dimensions: string[];
  metrics: string[];
}

interface AgentSummaryContext {
  uuid: string;
  projectUuid: string;
  name: string;
  description: string | null;
  explores: string[];
  verifiedQuestions: string[];
  instruction: string | null;
}

type AiAgentWithContext = AiAgentSummary & {
  context: AgentSummaryContext;
};

// API Request/Response Types
type ApiAiAgentResponse = ApiSuccess<AiAgent>;
type ApiAiAgentSummaryResponse = ApiSuccess<AiAgentSummary[]>;

type ApiCreateAiAgent = Pick<
  AiAgent,
  | 'projectUuid'
  | 'integrations'
  | 'tags'
  | 'name'
  | 'description'
  | 'instruction'
  | 'imageUrl'
  | 'groupAccess'
  | 'userAccess'
  | 'spaceAccess'
  | 'enableDataAccess'
  | 'enableSelfImprovement'
  | 'enableReasoning'
  | 'version'
>;

type ApiUpdateAiAgent = Partial<
  Pick<
    AiAgent,
    | 'projectUuid'
    | 'integrations'
    | 'tags'
    | 'name'
    | 'description'
    | 'instruction'
    | 'imageUrl'
    | 'groupAccess'
    | 'userAccess'
    | 'spaceAccess'
    | 'enableDataAccess'
    | 'enableSelfImprovement'
    | 'enableReasoning'
    | 'version'
  >
> & {
  uuid: string;
};

type ApiCreateAiAgentResponse = ApiSuccess<AiAgent>;
type ApiAiAgentThreadSummaryListResponse = ApiSuccess<AiAgentThreadSummary[]>;
type ApiAiAgentThreadResponse = ApiSuccess<AiAgentThread>;

interface ApiAiAgentThreadCreateRequest {
  prompt?: string;
  modelConfig?: {
    modelName: string;
    modelProvider: string;
    reasoning?: boolean;
  };
}

type ApiAiAgentThreadCreateResponse = ApiSuccess<AiAgentThreadSummary>;

interface ApiAiAgentThreadMessageCreateRequest {
  prompt: string;
  modelConfig?: {
    modelName: string;
    modelProvider: string;
    reasoning?: boolean;
  };
}

type ApiAiAgentThreadMessageCreateResponse = ApiSuccess<
  AiAgentMessageUser<AiAgentUser>
>;

interface ApiAiAgentStartThreadResponse {
  status: 'ok';
  results: {
    jobId: string;
    threadUuid: string;
  };
}

interface ApiAiAgentThreadGenerateResponse {
  status: 'ok';
  results: {
    response: string;
  };
}

interface ApiAiAgentThreadGenerateTitleResponse {
  status: 'ok';
  results: {
    title: string;
  };
}

interface ApiAiAgentThreadMessageViz {
  type: string;
  metricQuery: object;
  chartOptions?: object;
  results: {
    rows: Record<string, unknown>[];
    cacheMetadata: object;
    fields: object;
  };
}

type ApiAiAgentThreadMessageVizResponse = ApiSuccess<ApiAiAgentThreadMessageViz>;
type ApiAiAgentThreadMessageVizQueryResponse = ApiSuccess<object>;
type ApiGetUserAgentPreferencesResponse =
  | ApiSuccess<AiAgentUserPreferences>
  | ApiSuccessEmpty;
type ApiUpdateUserAgentPreferences = AiAgentUserPreferences;
type ApiUpdateUserAgentPreferencesResponse = ApiSuccessEmpty;
type ApiAiAgentExploreAccessSummaryResponse = ApiSuccess<
  AiAgentExploreAccessSummary[]
>;
type ApiAiAgentArtifactResponse = ApiSuccess<AiArtifact>;
type ApiAiAgentVerifiedArtifactsResponse = ApiSuccess<object>;
type ApiAiAgentVerifiedQuestionsResponse = ApiSuccess<
  { question: string; uuid: string }[]
>;

// Evaluation API Types
interface ApiCreateEvaluationRequest {
  title: string;
  description?: string;
  prompts: CreateEvaluationPrompt[];
}

interface ApiUpdateEvaluationRequest {
  title?: string;
  description?: string;
  prompts?: CreateEvaluationPrompt[];
}

interface ApiAppendEvaluationRequest {
  prompts: CreateEvaluationPrompt[];
}

type ApiAiAgentEvaluationSummaryListResponse = ApiSuccess<
  AiAgentEvaluationSummary[]
>;
type ApiAiAgentEvaluationResponse = ApiSuccess<AiAgentEvaluation>;
type ApiAiAgentEvaluationRunResponse = ApiSuccess<AiAgentEvaluationRunSummary>;
type ApiAiAgentEvaluationRunSummaryListResponse = ApiSuccess<object>;
type ApiAiAgentEvaluationRunResultsResponse = ApiSuccess<AiAgentEvaluationRun>;
type ApiCreateEvaluationResponse = ApiSuccess<
  Pick<AiAgentEvaluation, 'evalUuid'>
>;
type ApiUpdateEvaluationResponse = ApiSuccess<AiAgentEvaluation>;
type ApiCloneThreadResponse = ApiSuccess<AiAgentThreadSummary>;

interface ApiAppendInstructionRequest {
  instruction: string;
}

interface ApiAppendInstructionResponse {
  status: 'ok';
  results: {
    updatedInstruction: string;
  };
}

interface ApiRevertChangeRequest {
  changeUuid: string;
}

type ApiRevertChangeResponse = ApiSuccessEmpty;

type ApiAiAgentModelOptionsResponse = ApiSuccess<AiModelOption[]>;

Resource View Item Types

Types for unified resource views displaying charts, dashboards, and spaces in lists with metadata.

import { type ContentType as ResourceViewItemType } from '@lightdash/common';

/** Export ContentType as ResourceViewItemType for resource views */
export { ResourceViewItemType };

/**
 * Category classification for resources in views
 */
enum ResourceItemCategory {
  MOST_POPULAR = 'mostPopular',
  RECENTLY_UPDATED = 'recentlyUpdated',
  PINNED = 'pinned',
}

/**
 * Resource view item for a chart with summary details
 */
interface ResourceViewChartItem {
  type: ResourceViewItemType.CHART;
  data: Pick<
    SpaceQuery,
    | 'uuid'
    | 'name'
    | 'chartType'
    | 'chartKind'
    | 'firstViewedAt'
    | 'views'
    | 'pinnedListUuid'
    | 'pinnedListOrder'
    | 'spaceUuid'
    | 'description'
    | 'updatedAt'
    | 'updatedByUser'
    | 'validationErrors'
    | 'slug'
  > & { source?: ChartSourceType };
  category?: ResourceItemCategory;
}

/**
 * Resource view item for a dashboard with summary details
 */
interface ResourceViewDashboardItem {
  type: ResourceViewItemType.DASHBOARD;
  data: Pick<
    DashboardBasicDetails,
    | 'uuid'
    | 'spaceUuid'
    | 'description'
    | 'name'
    | 'views'
    | 'firstViewedAt'
    | 'pinnedListUuid'
    | 'pinnedListOrder'
    | 'updatedAt'
    | 'updatedByUser'
    | 'validationErrors'
  >;
  category?: ResourceItemCategory;
}

/**
 * Resource view item for a space with summary details
 */
interface ResourceViewSpaceItem {
  type: ResourceViewItemType.SPACE;
  data: Pick<
    Space,
    | 'projectUuid'
    | 'uuid'
    | 'name'
    | 'isPrivate'
    | 'pinnedListUuid'
    | 'pinnedListOrder'
    | 'organizationUuid'
    | 'parentSpaceUuid'
    | 'path'
  > & {
    /** User UUIDs with access */
    access: string[];
    /** Total number of users with access */
    accessListLength: number;
    /** Number of dashboards in the space */
    dashboardCount: number;
    /** Number of charts in the space */
    chartCount: number;
  };
}

/**
 * Union type for any resource view item
 */
type ResourceViewItem =
  | ResourceViewChartItem
  | ResourceViewDashboardItem
  | ResourceViewSpaceItem;

/**
 * Type guard for chart resource items
 */
function isResourceViewItemChart(
  item: ResourceViewItem
): item is ResourceViewChartItem;

/**
 * Type guard for dashboard resource items
 */
function isResourceViewItemDashboard(
  item: ResourceViewItem
): item is ResourceViewDashboardItem;

/**
 * Type guard for space resource items
 */
function isResourceViewSpaceItem(
  item: ResourceViewItem
): item is ResourceViewSpaceItem;

/**
 * Wrap a resource object in a ResourceViewItem
 * @param resource - The resource data
 * @param type - The resource type
 * @returns Wrapped resource view item
 */
function wrapResource<T>(
  resource: T,
  type: ResourceViewItemType
): ResourceViewItem;

/**
 * Wrap multiple resources in ResourceViewItems
 * @param resources - Array of resource data
 * @param type - The resource type
 * @returns Array of wrapped resource view items
 */
function wrapResourceView(
  resources: any[],
  type: ResourceViewItemType
): ResourceViewItem[];

/**
 * Convert a SpaceSummary to ResourceViewSpaceItem data
 */
function spaceToResourceViewItem(
  space: SpaceSummary
): ResourceViewSpaceItem['data'];

/**
 * Convert SummaryContent to a ResourceViewItem
 */
function contentToResourceViewItem(content: SummaryContent): ResourceViewItem;

/**
 * Extract the data from a ResourceViewItem
 */
function resourceToContent(resource: ResourceViewItem): any;

/**
 * Type for most popular and recently updated resources
 */
interface MostPopularAndRecentlyUpdated {
  mostPopular: (DashboardBasicDetails | SpaceQuery)[];
  recentlyUpdated: (DashboardBasicDetails | SpaceQuery)[];
}

Usage Example:

import {
  type ResourceViewItem,
  type ResourceViewChartItem,
  isResourceViewItemChart,
  wrapResource,
  ResourceViewItemType,
} from '@lightdash/common';

// Wrap a chart in a resource view item
const chartItem: ResourceViewChartItem = wrapResource(
  chartData,
  ResourceViewItemType.CHART
);

// Type-safe handling of resource items
function handleResource(item: ResourceViewItem) {
  if (isResourceViewItemChart(item)) {
    console.log(`Chart: ${item.data.name}`);
    console.log(`Views: ${item.data.views}`);
    console.log(`Chart type: ${item.data.chartType}`);
  } else if (isResourceViewItemDashboard(item)) {
    console.log(`Dashboard: ${item.data.name}`);
  } else {
    console.log(`Space: ${item.data.name}`);
    console.log(`Contains ${item.data.chartCount} charts`);
  }
}

// Display resources by category
function displayResourcesByCategory(items: ResourceViewItem[]) {
  const pinned = items.filter(item => item.category === 'pinned');
  const popular = items.filter(item => item.category === 'mostPopular');
  const recent = items.filter(item => item.category === 'recentlyUpdated');

  console.log(`Pinned: ${pinned.length}`);
  console.log(`Most Popular: ${popular.length}`);
  console.log(`Recently Updated: ${recent.length}`);
}

Spotlight Table Configuration Types

Types for configuring the Spotlight metrics table column visibility.

/**
 * Available columns in the Spotlight metrics table
 * These must match the keys of CatalogField type
 */
enum SpotlightTableColumns {
  METRIC = 'label',
  TABLE = 'tableLabel',
  DESCRIPTION = 'description',
  CATEGORIES = 'categories',
  CHART_USAGE = 'chartUsage',
}

/**
 * Configuration for a single Spotlight table column
 */
type ColumnConfig = Array<{
  column: SpotlightTableColumns;
  isVisible: boolean;
}>;

/**
 * Spotlight table configuration for a project
 */
interface SpotlightTableConfig {
  /** UUID of the configuration */
  spotlightTableConfigUuid: string;
  /** UUID of the project this config belongs to */
  projectUuid: string;
  /** Column visibility configuration */
  columnConfig: ColumnConfig;
}

/**
 * Default column configuration for Spotlight tables
 * METRIC: visible, TABLE: hidden, DESCRIPTION: visible,
 * CATEGORIES: visible, CHART_USAGE: visible
 */
const DEFAULT_SPOTLIGHT_TABLE_COLUMN_CONFIG: ColumnConfig = [
  { column: SpotlightTableColumns.METRIC, isVisible: true },
  { column: SpotlightTableColumns.TABLE, isVisible: false },
  { column: SpotlightTableColumns.DESCRIPTION, isVisible: true },
  { column: SpotlightTableColumns.CATEGORIES, isVisible: true },
  { column: SpotlightTableColumns.CHART_USAGE, isVisible: true },
];

Usage Example:

import {
  type SpotlightTableConfig,
  SpotlightTableColumns,
  DEFAULT_SPOTLIGHT_TABLE_COLUMN_CONFIG,
} from '@lightdash/common';

// Use default configuration
const defaultConfig = DEFAULT_SPOTLIGHT_TABLE_COLUMN_CONFIG;

// Create custom configuration
const customConfig: SpotlightTableConfig = {
  spotlightTableConfigUuid: 'uuid-123',
  projectUuid: 'project-456',
  columnConfig: [
    { column: SpotlightTableColumns.METRIC, isVisible: true },
    { column: SpotlightTableColumns.TABLE, isVisible: true }, // Show table column
    { column: SpotlightTableColumns.DESCRIPTION, isVisible: true },
    { column: SpotlightTableColumns.CATEGORIES, isVisible: false }, // Hide categories
    { column: SpotlightTableColumns.CHART_USAGE, isVisible: true },
  ],
};

// Check which columns are visible
function getVisibleColumns(config: SpotlightTableConfig): SpotlightTableColumns[] {
  return config.columnConfig
    .filter(col => col.isVisible)
    .map(col => col.column);
}

TimeZone Types

Timezone support for date/time formatting and display across the Lightdash platform.

/**
 * Supported timezone values for date/time display
 * Covers major timezones across all continents
 */
enum TimeZone {
  'UTC' = 'UTC',

  // Americas - Pacific
  'Pacific/Pago_Pago' = 'Pacific/Pago_Pago',
  'Pacific/Honolulu' = 'Pacific/Honolulu',
  'America/Anchorage' = 'America/Anchorage',
  'America/Los_Angeles' = 'America/Los_Angeles',
  'America/Denver' = 'America/Denver',
  'America/Chicago' = 'America/Chicago',
  'America/New_York' = 'America/New_York',

  // Americas - Atlantic & South
  'America/Santo_Domingo' = 'America/Santo_Domingo',
  'America/Buenos_Aires' = 'America/Buenos_Aires',
  'America/Noronha' = 'America/Noronha',
  'Atlantic/Cape_Verde' = 'Atlantic/Cape_Verde',

  // Europe
  'Europe/London' = 'Europe/London',
  'Europe/Paris' = 'Europe/Paris',
  'Europe/Athens' = 'Europe/Athens',
  'Europe/Moscow' = 'Europe/Moscow',

  // Asia
  'Asia/Dubai' = 'Asia/Dubai',
  'Asia/Karachi' = 'Asia/Karachi',
  'Asia/Dhaka' = 'Asia/Dhaka',
  'Asia/Bangkok' = 'Asia/Bangkok',
  'Asia/Shanghai' = 'Asia/Shanghai',
  'Asia/Tokyo' = 'Asia/Tokyo',

  // Pacific
  'Australia/Sydney' = 'Australia/Sydney',
  'Pacific/Noumea' = 'Pacific/Noumea',
  'Pacific/Auckland' = 'Pacific/Auckland',
  'Pacific/Apia' = 'Pacific/Apia',
  'Pacific/Kiritimati' = 'Pacific/Kiritimati',
}

/**
 * Type guard to check if a string is a valid TimeZone value
 */
function isTimeZone(timezone: string): timezone is TimeZone;

Usage Example:

import { TimeZone, isTimeZone } from '@lightdash/common';

// Use specific timezone
const userTimezone: TimeZone = TimeZone.UTC;
const australianTz: TimeZone = TimeZone['Australia/Sydney'];
const newYorkTz: TimeZone = TimeZone['America/New_York'];

// Validate timezone string
function setUserTimezone(tz: string): TimeZone {
  if (isTimeZone(tz)) {
    return tz;
  }
  throw new Error(`Invalid timezone: ${tz}`);
}

// Get all available timezones
const allTimezones = Object.values(TimeZone);
console.log(`Available timezones: ${allTimezones.length}`);

Slack Settings Types

Configuration for Slack workspace integration including AI features and channel mappings.

/**
 * Slack workspace integration settings for an organization
 * Includes OAuth scopes, notification channels, and AI feature consent
 */
type SlackSettings = {
  /** UUID of the organization this Slack workspace is connected to */
  organizationUuid: string;
  /** Name of the Slack team/workspace */
  slackTeamName: string;
  /** Custom app name (optional override) */
  appName?: string;
  /** When this Slack connection was created */
  createdAt: Date;
  /** OAuth access token (sensitive - handle securely) */
  token?: string;
  /** OAuth scopes granted to the Lightdash app */
  scopes: string[];
  /** Default channel for sending notifications */
  notificationChannel: string | undefined;
  /** URL for the app's profile photo in Slack */
  appProfilePhotoUrl: string | undefined;
  /** Mapping of Slack channels to Lightdash projects */
  slackChannelProjectMappings?: SlackChannelProjectMapping[];
  /** Whether users have consented to AI thread access */
  aiThreadAccessConsent?: boolean;
  /** Whether all required OAuth scopes are granted */
  hasRequiredScopes: boolean;
  /** Whether AI features require explicit OAuth per user */
  aiRequireOAuth?: boolean;
  /** Channel ID for multi-agent AI conversations */
  aiMultiAgentChannelId?: string;
};

Usage Example:

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

// Configure Slack integration
const slackConfig: SlackSettings = {
  organizationUuid: 'org-uuid-123',
  slackTeamName: 'Acme Corp',
  appName: 'Lightdash',
  createdAt: new Date(),
  scopes: ['channels:read', 'chat:write', 'commands'],
  notificationChannel: 'C01234567',
  appProfilePhotoUrl: 'https://example.com/logo.png',
  hasRequiredScopes: true,
  aiThreadAccessConsent: true,
  aiRequireOAuth: false,
};

// Check if AI features are enabled
function hasAiFeatures(settings: SlackSettings): boolean {
  return (
    settings.aiThreadAccessConsent === true &&
    settings.hasRequiredScopes &&
    !!settings.aiMultiAgentChannelId
  );
}

// Validate required scopes
function validateSlackScopes(settings: SlackSettings): boolean {
  const requiredScopes = ['channels:read', 'chat:write'];
  return requiredScopes.every(scope => settings.scopes.includes(scope));
}

Install with Tessl CLI

npx tessl i tessl/npm-lightdash--common

docs

api

index.md

tile.json