sdk: loginWithCustom facade + regenerated models
This commit is contained in:
+41
-4
@@ -1,15 +1,15 @@
|
||||
/**
|
||||
* AuthService — device-based player authentication.
|
||||
* AuthService — player authentication.
|
||||
*
|
||||
* Handles login via device ID (the primary auth flow for game clients),
|
||||
* logout (token clearing), and auth state observation.
|
||||
* Handles login via device ID (the primary auth flow for game clients) or a
|
||||
* custom backend webhook, logout (token clearing), and auth state observation.
|
||||
*/
|
||||
|
||||
import type { RudderContext } from '../core/context.js';
|
||||
import type { RemoteConfigShape } from '../state/RemoteConfigState.js';
|
||||
import { getOrCreateDeviceId } from '../device/DeviceId.js';
|
||||
import { api } from '../generated/api.js';
|
||||
import type { LoginViaDeviceResponse } from '../generated/auth.js';
|
||||
import type { LoginViaCustomResponse, LoginViaDeviceResponse } from '../generated/auth.js';
|
||||
|
||||
export type AuthState = 'signed-in' | 'signed-out';
|
||||
|
||||
@@ -24,6 +24,17 @@ export interface LoginWithDeviceOptions {
|
||||
nickname?: string;
|
||||
}
|
||||
|
||||
export interface LoginWithCustomOptions {
|
||||
/** Arbitrary payload forwarded to the developer's custom auth webhook. */
|
||||
customData: Record<string, unknown>;
|
||||
/** Player's region code (default: "global"). */
|
||||
region?: string;
|
||||
/** Player's language code (default: "en"). */
|
||||
language?: string;
|
||||
/** Optional player nickname; omitted from the request when not set. */
|
||||
nickname?: string;
|
||||
}
|
||||
|
||||
export class AuthService<TConfig extends RemoteConfigShape = RemoteConfigShape> {
|
||||
private readonly listeners = new Set<AuthStateListener>();
|
||||
private state: AuthState;
|
||||
@@ -81,6 +92,32 @@ export class AuthService<TConfig extends RemoteConfigShape = RemoteConfigShape>
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticates via the project's custom authorization webhook and returns
|
||||
* access + refresh tokens.
|
||||
*
|
||||
* The payload is forwarded to the developer's backend; on success, tokens are
|
||||
* saved to the client's TokenStore.
|
||||
*/
|
||||
async loginWithCustom(options: LoginWithCustomOptions): Promise<LoginViaCustomResponse> {
|
||||
const { customData, region = 'global', language = 'en', nickname } = options;
|
||||
const response = await api.loginViaCustom(this.ctx, {
|
||||
key: this.ctx.options.projectKey,
|
||||
customData,
|
||||
region,
|
||||
language,
|
||||
nickname,
|
||||
});
|
||||
|
||||
this.ctx.options.tokenStore.saveTokens(
|
||||
response.accessToken ?? '',
|
||||
response.refreshToken ?? '',
|
||||
);
|
||||
await this.startRuntime();
|
||||
this.setState('signed-in');
|
||||
return response;
|
||||
}
|
||||
|
||||
/** Clears all stored tokens (logout). */
|
||||
logout(): void {
|
||||
this.ctx.options.tokenStore.clear();
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
// Code generated by apigen. DO NOT EDIT.
|
||||
|
||||
import type { LoginViaDeviceRequest, LoginViaDeviceResponse, RefreshAccessTokenRequest, RefreshAccessTokenResponse } from './auth.js';
|
||||
import type { LoginViaCustomRequest, LoginViaCustomResponse, LoginViaDeviceRequest, LoginViaDeviceResponse, RefreshAccessTokenRequest, RefreshAccessTokenResponse } from './auth.js';
|
||||
import type { AddBattlePassXpRequest, AddBattlePassXpResponse, ClaimBattlePassRewardRequest, ClaimBattlePassRewardResponse, GetBattlePassProgressRequest, GetBattlePassProgressResponse, PurchaseBattlePassPremiumRequest, PurchaseBattlePassPremiumResponse } from './battlepass.js';
|
||||
import type { ListCatalogItemsResponse } from './catalog.js';
|
||||
import type { GetInventoryResponse } from './inventory.js';
|
||||
import type { GetRankingResponse, SubmitScoreRequest } from './leaderboards.js';
|
||||
import type { PlayerProfile } from './player.js';
|
||||
import type { GetProjectStorageResponse, UpdateProjectStorageRequest } from './project-storage.js';
|
||||
import type { ClaimQuestRequest, ClaimQuestResponse, ListQuestsRequest, ListQuestsResponse, ReportQuestProgressRequest, ReportQuestProgressResponse } from './quests.js';
|
||||
import type { ClaimQuestRequest, ClaimQuestResponse, ListQuestsResponse, ReportQuestProgressRequest, ReportQuestProgressResponse } from './quests.js';
|
||||
import type { ListRemoteConfigsResponse, RemoteConfig } from './remote-config.js';
|
||||
import type { GetScenarioRunRequest, GetScenarioRunResponse, HandleScenarioCallbackRequest, HandleScenarioCallbackResponse, TriggerScenarioRequest, TriggerScenarioResponse, UpdateScenarioCounterRequest, UpdateScenarioCounterResponse } from './scenarios.js';
|
||||
import type { GetStorageResponse, UpdateStorageRequest } from './storage.js';
|
||||
@@ -131,9 +131,8 @@ export const api = {
|
||||
|
||||
listQuests: (
|
||||
t: Transport,
|
||||
body: ListQuestsRequest,
|
||||
): Promise<ListQuestsResponse> =>
|
||||
t.request<ListQuestsResponse>('POST', '/sdk/v1/quests/list', body),
|
||||
t.request<ListQuestsResponse>('POST', '/sdk/v1/quests/list'),
|
||||
|
||||
listSdkRemoteConfigs: (
|
||||
t: Transport,
|
||||
@@ -145,6 +144,12 @@ export const api = {
|
||||
): Promise<ListStoresResponse> =>
|
||||
t.request<ListStoresResponse>('GET', '/sdk/v1/stores'),
|
||||
|
||||
loginViaCustom: (
|
||||
t: Transport,
|
||||
body: LoginViaCustomRequest,
|
||||
): Promise<LoginViaCustomResponse> =>
|
||||
t.request<LoginViaCustomResponse>('POST', '/sdk/v1/authorization/custom', body),
|
||||
|
||||
loginViaDevice: (
|
||||
t: Transport,
|
||||
body: LoginViaDeviceRequest,
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
// Code generated by apigen. DO NOT EDIT.
|
||||
|
||||
export interface LoginViaCustomRequest {
|
||||
"customData"?: { [key: string]: unknown };
|
||||
"key"?: string;
|
||||
"language"?: string;
|
||||
"nickname"?: string;
|
||||
"region"?: string;
|
||||
}
|
||||
|
||||
export interface LoginViaCustomResponse {
|
||||
"accessToken"?: string;
|
||||
"refreshToken"?: string;
|
||||
}
|
||||
|
||||
export interface LoginViaDeviceRequest {
|
||||
"deviceId"?: string;
|
||||
"key"?: string;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Code generated by apigen. DO NOT EDIT.
|
||||
|
||||
import type { ExecutionPlan } from './common.js';
|
||||
import type { ExecutionPlan, Reward } from './common.js';
|
||||
|
||||
export interface AddBattlePassXpRequest {
|
||||
"amount"?: number;
|
||||
@@ -18,24 +18,18 @@ export interface AddBattlePassXpResponse {
|
||||
"xp"?: number;
|
||||
}
|
||||
|
||||
export interface BattlePassReward {
|
||||
"amount"?: number;
|
||||
"currency"?: string;
|
||||
"itemId"?: string;
|
||||
}
|
||||
|
||||
export interface ClaimBattlePassRewardRequest {
|
||||
"level"?: number;
|
||||
"nodeId"?: string;
|
||||
"runId"?: string;
|
||||
"scenarioId"?: string;
|
||||
"track"?: string;
|
||||
"track"?: "free" | "premium";
|
||||
}
|
||||
|
||||
export interface ClaimBattlePassRewardResponse {
|
||||
"alreadyClaimed"?: boolean;
|
||||
"error"?: string;
|
||||
"granted"?: BattlePassReward[];
|
||||
"granted"?: Reward[];
|
||||
"success"?: boolean;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@ export interface BoundaryNode {
|
||||
export interface ErrorResponse {
|
||||
"code"?: "early_completion" | "forbidden" | "level_not_reached" | "node_not_active" | "objectives_incomplete" | "run_expired" | "run_not_active" | "scenario_not_active" | "unknown_run";
|
||||
"error"?: string;
|
||||
"index"?: number;
|
||||
"playerId"?: string;
|
||||
"requestId"?: string;
|
||||
}
|
||||
|
||||
@@ -42,3 +44,9 @@ export interface PlanEdge {
|
||||
"targetHandle"?: string;
|
||||
}
|
||||
|
||||
export interface Reward {
|
||||
"amount"?: number;
|
||||
"currency"?: string;
|
||||
"itemId"?: string;
|
||||
}
|
||||
|
||||
|
||||
+5
-12
@@ -1,5 +1,7 @@
|
||||
// Code generated by apigen. DO NOT EDIT.
|
||||
|
||||
import type { Reward } from './common.js';
|
||||
|
||||
export interface ClaimQuestRequest {
|
||||
"questId"?: string;
|
||||
}
|
||||
@@ -7,13 +9,10 @@ export interface ClaimQuestRequest {
|
||||
export interface ClaimQuestResponse {
|
||||
"alreadyClaimed"?: boolean;
|
||||
"error"?: string;
|
||||
"granted"?: QuestReward[];
|
||||
"granted"?: Reward[];
|
||||
"success"?: boolean;
|
||||
}
|
||||
|
||||
export interface ListQuestsRequest {
|
||||
}
|
||||
|
||||
export interface ListQuestsResponse {
|
||||
"quests"?: Quest[];
|
||||
}
|
||||
@@ -22,8 +21,8 @@ export interface Quest {
|
||||
"id"?: string;
|
||||
"name"?: string;
|
||||
"objectives"?: QuestObjectiveProgress[];
|
||||
"rewards"?: QuestReward[];
|
||||
"status"?: string;
|
||||
"rewards"?: Reward[];
|
||||
"status"?: "active" | "claimed" | "completed";
|
||||
}
|
||||
|
||||
export interface QuestObjectiveProgress {
|
||||
@@ -34,12 +33,6 @@ export interface QuestObjectiveProgress {
|
||||
"target"?: number;
|
||||
}
|
||||
|
||||
export interface QuestReward {
|
||||
"amount"?: number;
|
||||
"currency"?: string;
|
||||
"itemId"?: string;
|
||||
}
|
||||
|
||||
export interface ReportQuestProgressRequest {
|
||||
"amount"?: number;
|
||||
"metric"?: string;
|
||||
|
||||
@@ -14,6 +14,6 @@ export interface RemoteConfig {
|
||||
"projectId"?: string;
|
||||
"updatedAt"?: string;
|
||||
"value"?: string;
|
||||
"valueType"?: string;
|
||||
"valueType"?: "bool" | "float" | "int" | "json" | "string";
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ export interface GetScenarioRunRequest {
|
||||
export interface GetScenarioRunResponse {
|
||||
"plan"?: ExecutionPlan;
|
||||
"runId"?: string;
|
||||
"status"?: string;
|
||||
"status"?: "active" | "completed" | "expired";
|
||||
}
|
||||
|
||||
export interface HandleScenarioCallbackRequest {
|
||||
|
||||
+2
-2
@@ -22,6 +22,7 @@ export type {
|
||||
AuthService,
|
||||
AuthState,
|
||||
AuthStateListener,
|
||||
LoginWithCustomOptions,
|
||||
LoginWithDeviceOptions,
|
||||
} from './auth/AuthService.js';
|
||||
export type { LeaderboardsService, LeaderboardHandle } from './leaderboards/LeaderboardsService.js';
|
||||
@@ -88,14 +89,13 @@ export type {
|
||||
ProjectStorageUpdateItem,
|
||||
} from './generated/project-storage.js';
|
||||
export type { RemoteConfig } from './generated/remote-config.js';
|
||||
export type { Reward } from './generated/common.js';
|
||||
export type {
|
||||
Quest,
|
||||
QuestObjectiveProgress,
|
||||
QuestReward,
|
||||
ClaimQuestResponse,
|
||||
} from './generated/quests.js';
|
||||
export type {
|
||||
BattlePassReward,
|
||||
ClaimedTier,
|
||||
AddBattlePassXpRequest,
|
||||
AddBattlePassXpResponse,
|
||||
|
||||
Reference in New Issue
Block a user