@ekmanss/5eplay 20260716.0.0
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/LICENSE +21 -0
- package/README.md +184 -0
- package/dist/async_queue.d.ts +6 -0
- package/dist/async_queue.js +44 -0
- package/dist/capture.d.ts +11 -0
- package/dist/capture.js +199 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +41 -0
- package/dist/client.d.ts +2 -0
- package/dist/client.js +4 -0
- package/dist/errors.d.ts +20 -0
- package/dist/errors.js +42 -0
- package/dist/http.d.ts +23 -0
- package/dist/http.js +75 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +7 -0
- package/dist/input.d.ts +3 -0
- package/dist/input.js +45 -0
- package/dist/live_matches.d.ts +2 -0
- package/dist/live_matches.js +209 -0
- package/dist/log.d.ts +4 -0
- package/dist/log.js +153 -0
- package/dist/markdown.d.ts +5 -0
- package/dist/markdown.js +508 -0
- package/dist/mqtt.d.ts +29 -0
- package/dist/mqtt.js +285 -0
- package/dist/session.d.ts +2 -0
- package/dist/session.js +169 -0
- package/dist/transform.d.ts +21 -0
- package/dist/transform.js +466 -0
- package/dist/types.d.ts +504 -0
- package/dist/types.js +2 -0
- package/dist/value.d.ts +13 -0
- package/dist/value.js +76 -0
- package/dist/write_markdown.d.ts +11 -0
- package/dist/write_markdown.js +34 -0
- package/docs/data-contracts.md +113 -0
- package/docs/recipes.md +129 -0
- package/package.json +55 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,504 @@
|
|
|
1
|
+
export type FiveEPlayJson = null | boolean | number | string | FiveEPlayJson[] | {
|
|
2
|
+
[key: string]: FiveEPlayJson;
|
|
3
|
+
};
|
|
4
|
+
export type FiveEPlayJsonObject = {
|
|
5
|
+
[key: string]: FiveEPlayJson;
|
|
6
|
+
};
|
|
7
|
+
export type FiveEPlayErrorCode = 'INVALID_INPUT' | 'HTTP_ERROR' | 'TIMEOUT' | 'ABORTED' | 'MATCH_NOT_FOUND' | 'INVALID_RESPONSE' | 'REALTIME_CONNECTION_FAILED' | 'SESSION_CLOSED' | 'INTERNAL_ERROR';
|
|
8
|
+
export type FiveEPlayOperation = 'match-detail' | 'match-realtime' | 'live-matches';
|
|
9
|
+
export type FiveEPlayStage = 'validating-input' | 'fetching-match' | 'fetching-analysis' | 'fetching-logs' | 'fetching-community' | 'fetching-live-matches' | 'building-output' | 'connecting-realtime' | 'streaming-realtime' | 'completed';
|
|
10
|
+
export interface FiveEPlayProgressEvent {
|
|
11
|
+
operation: FiveEPlayOperation;
|
|
12
|
+
stage: FiveEPlayStage;
|
|
13
|
+
message: string;
|
|
14
|
+
timestamp: string;
|
|
15
|
+
}
|
|
16
|
+
export interface FiveEPlayRequestOptions {
|
|
17
|
+
timeoutMs?: number;
|
|
18
|
+
signal?: AbortSignal;
|
|
19
|
+
includeAnalysis?: boolean;
|
|
20
|
+
includeCommunityRatings?: boolean;
|
|
21
|
+
includeLogs?: boolean;
|
|
22
|
+
onProgress?: (event: FiveEPlayProgressEvent) => void;
|
|
23
|
+
}
|
|
24
|
+
export interface FiveEPlayClientOptions {
|
|
25
|
+
fetch?: typeof globalThis.fetch;
|
|
26
|
+
webSocketFactory?: FiveEPlayWebSocketFactory;
|
|
27
|
+
}
|
|
28
|
+
export type GetFiveEPlayMatchOptions = FiveEPlayClientOptions & FiveEPlayRequestOptions;
|
|
29
|
+
export type CreateFiveEPlayMatchSessionOptions = FiveEPlayClientOptions & FiveEPlayRequestOptions;
|
|
30
|
+
export interface GetFiveEPlayLiveMatchesOptions {
|
|
31
|
+
fetch?: typeof globalThis.fetch;
|
|
32
|
+
timeoutMs?: number;
|
|
33
|
+
signal?: AbortSignal;
|
|
34
|
+
onProgress?: (event: FiveEPlayProgressEvent) => void;
|
|
35
|
+
}
|
|
36
|
+
export interface FiveEPlayMatchIdentity {
|
|
37
|
+
id: string;
|
|
38
|
+
numericId: number;
|
|
39
|
+
url: string;
|
|
40
|
+
}
|
|
41
|
+
export type FiveEPlayMatchStatus = 'upcoming' | 'live' | 'completed' | 'unknown';
|
|
42
|
+
export type FiveEPlayMapStatus = 'upcoming' | 'live' | 'completed' | 'unknown';
|
|
43
|
+
export type FiveEPlaySide = 'CT' | 'T';
|
|
44
|
+
export interface FiveEPlayTournament {
|
|
45
|
+
id: string | null;
|
|
46
|
+
name: string;
|
|
47
|
+
logoUrl: string | null;
|
|
48
|
+
status: string | null;
|
|
49
|
+
grade: string | null;
|
|
50
|
+
gradeLabel: string | null;
|
|
51
|
+
location: string | null;
|
|
52
|
+
prize: string | null;
|
|
53
|
+
startsAt: string | null;
|
|
54
|
+
endsAt: string | null;
|
|
55
|
+
color: string | null;
|
|
56
|
+
}
|
|
57
|
+
export interface FiveEPlayTeam {
|
|
58
|
+
id: string;
|
|
59
|
+
name: string;
|
|
60
|
+
logoUrl: string | null;
|
|
61
|
+
country: string | null;
|
|
62
|
+
rank: number | null;
|
|
63
|
+
valveRank: number | null;
|
|
64
|
+
seriesScore: number | null;
|
|
65
|
+
quickScore: number | null;
|
|
66
|
+
odds: number | null;
|
|
67
|
+
oddsPercent: number | null;
|
|
68
|
+
}
|
|
69
|
+
export interface FiveEPlayVetoEntry {
|
|
70
|
+
order: number;
|
|
71
|
+
action: 'ban' | 'pick' | 'left' | 'unknown';
|
|
72
|
+
teamId: string | null;
|
|
73
|
+
map: string;
|
|
74
|
+
iconUrl: string | null;
|
|
75
|
+
backgroundUrl: string | null;
|
|
76
|
+
}
|
|
77
|
+
export interface FiveEPlayHalfScore {
|
|
78
|
+
side: FiveEPlaySide | null;
|
|
79
|
+
score: number | null;
|
|
80
|
+
roundResults: number[];
|
|
81
|
+
}
|
|
82
|
+
export interface FiveEPlayTeamMapState {
|
|
83
|
+
teamId: string | null;
|
|
84
|
+
currentSide: FiveEPlaySide | null;
|
|
85
|
+
score: number | null;
|
|
86
|
+
quickScore: number | null;
|
|
87
|
+
firstHalf: FiveEPlayHalfScore;
|
|
88
|
+
secondHalf: FiveEPlayHalfScore;
|
|
89
|
+
overtime: FiveEPlayHalfScore;
|
|
90
|
+
flags: string[];
|
|
91
|
+
}
|
|
92
|
+
export interface FiveEPlayPlayerEquipment {
|
|
93
|
+
health: number | null;
|
|
94
|
+
money: number | null;
|
|
95
|
+
armor: boolean | null;
|
|
96
|
+
helmet: boolean | null;
|
|
97
|
+
defuseKit: boolean | null;
|
|
98
|
+
alive: boolean | null;
|
|
99
|
+
weapon: string | null;
|
|
100
|
+
weaponLogoUrl: string | null;
|
|
101
|
+
}
|
|
102
|
+
export interface FiveEPlayPlayerMetrics {
|
|
103
|
+
kills: number | null;
|
|
104
|
+
deaths: number | null;
|
|
105
|
+
assists: number | null;
|
|
106
|
+
kdRatio: number | null;
|
|
107
|
+
kdDifference: number | null;
|
|
108
|
+
rating: number | null;
|
|
109
|
+
kastRate: number | null;
|
|
110
|
+
adr: number | null;
|
|
111
|
+
killsPerRound: number | null;
|
|
112
|
+
deathsPerRound: number | null;
|
|
113
|
+
impact: number | null;
|
|
114
|
+
multiKillRating: number | null;
|
|
115
|
+
roundSwingRate: number | null;
|
|
116
|
+
headshots: number | null;
|
|
117
|
+
headshotRate: number | null;
|
|
118
|
+
firstKills: number | null;
|
|
119
|
+
firstDeaths: number | null;
|
|
120
|
+
firstKillRate: number | null;
|
|
121
|
+
flashAssists: number | null;
|
|
122
|
+
tradedDeaths: number | null;
|
|
123
|
+
clutchWins: number | null;
|
|
124
|
+
roundMvp: number | null;
|
|
125
|
+
multiKills: {
|
|
126
|
+
two: number | null;
|
|
127
|
+
three: number | null;
|
|
128
|
+
four: number | null;
|
|
129
|
+
five: number | null;
|
|
130
|
+
};
|
|
131
|
+
clutches: {
|
|
132
|
+
oneVsOne: number | null;
|
|
133
|
+
oneVsTwo: number | null;
|
|
134
|
+
oneVsThree: number | null;
|
|
135
|
+
oneVsFour: number | null;
|
|
136
|
+
oneVsFive: number | null;
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
export interface FiveEPlayPlayerStats {
|
|
140
|
+
id: string;
|
|
141
|
+
name: string;
|
|
142
|
+
countryLogoUrl: string | null;
|
|
143
|
+
portraitUrl: string | null;
|
|
144
|
+
halfPortraitUrl: string | null;
|
|
145
|
+
equipment: FiveEPlayPlayerEquipment;
|
|
146
|
+
metrics: FiveEPlayPlayerMetrics;
|
|
147
|
+
versusKills: Record<string, number>;
|
|
148
|
+
firstKillsByOpponent: Record<string, number>;
|
|
149
|
+
}
|
|
150
|
+
export interface FiveEPlayTeamPlayerStats {
|
|
151
|
+
teamId: string;
|
|
152
|
+
overall: FiveEPlayPlayerStats[];
|
|
153
|
+
ct: FiveEPlayPlayerStats[];
|
|
154
|
+
t: FiveEPlayPlayerStats[];
|
|
155
|
+
}
|
|
156
|
+
export interface FiveEPlayPlayerDuel {
|
|
157
|
+
playerId: string;
|
|
158
|
+
opponentPlayerId: string;
|
|
159
|
+
kills: number;
|
|
160
|
+
}
|
|
161
|
+
export interface FiveEPlayRoundStart {
|
|
162
|
+
round: number | null;
|
|
163
|
+
map: string | null;
|
|
164
|
+
mapNumber: number | null;
|
|
165
|
+
}
|
|
166
|
+
export interface FiveEPlayRoundEnd {
|
|
167
|
+
ctScore: number | null;
|
|
168
|
+
tScore: number | null;
|
|
169
|
+
winnerSide: FiveEPlaySide | null;
|
|
170
|
+
reason: string | null;
|
|
171
|
+
reasonCode: number | null;
|
|
172
|
+
}
|
|
173
|
+
export interface FiveEPlayLogPlayer {
|
|
174
|
+
id: string | null;
|
|
175
|
+
name: string;
|
|
176
|
+
side: FiveEPlaySide | null;
|
|
177
|
+
}
|
|
178
|
+
export interface FiveEPlayKillEvent {
|
|
179
|
+
eventId: string | null;
|
|
180
|
+
killer: FiveEPlayLogPlayer;
|
|
181
|
+
victim: FiveEPlayLogPlayer;
|
|
182
|
+
assister: FiveEPlayLogPlayer | null;
|
|
183
|
+
flasher: FiveEPlayLogPlayer | null;
|
|
184
|
+
weapon: string | null;
|
|
185
|
+
weaponLogoUrl: string | null;
|
|
186
|
+
headshot: boolean;
|
|
187
|
+
wallbang: boolean;
|
|
188
|
+
throughSmoke: boolean;
|
|
189
|
+
noScope: boolean;
|
|
190
|
+
killerBlind: boolean;
|
|
191
|
+
killerPosition: {
|
|
192
|
+
x: number | null;
|
|
193
|
+
y: number | null;
|
|
194
|
+
};
|
|
195
|
+
victimPosition: {
|
|
196
|
+
x: number | null;
|
|
197
|
+
y: number | null;
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
export interface FiveEPlayBombEvent {
|
|
201
|
+
player: FiveEPlayLogPlayer;
|
|
202
|
+
site: string | null;
|
|
203
|
+
ctPlayers: number | null;
|
|
204
|
+
tPlayers: number | null;
|
|
205
|
+
}
|
|
206
|
+
export interface FiveEPlayLogEvent {
|
|
207
|
+
updateVersion: string;
|
|
208
|
+
matchId: string;
|
|
209
|
+
tournamentId: string | null;
|
|
210
|
+
mapId: string | null;
|
|
211
|
+
mapNumber: number | null;
|
|
212
|
+
map: string | null;
|
|
213
|
+
type: number | null;
|
|
214
|
+
kind: 'round-start' | 'round-end' | 'player-joined' | 'player-left' | 'bomb-planted' | 'bomb-defused' | 'kill' | 'suicide' | 'match-started' | 'restart' | 'unknown';
|
|
215
|
+
roundStart: FiveEPlayRoundStart | null;
|
|
216
|
+
roundEnd: FiveEPlayRoundEnd | null;
|
|
217
|
+
playerJoined: FiveEPlayLogPlayer | null;
|
|
218
|
+
playerLeft: FiveEPlayLogPlayer | null;
|
|
219
|
+
kill: FiveEPlayKillEvent | null;
|
|
220
|
+
suicide: {
|
|
221
|
+
player: FiveEPlayLogPlayer;
|
|
222
|
+
weapon: string | null;
|
|
223
|
+
weaponLogoUrl: string | null;
|
|
224
|
+
} | null;
|
|
225
|
+
bombPlanted: FiveEPlayBombEvent | null;
|
|
226
|
+
bombDefused: FiveEPlayLogPlayer | null;
|
|
227
|
+
restart: FiveEPlayJson | null;
|
|
228
|
+
}
|
|
229
|
+
export interface FiveEPlayMap {
|
|
230
|
+
id: string;
|
|
231
|
+
number: number;
|
|
232
|
+
label: string;
|
|
233
|
+
name: string;
|
|
234
|
+
status: FiveEPlayMapStatus;
|
|
235
|
+
display: boolean;
|
|
236
|
+
pickedByTeamId: string | null;
|
|
237
|
+
pickAction: 'pick' | 'left' | 'unknown';
|
|
238
|
+
resultTeamId: string | null;
|
|
239
|
+
iconUrl: string | null;
|
|
240
|
+
backgroundUrl: string | null;
|
|
241
|
+
startedAtUnixSeconds: number | null;
|
|
242
|
+
endedAtUnixSeconds: number | null;
|
|
243
|
+
currentRound: number | null;
|
|
244
|
+
roundStage: string | null;
|
|
245
|
+
gameTimeSeconds: number | null;
|
|
246
|
+
roundStartedAtUnixSeconds: number | null;
|
|
247
|
+
bombPlanted: boolean;
|
|
248
|
+
bombPlantedAtUnixSeconds: number | null;
|
|
249
|
+
teams: FiveEPlayTeamMapState[];
|
|
250
|
+
playerStats: FiveEPlayTeamPlayerStats[];
|
|
251
|
+
playerDuels: FiveEPlayPlayerDuel[];
|
|
252
|
+
highlights: FiveEPlayJsonObject[];
|
|
253
|
+
milestones: FiveEPlayJsonObject[];
|
|
254
|
+
eventLog: {
|
|
255
|
+
order: 'chronological';
|
|
256
|
+
complete: boolean;
|
|
257
|
+
fromVersion: string | null;
|
|
258
|
+
toVersion: string | null;
|
|
259
|
+
events: FiveEPlayLogEvent[];
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
export interface FiveEPlayAnalysisPlayer {
|
|
263
|
+
id: string;
|
|
264
|
+
name: string;
|
|
265
|
+
country: string | null;
|
|
266
|
+
countryLogoUrl: string | null;
|
|
267
|
+
logoUrl: string | null;
|
|
268
|
+
halfPortraitUrl: string | null;
|
|
269
|
+
rating: number | null;
|
|
270
|
+
kdRatio: number | null;
|
|
271
|
+
kastRate: number | null;
|
|
272
|
+
adr: number | null;
|
|
273
|
+
killsPerRound: number | null;
|
|
274
|
+
impact: number | null;
|
|
275
|
+
multiKillRating: number | null;
|
|
276
|
+
roundSwingRate: number | null;
|
|
277
|
+
}
|
|
278
|
+
export interface FiveEPlayAnalysisMap {
|
|
279
|
+
id: string | null;
|
|
280
|
+
name: string;
|
|
281
|
+
localizedName: string | null;
|
|
282
|
+
iconUrl: string | null;
|
|
283
|
+
backgroundUrl: string | null;
|
|
284
|
+
bpType: string | null;
|
|
285
|
+
teams: Array<{
|
|
286
|
+
teamId: string;
|
|
287
|
+
matches: number | null;
|
|
288
|
+
wins: number | null;
|
|
289
|
+
winRate: number | null;
|
|
290
|
+
picks: number | null;
|
|
291
|
+
pickRate: number | null;
|
|
292
|
+
bans: number | null;
|
|
293
|
+
banRate: number | null;
|
|
294
|
+
}>;
|
|
295
|
+
}
|
|
296
|
+
export interface FiveEPlayPrematchAnalysis {
|
|
297
|
+
hidden: boolean;
|
|
298
|
+
teams: Array<{
|
|
299
|
+
teamId: string;
|
|
300
|
+
winRate: number | null;
|
|
301
|
+
rating: number | null;
|
|
302
|
+
kdRatio: number | null;
|
|
303
|
+
firstHalfPistolWinRate: number | null;
|
|
304
|
+
secondHalfPistolWinRate: number | null;
|
|
305
|
+
players: FiveEPlayAnalysisPlayer[];
|
|
306
|
+
}>;
|
|
307
|
+
maps: FiveEPlayAnalysisMap[];
|
|
308
|
+
playerPower: Array<{
|
|
309
|
+
teamId: string;
|
|
310
|
+
players: FiveEPlayJsonObject[];
|
|
311
|
+
}>;
|
|
312
|
+
recentMatches: Array<{
|
|
313
|
+
teamId: string;
|
|
314
|
+
matches: FiveEPlayJsonObject[];
|
|
315
|
+
}>;
|
|
316
|
+
headToHead: {
|
|
317
|
+
teamWinRates: Array<{
|
|
318
|
+
teamId: string;
|
|
319
|
+
winRate: number | null;
|
|
320
|
+
}>;
|
|
321
|
+
matches: FiveEPlayJsonObject[];
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
export interface FiveEPlayCommunityScore {
|
|
325
|
+
average: number | null;
|
|
326
|
+
userCount: number;
|
|
327
|
+
text: string | null;
|
|
328
|
+
starCounts: number[];
|
|
329
|
+
starPercentages: Array<number | null>;
|
|
330
|
+
}
|
|
331
|
+
export interface FiveEPlayCommunityCard {
|
|
332
|
+
tab: string;
|
|
333
|
+
contentType: string | null;
|
|
334
|
+
id: string;
|
|
335
|
+
name: string;
|
|
336
|
+
logoUrl: string | null;
|
|
337
|
+
teamLogoUrl: string | null;
|
|
338
|
+
countryLogoUrl: string | null;
|
|
339
|
+
detail: string | null;
|
|
340
|
+
positions: string[];
|
|
341
|
+
content: string[];
|
|
342
|
+
score: FiveEPlayCommunityScore;
|
|
343
|
+
starLabels: string[];
|
|
344
|
+
}
|
|
345
|
+
export interface FiveEPlayCommunityRatings {
|
|
346
|
+
tabs: Array<{
|
|
347
|
+
tab: string;
|
|
348
|
+
id: string;
|
|
349
|
+
name: string;
|
|
350
|
+
logoUrl: string | null;
|
|
351
|
+
selected: boolean;
|
|
352
|
+
cards: FiveEPlayCommunityCard[];
|
|
353
|
+
}>;
|
|
354
|
+
}
|
|
355
|
+
export interface FiveEPlayMatch {
|
|
356
|
+
schemaVersion: '1.0.0';
|
|
357
|
+
capturedAt: string;
|
|
358
|
+
sport: 'cs2';
|
|
359
|
+
source: {
|
|
360
|
+
provider: '5eplay';
|
|
361
|
+
url: string;
|
|
362
|
+
};
|
|
363
|
+
stateVersion: string | null;
|
|
364
|
+
match: {
|
|
365
|
+
id: string;
|
|
366
|
+
numericId: number;
|
|
367
|
+
status: FiveEPlayMatchStatus;
|
|
368
|
+
version: string | null;
|
|
369
|
+
bestOf: number | null;
|
|
370
|
+
scheduledAtUnixSeconds: number | null;
|
|
371
|
+
stage: string | null;
|
|
372
|
+
stageDescription: string | null;
|
|
373
|
+
seriesScore: Array<{
|
|
374
|
+
teamId: string;
|
|
375
|
+
score: number | null;
|
|
376
|
+
}>;
|
|
377
|
+
};
|
|
378
|
+
tournament: FiveEPlayTournament;
|
|
379
|
+
teams: FiveEPlayTeam[];
|
|
380
|
+
veto: FiveEPlayVetoEntry[];
|
|
381
|
+
maps: FiveEPlayMap[];
|
|
382
|
+
current: FiveEPlayMap | null;
|
|
383
|
+
analysis: FiveEPlayPrematchAnalysis | null;
|
|
384
|
+
communityRatings: FiveEPlayCommunityRatings | null;
|
|
385
|
+
}
|
|
386
|
+
export interface FiveEPlayRequestDiagnostic {
|
|
387
|
+
kind: 'match' | 'analysis' | 'log' | 'community-tabs' | 'community-list' | 'live-list';
|
|
388
|
+
status: number;
|
|
389
|
+
durationMs: number;
|
|
390
|
+
bytes: number | null;
|
|
391
|
+
mapNumber?: number;
|
|
392
|
+
tab?: string;
|
|
393
|
+
page?: number;
|
|
394
|
+
}
|
|
395
|
+
export interface FiveEPlayDiagnosticWarning {
|
|
396
|
+
code: string;
|
|
397
|
+
reason: string;
|
|
398
|
+
section?: string;
|
|
399
|
+
mapNumber?: number;
|
|
400
|
+
}
|
|
401
|
+
export interface FiveEPlayMatchDiagnostics {
|
|
402
|
+
schemaVersion: '1.0.0';
|
|
403
|
+
operation: 'match-detail';
|
|
404
|
+
startedAt: string;
|
|
405
|
+
completedAt: string;
|
|
406
|
+
durationMs: number;
|
|
407
|
+
input: FiveEPlayMatchIdentity;
|
|
408
|
+
requests: FiveEPlayRequestDiagnostic[];
|
|
409
|
+
warnings: FiveEPlayDiagnosticWarning[];
|
|
410
|
+
}
|
|
411
|
+
export interface GetFiveEPlayMatchResult {
|
|
412
|
+
data: FiveEPlayMatch;
|
|
413
|
+
diagnostics: FiveEPlayMatchDiagnostics;
|
|
414
|
+
}
|
|
415
|
+
export interface FiveEPlayLiveMatchTeam {
|
|
416
|
+
id: string;
|
|
417
|
+
name: string;
|
|
418
|
+
country: string | null;
|
|
419
|
+
rank: number | null;
|
|
420
|
+
valveRank: number | null;
|
|
421
|
+
seriesScore: number | null;
|
|
422
|
+
}
|
|
423
|
+
export interface FiveEPlayLiveMatchMap {
|
|
424
|
+
id: string;
|
|
425
|
+
number: number;
|
|
426
|
+
name: string;
|
|
427
|
+
status: FiveEPlayMapStatus;
|
|
428
|
+
winnerTeamId: string | null;
|
|
429
|
+
teams: Array<{
|
|
430
|
+
teamId: string;
|
|
431
|
+
score: number | null;
|
|
432
|
+
}>;
|
|
433
|
+
}
|
|
434
|
+
export interface FiveEPlayLiveMatch {
|
|
435
|
+
id: string;
|
|
436
|
+
numericId: number;
|
|
437
|
+
url: string;
|
|
438
|
+
status: 'live';
|
|
439
|
+
bestOf: number | null;
|
|
440
|
+
scheduledAtUnixSeconds: number | null;
|
|
441
|
+
stage: string | null;
|
|
442
|
+
stageDescription: string | null;
|
|
443
|
+
tournament: {
|
|
444
|
+
id: string | null;
|
|
445
|
+
name: string;
|
|
446
|
+
grade: string | null;
|
|
447
|
+
gradeLabel: string | null;
|
|
448
|
+
};
|
|
449
|
+
teams: FiveEPlayLiveMatchTeam[];
|
|
450
|
+
maps: FiveEPlayLiveMatchMap[];
|
|
451
|
+
currentMap: FiveEPlayLiveMatchMap | null;
|
|
452
|
+
}
|
|
453
|
+
export interface FiveEPlayLiveMatchesData {
|
|
454
|
+
schemaVersion: '1.0.0';
|
|
455
|
+
capturedAt: string;
|
|
456
|
+
source: {
|
|
457
|
+
provider: '5eplay';
|
|
458
|
+
url: 'https://event.5eplay.com/csgo/matches';
|
|
459
|
+
};
|
|
460
|
+
hasLiveMatches: boolean;
|
|
461
|
+
matches: FiveEPlayLiveMatch[];
|
|
462
|
+
}
|
|
463
|
+
export interface FiveEPlayLiveMatchesDiagnostics {
|
|
464
|
+
schemaVersion: '1.0.0';
|
|
465
|
+
operation: 'live-matches';
|
|
466
|
+
startedAt: string;
|
|
467
|
+
completedAt: string;
|
|
468
|
+
durationMs: number;
|
|
469
|
+
requests: FiveEPlayRequestDiagnostic[];
|
|
470
|
+
}
|
|
471
|
+
export interface GetFiveEPlayLiveMatchesResult {
|
|
472
|
+
data: FiveEPlayLiveMatchesData;
|
|
473
|
+
diagnostics: FiveEPlayLiveMatchesDiagnostics;
|
|
474
|
+
}
|
|
475
|
+
export type FiveEPlayRealtimeUpdate = {
|
|
476
|
+
type: 'snapshot';
|
|
477
|
+
capturedAt: string;
|
|
478
|
+
snapshot: FiveEPlayMatch;
|
|
479
|
+
} | {
|
|
480
|
+
type: 'state';
|
|
481
|
+
capturedAt: string;
|
|
482
|
+
stateVersion: string | null;
|
|
483
|
+
snapshot: FiveEPlayMatch;
|
|
484
|
+
} | {
|
|
485
|
+
type: 'log';
|
|
486
|
+
capturedAt: string;
|
|
487
|
+
event: FiveEPlayLogEvent;
|
|
488
|
+
snapshot: FiveEPlayMatch;
|
|
489
|
+
};
|
|
490
|
+
export interface FiveEPlayMatchSession extends AsyncIterable<FiveEPlayRealtimeUpdate>, AsyncDisposable {
|
|
491
|
+
readonly id: string;
|
|
492
|
+
readonly initial: GetFiveEPlayMatchResult;
|
|
493
|
+
snapshot(): FiveEPlayMatch;
|
|
494
|
+
close(): Promise<void>;
|
|
495
|
+
}
|
|
496
|
+
export interface FiveEPlayWebSocketLike {
|
|
497
|
+
binaryType: BinaryType;
|
|
498
|
+
readyState: number;
|
|
499
|
+
addEventListener(type: 'open' | 'message' | 'error' | 'close', listener: EventListener): void;
|
|
500
|
+
removeEventListener(type: 'open' | 'message' | 'error' | 'close', listener: EventListener): void;
|
|
501
|
+
send(data: ArrayBufferView | ArrayBuffer | Blob | string): void;
|
|
502
|
+
close(code?: number, reason?: string): void;
|
|
503
|
+
}
|
|
504
|
+
export type FiveEPlayWebSocketFactory = (url: string, protocols: string[]) => FiveEPlayWebSocketLike;
|
package/dist/types.js
ADDED
package/dist/value.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { FiveEPlayJson, FiveEPlayJsonObject } from './types.js';
|
|
2
|
+
export declare function record(value: unknown): Record<string, unknown>;
|
|
3
|
+
export declare function records(value: unknown): Record<string, unknown>[];
|
|
4
|
+
export declare function text(value: unknown): string | null;
|
|
5
|
+
export declare function sourceText(value: unknown): string;
|
|
6
|
+
export declare function numeric(value: unknown): number | null;
|
|
7
|
+
export declare function integer(value: unknown): number | null;
|
|
8
|
+
export declare function flag(value: unknown): boolean | null;
|
|
9
|
+
export declare function strings(value: unknown): string[];
|
|
10
|
+
export declare function json(value: unknown): FiveEPlayJson;
|
|
11
|
+
export declare function jsonObject(value: unknown): FiveEPlayJsonObject;
|
|
12
|
+
export declare function jsonObjects(value: unknown): FiveEPlayJsonObject[];
|
|
13
|
+
export declare function side(value: unknown): 'CT' | 'T' | null;
|
package/dist/value.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
export function record(value) {
|
|
2
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value)
|
|
3
|
+
? value
|
|
4
|
+
: {};
|
|
5
|
+
}
|
|
6
|
+
export function records(value) {
|
|
7
|
+
return Array.isArray(value) ? value.map(record) : [];
|
|
8
|
+
}
|
|
9
|
+
export function text(value) {
|
|
10
|
+
if (typeof value === 'string')
|
|
11
|
+
return value.trim() || null;
|
|
12
|
+
if (typeof value === 'number' && Number.isFinite(value))
|
|
13
|
+
return String(value);
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
export function sourceText(value) {
|
|
17
|
+
return typeof value === 'string' ? value : value == null ? '' : String(value);
|
|
18
|
+
}
|
|
19
|
+
export function numeric(value) {
|
|
20
|
+
if (typeof value === 'number')
|
|
21
|
+
return Number.isFinite(value) ? value : null;
|
|
22
|
+
if (typeof value !== 'string')
|
|
23
|
+
return null;
|
|
24
|
+
const normalized = value.trim().replace(/[%+,]/g, '');
|
|
25
|
+
if (!normalized || normalized === '--' || normalized === '-')
|
|
26
|
+
return null;
|
|
27
|
+
const parsed = Number(normalized);
|
|
28
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
29
|
+
}
|
|
30
|
+
export function integer(value) {
|
|
31
|
+
const parsed = numeric(value);
|
|
32
|
+
return parsed === null || !Number.isInteger(parsed) ? null : parsed;
|
|
33
|
+
}
|
|
34
|
+
export function flag(value) {
|
|
35
|
+
if (typeof value === 'boolean')
|
|
36
|
+
return value;
|
|
37
|
+
if (value === 1 || value === '1')
|
|
38
|
+
return true;
|
|
39
|
+
if (value === 0 || value === '0' || value === 2 || value === '2')
|
|
40
|
+
return false;
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
export function strings(value) {
|
|
44
|
+
return Array.isArray(value)
|
|
45
|
+
? value.flatMap((item) => typeof item === 'string' ? [item] : [])
|
|
46
|
+
: [];
|
|
47
|
+
}
|
|
48
|
+
export function json(value) {
|
|
49
|
+
if (value === null || typeof value === 'string' || typeof value === 'boolean')
|
|
50
|
+
return value;
|
|
51
|
+
if (typeof value === 'number')
|
|
52
|
+
return Number.isFinite(value) ? value : null;
|
|
53
|
+
if (Array.isArray(value))
|
|
54
|
+
return value.map(json);
|
|
55
|
+
if (typeof value === 'object') {
|
|
56
|
+
return Object.fromEntries(Object.entries(value).map(([key, nested]) => [key, json(nested)]));
|
|
57
|
+
}
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
export function jsonObject(value) {
|
|
61
|
+
const converted = json(value);
|
|
62
|
+
return converted !== null && typeof converted === 'object' && !Array.isArray(converted)
|
|
63
|
+
? converted
|
|
64
|
+
: {};
|
|
65
|
+
}
|
|
66
|
+
export function jsonObjects(value) {
|
|
67
|
+
return Array.isArray(value) ? value.map(jsonObject) : [];
|
|
68
|
+
}
|
|
69
|
+
export function side(value) {
|
|
70
|
+
const normalized = text(value)?.toUpperCase();
|
|
71
|
+
if (normalized === 'CT')
|
|
72
|
+
return 'CT';
|
|
73
|
+
if (normalized === 'T' || normalized === 'TERRORIST')
|
|
74
|
+
return 'T';
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type FiveEPlayMarkdownOptions } from './markdown.js';
|
|
2
|
+
import type { GetFiveEPlayMatchOptions, GetFiveEPlayMatchResult } from './types.js';
|
|
3
|
+
export interface WriteFiveEPlayMatchMarkdownOptions extends GetFiveEPlayMatchOptions, FiveEPlayMarkdownOptions {
|
|
4
|
+
}
|
|
5
|
+
export interface WriteFiveEPlayMatchMarkdownResult {
|
|
6
|
+
outputPath: string;
|
|
7
|
+
bytes: number;
|
|
8
|
+
result: GetFiveEPlayMatchResult;
|
|
9
|
+
}
|
|
10
|
+
export declare function fiveEPlayMarkdownOutputPath(target: string, matchId: string): string;
|
|
11
|
+
export declare function writeFiveEPlayMatchMarkdown(input: string, target: string, options?: WriteFiveEPlayMatchMarkdownOptions): Promise<WriteFiveEPlayMatchMarkdownResult>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { mkdir, rename, rm, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { basename, dirname, extname, resolve } from 'node:path';
|
|
4
|
+
import { getFiveEPlayMatch } from './client.js';
|
|
5
|
+
import { renderFiveEPlayMatchMarkdown, } from './markdown.js';
|
|
6
|
+
export function fiveEPlayMarkdownOutputPath(target, matchId) {
|
|
7
|
+
const normalized = resolve(target);
|
|
8
|
+
return extname(normalized).toLowerCase() === '.md'
|
|
9
|
+
? normalized
|
|
10
|
+
: resolve(normalized, `${matchId}.md`);
|
|
11
|
+
}
|
|
12
|
+
export async function writeFiveEPlayMatchMarkdown(input, target, options = {}) {
|
|
13
|
+
const result = await getFiveEPlayMatch(input, {
|
|
14
|
+
...options,
|
|
15
|
+
includeCommunityRatings: false,
|
|
16
|
+
});
|
|
17
|
+
const outputPath = fiveEPlayMarkdownOutputPath(target, result.data.match.id);
|
|
18
|
+
const markdown = renderFiveEPlayMatchMarkdown(result, options);
|
|
19
|
+
await mkdir(dirname(outputPath), { recursive: true });
|
|
20
|
+
const temporaryPath = resolve(dirname(outputPath), `.${basename(outputPath)}.${process.pid}.${randomUUID()}.tmp`);
|
|
21
|
+
try {
|
|
22
|
+
await writeFile(temporaryPath, markdown, 'utf8');
|
|
23
|
+
await rename(temporaryPath, outputPath);
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
await rm(temporaryPath, { force: true });
|
|
27
|
+
throw error;
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
outputPath,
|
|
31
|
+
bytes: Buffer.byteLength(markdown),
|
|
32
|
+
result,
|
|
33
|
+
};
|
|
34
|
+
}
|