glitch-javascript-sdk 1.8.0 → 1.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.js +458 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/api/Ads.d.ts +31 -0
- package/dist/esm/api/Scheduler.d.ts +17 -0
- package/dist/esm/api/WebsiteAnalytics.d.ts +187 -0
- package/dist/esm/api/index.d.ts +2 -0
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.js +458 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/routes/WebsiteAnalyticsRoute.d.ts +7 -0
- package/dist/esm/util/Session.d.ts +8 -0
- package/dist/index.d.ts +242 -0
- package/package.json +2 -1
- package/src/api/Ads.ts +87 -0
- package/src/api/Scheduler.ts +23 -0
- package/src/api/WebsiteAnalytics.ts +308 -0
- package/src/api/index.ts +3 -1
- package/src/index.ts +3 -1
- package/src/routes/AdsRoute.ts +30 -0
- package/src/routes/SchedulerRoute.ts +2 -0
- package/src/routes/WebsiteAnalyticsRoute.ts +69 -0
- package/src/util/Session.ts +92 -4
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
import WebsiteAnalyticsRoute from "../routes/WebsiteAnalyticsRoute";
|
|
2
|
+
import Requests from "../util/Requests";
|
|
3
|
+
import Response from "../util/Response";
|
|
4
|
+
import { AxiosPromise } from "axios";
|
|
5
|
+
|
|
6
|
+
class WebsiteAnalytics {
|
|
7
|
+
/**
|
|
8
|
+
* List website analytics sessions with comprehensive filtering
|
|
9
|
+
*
|
|
10
|
+
* @param params Filtering options:
|
|
11
|
+
* - title_id?: string - Filter by title ID
|
|
12
|
+
* - start_date?: string - Start date (YYYY-MM-DD)
|
|
13
|
+
* - end_date?: string - End date (YYYY-MM-DD)
|
|
14
|
+
* - device_type?: 'desktop'|'mobile'|'tablet'|'bot'|'other'
|
|
15
|
+
* - country_code?: string - 2-letter country code
|
|
16
|
+
* - is_bot?: boolean - Filter by bot status
|
|
17
|
+
* - sort?: 'started_at'|'total_duration'|'pageview_count' - Sort field
|
|
18
|
+
* - order?: 'asc'|'desc' - Sort order
|
|
19
|
+
* - per_page?: number - Items per page (max 100)
|
|
20
|
+
* @returns Promise with paginated sessions data
|
|
21
|
+
*/
|
|
22
|
+
public static listSessions<T>(params?: Record<string, any>): AxiosPromise<Response<T>> {
|
|
23
|
+
return Requests.processRoute(
|
|
24
|
+
WebsiteAnalyticsRoute.routes.listSessions,
|
|
25
|
+
{},
|
|
26
|
+
undefined,
|
|
27
|
+
params
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Get a paginated list of pageviews with filtering options
|
|
33
|
+
*
|
|
34
|
+
* @param params Filtering options:
|
|
35
|
+
* - title_id?: string - Filter by title ID
|
|
36
|
+
* - analytics_session_id?: string - Filter by session ID
|
|
37
|
+
* - start_date?: string - Start date (YYYY-MM-DD)
|
|
38
|
+
* - end_date?: string - End date (YYYY-MM-DD)
|
|
39
|
+
* - is_exit?: boolean - Filter by exit pageviews
|
|
40
|
+
* - sort?: 'occurred_at'|'load_time_ms'|'dom_complete_ms' - Sort field
|
|
41
|
+
* - order?: 'asc'|'desc' - Sort order
|
|
42
|
+
* - per_page?: number - Items per page (max 100)
|
|
43
|
+
* @returns Promise with paginated pageviews data
|
|
44
|
+
*/
|
|
45
|
+
public static listPageviews<T>(params?: Record<string, any>): AxiosPromise<Response<T>> {
|
|
46
|
+
return Requests.processRoute(
|
|
47
|
+
WebsiteAnalyticsRoute.routes.listPageviews,
|
|
48
|
+
{},
|
|
49
|
+
undefined,
|
|
50
|
+
params
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Get a paginated list of events with filtering options
|
|
56
|
+
*
|
|
57
|
+
* @param params Filtering options:
|
|
58
|
+
* - title_id?: string - Filter by title ID
|
|
59
|
+
* - analytics_session_id?: string - Filter by session ID
|
|
60
|
+
* - event_name?: string - Filter by event name
|
|
61
|
+
* - event_category?: string - Filter by event category
|
|
62
|
+
* - start_date?: string - Start date (YYYY-MM-DD)
|
|
63
|
+
* - end_date?: string - End date (YYYY-MM-DD)
|
|
64
|
+
* - sort?: 'occurred_at'|'event_name' - Sort field
|
|
65
|
+
* - order?: 'asc'|'desc' - Sort order
|
|
66
|
+
* - per_page?: number - Items per page (max 100)
|
|
67
|
+
* @returns Promise with paginated events data
|
|
68
|
+
*/
|
|
69
|
+
public static listEvents<T>(params?: Record<string, any>): AxiosPromise<Response<T>> {
|
|
70
|
+
return Requests.processRoute(
|
|
71
|
+
WebsiteAnalyticsRoute.routes.listEvents,
|
|
72
|
+
{},
|
|
73
|
+
undefined,
|
|
74
|
+
params
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Get an analytics overview with summarized metrics
|
|
80
|
+
*
|
|
81
|
+
* @param params Overview options:
|
|
82
|
+
* - title_id: string - Required title ID
|
|
83
|
+
* - start_date?: string - Start date (YYYY-MM-DD)
|
|
84
|
+
* - end_date?: string - End date (YYYY-MM-DD)
|
|
85
|
+
* - group_by?: 'day'|'week'|'month'|'year' - Grouping period
|
|
86
|
+
* - include_breakdowns?: boolean - Include detailed breakdowns
|
|
87
|
+
* @returns Promise with overview data
|
|
88
|
+
*/
|
|
89
|
+
public static overview<T>(params: Record<string, any>): AxiosPromise<Response<T>> {
|
|
90
|
+
return Requests.processRoute(
|
|
91
|
+
WebsiteAnalyticsRoute.routes.overview,
|
|
92
|
+
{},
|
|
93
|
+
undefined,
|
|
94
|
+
params
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Single ingestion endpoint for sessions, pageviews and events
|
|
100
|
+
*
|
|
101
|
+
* @param data Analytics data payload with type property:
|
|
102
|
+
* - type: 'session'|'pageview'|'event' - Type of analytics data
|
|
103
|
+
* - title_id: string - Title ID
|
|
104
|
+
* - tracking_token: string - HMAC token for verification
|
|
105
|
+
* - plus type-specific fields
|
|
106
|
+
* @returns Promise with acceptance response
|
|
107
|
+
*/
|
|
108
|
+
public static collect<T>(data: object): AxiosPromise<Response<T>> {
|
|
109
|
+
return Requests.processRoute(
|
|
110
|
+
WebsiteAnalyticsRoute.routes.collect,
|
|
111
|
+
data
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Get average session length data with optional grouping
|
|
117
|
+
*
|
|
118
|
+
* @param params Filtering options:
|
|
119
|
+
* - title_id?: string - Filter by title ID
|
|
120
|
+
* - start_date?: string - Start date (YYYY-MM-DD)
|
|
121
|
+
* - end_date?: string - End date (YYYY-MM-DD)
|
|
122
|
+
* - group_by?: 'day'|'week'|'month' - Grouping period
|
|
123
|
+
* - device_type?: string - Filter by device type
|
|
124
|
+
* - country_code?: string - Filter by country
|
|
125
|
+
* @returns Promise with average session data
|
|
126
|
+
*/
|
|
127
|
+
public static sessionsAverage<T>(params?: Record<string, any>): AxiosPromise<Response<T>> {
|
|
128
|
+
return Requests.processRoute(
|
|
129
|
+
WebsiteAnalyticsRoute.routes.sessionsAverage,
|
|
130
|
+
{},
|
|
131
|
+
undefined,
|
|
132
|
+
params
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Get session duration histogram data
|
|
138
|
+
*
|
|
139
|
+
* @param params Filtering options:
|
|
140
|
+
* - title_id?: string - Filter by title ID
|
|
141
|
+
* - start_date?: string - Start date (YYYY-MM-DD)
|
|
142
|
+
* - end_date?: string - End date (YYYY-MM-DD)
|
|
143
|
+
* - bucket_size?: number - Duration bucket size in seconds
|
|
144
|
+
* @returns Promise with histogram data
|
|
145
|
+
*/
|
|
146
|
+
public static sessionsHistogram<T>(params?: Record<string, any>): AxiosPromise<Response<T>> {
|
|
147
|
+
return Requests.processRoute(
|
|
148
|
+
WebsiteAnalyticsRoute.routes.sessionsHistogram,
|
|
149
|
+
{},
|
|
150
|
+
undefined,
|
|
151
|
+
params
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Get pageviews over time with optional grouping
|
|
157
|
+
*
|
|
158
|
+
* @param params Filtering options:
|
|
159
|
+
* - title_id?: string - Filter by title ID
|
|
160
|
+
* - start_date?: string - Start date (YYYY-MM-DD)
|
|
161
|
+
* - end_date?: string - End date (YYYY-MM-DD)
|
|
162
|
+
* - group_by?: 'hour'|'day'|'week'|'month' - Grouping period
|
|
163
|
+
* - path?: string - Filter by specific path
|
|
164
|
+
* @returns Promise with pageviews over time data
|
|
165
|
+
*/
|
|
166
|
+
public static pageviewsOverTime<T>(params?: Record<string, any>): AxiosPromise<Response<T>> {
|
|
167
|
+
return Requests.processRoute(
|
|
168
|
+
WebsiteAnalyticsRoute.routes.pageviewsOverTime,
|
|
169
|
+
{},
|
|
170
|
+
undefined,
|
|
171
|
+
params
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Get top pages by views
|
|
177
|
+
*
|
|
178
|
+
* @param params Filtering options:
|
|
179
|
+
* - title_id?: string - Filter by title ID
|
|
180
|
+
* - start_date?: string - Start date (YYYY-MM-DD)
|
|
181
|
+
* - end_date?: string - End date (YYYY-MM-DD)
|
|
182
|
+
* - limit?: number - Number of top pages to return
|
|
183
|
+
* @returns Promise with top pages data
|
|
184
|
+
*/
|
|
185
|
+
public static topPages<T>(params?: Record<string, any>): AxiosPromise<Response<T>> {
|
|
186
|
+
return Requests.processRoute(
|
|
187
|
+
WebsiteAnalyticsRoute.routes.topPages,
|
|
188
|
+
{},
|
|
189
|
+
undefined,
|
|
190
|
+
params
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Get summary of events
|
|
196
|
+
*
|
|
197
|
+
* @param params Filtering options:
|
|
198
|
+
* - title_id?: string - Filter by title ID
|
|
199
|
+
* - start_date?: string - Start date (YYYY-MM-DD)
|
|
200
|
+
* - end_date?: string - End date (YYYY-MM-DD)
|
|
201
|
+
* - event_category?: string - Filter by event category
|
|
202
|
+
* @returns Promise with events summary data
|
|
203
|
+
*/
|
|
204
|
+
public static eventsSummary<T>(params?: Record<string, any>): AxiosPromise<Response<T>> {
|
|
205
|
+
return Requests.processRoute(
|
|
206
|
+
WebsiteAnalyticsRoute.routes.eventsSummary,
|
|
207
|
+
{},
|
|
208
|
+
undefined,
|
|
209
|
+
params
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Get most popular events
|
|
215
|
+
*
|
|
216
|
+
* @param params Filtering options:
|
|
217
|
+
* - title_id?: string - Filter by title ID
|
|
218
|
+
* - start_date?: string - Start date (YYYY-MM-DD)
|
|
219
|
+
* - end_date?: string - End date (YYYY-MM-DD)
|
|
220
|
+
* - limit?: number - Number of events to return
|
|
221
|
+
* @returns Promise with popular events data
|
|
222
|
+
*/
|
|
223
|
+
public static popularEvents<T>(params?: Record<string, any>): AxiosPromise<Response<T>> {
|
|
224
|
+
return Requests.processRoute(
|
|
225
|
+
WebsiteAnalyticsRoute.routes.popularEvents,
|
|
226
|
+
{},
|
|
227
|
+
undefined,
|
|
228
|
+
params
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Get geographic distribution of visitors
|
|
234
|
+
*
|
|
235
|
+
* @param params Filtering options:
|
|
236
|
+
* - title_id?: string - Filter by title ID
|
|
237
|
+
* - start_date?: string - Start date (YYYY-MM-DD)
|
|
238
|
+
* - end_date?: string - End date (YYYY-MM-DD)
|
|
239
|
+
* - limit?: number - Number of countries to return
|
|
240
|
+
* @returns Promise with geo distribution data
|
|
241
|
+
*/
|
|
242
|
+
public static geoDistribution<T>(params?: Record<string, any>): AxiosPromise<Response<T>> {
|
|
243
|
+
return Requests.processRoute(
|
|
244
|
+
WebsiteAnalyticsRoute.routes.geoDistribution,
|
|
245
|
+
{},
|
|
246
|
+
undefined,
|
|
247
|
+
params
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Get device type breakdown
|
|
253
|
+
*
|
|
254
|
+
* @param params Filtering options:
|
|
255
|
+
* - title_id?: string - Filter by title ID
|
|
256
|
+
* - start_date?: string - Start date (YYYY-MM-DD)
|
|
257
|
+
* - end_date?: string - End date (YYYY-MM-DD)
|
|
258
|
+
* @returns Promise with device breakdown data
|
|
259
|
+
*/
|
|
260
|
+
public static deviceBreakdown<T>(params?: Record<string, any>): AxiosPromise<Response<T>> {
|
|
261
|
+
return Requests.processRoute(
|
|
262
|
+
WebsiteAnalyticsRoute.routes.deviceBreakdown,
|
|
263
|
+
{},
|
|
264
|
+
undefined,
|
|
265
|
+
params
|
|
266
|
+
);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Get top referrers
|
|
271
|
+
*
|
|
272
|
+
* @param params Filtering options:
|
|
273
|
+
* - title_id?: string - Filter by title ID
|
|
274
|
+
* - start_date?: string - Start date (YYYY-MM-DD)
|
|
275
|
+
* - end_date?: string - End date (YYYY-MM-DD)
|
|
276
|
+
* - limit?: number - Number of referrers to return
|
|
277
|
+
* @returns Promise with referrers data
|
|
278
|
+
*/
|
|
279
|
+
public static referrers<T>(params?: Record<string, any>): AxiosPromise<Response<T>> {
|
|
280
|
+
return Requests.processRoute(
|
|
281
|
+
WebsiteAnalyticsRoute.routes.referrers,
|
|
282
|
+
{},
|
|
283
|
+
undefined,
|
|
284
|
+
params
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Get UTM campaign performance
|
|
290
|
+
*
|
|
291
|
+
* @param params Filtering options:
|
|
292
|
+
* - title_id?: string - Filter by title ID
|
|
293
|
+
* - start_date?: string - Start date (YYYY-MM-DD)
|
|
294
|
+
* - end_date?: string - End date (YYYY-MM-DD)
|
|
295
|
+
* - group_by?: 'source'|'medium'|'campaign' - Grouping field
|
|
296
|
+
* @returns Promise with UTM performance data
|
|
297
|
+
*/
|
|
298
|
+
public static utmPerformance<T>(params?: Record<string, any>): AxiosPromise<Response<T>> {
|
|
299
|
+
return Requests.processRoute(
|
|
300
|
+
WebsiteAnalyticsRoute.routes.utmPerformance,
|
|
301
|
+
{},
|
|
302
|
+
undefined,
|
|
303
|
+
params
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
export default WebsiteAnalytics;
|
package/src/api/index.ts
CHANGED
|
@@ -31,6 +31,7 @@ import Scheduler from "./Scheduler";
|
|
|
31
31
|
import Funnel from "./Funnel";
|
|
32
32
|
import SocialStats from "./SocialStats";
|
|
33
33
|
import Hashtags from "./Hashtags";
|
|
34
|
+
import WebsiteAnalytics from "./WebsiteAnalytics";
|
|
34
35
|
|
|
35
36
|
export {Ads};
|
|
36
37
|
export {Auth};
|
|
@@ -64,4 +65,5 @@ export {Media};
|
|
|
64
65
|
export {Scheduler};
|
|
65
66
|
export {Funnel};
|
|
66
67
|
export {SocialStats};
|
|
67
|
-
export {Hashtags};
|
|
68
|
+
export {Hashtags};
|
|
69
|
+
export {WebsiteAnalytics};
|
package/src/index.ts
CHANGED
|
@@ -35,6 +35,7 @@ import {Scheduler} from "./api";
|
|
|
35
35
|
import {Funnel} from "./api";
|
|
36
36
|
import {SocialStats} from "./api";
|
|
37
37
|
import {Hashtags} from "./api";
|
|
38
|
+
import {WebsiteAnalytics} from "./api";
|
|
38
39
|
|
|
39
40
|
import Requests from "./util/Requests";
|
|
40
41
|
import Parser from "./util/Parser";
|
|
@@ -98,7 +99,8 @@ class Glitch {
|
|
|
98
99
|
Media : Media,
|
|
99
100
|
Scheduler : Scheduler,
|
|
100
101
|
Funnel: Funnel,
|
|
101
|
-
SocialStats : SocialStats
|
|
102
|
+
SocialStats : SocialStats,
|
|
103
|
+
WebsiteAnalytics: WebsiteAnalytics
|
|
102
104
|
}
|
|
103
105
|
|
|
104
106
|
public static util = {
|
package/src/routes/AdsRoute.ts
CHANGED
|
@@ -136,6 +136,36 @@ class AdsRoute {
|
|
|
136
136
|
url: "/ads/campaigns/{campaign_id}/groups/{group_id}/triggers/{trigger_id}",
|
|
137
137
|
method: HTTP_METHODS.DELETE,
|
|
138
138
|
},
|
|
139
|
+
|
|
140
|
+
// REDDIT TARGETING routes
|
|
141
|
+
getRedditCarriers: {
|
|
142
|
+
url: "/ads/reddit/targeting/carriers",
|
|
143
|
+
method: HTTP_METHODS.GET,
|
|
144
|
+
},
|
|
145
|
+
getRedditCommunities: {
|
|
146
|
+
url: "/ads/reddit/targeting/communities",
|
|
147
|
+
method: HTTP_METHODS.GET,
|
|
148
|
+
},
|
|
149
|
+
searchRedditCommunities: {
|
|
150
|
+
url: "/ads/reddit/targeting/communities/search",
|
|
151
|
+
method: HTTP_METHODS.GET,
|
|
152
|
+
},
|
|
153
|
+
getRedditDevices: {
|
|
154
|
+
url: "/ads/reddit/targeting/devices",
|
|
155
|
+
method: HTTP_METHODS.GET,
|
|
156
|
+
},
|
|
157
|
+
getRedditGeolocations: {
|
|
158
|
+
url: "/ads/reddit/targeting/geolocations",
|
|
159
|
+
method: HTTP_METHODS.GET,
|
|
160
|
+
},
|
|
161
|
+
getRedditInterests: {
|
|
162
|
+
url: "/ads/reddit/targeting/interests",
|
|
163
|
+
method: HTTP_METHODS.GET,
|
|
164
|
+
},
|
|
165
|
+
getRedditThirdPartyAudiences: {
|
|
166
|
+
url: "/ads/reddit/targeting/third_party_audiences",
|
|
167
|
+
method: HTTP_METHODS.GET,
|
|
168
|
+
},
|
|
139
169
|
};
|
|
140
170
|
}
|
|
141
171
|
|
|
@@ -13,6 +13,7 @@ class SchedulerRoute {
|
|
|
13
13
|
|
|
14
14
|
// Title Update Routes
|
|
15
15
|
listUpdates: { url: '/schedulers/{scheduler_id}/updates', method: HTTP_METHODS.GET },
|
|
16
|
+
searchUpdates: { url: '/schedulers/{scheduler_id}/updates/search', method: HTTP_METHODS.GET },
|
|
16
17
|
createUpdate: { url: '/schedulers/{scheduler_id}/updates', method: HTTP_METHODS.POST },
|
|
17
18
|
getUpdate: { url: '/schedulers/{scheduler_id}/updates/{update_id}', method: HTTP_METHODS.GET },
|
|
18
19
|
updateUpdate: { url: '/schedulers/{scheduler_id}/updates/{update_id}', method: HTTP_METHODS.PUT },
|
|
@@ -32,6 +33,7 @@ class SchedulerRoute {
|
|
|
32
33
|
clearTwitchAuth: { url: '/schedulers/{scheduler_id}/clearTwitchAuth', method: HTTP_METHODS.DELETE },
|
|
33
34
|
clearKickAuth: { url: '/schedulers/{scheduler_id}/clearKickAuth', method: HTTP_METHODS.DELETE },
|
|
34
35
|
clearRedditAuth: { url: '/schedulers/{scheduler_id}/clearRedditAuth', method: HTTP_METHODS.DELETE },
|
|
36
|
+
clearRedditAdsAuth: { url: '/schedulers/{scheduler_id}/clearRedditAdsAuth', method: HTTP_METHODS.DELETE },
|
|
35
37
|
clearYouTubeAuth: { url: '/schedulers/{scheduler_id}/clearYouTubeAuth', method: HTTP_METHODS.DELETE },
|
|
36
38
|
clearPatreonAuth: { url: '/schedulers/{scheduler_id}/clearPatreonAuth', method: HTTP_METHODS.DELETE },
|
|
37
39
|
clearPinterestAuth: { url: '/schedulers/{scheduler_id}/clearPinterestAuth', method: HTTP_METHODS.DELETE },
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import Route from "./interface";
|
|
2
|
+
import HTTP_METHODS from "../constants/HttpMethods";
|
|
3
|
+
|
|
4
|
+
class WebsiteAnalyticsRoute {
|
|
5
|
+
public static routes: { [key: string]: Route } = {
|
|
6
|
+
listSessions: {
|
|
7
|
+
url: '/analytics/sessions',
|
|
8
|
+
method: HTTP_METHODS.GET
|
|
9
|
+
},
|
|
10
|
+
listPageviews: {
|
|
11
|
+
url: '/analytics/pageviews',
|
|
12
|
+
method: HTTP_METHODS.GET
|
|
13
|
+
},
|
|
14
|
+
listEvents: {
|
|
15
|
+
url: '/analytics/events',
|
|
16
|
+
method: HTTP_METHODS.GET
|
|
17
|
+
},
|
|
18
|
+
overview: {
|
|
19
|
+
url: '/analytics/overview',
|
|
20
|
+
method: HTTP_METHODS.GET
|
|
21
|
+
},
|
|
22
|
+
collect: {
|
|
23
|
+
url: '/analytics/collect',
|
|
24
|
+
method: HTTP_METHODS.POST
|
|
25
|
+
},
|
|
26
|
+
sessionsAverage: {
|
|
27
|
+
url: '/analytics/sessions/average',
|
|
28
|
+
method: HTTP_METHODS.GET
|
|
29
|
+
},
|
|
30
|
+
sessionsHistogram: {
|
|
31
|
+
url: '/analytics/sessions/histogram',
|
|
32
|
+
method: HTTP_METHODS.GET
|
|
33
|
+
},
|
|
34
|
+
pageviewsOverTime: {
|
|
35
|
+
url: '/analytics/pageviews/over-time',
|
|
36
|
+
method: HTTP_METHODS.GET
|
|
37
|
+
},
|
|
38
|
+
topPages: {
|
|
39
|
+
url: '/analytics/pageviews/top-pages',
|
|
40
|
+
method: HTTP_METHODS.GET
|
|
41
|
+
},
|
|
42
|
+
eventsSummary: {
|
|
43
|
+
url: '/analytics/events/summary',
|
|
44
|
+
method: HTTP_METHODS.GET
|
|
45
|
+
},
|
|
46
|
+
popularEvents: {
|
|
47
|
+
url: '/analytics/events/popular',
|
|
48
|
+
method: HTTP_METHODS.GET
|
|
49
|
+
},
|
|
50
|
+
geoDistribution: {
|
|
51
|
+
url: '/analytics/geo-distribution',
|
|
52
|
+
method: HTTP_METHODS.GET
|
|
53
|
+
},
|
|
54
|
+
deviceBreakdown: {
|
|
55
|
+
url: '/analytics/device-breakdown',
|
|
56
|
+
method: HTTP_METHODS.GET
|
|
57
|
+
},
|
|
58
|
+
referrers: {
|
|
59
|
+
url: '/analytics/referrers',
|
|
60
|
+
method: HTTP_METHODS.GET
|
|
61
|
+
},
|
|
62
|
+
utmPerformance: {
|
|
63
|
+
url: '/analytics/utm-performance',
|
|
64
|
+
method: HTTP_METHODS.GET
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export default WebsiteAnalyticsRoute;
|
package/src/util/Session.ts
CHANGED
|
@@ -1,8 +1,70 @@
|
|
|
1
1
|
import { Config } from "../config";
|
|
2
2
|
import Storage from "./Storage";
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
// Type declarations for crypto functionality
|
|
5
|
+
interface HmacInterface {
|
|
6
|
+
update(data: string): HmacInterface;
|
|
7
|
+
digest(encoding: 'hex'): string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface CryptoInterface {
|
|
11
|
+
createHmac(algorithm: string, secret: string): HmacInterface;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Browser implementation using crypto-js
|
|
15
|
+
class BrowserCrypto implements CryptoInterface {
|
|
16
|
+
createHmac(algorithm: string, secret: string): HmacInterface {
|
|
17
|
+
const CryptoJS = require('crypto-js');
|
|
18
|
+
|
|
19
|
+
let data = '';
|
|
20
|
+
|
|
21
|
+
const hmac: HmacInterface = {
|
|
22
|
+
update: (updateData: string): HmacInterface => {
|
|
23
|
+
data = updateData;
|
|
24
|
+
return hmac;
|
|
25
|
+
},
|
|
26
|
+
digest: (encoding: 'hex'): string => {
|
|
27
|
+
if (encoding !== 'hex') {
|
|
28
|
+
throw new Error('Only hex encoding is supported in browser implementation');
|
|
29
|
+
}
|
|
30
|
+
return CryptoJS.HmacSHA256(data, secret).toString(CryptoJS.enc.Hex);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
return hmac;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Node.js implementation using native crypto
|
|
39
|
+
class NodeCrypto implements CryptoInterface {
|
|
40
|
+
private crypto: typeof import('crypto');
|
|
41
|
+
|
|
42
|
+
constructor() {
|
|
43
|
+
this.crypto = require('crypto');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
createHmac(algorithm: string, secret: string): HmacInterface {
|
|
47
|
+
return this.crypto.createHmac(algorithm, secret);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Determine which crypto implementation to use
|
|
52
|
+
const getCrypto = (): CryptoInterface => {
|
|
53
|
+
try {
|
|
54
|
+
// Check if we're in Node.js environment
|
|
55
|
+
if (typeof process !== 'undefined' && process.versions && process.versions.node) {
|
|
56
|
+
return new NodeCrypto();
|
|
57
|
+
}
|
|
58
|
+
// Fall back to browser implementation
|
|
59
|
+
return new BrowserCrypto();
|
|
60
|
+
} catch (e) {
|
|
61
|
+
return new BrowserCrypto();
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const crypto = getCrypto();
|
|
5
66
|
|
|
67
|
+
class Session {
|
|
6
68
|
private static _id_key = 'user_id';
|
|
7
69
|
private static _first_name_key = 'user_first_name';
|
|
8
70
|
private static _last_name_key = 'user_last_name';
|
|
@@ -37,7 +99,7 @@ class Session {
|
|
|
37
99
|
public static hasJoinedCommunity() {
|
|
38
100
|
const community = Storage.get('community');
|
|
39
101
|
|
|
40
|
-
if(!community) {
|
|
102
|
+
if (!community) {
|
|
41
103
|
return false;
|
|
42
104
|
}
|
|
43
105
|
|
|
@@ -53,7 +115,7 @@ class Session {
|
|
|
53
115
|
Storage.set(Session._username_key, null);
|
|
54
116
|
}
|
|
55
117
|
|
|
56
|
-
public static processAuthentication(data: { token: { access_token: string }, id: string, first_name: string, last_name: string, email: string, username: string
|
|
118
|
+
public static processAuthentication(data: { token: { access_token: string }, id: string, first_name: string, last_name: string, email: string, username: string }): void {
|
|
57
119
|
Storage.setAuthToken(data.token.access_token);
|
|
58
120
|
Storage.set(Session._id_key, data.id);
|
|
59
121
|
Storage.set(Session._first_name_key, data.first_name);
|
|
@@ -63,6 +125,32 @@ class Session {
|
|
|
63
125
|
|
|
64
126
|
Config.setAuthToken(data.token.access_token);
|
|
65
127
|
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Generate a tracking token for analytics collection
|
|
131
|
+
* @param titleId The title ID to generate token for
|
|
132
|
+
* @param secret The secret key (should match server config)
|
|
133
|
+
* @returns HMAC-SHA256 token
|
|
134
|
+
* @throws Error if crypto operations fail
|
|
135
|
+
*/
|
|
136
|
+
public static generateTrackingToken(titleId: string, secret: string): string {
|
|
137
|
+
try {
|
|
138
|
+
if (!titleId) {
|
|
139
|
+
throw new Error('titleId is required');
|
|
140
|
+
}
|
|
141
|
+
if (!secret) {
|
|
142
|
+
throw new Error('secret is required');
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return crypto
|
|
146
|
+
.createHmac('sha256', secret)
|
|
147
|
+
.update(titleId)
|
|
148
|
+
.digest('hex');
|
|
149
|
+
} catch (error) {
|
|
150
|
+
console.error('Failed to generate tracking token:', error);
|
|
151
|
+
throw new Error('Failed to generate tracking token');
|
|
152
|
+
}
|
|
153
|
+
}
|
|
66
154
|
}
|
|
67
155
|
|
|
68
|
-
export default Session;
|
|
156
|
+
export default Session;
|