Shared TypeScript library for the Lightdash platform containing common types, utilities, and business logic for analytics workflows
Overall
score
72%
Evaluation — 72%
↑ 1.09xAgent success when using this tile
Background job types for tracking asynchronous operations like project compilation and creation.
Defines the types of background jobs that can be executed.
enum JobType {
COMPILE_PROJECT = 'COMPILE_PROJECT',
CREATE_PROJECT = 'CREATE_PROJECT'
}Status values for tracking job execution state.
enum JobStatusType {
STARTED = 'STARTED',
DONE = 'DONE',
RUNNING = 'RUNNING',
ERROR = 'ERROR'
}Status values for individual steps within a job.
enum JobStepStatusType {
DONE = 'DONE',
RUNNING = 'RUNNING',
ERROR = 'ERROR',
PENDING = 'PENDING',
SKIPPED = 'SKIPPED'
}Types of steps that can be executed within a job.
enum JobStepType {
TESTING_ADAPTOR = 'TESTING_ADAPTOR',
COMPILING = 'COMPILING',
CREATING_PROJECT = 'CREATING_PROJECT',
CACHING = 'CACHING'
}Human-readable labels for job steps.
const JobLabels: {
TESTING_ADAPTOR: 'Testing adaptor';
COMPILING: 'Compiling';
CREATING_PROJECT: 'Creating project';
CACHING: 'Saving cache';
};Base structure for all job types.
interface BaseJob {
jobUuid: string;
projectUuid: string | undefined;
userUuid: string | undefined;
createdAt: Date;
updatedAt: Date;
jobStatus: JobStatusType;
steps: JobStep[];
}The main exported job type is a discriminated union of different job kinds. You cannot import CompileJob or CreateProjectJob directly - instead, import the Job union type and use type guards (isCompileJob, isCreateProjectJob) to narrow the type.
type Job = CompileJob | CreateProjectJob;Where CompileJob and CreateProjectJob are part of the union:
// Part of Job union type (not separately importable)
type CompileJob = BaseJob & {
jobType: JobType.COMPILE_PROJECT;
jobResults?: {
indexCatalogJobUuid: string;
};
};
// Part of Job union type (not separately importable)
type CreateProjectJob = BaseJob & {
jobType: JobType.CREATE_PROJECT;
jobResults?: {
projectUuid: string;
};
};Note: Import the Job union type and use type guards to safely access job-specific properties.
Type guards for discriminating between job types at runtime. Use these to safely access job-specific properties.
/**
* Check if a job is a CompileJob
* @param value - Value to check
* @returns True if value is a CompileJob
*/
function isCompileJob(value: unknown): value is CompileJob;
/**
* Check if a job is a CreateProjectJob
* @param value - Value to check
* @returns True if value is a CreateProjectJob
*/
function isCreateProjectJob(value: unknown): value is CreateProjectJob;Individual step within a job execution.
interface JobStep {
jobUuid: string;
createdAt: Date;
updatedAt: Date;
stepStatus: JobStepStatusType;
stepType: JobStepType;
stepError: string | undefined;
stepDbtLogs: DbtLog[] | undefined;
stepLabel: string;
startedAt: Date | undefined;
}Structured logging from dbt operations following the dbt events-logging specification.
interface DbtLog {
code: string;
info: {
category: string;
code: string;
extra: Record<string, unknown>;
invocation_id: string;
level: 'debug' | 'info' | 'warn' | 'error';
log_version: 2;
msg: string;
name: string;
pid: number;
thread_name: string;
ts: string;
type: 'log_line';
};
}
/**
* Check if a value is a valid DbtLog
* @param value - Value to check
* @returns True if value is a DbtLog
*/
function isDbtLog(value: unknown): value is DbtLog;Type for creating a new job with minimal required fields.
type CreateJob = Pick<
Job,
'jobUuid' | 'projectUuid' | 'jobType' | 'jobStatus' | 'userUuid'
> & {
steps: CreateJobStep[];
};
type CreateJobStep = Pick<JobStep, 'stepType'>;Constants and types for defining and identifying background tasks that can be scheduled and executed by the scheduler system.
/**
* Core scheduler task names for background jobs
*/
const SCHEDULER_TASKS: {
HANDLE_SCHEDULED_DELIVERY: 'handleScheduledDelivery';
SEND_SLACK_NOTIFICATION: 'sendSlackNotification';
SEND_EMAIL_NOTIFICATION: 'sendEmailNotification';
SEND_MSTEAMS_NOTIFICATION: 'sendMsTeamsNotification';
UPLOAD_GSHEETS: 'uploadGsheets';
DOWNLOAD_CSV: 'downloadCsv';
UPLOAD_GSHEET_FROM_QUERY: 'uploadGsheetFromQuery';
VALIDATE_PROJECT: 'validateProject';
COMPILE_PROJECT: 'compileProject';
CREATE_PROJECT_WITH_COMPILE: 'createProjectWithCompile';
TEST_AND_COMPILE_PROJECT: 'testAndCompileProject';
SQL_RUNNER: 'sqlRunner';
SQL_RUNNER_PIVOT_QUERY: 'sqlRunnerPivotQuery';
REPLACE_CUSTOM_FIELDS: 'replaceCustomFields';
INDEX_CATALOG: 'indexCatalog';
GENERATE_DAILY_JOBS: 'generateDailyJobs';
EXPORT_CSV_DASHBOARD: 'exportCsvDashboard';
RENAME_RESOURCES: 'renameResources';
CLEAN_QUERY_HISTORY: 'cleanQueryHistory';
DOWNLOAD_ASYNC_QUERY_RESULTS: 'downloadAsyncQueryResults';
// Enterprise Edition tasks
SLACK_AI_PROMPT: 'slackAiPrompt';
AI_AGENT_EVAL_RESULT: 'aiAgentEvalResult';
EMBED_ARTIFACT_VERSION: 'embedArtifactVersion';
GENERATE_ARTIFACT_QUESTION: 'generateArtifactQuestion';
};
/**
* Enterprise Edition scheduler task names
*/
const EE_SCHEDULER_TASKS: {
SLACK_AI_PROMPT: 'slackAiPrompt';
AI_AGENT_EVAL_RESULT: 'aiAgentEvalResult';
EMBED_ARTIFACT_VERSION: 'embedArtifactVersion';
GENERATE_ARTIFACT_QUESTION: 'generateArtifactQuestion';
};
/**
* Union type of all valid scheduler task names
*/
type SchedulerTaskName = typeof SCHEDULER_TASKS[keyof typeof SCHEDULER_TASKS];
/**
* Maps each scheduler task name to its payload type
*/
interface TaskPayloadMap {
[SCHEDULER_TASKS.HANDLE_SCHEDULED_DELIVERY]: ScheduledDeliveryPayload;
[SCHEDULER_TASKS.SEND_SLACK_NOTIFICATION]: SlackNotificationPayload;
[SCHEDULER_TASKS.SEND_EMAIL_NOTIFICATION]: EmailNotificationPayload;
[SCHEDULER_TASKS.SEND_MSTEAMS_NOTIFICATION]: MsTeamsNotificationPayload;
[SCHEDULER_TASKS.UPLOAD_GSHEETS]: GsheetsNotificationPayload;
[SCHEDULER_TASKS.DOWNLOAD_CSV]: DownloadCsvPayload;
[SCHEDULER_TASKS.UPLOAD_GSHEET_FROM_QUERY]: UploadMetricGsheetPayload;
[SCHEDULER_TASKS.VALIDATE_PROJECT]: ValidateProjectPayload;
[SCHEDULER_TASKS.COMPILE_PROJECT]: CompileProjectPayload;
[SCHEDULER_TASKS.CREATE_PROJECT_WITH_COMPILE]: SchedulerCreateProjectWithCompilePayload;
[SCHEDULER_TASKS.TEST_AND_COMPILE_PROJECT]: CompileProjectPayload;
[SCHEDULER_TASKS.SQL_RUNNER]: SqlRunnerPayload;
[SCHEDULER_TASKS.SQL_RUNNER_PIVOT_QUERY]: SqlRunnerPivotQueryPayload;
[SCHEDULER_TASKS.REPLACE_CUSTOM_FIELDS]: ReplaceCustomFieldsPayload;
[SCHEDULER_TASKS.INDEX_CATALOG]: SchedulerIndexCatalogJobPayload;
[SCHEDULER_TASKS.GENERATE_DAILY_JOBS]: TraceTaskBase;
[SCHEDULER_TASKS.EXPORT_CSV_DASHBOARD]: ExportCsvDashboardPayload;
[SCHEDULER_TASKS.SLACK_AI_PROMPT]: SlackPromptJobPayload;
[SCHEDULER_TASKS.RENAME_RESOURCES]: RenameResourcesPayload;
[SCHEDULER_TASKS.CLEAN_QUERY_HISTORY]: TraceTaskBase;
[SCHEDULER_TASKS.DOWNLOAD_ASYNC_QUERY_RESULTS]: DownloadAsyncQueryResultsPayload;
[SCHEDULER_TASKS.AI_AGENT_EVAL_RESULT]: AiAgentEvalRunJobPayload;
[SCHEDULER_TASKS.EMBED_ARTIFACT_VERSION]: EmbedArtifactVersionJobPayload;
[SCHEDULER_TASKS.GENERATE_ARTIFACT_QUESTION]: GenerateArtifactQuestionJobPayload;
}
/**
* Maps Enterprise Edition task names to their payload types
*/
interface EETaskPayloadMap {
[EE_SCHEDULER_TASKS.SLACK_AI_PROMPT]: SlackPromptJobPayload;
[EE_SCHEDULER_TASKS.AI_AGENT_EVAL_RESULT]: AiAgentEvalRunJobPayload;
[EE_SCHEDULER_TASKS.EMBED_ARTIFACT_VERSION]: EmbedArtifactVersionJobPayload;
[EE_SCHEDULER_TASKS.GENERATE_ARTIFACT_QUESTION]: GenerateArtifactQuestionJobPayload;
}
/**
* Type guard to check if a string is a valid scheduler task name
* @param task - Task name to validate
* @returns True if task is a valid SchedulerTaskName
*/
function isSchedulerTaskName(task: string): task is SchedulerTaskName;import { type Job, JobStatusType, isCompileJob, isCreateProjectJob } from '@lightdash/common';
// Job is a discriminated union - use type guards to narrow the type
function checkJobStatus(job: Job): void {
if (job.jobStatus === JobStatusType.DONE) {
// Use type guard to narrow Job to CompileJob
if (isCompileJob(job)) {
console.log('Compilation completed:', job.jobResults?.indexCatalogJobUuid);
}
// Use type guard to narrow Job to CreateProjectJob
else if (isCreateProjectJob(job)) {
console.log('Project created:', job.jobResults?.projectUuid);
}
} else if (job.jobStatus === JobStatusType.ERROR) {
const errorSteps = job.steps.filter(step => step.stepError);
console.error('Job failed with errors:', errorSteps);
}
}import { type JobStep, JobStepStatusType, JobLabels } from '@lightdash/common';
function getJobProgress(steps: JobStep[]): number {
const completedSteps = steps.filter(
step => step.stepStatus === JobStepStatusType.DONE
).length;
return (completedSteps / steps.length) * 100;
}
function getJobStepLabel(step: JobStep): string {
return JobLabels[step.stepType] || step.stepLabel;
}Install with Tessl CLI
npx tessl i tessl/npm-lightdash--commondocs
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10
scenario-11
scenario-12
scenario-13
scenario-14
scenario-15
scenario-16
scenario-17
scenario-18
scenario-19
scenario-20