dupr-js-client 2.0.0 → 2.4.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/dist/index.d.ts +22 -5
- package/dist/index.js +10 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.d.ts
CHANGED
|
@@ -145,6 +145,16 @@ interface ClubMembershipResult {
|
|
|
145
145
|
clubs: ClubMembership[];
|
|
146
146
|
}
|
|
147
147
|
type ClubMembershipResponse = ApiWrapper<ClubMembershipResult>;
|
|
148
|
+
/** Club membership entry returned by the SSO user API (`GET /user/club/membership`). */
|
|
149
|
+
interface UserClubMembership {
|
|
150
|
+
clubId: number;
|
|
151
|
+
clubName: string;
|
|
152
|
+
role: string;
|
|
153
|
+
}
|
|
154
|
+
/** Response from `GET https://api.{env}.dupr.gg/user/club/membership` (SSO user API). */
|
|
155
|
+
interface UserClubMembershipResponse {
|
|
156
|
+
membership: UserClubMembership[];
|
|
157
|
+
}
|
|
148
158
|
interface ExternalSearchFilter {
|
|
149
159
|
gender?: Gender;
|
|
150
160
|
location?: ExternalFilterLocation;
|
|
@@ -233,7 +243,7 @@ interface ExternalMatchRequest {
|
|
|
233
243
|
/** Display-only bracket name. */
|
|
234
244
|
bracket?: string;
|
|
235
245
|
/** DUPR Club unique identifier. Required when matchSource is CLUB. */
|
|
236
|
-
clubId?: number;
|
|
246
|
+
clubId?: string | number;
|
|
237
247
|
/** Optional key-value metadata. */
|
|
238
248
|
extras?: Record<string, string>;
|
|
239
249
|
matchCompletionType?: MatchCompletionType;
|
|
@@ -261,7 +271,7 @@ interface ExternalUpdateMatchRequest {
|
|
|
261
271
|
/** Display-only bracket name. */
|
|
262
272
|
bracket?: string;
|
|
263
273
|
/** DUPR Club unique identifier. */
|
|
264
|
-
clubId?: number;
|
|
274
|
+
clubId?: string | number;
|
|
265
275
|
/** Optional key-value metadata. */
|
|
266
276
|
extras?: Record<string, string>;
|
|
267
277
|
matchCompletionType?: MatchCompletionType;
|
|
@@ -318,7 +328,7 @@ interface CreateEventRequestV1 {
|
|
|
318
328
|
startDate: string;
|
|
319
329
|
endDate: string;
|
|
320
330
|
location?: string;
|
|
321
|
-
clubId?: number;
|
|
331
|
+
clubId?: string | number;
|
|
322
332
|
}
|
|
323
333
|
interface UpdateEventRequestV1 {
|
|
324
334
|
eventId: string;
|
|
@@ -448,8 +458,15 @@ declare class UsersModule {
|
|
|
448
458
|
getUser(duprId: string): Promise<ApiWrapper<UserInfo>>;
|
|
449
459
|
/** GET /user/{version}/{id}/details — extended profile (requires USER_EMAIL::VIEW permission) */
|
|
450
460
|
getExtendedUser(duprId: string): Promise<ApiWrapper<ExtendedUserInfo>>;
|
|
451
|
-
/** GET /user/{version}/{id}/clubs — club memberships for a player */
|
|
461
|
+
/** GET /user/{version}/{id}/clubs — club memberships for a player (partner API, legacy) */
|
|
452
462
|
getClubMemberships(duprId: string): Promise<ClubMembershipResponse>;
|
|
463
|
+
/**
|
|
464
|
+
* GET /user/club/membership — club memberships for the authenticated user (SSO user API).
|
|
465
|
+
* Must be called against the SSO API base URL (e.g. https://api.uat.dupr.gg) with the
|
|
466
|
+
* user's SSO bearer token, NOT the partner API base URL.
|
|
467
|
+
* Returns `{ membership: [{ clubId: number, clubName: string, role: string }] }`.
|
|
468
|
+
*/
|
|
469
|
+
getMyClubMemberships(): Promise<UserClubMembershipResponse>;
|
|
453
470
|
/** POST /user/{version}/search — full-text player search with optional filters */
|
|
454
471
|
search(req: ExternalSearchRequest): Promise<ApiWrapper<UserInfo[]>>;
|
|
455
472
|
/** POST /user/{version}/batch — fetch multiple players by DUPR ID in one request */
|
|
@@ -617,4 +634,4 @@ declare class ServerError extends DuprApiError {
|
|
|
617
634
|
constructor(message: string, statusCode: number, details?: unknown, duprRequestId?: string);
|
|
618
635
|
}
|
|
619
636
|
|
|
620
|
-
export { type ApiStatus, type ApiWrapper, type AttributionRequest, type AuthCodeTokenResponse, type AuthMode, AuthModule, AuthenticationError, type AuthorizationUrlParams, type ClientHookRequest, type ClubMembership, type ClubMembershipResponse, ClubsModule, type CreateEventRequestV1, type CreateEventResponseV1, type CreateProvisionalRatingRequest, type DeleteEventRequestV1, type DeleteEventResponseV1, type DeleteProvisionalRatingRequest, DuprApiError, DuprClient, type DuprClientOptions, EventsModule, type ExtendedUserInfo, type ExternalAgeRangeFilter, type ExternalBatchUserDetailRequest, type ExternalClubMatchSearchRequest, type ExternalClubMemberRequest, type ExternalDeleteMatchRequest, type ExternalFilterLocation, type ExternalInviteRequest, type ExternalMatchRequest, type ExternalMatchSearchRequest, type ExternalMatchTeam, type ExternalRatingFilter, type ExternalSearchFilter, type ExternalSearchRequest, type ExternalUpdateMatchRequest, type Gender, type GetEventRequestV1, type GetEventResponseV1, type GetProvisionalRatingRequest, type GrantExternalSubscriptionRequest, type MatchCompletionType, type MatchFormat, type MatchPlayType, type MatchResponse, type MatchSource, type MatchType, MatchesModule, NotFoundError, PlayerRatingModule, type PlayerRatingSubscribeRequest, PlayersModule, RateLimitError, type RatingCoach, type RatingType, type RequestInfo, type ResolvedConfig, type ResolvedRetryOptions, type ResponseInfo, type RetryOptions, ServerError, type SsoTokenResponse, type SubscriptionItemRequest, type TargetUserRequest, type TokenResponse, type UpdateEventRequestV1, type UpdateEventResponseV1, type UpdateProvisionalRatingRequest, type UserInfo, type UserWebhookRequest, UsersModule, ValidationError, type WebhookSchema, type WebhookTopic, WebhooksModule };
|
|
637
|
+
export { type ApiStatus, type ApiWrapper, type AttributionRequest, type AuthCodeTokenResponse, type AuthMode, AuthModule, AuthenticationError, type AuthorizationUrlParams, type ClientHookRequest, type ClubMembership, type ClubMembershipResponse, ClubsModule, type CreateEventRequestV1, type CreateEventResponseV1, type CreateProvisionalRatingRequest, type DeleteEventRequestV1, type DeleteEventResponseV1, type DeleteProvisionalRatingRequest, DuprApiError, DuprClient, type DuprClientOptions, EventsModule, type ExtendedUserInfo, type ExternalAgeRangeFilter, type ExternalBatchUserDetailRequest, type ExternalClubMatchSearchRequest, type ExternalClubMemberRequest, type ExternalDeleteMatchRequest, type ExternalFilterLocation, type ExternalInviteRequest, type ExternalMatchRequest, type ExternalMatchSearchRequest, type ExternalMatchTeam, type ExternalRatingFilter, type ExternalSearchFilter, type ExternalSearchRequest, type ExternalUpdateMatchRequest, type Gender, type GetEventRequestV1, type GetEventResponseV1, type GetProvisionalRatingRequest, type GrantExternalSubscriptionRequest, type MatchCompletionType, type MatchFormat, type MatchPlayType, type MatchResponse, type MatchSource, type MatchType, MatchesModule, NotFoundError, PlayerRatingModule, type PlayerRatingSubscribeRequest, PlayersModule, RateLimitError, type RatingCoach, type RatingType, type RequestInfo, type ResolvedConfig, type ResolvedRetryOptions, type ResponseInfo, type RetryOptions, ServerError, type SsoTokenResponse, type SubscriptionItemRequest, type TargetUserRequest, type TokenResponse, type UpdateEventRequestV1, type UpdateEventResponseV1, type UpdateProvisionalRatingRequest, type UserClubMembership, type UserClubMembershipResponse, type UserInfo, type UserWebhookRequest, UsersModule, ValidationError, type WebhookSchema, type WebhookTopic, WebhooksModule };
|
package/dist/index.js
CHANGED
|
@@ -480,10 +480,19 @@ var UsersModule = class {
|
|
|
480
480
|
getExtendedUser(duprId) {
|
|
481
481
|
return this.http.get(`/user/${this.cfg.version}/${encodeURIComponent(duprId)}/details`);
|
|
482
482
|
}
|
|
483
|
-
/** GET /user/{version}/{id}/clubs — club memberships for a player */
|
|
483
|
+
/** GET /user/{version}/{id}/clubs — club memberships for a player (partner API, legacy) */
|
|
484
484
|
getClubMemberships(duprId) {
|
|
485
485
|
return this.http.get(`/user/${this.cfg.version}/${encodeURIComponent(duprId)}/clubs`);
|
|
486
486
|
}
|
|
487
|
+
/**
|
|
488
|
+
* GET /user/club/membership — club memberships for the authenticated user (SSO user API).
|
|
489
|
+
* Must be called against the SSO API base URL (e.g. https://api.uat.dupr.gg) with the
|
|
490
|
+
* user's SSO bearer token, NOT the partner API base URL.
|
|
491
|
+
* Returns `{ membership: [{ clubId: number, clubName: string, role: string }] }`.
|
|
492
|
+
*/
|
|
493
|
+
getMyClubMemberships() {
|
|
494
|
+
return this.http.get(`/user/club/membership`);
|
|
495
|
+
}
|
|
487
496
|
/** POST /user/{version}/search — full-text player search with optional filters */
|
|
488
497
|
search(req) {
|
|
489
498
|
return this.http.post(`/user/${this.cfg.version}/search`, req);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config.ts","../src/errors.ts","../src/http.ts","../src/auth.ts","../src/resources/users.ts","../src/resources/players.ts","../src/resources/playerRating.ts","../src/resources/matches.ts","../src/resources/clubs.ts","../src/resources/events.ts","../src/resources/webhooks.ts","../src/client.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["export type AuthMode =\r\n | { type: \"clientCredentials\"; clientKey: string; clientSecret: string }\r\n | { type: \"staticBearer\"; bearerToken: string }\r\n | { type: \"none\" };\r\n\r\nexport interface RequestInfo {\r\n method: string;\r\n url: string;\r\n headers: Record<string, string>;\r\n}\r\n\r\nexport interface ResponseInfo {\r\n status: number;\r\n url: string;\r\n durationMs: number;\r\n}\r\n\r\nexport interface RetryOptions {\r\n /** Max number of retry attempts after the initial failure. @default 3 */\r\n maxRetries?: number;\r\n /** Base delay in ms before the first retry. Doubles on each attempt. @default 1_000 */\r\n baseDelayMs?: number;\r\n /** Max delay cap in ms (prevents infinite backoff). @default 30_000 */\r\n maxDelayMs?: number;\r\n}\r\n\r\nexport interface DuprClientOptions {\r\n /** @default \"https://uat.mydupr.com/api\" */\r\n baseUrl?: string;\r\n /** API version prefix used in all paths. @default \"v1.0\" */\r\n version?: string;\r\n /** Request timeout in milliseconds. @default 30_000 */\r\n timeoutMs?: number;\r\n auth?: AuthMode;\r\n /** Custom User-Agent header. */\r\n userAgent?: string;\r\n /** Inject a custom fetch implementation (useful for testing or polyfilling). */\r\n customFetch?: typeof fetch;\r\n /** Called before every request. Useful for logging or tracing. */\r\n onRequest?: (info: RequestInfo) => void;\r\n /** Called after every response (including errors). */\r\n onResponse?: (info: ResponseInfo) => void;\r\n /** Retry behaviour for transient errors (5xx, network failures, 429). Pass `false` to disable. */\r\n retry?: RetryOptions | false;\r\n /**\r\n * Base URL for the DUPR SSO iframe login widget.\r\n * UAT: \"https://uat.dupr.gg\"\r\n * Prod: \"https://dashboard.dupr.com\"\r\n * Required to call `client.auth.getSsoIframeUrl()`.\r\n */\r\n ssoBaseUrl?: string;\r\n /**\r\n * Base URL for refreshing DUPR SSO user tokens — a separate host from the Partner API.\r\n * UAT: \"https://api.uat.dupr.gg\"\r\n * Prod: \"https://api.dupr.gg\"\r\n * Required to call `client.auth.refreshSsoToken()`.\r\n */\r\n ssoRefreshBaseUrl?: string;\r\n /**\r\n * Authorization endpoint URL for the OAuth 2.0 authorization code flow.\r\n * Confirm the exact value with DUPR support before use.\r\n * Required to call `client.auth.getAuthorizationUrl()`.\r\n */\r\n authorizationUrl?: string;\r\n}\r\n\r\nexport interface ResolvedRetryOptions {\r\n maxRetries: number;\r\n baseDelayMs: number;\r\n maxDelayMs: number;\r\n}\r\n\r\nexport interface ResolvedConfig {\r\n baseUrl: string;\r\n version: string;\r\n timeoutMs: number;\r\n auth: AuthMode;\r\n userAgent: string;\r\n customFetch: typeof fetch;\r\n retry: ResolvedRetryOptions | false;\r\n onRequest?: (info: RequestInfo) => void;\r\n onResponse?: (info: ResponseInfo) => void;\r\n /** Runtime override for the bearer token — set via `client.setBearerToken()`. */\r\n overrideBearerToken?: string;\r\n ssoBaseUrl?: string;\r\n ssoRefreshBaseUrl?: string;\r\n authorizationUrl?: string;\r\n}\r\n\r\nexport function resolveConfig(opts: DuprClientOptions): ResolvedConfig {\r\n const cfg: ResolvedConfig = {\r\n baseUrl: opts.baseUrl ?? \"https://uat.mydupr.com/api\",\r\n version: opts.version ?? \"v1.0\",\r\n timeoutMs: opts.timeoutMs ?? 30_000,\r\n auth: opts.auth ?? { type: \"none\" },\r\n userAgent: opts.userAgent ?? \"dupr-js-client/0.1.0\",\r\n customFetch: opts.customFetch ?? globalThis.fetch.bind(globalThis),\r\n retry:\r\n opts.retry === false\r\n ? false\r\n : {\r\n maxRetries: opts.retry?.maxRetries ?? 3,\r\n baseDelayMs: opts.retry?.baseDelayMs ?? 1_000,\r\n maxDelayMs: opts.retry?.maxDelayMs ?? 30_000,\r\n },\r\n };\r\n if (opts.onRequest) cfg.onRequest = opts.onRequest;\r\n if (opts.onResponse) cfg.onResponse = opts.onResponse;\r\n if (opts.ssoBaseUrl) cfg.ssoBaseUrl = opts.ssoBaseUrl;\r\n if (opts.ssoRefreshBaseUrl) cfg.ssoRefreshBaseUrl = opts.ssoRefreshBaseUrl;\r\n if (opts.authorizationUrl) cfg.authorizationUrl = opts.authorizationUrl;\r\n return cfg;\r\n}\r\n","export class DuprApiError extends Error {\r\n constructor(\r\n message: string,\r\n public readonly statusCode: number,\r\n public readonly details?: unknown,\r\n public readonly duprRequestId?: string,\r\n ) {\r\n super(message);\r\n this.name = \"DuprApiError\";\r\n // Maintain proper prototype chain in transpiled environments\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n }\r\n}\r\n\r\nexport class AuthenticationError extends DuprApiError {\r\n constructor(message: string, statusCode: number, details?: unknown, duprRequestId?: string) {\r\n super(message, statusCode, details, duprRequestId);\r\n this.name = \"AuthenticationError\";\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n }\r\n}\r\n\r\nexport class ValidationError extends DuprApiError {\r\n constructor(message: string, statusCode: number, details?: unknown, duprRequestId?: string) {\r\n super(message, statusCode, details, duprRequestId);\r\n this.name = \"ValidationError\";\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n }\r\n}\r\n\r\nexport class NotFoundError extends DuprApiError {\r\n constructor(message: string, statusCode: number, details?: unknown, duprRequestId?: string) {\r\n super(message, statusCode, details, duprRequestId);\r\n this.name = \"NotFoundError\";\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n }\r\n}\r\n\r\nexport class RateLimitError extends DuprApiError {\r\n constructor(message: string, statusCode: number, details?: unknown, duprRequestId?: string) {\r\n super(message, statusCode, details, duprRequestId);\r\n this.name = \"RateLimitError\";\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n }\r\n}\r\n\r\nexport class ServerError extends DuprApiError {\r\n constructor(message: string, statusCode: number, details?: unknown, duprRequestId?: string) {\r\n super(message, statusCode, details, duprRequestId);\r\n this.name = \"ServerError\";\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n }\r\n}\r\n\r\nexport async function buildError(res: Response): Promise<DuprApiError> {\r\n let body: unknown;\r\n const requestId = res.headers.get(\"x-request-id\") ?? res.headers.get(\"x-dupr-request-id\") ?? undefined;\r\n\r\n try {\r\n body = await res.json();\r\n } catch {\r\n // non-JSON body — leave body undefined\r\n }\r\n\r\n const msg =\r\n (typeof body === \"object\" && body !== null && \"message\" in body && typeof (body as Record<string, unknown>)[\"message\"] === \"string\"\r\n ? (body as Record<string, unknown>)[\"message\"] as string\r\n : null) ??\r\n `DUPR API error ${res.status}`;\r\n\r\n switch (true) {\r\n case res.status === 401 || res.status === 403:\r\n return new AuthenticationError(msg, res.status, body, requestId);\r\n case res.status === 404:\r\n return new NotFoundError(msg, res.status, body, requestId);\r\n case res.status === 400:\r\n return new ValidationError(msg, res.status, body, requestId);\r\n case res.status === 429:\r\n return new RateLimitError(msg, res.status, body, requestId);\r\n case res.status >= 500:\r\n return new ServerError(msg, res.status, body, requestId);\r\n default:\r\n return new DuprApiError(msg, res.status, body, requestId);\r\n }\r\n}\r\n","import { ResolvedConfig } from \"./config.js\";\r\nimport { AuthenticationError, buildError, RateLimitError, ServerError } from \"./errors.js\";\r\nimport type { TokenResponse } from \"./types.js\";\r\n\r\nfunction sleep(ms: number): Promise<void> {\r\n return new Promise((resolve) => setTimeout(resolve, ms));\r\n}\r\n\r\nfunction retryDelayMs(attempt: number, baseDelayMs: number, maxDelayMs: number): number {\r\n // Exponential backoff with ±20% jitter to avoid thundering herd\r\n const exp = Math.min(baseDelayMs * 2 ** attempt, maxDelayMs);\r\n return exp * (0.8 + Math.random() * 0.4);\r\n}\r\n\r\nfunction isRetryable(err: unknown): boolean {\r\n if (err instanceof RateLimitError) return true;\r\n if (err instanceof ServerError) return true;\r\n // Network-level failures (fetch throws a TypeError on connection refused etc.)\r\n if (err instanceof TypeError) return true;\r\n return false;\r\n}\r\n\r\nexport class HttpClient {\r\n private token: string | null = null;\r\n private tokenExpiresAt = 0;\r\n\r\n constructor(private readonly config: ResolvedConfig) {}\r\n\r\n private async getBearerToken(): Promise<string> {\r\n if (this.config.overrideBearerToken) {\r\n return this.config.overrideBearerToken;\r\n }\r\n if (this.config.auth.type === \"staticBearer\") {\r\n return this.config.auth.bearerToken;\r\n }\r\n if (this.config.auth.type !== \"clientCredentials\") {\r\n throw new AuthenticationError(\"No auth configured — set auth in DuprClientOptions or call setBearerToken()\", 401);\r\n }\r\n\r\n if (this.token && Date.now() < this.tokenExpiresAt) {\r\n return this.token;\r\n }\r\n\r\n const { clientKey, clientSecret } = this.config.auth;\r\n const encoded = Buffer.from(`${clientKey}:${clientSecret}`).toString(\"base64\");\r\n const url = `${this.config.baseUrl}/auth/${this.config.version}/token`;\r\n\r\n const start = Date.now();\r\n const res = await this.config.customFetch(url, {\r\n method: \"POST\",\r\n headers: {\r\n \"x-authorization\": encoded,\r\n \"User-Agent\": this.config.userAgent,\r\n },\r\n signal: AbortSignal.timeout(this.config.timeoutMs),\r\n });\r\n\r\n this.config.onResponse?.({ status: res.status, url, durationMs: Date.now() - start });\r\n\r\n if (!res.ok) throw await buildError(res);\r\n\r\n const body = await res.json() as TokenResponse;\r\n // The Partner API wraps the token in result: { token, expiry }.\r\n // Older/alternate environments return it at the top level — handle both.\r\n this.token = body.result?.token ?? body.token ?? body.accessToken ?? null;\r\n if (!this.token) throw new AuthenticationError(\"Token response contained no token\", 401);\r\n\r\n if (body.result?.expiry) {\r\n // expiry is an ISO datetime string; subtract 60s buffer\r\n this.tokenExpiresAt = new Date(body.result.expiry).getTime() - 60_000;\r\n } else {\r\n const ttlSec = body.expiresIn ?? 3600;\r\n this.tokenExpiresAt = Date.now() + (ttlSec - 60) * 1000;\r\n }\r\n return this.token;\r\n }\r\n\r\n async get<T>(path: string, init?: RequestInit): Promise<T> {\r\n return this.request<T>(\"GET\", path, init);\r\n }\r\n\r\n async post<T>(path: string, body?: unknown, init?: RequestInit): Promise<T> {\r\n const extra: RequestInit = { headers: { \"Content-Type\": \"application/json\", ...(init?.headers ?? {}) } };\r\n if (body !== undefined) extra.body = JSON.stringify(body);\r\n return this.request<T>(\"POST\", path, { ...init, ...extra });\r\n }\r\n\r\n async delete<T>(path: string, body?: unknown, init?: RequestInit): Promise<T> {\r\n const extra: RequestInit = { headers: { \"Content-Type\": \"application/json\", ...(init?.headers ?? {}) } };\r\n if (body !== undefined) extra.body = JSON.stringify(body);\r\n return this.request<T>(\"DELETE\", path, { ...init, ...extra });\r\n }\r\n\r\n async request<T>(method: string, path: string, init?: RequestInit): Promise<T> {\r\n const retryCfg = this.config.retry;\r\n const maxAttempts = retryCfg === false ? 1 : retryCfg.maxRetries + 1;\r\n\r\n let lastErr: unknown;\r\n\r\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\r\n try {\r\n return await this.rawRequest<T>(method, path, init);\r\n } catch (err) {\r\n lastErr = err;\r\n\r\n if (attempt >= maxAttempts - 1) break;\r\n if (!isRetryable(err)) break;\r\n if (retryCfg === false) break;\r\n\r\n let delay: number;\r\n if (err instanceof RateLimitError) {\r\n // Honor Retry-After header (value in seconds)\r\n const retryAfterSec =\r\n err.details !== null &&\r\n typeof err.details === \"object\" &&\r\n \"retryAfterSeconds\" in (err.details as object)\r\n ? Number((err.details as { retryAfterSeconds: unknown }).retryAfterSeconds)\r\n : NaN;\r\n delay = Number.isFinite(retryAfterSec) && retryAfterSec > 0\r\n ? retryAfterSec * 1000\r\n : retryDelayMs(attempt, retryCfg.baseDelayMs, retryCfg.maxDelayMs);\r\n } else {\r\n delay = retryDelayMs(attempt, retryCfg.baseDelayMs, retryCfg.maxDelayMs);\r\n }\r\n\r\n await sleep(delay);\r\n }\r\n }\r\n\r\n throw lastErr;\r\n }\r\n\r\n private async rawRequest<T>(method: string, path: string, init?: RequestInit): Promise<T> {\r\n const token = await this.getBearerToken();\r\n const url = `${this.config.baseUrl}${path}`;\r\n\r\n const headers: Record<string, string> = {\r\n Authorization: `Bearer ${token}`,\r\n \"User-Agent\": this.config.userAgent,\r\n ...(init?.headers as Record<string, string> | undefined ?? {}),\r\n };\r\n\r\n const { Authorization: _redacted, ...hookHeaders } = headers;\r\n this.config.onRequest?.({ method, url, headers: hookHeaders });\r\n\r\n const start = Date.now();\r\n const res = await this.config.customFetch(url, {\r\n method,\r\n ...init,\r\n headers,\r\n signal: AbortSignal.timeout(this.config.timeoutMs),\r\n });\r\n\r\n this.config.onResponse?.({ status: res.status, url, durationMs: Date.now() - start });\r\n\r\n if (!res.ok) {\r\n const err = await buildError(res);\r\n // Attach Retry-After from the response header so the retry loop can read it\r\n if (err instanceof RateLimitError) {\r\n const retryAfter = res.headers.get(\"Retry-After\");\r\n if (retryAfter) {\r\n (err as RateLimitError & { details: unknown }).details =\r\n typeof err.details === \"object\" && err.details !== null\r\n ? { ...err.details as object, retryAfterSeconds: Number(retryAfter) }\r\n : { retryAfterSeconds: Number(retryAfter) };\r\n }\r\n }\r\n throw err;\r\n }\r\n\r\n // Some endpoints return 204 No Content\r\n if (res.status === 204 || res.headers.get(\"content-length\") === \"0\") {\r\n return undefined as T;\r\n }\r\n\r\n return res.json() as Promise<T>;\r\n }\r\n}\r\n","import { createHash, randomBytes } from \"crypto\";\r\nimport { HttpClient } from \"./http.js\";\r\nimport { ResolvedConfig } from \"./config.js\";\r\nimport { AuthenticationError } from \"./errors.js\";\r\nimport { TokenResponse } from \"./types.js\";\r\n\r\nexport interface AuthCodeTokenResponse extends TokenResponse {\r\n refresh_token?: string;\r\n token_type?: string;\r\n scope?: string;\r\n}\r\n\r\n/** Response from `client.auth.refreshSsoToken()`. Both tokens are always present — DUPR rotates refresh tokens on every use. */\r\nexport interface SsoTokenResponse {\r\n accessToken: string;\r\n refreshToken: string;\r\n /** Seconds until the access token expires, if provided by DUPR. */\r\n expiresIn?: number;\r\n}\r\n\r\nexport interface AuthorizationUrlParams {\r\n /** Your OAuth redirect URI, must match what is registered with DUPR. */\r\n redirectUri: string;\r\n /** OAuth scopes to request (e.g. [\"user.read\"]). Defaults to empty. */\r\n scopes?: string[];\r\n /** Opaque value passed through the flow to prevent CSRF. Recommended. */\r\n state?: string;\r\n /** PKCE code_challenge (S256). Generate the pair with `client.auth.generatePkce()`. */\r\n codeChallenge?: string;\r\n}\r\n\r\nexport class AuthModule {\r\n constructor(\r\n private readonly http: HttpClient,\r\n private readonly config: ResolvedConfig,\r\n ) {}\r\n\r\n /**\r\n * Explicitly request a new access token using client credentials.\r\n * Normally you don't need to call this — the HTTP client handles token refresh automatically.\r\n */\r\n async getToken(): Promise<TokenResponse> {\r\n if (this.config.auth.type !== \"clientCredentials\") {\r\n throw new AuthenticationError(\"getToken() requires clientCredentials auth mode\", 401);\r\n }\r\n const { clientKey, clientSecret } = this.config.auth;\r\n const encoded = Buffer.from(`${clientKey}:${clientSecret}`).toString(\"base64\");\r\n const url = `${this.config.baseUrl}/auth/${this.config.version}/token`;\r\n\r\n const res = await this.config.customFetch(url, {\r\n method: \"POST\",\r\n headers: {\r\n \"x-authorization\": encoded,\r\n \"User-Agent\": this.config.userAgent,\r\n },\r\n signal: AbortSignal.timeout(this.config.timeoutMs),\r\n });\r\n\r\n if (!res.ok) {\r\n const body = await res.json().catch(() => undefined) as Record<string, unknown> | undefined;\r\n throw new AuthenticationError(\r\n (body?.[\"message\"] as string | undefined) ?? `Auth failed: ${res.status}`,\r\n res.status,\r\n body,\r\n );\r\n }\r\n\r\n return res.json() as Promise<TokenResponse>;\r\n }\r\n\r\n // ── Authorization Code Flow ───────────────────────────────────────────────\r\n //\r\n // Use this flow to let end-users authorise your app to act on their behalf\r\n // (e.g. the \"Connect DUPR\" button). The user is redirected to DUPR's login\r\n // page, then back to your redirectUri with an authorization code.\r\n //\r\n // NOTE: This requires a DUPR OAuth application with an authorization endpoint\r\n // separate from the Partner API client credentials. Confirm the exact\r\n // authorization URL with DUPR support.\r\n //\r\n // Typical flow:\r\n // 1. client.auth.getAuthorizationUrl({ redirectUri, state }) → redirect user\r\n // 2. User approves → DUPR calls back to redirectUri?code=xxx&state=yyy\r\n // 3. client.auth.exchangeCode({ code, redirectUri }) → tokens\r\n // 4. Store access_token + refresh_token; call client.setBearerToken(access_token)\r\n // 5. When access_token expires: client.auth.refreshToken(refresh_token)\r\n\r\n /** Generate a PKCE `code_verifier` + `code_challenge` pair (S256 method).\r\n * Pass `codeChallenge` to `getAuthorizationUrl()` and `codeVerifier` to `exchangeCode()`. */\r\n generatePkce(): { codeVerifier: string; codeChallenge: string } {\r\n const codeVerifier = randomBytes(32).toString(\"base64url\");\r\n const codeChallenge = createHash(\"sha256\").update(codeVerifier).digest(\"base64url\");\r\n return { codeVerifier, codeChallenge };\r\n }\r\n\r\n /**\r\n * Build the DUPR authorization URL to redirect the user to for login.\r\n * The `authorizationUrl` config option must be set (see above note).\r\n * Pass `codeChallenge` (from `generatePkce()`) to enable PKCE.\r\n */\r\n getAuthorizationUrl(params: AuthorizationUrlParams): string {\r\n if (!this.config.authorizationUrl) {\r\n throw new Error(\r\n \"authorizationUrl is not configured. Pass it in DuprClientOptions to use the Authorization Code flow.\",\r\n );\r\n }\r\n const url = new URL(this.config.authorizationUrl);\r\n const clientId = this.config.auth.type === \"clientCredentials\" ? this.config.auth.clientKey : \"\";\r\n url.searchParams.set(\"response_type\", \"code\");\r\n url.searchParams.set(\"client_id\", clientId);\r\n url.searchParams.set(\"redirect_uri\", params.redirectUri);\r\n if (params.scopes?.length) url.searchParams.set(\"scope\", params.scopes.join(\" \"));\r\n if (params.state) url.searchParams.set(\"state\", params.state);\r\n if (params.codeChallenge) {\r\n url.searchParams.set(\"code_challenge\", params.codeChallenge);\r\n url.searchParams.set(\"code_challenge_method\", \"S256\");\r\n }\r\n return url.toString();\r\n }\r\n\r\n /**\r\n * Exchange an authorization code (from the OAuth callback) for access + refresh tokens.\r\n * Uses `POST /auth/{version}/token` with `grant_type=authorization_code`.\r\n */\r\n async exchangeCode(params: {\r\n code: string;\r\n redirectUri: string;\r\n /** PKCE code_verifier. Required if `codeChallenge` was passed to `getAuthorizationUrl()`. */\r\n codeVerifier?: string;\r\n }): Promise<AuthCodeTokenResponse> {\r\n if (this.config.auth.type !== \"clientCredentials\") {\r\n throw new AuthenticationError(\"exchangeCode() requires clientCredentials auth configured with clientKey/clientSecret\", 401);\r\n }\r\n const { clientKey, clientSecret } = this.config.auth;\r\n const url = `${this.config.baseUrl}/auth/${this.config.version}/token`;\r\n const body = new URLSearchParams({\r\n grant_type: \"authorization_code\",\r\n code: params.code,\r\n redirect_uri: params.redirectUri,\r\n client_id: clientKey,\r\n client_secret: clientSecret,\r\n });\r\n if (params.codeVerifier) body.set(\"code_verifier\", params.codeVerifier);\r\n\r\n const res = await this.config.customFetch(url, {\r\n method: \"POST\",\r\n headers: {\r\n \"Content-Type\": \"application/x-www-form-urlencoded\",\r\n \"User-Agent\": this.config.userAgent,\r\n },\r\n body: body.toString(),\r\n signal: AbortSignal.timeout(this.config.timeoutMs),\r\n });\r\n\r\n if (!res.ok) {\r\n const errBody = await res.json().catch(() => undefined) as Record<string, unknown> | undefined;\r\n throw new AuthenticationError(\r\n (errBody?.[\"message\"] as string | undefined) ?? `Code exchange failed: ${res.status}`,\r\n res.status,\r\n errBody,\r\n );\r\n }\r\n\r\n return res.json() as Promise<AuthCodeTokenResponse>;\r\n }\r\n\r\n // ── SSO Iframe Flow ───────────────────────────────────────────────────────\r\n //\r\n // DUPR's documented SSO approach for user-facing login uses an embedded iframe\r\n // rather than a standard OAuth2 redirect. The iframe emits a window.postMessage\r\n // event upon successful login.\r\n //\r\n // Typical flow:\r\n // 1. client.auth.getSsoIframeUrl() → embed in <iframe allow=\"payment\">\r\n // 2. User logs in inside the iframe\r\n // 3. Listen for window.postMessage → { userToken, refreshToken, id, duprId, stats }\r\n // 4. Store userToken + refreshToken server-side; record tokenExpiresAt\r\n // (7 days UAT / 30 days prod — not returned in the event, apply based on env)\r\n // 5. When userToken nears expiry: client.auth.refreshSsoToken(refreshToken)\r\n // DUPR rotates refresh tokens — store both returned tokens.\r\n //\r\n // UAT iframe host: https://uat.dupr.gg\r\n // Prod iframe host: https://dashboard.dupr.com\r\n // Always validate window.postMessage origin against the expected host.\r\n\r\n /**\r\n * Returns the DUPR SSO iframe URL. Embed this in an `<iframe allow=\"payment\">` to\r\n * display the DUPR login widget. Requires `ssoBaseUrl` in `DuprClientOptions`.\r\n */\r\n getSsoIframeUrl(): string {\r\n if (!this.config.ssoBaseUrl) {\r\n throw new Error(\r\n \"ssoBaseUrl is not configured. Pass it in DuprClientOptions to use the SSO iframe flow.\",\r\n );\r\n }\r\n if (this.config.auth.type !== \"clientCredentials\") {\r\n throw new AuthenticationError(\r\n \"getSsoIframeUrl() requires clientCredentials auth mode\",\r\n 401,\r\n );\r\n }\r\n const encoded = Buffer.from(this.config.auth.clientKey).toString(\"base64\");\r\n return `${this.config.ssoBaseUrl}/login-external-app/${encoded}`;\r\n }\r\n\r\n /**\r\n * Refresh a DUPR SSO user token obtained from the iframe login `postMessage` event.\r\n * Uses a separate refresh endpoint on `ssoRefreshBaseUrl` (distinct from the Partner API).\r\n * Requires `ssoRefreshBaseUrl` in `DuprClientOptions`.\r\n *\r\n * DUPR rotates refresh tokens on every use — always store both `accessToken` and\r\n * `refreshToken` from the response.\r\n */\r\n async refreshSsoToken(refreshToken: string): Promise<SsoTokenResponse> {\r\n if (!this.config.ssoRefreshBaseUrl) {\r\n throw new Error(\r\n \"ssoRefreshBaseUrl is not configured. Pass it in DuprClientOptions to use SSO token refresh.\",\r\n );\r\n }\r\n const res = await this.config.customFetch(\r\n `${this.config.ssoRefreshBaseUrl}/api/auth/refreshAccessToken`,\r\n {\r\n method: \"POST\",\r\n headers: {\r\n \"Content-Type\": \"application/json\",\r\n \"User-Agent\": this.config.userAgent,\r\n },\r\n body: JSON.stringify({ refreshToken }),\r\n signal: AbortSignal.timeout(this.config.timeoutMs),\r\n },\r\n );\r\n\r\n if (!res.ok) {\r\n const errBody = await res.json().catch(() => undefined) as Record<string, unknown> | undefined;\r\n throw new AuthenticationError(\r\n (errBody?.[\"message\"] as string | undefined) ?? `SSO token refresh failed: ${res.status}`,\r\n res.status,\r\n errBody,\r\n );\r\n }\r\n\r\n const data = await res.json() as Record<string, unknown>;\r\n const accessToken = (data[\"accessToken\"] ?? data[\"userToken\"]) as string | undefined;\r\n const newRefreshToken = data[\"refreshToken\"] as string | undefined;\r\n\r\n if (!accessToken) {\r\n throw new AuthenticationError(\"SSO token refresh response missing accessToken\", 502);\r\n }\r\n if (!newRefreshToken) {\r\n throw new AuthenticationError(\r\n \"SSO token refresh response missing refreshToken — DUPR token rotation failed\",\r\n 502,\r\n );\r\n }\r\n\r\n return {\r\n accessToken,\r\n refreshToken: newRefreshToken,\r\n ...(data[\"expiresIn\"] !== undefined && { expiresIn: data[\"expiresIn\"] as number }),\r\n };\r\n }\r\n\r\n /**\r\n * Obtain a new access token using a refresh token from a previous Authorization Code flow.\r\n * Uses `POST /auth/{version}/token` with `grant_type=refresh_token`.\r\n */\r\n async refreshToken(refreshToken: string): Promise<AuthCodeTokenResponse> {\r\n if (this.config.auth.type !== \"clientCredentials\") {\r\n throw new AuthenticationError(\"refreshToken() requires clientCredentials auth configured\", 401);\r\n }\r\n const { clientKey, clientSecret } = this.config.auth;\r\n const url = `${this.config.baseUrl}/auth/${this.config.version}/token`;\r\n const body = new URLSearchParams({\r\n grant_type: \"refresh_token\",\r\n refresh_token: refreshToken,\r\n client_id: clientKey,\r\n client_secret: clientSecret,\r\n });\r\n\r\n const res = await this.config.customFetch(url, {\r\n method: \"POST\",\r\n headers: {\r\n \"Content-Type\": \"application/x-www-form-urlencoded\",\r\n \"User-Agent\": this.config.userAgent,\r\n },\r\n body: body.toString(),\r\n signal: AbortSignal.timeout(this.config.timeoutMs),\r\n });\r\n\r\n if (!res.ok) {\r\n const errBody = await res.json().catch(() => undefined) as Record<string, unknown> | undefined;\r\n throw new AuthenticationError(\r\n (errBody?.[\"message\"] as string | undefined) ?? `Token refresh failed: ${res.status}`,\r\n res.status,\r\n errBody,\r\n );\r\n }\r\n\r\n return res.json() as Promise<AuthCodeTokenResponse>;\r\n }\r\n}\r\n","import { HttpClient } from \"../http.js\";\r\nimport { ResolvedConfig } from \"../config.js\";\r\nimport {\r\n ApiWrapper,\r\n ClubMembershipResponse,\r\n CreateProvisionalRatingRequest,\r\n DeleteProvisionalRatingRequest,\r\n ExtendedUserInfo,\r\n ExternalBatchUserDetailRequest,\r\n ExternalInviteRequest,\r\n ExternalSearchRequest,\r\n GetProvisionalRatingRequest,\r\n GrantExternalSubscriptionRequest,\r\n UpdateProvisionalRatingRequest,\r\n UserInfo,\r\n} from \"../types.js\";\r\n\r\nexport class UsersModule {\r\n constructor(\r\n private readonly http: HttpClient,\r\n private readonly cfg: ResolvedConfig,\r\n ) {}\r\n\r\n /** GET /user/{version}/{id} — basic player profile */\r\n getUser(duprId: string): Promise<ApiWrapper<UserInfo>> {\r\n return this.http.get(`/user/${this.cfg.version}/${encodeURIComponent(duprId)}`);\r\n }\r\n\r\n /** GET /user/{version}/{id}/details — extended profile (requires USER_EMAIL::VIEW permission) */\r\n getExtendedUser(duprId: string): Promise<ApiWrapper<ExtendedUserInfo>> {\r\n return this.http.get(`/user/${this.cfg.version}/${encodeURIComponent(duprId)}/details`);\r\n }\r\n\r\n /** GET /user/{version}/{id}/clubs — club memberships for a player */\r\n getClubMemberships(duprId: string): Promise<ClubMembershipResponse> {\r\n return this.http.get(`/user/${this.cfg.version}/${encodeURIComponent(duprId)}/clubs`);\r\n }\r\n\r\n /** POST /user/{version}/search — full-text player search with optional filters */\r\n search(req: ExternalSearchRequest): Promise<ApiWrapper<UserInfo[]>> {\r\n return this.http.post(`/user/${this.cfg.version}/search`, req);\r\n }\r\n\r\n /** POST /user/{version}/batch — fetch multiple players by DUPR ID in one request */\r\n getBatch(req: ExternalBatchUserDetailRequest): Promise<ApiWrapper<UserInfo[]>> {\r\n return this.http.post(`/user/${this.cfg.version}/batch`, req);\r\n }\r\n\r\n /** POST /user/{version}/invite — pre-generate a DUPR ID and send an invite email */\r\n invite(req: ExternalInviteRequest): Promise<ApiWrapper<{ duprId: string }>> {\r\n return this.http.post(`/user/${this.cfg.version}/invite`, req);\r\n }\r\n\r\n /** POST /user/{version}/subscription/grants — grant a subscription to a user */\r\n grantSubscription(req: GrantExternalSubscriptionRequest): Promise<ApiWrapper> {\r\n return this.http.post(`/user/${this.cfg.version}/subscription/grants`, req);\r\n }\r\n\r\n // ── Provisional ratings ──────────────────────────────────────\r\n\r\n /** POST /user/{version}/provisional_rating — get provisional ratings for a player */\r\n getProvisionalRating(req: GetProvisionalRatingRequest): Promise<ApiWrapper> {\r\n return this.http.post(`/user/${this.cfg.version}/provisional_rating`, req);\r\n }\r\n\r\n /** POST /user/{version}/provisional_rating/create */\r\n createProvisionalRating(req: CreateProvisionalRatingRequest): Promise<ApiWrapper> {\r\n return this.http.post(`/user/${this.cfg.version}/provisional_rating/create`, req);\r\n }\r\n\r\n /** POST /user/{version}/provisional_rating/update */\r\n updateProvisionalRating(req: UpdateProvisionalRatingRequest): Promise<ApiWrapper> {\r\n return this.http.post(`/user/${this.cfg.version}/provisional_rating/update`, req);\r\n }\r\n\r\n /** DELETE /user/{version}/provisional_rating/delete */\r\n deleteProvisionalRating(req: DeleteProvisionalRatingRequest): Promise<ApiWrapper> {\r\n return this.http.delete(`/user/${this.cfg.version}/provisional_rating/delete`, req);\r\n }\r\n}\r\n","import { HttpClient } from \"../http.js\";\r\nimport { ResolvedConfig } from \"../config.js\";\r\nimport { ApiWrapper } from \"../types.js\";\r\n\r\nexport interface GetDuprIdByEmailRequest {\r\n email: string;\r\n}\r\n\r\nexport interface DuprIdByEmailResponse {\r\n duprId?: string;\r\n}\r\n\r\nexport class PlayersModule {\r\n constructor(\r\n private readonly http: HttpClient,\r\n private readonly cfg: ResolvedConfig,\r\n ) {}\r\n\r\n /** POST /{version}/player/duprid-by-email — resolve a DUPR ID from an email address */\r\n getDuprIdByEmail(req: GetDuprIdByEmailRequest): Promise<ApiWrapper<DuprIdByEmailResponse>> {\r\n return this.http.post(`/${this.cfg.version}/player/duprid-by-email`, req);\r\n }\r\n}\r\n","import { HttpClient } from \"../http.js\";\r\nimport { ResolvedConfig } from \"../config.js\";\r\nimport { ApiWrapper, PlayerRatingSubscribeRequest } from \"../types.js\";\r\n\r\nexport interface PlayerRatingHistoryRequest {\r\n duprId: string;\r\n offset?: number;\r\n limit?: number;\r\n}\r\n\r\nexport interface PlayerRatingHistoryEntry {\r\n date?: string;\r\n singlesRating?: number;\r\n doublesRating?: number;\r\n}\r\n\r\nexport class PlayerRatingModule {\r\n constructor(\r\n private readonly http: HttpClient,\r\n private readonly cfg: ResolvedConfig,\r\n ) {}\r\n\r\n /** POST /history — get rating history for a player */\r\n getHistory(req: PlayerRatingHistoryRequest): Promise<ApiWrapper<PlayerRatingHistoryEntry[]>> {\r\n return this.http.post(`/history`, req);\r\n }\r\n\r\n /** GET /{version}/subscribe/rating-changes — list currently subscribed DUPR IDs */\r\n getSubscriptions(): Promise<ApiWrapper<{ duprIds: string[] }>> {\r\n return this.http.get(`/${this.cfg.version}/subscribe/rating-changes`);\r\n }\r\n\r\n /** POST /{version}/subscribe/rating-changes — subscribe to rating-change events for a list of players */\r\n subscribe(req: PlayerRatingSubscribeRequest): Promise<ApiWrapper> {\r\n return this.http.post(`/${this.cfg.version}/subscribe/rating-changes`, req);\r\n }\r\n\r\n /** DELETE /{version}/subscribe/rating-changes — unsubscribe from rating-change events */\r\n unsubscribe(req: PlayerRatingSubscribeRequest): Promise<ApiWrapper> {\r\n return this.http.delete(`/${this.cfg.version}/subscribe/rating-changes`, req);\r\n }\r\n}\r\n","import { HttpClient } from \"../http.js\";\r\nimport { ResolvedConfig } from \"../config.js\";\r\nimport {\r\n ApiWrapper,\r\n ExternalDeleteMatchRequest,\r\n ExternalMatchRequest,\r\n ExternalMatchSearchRequest,\r\n ExternalUpdateMatchRequest,\r\n MatchResponse,\r\n} from \"../types.js\";\r\n\r\nexport interface AnnotateMatchRequest {\r\n matchId: string;\r\n annotation: Record<string, unknown>;\r\n}\r\n\r\nexport class MatchesModule {\r\n constructor(\r\n private readonly http: HttpClient,\r\n private readonly cfg: ResolvedConfig,\r\n ) {}\r\n\r\n /** GET /match/{version}/{id} — view a single match */\r\n get(matchId: string): Promise<ApiWrapper<MatchResponse>> {\r\n return this.http.get(`/match/${this.cfg.version}/${encodeURIComponent(matchId)}`);\r\n }\r\n\r\n /** POST /match/{version}/create — submit a new match result */\r\n create(match: ExternalMatchRequest): Promise<ApiWrapper<MatchResponse>> {\r\n return this.http.post(`/match/${this.cfg.version}/create`, match);\r\n }\r\n\r\n /** POST /match/{version}/batch — submit multiple match results in one call */\r\n createBulk(matches: ExternalMatchRequest[]): Promise<ApiWrapper<MatchResponse[]>> {\r\n return this.http.post(`/match/${this.cfg.version}/batch`, matches);\r\n }\r\n\r\n /** POST /match/{version}/update — update an existing match */\r\n update(req: ExternalUpdateMatchRequest): Promise<ApiWrapper<MatchResponse>> {\r\n return this.http.post(`/match/${this.cfg.version}/update`, req);\r\n }\r\n\r\n /** DELETE /match/{version}/delete — delete a match */\r\n delete(req: ExternalDeleteMatchRequest): Promise<ApiWrapper> {\r\n return this.http.delete(`/match/${this.cfg.version}/delete`, req);\r\n }\r\n\r\n /** POST /match/{version}/annotate — attach vendor-specific metadata to a match */\r\n annotate(req: AnnotateMatchRequest): Promise<ApiWrapper> {\r\n return this.http.post(`/match/${this.cfg.version}/annotate`, req);\r\n }\r\n\r\n /** DELETE /match/{version}/annotate/{matchId} — remove a match annotation */\r\n deleteAnnotation(matchId: string): Promise<ApiWrapper> {\r\n return this.http.delete(`/match/${this.cfg.version}/annotate/${encodeURIComponent(matchId)}`);\r\n }\r\n\r\n /** POST /match/history/search — search a player's match history */\r\n searchHistory(req: ExternalMatchSearchRequest): Promise<ApiWrapper<MatchResponse[]>> {\r\n return this.http.post(`/match/history/search`, req);\r\n }\r\n}\r\n","import { HttpClient } from \"../http.js\";\r\nimport { ResolvedConfig } from \"../config.js\";\r\nimport {\r\n ApiWrapper,\r\n ExternalClubMemberRequest,\r\n ExternalClubMatchSearchRequest,\r\n MatchResponse,\r\n UserInfo,\r\n} from \"../types.js\";\r\n\r\nexport class ClubsModule {\r\n constructor(\r\n private readonly http: HttpClient,\r\n private readonly cfg: ResolvedConfig,\r\n ) {}\r\n\r\n /** POST /club/{version}/members — get ratings for all members of a club */\r\n membersRating(req: ExternalClubMemberRequest): Promise<ApiWrapper<UserInfo[]>> {\r\n return this.http.post(`/club/${this.cfg.version}/members`, req);\r\n }\r\n\r\n /** POST /club/{version}/match/search — search matches associated with a club */\r\n searchMatches(req: ExternalClubMatchSearchRequest): Promise<ApiWrapper<MatchResponse[]>> {\r\n return this.http.post(`/club/${this.cfg.version}/match/search`, req);\r\n }\r\n}\r\n","import { HttpClient } from \"../http.js\";\r\nimport { ResolvedConfig } from \"../config.js\";\r\nimport {\r\n ApiWrapper,\r\n CreateEventRequestV1,\r\n CreateEventResponseV1,\r\n DeleteEventRequestV1,\r\n DeleteEventResponseV1,\r\n GetEventRequestV1,\r\n GetEventResponseV1,\r\n UpdateEventRequestV1,\r\n UpdateEventResponseV1,\r\n} from \"../types.js\";\r\n\r\nexport class EventsModule {\r\n constructor(\r\n private readonly http: HttpClient,\r\n private readonly cfg: ResolvedConfig,\r\n ) {}\r\n\r\n /** POST /events/{version}/create */\r\n create(req: CreateEventRequestV1): Promise<ApiWrapper<CreateEventResponseV1>> {\r\n return this.http.post(`/events/${this.cfg.version}/create`, req);\r\n }\r\n\r\n /** GET /events/{version}/get */\r\n get(req: GetEventRequestV1): Promise<ApiWrapper<GetEventResponseV1>> {\r\n return this.http.post(`/events/${this.cfg.version}/get`, req);\r\n }\r\n\r\n /** POST /events/{version}/update */\r\n update(req: UpdateEventRequestV1): Promise<ApiWrapper<UpdateEventResponseV1>> {\r\n return this.http.post(`/events/${this.cfg.version}/update`, req);\r\n }\r\n\r\n /** POST /events/{version}/delete */\r\n delete(req: DeleteEventRequestV1): Promise<ApiWrapper<DeleteEventResponseV1>> {\r\n return this.http.post(`/events/${this.cfg.version}/delete`, req);\r\n }\r\n}\r\n","import { HttpClient } from \"../http.js\";\r\nimport { ResolvedConfig } from \"../config.js\";\r\nimport { ApiWrapper, ClientHookRequest, UserWebhookRequest, WebhookSchema } from \"../types.js\";\r\n\r\nexport class WebhooksModule {\r\n constructor(\r\n private readonly http: HttpClient,\r\n private readonly cfg: ResolvedConfig,\r\n ) {}\r\n\r\n /** POST /{version}/webhook — register a webhook endpoint */\r\n register(req: ClientHookRequest): Promise<ApiWrapper> {\r\n return this.http.post(`/${this.cfg.version}/webhook`, req);\r\n }\r\n\r\n /** GET /{version}/topic — list all available webhook topics */\r\n getTopics(): Promise<ApiWrapper<string[]>> {\r\n return this.http.get(`/${this.cfg.version}/topic`);\r\n }\r\n\r\n /** GET /{version}/webhook/schema — list available webhook schemas */\r\n listSchemas(): Promise<ApiWrapper<WebhookSchema[]>> {\r\n return this.http.get(`/${this.cfg.version}/webhook/schema`);\r\n }\r\n\r\n /** GET /{version}/webhook/schema/{topic} — get the JSON schema for a specific topic */\r\n getSchema(topic: string): Promise<ApiWrapper<WebhookSchema>> {\r\n return this.http.get(`/${this.cfg.version}/webhook/schema/${encodeURIComponent(topic)}`);\r\n }\r\n\r\n /** POST /user/{version}/subscribe/webhook-event — subscribe specific users to a webhook topic */\r\n subscribeUsers(req: UserWebhookRequest): Promise<ApiWrapper> {\r\n return this.http.post(`/user/${this.cfg.version}/subscribe/webhook-event`, req);\r\n }\r\n\r\n /** DELETE /user/{version}/subscribe/webhook-event — unsubscribe specific users from a webhook topic */\r\n unsubscribeUsers(req: UserWebhookRequest): Promise<ApiWrapper> {\r\n return this.http.delete(`/user/${this.cfg.version}/subscribe/webhook-event`, req);\r\n }\r\n}\r\n","import { DuprClientOptions, ResolvedConfig, resolveConfig } from \"./config.js\";\r\nimport { HttpClient } from \"./http.js\";\r\nimport { AuthModule } from \"./auth.js\";\r\nimport { UsersModule } from \"./resources/users.js\";\r\nimport { PlayersModule } from \"./resources/players.js\";\r\nimport { PlayerRatingModule } from \"./resources/playerRating.js\";\r\nimport { MatchesModule } from \"./resources/matches.js\";\r\nimport { ClubsModule } from \"./resources/clubs.js\";\r\nimport { EventsModule } from \"./resources/events.js\";\r\nimport { WebhooksModule } from \"./resources/webhooks.js\";\r\n\r\nexport class DuprClient {\r\n readonly config: ResolvedConfig;\r\n readonly auth: AuthModule;\r\n readonly users: UsersModule;\r\n readonly players: PlayersModule;\r\n readonly playerRating: PlayerRatingModule;\r\n readonly matches: MatchesModule;\r\n readonly clubs: ClubsModule;\r\n readonly events: EventsModule;\r\n readonly webhooks: WebhooksModule;\r\n\r\n constructor(opts: DuprClientOptions = {}) {\r\n this.config = resolveConfig(opts);\r\n const http = new HttpClient(this.config);\r\n this.auth = new AuthModule(http, this.config);\r\n this.users = new UsersModule(http, this.config);\r\n this.players = new PlayersModule(http, this.config);\r\n this.playerRating = new PlayerRatingModule(http, this.config);\r\n this.matches = new MatchesModule(http, this.config);\r\n this.clubs = new ClubsModule(http, this.config);\r\n this.events = new EventsModule(http, this.config);\r\n this.webhooks = new WebhooksModule(http, this.config);\r\n }\r\n\r\n /** Override the bearer token at runtime — useful when your backend handles auth separately. */\r\n setBearerToken(token: string): void {\r\n this.config.overrideBearerToken = token;\r\n }\r\n\r\n /** Clear the runtime bearer token override and fall back to configured auth. */\r\n clearBearerToken(): void {\r\n delete this.config.overrideBearerToken;\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/config.ts","../src/errors.ts","../src/http.ts","../src/auth.ts","../src/resources/users.ts","../src/resources/players.ts","../src/resources/playerRating.ts","../src/resources/matches.ts","../src/resources/clubs.ts","../src/resources/events.ts","../src/resources/webhooks.ts","../src/client.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["export type AuthMode =\r\n | { type: \"clientCredentials\"; clientKey: string; clientSecret: string }\r\n | { type: \"staticBearer\"; bearerToken: string }\r\n | { type: \"none\" };\r\n\r\nexport interface RequestInfo {\r\n method: string;\r\n url: string;\r\n headers: Record<string, string>;\r\n}\r\n\r\nexport interface ResponseInfo {\r\n status: number;\r\n url: string;\r\n durationMs: number;\r\n}\r\n\r\nexport interface RetryOptions {\r\n /** Max number of retry attempts after the initial failure. @default 3 */\r\n maxRetries?: number;\r\n /** Base delay in ms before the first retry. Doubles on each attempt. @default 1_000 */\r\n baseDelayMs?: number;\r\n /** Max delay cap in ms (prevents infinite backoff). @default 30_000 */\r\n maxDelayMs?: number;\r\n}\r\n\r\nexport interface DuprClientOptions {\r\n /** @default \"https://uat.mydupr.com/api\" */\r\n baseUrl?: string;\r\n /** API version prefix used in all paths. @default \"v1.0\" */\r\n version?: string;\r\n /** Request timeout in milliseconds. @default 30_000 */\r\n timeoutMs?: number;\r\n auth?: AuthMode;\r\n /** Custom User-Agent header. */\r\n userAgent?: string;\r\n /** Inject a custom fetch implementation (useful for testing or polyfilling). */\r\n customFetch?: typeof fetch;\r\n /** Called before every request. Useful for logging or tracing. */\r\n onRequest?: (info: RequestInfo) => void;\r\n /** Called after every response (including errors). */\r\n onResponse?: (info: ResponseInfo) => void;\r\n /** Retry behaviour for transient errors (5xx, network failures, 429). Pass `false` to disable. */\r\n retry?: RetryOptions | false;\r\n /**\r\n * Base URL for the DUPR SSO iframe login widget.\r\n * UAT: \"https://uat.dupr.gg\"\r\n * Prod: \"https://dashboard.dupr.com\"\r\n * Required to call `client.auth.getSsoIframeUrl()`.\r\n */\r\n ssoBaseUrl?: string;\r\n /**\r\n * Base URL for refreshing DUPR SSO user tokens — a separate host from the Partner API.\r\n * UAT: \"https://api.uat.dupr.gg\"\r\n * Prod: \"https://api.dupr.gg\"\r\n * Required to call `client.auth.refreshSsoToken()`.\r\n */\r\n ssoRefreshBaseUrl?: string;\r\n /**\r\n * Authorization endpoint URL for the OAuth 2.0 authorization code flow.\r\n * Confirm the exact value with DUPR support before use.\r\n * Required to call `client.auth.getAuthorizationUrl()`.\r\n */\r\n authorizationUrl?: string;\r\n}\r\n\r\nexport interface ResolvedRetryOptions {\r\n maxRetries: number;\r\n baseDelayMs: number;\r\n maxDelayMs: number;\r\n}\r\n\r\nexport interface ResolvedConfig {\r\n baseUrl: string;\r\n version: string;\r\n timeoutMs: number;\r\n auth: AuthMode;\r\n userAgent: string;\r\n customFetch: typeof fetch;\r\n retry: ResolvedRetryOptions | false;\r\n onRequest?: (info: RequestInfo) => void;\r\n onResponse?: (info: ResponseInfo) => void;\r\n /** Runtime override for the bearer token — set via `client.setBearerToken()`. */\r\n overrideBearerToken?: string;\r\n ssoBaseUrl?: string;\r\n ssoRefreshBaseUrl?: string;\r\n authorizationUrl?: string;\r\n}\r\n\r\nexport function resolveConfig(opts: DuprClientOptions): ResolvedConfig {\r\n const cfg: ResolvedConfig = {\r\n baseUrl: opts.baseUrl ?? \"https://uat.mydupr.com/api\",\r\n version: opts.version ?? \"v1.0\",\r\n timeoutMs: opts.timeoutMs ?? 30_000,\r\n auth: opts.auth ?? { type: \"none\" },\r\n userAgent: opts.userAgent ?? \"dupr-js-client/0.1.0\",\r\n customFetch: opts.customFetch ?? globalThis.fetch.bind(globalThis),\r\n retry:\r\n opts.retry === false\r\n ? false\r\n : {\r\n maxRetries: opts.retry?.maxRetries ?? 3,\r\n baseDelayMs: opts.retry?.baseDelayMs ?? 1_000,\r\n maxDelayMs: opts.retry?.maxDelayMs ?? 30_000,\r\n },\r\n };\r\n if (opts.onRequest) cfg.onRequest = opts.onRequest;\r\n if (opts.onResponse) cfg.onResponse = opts.onResponse;\r\n if (opts.ssoBaseUrl) cfg.ssoBaseUrl = opts.ssoBaseUrl;\r\n if (opts.ssoRefreshBaseUrl) cfg.ssoRefreshBaseUrl = opts.ssoRefreshBaseUrl;\r\n if (opts.authorizationUrl) cfg.authorizationUrl = opts.authorizationUrl;\r\n return cfg;\r\n}\r\n","export class DuprApiError extends Error {\r\n constructor(\r\n message: string,\r\n public readonly statusCode: number,\r\n public readonly details?: unknown,\r\n public readonly duprRequestId?: string,\r\n ) {\r\n super(message);\r\n this.name = \"DuprApiError\";\r\n // Maintain proper prototype chain in transpiled environments\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n }\r\n}\r\n\r\nexport class AuthenticationError extends DuprApiError {\r\n constructor(message: string, statusCode: number, details?: unknown, duprRequestId?: string) {\r\n super(message, statusCode, details, duprRequestId);\r\n this.name = \"AuthenticationError\";\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n }\r\n}\r\n\r\nexport class ValidationError extends DuprApiError {\r\n constructor(message: string, statusCode: number, details?: unknown, duprRequestId?: string) {\r\n super(message, statusCode, details, duprRequestId);\r\n this.name = \"ValidationError\";\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n }\r\n}\r\n\r\nexport class NotFoundError extends DuprApiError {\r\n constructor(message: string, statusCode: number, details?: unknown, duprRequestId?: string) {\r\n super(message, statusCode, details, duprRequestId);\r\n this.name = \"NotFoundError\";\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n }\r\n}\r\n\r\nexport class RateLimitError extends DuprApiError {\r\n constructor(message: string, statusCode: number, details?: unknown, duprRequestId?: string) {\r\n super(message, statusCode, details, duprRequestId);\r\n this.name = \"RateLimitError\";\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n }\r\n}\r\n\r\nexport class ServerError extends DuprApiError {\r\n constructor(message: string, statusCode: number, details?: unknown, duprRequestId?: string) {\r\n super(message, statusCode, details, duprRequestId);\r\n this.name = \"ServerError\";\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n }\r\n}\r\n\r\nexport async function buildError(res: Response): Promise<DuprApiError> {\r\n let body: unknown;\r\n const requestId = res.headers.get(\"x-request-id\") ?? res.headers.get(\"x-dupr-request-id\") ?? undefined;\r\n\r\n try {\r\n body = await res.json();\r\n } catch {\r\n // non-JSON body — leave body undefined\r\n }\r\n\r\n const msg =\r\n (typeof body === \"object\" && body !== null && \"message\" in body && typeof (body as Record<string, unknown>)[\"message\"] === \"string\"\r\n ? (body as Record<string, unknown>)[\"message\"] as string\r\n : null) ??\r\n `DUPR API error ${res.status}`;\r\n\r\n switch (true) {\r\n case res.status === 401 || res.status === 403:\r\n return new AuthenticationError(msg, res.status, body, requestId);\r\n case res.status === 404:\r\n return new NotFoundError(msg, res.status, body, requestId);\r\n case res.status === 400:\r\n return new ValidationError(msg, res.status, body, requestId);\r\n case res.status === 429:\r\n return new RateLimitError(msg, res.status, body, requestId);\r\n case res.status >= 500:\r\n return new ServerError(msg, res.status, body, requestId);\r\n default:\r\n return new DuprApiError(msg, res.status, body, requestId);\r\n }\r\n}\r\n","import { ResolvedConfig } from \"./config.js\";\r\nimport { AuthenticationError, buildError, RateLimitError, ServerError } from \"./errors.js\";\r\nimport type { TokenResponse } from \"./types.js\";\r\n\r\nfunction sleep(ms: number): Promise<void> {\r\n return new Promise((resolve) => setTimeout(resolve, ms));\r\n}\r\n\r\nfunction retryDelayMs(attempt: number, baseDelayMs: number, maxDelayMs: number): number {\r\n // Exponential backoff with ±20% jitter to avoid thundering herd\r\n const exp = Math.min(baseDelayMs * 2 ** attempt, maxDelayMs);\r\n return exp * (0.8 + Math.random() * 0.4);\r\n}\r\n\r\nfunction isRetryable(err: unknown): boolean {\r\n if (err instanceof RateLimitError) return true;\r\n if (err instanceof ServerError) return true;\r\n // Network-level failures (fetch throws a TypeError on connection refused etc.)\r\n if (err instanceof TypeError) return true;\r\n return false;\r\n}\r\n\r\nexport class HttpClient {\r\n private token: string | null = null;\r\n private tokenExpiresAt = 0;\r\n\r\n constructor(private readonly config: ResolvedConfig) {}\r\n\r\n private async getBearerToken(): Promise<string> {\r\n if (this.config.overrideBearerToken) {\r\n return this.config.overrideBearerToken;\r\n }\r\n if (this.config.auth.type === \"staticBearer\") {\r\n return this.config.auth.bearerToken;\r\n }\r\n if (this.config.auth.type !== \"clientCredentials\") {\r\n throw new AuthenticationError(\"No auth configured — set auth in DuprClientOptions or call setBearerToken()\", 401);\r\n }\r\n\r\n if (this.token && Date.now() < this.tokenExpiresAt) {\r\n return this.token;\r\n }\r\n\r\n const { clientKey, clientSecret } = this.config.auth;\r\n const encoded = Buffer.from(`${clientKey}:${clientSecret}`).toString(\"base64\");\r\n const url = `${this.config.baseUrl}/auth/${this.config.version}/token`;\r\n\r\n const start = Date.now();\r\n const res = await this.config.customFetch(url, {\r\n method: \"POST\",\r\n headers: {\r\n \"x-authorization\": encoded,\r\n \"User-Agent\": this.config.userAgent,\r\n },\r\n signal: AbortSignal.timeout(this.config.timeoutMs),\r\n });\r\n\r\n this.config.onResponse?.({ status: res.status, url, durationMs: Date.now() - start });\r\n\r\n if (!res.ok) throw await buildError(res);\r\n\r\n const body = await res.json() as TokenResponse;\r\n // The Partner API wraps the token in result: { token, expiry }.\r\n // Older/alternate environments return it at the top level — handle both.\r\n this.token = body.result?.token ?? body.token ?? body.accessToken ?? null;\r\n if (!this.token) throw new AuthenticationError(\"Token response contained no token\", 401);\r\n\r\n if (body.result?.expiry) {\r\n // expiry is an ISO datetime string; subtract 60s buffer\r\n this.tokenExpiresAt = new Date(body.result.expiry).getTime() - 60_000;\r\n } else {\r\n const ttlSec = body.expiresIn ?? 3600;\r\n this.tokenExpiresAt = Date.now() + (ttlSec - 60) * 1000;\r\n }\r\n return this.token;\r\n }\r\n\r\n async get<T>(path: string, init?: RequestInit): Promise<T> {\r\n return this.request<T>(\"GET\", path, init);\r\n }\r\n\r\n async post<T>(path: string, body?: unknown, init?: RequestInit): Promise<T> {\r\n const extra: RequestInit = { headers: { \"Content-Type\": \"application/json\", ...(init?.headers ?? {}) } };\r\n if (body !== undefined) extra.body = JSON.stringify(body);\r\n return this.request<T>(\"POST\", path, { ...init, ...extra });\r\n }\r\n\r\n async delete<T>(path: string, body?: unknown, init?: RequestInit): Promise<T> {\r\n const extra: RequestInit = { headers: { \"Content-Type\": \"application/json\", ...(init?.headers ?? {}) } };\r\n if (body !== undefined) extra.body = JSON.stringify(body);\r\n return this.request<T>(\"DELETE\", path, { ...init, ...extra });\r\n }\r\n\r\n async request<T>(method: string, path: string, init?: RequestInit): Promise<T> {\r\n const retryCfg = this.config.retry;\r\n const maxAttempts = retryCfg === false ? 1 : retryCfg.maxRetries + 1;\r\n\r\n let lastErr: unknown;\r\n\r\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\r\n try {\r\n return await this.rawRequest<T>(method, path, init);\r\n } catch (err) {\r\n lastErr = err;\r\n\r\n if (attempt >= maxAttempts - 1) break;\r\n if (!isRetryable(err)) break;\r\n if (retryCfg === false) break;\r\n\r\n let delay: number;\r\n if (err instanceof RateLimitError) {\r\n // Honor Retry-After header (value in seconds)\r\n const retryAfterSec =\r\n err.details !== null &&\r\n typeof err.details === \"object\" &&\r\n \"retryAfterSeconds\" in (err.details as object)\r\n ? Number((err.details as { retryAfterSeconds: unknown }).retryAfterSeconds)\r\n : NaN;\r\n delay = Number.isFinite(retryAfterSec) && retryAfterSec > 0\r\n ? retryAfterSec * 1000\r\n : retryDelayMs(attempt, retryCfg.baseDelayMs, retryCfg.maxDelayMs);\r\n } else {\r\n delay = retryDelayMs(attempt, retryCfg.baseDelayMs, retryCfg.maxDelayMs);\r\n }\r\n\r\n await sleep(delay);\r\n }\r\n }\r\n\r\n throw lastErr;\r\n }\r\n\r\n private async rawRequest<T>(method: string, path: string, init?: RequestInit): Promise<T> {\r\n const token = await this.getBearerToken();\r\n const url = `${this.config.baseUrl}${path}`;\r\n\r\n const headers: Record<string, string> = {\r\n Authorization: `Bearer ${token}`,\r\n \"User-Agent\": this.config.userAgent,\r\n ...(init?.headers as Record<string, string> | undefined ?? {}),\r\n };\r\n\r\n const { Authorization: _redacted, ...hookHeaders } = headers;\r\n this.config.onRequest?.({ method, url, headers: hookHeaders });\r\n\r\n const start = Date.now();\r\n const res = await this.config.customFetch(url, {\r\n method,\r\n ...init,\r\n headers,\r\n signal: AbortSignal.timeout(this.config.timeoutMs),\r\n });\r\n\r\n this.config.onResponse?.({ status: res.status, url, durationMs: Date.now() - start });\r\n\r\n if (!res.ok) {\r\n const err = await buildError(res);\r\n // Attach Retry-After from the response header so the retry loop can read it\r\n if (err instanceof RateLimitError) {\r\n const retryAfter = res.headers.get(\"Retry-After\");\r\n if (retryAfter) {\r\n (err as RateLimitError & { details: unknown }).details =\r\n typeof err.details === \"object\" && err.details !== null\r\n ? { ...err.details as object, retryAfterSeconds: Number(retryAfter) }\r\n : { retryAfterSeconds: Number(retryAfter) };\r\n }\r\n }\r\n throw err;\r\n }\r\n\r\n // Some endpoints return 204 No Content\r\n if (res.status === 204 || res.headers.get(\"content-length\") === \"0\") {\r\n return undefined as T;\r\n }\r\n\r\n return res.json() as Promise<T>;\r\n }\r\n}\r\n","import { createHash, randomBytes } from \"crypto\";\r\nimport { HttpClient } from \"./http.js\";\r\nimport { ResolvedConfig } from \"./config.js\";\r\nimport { AuthenticationError } from \"./errors.js\";\r\nimport { TokenResponse } from \"./types.js\";\r\n\r\nexport interface AuthCodeTokenResponse extends TokenResponse {\r\n refresh_token?: string;\r\n token_type?: string;\r\n scope?: string;\r\n}\r\n\r\n/** Response from `client.auth.refreshSsoToken()`. Both tokens are always present — DUPR rotates refresh tokens on every use. */\r\nexport interface SsoTokenResponse {\r\n accessToken: string;\r\n refreshToken: string;\r\n /** Seconds until the access token expires, if provided by DUPR. */\r\n expiresIn?: number;\r\n}\r\n\r\nexport interface AuthorizationUrlParams {\r\n /** Your OAuth redirect URI, must match what is registered with DUPR. */\r\n redirectUri: string;\r\n /** OAuth scopes to request (e.g. [\"user.read\"]). Defaults to empty. */\r\n scopes?: string[];\r\n /** Opaque value passed through the flow to prevent CSRF. Recommended. */\r\n state?: string;\r\n /** PKCE code_challenge (S256). Generate the pair with `client.auth.generatePkce()`. */\r\n codeChallenge?: string;\r\n}\r\n\r\nexport class AuthModule {\r\n constructor(\r\n private readonly http: HttpClient,\r\n private readonly config: ResolvedConfig,\r\n ) {}\r\n\r\n /**\r\n * Explicitly request a new access token using client credentials.\r\n * Normally you don't need to call this — the HTTP client handles token refresh automatically.\r\n */\r\n async getToken(): Promise<TokenResponse> {\r\n if (this.config.auth.type !== \"clientCredentials\") {\r\n throw new AuthenticationError(\"getToken() requires clientCredentials auth mode\", 401);\r\n }\r\n const { clientKey, clientSecret } = this.config.auth;\r\n const encoded = Buffer.from(`${clientKey}:${clientSecret}`).toString(\"base64\");\r\n const url = `${this.config.baseUrl}/auth/${this.config.version}/token`;\r\n\r\n const res = await this.config.customFetch(url, {\r\n method: \"POST\",\r\n headers: {\r\n \"x-authorization\": encoded,\r\n \"User-Agent\": this.config.userAgent,\r\n },\r\n signal: AbortSignal.timeout(this.config.timeoutMs),\r\n });\r\n\r\n if (!res.ok) {\r\n const body = await res.json().catch(() => undefined) as Record<string, unknown> | undefined;\r\n throw new AuthenticationError(\r\n (body?.[\"message\"] as string | undefined) ?? `Auth failed: ${res.status}`,\r\n res.status,\r\n body,\r\n );\r\n }\r\n\r\n return res.json() as Promise<TokenResponse>;\r\n }\r\n\r\n // ── Authorization Code Flow ───────────────────────────────────────────────\r\n //\r\n // Use this flow to let end-users authorise your app to act on their behalf\r\n // (e.g. the \"Connect DUPR\" button). The user is redirected to DUPR's login\r\n // page, then back to your redirectUri with an authorization code.\r\n //\r\n // NOTE: This requires a DUPR OAuth application with an authorization endpoint\r\n // separate from the Partner API client credentials. Confirm the exact\r\n // authorization URL with DUPR support.\r\n //\r\n // Typical flow:\r\n // 1. client.auth.getAuthorizationUrl({ redirectUri, state }) → redirect user\r\n // 2. User approves → DUPR calls back to redirectUri?code=xxx&state=yyy\r\n // 3. client.auth.exchangeCode({ code, redirectUri }) → tokens\r\n // 4. Store access_token + refresh_token; call client.setBearerToken(access_token)\r\n // 5. When access_token expires: client.auth.refreshToken(refresh_token)\r\n\r\n /** Generate a PKCE `code_verifier` + `code_challenge` pair (S256 method).\r\n * Pass `codeChallenge` to `getAuthorizationUrl()` and `codeVerifier` to `exchangeCode()`. */\r\n generatePkce(): { codeVerifier: string; codeChallenge: string } {\r\n const codeVerifier = randomBytes(32).toString(\"base64url\");\r\n const codeChallenge = createHash(\"sha256\").update(codeVerifier).digest(\"base64url\");\r\n return { codeVerifier, codeChallenge };\r\n }\r\n\r\n /**\r\n * Build the DUPR authorization URL to redirect the user to for login.\r\n * The `authorizationUrl` config option must be set (see above note).\r\n * Pass `codeChallenge` (from `generatePkce()`) to enable PKCE.\r\n */\r\n getAuthorizationUrl(params: AuthorizationUrlParams): string {\r\n if (!this.config.authorizationUrl) {\r\n throw new Error(\r\n \"authorizationUrl is not configured. Pass it in DuprClientOptions to use the Authorization Code flow.\",\r\n );\r\n }\r\n const url = new URL(this.config.authorizationUrl);\r\n const clientId = this.config.auth.type === \"clientCredentials\" ? this.config.auth.clientKey : \"\";\r\n url.searchParams.set(\"response_type\", \"code\");\r\n url.searchParams.set(\"client_id\", clientId);\r\n url.searchParams.set(\"redirect_uri\", params.redirectUri);\r\n if (params.scopes?.length) url.searchParams.set(\"scope\", params.scopes.join(\" \"));\r\n if (params.state) url.searchParams.set(\"state\", params.state);\r\n if (params.codeChallenge) {\r\n url.searchParams.set(\"code_challenge\", params.codeChallenge);\r\n url.searchParams.set(\"code_challenge_method\", \"S256\");\r\n }\r\n return url.toString();\r\n }\r\n\r\n /**\r\n * Exchange an authorization code (from the OAuth callback) for access + refresh tokens.\r\n * Uses `POST /auth/{version}/token` with `grant_type=authorization_code`.\r\n */\r\n async exchangeCode(params: {\r\n code: string;\r\n redirectUri: string;\r\n /** PKCE code_verifier. Required if `codeChallenge` was passed to `getAuthorizationUrl()`. */\r\n codeVerifier?: string;\r\n }): Promise<AuthCodeTokenResponse> {\r\n if (this.config.auth.type !== \"clientCredentials\") {\r\n throw new AuthenticationError(\"exchangeCode() requires clientCredentials auth configured with clientKey/clientSecret\", 401);\r\n }\r\n const { clientKey, clientSecret } = this.config.auth;\r\n const url = `${this.config.baseUrl}/auth/${this.config.version}/token`;\r\n const body = new URLSearchParams({\r\n grant_type: \"authorization_code\",\r\n code: params.code,\r\n redirect_uri: params.redirectUri,\r\n client_id: clientKey,\r\n client_secret: clientSecret,\r\n });\r\n if (params.codeVerifier) body.set(\"code_verifier\", params.codeVerifier);\r\n\r\n const res = await this.config.customFetch(url, {\r\n method: \"POST\",\r\n headers: {\r\n \"Content-Type\": \"application/x-www-form-urlencoded\",\r\n \"User-Agent\": this.config.userAgent,\r\n },\r\n body: body.toString(),\r\n signal: AbortSignal.timeout(this.config.timeoutMs),\r\n });\r\n\r\n if (!res.ok) {\r\n const errBody = await res.json().catch(() => undefined) as Record<string, unknown> | undefined;\r\n throw new AuthenticationError(\r\n (errBody?.[\"message\"] as string | undefined) ?? `Code exchange failed: ${res.status}`,\r\n res.status,\r\n errBody,\r\n );\r\n }\r\n\r\n return res.json() as Promise<AuthCodeTokenResponse>;\r\n }\r\n\r\n // ── SSO Iframe Flow ───────────────────────────────────────────────────────\r\n //\r\n // DUPR's documented SSO approach for user-facing login uses an embedded iframe\r\n // rather than a standard OAuth2 redirect. The iframe emits a window.postMessage\r\n // event upon successful login.\r\n //\r\n // Typical flow:\r\n // 1. client.auth.getSsoIframeUrl() → embed in <iframe allow=\"payment\">\r\n // 2. User logs in inside the iframe\r\n // 3. Listen for window.postMessage → { userToken, refreshToken, id, duprId, stats }\r\n // 4. Store userToken + refreshToken server-side; record tokenExpiresAt\r\n // (7 days UAT / 30 days prod — not returned in the event, apply based on env)\r\n // 5. When userToken nears expiry: client.auth.refreshSsoToken(refreshToken)\r\n // DUPR rotates refresh tokens — store both returned tokens.\r\n //\r\n // UAT iframe host: https://uat.dupr.gg\r\n // Prod iframe host: https://dashboard.dupr.com\r\n // Always validate window.postMessage origin against the expected host.\r\n\r\n /**\r\n * Returns the DUPR SSO iframe URL. Embed this in an `<iframe allow=\"payment\">` to\r\n * display the DUPR login widget. Requires `ssoBaseUrl` in `DuprClientOptions`.\r\n */\r\n getSsoIframeUrl(): string {\r\n if (!this.config.ssoBaseUrl) {\r\n throw new Error(\r\n \"ssoBaseUrl is not configured. Pass it in DuprClientOptions to use the SSO iframe flow.\",\r\n );\r\n }\r\n if (this.config.auth.type !== \"clientCredentials\") {\r\n throw new AuthenticationError(\r\n \"getSsoIframeUrl() requires clientCredentials auth mode\",\r\n 401,\r\n );\r\n }\r\n const encoded = Buffer.from(this.config.auth.clientKey).toString(\"base64\");\r\n return `${this.config.ssoBaseUrl}/login-external-app/${encoded}`;\r\n }\r\n\r\n /**\r\n * Refresh a DUPR SSO user token obtained from the iframe login `postMessage` event.\r\n * Uses a separate refresh endpoint on `ssoRefreshBaseUrl` (distinct from the Partner API).\r\n * Requires `ssoRefreshBaseUrl` in `DuprClientOptions`.\r\n *\r\n * DUPR rotates refresh tokens on every use — always store both `accessToken` and\r\n * `refreshToken` from the response.\r\n */\r\n async refreshSsoToken(refreshToken: string): Promise<SsoTokenResponse> {\r\n if (!this.config.ssoRefreshBaseUrl) {\r\n throw new Error(\r\n \"ssoRefreshBaseUrl is not configured. Pass it in DuprClientOptions to use SSO token refresh.\",\r\n );\r\n }\r\n const res = await this.config.customFetch(\r\n `${this.config.ssoRefreshBaseUrl}/api/auth/refreshAccessToken`,\r\n {\r\n method: \"POST\",\r\n headers: {\r\n \"Content-Type\": \"application/json\",\r\n \"User-Agent\": this.config.userAgent,\r\n },\r\n body: JSON.stringify({ refreshToken }),\r\n signal: AbortSignal.timeout(this.config.timeoutMs),\r\n },\r\n );\r\n\r\n if (!res.ok) {\r\n const errBody = await res.json().catch(() => undefined) as Record<string, unknown> | undefined;\r\n throw new AuthenticationError(\r\n (errBody?.[\"message\"] as string | undefined) ?? `SSO token refresh failed: ${res.status}`,\r\n res.status,\r\n errBody,\r\n );\r\n }\r\n\r\n const data = await res.json() as Record<string, unknown>;\r\n const accessToken = (data[\"accessToken\"] ?? data[\"userToken\"]) as string | undefined;\r\n const newRefreshToken = data[\"refreshToken\"] as string | undefined;\r\n\r\n if (!accessToken) {\r\n throw new AuthenticationError(\"SSO token refresh response missing accessToken\", 502);\r\n }\r\n if (!newRefreshToken) {\r\n throw new AuthenticationError(\r\n \"SSO token refresh response missing refreshToken — DUPR token rotation failed\",\r\n 502,\r\n );\r\n }\r\n\r\n return {\r\n accessToken,\r\n refreshToken: newRefreshToken,\r\n ...(data[\"expiresIn\"] !== undefined && { expiresIn: data[\"expiresIn\"] as number }),\r\n };\r\n }\r\n\r\n /**\r\n * Obtain a new access token using a refresh token from a previous Authorization Code flow.\r\n * Uses `POST /auth/{version}/token` with `grant_type=refresh_token`.\r\n */\r\n async refreshToken(refreshToken: string): Promise<AuthCodeTokenResponse> {\r\n if (this.config.auth.type !== \"clientCredentials\") {\r\n throw new AuthenticationError(\"refreshToken() requires clientCredentials auth configured\", 401);\r\n }\r\n const { clientKey, clientSecret } = this.config.auth;\r\n const url = `${this.config.baseUrl}/auth/${this.config.version}/token`;\r\n const body = new URLSearchParams({\r\n grant_type: \"refresh_token\",\r\n refresh_token: refreshToken,\r\n client_id: clientKey,\r\n client_secret: clientSecret,\r\n });\r\n\r\n const res = await this.config.customFetch(url, {\r\n method: \"POST\",\r\n headers: {\r\n \"Content-Type\": \"application/x-www-form-urlencoded\",\r\n \"User-Agent\": this.config.userAgent,\r\n },\r\n body: body.toString(),\r\n signal: AbortSignal.timeout(this.config.timeoutMs),\r\n });\r\n\r\n if (!res.ok) {\r\n const errBody = await res.json().catch(() => undefined) as Record<string, unknown> | undefined;\r\n throw new AuthenticationError(\r\n (errBody?.[\"message\"] as string | undefined) ?? `Token refresh failed: ${res.status}`,\r\n res.status,\r\n errBody,\r\n );\r\n }\r\n\r\n return res.json() as Promise<AuthCodeTokenResponse>;\r\n }\r\n}\r\n","import { HttpClient } from \"../http.js\";\r\nimport { ResolvedConfig } from \"../config.js\";\r\nimport {\r\n ApiWrapper,\r\n ClubMembershipResponse,\r\n UserClubMembershipResponse,\r\n CreateProvisionalRatingRequest,\r\n DeleteProvisionalRatingRequest,\r\n ExtendedUserInfo,\r\n ExternalBatchUserDetailRequest,\r\n ExternalInviteRequest,\r\n ExternalSearchRequest,\r\n GetProvisionalRatingRequest,\r\n GrantExternalSubscriptionRequest,\r\n UpdateProvisionalRatingRequest,\r\n UserInfo,\r\n} from \"../types.js\";\r\n\r\nexport class UsersModule {\r\n constructor(\r\n private readonly http: HttpClient,\r\n private readonly cfg: ResolvedConfig,\r\n ) {}\r\n\r\n /** GET /user/{version}/{id} — basic player profile */\r\n getUser(duprId: string): Promise<ApiWrapper<UserInfo>> {\r\n return this.http.get(`/user/${this.cfg.version}/${encodeURIComponent(duprId)}`);\r\n }\r\n\r\n /** GET /user/{version}/{id}/details — extended profile (requires USER_EMAIL::VIEW permission) */\r\n getExtendedUser(duprId: string): Promise<ApiWrapper<ExtendedUserInfo>> {\r\n return this.http.get(`/user/${this.cfg.version}/${encodeURIComponent(duprId)}/details`);\r\n }\r\n\r\n /** GET /user/{version}/{id}/clubs — club memberships for a player (partner API, legacy) */\r\n getClubMemberships(duprId: string): Promise<ClubMembershipResponse> {\r\n return this.http.get(`/user/${this.cfg.version}/${encodeURIComponent(duprId)}/clubs`);\r\n }\r\n\r\n /**\r\n * GET /user/club/membership — club memberships for the authenticated user (SSO user API).\r\n * Must be called against the SSO API base URL (e.g. https://api.uat.dupr.gg) with the\r\n * user's SSO bearer token, NOT the partner API base URL.\r\n * Returns `{ membership: [{ clubId: number, clubName: string, role: string }] }`.\r\n */\r\n getMyClubMemberships(): Promise<UserClubMembershipResponse> {\r\n return this.http.get(`/user/club/membership`);\r\n }\r\n\r\n /** POST /user/{version}/search — full-text player search with optional filters */\r\n search(req: ExternalSearchRequest): Promise<ApiWrapper<UserInfo[]>> {\r\n return this.http.post(`/user/${this.cfg.version}/search`, req);\r\n }\r\n\r\n /** POST /user/{version}/batch — fetch multiple players by DUPR ID in one request */\r\n getBatch(req: ExternalBatchUserDetailRequest): Promise<ApiWrapper<UserInfo[]>> {\r\n return this.http.post(`/user/${this.cfg.version}/batch`, req);\r\n }\r\n\r\n /** POST /user/{version}/invite — pre-generate a DUPR ID and send an invite email */\r\n invite(req: ExternalInviteRequest): Promise<ApiWrapper<{ duprId: string }>> {\r\n return this.http.post(`/user/${this.cfg.version}/invite`, req);\r\n }\r\n\r\n /** POST /user/{version}/subscription/grants — grant a subscription to a user */\r\n grantSubscription(req: GrantExternalSubscriptionRequest): Promise<ApiWrapper> {\r\n return this.http.post(`/user/${this.cfg.version}/subscription/grants`, req);\r\n }\r\n\r\n // ── Provisional ratings ──────────────────────────────────────\r\n\r\n /** POST /user/{version}/provisional_rating — get provisional ratings for a player */\r\n getProvisionalRating(req: GetProvisionalRatingRequest): Promise<ApiWrapper> {\r\n return this.http.post(`/user/${this.cfg.version}/provisional_rating`, req);\r\n }\r\n\r\n /** POST /user/{version}/provisional_rating/create */\r\n createProvisionalRating(req: CreateProvisionalRatingRequest): Promise<ApiWrapper> {\r\n return this.http.post(`/user/${this.cfg.version}/provisional_rating/create`, req);\r\n }\r\n\r\n /** POST /user/{version}/provisional_rating/update */\r\n updateProvisionalRating(req: UpdateProvisionalRatingRequest): Promise<ApiWrapper> {\r\n return this.http.post(`/user/${this.cfg.version}/provisional_rating/update`, req);\r\n }\r\n\r\n /** DELETE /user/{version}/provisional_rating/delete */\r\n deleteProvisionalRating(req: DeleteProvisionalRatingRequest): Promise<ApiWrapper> {\r\n return this.http.delete(`/user/${this.cfg.version}/provisional_rating/delete`, req);\r\n }\r\n}\r\n","import { HttpClient } from \"../http.js\";\r\nimport { ResolvedConfig } from \"../config.js\";\r\nimport { ApiWrapper } from \"../types.js\";\r\n\r\nexport interface GetDuprIdByEmailRequest {\r\n email: string;\r\n}\r\n\r\nexport interface DuprIdByEmailResponse {\r\n duprId?: string;\r\n}\r\n\r\nexport class PlayersModule {\r\n constructor(\r\n private readonly http: HttpClient,\r\n private readonly cfg: ResolvedConfig,\r\n ) {}\r\n\r\n /** POST /{version}/player/duprid-by-email — resolve a DUPR ID from an email address */\r\n getDuprIdByEmail(req: GetDuprIdByEmailRequest): Promise<ApiWrapper<DuprIdByEmailResponse>> {\r\n return this.http.post(`/${this.cfg.version}/player/duprid-by-email`, req);\r\n }\r\n}\r\n","import { HttpClient } from \"../http.js\";\r\nimport { ResolvedConfig } from \"../config.js\";\r\nimport { ApiWrapper, PlayerRatingSubscribeRequest } from \"../types.js\";\r\n\r\nexport interface PlayerRatingHistoryRequest {\r\n duprId: string;\r\n offset?: number;\r\n limit?: number;\r\n}\r\n\r\nexport interface PlayerRatingHistoryEntry {\r\n date?: string;\r\n singlesRating?: number;\r\n doublesRating?: number;\r\n}\r\n\r\nexport class PlayerRatingModule {\r\n constructor(\r\n private readonly http: HttpClient,\r\n private readonly cfg: ResolvedConfig,\r\n ) {}\r\n\r\n /** POST /history — get rating history for a player */\r\n getHistory(req: PlayerRatingHistoryRequest): Promise<ApiWrapper<PlayerRatingHistoryEntry[]>> {\r\n return this.http.post(`/history`, req);\r\n }\r\n\r\n /** GET /{version}/subscribe/rating-changes — list currently subscribed DUPR IDs */\r\n getSubscriptions(): Promise<ApiWrapper<{ duprIds: string[] }>> {\r\n return this.http.get(`/${this.cfg.version}/subscribe/rating-changes`);\r\n }\r\n\r\n /** POST /{version}/subscribe/rating-changes — subscribe to rating-change events for a list of players */\r\n subscribe(req: PlayerRatingSubscribeRequest): Promise<ApiWrapper> {\r\n return this.http.post(`/${this.cfg.version}/subscribe/rating-changes`, req);\r\n }\r\n\r\n /** DELETE /{version}/subscribe/rating-changes — unsubscribe from rating-change events */\r\n unsubscribe(req: PlayerRatingSubscribeRequest): Promise<ApiWrapper> {\r\n return this.http.delete(`/${this.cfg.version}/subscribe/rating-changes`, req);\r\n }\r\n}\r\n","import { HttpClient } from \"../http.js\";\r\nimport { ResolvedConfig } from \"../config.js\";\r\nimport {\r\n ApiWrapper,\r\n ExternalDeleteMatchRequest,\r\n ExternalMatchRequest,\r\n ExternalMatchSearchRequest,\r\n ExternalUpdateMatchRequest,\r\n MatchResponse,\r\n} from \"../types.js\";\r\n\r\nexport interface AnnotateMatchRequest {\r\n matchId: string;\r\n annotation: Record<string, unknown>;\r\n}\r\n\r\nexport class MatchesModule {\r\n constructor(\r\n private readonly http: HttpClient,\r\n private readonly cfg: ResolvedConfig,\r\n ) {}\r\n\r\n /** GET /match/{version}/{id} — view a single match */\r\n get(matchId: string): Promise<ApiWrapper<MatchResponse>> {\r\n return this.http.get(`/match/${this.cfg.version}/${encodeURIComponent(matchId)}`);\r\n }\r\n\r\n /** POST /match/{version}/create — submit a new match result */\r\n create(match: ExternalMatchRequest): Promise<ApiWrapper<MatchResponse>> {\r\n return this.http.post(`/match/${this.cfg.version}/create`, match);\r\n }\r\n\r\n /** POST /match/{version}/batch — submit multiple match results in one call */\r\n createBulk(matches: ExternalMatchRequest[]): Promise<ApiWrapper<MatchResponse[]>> {\r\n return this.http.post(`/match/${this.cfg.version}/batch`, matches);\r\n }\r\n\r\n /** POST /match/{version}/update — update an existing match */\r\n update(req: ExternalUpdateMatchRequest): Promise<ApiWrapper<MatchResponse>> {\r\n return this.http.post(`/match/${this.cfg.version}/update`, req);\r\n }\r\n\r\n /** DELETE /match/{version}/delete — delete a match */\r\n delete(req: ExternalDeleteMatchRequest): Promise<ApiWrapper> {\r\n return this.http.delete(`/match/${this.cfg.version}/delete`, req);\r\n }\r\n\r\n /** POST /match/{version}/annotate — attach vendor-specific metadata to a match */\r\n annotate(req: AnnotateMatchRequest): Promise<ApiWrapper> {\r\n return this.http.post(`/match/${this.cfg.version}/annotate`, req);\r\n }\r\n\r\n /** DELETE /match/{version}/annotate/{matchId} — remove a match annotation */\r\n deleteAnnotation(matchId: string): Promise<ApiWrapper> {\r\n return this.http.delete(`/match/${this.cfg.version}/annotate/${encodeURIComponent(matchId)}`);\r\n }\r\n\r\n /** POST /match/history/search — search a player's match history */\r\n searchHistory(req: ExternalMatchSearchRequest): Promise<ApiWrapper<MatchResponse[]>> {\r\n return this.http.post(`/match/history/search`, req);\r\n }\r\n}\r\n","import { HttpClient } from \"../http.js\";\r\nimport { ResolvedConfig } from \"../config.js\";\r\nimport {\r\n ApiWrapper,\r\n ExternalClubMemberRequest,\r\n ExternalClubMatchSearchRequest,\r\n MatchResponse,\r\n UserInfo,\r\n} from \"../types.js\";\r\n\r\nexport class ClubsModule {\r\n constructor(\r\n private readonly http: HttpClient,\r\n private readonly cfg: ResolvedConfig,\r\n ) {}\r\n\r\n /** POST /club/{version}/members — get ratings for all members of a club */\r\n membersRating(req: ExternalClubMemberRequest): Promise<ApiWrapper<UserInfo[]>> {\r\n return this.http.post(`/club/${this.cfg.version}/members`, req);\r\n }\r\n\r\n /** POST /club/{version}/match/search — search matches associated with a club */\r\n searchMatches(req: ExternalClubMatchSearchRequest): Promise<ApiWrapper<MatchResponse[]>> {\r\n return this.http.post(`/club/${this.cfg.version}/match/search`, req);\r\n }\r\n}\r\n","import { HttpClient } from \"../http.js\";\r\nimport { ResolvedConfig } from \"../config.js\";\r\nimport {\r\n ApiWrapper,\r\n CreateEventRequestV1,\r\n CreateEventResponseV1,\r\n DeleteEventRequestV1,\r\n DeleteEventResponseV1,\r\n GetEventRequestV1,\r\n GetEventResponseV1,\r\n UpdateEventRequestV1,\r\n UpdateEventResponseV1,\r\n} from \"../types.js\";\r\n\r\nexport class EventsModule {\r\n constructor(\r\n private readonly http: HttpClient,\r\n private readonly cfg: ResolvedConfig,\r\n ) {}\r\n\r\n /** POST /events/{version}/create */\r\n create(req: CreateEventRequestV1): Promise<ApiWrapper<CreateEventResponseV1>> {\r\n return this.http.post(`/events/${this.cfg.version}/create`, req);\r\n }\r\n\r\n /** GET /events/{version}/get */\r\n get(req: GetEventRequestV1): Promise<ApiWrapper<GetEventResponseV1>> {\r\n return this.http.post(`/events/${this.cfg.version}/get`, req);\r\n }\r\n\r\n /** POST /events/{version}/update */\r\n update(req: UpdateEventRequestV1): Promise<ApiWrapper<UpdateEventResponseV1>> {\r\n return this.http.post(`/events/${this.cfg.version}/update`, req);\r\n }\r\n\r\n /** POST /events/{version}/delete */\r\n delete(req: DeleteEventRequestV1): Promise<ApiWrapper<DeleteEventResponseV1>> {\r\n return this.http.post(`/events/${this.cfg.version}/delete`, req);\r\n }\r\n}\r\n","import { HttpClient } from \"../http.js\";\r\nimport { ResolvedConfig } from \"../config.js\";\r\nimport { ApiWrapper, ClientHookRequest, UserWebhookRequest, WebhookSchema } from \"../types.js\";\r\n\r\nexport class WebhooksModule {\r\n constructor(\r\n private readonly http: HttpClient,\r\n private readonly cfg: ResolvedConfig,\r\n ) {}\r\n\r\n /** POST /{version}/webhook — register a webhook endpoint */\r\n register(req: ClientHookRequest): Promise<ApiWrapper> {\r\n return this.http.post(`/${this.cfg.version}/webhook`, req);\r\n }\r\n\r\n /** GET /{version}/topic — list all available webhook topics */\r\n getTopics(): Promise<ApiWrapper<string[]>> {\r\n return this.http.get(`/${this.cfg.version}/topic`);\r\n }\r\n\r\n /** GET /{version}/webhook/schema — list available webhook schemas */\r\n listSchemas(): Promise<ApiWrapper<WebhookSchema[]>> {\r\n return this.http.get(`/${this.cfg.version}/webhook/schema`);\r\n }\r\n\r\n /** GET /{version}/webhook/schema/{topic} — get the JSON schema for a specific topic */\r\n getSchema(topic: string): Promise<ApiWrapper<WebhookSchema>> {\r\n return this.http.get(`/${this.cfg.version}/webhook/schema/${encodeURIComponent(topic)}`);\r\n }\r\n\r\n /** POST /user/{version}/subscribe/webhook-event — subscribe specific users to a webhook topic */\r\n subscribeUsers(req: UserWebhookRequest): Promise<ApiWrapper> {\r\n return this.http.post(`/user/${this.cfg.version}/subscribe/webhook-event`, req);\r\n }\r\n\r\n /** DELETE /user/{version}/subscribe/webhook-event — unsubscribe specific users from a webhook topic */\r\n unsubscribeUsers(req: UserWebhookRequest): Promise<ApiWrapper> {\r\n return this.http.delete(`/user/${this.cfg.version}/subscribe/webhook-event`, req);\r\n }\r\n}\r\n","import { DuprClientOptions, ResolvedConfig, resolveConfig } from \"./config.js\";\r\nimport { HttpClient } from \"./http.js\";\r\nimport { AuthModule } from \"./auth.js\";\r\nimport { UsersModule } from \"./resources/users.js\";\r\nimport { PlayersModule } from \"./resources/players.js\";\r\nimport { PlayerRatingModule } from \"./resources/playerRating.js\";\r\nimport { MatchesModule } from \"./resources/matches.js\";\r\nimport { ClubsModule } from \"./resources/clubs.js\";\r\nimport { EventsModule } from \"./resources/events.js\";\r\nimport { WebhooksModule } from \"./resources/webhooks.js\";\r\n\r\nexport class DuprClient {\r\n readonly config: ResolvedConfig;\r\n readonly auth: AuthModule;\r\n readonly users: UsersModule;\r\n readonly players: PlayersModule;\r\n readonly playerRating: PlayerRatingModule;\r\n readonly matches: MatchesModule;\r\n readonly clubs: ClubsModule;\r\n readonly events: EventsModule;\r\n readonly webhooks: WebhooksModule;\r\n\r\n constructor(opts: DuprClientOptions = {}) {\r\n this.config = resolveConfig(opts);\r\n const http = new HttpClient(this.config);\r\n this.auth = new AuthModule(http, this.config);\r\n this.users = new UsersModule(http, this.config);\r\n this.players = new PlayersModule(http, this.config);\r\n this.playerRating = new PlayerRatingModule(http, this.config);\r\n this.matches = new MatchesModule(http, this.config);\r\n this.clubs = new ClubsModule(http, this.config);\r\n this.events = new EventsModule(http, this.config);\r\n this.webhooks = new WebhooksModule(http, this.config);\r\n }\r\n\r\n /** Override the bearer token at runtime — useful when your backend handles auth separately. */\r\n setBearerToken(token: string): void {\r\n this.config.overrideBearerToken = token;\r\n }\r\n\r\n /** Clear the runtime bearer token override and fall back to configured auth. */\r\n clearBearerToken(): void {\r\n delete this.config.overrideBearerToken;\r\n }\r\n}\r\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dupr-js-client",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"description": "A comprehensive TypeScript/JavaScript client for the DUPR (Dynamic Universal Pickleball Rating) API.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Sunny Tambi",
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
"prepublishOnly": "npm run build && npm run typecheck"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
+
"@changesets/cli": "^2.31.0",
|
|
38
39
|
"@types/node": "^20.0.0",
|
|
39
40
|
"@typescript-eslint/eslint-plugin": "^7.0.0",
|
|
40
41
|
"@typescript-eslint/parser": "^7.0.0",
|