gametime-api-client 1.0.0 → 1.1.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/README.md +35 -1
- package/dist/index.d.ts +83 -2
- package/dist/index.js +29 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -78,22 +78,56 @@ try {
|
|
|
78
78
|
}
|
|
79
79
|
```
|
|
80
80
|
|
|
81
|
+
### Situations (historical stats + CSV export)
|
|
82
|
+
|
|
83
|
+
```js
|
|
84
|
+
import { gametime } from 'gametime-api-client';
|
|
85
|
+
import { writeFileSync } from 'fs';
|
|
86
|
+
|
|
87
|
+
// Austin Reaves, 4th quarter, down 1–15
|
|
88
|
+
const { id } = await gametime.situations.create({
|
|
89
|
+
sport: 'nba',
|
|
90
|
+
player: { name: 'Austin Reaves', team: 'LAL' },
|
|
91
|
+
filters: {
|
|
92
|
+
nba: {
|
|
93
|
+
quarter: 4,
|
|
94
|
+
timeRemainingSeconds: { gte: 0, lte: 720 },
|
|
95
|
+
scoreDiff: { gte: -15, lte: -1 },
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
season: { year: 2025, type: 'REG' },
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// Get analysis
|
|
102
|
+
const summary = await gametime.situations.analysis(id, 'nba');
|
|
103
|
+
console.log(summary.analysis.totals, summary.analysis.perStart);
|
|
104
|
+
|
|
105
|
+
// Export to CSV file
|
|
106
|
+
const csv = await gametime.situations.exportCsv(id, 'nba');
|
|
107
|
+
writeFileSync('austin-reaves-q4-down-1-15.csv', csv);
|
|
108
|
+
```
|
|
109
|
+
|
|
81
110
|
## API reference
|
|
82
111
|
|
|
83
112
|
| Method | Description |
|
|
84
113
|
|--------|-------------|
|
|
114
|
+
| **Live** | |
|
|
85
115
|
| `live.games(sport)` | `'soccer' \| 'nba'` – list in-progress live games |
|
|
86
116
|
| `live.players(sportEventId, sport)` | List players for a game |
|
|
87
117
|
| `live.soccerAnalysis({ sportEventId, focusPlayerId? })` | Soccer prediction analysis |
|
|
88
118
|
| `live.nbaAnalysis({ sportEventId, focusPlayerId?, verbosity? })` | NBA prediction analysis |
|
|
89
119
|
| `live.createSession({ sport, sportEventId, focusPlayerId? })` | Create live WebSocket session |
|
|
120
|
+
| **Situations** | |
|
|
121
|
+
| `situations.create(params)` | Create situation (player + filters + season or game) |
|
|
122
|
+
| `situations.analysis(id, sport)` | Get analysis (totals, perStart, reliability) |
|
|
123
|
+
| `situations.exportCsv(id, sport, { includeSummary? })` | Export stats as CSV string |
|
|
90
124
|
|
|
91
125
|
## Types
|
|
92
126
|
|
|
93
127
|
The client is written in TypeScript and ships with `.d.ts` definitions. Import types for better IDE support:
|
|
94
128
|
|
|
95
129
|
```ts
|
|
96
|
-
import type { LiveGame, SoccerAnalysis, NbaAnalysis } from 'gametime-api-client';
|
|
130
|
+
import type { LiveGame, SoccerAnalysis, NbaAnalysis, CreateSituationParams, SituationAnalysis } from 'gametime-api-client';
|
|
97
131
|
```
|
|
98
132
|
|
|
99
133
|
## Links
|
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Gametime API JavaScript Client
|
|
3
|
-
* Live sports data, player analysis, and
|
|
3
|
+
* Live sports data, player analysis, predictions, and historical situations for NBA & Soccer.
|
|
4
4
|
*
|
|
5
5
|
* @example
|
|
6
6
|
* ```js
|
|
7
7
|
* import { createClient } from 'gametime-api-client';
|
|
8
|
-
* const api = createClient(
|
|
8
|
+
* const api = createClient();
|
|
9
9
|
* const games = await api.live.games('soccer');
|
|
10
10
|
* const analysis = await api.live.soccerAnalysis({ sportEventId: games[0].sportEventId });
|
|
11
|
+
* const { id } = await api.situations.create({ player: {...}, filters: {...}, season: {...} });
|
|
12
|
+
* const csv = await api.situations.exportCsv(id, 'nba');
|
|
11
13
|
* ```
|
|
12
14
|
*/
|
|
13
15
|
export interface ClientOptions {
|
|
@@ -122,12 +124,91 @@ export interface NbaAnalysis {
|
|
|
122
124
|
};
|
|
123
125
|
narration?: Record<string, unknown>;
|
|
124
126
|
}
|
|
127
|
+
/** Situation create filters */
|
|
128
|
+
export interface SituationFiltersNba {
|
|
129
|
+
nba: {
|
|
130
|
+
quarter: 1 | 2 | 3 | 4;
|
|
131
|
+
timeRemainingSeconds: {
|
|
132
|
+
gte: number;
|
|
133
|
+
lte: number;
|
|
134
|
+
};
|
|
135
|
+
scoreDiff: {
|
|
136
|
+
gte: number;
|
|
137
|
+
lte: number;
|
|
138
|
+
};
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
export interface SituationFiltersSoccer {
|
|
142
|
+
soccer: {
|
|
143
|
+
half: 1 | 2;
|
|
144
|
+
minuteRange: {
|
|
145
|
+
gte: number;
|
|
146
|
+
lte: number;
|
|
147
|
+
};
|
|
148
|
+
scoreState: "leading" | "drawing" | "trailing";
|
|
149
|
+
goalDiffRange?: {
|
|
150
|
+
gte: number;
|
|
151
|
+
lte: number;
|
|
152
|
+
};
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
export interface CreateSituationParams {
|
|
156
|
+
sport?: "nba" | "soccer";
|
|
157
|
+
player: {
|
|
158
|
+
name: string;
|
|
159
|
+
id?: string;
|
|
160
|
+
team?: string;
|
|
161
|
+
};
|
|
162
|
+
filters: SituationFiltersNba | SituationFiltersSoccer;
|
|
163
|
+
limits?: {
|
|
164
|
+
maxGames?: number;
|
|
165
|
+
minStarts?: number;
|
|
166
|
+
maxStartsPerGame?: number;
|
|
167
|
+
};
|
|
168
|
+
game?: {
|
|
169
|
+
id: string;
|
|
170
|
+
};
|
|
171
|
+
season?: {
|
|
172
|
+
year: number;
|
|
173
|
+
type: "REG" | "PST" | "PRE";
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
export interface CreateSituationResponse {
|
|
177
|
+
id: string;
|
|
178
|
+
gamesScanned: number;
|
|
179
|
+
gamesUsed: number;
|
|
180
|
+
}
|
|
181
|
+
export interface SituationAnalysis {
|
|
182
|
+
id: string;
|
|
183
|
+
status: "ready" | "failed";
|
|
184
|
+
analysis: {
|
|
185
|
+
gamesScanned: number;
|
|
186
|
+
gamesUsed: number;
|
|
187
|
+
startsMatched: number;
|
|
188
|
+
reliabilityGrade: "A" | "B" | "C" | "D";
|
|
189
|
+
totals: Record<string, number>;
|
|
190
|
+
perStart: Record<string, number>;
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
/** Situations: create, analysis, CSV export */
|
|
194
|
+
export interface SituationsApi {
|
|
195
|
+
/** Create a situation (provide either game or season, not both) */
|
|
196
|
+
create(params: CreateSituationParams): Promise<CreateSituationResponse>;
|
|
197
|
+
/** Get analysis for a situation */
|
|
198
|
+
analysis(id: string, sport: "nba" | "soccer"): Promise<SituationAnalysis>;
|
|
199
|
+
/** Export situation stats as CSV string */
|
|
200
|
+
exportCsv(id: string, sport: "nba" | "soccer", options?: {
|
|
201
|
+
includeSummary?: boolean;
|
|
202
|
+
}): Promise<string>;
|
|
203
|
+
}
|
|
125
204
|
/** Create a Gametime API client */
|
|
126
205
|
export declare function createClient(options?: ClientOptions): {
|
|
127
206
|
live: LiveApi;
|
|
207
|
+
situations: SituationsApi;
|
|
128
208
|
};
|
|
129
209
|
/** Pre-built client using default hosted API URL */
|
|
130
210
|
export declare const gametime: {
|
|
131
211
|
live: LiveApi;
|
|
212
|
+
situations: SituationsApi;
|
|
132
213
|
};
|
|
133
214
|
export { ApiError };
|
package/dist/index.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Gametime API JavaScript Client
|
|
3
|
-
* Live sports data, player analysis, and
|
|
3
|
+
* Live sports data, player analysis, predictions, and historical situations for NBA & Soccer.
|
|
4
4
|
*
|
|
5
5
|
* @example
|
|
6
6
|
* ```js
|
|
7
7
|
* import { createClient } from 'gametime-api-client';
|
|
8
|
-
* const api = createClient(
|
|
8
|
+
* const api = createClient();
|
|
9
9
|
* const games = await api.live.games('soccer');
|
|
10
10
|
* const analysis = await api.live.soccerAnalysis({ sportEventId: games[0].sportEventId });
|
|
11
|
+
* const { id } = await api.situations.create({ player: {...}, filters: {...}, season: {...} });
|
|
12
|
+
* const csv = await api.situations.exportCsv(id, 'nba');
|
|
11
13
|
* ```
|
|
12
14
|
*/
|
|
13
15
|
const DEFAULT_BASE = "https://gametimeapi.onrender.com";
|
|
@@ -36,6 +38,16 @@ async function request(baseUrl, path, init) {
|
|
|
36
38
|
function get(baseUrl, path) {
|
|
37
39
|
return request(baseUrl, path, { method: "GET" });
|
|
38
40
|
}
|
|
41
|
+
async function getText(baseUrl, path) {
|
|
42
|
+
const url = `${baseUrl.replace(/\/$/, "")}${path}`;
|
|
43
|
+
const res = await fetch(url);
|
|
44
|
+
if (!res.ok) {
|
|
45
|
+
const body = await res.json().catch(() => ({}));
|
|
46
|
+
const err = body?.error ?? body;
|
|
47
|
+
throw new ApiError(err?.message ?? body?.message ?? res.statusText, err?.code, res.status, err?.details);
|
|
48
|
+
}
|
|
49
|
+
return res.text();
|
|
50
|
+
}
|
|
39
51
|
function post(baseUrl, path, body) {
|
|
40
52
|
return request(baseUrl, path, {
|
|
41
53
|
method: "POST",
|
|
@@ -63,7 +75,21 @@ export function createClient(options = {}) {
|
|
|
63
75
|
return post(baseUrl, "/v1/live/sessions", params);
|
|
64
76
|
},
|
|
65
77
|
};
|
|
66
|
-
|
|
78
|
+
const situations = {
|
|
79
|
+
create(params) {
|
|
80
|
+
return post(baseUrl, "/v1/situations", params);
|
|
81
|
+
},
|
|
82
|
+
analysis(id, sport) {
|
|
83
|
+
return get(baseUrl, `/v1/situations/${encodeURIComponent(id)}/analysis?sport=${sport}`);
|
|
84
|
+
},
|
|
85
|
+
exportCsv(id, sport, options) {
|
|
86
|
+
const q = new URLSearchParams({ sport });
|
|
87
|
+
if (options?.includeSummary !== undefined)
|
|
88
|
+
q.set("includeSummary", String(options.includeSummary));
|
|
89
|
+
return getText(baseUrl, `/v1/situations/${encodeURIComponent(id)}/export.csv?${q}`);
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
return { live, situations };
|
|
67
93
|
}
|
|
68
94
|
/** Pre-built client using default hosted API URL */
|
|
69
95
|
export const gametime = createClient();
|