vairified 0.2.0 → 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 +91 -21
- package/dist/index.cjs +213 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +215 -7
- package/dist/index.d.ts +215 -7
- package/dist/index.js +209 -12
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -244,6 +244,34 @@ var MatchBatchResult = class {
|
|
|
244
244
|
}
|
|
245
245
|
};
|
|
246
246
|
|
|
247
|
+
// src/models/tournament-import-result.ts
|
|
248
|
+
var TournamentImportResult = class {
|
|
249
|
+
success;
|
|
250
|
+
matchesImported;
|
|
251
|
+
gamesRecorded;
|
|
252
|
+
ghostPlayersCreated;
|
|
253
|
+
existingPlayersMatched;
|
|
254
|
+
dryRun;
|
|
255
|
+
message;
|
|
256
|
+
errors;
|
|
257
|
+
/** @internal */
|
|
258
|
+
constructor(wire) {
|
|
259
|
+
this.success = wire.success;
|
|
260
|
+
this.matchesImported = wire.matchesImported;
|
|
261
|
+
this.gamesRecorded = wire.gamesRecorded;
|
|
262
|
+
this.ghostPlayersCreated = wire.ghostPlayersCreated;
|
|
263
|
+
this.existingPlayersMatched = wire.existingPlayersMatched;
|
|
264
|
+
this.dryRun = wire.dryRun ?? false;
|
|
265
|
+
this.message = wire.message;
|
|
266
|
+
this.errors = Object.freeze(wire.errors ?? []);
|
|
267
|
+
Object.freeze(this);
|
|
268
|
+
}
|
|
269
|
+
/** True when the import succeeded without errors. */
|
|
270
|
+
get ok() {
|
|
271
|
+
return this.success && this.errors.length === 0;
|
|
272
|
+
}
|
|
273
|
+
};
|
|
274
|
+
|
|
247
275
|
// src/resources/matches.ts
|
|
248
276
|
var MatchesResource = class {
|
|
249
277
|
#http;
|
|
@@ -254,9 +282,9 @@ var MatchesResource = class {
|
|
|
254
282
|
/**
|
|
255
283
|
* Submit a {@link MatchBatch} for rating calculation.
|
|
256
284
|
*
|
|
257
|
-
* All players in every match must have granted the `match:submit`
|
|
285
|
+
* All players in every match must have granted the `user:match:submit`
|
|
258
286
|
* scope via OAuth (unless your API key has the
|
|
259
|
-
* `match:submit:trusted` scope, which skips per-player consent).
|
|
287
|
+
* `user:match:submit:trusted` scope, which skips per-player consent).
|
|
260
288
|
*
|
|
261
289
|
* Set `batch.dryRun = true` to validate without persisting.
|
|
262
290
|
*
|
|
@@ -290,6 +318,37 @@ var MatchesResource = class {
|
|
|
290
318
|
});
|
|
291
319
|
return new MatchBatchResult(wire);
|
|
292
320
|
}
|
|
321
|
+
/**
|
|
322
|
+
* Import tournament results.
|
|
323
|
+
*
|
|
324
|
+
* The request body is a free-form JSON object whose structure is
|
|
325
|
+
* defined by the Vairified tournament import schema. Set
|
|
326
|
+
* `body.dryRun = true` to validate without persisting.
|
|
327
|
+
*
|
|
328
|
+
* @param body - Tournament import payload.
|
|
329
|
+
* @returns {@link TournamentImportResult} with match/game counts.
|
|
330
|
+
* @category Matches
|
|
331
|
+
*
|
|
332
|
+
* @example
|
|
333
|
+
* ```ts
|
|
334
|
+
* const result = await client.matches.tournamentImport({
|
|
335
|
+
* sport: 'pickleball',
|
|
336
|
+
* tournamentName: 'Spring Classic',
|
|
337
|
+
* matches: [...],
|
|
338
|
+
* });
|
|
339
|
+
* if (result.ok) {
|
|
340
|
+
* console.log(`Imported ${result.matchesImported} matches`);
|
|
341
|
+
* }
|
|
342
|
+
* ```
|
|
343
|
+
*/
|
|
344
|
+
async tournamentImport(body) {
|
|
345
|
+
const wire = await this.#http.request({
|
|
346
|
+
method: "POST",
|
|
347
|
+
path: "/partner/tournament-import",
|
|
348
|
+
body
|
|
349
|
+
});
|
|
350
|
+
return new TournamentImportResult(wire);
|
|
351
|
+
}
|
|
293
352
|
/** Send a test payload to a webhook URL. */
|
|
294
353
|
async testWebhook(webhookUrl) {
|
|
295
354
|
const data = await this.#http.request({
|
|
@@ -614,13 +673,48 @@ var MembersResource = class {
|
|
|
614
673
|
}
|
|
615
674
|
return null;
|
|
616
675
|
}
|
|
676
|
+
/**
|
|
677
|
+
* Fetch up to 100 members by their member IDs in one call.
|
|
678
|
+
*
|
|
679
|
+
* Unknown IDs are silently omitted — the returned array may be
|
|
680
|
+
* shorter than the input. Results are returned in the same order
|
|
681
|
+
* as the input IDs.
|
|
682
|
+
*
|
|
683
|
+
* @param ids - Array of integer member IDs (max 100).
|
|
684
|
+
* @param options - Optional filters.
|
|
685
|
+
* @param options.sport - Sport code to scope ratings (e.g. `'pickleball'`).
|
|
686
|
+
* @returns Array of {@link Member} instances.
|
|
687
|
+
* @throws {@link ValidationError} If more than 100 IDs are provided.
|
|
688
|
+
* @category Members
|
|
689
|
+
*
|
|
690
|
+
* @example
|
|
691
|
+
* ```ts
|
|
692
|
+
* const members = await client.members.getBulk([4873327, 4873328]);
|
|
693
|
+
* for (const m of members) {
|
|
694
|
+
* console.log(m.name, m.ratingFor('pickleball'));
|
|
695
|
+
* }
|
|
696
|
+
* ```
|
|
697
|
+
*/
|
|
698
|
+
async getBulk(ids, options) {
|
|
699
|
+
if (ids.length > 100) {
|
|
700
|
+
throw new ValidationError("Maximum 100 member IDs per request");
|
|
701
|
+
}
|
|
702
|
+
const query = { ids: ids.join(",") };
|
|
703
|
+
if (options?.sport) query.sport = options.sport;
|
|
704
|
+
const rows = await this.#http.request({
|
|
705
|
+
method: "GET",
|
|
706
|
+
path: "/partner/members",
|
|
707
|
+
query
|
|
708
|
+
});
|
|
709
|
+
return rows.map((row) => new Member(row));
|
|
710
|
+
}
|
|
617
711
|
/**
|
|
618
712
|
* Poll for rating change notifications.
|
|
619
713
|
*
|
|
620
714
|
* Returns a list of {@link RatingUpdate} objects for every player
|
|
621
715
|
* whose rating has changed since the last poll. Members are
|
|
622
716
|
* considered subscribed when they have an active OAuth connection
|
|
623
|
-
* with the `webhook:subscribe` scope.
|
|
717
|
+
* with the `user:webhook:subscribe` scope.
|
|
624
718
|
*/
|
|
625
719
|
async ratingUpdates() {
|
|
626
720
|
const data = await this.#http.request({
|
|
@@ -683,14 +777,17 @@ function resolveAgeFilter(filters) {
|
|
|
683
777
|
|
|
684
778
|
// src/oauth.ts
|
|
685
779
|
var SCOPES = Object.freeze({
|
|
686
|
-
"profile:read": "Access your name, location, and verification status",
|
|
687
|
-
"profile:email": "Access your email address",
|
|
688
|
-
"rating:read": "View your current rating and rating splits",
|
|
689
|
-
"rating:history": "View your complete rating history",
|
|
690
|
-
"match:submit": "Submit match results on your behalf",
|
|
691
|
-
"webhook:subscribe": "Receive notifications when your rating changes"
|
|
780
|
+
"user:profile:read": "Access your name, location, and verification status",
|
|
781
|
+
"user:profile:email": "Access your email address",
|
|
782
|
+
"user:rating:read": "View your current rating and rating splits",
|
|
783
|
+
"user:rating:history": "View your complete rating history",
|
|
784
|
+
"user:match:submit": "Submit match results on your behalf",
|
|
785
|
+
"user:webhook:subscribe": "Receive notifications when your rating changes"
|
|
692
786
|
});
|
|
693
|
-
var DEFAULT_SCOPES = Object.freeze([
|
|
787
|
+
var DEFAULT_SCOPES = Object.freeze([
|
|
788
|
+
"user:profile:read",
|
|
789
|
+
"user:rating:read"
|
|
790
|
+
]);
|
|
694
791
|
function getAuthorizationUrl(config, options = {}) {
|
|
695
792
|
const baseUrl = (config.baseUrl ?? "https://api-next.vairified.com/api/v1").replace(/\/+$/, "");
|
|
696
793
|
const scopeList = ensureProfileRead(options.scopes ?? DEFAULT_SCOPES);
|
|
@@ -729,10 +826,10 @@ function generateState() {
|
|
|
729
826
|
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
730
827
|
}
|
|
731
828
|
function ensureProfileRead(scopes) {
|
|
732
|
-
if (scopes.includes("profile:read")) {
|
|
829
|
+
if (scopes.includes("user:profile:read")) {
|
|
733
830
|
return scopes;
|
|
734
831
|
}
|
|
735
|
-
return ["profile:read", ...scopes];
|
|
832
|
+
return ["user:profile:read", ...scopes];
|
|
736
833
|
}
|
|
737
834
|
|
|
738
835
|
// src/resources/oauth.ts
|
|
@@ -821,6 +918,99 @@ function tokenResponseFromWire(data) {
|
|
|
821
918
|
};
|
|
822
919
|
}
|
|
823
920
|
|
|
921
|
+
// src/models/webhook-delivery.ts
|
|
922
|
+
var WebhookDelivery = class {
|
|
923
|
+
id;
|
|
924
|
+
event;
|
|
925
|
+
url;
|
|
926
|
+
statusCode;
|
|
927
|
+
responseBody;
|
|
928
|
+
errorMessage;
|
|
929
|
+
attempts;
|
|
930
|
+
maxAttempts;
|
|
931
|
+
lastAttemptAt;
|
|
932
|
+
nextRetryAt;
|
|
933
|
+
completedAt;
|
|
934
|
+
createdAt;
|
|
935
|
+
payload;
|
|
936
|
+
/** @internal */
|
|
937
|
+
constructor(wire) {
|
|
938
|
+
this.id = wire.id;
|
|
939
|
+
this.event = wire.event;
|
|
940
|
+
this.url = wire.url;
|
|
941
|
+
this.statusCode = wire.statusCode;
|
|
942
|
+
this.responseBody = wire.responseBody;
|
|
943
|
+
this.errorMessage = wire.errorMessage;
|
|
944
|
+
this.attempts = wire.attempts;
|
|
945
|
+
this.maxAttempts = wire.maxAttempts;
|
|
946
|
+
this.lastAttemptAt = wire.lastAttemptAt;
|
|
947
|
+
this.nextRetryAt = wire.nextRetryAt;
|
|
948
|
+
this.completedAt = wire.completedAt;
|
|
949
|
+
this.createdAt = wire.createdAt;
|
|
950
|
+
this.payload = Object.freeze({ ...wire.payload });
|
|
951
|
+
Object.freeze(this);
|
|
952
|
+
}
|
|
953
|
+
/** Whether delivery completed successfully (2xx status). */
|
|
954
|
+
get succeeded() {
|
|
955
|
+
return this.completedAt != null && this.statusCode != null && this.statusCode >= 200 && this.statusCode < 300;
|
|
956
|
+
}
|
|
957
|
+
/** Whether delivery failed definitively (completed with non-2xx). */
|
|
958
|
+
get failed() {
|
|
959
|
+
return this.completedAt != null && !this.succeeded;
|
|
960
|
+
}
|
|
961
|
+
};
|
|
962
|
+
var WebhookDeliveriesResult = class {
|
|
963
|
+
deliveries;
|
|
964
|
+
total;
|
|
965
|
+
/** @internal */
|
|
966
|
+
constructor(wire) {
|
|
967
|
+
this.deliveries = Object.freeze(wire.deliveries.map((d) => new WebhookDelivery(d)));
|
|
968
|
+
this.total = wire.total;
|
|
969
|
+
Object.freeze(this);
|
|
970
|
+
}
|
|
971
|
+
};
|
|
972
|
+
|
|
973
|
+
// src/resources/webhooks.ts
|
|
974
|
+
var WebhooksResource = class {
|
|
975
|
+
#http;
|
|
976
|
+
/** @internal */
|
|
977
|
+
constructor(http) {
|
|
978
|
+
this.#http = http;
|
|
979
|
+
}
|
|
980
|
+
/**
|
|
981
|
+
* List recent webhook delivery attempts.
|
|
982
|
+
*
|
|
983
|
+
* @param options - Optional filters and pagination.
|
|
984
|
+
* @param options.event - Filter by event type (e.g. `'rating.updated'`).
|
|
985
|
+
* @param options.status - Filter: `'all'`, `'pending'`, `'success'`, or `'failed'`.
|
|
986
|
+
* @param options.limit - Results per page (1-100, default 20).
|
|
987
|
+
* @param options.offset - Pagination offset.
|
|
988
|
+
* @returns {@link WebhookDeliveriesResult} with entries and total.
|
|
989
|
+
* @category Webhooks
|
|
990
|
+
*
|
|
991
|
+
* @example
|
|
992
|
+
* ```ts
|
|
993
|
+
* const result = await client.webhooks.deliveries({ status: 'failed' });
|
|
994
|
+
* for (const d of result.deliveries) {
|
|
995
|
+
* console.log(d.event, d.statusCode, d.errorMessage);
|
|
996
|
+
* }
|
|
997
|
+
* ```
|
|
998
|
+
*/
|
|
999
|
+
async deliveries(options) {
|
|
1000
|
+
const query = {};
|
|
1001
|
+
if (options?.event) query.event = options.event;
|
|
1002
|
+
if (options?.status) query.status = options.status;
|
|
1003
|
+
if (options?.limit != null) query.limit = options.limit;
|
|
1004
|
+
if (options?.offset != null) query.offset = options.offset;
|
|
1005
|
+
const data = await this.#http.request({
|
|
1006
|
+
method: "GET",
|
|
1007
|
+
path: "/partner/webhook-deliveries",
|
|
1008
|
+
query
|
|
1009
|
+
});
|
|
1010
|
+
return new WebhookDeliveriesResult(data);
|
|
1011
|
+
}
|
|
1012
|
+
};
|
|
1013
|
+
|
|
824
1014
|
// src/client.ts
|
|
825
1015
|
var ENVIRONMENTS = Object.freeze({
|
|
826
1016
|
production: "https://api-next.vairified.com/api/v1",
|
|
@@ -845,6 +1035,8 @@ var Vairified = class {
|
|
|
845
1035
|
oauth;
|
|
846
1036
|
/** Leaderboard queries — list, rank, categories. */
|
|
847
1037
|
leaderboard;
|
|
1038
|
+
/** Webhook delivery inspection — deliveries. */
|
|
1039
|
+
webhooks;
|
|
848
1040
|
#transport;
|
|
849
1041
|
constructor(options = {}) {
|
|
850
1042
|
const apiKey = options.apiKey ?? process.env.VAIRIFIED_API_KEY ?? "";
|
|
@@ -876,6 +1068,7 @@ var Vairified = class {
|
|
|
876
1068
|
this.matches = new MatchesResource(this.#transport);
|
|
877
1069
|
this.oauth = new OAuthResource(this.#transport);
|
|
878
1070
|
this.leaderboard = new LeaderboardResource(this.#transport);
|
|
1071
|
+
this.webhooks = new WebhooksResource(this.#transport);
|
|
879
1072
|
}
|
|
880
1073
|
/**
|
|
881
1074
|
* API usage statistics for the current API key.
|
|
@@ -927,9 +1120,13 @@ export {
|
|
|
927
1120
|
RatingUpdate,
|
|
928
1121
|
SCOPES,
|
|
929
1122
|
SportRating,
|
|
1123
|
+
TournamentImportResult,
|
|
930
1124
|
Vairified,
|
|
931
1125
|
VairifiedError,
|
|
932
1126
|
ValidationError,
|
|
1127
|
+
WebhookDeliveriesResult,
|
|
1128
|
+
WebhookDelivery,
|
|
1129
|
+
WebhooksResource,
|
|
933
1130
|
describeScope,
|
|
934
1131
|
describeScopes,
|
|
935
1132
|
generateState,
|