11import { logger , query , task } from "@trigger.dev/sdk" ;
22
3+ // Type definition for a run row
4+ type RunRow = {
5+ id : string ;
6+ status : string ;
7+ created_at : string ;
8+ duration : number ;
9+ } ;
10+
311// Simple query example - just the query string, all defaults
412export const simpleQueryTask = task ( {
513 id : "simple-query" ,
@@ -9,31 +17,51 @@ export const simpleQueryTask = task({
917 // Simplest usage - uses environment scope, json format, default period
1018 const result = await query . execute ( "SELECT * FROM runs LIMIT 10" ) ;
1119
12- logger . info ( "Query results" , {
13- rowCount : result . rows . length ,
14- firstRow : result . rows [ 0 ] ,
20+ logger . info ( "Query results (untyped)" , {
21+ format : result . format ,
22+ rowCount : result . results . length ,
23+ firstRow : result . results [ 0 ] ,
24+ } ) ;
25+
26+ // Type-safe query with explicit row type
27+ const typedResult = await query . execute < RunRow > (
28+ "SELECT id, status, created_at, duration FROM runs LIMIT 10"
29+ ) ;
30+
31+ logger . info ( "Query results (typed)" , {
32+ format : typedResult . format ,
33+ rowCount : typedResult . results . length ,
34+ firstRow : typedResult . results [ 0 ] ,
1535 } ) ;
1636
17- // Log all rows
18- result . rows . forEach ( ( row , index ) => {
19- logger . info ( `Row ${ index + 1 } ` , { row } ) ;
37+ // Now we have full type safety on the rows!
38+ typedResult . results . forEach ( ( row , index ) => {
39+ logger . info ( `Run ${ index + 1 } ` , {
40+ id : row . id , // TypeScript knows this is a string
41+ status : row . status , // TypeScript knows this is a string
42+ duration : row . duration , // TypeScript knows this is a number
43+ } ) ;
2044 } ) ;
2145
2246 return {
23- totalRows : result . rows . length ,
24- rows : result . rows ,
47+ totalRows : typedResult . results . length ,
48+ rows : typedResult . results ,
2549 } ;
2650 } ,
2751} ) ;
2852
29- // JSON query with all options
53+ // JSON query with all options and inline type
3054export const fullJsonQueryTask = task ( {
3155 id : "full-json-query" ,
3256 run : async ( ) => {
3357 logger . info ( "Running full JSON query example with all options" ) ;
3458
35- // All options specified
36- const result = await query . execute (
59+ // All options specified with inline type for aggregation
60+ const result = await query . execute < {
61+ status : string ;
62+ count : number ;
63+ avg_duration : number ;
64+ } > (
3765 `SELECT
3866 status,
3967 COUNT(*) as count,
@@ -44,25 +72,26 @@ export const fullJsonQueryTask = task({
4472 {
4573 scope : "environment" , // Query current environment only
4674 period : "30d" , // Last 30 days of data
47- format : "json" , // JSON format (default)
75+ // format defaults to "json"
4876 }
4977 ) ;
5078
5179 logger . info ( "Query completed" , {
52- rowCount : result . rows . length ,
80+ format : result . format ,
81+ rowCount : result . results . length ,
5382 } ) ;
5483
55- // Log the aggregated results
56- result . rows . forEach ( ( row ) => {
84+ // Log the aggregated results - now fully type-safe!
85+ result . results . forEach ( ( row ) => {
5786 logger . info ( "Status breakdown" , {
58- status : row . status ,
59- count : row . count ,
60- averageDuration : row . avg_duration ,
87+ status : row . status , // string
88+ count : row . count , // number
89+ averageDuration : row . avg_duration , // number
6190 } ) ;
6291 } ) ;
6392
6493 return {
65- summary : result . rows ,
94+ summary : result . results ,
6695 } ;
6796 } ,
6897} ) ;
@@ -73,8 +102,8 @@ export const csvQueryTask = task({
73102 run : async ( ) => {
74103 logger . info ( "Running CSV query example" ) ;
75104
76- // Query with CSV format - returns a string
77- const csvData = await query . execute (
105+ // Query with CSV format - automatically typed as discriminated union!
106+ const result = await query . execute (
78107 "SELECT id, status, created_at, duration FROM runs LIMIT 100" ,
79108 {
80109 scope : "project" , // Query all environments in the project
@@ -83,13 +112,15 @@ export const csvQueryTask = task({
83112 }
84113 ) ;
85114
115+ // result.format is "csv" and result.results is automatically typed as string!
86116 logger . info ( "CSV query completed" , {
87- dataLength : csvData . length ,
88- preview : csvData . substring ( 0 , 200 ) , // Show first 200 chars
117+ format : result . format ,
118+ dataLength : result . results . length ,
119+ preview : result . results . substring ( 0 , 200 ) , // Show first 200 chars
89120 } ) ;
90121
91122 // Count the number of rows (lines - 1 for header)
92- const lines = csvData . split ( "\n" ) ;
123+ const lines = result . results . split ( "\n" ) ;
93124 const rowCount = lines . length - 1 ;
94125
95126 logger . info ( "CSV stats" , {
@@ -98,19 +129,29 @@ export const csvQueryTask = task({
98129 } ) ;
99130
100131 return {
101- csv : csvData ,
132+ format : result . format ,
133+ csv : result . results ,
102134 rowCount,
103135 } ;
104136 } ,
105137} ) ;
106138
107- // Organization-wide query with date range
139+ // Organization-wide query with date range and type safety
108140export const orgQueryTask = task ( {
109141 id : "org-query" ,
110142 run : async ( ) => {
111143 logger . info ( "Running organization-wide query" ) ;
112144
113- const result = await query . execute (
145+ // Define the shape of our aggregated results
146+ type ProjectStats = {
147+ project : string ;
148+ environment : string ;
149+ total_runs : number ;
150+ successful_runs : number ;
151+ failed_runs : number ;
152+ } ;
153+
154+ const result = await query . execute < ProjectStats > (
114155 `SELECT
115156 project,
116157 environment,
@@ -124,25 +165,31 @@ export const orgQueryTask = task({
124165 scope : "organization" , // Query across all projects
125166 from : "2025-02-01T00:00:00Z" , // Custom date range
126167 to : "2025-02-11T23:59:59Z" ,
127- format : "json" ,
168+ // format defaults to "json"
128169 }
129170 ) ;
130171
131172 logger . info ( "Organization query completed" , {
132- projectCount : result . rows . length ,
173+ format : result . format ,
174+ projectCount : result . results . length ,
133175 } ) ;
134176
135- result . rows . forEach ( ( row ) => {
177+ // Full type safety on aggregated results
178+ result . results . forEach ( ( row ) => {
179+ const successRate = ( row . successful_runs / row . total_runs ) * 100 ;
180+
136181 logger . info ( "Project stats" , {
137182 project : row . project ,
138183 environment : row . environment ,
139184 totalRuns : row . total_runs ,
140- successRate : `${ ( ( row . successful_runs / row . total_runs ) * 100 ) . toFixed ( 2 ) } %` ,
185+ successfulRuns : row . successful_runs ,
186+ failedRuns : row . failed_runs ,
187+ successRate : `${ successRate . toFixed ( 2 ) } %` ,
141188 } ) ;
142189 } ) ;
143190
144191 return {
145- projects : result . rows ,
192+ projects : result . results ,
146193 } ;
147194 } ,
148195} ) ;
0 commit comments