vairified 0.3.2 → 0.6.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 +104 -3
- package/dist/index.cjs +419 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +401 -6
- package/dist/index.d.ts +401 -6
- package/dist/index.js +417 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -115,17 +115,29 @@ interface SportRatingWire {
|
|
|
115
115
|
readonly rating: number;
|
|
116
116
|
readonly abbr: string;
|
|
117
117
|
readonly ratingSplits: Readonly<Record<string, RatingSplitWire>>;
|
|
118
|
+
readonly isVairified?: boolean;
|
|
119
|
+
readonly isRater?: boolean;
|
|
120
|
+
readonly isVairPro?: boolean;
|
|
121
|
+
readonly isVairProStatus?: VairProStatus;
|
|
118
122
|
}
|
|
119
123
|
/**
|
|
120
|
-
*
|
|
124
|
+
* VAIR-Pro lifecycle status in a sport: `'ACTIVE'` (approved, can rate),
|
|
125
|
+
* `'PENDING'` (paid, awaiting approval), or `null` (not a VAIR Pro here).
|
|
126
|
+
*
|
|
127
|
+
* @category Members
|
|
128
|
+
*/
|
|
129
|
+
type VairProStatus = 'PENDING' | 'ACTIVE' | null;
|
|
130
|
+
/**
|
|
131
|
+
* Grouped member status flags — only the genuinely GLOBAL ones.
|
|
132
|
+
*
|
|
133
|
+
* VAIRification and VAIR-Pro status are per-sport (Vairified#783) and live on
|
|
134
|
+
* each {@link SportRatingWire} entry (`member.sport.get(code)`), not here.
|
|
121
135
|
*
|
|
122
136
|
* @category Members
|
|
123
137
|
*/
|
|
124
138
|
interface MemberStatusWire {
|
|
125
|
-
readonly isVairified: boolean;
|
|
126
139
|
readonly isWheelchair: boolean;
|
|
127
140
|
readonly isAmbassador: boolean;
|
|
128
|
-
readonly isRater: boolean;
|
|
129
141
|
readonly isConnected: boolean;
|
|
130
142
|
}
|
|
131
143
|
/**
|
|
@@ -145,6 +157,7 @@ interface PartnerMemberWire {
|
|
|
145
157
|
readonly state?: string;
|
|
146
158
|
readonly zip?: string;
|
|
147
159
|
readonly country?: string;
|
|
160
|
+
readonly memberSince?: string;
|
|
148
161
|
readonly gender?: Gender;
|
|
149
162
|
readonly status: MemberStatusWire;
|
|
150
163
|
readonly sport?: Readonly<Record<string, SportRatingWire>>;
|
|
@@ -152,6 +165,30 @@ interface PartnerMemberWire {
|
|
|
152
165
|
readonly email?: string;
|
|
153
166
|
readonly grantedScopes?: readonly string[];
|
|
154
167
|
}
|
|
168
|
+
/**
|
|
169
|
+
* One resolved address in a {@link MembersByEmailResultWire}.
|
|
170
|
+
*
|
|
171
|
+
* `members` is always an array: an email address is not a unique key in
|
|
172
|
+
* VAIR, so one address can resolve to more than one member.
|
|
173
|
+
*
|
|
174
|
+
* @category Members
|
|
175
|
+
*/
|
|
176
|
+
interface PartnerMemberEmailMatchWire {
|
|
177
|
+
readonly email: string;
|
|
178
|
+
readonly members: readonly PartnerMemberWire[];
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Raw envelope returned by `GET /partner/members/by-email`.
|
|
182
|
+
*
|
|
183
|
+
* Every requested address appears in exactly one of `matched` or
|
|
184
|
+
* `notFound` — the endpoint never silently drops one.
|
|
185
|
+
*
|
|
186
|
+
* @category Members
|
|
187
|
+
*/
|
|
188
|
+
interface MembersByEmailResultWire {
|
|
189
|
+
readonly matched: readonly PartnerMemberEmailMatchWire[];
|
|
190
|
+
readonly notFound: readonly string[];
|
|
191
|
+
}
|
|
155
192
|
/**
|
|
156
193
|
* Raw rating change notification.
|
|
157
194
|
*
|
|
@@ -344,6 +381,10 @@ interface PlayerRankOptions {
|
|
|
344
381
|
*
|
|
345
382
|
* @category Matches
|
|
346
383
|
*/
|
|
384
|
+
interface TournamentImportCreatedGhostWire {
|
|
385
|
+
readonly ref: string;
|
|
386
|
+
readonly memberId: number;
|
|
387
|
+
}
|
|
347
388
|
interface TournamentImportResultWire {
|
|
348
389
|
readonly success: boolean;
|
|
349
390
|
readonly matchesImported: number;
|
|
@@ -353,6 +394,7 @@ interface TournamentImportResultWire {
|
|
|
353
394
|
readonly dryRun?: boolean;
|
|
354
395
|
readonly message?: string;
|
|
355
396
|
readonly errors?: readonly string[];
|
|
397
|
+
readonly createdGhostMembers?: readonly TournamentImportCreatedGhostWire[];
|
|
356
398
|
}
|
|
357
399
|
/**
|
|
358
400
|
* Wire shape for a single webhook delivery attempt.
|
|
@@ -393,6 +435,24 @@ interface ApiErrorResponse {
|
|
|
393
435
|
readonly error?: string;
|
|
394
436
|
readonly statusCode?: number;
|
|
395
437
|
}
|
|
438
|
+
type AttributionOutcome = 'attributed' | 'already_attributed' | 'account_predates_event' | 'not_found';
|
|
439
|
+
interface MemberAttributionWire {
|
|
440
|
+
readonly memberId: number;
|
|
441
|
+
readonly attributed: boolean;
|
|
442
|
+
readonly ambassadorMemberId?: number | null;
|
|
443
|
+
readonly attributedAt?: string;
|
|
444
|
+
}
|
|
445
|
+
interface MembersAttributionResultWire {
|
|
446
|
+
readonly attributions?: readonly MemberAttributionWire[];
|
|
447
|
+
readonly notFound?: readonly number[];
|
|
448
|
+
}
|
|
449
|
+
interface AttributionResultWire {
|
|
450
|
+
readonly attributed: number;
|
|
451
|
+
readonly results?: readonly {
|
|
452
|
+
readonly memberId: number;
|
|
453
|
+
readonly outcome: AttributionOutcome;
|
|
454
|
+
}[];
|
|
455
|
+
}
|
|
396
456
|
|
|
397
457
|
/**
|
|
398
458
|
* {@link LeaderboardResource} — read-only leaderboard queries.
|
|
@@ -452,6 +512,17 @@ declare class MatchBatchResult {
|
|
|
452
512
|
* @module
|
|
453
513
|
*/
|
|
454
514
|
|
|
515
|
+
/**
|
|
516
|
+
* One ghost player created by a tournament import.
|
|
517
|
+
*
|
|
518
|
+
* @category Matches
|
|
519
|
+
*/
|
|
520
|
+
interface TournamentImportCreatedGhost {
|
|
521
|
+
/** The email or phone you supplied for this person in `ghostMembers[]`. */
|
|
522
|
+
readonly ref: string;
|
|
523
|
+
/** The public member id allocated to them, usable in `matches.submit()`. */
|
|
524
|
+
readonly memberId: number;
|
|
525
|
+
}
|
|
455
526
|
/**
|
|
456
527
|
* Result of a tournament import submission.
|
|
457
528
|
*
|
|
@@ -466,6 +537,19 @@ declare class TournamentImportResult {
|
|
|
466
537
|
readonly dryRun: boolean;
|
|
467
538
|
readonly message: string | undefined;
|
|
468
539
|
readonly errors: readonly string[];
|
|
540
|
+
/**
|
|
541
|
+
* Public member ids for the ghost players THIS import created, keyed by the
|
|
542
|
+
* `ref` supplied in `ghostMembers[]`.
|
|
543
|
+
*
|
|
544
|
+
* Empty on a dry-run, and empty for entries the import matched to a player who
|
|
545
|
+
* already existed — resolving an existing email to a member requires the
|
|
546
|
+
* `key:player:lookup` scope and `members.getByEmail()`.
|
|
547
|
+
*
|
|
548
|
+
* Use these ids directly in a follow-up `matches.submit()`; without them an
|
|
549
|
+
* import reports only how many accounts it caused and you cannot address any
|
|
550
|
+
* of them.
|
|
551
|
+
*/
|
|
552
|
+
readonly createdGhostMembers: readonly TournamentImportCreatedGhost[];
|
|
469
553
|
/** @internal */
|
|
470
554
|
constructor(wire: TournamentImportResultWire);
|
|
471
555
|
/** True when the import succeeded without errors. */
|
|
@@ -582,6 +666,14 @@ declare class SportRating {
|
|
|
582
666
|
readonly rating: number;
|
|
583
667
|
/** Category abbreviation for the primary rating (e.g. `'VO'`). */
|
|
584
668
|
readonly abbr: string;
|
|
669
|
+
/** Player is VAIRified in this sport (has a verified, non-recreational rating). */
|
|
670
|
+
readonly isVairified: boolean;
|
|
671
|
+
/** Player is an active VAIR Pro (can rate) in this sport. Alias of {@link isVairPro}. */
|
|
672
|
+
readonly isRater: boolean;
|
|
673
|
+
/** Player is an active VAIR Pro (can rate) in this sport. */
|
|
674
|
+
readonly isVairPro: boolean;
|
|
675
|
+
/** VAIR-Pro lifecycle status in this sport (`'ACTIVE'` / `'PENDING'` / `null`). */
|
|
676
|
+
readonly isVairProStatus: VairProStatus;
|
|
585
677
|
constructor(wire: SportRatingWire);
|
|
586
678
|
/**
|
|
587
679
|
* Look up a rating split by key (e.g. `'overall-open'`,
|
|
@@ -663,6 +755,20 @@ declare class Member {
|
|
|
663
755
|
readonly state: string | null;
|
|
664
756
|
readonly zip: string | null;
|
|
665
757
|
readonly country: string | null;
|
|
758
|
+
/**
|
|
759
|
+
* The DATE this member's VAIR account was created (`YYYY-MM-DD`, UTC), or
|
|
760
|
+
* `null` when the endpoint does not supply it.
|
|
761
|
+
*
|
|
762
|
+
* Present on `members.get()`, `members.getBulk()` and `members.getByEmail()` —
|
|
763
|
+
* the calls where you already know which member you asked about. **Never on
|
|
764
|
+
* `members.search()`**, which is discovery: account age is not something you
|
|
765
|
+
* can browse strangers by.
|
|
766
|
+
*
|
|
767
|
+
* Deliberately a date, not a timestamp. It exists so you can apply a
|
|
768
|
+
* new-accounts-only referral rule — crediting an ambassador only for accounts
|
|
769
|
+
* created because of their event.
|
|
770
|
+
*/
|
|
771
|
+
readonly memberSince: string | null;
|
|
666
772
|
readonly gender: Gender | null;
|
|
667
773
|
readonly status: MemberStatusWire;
|
|
668
774
|
readonly sport: MemberSportMap;
|
|
@@ -693,6 +799,74 @@ declare class Member {
|
|
|
693
799
|
toString(): string;
|
|
694
800
|
}
|
|
695
801
|
|
|
802
|
+
/**
|
|
803
|
+
* {@link MembersByEmailResult} — result of an email → member lookup.
|
|
804
|
+
*
|
|
805
|
+
* @module
|
|
806
|
+
*/
|
|
807
|
+
|
|
808
|
+
/**
|
|
809
|
+
* One requested address that resolved to at least one member.
|
|
810
|
+
*
|
|
811
|
+
* {@link members} is always an array. An email address is not a unique
|
|
812
|
+
* key in VAIR — an unclaimed imported record can share an address with a
|
|
813
|
+
* claimed account — so never assume a single element without checking.
|
|
814
|
+
*
|
|
815
|
+
* @category Members
|
|
816
|
+
*/
|
|
817
|
+
declare class MemberEmailMatch {
|
|
818
|
+
/** The address exactly as you supplied it, not as stored. */
|
|
819
|
+
readonly email: string;
|
|
820
|
+
/** Every member holding this address. Never empty. */
|
|
821
|
+
readonly members: readonly Member[];
|
|
822
|
+
/** @internal */
|
|
823
|
+
constructor(wire: PartnerMemberEmailMatchWire);
|
|
824
|
+
/**
|
|
825
|
+
* The single member for this address, or `null` when the address is
|
|
826
|
+
* ambiguous (more than one match).
|
|
827
|
+
*
|
|
828
|
+
* Use this rather than `members[0]` when a wrong link is worse than no
|
|
829
|
+
* link — it refuses to guess instead of silently picking one.
|
|
830
|
+
*/
|
|
831
|
+
get sole(): Member | null;
|
|
832
|
+
/** Whether this address resolved to more than one member. */
|
|
833
|
+
get isAmbiguous(): boolean;
|
|
834
|
+
toString(): string;
|
|
835
|
+
}
|
|
836
|
+
/**
|
|
837
|
+
* Result of a {@link MembersResource.getByEmail} call.
|
|
838
|
+
*
|
|
839
|
+
* Every address you supplied appears in exactly one of {@link matched} or
|
|
840
|
+
* {@link notFound} — the endpoint never silently drops one, so consume
|
|
841
|
+
* {@link notFound} directly rather than diffing your input against the
|
|
842
|
+
* results.
|
|
843
|
+
*
|
|
844
|
+
* A `notFound` address is not proof the person has no VAIR account:
|
|
845
|
+
* unclaimed imported records are deliberately excluded from this lookup.
|
|
846
|
+
*
|
|
847
|
+
* @category Members
|
|
848
|
+
*/
|
|
849
|
+
declare class MembersByEmailResult {
|
|
850
|
+
readonly matched: readonly MemberEmailMatch[];
|
|
851
|
+
/** Addresses that resolved to nothing, echoed as you supplied them. */
|
|
852
|
+
readonly notFound: readonly string[];
|
|
853
|
+
/** @internal */
|
|
854
|
+
constructor(wire: MembersByEmailResultWire);
|
|
855
|
+
/**
|
|
856
|
+
* Look up one address's match, case-insensitively.
|
|
857
|
+
*
|
|
858
|
+
* Saves callers a linear scan and, more importantly, saves them from
|
|
859
|
+
* matching case-sensitively against an address the server echoed back
|
|
860
|
+
* in whatever case they originally sent.
|
|
861
|
+
*/
|
|
862
|
+
get(email: string): MemberEmailMatch | null;
|
|
863
|
+
/** Whether every requested address resolved to at least one member. */
|
|
864
|
+
get allResolved(): boolean;
|
|
865
|
+
/** Total number of members across every matched address. */
|
|
866
|
+
get memberCount(): number;
|
|
867
|
+
toString(): string;
|
|
868
|
+
}
|
|
869
|
+
|
|
696
870
|
/**
|
|
697
871
|
* {@link RatingUpdate} — a single rating change notification.
|
|
698
872
|
*
|
|
@@ -830,6 +1004,50 @@ declare class MembersResource {
|
|
|
830
1004
|
getBulk(ids: number[], options?: {
|
|
831
1005
|
sport?: string;
|
|
832
1006
|
}): Promise<Member[]>;
|
|
1007
|
+
/**
|
|
1008
|
+
* Resolve up to 100 members by their **exact** email address.
|
|
1009
|
+
*
|
|
1010
|
+
* Use this to link your users to their VAIR identity when you hold
|
|
1011
|
+
* their email but not their member ID — e.g. resolving a tournament
|
|
1012
|
+
* roster at registration instead of waiting for each player to
|
|
1013
|
+
* complete SSO.
|
|
1014
|
+
*
|
|
1015
|
+
* **Requires the `key:player:lookup` scope**, which is granted per
|
|
1016
|
+
* partner on approval. Holding `key:player:search` does not imply it.
|
|
1017
|
+
*
|
|
1018
|
+
* Matching is exact and case-insensitive; there is deliberately no
|
|
1019
|
+
* partial, prefix or fuzzy matching. Every address you supply comes
|
|
1020
|
+
* back in either `matched` or `notFound`, so read `notFound` directly
|
|
1021
|
+
* instead of diffing your input against the results.
|
|
1022
|
+
*
|
|
1023
|
+
* A `notFound` address is **not** proof the person has no VAIR
|
|
1024
|
+
* account — unclaimed imported records are excluded from this lookup.
|
|
1025
|
+
*
|
|
1026
|
+
* @param emails - Email addresses to resolve (max 100).
|
|
1027
|
+
* @param options - Optional filters.
|
|
1028
|
+
* @param options.sport - Sport code to scope ratings (e.g. `'pickleball'`).
|
|
1029
|
+
* @throws {@link ValidationError} If more than 100 addresses are
|
|
1030
|
+
* provided, or the list is empty.
|
|
1031
|
+
* @category Members
|
|
1032
|
+
*
|
|
1033
|
+
* @example
|
|
1034
|
+
* ```ts
|
|
1035
|
+
* const result = await client.members.getByEmail([
|
|
1036
|
+
* 'ada@example.com',
|
|
1037
|
+
* 'nobody@example.com',
|
|
1038
|
+
* ]);
|
|
1039
|
+
*
|
|
1040
|
+
* for (const match of result.matched) {
|
|
1041
|
+
* const member = match.sole; // null when the address is ambiguous
|
|
1042
|
+
* if (member) console.log(match.email, '->', member.memberId);
|
|
1043
|
+
* }
|
|
1044
|
+
*
|
|
1045
|
+
* console.log('no VAIR account found for:', result.notFound);
|
|
1046
|
+
* ```
|
|
1047
|
+
*/
|
|
1048
|
+
getByEmail(emails: readonly string[], options?: {
|
|
1049
|
+
sport?: string;
|
|
1050
|
+
}): Promise<MembersByEmailResult>;
|
|
833
1051
|
/**
|
|
834
1052
|
* Poll for rating change notifications.
|
|
835
1053
|
*
|
|
@@ -961,9 +1179,17 @@ declare function describeScopes(scopes: readonly string[]): readonly {
|
|
|
961
1179
|
* Generate a cryptographically-random CSRF state token suitable for
|
|
962
1180
|
* use with {@link OAuthResource.authorize}.
|
|
963
1181
|
*
|
|
964
|
-
* Uses the Web Crypto API (
|
|
965
|
-
* browsers). The returned string is URL-safe
|
|
1182
|
+
* Uses the Web Crypto API `crypto.getRandomValues` (built into Node 19+
|
|
1183
|
+
* and all modern browsers). The returned string is URL-safe, unpadded
|
|
1184
|
+
* base64 of 32 random bytes.
|
|
966
1185
|
*
|
|
1186
|
+
* On runtimes without Web Crypto — notably **React Native / Hermes** —
|
|
1187
|
+
* this throws a descriptive `Error` (rather than a bare `ReferenceError`)
|
|
1188
|
+
* telling you to install and import `react-native-get-random-values` at
|
|
1189
|
+
* your app entry, or to pass your own high-entropy `state` string. Base64
|
|
1190
|
+
* encoding is done in pure JS, so no `btoa` polyfill is required.
|
|
1191
|
+
*
|
|
1192
|
+
* @throws {Error} when `crypto.getRandomValues` is unavailable.
|
|
967
1193
|
* @category OAuth
|
|
968
1194
|
*/
|
|
969
1195
|
declare function generateState(): string;
|
|
@@ -1022,6 +1248,170 @@ declare class OAuthResource {
|
|
|
1022
1248
|
}[]>;
|
|
1023
1249
|
}
|
|
1024
1250
|
|
|
1251
|
+
/**
|
|
1252
|
+
* {@link MemberAttribution}, {@link MembersAttributionResult} and
|
|
1253
|
+
* {@link AttributionResult} — ambassador referral credit.
|
|
1254
|
+
*
|
|
1255
|
+
* @module
|
|
1256
|
+
*/
|
|
1257
|
+
|
|
1258
|
+
/**
|
|
1259
|
+
* Who currently earns referral credit for one member.
|
|
1260
|
+
*
|
|
1261
|
+
* @category Referrals
|
|
1262
|
+
*/
|
|
1263
|
+
declare class MemberAttribution {
|
|
1264
|
+
readonly memberId: number;
|
|
1265
|
+
/** True when some ambassador already holds credit for this member. */
|
|
1266
|
+
readonly attributed: boolean;
|
|
1267
|
+
/**
|
|
1268
|
+
* The member id of the ambassador holding the credit.
|
|
1269
|
+
*
|
|
1270
|
+
* Compare it against your own event host's member id to tell "already credited
|
|
1271
|
+
* to my host — nothing to do" from "credited to somebody else — a person needs
|
|
1272
|
+
* to look, because claiming it takes credit from them".
|
|
1273
|
+
*
|
|
1274
|
+
* `null` both when nobody holds credit and when credit is held by a record that
|
|
1275
|
+
* has no member id of its own, so check {@link attributed} to tell those apart.
|
|
1276
|
+
*/
|
|
1277
|
+
readonly ambassadorMemberId: number | null;
|
|
1278
|
+
/** The date the credit was established (`YYYY-MM-DD`), or `null`. */
|
|
1279
|
+
readonly attributedAt: string | null;
|
|
1280
|
+
/** @internal */
|
|
1281
|
+
constructor(wire: MemberAttributionWire);
|
|
1282
|
+
/** True when nobody holds credit yet, so this member can be claimed. */
|
|
1283
|
+
get isClaimable(): boolean;
|
|
1284
|
+
/** True when credit is held by an ambassador OTHER than the one given. */
|
|
1285
|
+
heldBySomeoneOtherThan(ambassadorMemberId: number): boolean;
|
|
1286
|
+
}
|
|
1287
|
+
/**
|
|
1288
|
+
* Attribution for a batch of members, plus the ids that matched nothing.
|
|
1289
|
+
*
|
|
1290
|
+
* @category Referrals
|
|
1291
|
+
*/
|
|
1292
|
+
declare class MembersAttributionResult {
|
|
1293
|
+
readonly attributions: readonly MemberAttribution[];
|
|
1294
|
+
/**
|
|
1295
|
+
* Member ids that matched no member. Read this rather than diffing your input
|
|
1296
|
+
* against the results — every id you sent lands in one bucket or the other.
|
|
1297
|
+
*/
|
|
1298
|
+
readonly notFound: readonly number[];
|
|
1299
|
+
/** @internal */
|
|
1300
|
+
constructor(wire: MembersAttributionResultWire);
|
|
1301
|
+
/** Attribution for one member id, or `undefined` if it was not returned. */
|
|
1302
|
+
get(memberId: number): MemberAttribution | undefined;
|
|
1303
|
+
/** Members nobody holds credit for yet. */
|
|
1304
|
+
get claimable(): readonly MemberAttribution[];
|
|
1305
|
+
}
|
|
1306
|
+
/**
|
|
1307
|
+
* Outcome of submitting attribution for a batch of members.
|
|
1308
|
+
*
|
|
1309
|
+
* @category Referrals
|
|
1310
|
+
*/
|
|
1311
|
+
declare class AttributionResult {
|
|
1312
|
+
/** How many members were newly attributed by this request. */
|
|
1313
|
+
readonly attributed: number;
|
|
1314
|
+
/** One entry per member id supplied, in the order supplied. */
|
|
1315
|
+
readonly results: readonly Readonly<{
|
|
1316
|
+
memberId: number;
|
|
1317
|
+
outcome: AttributionOutcome;
|
|
1318
|
+
}>[];
|
|
1319
|
+
/** @internal */
|
|
1320
|
+
constructor(wire: AttributionResultWire);
|
|
1321
|
+
/** Member ids with the given outcome. */
|
|
1322
|
+
withOutcome(outcome: AttributionOutcome): readonly number[];
|
|
1323
|
+
/**
|
|
1324
|
+
* Members already credited to somebody. These are the ones worth a human
|
|
1325
|
+
* look — it may be your own host, or it may be another ambassador.
|
|
1326
|
+
*/
|
|
1327
|
+
get alreadyAttributed(): readonly number[];
|
|
1328
|
+
/**
|
|
1329
|
+
* Members rejected because their account pre-dates the event's registration
|
|
1330
|
+
* page. The event did not recruit them, so no credit is due.
|
|
1331
|
+
*/
|
|
1332
|
+
get predatedEvent(): readonly number[];
|
|
1333
|
+
}
|
|
1334
|
+
|
|
1335
|
+
/**
|
|
1336
|
+
* {@link ReferralsResource} — read and record ambassador referral credit.
|
|
1337
|
+
*
|
|
1338
|
+
* @module
|
|
1339
|
+
*/
|
|
1340
|
+
|
|
1341
|
+
/**
|
|
1342
|
+
* Read and record which ambassador earns referral credit for a player.
|
|
1343
|
+
*
|
|
1344
|
+
* Each method needs its own API-key permission, granted per partner:
|
|
1345
|
+
* `key:referral:read` for {@link get} and `key:referral:write` for
|
|
1346
|
+
* {@link attribute}. Neither is implied by a general read, write or admin key —
|
|
1347
|
+
* reading attribution exposes who recruited whom, and writing it decides who
|
|
1348
|
+
* earns commission.
|
|
1349
|
+
*
|
|
1350
|
+
* @category Resources
|
|
1351
|
+
*/
|
|
1352
|
+
declare class ReferralsResource {
|
|
1353
|
+
#private;
|
|
1354
|
+
/** @internal */
|
|
1355
|
+
constructor(http: HttpTransport);
|
|
1356
|
+
/**
|
|
1357
|
+
* Who currently earns referral credit for these members.
|
|
1358
|
+
*
|
|
1359
|
+
* Use this before {@link attribute} to tell the two cases apart that matter:
|
|
1360
|
+
* a member already credited to your own event host (nothing to do) and one
|
|
1361
|
+
* credited to a different ambassador (a person should look, because claiming
|
|
1362
|
+
* it takes credit from them).
|
|
1363
|
+
*
|
|
1364
|
+
* @example
|
|
1365
|
+
* ```ts
|
|
1366
|
+
* const result = await client.referrals.get([4873327, 4873328]);
|
|
1367
|
+
*
|
|
1368
|
+
* for (const a of result.claimable) {
|
|
1369
|
+
* console.log(a.memberId, 'has no credit yet');
|
|
1370
|
+
* }
|
|
1371
|
+
* console.log('no such member:', result.notFound);
|
|
1372
|
+
* ```
|
|
1373
|
+
*
|
|
1374
|
+
* @throws {@link ValidationError} If the list is empty or exceeds 100 ids.
|
|
1375
|
+
*/
|
|
1376
|
+
get(memberIds: readonly number[]): Promise<MembersAttributionResult>;
|
|
1377
|
+
/**
|
|
1378
|
+
* Credit an ambassador for players their event recruited.
|
|
1379
|
+
*
|
|
1380
|
+
* `registrationPublishedAt` is the date the event's registration page was
|
|
1381
|
+
* **first published**. Accounts created before it did not come from the event
|
|
1382
|
+
* and are rejected with `account_predates_event`. VAIR applies that rule
|
|
1383
|
+
* itself, so every partner is held to the same one.
|
|
1384
|
+
*
|
|
1385
|
+
* VAIR cannot verify the date — it holds no record of your registration pages —
|
|
1386
|
+
* so the value you send is recorded for audit. Send the real one.
|
|
1387
|
+
*
|
|
1388
|
+
* Safe to retry: attribution is one-per-player forever, enforced by the
|
|
1389
|
+
* database, so a resubmitted player returns `already_attributed` and nothing
|
|
1390
|
+
* changes.
|
|
1391
|
+
*
|
|
1392
|
+
* @example
|
|
1393
|
+
* ```ts
|
|
1394
|
+
* const result = await client.referrals.attribute({
|
|
1395
|
+
* referralCode: 'hillhurst-open',
|
|
1396
|
+
* registrationPublishedAt: '2026-08-01',
|
|
1397
|
+
* memberIds: [4873327, 4873328],
|
|
1398
|
+
* });
|
|
1399
|
+
*
|
|
1400
|
+
* console.log(result.attributed, 'newly credited');
|
|
1401
|
+
* console.log('need a human:', result.alreadyAttributed);
|
|
1402
|
+
* console.log('too old to credit:', result.predatedEvent);
|
|
1403
|
+
* ```
|
|
1404
|
+
*
|
|
1405
|
+
* @throws {@link ValidationError} If the list is empty or exceeds 500 ids, or
|
|
1406
|
+
* the date is not `YYYY-MM-DD`.
|
|
1407
|
+
*/
|
|
1408
|
+
attribute(input: {
|
|
1409
|
+
referralCode: string;
|
|
1410
|
+
registrationPublishedAt: string;
|
|
1411
|
+
memberIds: readonly number[];
|
|
1412
|
+
}): Promise<AttributionResult>;
|
|
1413
|
+
}
|
|
1414
|
+
|
|
1025
1415
|
/**
|
|
1026
1416
|
* {@link WebhookDelivery} and {@link WebhookDeliveriesResult} — webhook
|
|
1027
1417
|
* delivery inspection models.
|
|
@@ -1174,6 +1564,11 @@ declare class Vairified {
|
|
|
1174
1564
|
readonly leaderboard: LeaderboardResource;
|
|
1175
1565
|
/** Webhook delivery inspection — deliveries. */
|
|
1176
1566
|
readonly webhooks: WebhooksResource;
|
|
1567
|
+
/**
|
|
1568
|
+
* Read and record ambassador referral credit. Each method needs its own
|
|
1569
|
+
* per-partner permission — see {@link ReferralsResource}.
|
|
1570
|
+
*/
|
|
1571
|
+
readonly referrals: ReferralsResource;
|
|
1177
1572
|
constructor(options?: VairifiedOptions);
|
|
1178
1573
|
/**
|
|
1179
1574
|
* API usage statistics for the current API key.
|
|
@@ -1272,4 +1667,4 @@ declare class OAuthError extends VairifiedError {
|
|
|
1272
1667
|
constructor(message?: string, errorCode?: string, response?: unknown);
|
|
1273
1668
|
}
|
|
1274
1669
|
|
|
1275
|
-
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 };
|
|
1670
|
+
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, MemberEmailMatch, MemberSportMap, type MemberStatusWire, MembersByEmailResult, type MembersByEmailResultWire, MembersResource, NotFoundError, type OAuthConfig, OAuthError, OAuthResource, type OAuthScope, type PartnerMemberEmailMatchWire, 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 };
|