vairified 0.1.1 → 0.3.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 +314 -250
- package/dist/index.cjs +950 -802
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1016 -767
- package/dist/index.d.ts +1016 -767
- package/dist/index.js +938 -796
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,982 +1,1227 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* HTTP transport — internal. Not part of the public API.
|
|
3
|
+
*
|
|
4
|
+
* The transport is a thin wrapper around native `fetch` that:
|
|
5
|
+
*
|
|
6
|
+
* - Injects the API key header on every request.
|
|
7
|
+
* - Serializes query params (dropping `undefined`) and JSON bodies.
|
|
8
|
+
* - Applies a request timeout via `AbortController`.
|
|
9
|
+
* - Maps non-2xx responses to the right typed exception.
|
|
10
|
+
*
|
|
11
|
+
* @internal
|
|
12
|
+
* @module
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Values accepted as query parameters.
|
|
16
|
+
*
|
|
17
|
+
* `null` and `undefined` are silently dropped. Arrays are joined with
|
|
18
|
+
* `','`. Everything else is stringified.
|
|
19
|
+
*
|
|
20
|
+
* @internal
|
|
21
|
+
*/
|
|
22
|
+
type QueryParams = Readonly<Record<string, string | number | boolean | readonly (string | number)[] | null | undefined>>;
|
|
23
|
+
/**
|
|
24
|
+
* Options passed to the internal HTTP layer.
|
|
25
|
+
*
|
|
26
|
+
* @internal
|
|
27
|
+
*/
|
|
28
|
+
interface RequestOptions {
|
|
29
|
+
readonly method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
30
|
+
readonly path: string;
|
|
31
|
+
readonly query?: QueryParams;
|
|
32
|
+
readonly body?: unknown;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Transport configuration.
|
|
36
|
+
*
|
|
37
|
+
* @internal
|
|
38
|
+
*/
|
|
39
|
+
interface TransportConfig {
|
|
40
|
+
readonly baseUrl: string;
|
|
41
|
+
readonly apiKey: string;
|
|
42
|
+
readonly timeoutMs: number;
|
|
43
|
+
readonly fetch: typeof fetch;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Internal HTTP client. Holds no state between requests — each call
|
|
47
|
+
* builds a fresh `Request`, runs it, and returns the parsed body.
|
|
48
|
+
*
|
|
49
|
+
* @internal
|
|
50
|
+
*/
|
|
51
|
+
declare class HttpTransport {
|
|
52
|
+
#private;
|
|
53
|
+
constructor(config: TransportConfig);
|
|
54
|
+
request<T>(options: RequestOptions): Promise<T>;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Vairified SDK — Partner API v1 wire types.
|
|
59
|
+
*
|
|
60
|
+
* These are the raw shapes the server returns or accepts. Request
|
|
61
|
+
* types (e.g. {@link MatchBatch}, {@link SearchFilters}) are used as-is
|
|
62
|
+
* by the SDK. Response types (e.g. {@link PartnerMemberWire}) are
|
|
63
|
+
* wrapped in class instances by the SDK — see the `models/` folder.
|
|
3
64
|
*
|
|
4
65
|
* @module
|
|
5
66
|
*/
|
|
6
67
|
/**
|
|
7
|
-
*
|
|
68
|
+
* Environment preset for the Vairified API.
|
|
8
69
|
*
|
|
9
|
-
* @category
|
|
70
|
+
* @category Client
|
|
71
|
+
*/
|
|
72
|
+
type VairifiedEnvironment = 'production' | 'staging' | 'local';
|
|
73
|
+
/**
|
|
74
|
+
* Options passed to the {@link Vairified} constructor.
|
|
75
|
+
*
|
|
76
|
+
* @category Client
|
|
10
77
|
*/
|
|
11
78
|
interface VairifiedOptions {
|
|
12
|
-
/** API key
|
|
79
|
+
/** Partner API key (`vair_pk_...`). Falls back to `VAIRIFIED_API_KEY`. */
|
|
13
80
|
apiKey?: string;
|
|
14
|
-
/** Environment preset
|
|
15
|
-
env?:
|
|
16
|
-
/**
|
|
81
|
+
/** Environment preset. Falls back to `VAIRIFIED_ENV` or `'production'`. */
|
|
82
|
+
env?: VairifiedEnvironment;
|
|
83
|
+
/** Explicit base URL. Takes precedence over `env`. */
|
|
17
84
|
baseUrl?: string;
|
|
18
|
-
/** Request timeout in milliseconds (
|
|
19
|
-
|
|
85
|
+
/** Request timeout in milliseconds. Defaults to 30_000 (30s). */
|
|
86
|
+
timeoutMs?: number;
|
|
87
|
+
/**
|
|
88
|
+
* Inject a custom `fetch` implementation. Defaults to the global
|
|
89
|
+
* `fetch`. Useful for test shims or non-Node environments.
|
|
90
|
+
*/
|
|
91
|
+
fetch?: typeof fetch;
|
|
20
92
|
}
|
|
21
93
|
/**
|
|
22
|
-
*
|
|
94
|
+
* Normalized gender tokens emitted by the Partner API.
|
|
95
|
+
*
|
|
96
|
+
* @category Members
|
|
97
|
+
*/
|
|
98
|
+
type Gender = 'MALE' | 'FEMALE' | 'OTHER' | 'UNKNOWN';
|
|
99
|
+
/**
|
|
100
|
+
* Raw rating split — one slice of a player's rating for a specific
|
|
101
|
+
* category × age bracket.
|
|
23
102
|
*
|
|
24
|
-
* @category
|
|
103
|
+
* @category Members
|
|
25
104
|
*/
|
|
26
|
-
interface
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
/** Abbreviation (e.g., "VG", "50+") */
|
|
30
|
-
abbr: string;
|
|
31
|
-
/** Date of last match in this category */
|
|
32
|
-
date_played?: string;
|
|
105
|
+
interface RatingSplitWire {
|
|
106
|
+
readonly rating: number;
|
|
107
|
+
readonly abbr: string;
|
|
33
108
|
}
|
|
34
109
|
/**
|
|
35
|
-
*
|
|
110
|
+
* Raw sport rating — a player's ratings for one sport.
|
|
36
111
|
*
|
|
37
|
-
* @category
|
|
112
|
+
* @category Members
|
|
38
113
|
*/
|
|
39
|
-
|
|
114
|
+
interface SportRatingWire {
|
|
115
|
+
readonly rating: number;
|
|
116
|
+
readonly abbr: string;
|
|
117
|
+
readonly ratingSplits: Readonly<Record<string, RatingSplitWire>>;
|
|
118
|
+
}
|
|
40
119
|
/**
|
|
41
|
-
*
|
|
120
|
+
* Grouped member status flags.
|
|
42
121
|
*
|
|
43
|
-
* @category
|
|
122
|
+
* @category Members
|
|
44
123
|
*/
|
|
45
|
-
interface
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
email?: string;
|
|
52
|
-
rating?: number;
|
|
53
|
-
isVairified?: boolean;
|
|
54
|
-
ratingSplits?: RatingSplitsData;
|
|
55
|
-
city?: string;
|
|
56
|
-
state?: string;
|
|
57
|
-
country?: string;
|
|
58
|
-
/** Scopes the player granted to your app */
|
|
59
|
-
grantedScopes?: string[];
|
|
124
|
+
interface MemberStatusWire {
|
|
125
|
+
readonly isVairified: boolean;
|
|
126
|
+
readonly isWheelchair: boolean;
|
|
127
|
+
readonly isAmbassador: boolean;
|
|
128
|
+
readonly isRater: boolean;
|
|
129
|
+
readonly isConnected: boolean;
|
|
60
130
|
}
|
|
61
131
|
/**
|
|
62
|
-
*
|
|
132
|
+
* Raw partner-facing member record returned by the Partner API.
|
|
63
133
|
*
|
|
64
|
-
* @category
|
|
134
|
+
* @category Members
|
|
65
135
|
*/
|
|
66
|
-
interface
|
|
67
|
-
|
|
68
|
-
id
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
136
|
+
interface PartnerMemberWire {
|
|
137
|
+
readonly memberId: number;
|
|
138
|
+
readonly id?: string;
|
|
139
|
+
readonly firstName: string;
|
|
140
|
+
readonly lastName: string;
|
|
141
|
+
readonly fullName: string;
|
|
142
|
+
readonly displayName: string;
|
|
143
|
+
readonly age?: number;
|
|
144
|
+
readonly city?: string;
|
|
145
|
+
readonly state?: string;
|
|
146
|
+
readonly zip?: string;
|
|
147
|
+
readonly country?: string;
|
|
148
|
+
readonly gender?: Gender;
|
|
149
|
+
readonly status: MemberStatusWire;
|
|
150
|
+
readonly sport?: Readonly<Record<string, SportRatingWire>>;
|
|
151
|
+
readonly activeLeagues?: readonly string[];
|
|
152
|
+
readonly email?: string;
|
|
153
|
+
readonly grantedScopes?: readonly string[];
|
|
78
154
|
}
|
|
79
155
|
/**
|
|
80
|
-
*
|
|
156
|
+
* Raw rating change notification.
|
|
157
|
+
*
|
|
158
|
+
* @category Members
|
|
159
|
+
*/
|
|
160
|
+
interface PartnerRatingUpdateWire {
|
|
161
|
+
readonly memberId: number;
|
|
162
|
+
readonly id?: string;
|
|
163
|
+
readonly displayName?: string;
|
|
164
|
+
readonly sport?: string;
|
|
165
|
+
readonly previousRating?: number;
|
|
166
|
+
readonly newRating?: number;
|
|
167
|
+
readonly changedAt?: string;
|
|
168
|
+
readonly ratingSplits?: Readonly<Record<string, RatingSplitWire>>;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Filters accepted by {@link MembersResource.search}.
|
|
172
|
+
*
|
|
173
|
+
* Most callers pass these as keyword arguments directly to `search()`;
|
|
174
|
+
* the SDK serializes them to query parameters for you.
|
|
81
175
|
*
|
|
82
|
-
* @category
|
|
176
|
+
* @category Members
|
|
83
177
|
*/
|
|
84
178
|
interface SearchFilters {
|
|
85
|
-
/**
|
|
179
|
+
/** Sport code (e.g. `'pickleball'`) or list of codes. */
|
|
180
|
+
sport?: string | readonly string[];
|
|
181
|
+
/** Partial name match (first or last). */
|
|
86
182
|
name?: string;
|
|
87
|
-
/**
|
|
183
|
+
/** Exact numeric member ID. */
|
|
184
|
+
memberId?: number | string;
|
|
88
185
|
city?: string;
|
|
89
|
-
/** State code (e.g., "TX") */
|
|
90
186
|
state?: string;
|
|
91
|
-
/** Country code (e.g., "US") */
|
|
92
187
|
country?: string;
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
188
|
+
zip?: string;
|
|
189
|
+
location?: string;
|
|
190
|
+
gender?: Gender | Lowercase<Gender>;
|
|
191
|
+
/** When `true`, only return verified players. */
|
|
192
|
+
vairifiedOnly?: boolean;
|
|
193
|
+
/** When `true`, only return wheelchair players. */
|
|
194
|
+
wheelchair?: boolean;
|
|
195
|
+
/** Lower rating bound (2.0–8.0). */
|
|
96
196
|
ratingMin?: number;
|
|
97
|
-
/**
|
|
197
|
+
/** Upper rating bound (2.0–8.0). */
|
|
98
198
|
ratingMax?: number;
|
|
99
|
-
/**
|
|
100
|
-
gender?: 'MALE' | 'FEMALE';
|
|
101
|
-
/** Only verified players */
|
|
102
|
-
vairifiedOnly?: boolean;
|
|
103
|
-
/** Exact age */
|
|
199
|
+
/** Exact age. */
|
|
104
200
|
age?: number;
|
|
105
|
-
/**
|
|
201
|
+
/** Lower age bound. */
|
|
106
202
|
ageMin?: number;
|
|
107
|
-
/**
|
|
203
|
+
/** Upper age bound. */
|
|
108
204
|
ageMax?: number;
|
|
109
|
-
/** Field to sort by */
|
|
110
205
|
sortBy?: string;
|
|
111
|
-
/** Sort direction */
|
|
112
206
|
sortOrder?: 'asc' | 'desc';
|
|
113
|
-
/** Page
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
|
|
207
|
+
/** Page size requested per HTTP request (server cap 100). Default 20. */
|
|
208
|
+
pageSize?: number;
|
|
209
|
+
/**
|
|
210
|
+
* Maximum total results to iterate. When set, the async iterator
|
|
211
|
+
* stops after yielding this many items, regardless of page count.
|
|
212
|
+
*/
|
|
213
|
+
maxResults?: number;
|
|
117
214
|
}
|
|
118
215
|
/**
|
|
119
|
-
*
|
|
216
|
+
* One scored game within a {@link MatchInput}.
|
|
217
|
+
*
|
|
218
|
+
* `scores` contains one integer per team, in the same order as the
|
|
219
|
+
* parent match's `teams` list. For a standard 2-team game that's
|
|
220
|
+
* `[team1Score, team2Score]`. Longer lists are supported for
|
|
221
|
+
* n-team matches.
|
|
120
222
|
*
|
|
121
|
-
*
|
|
223
|
+
* All other fields override the parent match's defaults for this
|
|
224
|
+
* specific game (e.g. a championship game played to 15 when the rest
|
|
225
|
+
* of the match was to 11).
|
|
226
|
+
*
|
|
227
|
+
* @category Matches
|
|
122
228
|
*/
|
|
123
|
-
interface
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
/** Match date and time */
|
|
129
|
-
date: Date | string;
|
|
130
|
-
/** Team 1 player IDs (1 for singles, 2 for doubles) */
|
|
131
|
-
team1: [string] | [string, string];
|
|
132
|
-
/** Team 2 player IDs (1 for singles, 2 for doubles) */
|
|
133
|
-
team2: [string] | [string, string];
|
|
134
|
-
/** Game scores as [team1Score, team2Score] tuples */
|
|
135
|
-
scores: [number, number][];
|
|
136
|
-
/** Match type (default: "SIDEOUT") */
|
|
137
|
-
matchType?: string;
|
|
138
|
-
/** Match source (default: "PARTNER") */
|
|
139
|
-
source?: string;
|
|
140
|
-
/** Location (optional) */
|
|
141
|
-
location?: string;
|
|
142
|
-
/** Unique identifier (auto-generated if not provided) */
|
|
143
|
-
identifier?: string;
|
|
229
|
+
interface GameInput {
|
|
230
|
+
readonly scores: readonly number[];
|
|
231
|
+
readonly identifier?: string;
|
|
232
|
+
readonly winScore?: number;
|
|
233
|
+
readonly winBy?: number;
|
|
144
234
|
}
|
|
145
235
|
/**
|
|
146
|
-
*
|
|
236
|
+
* One match to submit in a {@link MatchBatch}.
|
|
237
|
+
*
|
|
238
|
+
* A match is n-team × n-game:
|
|
239
|
+
*
|
|
240
|
+
* - `teams: [['p1', 'p2'], ['p3', 'p4']]` — standard doubles
|
|
241
|
+
* - `teams: [['p1'], ['p2']]` — singles
|
|
242
|
+
* - `teams: [['p1'], ['p2'], ['p3']]` — 3-way round robin
|
|
243
|
+
*
|
|
244
|
+
* Scores in each {@link GameInput} are parallel to the `teams` order.
|
|
147
245
|
*
|
|
148
|
-
* @category
|
|
246
|
+
* @category Matches
|
|
149
247
|
*/
|
|
150
|
-
interface
|
|
151
|
-
identifier: string;
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
};
|
|
168
|
-
teamB: {
|
|
169
|
-
player1: string;
|
|
170
|
-
player2?: string;
|
|
171
|
-
game1?: number;
|
|
172
|
-
game2?: number;
|
|
173
|
-
game3?: number;
|
|
174
|
-
game4?: number;
|
|
175
|
-
game5?: number;
|
|
176
|
-
};
|
|
177
|
-
}
|
|
178
|
-
/**
|
|
179
|
-
* Response from match submission.
|
|
180
|
-
*
|
|
181
|
-
* @category Types
|
|
182
|
-
*/
|
|
183
|
-
interface MatchResultData {
|
|
184
|
-
/** Whether submission succeeded */
|
|
185
|
-
success: boolean;
|
|
186
|
-
/** Number of matches processed */
|
|
187
|
-
numMatches: number;
|
|
188
|
-
/** Total number of games recorded */
|
|
189
|
-
numGames: number;
|
|
190
|
-
/** Whether this was a dry-run (validation only) */
|
|
191
|
-
dryRun?: boolean;
|
|
192
|
-
/** Human-readable result message */
|
|
193
|
-
message?: string;
|
|
194
|
-
/** List of validation/processing errors */
|
|
195
|
-
errors?: string[];
|
|
196
|
-
}
|
|
197
|
-
/**
|
|
198
|
-
* Rating update from API.
|
|
199
|
-
*
|
|
200
|
-
* @category Types
|
|
201
|
-
*/
|
|
202
|
-
interface RatingUpdateData {
|
|
203
|
-
/** External player ID (vair_mem_xxx format) */
|
|
204
|
-
id: string;
|
|
205
|
-
memberName?: string;
|
|
206
|
-
previousRating?: number;
|
|
207
|
-
newRating?: number;
|
|
208
|
-
changedAt?: string;
|
|
209
|
-
ratingSplits?: RatingSplitsData;
|
|
210
|
-
}
|
|
211
|
-
/**
|
|
212
|
-
* Search results from API.
|
|
213
|
-
*
|
|
214
|
-
* @category Types
|
|
215
|
-
*/
|
|
216
|
-
interface SearchResultsData {
|
|
217
|
-
players: PlayerSearchData[];
|
|
218
|
-
total: number;
|
|
219
|
-
page: number;
|
|
220
|
-
limit: number;
|
|
248
|
+
interface MatchInput {
|
|
249
|
+
readonly identifier: string;
|
|
250
|
+
readonly teams: readonly (readonly string[])[];
|
|
251
|
+
readonly games: readonly GameInput[];
|
|
252
|
+
readonly sport?: string;
|
|
253
|
+
readonly bracket?: string;
|
|
254
|
+
readonly event?: string;
|
|
255
|
+
readonly location?: string;
|
|
256
|
+
readonly matchDate?: string;
|
|
257
|
+
readonly matchSource?: string;
|
|
258
|
+
readonly matchType?: string;
|
|
259
|
+
readonly winScore?: number;
|
|
260
|
+
readonly winBy?: number;
|
|
261
|
+
readonly extras?: Readonly<Record<string, unknown>>;
|
|
262
|
+
readonly originalId?: string;
|
|
263
|
+
readonly originalType?: string;
|
|
264
|
+
readonly clubId?: number;
|
|
221
265
|
}
|
|
222
|
-
|
|
223
266
|
/**
|
|
224
|
-
*
|
|
267
|
+
* Compressed bulk match submission.
|
|
225
268
|
*
|
|
226
|
-
*
|
|
269
|
+
* Top-level fields are defaults applied to every match in the
|
|
270
|
+
* {@link matches} list. Any match can override any field. `sport`,
|
|
271
|
+
* `winScore`, and `winBy` are **required** at the batch level — partners
|
|
272
|
+
* must tell the rater which sport the matches are in and what the
|
|
273
|
+
* winning conditions were so scores can be interpreted correctly.
|
|
227
274
|
*
|
|
228
|
-
* @
|
|
275
|
+
* @category Matches
|
|
229
276
|
*/
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
277
|
+
interface MatchBatch {
|
|
278
|
+
readonly sport: string;
|
|
279
|
+
readonly winScore: number;
|
|
280
|
+
readonly winBy: number;
|
|
281
|
+
readonly matches: readonly MatchInput[];
|
|
282
|
+
readonly bracket?: string;
|
|
283
|
+
readonly event?: string;
|
|
284
|
+
readonly location?: string;
|
|
285
|
+
readonly matchDate?: string;
|
|
286
|
+
readonly matchSource?: string;
|
|
287
|
+
readonly matchType?: string;
|
|
288
|
+
readonly extras?: Readonly<Record<string, unknown>>;
|
|
289
|
+
readonly identifier?: string;
|
|
290
|
+
readonly originalId?: string;
|
|
291
|
+
readonly originalType?: string;
|
|
292
|
+
readonly clubId?: number;
|
|
293
|
+
readonly dryRun?: boolean;
|
|
294
|
+
}
|
|
233
295
|
/**
|
|
234
|
-
*
|
|
296
|
+
* Raw result from a batch submission.
|
|
235
297
|
*
|
|
236
|
-
* @category
|
|
298
|
+
* @category Matches
|
|
237
299
|
*/
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
readonly
|
|
241
|
-
|
|
242
|
-
readonly
|
|
243
|
-
|
|
244
|
-
readonly
|
|
245
|
-
constructor(data: RatingSplitData | number);
|
|
246
|
-
}
|
|
247
|
-
/**
|
|
248
|
-
* Rating breakdown by category.
|
|
249
|
-
*
|
|
250
|
-
* Access ratings by category name or use convenience properties.
|
|
251
|
-
*
|
|
252
|
-
* @category Models
|
|
253
|
-
*/
|
|
254
|
-
declare class RatingSplits {
|
|
255
|
-
/** Map of category names to rating splits */
|
|
256
|
-
readonly splits: Map<string, RatingSplit>;
|
|
257
|
-
constructor(data?: RatingSplitsData);
|
|
258
|
-
/** Get rating for a category */
|
|
259
|
-
get(category: string): number | undefined;
|
|
260
|
-
/** Open division rating */
|
|
261
|
-
get open(): number | undefined;
|
|
262
|
-
/** Gender-specific rating (same gender doubles) */
|
|
263
|
-
get gender(): number | undefined;
|
|
264
|
-
/** Mixed doubles rating */
|
|
265
|
-
get mixed(): number | undefined;
|
|
266
|
-
/** Recreational rating */
|
|
267
|
-
get recreational(): number | undefined;
|
|
268
|
-
/** Singles rating */
|
|
269
|
-
get singles(): number | undefined;
|
|
270
|
-
/** Best available verified rating */
|
|
271
|
-
get best(): number | undefined;
|
|
272
|
-
/** Convert to plain object */
|
|
273
|
-
toJSON(): Record<string, {
|
|
274
|
-
rating: number;
|
|
275
|
-
abbr: string;
|
|
276
|
-
}>;
|
|
277
|
-
}
|
|
278
|
-
/**
|
|
279
|
-
* A player in the Vairified system.
|
|
280
|
-
*
|
|
281
|
-
* From public search, only limited data is available (display name, location, rating).
|
|
282
|
-
* For full profile data, use getMember() with OAuth consent.
|
|
283
|
-
*
|
|
284
|
-
* @category Models
|
|
285
|
-
*/
|
|
286
|
-
declare class Player {
|
|
287
|
-
/** External player ID (vair_mem_xxx format) */
|
|
288
|
-
readonly id: string;
|
|
289
|
-
/** Display name (First Name + Last Initial from search) */
|
|
290
|
-
readonly displayName?: string;
|
|
291
|
-
/** First name (only from connected member) */
|
|
292
|
-
readonly firstName?: string;
|
|
293
|
-
/** Last name (only from connected member) */
|
|
294
|
-
readonly lastName?: string;
|
|
295
|
-
/** Primary/overall rating (2.0-8.0) */
|
|
296
|
-
readonly rating: number;
|
|
297
|
-
/** Whether player is verified */
|
|
298
|
-
readonly isVairified: boolean;
|
|
299
|
-
/** Whether player has connected to your app */
|
|
300
|
-
readonly isConnected: boolean;
|
|
301
|
-
/** Ratings by category (only from connected member) */
|
|
302
|
-
readonly ratingSplits: RatingSplits;
|
|
303
|
-
/** City */
|
|
304
|
-
readonly city?: string;
|
|
305
|
-
/** State code */
|
|
306
|
-
readonly state?: string;
|
|
307
|
-
/** Country code */
|
|
308
|
-
readonly country?: string;
|
|
309
|
-
protected _client?: Vairified;
|
|
310
|
-
constructor(data: PlayerData, client?: Vairified);
|
|
311
|
-
/** Full name (or display name if full name not available) */
|
|
312
|
-
get name(): string;
|
|
313
|
-
/** Best verified rating */
|
|
314
|
-
get verifiedRating(): number | undefined;
|
|
315
|
-
toString(): string;
|
|
300
|
+
interface MatchBatchResultWire {
|
|
301
|
+
readonly success: boolean;
|
|
302
|
+
readonly numMatches: number;
|
|
303
|
+
readonly numGames: number;
|
|
304
|
+
readonly dryRun?: boolean;
|
|
305
|
+
readonly message?: string;
|
|
306
|
+
readonly errors?: readonly string[];
|
|
316
307
|
}
|
|
317
308
|
/**
|
|
318
|
-
*
|
|
309
|
+
* Filters for {@link LeaderboardResource.list}.
|
|
319
310
|
*
|
|
320
|
-
*
|
|
321
|
-
*
|
|
322
|
-
* @category Models
|
|
311
|
+
* @category Leaderboards
|
|
323
312
|
*/
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
readonly
|
|
327
|
-
|
|
328
|
-
readonly
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
313
|
+
interface LeaderboardOptions {
|
|
314
|
+
readonly category?: string;
|
|
315
|
+
readonly ageBracket?: string;
|
|
316
|
+
readonly scope?: string;
|
|
317
|
+
readonly state?: string;
|
|
318
|
+
readonly city?: string;
|
|
319
|
+
readonly clubId?: string;
|
|
320
|
+
readonly gender?: Gender | Lowercase<Gender>;
|
|
321
|
+
readonly verifiedOnly?: boolean;
|
|
322
|
+
readonly minGames?: number;
|
|
323
|
+
readonly limit?: number;
|
|
324
|
+
readonly offset?: number;
|
|
325
|
+
readonly search?: string;
|
|
334
326
|
}
|
|
335
327
|
/**
|
|
336
|
-
*
|
|
328
|
+
* Options for {@link LeaderboardResource.rank}.
|
|
337
329
|
*
|
|
338
|
-
* @category
|
|
339
|
-
*
|
|
340
|
-
* @example
|
|
341
|
-
* ```ts
|
|
342
|
-
* // Doubles match: 11-9, 11-7
|
|
343
|
-
* const match = new Match({
|
|
344
|
-
* event: 'Weekly League',
|
|
345
|
-
* bracket: '4.0 Doubles',
|
|
346
|
-
* date: new Date(),
|
|
347
|
-
* team1: ['player1_id', 'player2_id'],
|
|
348
|
-
* team2: ['player3_id', 'player4_id'],
|
|
349
|
-
* scores: [[11, 9], [11, 7]],
|
|
350
|
-
* });
|
|
351
|
-
*
|
|
352
|
-
* // Singles match: 11-8, 9-11, 11-6
|
|
353
|
-
* const match = new Match({
|
|
354
|
-
* event: 'Club Singles',
|
|
355
|
-
* bracket: 'Open Singles',
|
|
356
|
-
* date: new Date(),
|
|
357
|
-
* team1: ['player1_id'],
|
|
358
|
-
* team2: ['player2_id'],
|
|
359
|
-
* scores: [[11, 8], [9, 11], [11, 6]],
|
|
360
|
-
* });
|
|
361
|
-
* ```
|
|
330
|
+
* @category Leaderboards
|
|
362
331
|
*/
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
readonly
|
|
366
|
-
|
|
367
|
-
readonly
|
|
368
|
-
|
|
369
|
-
readonly
|
|
370
|
-
/**
|
|
371
|
-
readonly
|
|
372
|
-
/** Team 2 player IDs */
|
|
373
|
-
readonly team2: readonly string[];
|
|
374
|
-
/** Game scores */
|
|
375
|
-
readonly scores: readonly [number, number][];
|
|
376
|
-
/** Match type */
|
|
377
|
-
readonly matchType: string;
|
|
378
|
-
/** Match source */
|
|
379
|
-
readonly source: string;
|
|
380
|
-
/** Location */
|
|
381
|
-
readonly location?: string;
|
|
382
|
-
/** Unique identifier */
|
|
383
|
-
readonly identifier: string;
|
|
384
|
-
/** Match ID (set after submission) */
|
|
385
|
-
id?: string;
|
|
386
|
-
constructor(data: MatchInput);
|
|
387
|
-
/** Match format: SINGLES or DOUBLES */
|
|
388
|
-
get format(): 'SINGLES' | 'DOUBLES';
|
|
389
|
-
/** Team that won (1 or 2). Returns 0 if tie. */
|
|
390
|
-
get winner(): 0 | 1 | 2;
|
|
391
|
-
/** Score summary like "11-9, 11-7" */
|
|
392
|
-
get scoreSummary(): string;
|
|
393
|
-
/** Convert to API request format */
|
|
394
|
-
toJSON(): MatchApiData;
|
|
332
|
+
interface PlayerRankOptions {
|
|
333
|
+
readonly category?: string;
|
|
334
|
+
readonly ageBracket?: string;
|
|
335
|
+
readonly scope?: string;
|
|
336
|
+
readonly state?: string;
|
|
337
|
+
readonly city?: string;
|
|
338
|
+
readonly clubId?: string;
|
|
339
|
+
/** Number of players on either side of the target. Default 5. */
|
|
340
|
+
readonly contextSize?: number;
|
|
395
341
|
}
|
|
396
342
|
/**
|
|
397
|
-
*
|
|
343
|
+
* Wire shape for tournament import response.
|
|
398
344
|
*
|
|
399
|
-
* @category
|
|
345
|
+
* @category Matches
|
|
400
346
|
*/
|
|
401
|
-
|
|
402
|
-
/** Whether submission succeeded */
|
|
347
|
+
interface TournamentImportResultWire {
|
|
403
348
|
readonly success: boolean;
|
|
404
|
-
|
|
405
|
-
readonly
|
|
406
|
-
|
|
407
|
-
readonly
|
|
408
|
-
|
|
409
|
-
readonly dryRun: boolean;
|
|
410
|
-
/** Human-readable result message */
|
|
349
|
+
readonly matchesImported: number;
|
|
350
|
+
readonly gamesRecorded: number;
|
|
351
|
+
readonly ghostPlayersCreated: number;
|
|
352
|
+
readonly existingPlayersMatched: number;
|
|
353
|
+
readonly dryRun?: boolean;
|
|
411
354
|
readonly message?: string;
|
|
412
|
-
|
|
413
|
-
readonly errors: string[];
|
|
414
|
-
constructor(data: MatchResultData);
|
|
415
|
-
/** Alias for dryRun */
|
|
416
|
-
get isDryRun(): boolean;
|
|
417
|
-
/** Returns true if submission succeeded without errors */
|
|
418
|
-
get ok(): boolean;
|
|
355
|
+
readonly errors?: readonly string[];
|
|
419
356
|
}
|
|
420
357
|
/**
|
|
421
|
-
*
|
|
358
|
+
* Wire shape for a single webhook delivery attempt.
|
|
422
359
|
*
|
|
423
|
-
* @category
|
|
360
|
+
* @category Webhooks
|
|
424
361
|
*/
|
|
425
|
-
|
|
426
|
-
/** External player ID (vair_mem_xxx format) */
|
|
362
|
+
interface WebhookDeliveryWire {
|
|
427
363
|
readonly id: string;
|
|
428
|
-
|
|
429
|
-
readonly
|
|
430
|
-
|
|
431
|
-
readonly
|
|
432
|
-
|
|
433
|
-
readonly
|
|
434
|
-
|
|
435
|
-
readonly
|
|
436
|
-
|
|
437
|
-
readonly
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
/** Amount of rating change */
|
|
441
|
-
get change(): number;
|
|
442
|
-
/** Whether rating improved */
|
|
443
|
-
get improved(): boolean;
|
|
444
|
-
/** Fetch the member associated with this update */
|
|
445
|
-
getMember(): Promise<Member>;
|
|
446
|
-
toString(): string;
|
|
364
|
+
readonly event: string;
|
|
365
|
+
readonly url: string;
|
|
366
|
+
readonly statusCode: number | null;
|
|
367
|
+
readonly responseBody: string | null;
|
|
368
|
+
readonly errorMessage: string | null;
|
|
369
|
+
readonly attempts: number;
|
|
370
|
+
readonly maxAttempts: number;
|
|
371
|
+
readonly lastAttemptAt: string;
|
|
372
|
+
readonly nextRetryAt: string | null;
|
|
373
|
+
readonly completedAt: string | null;
|
|
374
|
+
readonly createdAt: string;
|
|
375
|
+
readonly payload: Record<string, unknown>;
|
|
447
376
|
}
|
|
448
377
|
/**
|
|
449
|
-
*
|
|
378
|
+
* Wire shape for paginated webhook delivery results.
|
|
450
379
|
*
|
|
451
|
-
* @category
|
|
380
|
+
* @category Webhooks
|
|
452
381
|
*/
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
readonly players: Player[];
|
|
456
|
-
/** Total matching players */
|
|
382
|
+
interface WebhookDeliveriesResultWire {
|
|
383
|
+
readonly deliveries: readonly WebhookDeliveryWire[];
|
|
457
384
|
readonly total: number;
|
|
458
|
-
/** Current page */
|
|
459
|
-
readonly page: number;
|
|
460
|
-
/** Results per page */
|
|
461
|
-
readonly limit: number;
|
|
462
|
-
private _client?;
|
|
463
|
-
private _filters;
|
|
464
|
-
constructor(data: SearchResultsData, client?: Vairified, filters?: SearchFilters);
|
|
465
|
-
/** Whether more results are available */
|
|
466
|
-
get hasMore(): boolean;
|
|
467
|
-
/** Total number of pages */
|
|
468
|
-
get pages(): number;
|
|
469
|
-
/** Number of players in current page */
|
|
470
|
-
get length(): number;
|
|
471
|
-
/** Get player by index */
|
|
472
|
-
at(index: number): Player | undefined;
|
|
473
|
-
/** Iterate over players */
|
|
474
|
-
[Symbol.iterator](): Iterator<Player>;
|
|
475
|
-
/** Fetch next page of results */
|
|
476
|
-
nextPage(): Promise<SearchResults>;
|
|
477
385
|
}
|
|
478
|
-
|
|
479
386
|
/**
|
|
480
|
-
*
|
|
387
|
+
* Error envelope commonly returned by the Partner API on non-2xx status.
|
|
481
388
|
*
|
|
482
|
-
*
|
|
389
|
+
* @category Errors
|
|
390
|
+
*/
|
|
391
|
+
interface ApiErrorResponse {
|
|
392
|
+
readonly message?: string;
|
|
393
|
+
readonly error?: string;
|
|
394
|
+
readonly statusCode?: number;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* {@link LeaderboardResource} — read-only leaderboard queries.
|
|
483
399
|
*
|
|
484
400
|
* @module
|
|
485
401
|
*/
|
|
402
|
+
|
|
486
403
|
/**
|
|
487
|
-
*
|
|
404
|
+
* Read-only leaderboard queries.
|
|
488
405
|
*
|
|
489
|
-
* @category
|
|
406
|
+
* @category Resources
|
|
490
407
|
*/
|
|
491
|
-
declare
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
408
|
+
declare class LeaderboardResource {
|
|
409
|
+
#private;
|
|
410
|
+
/** @internal */
|
|
411
|
+
constructor(http: HttpTransport);
|
|
412
|
+
/** Fetch a leaderboard page with optional filters. */
|
|
413
|
+
list(options?: LeaderboardOptions): Promise<Record<string, unknown>>;
|
|
414
|
+
/** Fetch a specific player's rank plus nearby players. */
|
|
415
|
+
rank(playerId: string, options?: PlayerRankOptions): Promise<Record<string, unknown>>;
|
|
416
|
+
/** List available leaderboard categories, brackets, and scopes. */
|
|
417
|
+
categories(): Promise<Record<string, unknown>>;
|
|
418
|
+
}
|
|
419
|
+
|
|
499
420
|
/**
|
|
500
|
-
*
|
|
421
|
+
* {@link MatchBatchResult} — result of a batch match submission.
|
|
501
422
|
*
|
|
502
|
-
* @
|
|
423
|
+
* @module
|
|
503
424
|
*/
|
|
504
|
-
|
|
425
|
+
|
|
505
426
|
/**
|
|
506
|
-
*
|
|
427
|
+
* Result of a {@link MatchesResource.submit} call.
|
|
507
428
|
*
|
|
508
|
-
* @
|
|
429
|
+
* {@link success} is `true` only when every match in the batch was
|
|
430
|
+
* accepted. Check {@link errors} for per-match validation failures.
|
|
431
|
+
*
|
|
432
|
+
* @category Matches
|
|
509
433
|
*/
|
|
510
|
-
declare
|
|
434
|
+
declare class MatchBatchResult {
|
|
435
|
+
readonly success: boolean;
|
|
436
|
+
readonly numMatches: number;
|
|
437
|
+
readonly numGames: number;
|
|
438
|
+
readonly dryRun: boolean | null;
|
|
439
|
+
readonly message: string | null;
|
|
440
|
+
readonly errors: readonly string[] | null;
|
|
441
|
+
constructor(wire: MatchBatchResultWire);
|
|
442
|
+
/** Shorthand: successful submission with zero errors. */
|
|
443
|
+
get ok(): boolean;
|
|
444
|
+
/** Whether this was a dry-run (validation only, nothing persisted). */
|
|
445
|
+
get isDryRun(): boolean;
|
|
446
|
+
toString(): string;
|
|
447
|
+
}
|
|
448
|
+
|
|
511
449
|
/**
|
|
512
|
-
*
|
|
450
|
+
* {@link TournamentImportResult} — result of a tournament import submission.
|
|
513
451
|
*
|
|
514
|
-
* @
|
|
452
|
+
* @module
|
|
515
453
|
*/
|
|
516
|
-
|
|
517
|
-
/** Partner API key */
|
|
518
|
-
apiKey: string;
|
|
519
|
-
/** Your application's callback URL */
|
|
520
|
-
redirectUri: string;
|
|
521
|
-
/** Vairified API base URL */
|
|
522
|
-
baseUrl?: string;
|
|
523
|
-
}
|
|
454
|
+
|
|
524
455
|
/**
|
|
525
|
-
*
|
|
456
|
+
* Result of a tournament import submission.
|
|
526
457
|
*
|
|
527
|
-
* @category
|
|
458
|
+
* @category Matches
|
|
528
459
|
*/
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
460
|
+
declare class TournamentImportResult {
|
|
461
|
+
readonly success: boolean;
|
|
462
|
+
readonly matchesImported: number;
|
|
463
|
+
readonly gamesRecorded: number;
|
|
464
|
+
readonly ghostPlayersCreated: number;
|
|
465
|
+
readonly existingPlayersMatched: number;
|
|
466
|
+
readonly dryRun: boolean;
|
|
467
|
+
readonly message: string | undefined;
|
|
468
|
+
readonly errors: readonly string[];
|
|
469
|
+
/** @internal */
|
|
470
|
+
constructor(wire: TournamentImportResultWire);
|
|
471
|
+
/** True when the import succeeded without errors. */
|
|
472
|
+
get ok(): boolean;
|
|
536
473
|
}
|
|
474
|
+
|
|
537
475
|
/**
|
|
538
|
-
*
|
|
476
|
+
* {@link MatchesResource} — bulk match submission.
|
|
539
477
|
*
|
|
540
|
-
* @
|
|
478
|
+
* @module
|
|
541
479
|
*/
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
480
|
+
|
|
481
|
+
/**
|
|
482
|
+
* Match submission — one call submits a full batch.
|
|
483
|
+
*
|
|
484
|
+
* @category Resources
|
|
485
|
+
*/
|
|
486
|
+
declare class MatchesResource {
|
|
487
|
+
#private;
|
|
488
|
+
/** @internal */
|
|
489
|
+
constructor(http: HttpTransport);
|
|
490
|
+
/**
|
|
491
|
+
* Submit a {@link MatchBatch} for rating calculation.
|
|
492
|
+
*
|
|
493
|
+
* All players in every match must have granted the `user:match:submit`
|
|
494
|
+
* scope via OAuth (unless your API key has the
|
|
495
|
+
* `user:match:submit:trusted` scope, which skips per-player consent).
|
|
496
|
+
*
|
|
497
|
+
* Set `batch.dryRun = true` to validate without persisting.
|
|
498
|
+
*
|
|
499
|
+
* ```ts
|
|
500
|
+
* const result = await client.matches.submit({
|
|
501
|
+
* sport: 'pickleball',
|
|
502
|
+
* winScore: 11,
|
|
503
|
+
* winBy: 2,
|
|
504
|
+
* bracket: '4.0 Doubles',
|
|
505
|
+
* event: 'Weekly League',
|
|
506
|
+
* matchDate: '2026-04-11T14:00:00Z',
|
|
507
|
+
* matches: [
|
|
508
|
+
* {
|
|
509
|
+
* identifier: 'm1',
|
|
510
|
+
* teams: [['vair_mem_aaa', 'vair_mem_bbb'],
|
|
511
|
+
* ['vair_mem_ccc', 'vair_mem_ddd']],
|
|
512
|
+
* games: [{ scores: [11, 8] }, { scores: [11, 5] }],
|
|
513
|
+
* },
|
|
514
|
+
* ],
|
|
515
|
+
* });
|
|
516
|
+
* if (result.ok) {
|
|
517
|
+
* console.log(`Submitted ${result.numGames} games`);
|
|
518
|
+
* }
|
|
519
|
+
* ```
|
|
520
|
+
*/
|
|
521
|
+
submit(batch: MatchBatch): Promise<MatchBatchResult>;
|
|
522
|
+
/**
|
|
523
|
+
* Import tournament results.
|
|
524
|
+
*
|
|
525
|
+
* The request body is a free-form JSON object whose structure is
|
|
526
|
+
* defined by the Vairified tournament import schema. Set
|
|
527
|
+
* `body.dryRun = true` to validate without persisting.
|
|
528
|
+
*
|
|
529
|
+
* @param body - Tournament import payload.
|
|
530
|
+
* @returns {@link TournamentImportResult} with match/game counts.
|
|
531
|
+
* @category Matches
|
|
532
|
+
*
|
|
533
|
+
* @example
|
|
534
|
+
* ```ts
|
|
535
|
+
* const result = await client.matches.tournamentImport({
|
|
536
|
+
* sport: 'pickleball',
|
|
537
|
+
* tournamentName: 'Spring Classic',
|
|
538
|
+
* matches: [...],
|
|
539
|
+
* });
|
|
540
|
+
* if (result.ok) {
|
|
541
|
+
* console.log(`Imported ${result.matchesImported} matches`);
|
|
542
|
+
* }
|
|
543
|
+
* ```
|
|
544
|
+
*/
|
|
545
|
+
tournamentImport(body: Record<string, unknown>): Promise<TournamentImportResult>;
|
|
546
|
+
/** Send a test payload to a webhook URL. */
|
|
547
|
+
testWebhook(webhookUrl: string): Promise<Record<string, unknown>>;
|
|
553
548
|
}
|
|
549
|
+
|
|
554
550
|
/**
|
|
555
|
-
*
|
|
551
|
+
* {@link SportRating} — a player's ratings for one sport.
|
|
556
552
|
*
|
|
557
|
-
*
|
|
558
|
-
|
|
553
|
+
* @module
|
|
554
|
+
*/
|
|
555
|
+
|
|
556
|
+
/**
|
|
557
|
+
* A player's ratings for a single sport.
|
|
559
558
|
*
|
|
560
|
-
*
|
|
561
|
-
*
|
|
562
|
-
*
|
|
563
|
-
* @
|
|
559
|
+
* The top-level `rating` / `abbr` is the primary rating for that sport
|
|
560
|
+
* (conventionally the overall-open bracket). Every category × age
|
|
561
|
+
* bracket the player has played is also available via {@link get},
|
|
562
|
+
* {@link has}, subscript-style access, and iteration.
|
|
564
563
|
*
|
|
565
|
-
* @example
|
|
566
564
|
* ```ts
|
|
567
|
-
* const
|
|
568
|
-
*
|
|
569
|
-
*
|
|
570
|
-
*
|
|
571
|
-
*
|
|
572
|
-
*
|
|
573
|
-
* )
|
|
574
|
-
*
|
|
575
|
-
*
|
|
565
|
+
* const pb = member.sport.get('pickleball');
|
|
566
|
+
* if (pb) {
|
|
567
|
+
* console.log(pb.rating, pb.abbr); // 3.915 VO
|
|
568
|
+
* console.log(pb.get('overall-open')?.rating); // 3.915
|
|
569
|
+
* console.log(pb.has('singles-40+')); // false
|
|
570
|
+
* console.log(pb.size); // 3
|
|
571
|
+
* for (const [key, split] of pb) {
|
|
572
|
+
* console.log(key, split.rating);
|
|
573
|
+
* }
|
|
574
|
+
* }
|
|
576
575
|
* ```
|
|
577
576
|
*
|
|
578
|
-
* @category
|
|
577
|
+
* @category Members
|
|
579
578
|
*/
|
|
580
|
-
declare
|
|
579
|
+
declare class SportRating {
|
|
580
|
+
#private;
|
|
581
|
+
/** Primary rating for this sport. */
|
|
582
|
+
readonly rating: number;
|
|
583
|
+
/** Category abbreviation for the primary rating (e.g. `'VO'`). */
|
|
584
|
+
readonly abbr: string;
|
|
585
|
+
constructor(wire: SportRatingWire);
|
|
586
|
+
/**
|
|
587
|
+
* Look up a rating split by key (e.g. `'overall-open'`,
|
|
588
|
+
* `'singles-12-13'`, `'gender-40+'`). Returns `undefined` if the
|
|
589
|
+
* player has no rating for that bracket.
|
|
590
|
+
*/
|
|
591
|
+
get(key: string): RatingSplitWire | undefined;
|
|
592
|
+
/** Whether the player has a rating for the given split key. */
|
|
593
|
+
has(key: string): boolean;
|
|
594
|
+
/** Number of rating splits. */
|
|
595
|
+
get size(): number;
|
|
596
|
+
/** All split keys the player has ratings for. */
|
|
597
|
+
keys(): IterableIterator<string>;
|
|
598
|
+
/** All rating splits the player has. */
|
|
599
|
+
values(): IterableIterator<RatingSplitWire>;
|
|
600
|
+
/** `[key, split]` pairs for every rating split. */
|
|
601
|
+
entries(): IterableIterator<[string, RatingSplitWire]>;
|
|
602
|
+
/**
|
|
603
|
+
* `for (const [key, split] of sportRating) { ... }` — iterate every
|
|
604
|
+
* rating split the player has in this sport.
|
|
605
|
+
*/
|
|
606
|
+
[Symbol.iterator](): IterableIterator<[string, RatingSplitWire]>;
|
|
607
|
+
}
|
|
608
|
+
|
|
581
609
|
/**
|
|
582
|
-
*
|
|
583
|
-
*
|
|
584
|
-
* @param scope - Scope string to validate
|
|
585
|
-
* @returns True if scope is valid
|
|
610
|
+
* {@link Member} — partner-facing player record.
|
|
586
611
|
*
|
|
587
|
-
* @
|
|
612
|
+
* @module
|
|
588
613
|
*/
|
|
589
|
-
|
|
614
|
+
|
|
590
615
|
/**
|
|
591
|
-
*
|
|
616
|
+
* Map-like wrapper around a player's sport → {@link SportRating}.
|
|
592
617
|
*
|
|
593
|
-
*
|
|
594
|
-
*
|
|
618
|
+
* Supports `.get(code)`, `.has(code)`, `.size`, and iteration so the
|
|
619
|
+
* shape feels native:
|
|
595
620
|
*
|
|
596
|
-
*
|
|
621
|
+
* ```ts
|
|
622
|
+
* member.sport.get('pickleball')?.rating
|
|
623
|
+
* for (const [code, rating] of member.sport) { ... }
|
|
624
|
+
* ```
|
|
625
|
+
*
|
|
626
|
+
* @category Members
|
|
597
627
|
*/
|
|
598
|
-
declare
|
|
628
|
+
declare class MemberSportMap {
|
|
629
|
+
#private;
|
|
630
|
+
constructor(wire: Readonly<Record<string, SportRatingWire>> | undefined);
|
|
631
|
+
get(sport: string): SportRating | undefined;
|
|
632
|
+
has(sport: string): boolean;
|
|
633
|
+
get size(): number;
|
|
634
|
+
keys(): IterableIterator<string>;
|
|
635
|
+
values(): IterableIterator<SportRating>;
|
|
636
|
+
entries(): IterableIterator<[string, SportRating]>;
|
|
637
|
+
[Symbol.iterator](): IterableIterator<[string, SportRating]>;
|
|
638
|
+
}
|
|
599
639
|
/**
|
|
600
|
-
*
|
|
640
|
+
* A partner-facing player record.
|
|
601
641
|
*
|
|
602
|
-
* @
|
|
603
|
-
*
|
|
642
|
+
* Returned by {@link MembersResource.get} (full detail, requires an
|
|
643
|
+
* active OAuth connection) and {@link MembersResource.search} (limited
|
|
644
|
+
* detail for public search).
|
|
604
645
|
*
|
|
605
|
-
* @
|
|
646
|
+
* Rating data lives under {@link sport} — keyed by sport code. The
|
|
647
|
+
* backend returns only the sports the player has ratings in, or only
|
|
648
|
+
* the sports requested via the `sport=` query filter. Use
|
|
649
|
+
* {@link ratingFor} to fetch the primary rating for a specific sport
|
|
650
|
+
* with a sensible default.
|
|
651
|
+
*
|
|
652
|
+
* @category Members
|
|
606
653
|
*/
|
|
607
|
-
declare
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
654
|
+
declare class Member {
|
|
655
|
+
readonly memberId: number;
|
|
656
|
+
readonly id: string | null;
|
|
657
|
+
readonly firstName: string;
|
|
658
|
+
readonly lastName: string;
|
|
659
|
+
readonly fullName: string;
|
|
660
|
+
readonly displayName: string;
|
|
661
|
+
readonly age: number | null;
|
|
662
|
+
readonly city: string | null;
|
|
663
|
+
readonly state: string | null;
|
|
664
|
+
readonly zip: string | null;
|
|
665
|
+
readonly country: string | null;
|
|
666
|
+
readonly gender: Gender | null;
|
|
667
|
+
readonly status: MemberStatusWire;
|
|
668
|
+
readonly sport: MemberSportMap;
|
|
669
|
+
readonly activeLeagues: readonly string[] | null;
|
|
670
|
+
readonly email: string | null;
|
|
671
|
+
readonly grantedScopes: readonly string[] | null;
|
|
672
|
+
constructor(wire: PartnerMemberWire);
|
|
673
|
+
/** Full name — alias for {@link fullName}, matching common usage. */
|
|
674
|
+
get name(): string;
|
|
675
|
+
/** The list of sport codes this player has ratings in. */
|
|
676
|
+
get sports(): readonly string[];
|
|
677
|
+
/**
|
|
678
|
+
* Primary rating for a given sport.
|
|
679
|
+
*
|
|
680
|
+
* @param sport Sport code — defaults to `'pickleball'`.
|
|
681
|
+
* @returns The primary rating value, or `null` if the player has no
|
|
682
|
+
* ratings for that sport.
|
|
683
|
+
*/
|
|
684
|
+
ratingFor(sport?: string): number | null;
|
|
685
|
+
/**
|
|
686
|
+
* Get a specific rating split for a sport.
|
|
687
|
+
*
|
|
688
|
+
* @param key Split key (e.g. `'overall-open'`).
|
|
689
|
+
* @param sport Sport code — defaults to `'pickleball'`.
|
|
690
|
+
*/
|
|
691
|
+
split(key: string, sport?: string): RatingSplitWire | null;
|
|
692
|
+
/** Compact summary for console output. */
|
|
693
|
+
toString(): string;
|
|
694
|
+
}
|
|
695
|
+
|
|
611
696
|
/**
|
|
612
|
-
*
|
|
613
|
-
*
|
|
614
|
-
* @returns Random 32-character hexadecimal string
|
|
697
|
+
* {@link RatingUpdate} — a single rating change notification.
|
|
615
698
|
*
|
|
616
|
-
* @
|
|
699
|
+
* @module
|
|
617
700
|
*/
|
|
618
|
-
declare function generateState(): string;
|
|
619
701
|
|
|
620
702
|
/**
|
|
621
|
-
*
|
|
703
|
+
* A single rating change notification.
|
|
622
704
|
*
|
|
623
|
-
*
|
|
705
|
+
* Returned by {@link MembersResource.ratingUpdates} (polling) and
|
|
706
|
+
* delivered via webhook callbacks to partners that have registered a
|
|
707
|
+
* webhook URL and have subscribers.
|
|
624
708
|
*
|
|
625
|
-
* @
|
|
709
|
+
* @category Members
|
|
626
710
|
*/
|
|
711
|
+
declare class RatingUpdate {
|
|
712
|
+
readonly memberId: number;
|
|
713
|
+
readonly id: string | null;
|
|
714
|
+
readonly displayName: string | null;
|
|
715
|
+
readonly sport: string | null;
|
|
716
|
+
readonly previousRating: number | null;
|
|
717
|
+
readonly newRating: number | null;
|
|
718
|
+
readonly changedAt: string | null;
|
|
719
|
+
readonly ratingSplits: Readonly<Record<string, RatingSplitWire>> | null;
|
|
720
|
+
constructor(wire: PartnerRatingUpdateWire);
|
|
721
|
+
/**
|
|
722
|
+
* Rating change amount — `newRating - previousRating`. Returns `null`
|
|
723
|
+
* if either rating is missing from the update payload.
|
|
724
|
+
*/
|
|
725
|
+
get delta(): number | null;
|
|
726
|
+
/** `true` when the new rating is strictly higher than the previous. */
|
|
727
|
+
get improved(): boolean;
|
|
728
|
+
toString(): string;
|
|
729
|
+
}
|
|
627
730
|
|
|
628
|
-
declare const ENVIRONMENTS: {
|
|
629
|
-
readonly production: "https://api-next.vairified.com/api/v1";
|
|
630
|
-
readonly staging: "https://api-staging.vairified.com/api/v1";
|
|
631
|
-
readonly local: "http://localhost:3001/api/v1";
|
|
632
|
-
};
|
|
633
731
|
/**
|
|
634
|
-
*
|
|
732
|
+
* {@link MembersResource} — member lookups, search, and rating updates.
|
|
635
733
|
*
|
|
636
|
-
* @
|
|
734
|
+
* @module
|
|
637
735
|
*/
|
|
638
|
-
|
|
736
|
+
|
|
639
737
|
/**
|
|
640
|
-
*
|
|
641
|
-
*
|
|
642
|
-
* @category Client
|
|
643
|
-
*
|
|
644
|
-
* @example
|
|
645
|
-
* ```ts
|
|
646
|
-
* const client = new Vairified({ apiKey: 'vair_pk_xxx' });
|
|
647
|
-
*
|
|
648
|
-
* // Get a member
|
|
649
|
-
* const member = await client.getMember('user_123');
|
|
650
|
-
* console.log(member.name, member.rating);
|
|
651
|
-
*
|
|
652
|
-
* // Search for players
|
|
653
|
-
* const results = await client.search({ city: 'Austin', ratingMin: 4.0 });
|
|
654
|
-
* for (const player of results) {
|
|
655
|
-
* console.log(player.name, player.rating);
|
|
656
|
-
* }
|
|
657
|
-
*
|
|
658
|
-
* // Submit a match (doubles: 11-9, 11-7)
|
|
659
|
-
* const match = new Match({
|
|
660
|
-
* event: 'Weekly League',
|
|
661
|
-
* bracket: '4.0 Doubles',
|
|
662
|
-
* date: new Date(),
|
|
663
|
-
* team1: ['p1', 'p2'],
|
|
664
|
-
* team2: ['p3', 'p4'],
|
|
665
|
-
* scores: [[11, 9], [11, 7]],
|
|
666
|
-
* });
|
|
667
|
-
* const result = await client.submitMatch(match);
|
|
668
|
-
* if (result.ok) {
|
|
669
|
-
* console.log(`Submitted ${result.numGames} games`);
|
|
670
|
-
* }
|
|
671
|
-
* ```
|
|
738
|
+
* Member operations — get a single member, auto-paginating search,
|
|
739
|
+
* find by name, and polling for rating change notifications.
|
|
672
740
|
*
|
|
673
|
-
* @
|
|
674
|
-
* If your API key has the "dry-run" scope, match submissions will be
|
|
675
|
-
* validated but not persisted. This is useful for testing integrations.
|
|
741
|
+
* @category Resources
|
|
676
742
|
*/
|
|
677
|
-
declare class
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
readonly baseUrl: string;
|
|
682
|
-
/** Environment name */
|
|
683
|
-
readonly env: VairifiedEnvironment;
|
|
684
|
-
/** Request timeout in ms */
|
|
685
|
-
readonly timeout: number;
|
|
686
|
-
constructor(options?: VairifiedOptions);
|
|
687
|
-
private getEnvVar;
|
|
688
|
-
private getEnvApiKey;
|
|
689
|
-
private getHeaders;
|
|
690
|
-
private handleError;
|
|
691
|
-
private request;
|
|
743
|
+
declare class MembersResource {
|
|
744
|
+
#private;
|
|
745
|
+
/** @internal */
|
|
746
|
+
constructor(http: HttpTransport);
|
|
692
747
|
/**
|
|
693
|
-
* Get a connected member by
|
|
748
|
+
* Get a connected member by external ID.
|
|
694
749
|
*
|
|
695
|
-
* **Requires
|
|
696
|
-
*
|
|
750
|
+
* **Requires an active OAuth connection** between your partner app
|
|
751
|
+
* and the player. Use the OAuth flow on `client.oauth` first.
|
|
697
752
|
*
|
|
698
|
-
* @param playerId
|
|
699
|
-
* @
|
|
700
|
-
*
|
|
701
|
-
*
|
|
753
|
+
* @param playerId External player ID in `vair_mem_xxx` format.
|
|
754
|
+
* @param options.sport Optional sport filter — single code or list.
|
|
755
|
+
* When omitted, the response contains every sport the player has
|
|
756
|
+
* ratings in.
|
|
757
|
+
* @throws {@link NotFoundError} if the external ID is unknown.
|
|
758
|
+
* @throws {@link VairifiedError} if the player has not connected to
|
|
759
|
+
* your app (403) or the request otherwise fails.
|
|
702
760
|
*
|
|
703
761
|
* @example
|
|
704
762
|
* ```ts
|
|
705
|
-
* const member = await client.
|
|
706
|
-
* console.log(member.name, member.
|
|
707
|
-
* console.log(member.ratingSplits.open); // Open division rating
|
|
708
|
-
* console.log(member.grantedScopes); // ['profile:read', 'rating:read']
|
|
709
|
-
* ```
|
|
710
|
-
*/
|
|
711
|
-
getMember(playerId: string): Promise<Member>;
|
|
712
|
-
/**
|
|
713
|
-
* Search for players.
|
|
763
|
+
* const member = await client.members.get('vair_mem_xxx');
|
|
764
|
+
* console.log(member.name, member.ratingFor('pickleball'));
|
|
714
765
|
*
|
|
715
|
-
*
|
|
716
|
-
*
|
|
766
|
+
* // Just pickleball
|
|
767
|
+
* const member2 = await client.members.get('vair_mem_xxx', { sport: 'pickleball' });
|
|
717
768
|
*
|
|
718
|
-
*
|
|
719
|
-
*
|
|
720
|
-
*
|
|
721
|
-
* city: 'Austin',
|
|
722
|
-
* ratingMin: 4.0,
|
|
723
|
-
* vairifiedOnly: true,
|
|
769
|
+
* // Multiple sports
|
|
770
|
+
* const member3 = await client.members.get('vair_mem_xxx', {
|
|
771
|
+
* sport: ['pickleball', 'padel'],
|
|
724
772
|
* });
|
|
725
|
-
*
|
|
726
|
-
* for (const player of results) {
|
|
727
|
-
* console.log(player.name, player.rating);
|
|
728
|
-
* }
|
|
729
|
-
*
|
|
730
|
-
* // Pagination
|
|
731
|
-
* if (results.hasMore) {
|
|
732
|
-
* const nextPage = await results.nextPage();
|
|
733
|
-
* }
|
|
734
773
|
* ```
|
|
735
774
|
*/
|
|
736
|
-
|
|
775
|
+
get(playerId: string, options?: {
|
|
776
|
+
sport?: string | readonly string[];
|
|
777
|
+
}): Promise<Member>;
|
|
737
778
|
/**
|
|
738
|
-
*
|
|
779
|
+
* Search for members, yielding each match as a {@link Member}.
|
|
739
780
|
*
|
|
740
|
-
*
|
|
741
|
-
*
|
|
781
|
+
* This is an **auto-paginating async iterator** — it fetches pages
|
|
782
|
+
* from the server lazily as you iterate, so you can stream through
|
|
783
|
+
* thousands of results without holding them all in memory:
|
|
742
784
|
*
|
|
743
|
-
* @example
|
|
744
785
|
* ```ts
|
|
745
|
-
* const
|
|
746
|
-
*
|
|
747
|
-
* console.log(player.rating);
|
|
786
|
+
* for await (const m of client.members.search({ city: 'Austin' })) {
|
|
787
|
+
* console.log(m.name, m.ratingFor('pickleball'));
|
|
748
788
|
* }
|
|
749
789
|
* ```
|
|
750
|
-
*/
|
|
751
|
-
findPlayer(name: string): Promise<Player | undefined>;
|
|
752
|
-
/**
|
|
753
|
-
* Submit a single match.
|
|
754
|
-
*
|
|
755
|
-
* @param match - Match object with teams and scores
|
|
756
|
-
* @returns MatchResult with submission status
|
|
757
790
|
*
|
|
758
|
-
*
|
|
759
|
-
*
|
|
760
|
-
* const match = new Match({
|
|
761
|
-
* event: 'Weekly League',
|
|
762
|
-
* bracket: '4.0 Doubles',
|
|
763
|
-
* date: new Date(),
|
|
764
|
-
* team1: ['p1', 'p2'],
|
|
765
|
-
* team2: ['p3', 'p4'],
|
|
766
|
-
* scores: [[11, 9], [11, 7]],
|
|
767
|
-
* });
|
|
768
|
-
*
|
|
769
|
-
* const result = await client.submitMatch(match);
|
|
770
|
-
* if (result.ok) {
|
|
771
|
-
* console.log(`Submitted ${result.numGames} games`);
|
|
772
|
-
* }
|
|
773
|
-
* ```
|
|
791
|
+
* Stop early by `break`-ing out of the loop, or cap the total with
|
|
792
|
+
* `maxResults`.
|
|
774
793
|
*/
|
|
775
|
-
|
|
794
|
+
search(filters?: SearchFilters): AsyncGenerator<Member, void, void>;
|
|
776
795
|
/**
|
|
777
|
-
*
|
|
796
|
+
* Return the first search hit for a name, or `null`.
|
|
778
797
|
*
|
|
779
|
-
*
|
|
780
|
-
* @returns MatchResult with submission status
|
|
798
|
+
* Convenience for the common "look up by name" case:
|
|
781
799
|
*
|
|
782
|
-
* @example
|
|
783
800
|
* ```ts
|
|
784
|
-
* const
|
|
785
|
-
*
|
|
786
|
-
*
|
|
787
|
-
* if (result.dryRun) {
|
|
788
|
-
* console.log('This was a dry run - no data persisted');
|
|
801
|
+
* const mike = await client.members.find('Mike Barker');
|
|
802
|
+
* if (mike) {
|
|
803
|
+
* console.log(mike.ratingFor('pickleball'));
|
|
789
804
|
* }
|
|
790
805
|
* ```
|
|
791
806
|
*/
|
|
792
|
-
|
|
807
|
+
find(name: string): Promise<Member | null>;
|
|
793
808
|
/**
|
|
794
|
-
*
|
|
809
|
+
* Fetch up to 100 members by their member IDs in one call.
|
|
795
810
|
*
|
|
796
|
-
*
|
|
811
|
+
* Unknown IDs are silently omitted — the returned array may be
|
|
812
|
+
* shorter than the input. Results are returned in the same order
|
|
813
|
+
* as the input IDs.
|
|
797
814
|
*
|
|
798
|
-
* @
|
|
815
|
+
* @param ids - Array of integer member IDs (max 100).
|
|
816
|
+
* @param options - Optional filters.
|
|
817
|
+
* @param options.sport - Sport code to scope ratings (e.g. `'pickleball'`).
|
|
818
|
+
* @returns Array of {@link Member} instances.
|
|
819
|
+
* @throws {@link ValidationError} If more than 100 IDs are provided.
|
|
820
|
+
* @category Members
|
|
799
821
|
*
|
|
800
822
|
* @example
|
|
801
823
|
* ```ts
|
|
802
|
-
* const
|
|
803
|
-
* for (const
|
|
804
|
-
* console.log(
|
|
805
|
-
* if (update.improved) {
|
|
806
|
-
* const member = await update.getMember();
|
|
807
|
-
* console.log(`${member.name} improved!`);
|
|
808
|
-
* }
|
|
824
|
+
* const members = await client.members.getBulk([4873327, 4873328]);
|
|
825
|
+
* for (const m of members) {
|
|
826
|
+
* console.log(m.name, m.ratingFor('pickleball'));
|
|
809
827
|
* }
|
|
810
828
|
* ```
|
|
811
829
|
*/
|
|
812
|
-
|
|
830
|
+
getBulk(ids: number[], options?: {
|
|
831
|
+
sport?: string;
|
|
832
|
+
}): Promise<Member[]>;
|
|
813
833
|
/**
|
|
814
|
-
*
|
|
834
|
+
* Poll for rating change notifications.
|
|
815
835
|
*
|
|
816
|
-
*
|
|
817
|
-
*
|
|
836
|
+
* Returns a list of {@link RatingUpdate} objects for every player
|
|
837
|
+
* whose rating has changed since the last poll. Members are
|
|
838
|
+
* considered subscribed when they have an active OAuth connection
|
|
839
|
+
* with the `user:webhook:subscribe` scope.
|
|
818
840
|
*/
|
|
819
|
-
|
|
841
|
+
ratingUpdates(): Promise<readonly RatingUpdate[]>;
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
/**
|
|
845
|
+
* Vairified OAuth helpers and type definitions.
|
|
846
|
+
*
|
|
847
|
+
* Use the {@link OAuthResource} on `client.oauth` for the full flow —
|
|
848
|
+
* these helpers exist for partners who need to build authorization URLs
|
|
849
|
+
* or validate scopes outside the client (e.g. in a frontend that only
|
|
850
|
+
* handles the redirect step).
|
|
851
|
+
*
|
|
852
|
+
* @module
|
|
853
|
+
*/
|
|
854
|
+
/**
|
|
855
|
+
* Every OAuth scope the Vairified authorization server accepts.
|
|
856
|
+
*
|
|
857
|
+
* Declaring this as a string union (rather than a free-form `string`)
|
|
858
|
+
* lets TypeScript catch typos at authoring time:
|
|
859
|
+
*
|
|
860
|
+
* ```ts
|
|
861
|
+
* const scopes: OAuthScope[] = ['user:profile:read', 'user:rating:read']; // ok
|
|
862
|
+
* const bad: OAuthScope[] = ['user:profile:read', 'rating']; // type error
|
|
863
|
+
* ```
|
|
864
|
+
*
|
|
865
|
+
* @category OAuth
|
|
866
|
+
*/
|
|
867
|
+
type OAuthScope = 'user:profile:read' | 'user:profile:email' | 'user:rating:read' | 'user:rating:history' | 'user:match:submit' | 'user:webhook:subscribe';
|
|
868
|
+
/**
|
|
869
|
+
* Human-readable description for every OAuth scope.
|
|
870
|
+
*
|
|
871
|
+
* @category OAuth
|
|
872
|
+
*/
|
|
873
|
+
declare const SCOPES: Readonly<Record<OAuthScope, string>>;
|
|
874
|
+
/**
|
|
875
|
+
* The scopes automatically requested when none are specified.
|
|
876
|
+
*
|
|
877
|
+
* @category OAuth
|
|
878
|
+
*/
|
|
879
|
+
declare const DEFAULT_SCOPES: readonly OAuthScope[];
|
|
880
|
+
/**
|
|
881
|
+
* Configuration for building an authorization URL manually.
|
|
882
|
+
*
|
|
883
|
+
* @category OAuth
|
|
884
|
+
*/
|
|
885
|
+
interface OAuthConfig {
|
|
886
|
+
readonly apiKey: string;
|
|
887
|
+
readonly redirectUri: string;
|
|
888
|
+
readonly baseUrl?: string;
|
|
889
|
+
}
|
|
890
|
+
/**
|
|
891
|
+
* Response from starting an OAuth authorization flow.
|
|
892
|
+
*
|
|
893
|
+
* @category OAuth
|
|
894
|
+
*/
|
|
895
|
+
interface AuthorizationResponse {
|
|
896
|
+
readonly authorizationUrl: string;
|
|
897
|
+
readonly code: string;
|
|
898
|
+
readonly state?: string;
|
|
899
|
+
}
|
|
900
|
+
/**
|
|
901
|
+
* Response from exchanging an authorization code for tokens.
|
|
902
|
+
*
|
|
903
|
+
* @category OAuth
|
|
904
|
+
*/
|
|
905
|
+
interface TokenResponse {
|
|
906
|
+
readonly accessToken: string;
|
|
907
|
+
readonly refreshToken: string | null;
|
|
908
|
+
readonly expiresIn: number;
|
|
909
|
+
readonly scope: readonly string[];
|
|
910
|
+
readonly playerId: string;
|
|
911
|
+
}
|
|
912
|
+
/**
|
|
913
|
+
* Build the URL to redirect users to for OAuth authorization.
|
|
914
|
+
*
|
|
915
|
+
* Prefer {@link OAuthResource.authorize} on a Vairified client — this
|
|
916
|
+
* helper is only useful when you need to construct the URL without
|
|
917
|
+
* making an HTTP call first (for example, in a pure-frontend handoff).
|
|
918
|
+
*
|
|
919
|
+
* @category OAuth
|
|
920
|
+
*/
|
|
921
|
+
declare function getAuthorizationUrl(config: OAuthConfig, options?: {
|
|
922
|
+
scopes?: readonly OAuthScope[];
|
|
923
|
+
state?: string;
|
|
924
|
+
}): string;
|
|
925
|
+
/**
|
|
926
|
+
* Check whether a scope string is one the Vairified server accepts.
|
|
927
|
+
*
|
|
928
|
+
* @category OAuth
|
|
929
|
+
*/
|
|
930
|
+
declare function validateScope(scope: string): scope is OAuthScope;
|
|
931
|
+
/**
|
|
932
|
+
* Get a human-readable description of an OAuth scope.
|
|
933
|
+
*
|
|
934
|
+
* Returns `"Unknown scope: {scope}"` for unrecognized scopes so this
|
|
935
|
+
* function is safe to call on user-supplied input.
|
|
936
|
+
*
|
|
937
|
+
* @category OAuth
|
|
938
|
+
*/
|
|
939
|
+
declare function describeScope(scope: string): string;
|
|
940
|
+
/**
|
|
941
|
+
* Describe multiple scopes at once.
|
|
942
|
+
*
|
|
943
|
+
* @category OAuth
|
|
944
|
+
*/
|
|
945
|
+
declare function describeScopes(scopes: readonly string[]): readonly {
|
|
946
|
+
scope: string;
|
|
947
|
+
description: string;
|
|
948
|
+
}[];
|
|
949
|
+
/**
|
|
950
|
+
* Generate a cryptographically-random CSRF state token suitable for
|
|
951
|
+
* use with {@link OAuthResource.authorize}.
|
|
952
|
+
*
|
|
953
|
+
* Uses the Web Crypto API (available in Node 19+ and all modern
|
|
954
|
+
* browsers). The returned string is URL-safe base64 of 32 random bytes.
|
|
955
|
+
*
|
|
956
|
+
* @category OAuth
|
|
957
|
+
*/
|
|
958
|
+
declare function generateState(): string;
|
|
959
|
+
|
|
960
|
+
/**
|
|
961
|
+
* {@link OAuthResource} — OAuth 2.0 flow for player consent.
|
|
962
|
+
*
|
|
963
|
+
* @module
|
|
964
|
+
*/
|
|
965
|
+
|
|
966
|
+
/**
|
|
967
|
+
* OAuth 2.0 flow for obtaining player consent.
|
|
968
|
+
*
|
|
969
|
+
* Typical flow:
|
|
970
|
+
*
|
|
971
|
+
* 1. {@link authorize} — start an authorization, get a URL to redirect
|
|
972
|
+
* the player to.
|
|
973
|
+
* 2. Player approves on the Vairified site and is redirected back to
|
|
974
|
+
* your `redirectUri` with a `code` query parameter.
|
|
975
|
+
* 3. {@link exchangeToken} — swap the code for access and refresh
|
|
976
|
+
* tokens plus the player's external ID.
|
|
977
|
+
* 4. Store the refresh token and call {@link refresh} when the access
|
|
978
|
+
* token expires.
|
|
979
|
+
* 5. {@link revoke} — disconnect a player from your app.
|
|
980
|
+
*
|
|
981
|
+
* @category Resources
|
|
982
|
+
*/
|
|
983
|
+
declare class OAuthResource {
|
|
984
|
+
#private;
|
|
985
|
+
/** @internal */
|
|
986
|
+
constructor(http: HttpTransport);
|
|
820
987
|
/**
|
|
821
988
|
* Start an OAuth authorization flow.
|
|
822
989
|
*
|
|
823
|
-
*
|
|
824
|
-
*
|
|
825
|
-
*
|
|
826
|
-
* @param redirectUri - Your application's callback URL
|
|
827
|
-
* @param scopes - Permission scopes to request (defaults to profile:read, rating:read)
|
|
828
|
-
* @param state - CSRF protection state parameter (recommended)
|
|
829
|
-
* @returns AuthorizationResponse with the URL to redirect users to
|
|
830
|
-
* @throws OAuthError if the authorization fails to start
|
|
831
|
-
*
|
|
832
|
-
* @example
|
|
833
|
-
* ```ts
|
|
834
|
-
* const auth = await client.startOAuth(
|
|
835
|
-
* 'https://myapp.com/callback',
|
|
836
|
-
* ['profile:read', 'rating:read', 'match:submit'],
|
|
837
|
-
* 'random_csrf_token',
|
|
838
|
-
* );
|
|
839
|
-
* // Redirect user to auth.authorizationUrl
|
|
840
|
-
* window.location.href = auth.authorizationUrl;
|
|
841
|
-
* ```
|
|
842
|
-
*
|
|
843
|
-
* @category OAuth
|
|
844
|
-
*/
|
|
845
|
-
startOAuth(redirectUri: string, scopes?: OAuthScope[], state?: string): Promise<AuthorizationResponse>;
|
|
846
|
-
/**
|
|
847
|
-
* Exchange an authorization code for access and refresh tokens.
|
|
848
|
-
*
|
|
849
|
-
* Call this after the user approves access and is redirected back
|
|
850
|
-
* to your application with a code parameter.
|
|
851
|
-
*
|
|
852
|
-
* @param code - Authorization code from the callback URL
|
|
853
|
-
* @param redirectUri - Must match the redirectUri used in startOAuth
|
|
854
|
-
* @returns TokenResponse with access_token, refresh_token, and player_id
|
|
855
|
-
* @throws OAuthError if the code is invalid or expired
|
|
856
|
-
*
|
|
857
|
-
* @example
|
|
858
|
-
* ```ts
|
|
859
|
-
* // After user is redirected to: https://myapp.com/callback?code=xxx
|
|
860
|
-
* const tokens = await client.exchangeToken(
|
|
861
|
-
* new URL(window.location.href).searchParams.get('code')!,
|
|
862
|
-
* 'https://myapp.com/callback',
|
|
863
|
-
* );
|
|
864
|
-
* // Store tokens.accessToken and tokens.refreshToken securely
|
|
865
|
-
* // Use tokens.playerId to identify the connected player
|
|
866
|
-
* ```
|
|
867
|
-
*
|
|
868
|
-
* @category OAuth
|
|
990
|
+
* @throws {@link OAuthError} with `errorCode: 'invalid_scope'` if a
|
|
991
|
+
* requested scope is not in the accepted list.
|
|
869
992
|
*/
|
|
870
|
-
|
|
993
|
+
authorize(options: {
|
|
994
|
+
redirectUri: string;
|
|
995
|
+
scopes?: readonly OAuthScope[];
|
|
996
|
+
state?: string;
|
|
997
|
+
}): Promise<AuthorizationResponse>;
|
|
998
|
+
/** Exchange an authorization code for access and refresh tokens. */
|
|
999
|
+
exchangeToken(options: {
|
|
1000
|
+
code: string;
|
|
1001
|
+
redirectUri: string;
|
|
1002
|
+
}): Promise<TokenResponse>;
|
|
1003
|
+
/** Refresh an expired access token using a refresh token. */
|
|
1004
|
+
refresh(refreshToken: string): Promise<TokenResponse>;
|
|
1005
|
+
/** Revoke a player's OAuth connection to your app. */
|
|
1006
|
+
revoke(playerId: string): Promise<Record<string, unknown>>;
|
|
1007
|
+
/** Return the list of OAuth scopes the server currently supports. */
|
|
1008
|
+
availableScopes(): Promise<readonly {
|
|
1009
|
+
name: string;
|
|
1010
|
+
description: string;
|
|
1011
|
+
}[]>;
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
/**
|
|
1015
|
+
* {@link WebhookDelivery} and {@link WebhookDeliveriesResult} — webhook
|
|
1016
|
+
* delivery inspection models.
|
|
1017
|
+
*
|
|
1018
|
+
* @module
|
|
1019
|
+
*/
|
|
1020
|
+
|
|
1021
|
+
/**
|
|
1022
|
+
* A single webhook delivery attempt.
|
|
1023
|
+
*
|
|
1024
|
+
* @category Webhooks
|
|
1025
|
+
*/
|
|
1026
|
+
declare class WebhookDelivery {
|
|
1027
|
+
readonly id: string;
|
|
1028
|
+
readonly event: string;
|
|
1029
|
+
readonly url: string;
|
|
1030
|
+
readonly statusCode: number | null;
|
|
1031
|
+
readonly responseBody: string | null;
|
|
1032
|
+
readonly errorMessage: string | null;
|
|
1033
|
+
readonly attempts: number;
|
|
1034
|
+
readonly maxAttempts: number;
|
|
1035
|
+
readonly lastAttemptAt: string;
|
|
1036
|
+
readonly nextRetryAt: string | null;
|
|
1037
|
+
readonly completedAt: string | null;
|
|
1038
|
+
readonly createdAt: string;
|
|
1039
|
+
readonly payload: Readonly<Record<string, unknown>>;
|
|
1040
|
+
/** @internal */
|
|
1041
|
+
constructor(wire: WebhookDeliveryWire);
|
|
1042
|
+
/** Whether delivery completed successfully (2xx status). */
|
|
1043
|
+
get succeeded(): boolean;
|
|
1044
|
+
/** Whether delivery failed definitively (completed with non-2xx). */
|
|
1045
|
+
get failed(): boolean;
|
|
1046
|
+
}
|
|
1047
|
+
/**
|
|
1048
|
+
* Paginated list of webhook delivery attempts.
|
|
1049
|
+
*
|
|
1050
|
+
* @category Webhooks
|
|
1051
|
+
*/
|
|
1052
|
+
declare class WebhookDeliveriesResult {
|
|
1053
|
+
readonly deliveries: readonly WebhookDelivery[];
|
|
1054
|
+
readonly total: number;
|
|
1055
|
+
/** @internal */
|
|
1056
|
+
constructor(wire: WebhookDeliveriesResultWire);
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
/**
|
|
1060
|
+
* {@link WebhooksResource} — webhook delivery inspection.
|
|
1061
|
+
*
|
|
1062
|
+
* @module
|
|
1063
|
+
*/
|
|
1064
|
+
|
|
1065
|
+
/**
|
|
1066
|
+
* Webhook delivery inspection.
|
|
1067
|
+
*
|
|
1068
|
+
* @category Resources
|
|
1069
|
+
*/
|
|
1070
|
+
declare class WebhooksResource {
|
|
1071
|
+
#private;
|
|
1072
|
+
/** @internal */
|
|
1073
|
+
constructor(http: HttpTransport);
|
|
871
1074
|
/**
|
|
872
|
-
*
|
|
873
|
-
*
|
|
874
|
-
* Use this when an access token expires to obtain a new one
|
|
875
|
-
* without requiring the user to re-authorize.
|
|
1075
|
+
* List recent webhook delivery attempts.
|
|
876
1076
|
*
|
|
877
|
-
* @param
|
|
878
|
-
* @
|
|
879
|
-
* @
|
|
1077
|
+
* @param options - Optional filters and pagination.
|
|
1078
|
+
* @param options.event - Filter by event type (e.g. `'rating.updated'`).
|
|
1079
|
+
* @param options.status - Filter: `'all'`, `'pending'`, `'success'`, or `'failed'`.
|
|
1080
|
+
* @param options.limit - Results per page (1-100, default 20).
|
|
1081
|
+
* @param options.offset - Pagination offset.
|
|
1082
|
+
* @returns {@link WebhookDeliveriesResult} with entries and total.
|
|
1083
|
+
* @category Webhooks
|
|
880
1084
|
*
|
|
881
1085
|
* @example
|
|
882
1086
|
* ```ts
|
|
883
|
-
*
|
|
884
|
-
*
|
|
885
|
-
*
|
|
886
|
-
* } catch (e) {
|
|
887
|
-
* if (e instanceof OAuthError && e.errorCode === 'invalid_grant') {
|
|
888
|
-
* // Refresh token revoked, user needs to re-authorize
|
|
889
|
-
* }
|
|
1087
|
+
* const result = await client.webhooks.deliveries({ status: 'failed' });
|
|
1088
|
+
* for (const d of result.deliveries) {
|
|
1089
|
+
* console.log(d.event, d.statusCode, d.errorMessage);
|
|
890
1090
|
* }
|
|
891
1091
|
* ```
|
|
892
|
-
*
|
|
893
|
-
* @category OAuth
|
|
894
1092
|
*/
|
|
895
|
-
|
|
1093
|
+
deliveries(options?: {
|
|
1094
|
+
event?: string;
|
|
1095
|
+
status?: 'all' | 'pending' | 'success' | 'failed';
|
|
1096
|
+
limit?: number;
|
|
1097
|
+
offset?: number;
|
|
1098
|
+
}): Promise<WebhookDeliveriesResult>;
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
/**
|
|
1102
|
+
* {@link Vairified} — the main entry point of the SDK.
|
|
1103
|
+
*
|
|
1104
|
+
* @module
|
|
1105
|
+
*/
|
|
1106
|
+
|
|
1107
|
+
/**
|
|
1108
|
+
* Environment preset → base URL mapping.
|
|
1109
|
+
*
|
|
1110
|
+
* Partners can switch between production, staging, and local development
|
|
1111
|
+
* without memorizing hostnames.
|
|
1112
|
+
*
|
|
1113
|
+
* @category Client
|
|
1114
|
+
*/
|
|
1115
|
+
declare const ENVIRONMENTS: Readonly<Record<VairifiedEnvironment, string>>;
|
|
1116
|
+
/**
|
|
1117
|
+
* Async client for the Vairified Partner API.
|
|
1118
|
+
*
|
|
1119
|
+
* The client is organized around sub-resources that mirror the REST
|
|
1120
|
+
* structure — {@link members}, {@link matches}, {@link oauth},
|
|
1121
|
+
* {@link leaderboard}. Each sub-resource is a thin wrapper around the
|
|
1122
|
+
* HTTP transport on this object.
|
|
1123
|
+
*
|
|
1124
|
+
* ## Lifecycle
|
|
1125
|
+
*
|
|
1126
|
+
* The client holds no persistent connections itself — it's safe to
|
|
1127
|
+
* create one per request if you want. But for typical usage, wrap it
|
|
1128
|
+
* in `await using` so resources are cleaned up deterministically:
|
|
1129
|
+
*
|
|
1130
|
+
* ```ts
|
|
1131
|
+
* await using client = new Vairified({ apiKey: 'vair_pk_xxx' });
|
|
1132
|
+
*
|
|
1133
|
+
* const member = await client.members.get('vair_mem_xxx');
|
|
1134
|
+
* console.log(member.name, member.ratingFor('pickleball'));
|
|
1135
|
+
*
|
|
1136
|
+
* for await (const m of client.members.search({ city: 'Austin' })) {
|
|
1137
|
+
* console.log(m.name);
|
|
1138
|
+
* }
|
|
1139
|
+
* ```
|
|
1140
|
+
*
|
|
1141
|
+
* `await using` requires TypeScript 5.2+ and Node 20+. If you can't
|
|
1142
|
+
* use it, just call `await client.close()` manually when you're done.
|
|
1143
|
+
*
|
|
1144
|
+
* @category Client
|
|
1145
|
+
*/
|
|
1146
|
+
declare class Vairified {
|
|
1147
|
+
#private;
|
|
1148
|
+
/** The resolved API key this client is using. */
|
|
1149
|
+
readonly apiKey: string;
|
|
1150
|
+
/** The resolved base URL (production, staging, local, or custom). */
|
|
1151
|
+
readonly baseUrl: string;
|
|
1152
|
+
/** The resolved environment name. */
|
|
1153
|
+
readonly env: VairifiedEnvironment;
|
|
1154
|
+
/** Request timeout in milliseconds. */
|
|
1155
|
+
readonly timeoutMs: number;
|
|
1156
|
+
/** Member operations — get, search, find, ratingUpdates. */
|
|
1157
|
+
readonly members: MembersResource;
|
|
1158
|
+
/** Match submission — submit, testWebhook. */
|
|
1159
|
+
readonly matches: MatchesResource;
|
|
1160
|
+
/** OAuth flow — authorize, exchangeToken, refresh, revoke. */
|
|
1161
|
+
readonly oauth: OAuthResource;
|
|
1162
|
+
/** Leaderboard queries — list, rank, categories. */
|
|
1163
|
+
readonly leaderboard: LeaderboardResource;
|
|
1164
|
+
/** Webhook delivery inspection — deliveries. */
|
|
1165
|
+
readonly webhooks: WebhooksResource;
|
|
1166
|
+
constructor(options?: VairifiedOptions);
|
|
896
1167
|
/**
|
|
897
|
-
*
|
|
898
|
-
*
|
|
899
|
-
* This disconnects the player from your application. You will no
|
|
900
|
-
* longer be able to access their data or submit matches on their behalf.
|
|
1168
|
+
* API usage statistics for the current API key.
|
|
901
1169
|
*
|
|
902
|
-
*
|
|
903
|
-
* @throws OAuthError if the revocation fails
|
|
904
|
-
*
|
|
905
|
-
* @example
|
|
906
|
-
* ```ts
|
|
907
|
-
* await client.revokeConnection('vair_mem_0ABC123def456GHI789jk');
|
|
908
|
-
* // Player is now disconnected
|
|
909
|
-
* ```
|
|
910
|
-
*
|
|
911
|
-
* @category OAuth
|
|
1170
|
+
* Returns rate-limit status, request counts, and quota usage.
|
|
912
1171
|
*/
|
|
913
|
-
|
|
1172
|
+
usage(): Promise<Record<string, unknown>>;
|
|
914
1173
|
/**
|
|
915
|
-
*
|
|
916
|
-
*
|
|
917
|
-
* @returns List of scope objects with id, name, and description
|
|
918
|
-
*
|
|
919
|
-
* @example
|
|
920
|
-
* ```ts
|
|
921
|
-
* const scopes = await client.getAvailableScopes();
|
|
922
|
-
* for (const scope of scopes) {
|
|
923
|
-
* console.log(`${scope.id}: ${scope.description}`);
|
|
924
|
-
* }
|
|
925
|
-
* ```
|
|
1174
|
+
* Release any resources held by the client.
|
|
926
1175
|
*
|
|
927
|
-
*
|
|
1176
|
+
* The current transport is stateless, so this is a no-op today, but
|
|
1177
|
+
* partners should still call it (or use `await using`) so the SDK
|
|
1178
|
+
* can add connection pooling later without breaking them.
|
|
928
1179
|
*/
|
|
929
|
-
|
|
930
|
-
id: string;
|
|
931
|
-
name: string;
|
|
932
|
-
description: string;
|
|
933
|
-
}>>;
|
|
1180
|
+
close(): Promise<void>;
|
|
934
1181
|
/**
|
|
935
|
-
*
|
|
936
|
-
*
|
|
937
|
-
* @returns Usage statistics (requests, limits, etc.)
|
|
938
|
-
*
|
|
939
|
-
* @example
|
|
940
|
-
* ```ts
|
|
941
|
-
* const usage = await client.getUsage();
|
|
942
|
-
* console.log(`Requests today: ${usage.requestsToday}`);
|
|
943
|
-
* console.log(`Rate limit: ${usage.rateLimit}/hour`);
|
|
944
|
-
* ```
|
|
945
|
-
*
|
|
946
|
-
* @category Client
|
|
1182
|
+
* Explicit resource management hook — enables
|
|
1183
|
+
* `await using client = new Vairified({ ... })` (TypeScript 5.2+).
|
|
947
1184
|
*/
|
|
948
|
-
|
|
1185
|
+
[Symbol.asyncDispose](): Promise<void>;
|
|
1186
|
+
/** Compact summary for console output. */
|
|
1187
|
+
toString(): string;
|
|
949
1188
|
}
|
|
950
1189
|
|
|
951
1190
|
/**
|
|
952
|
-
* Vairified SDK
|
|
1191
|
+
* Vairified SDK — error hierarchy.
|
|
1192
|
+
*
|
|
1193
|
+
* All SDK errors inherit from {@link VairifiedError}, so a single
|
|
1194
|
+
* `catch (err: unknown) { if (err instanceof VairifiedError) ... }`
|
|
1195
|
+
* covers everything. HTTP-status-specific subclasses (auth, not found,
|
|
1196
|
+
* rate limit, validation) are thrown automatically by the HTTP layer.
|
|
953
1197
|
*
|
|
954
1198
|
* @module
|
|
955
1199
|
*/
|
|
956
1200
|
/**
|
|
957
|
-
* Base
|
|
1201
|
+
* Base class for every error thrown by the Vairified SDK.
|
|
958
1202
|
*
|
|
959
1203
|
* @category Errors
|
|
960
1204
|
*/
|
|
961
1205
|
declare class VairifiedError extends Error {
|
|
962
|
-
/** HTTP status code */
|
|
963
|
-
statusCode?: number;
|
|
964
|
-
/**
|
|
965
|
-
response?: unknown;
|
|
1206
|
+
/** HTTP status code (if the error came from an API response). */
|
|
1207
|
+
readonly statusCode?: number;
|
|
1208
|
+
/** Raw response body parsed as JSON when available. */
|
|
1209
|
+
readonly response?: unknown;
|
|
966
1210
|
constructor(message: string, statusCode?: number, response?: unknown);
|
|
967
1211
|
}
|
|
968
1212
|
/**
|
|
969
|
-
*
|
|
1213
|
+
* Thrown on HTTP 429 responses. Carries the `Retry-After` header value
|
|
1214
|
+
* when the server provides one.
|
|
970
1215
|
*
|
|
971
1216
|
* @category Errors
|
|
972
1217
|
*/
|
|
973
1218
|
declare class RateLimitError extends VairifiedError {
|
|
974
|
-
/** Seconds to wait before retrying */
|
|
975
|
-
retryAfter?: number;
|
|
1219
|
+
/** Seconds to wait before retrying, or `undefined` if the server didn't say. */
|
|
1220
|
+
readonly retryAfter?: number;
|
|
976
1221
|
constructor(message?: string, retryAfter?: number, response?: unknown);
|
|
977
1222
|
}
|
|
978
1223
|
/**
|
|
979
|
-
*
|
|
1224
|
+
* Thrown on HTTP 401 — invalid or missing API key.
|
|
980
1225
|
*
|
|
981
1226
|
* @category Errors
|
|
982
1227
|
*/
|
|
@@ -984,7 +1229,7 @@ declare class AuthenticationError extends VairifiedError {
|
|
|
984
1229
|
constructor(message?: string, response?: unknown);
|
|
985
1230
|
}
|
|
986
1231
|
/**
|
|
987
|
-
*
|
|
1232
|
+
* Thrown on HTTP 404 — the resource doesn't exist.
|
|
988
1233
|
*
|
|
989
1234
|
* @category Errors
|
|
990
1235
|
*/
|
|
@@ -992,7 +1237,9 @@ declare class NotFoundError extends VairifiedError {
|
|
|
992
1237
|
constructor(message?: string, response?: unknown);
|
|
993
1238
|
}
|
|
994
1239
|
/**
|
|
995
|
-
*
|
|
1240
|
+
* Thrown on HTTP 400 — the server rejected the request payload.
|
|
1241
|
+
*
|
|
1242
|
+
* Inspect {@link VairifiedError.response} for field-level details.
|
|
996
1243
|
*
|
|
997
1244
|
* @category Errors
|
|
998
1245
|
*/
|
|
@@ -1000,16 +1247,18 @@ declare class ValidationError extends VairifiedError {
|
|
|
1000
1247
|
constructor(message?: string, response?: unknown);
|
|
1001
1248
|
}
|
|
1002
1249
|
/**
|
|
1003
|
-
*
|
|
1004
|
-
*
|
|
1005
|
-
* This can occur during authorization, token exchange, refresh, or revocation.
|
|
1250
|
+
* Thrown by {@link OAuthResource} methods when authorization, token
|
|
1251
|
+
* exchange, refresh, or revocation fails.
|
|
1006
1252
|
*
|
|
1007
1253
|
* @category Errors
|
|
1008
1254
|
*/
|
|
1009
1255
|
declare class OAuthError extends VairifiedError {
|
|
1010
|
-
/**
|
|
1011
|
-
|
|
1256
|
+
/**
|
|
1257
|
+
* OAuth error code such as `'invalid_grant'`, `'invalid_scope'`,
|
|
1258
|
+
* or `'expired_token'`. Check this to branch on the specific failure.
|
|
1259
|
+
*/
|
|
1260
|
+
readonly errorCode?: string;
|
|
1012
1261
|
constructor(message?: string, errorCode?: string, response?: unknown);
|
|
1013
1262
|
}
|
|
1014
1263
|
|
|
1015
|
-
export { AuthenticationError, type AuthorizationResponse, DEFAULT_SCOPES,
|
|
1264
|
+
export { type ApiErrorResponse, AuthenticationError, type AuthorizationResponse, DEFAULT_SCOPES, ENVIRONMENTS, type GameInput, type Gender, type LeaderboardOptions, LeaderboardResource, type MatchBatch, MatchBatchResult, type MatchBatchResultWire, type MatchInput, MatchesResource, Member, MemberSportMap, type MemberStatusWire, MembersResource, NotFoundError, type OAuthConfig, OAuthError, OAuthResource, type OAuthScope, type PartnerMemberWire, type PartnerRatingUpdateWire, type PlayerRankOptions, RateLimitError, type RatingSplitWire, RatingUpdate, SCOPES, type SearchFilters, SportRating, type SportRatingWire, type TokenResponse, TournamentImportResult, type TournamentImportResultWire, Vairified, type VairifiedEnvironment, VairifiedError, type VairifiedOptions, ValidationError, WebhookDeliveriesResult, type WebhookDeliveriesResultWire, WebhookDelivery, type WebhookDeliveryWire, WebhooksResource, describeScope, describeScopes, generateState, getAuthorizationUrl, validateScope };
|