@@ -17,25 +17,36 @@ type Event = Record<string, unknown> & {
1717type ErrorLog = Record < string , unknown > & {
1818 id : string ;
1919 client_id : string ;
20+ anonymous_id : string ;
21+ session_id : string ;
2022 timestamp : string ;
23+ path : string ;
2124 message : string ;
25+ filename ?: string ;
26+ lineno ?: number ;
27+ colno ?: number ;
28+ stack ?: string ;
29+ error_type : string ;
2230} ;
2331
2432type WebVital = Record < string , unknown > & {
2533 id : string ;
2634 client_id : string ;
35+ anonymous_id : string ;
36+ session_id : string ;
2737 timestamp : string ;
28- name : string ;
29- value : number ;
38+ path : string ;
39+ metric_name : string ;
40+ metric_value : number ;
3041} ;
3142
32- type ExportData = {
43+ interface ExportData {
3344 events : Event [ ] ;
3445 errors : ErrorLog [ ] ;
3546 webVitals : WebVital [ ] ;
36- } ;
47+ }
3748
38- export type ExportMetadata = {
49+ export interface ExportMetadata {
3950 websiteId : string ;
4051 format : ExportFormat ;
4152 exportDate : string ;
@@ -47,23 +58,23 @@ export type ExportMetadata = {
4758 } ;
4859 totalRecords : number ;
4960 fileSize : number ;
50- } ;
61+ }
5162
52- export type GenerateExportResult = {
63+ export interface GenerateExportResult {
5364 filename : string ;
5465 buffer : Buffer ;
5566 meta : ExportMetadata ;
56- } ;
67+ }
5768
58- export type ValidatedExportDates = {
69+ export interface ValidatedExportDates {
5970 startDate ?: string ;
6071 endDate ?: string ;
61- } ;
72+ }
6273
63- export type ValidateExportDateRangeResult = {
74+ export interface ValidateExportDateRangeResult {
6475 dates : ValidatedExportDates ;
6576 error ?: string ;
66- } ;
77+ }
6778
6879const MAX_HISTORY_DAYS = 365 * 2 ;
6980const MAX_RANGE_DAYS = 365 ;
@@ -239,33 +250,49 @@ async function fetchExportData(
239250 startDate ?: string ,
240251 endDate ?: string
241252) : Promise < ExportData > {
242- const { filter, params } = buildDateFilter ( startDate , endDate ) ;
243- const queryParams = { websiteId, ...params } ;
253+ const eventsFilter = buildDateFilter ( startDate , endDate , "time" ) ;
254+ const errorsFilter = buildDateFilter ( startDate , endDate , "timestamp" ) ;
255+ const webVitalsFilter = buildDateFilter ( startDate , endDate , "timestamp" ) ;
256+
257+ const queryParams = { websiteId, ...eventsFilter . params } ;
244258
245259 const [ events , errors , webVitals ] = await Promise . all ( [
246- chQuery < Event > ( getEventsQuery ( filter ) , queryParams ) ,
247- chQuery < ErrorLog > ( getErrorsQuery ( filter ) , queryParams ) ,
248- chQuery < WebVital > ( getWebVitalsQuery ( filter ) , queryParams ) ,
260+ chQuery < Event > ( getEventsQuery ( eventsFilter . filter ) , queryParams ) ,
261+ chQuery < ErrorLog > ( getErrorsQuery ( errorsFilter . filter ) , queryParams ) ,
262+ chQuery < WebVital > ( getWebVitalsQuery ( webVitalsFilter . filter ) , queryParams ) ,
249263 ] ) ;
250264
251- return { events, errors, webVitals } ;
265+ return {
266+ events,
267+ errors : errors . map ( ( error ) => ( {
268+ ...error ,
269+ id : `${ error . client_id } _${ error . timestamp } _${ error . session_id } ` ,
270+ } ) ) ,
271+ webVitals : webVitals . map ( ( vital ) => ( {
272+ ...vital ,
273+ id : `${ vital . client_id } _${ vital . timestamp } _${ vital . session_id } ` ,
274+ name : vital . metric_name ,
275+ value : vital . metric_value ,
276+ } ) ) ,
277+ } ;
252278}
253279
254280function buildDateFilter (
255281 startDate ?: string ,
256- endDate ?: string
282+ endDate ?: string ,
283+ dateColumn = "time"
257284) : { filter : string ; params : Record < string , string > } {
258285 const params : Record < string , string > = { } ;
259286 const conditions : string [ ] = [ ] ;
260287
261288 if ( startDate ) {
262289 params . startDate = startDate ;
263- conditions . push ( "time >= {startDate:String}" ) ;
290+ conditions . push ( ` ${ dateColumn } >= {startDate:String}` ) ;
264291 }
265292
266293 if ( endDate ) {
267294 params . endDate = endDate ;
268- conditions . push ( "time <= {endDate:String}" ) ;
295+ conditions . push ( ` ${ dateColumn } <= {endDate:String}` ) ;
269296 }
270297
271298 const filter = conditions . length > 0 ? `AND ${ conditions . join ( " AND " ) } ` : "" ;
@@ -278,29 +305,42 @@ function getEventsQuery(dateFilter: string): string {
278305 FROM analytics.events
279306 WHERE client_id = {websiteId:String} ${ dateFilter }
280307 ORDER BY time DESC
281- LIMIT 100000
282308 ` ;
283309}
284310
285311function getErrorsQuery ( dateFilter : string ) : string {
286- const errorDateFilter = dateFilter . replace ( / \b t i m e \b / g, "timestamp" ) ;
287312 return `
288- SELECT * EXCEPT(ip, user_agent)
289- FROM analytics.errors
290- WHERE client_id = {websiteId:String} ${ errorDateFilter }
313+ SELECT
314+ client_id,
315+ anonymous_id,
316+ session_id,
317+ timestamp,
318+ path,
319+ message,
320+ filename,
321+ lineno,
322+ colno,
323+ stack,
324+ error_type
325+ FROM analytics.error_spans
326+ WHERE client_id = {websiteId:String} ${ dateFilter }
291327 ORDER BY timestamp DESC
292- LIMIT 50000
293328 ` ;
294329}
295330
296331function getWebVitalsQuery ( dateFilter : string ) : string {
297- const vitalsDateFilter = dateFilter . replace ( / \b t i m e \b / g, "timestamp" ) ;
298332 return `
299- SELECT * EXCEPT(ip, user_agent)
300- FROM analytics.web_vitals
301- WHERE client_id = {websiteId:String} ${ vitalsDateFilter }
333+ SELECT
334+ client_id,
335+ anonymous_id,
336+ session_id,
337+ timestamp,
338+ path,
339+ metric_name,
340+ metric_value
341+ FROM analytics.web_vitals_spans
342+ WHERE client_id = {websiteId:String} ${ dateFilter }
302343 ORDER BY timestamp DESC
303- LIMIT 25000
304344 ` ;
305345}
306346
0 commit comments