@gamecore-api/sdk 0.9.0 → 0.12.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/client.d.ts +106 -9
- package/dist/index.js +23 -2
- package/dist/types.d.ts +60 -0
- package/package.json +1 -1
package/dist/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { TelegramInitResponse, User, SiteConfig, ExchangeRates, LegalDocument, Game, GameDetail, Product, SearchResult, Category, CartItem, CheckoutRequest, CheckoutResponse, Order, UserBalance, LevelStatus, Transaction, Notification, Favorite, Review, ReviewStats, CouponResult, ReferralStats, ReferralLink, ReferralCommission, TopupMethod, TopupResponse, TopupStatus, GiftCard, Announcement, AnnouncementBar, SiteUIConfig, PaymentMethod, CatalogSection, SiteStats, ProductFilters, PaginatedResponse } from "./types";
|
|
1
|
+
import type { TelegramInitResponse, TelegramWidgetUser, TelegramAuthResponse, User, SiteConfig, ExchangeRates, LegalDocument, Game, GameDetail, Product, SearchResult, Category, CartItem, CheckoutRequest, CheckoutResponse, Order, UserBalance, LevelStatus, Transaction, Notification, Favorite, Review, ReviewStats, CouponResult, ReferralStats, ReferralLink, ReferralCommission, TopupMethod, TopupResponse, TopupStatus, GiftCard, Announcement, AnnouncementBar, SiteUIConfig, PaymentMethod, CatalogSection, SiteStats, ProductFilters, PaginatedResponse, PagedGamesResponse } from "./types";
|
|
2
2
|
export interface GameCoreOptions {
|
|
3
3
|
/** Site API key (gc_live_xxx or gc_test_xxx) */
|
|
4
4
|
apiKey: string;
|
|
@@ -65,15 +65,82 @@ export declare class GameCoreClient {
|
|
|
65
65
|
initTelegram: () => Promise<TelegramInitResponse>;
|
|
66
66
|
/** Poll Telegram auth status until authenticated or expired */
|
|
67
67
|
pollTelegramStatus: (token: string, intervalMs?: number) => Promise<User>;
|
|
68
|
-
/**
|
|
69
|
-
|
|
68
|
+
/**
|
|
69
|
+
* Verify Telegram Mini App initData and issue a session cookie.
|
|
70
|
+
* Call this when your storefront is opened inside Telegram via the
|
|
71
|
+
* bot's Mini App / Web App button — `window.Telegram.WebApp.initData`
|
|
72
|
+
* is the raw URL-encoded string you should pass in. The backend
|
|
73
|
+
* validates the HMAC signature against the bot token and mints a
|
|
74
|
+
* normal auth cookie, so the rest of the site stays logged in.
|
|
75
|
+
* Optional `ref` threads a referral code through user creation.
|
|
76
|
+
*/
|
|
77
|
+
verifyMiniApp: (initData: string, ref?: string) => Promise<TelegramAuthResponse>;
|
|
78
|
+
/**
|
|
79
|
+
* Verify Telegram Login Widget payload (JSON POST variant) and
|
|
80
|
+
* issue a session cookie. Use this when you embed the Login Widget
|
|
81
|
+
* with `data-onauth` (JS callback) instead of `data-auth-url`
|
|
82
|
+
* (full-page redirect) — pass the object the widget handed you
|
|
83
|
+
* directly to this method.
|
|
84
|
+
*/
|
|
85
|
+
verifyTelegramWidget: (data: TelegramWidgetUser, ref?: string) => Promise<TelegramAuthResponse>;
|
|
86
|
+
/**
|
|
87
|
+
* Get VK OAuth authorize URL (authorization code flow).
|
|
88
|
+
*
|
|
89
|
+
* Backend generates a single-use state nonce, stores it server-
|
|
90
|
+
* side, and returns a URL pointing at VK with response_type=code.
|
|
91
|
+
* The storefront redirects the user to this URL; VK redirects
|
|
92
|
+
* back to `redirectUri` with ?code=...&state=...; the storefront
|
|
93
|
+
* then calls {@link vkCallback} with those two values.
|
|
94
|
+
*
|
|
95
|
+
* `redirectUri` must exactly match one of the site's allowed
|
|
96
|
+
* origins configured in master-admin — the backend validates
|
|
97
|
+
* this before storing the state. `ref` is an optional referral
|
|
98
|
+
* code that gets threaded through to user registration.
|
|
99
|
+
*/
|
|
100
|
+
getVkAuthUrl: (redirectUri: string, ref?: string) => Promise<{
|
|
70
101
|
url: string;
|
|
102
|
+
state: string;
|
|
71
103
|
}>;
|
|
72
|
-
/**
|
|
104
|
+
/**
|
|
105
|
+
* Exchange an authorization code for a session cookie (code flow).
|
|
106
|
+
* Call this after VK redirects back to your storefront with
|
|
107
|
+
* ?code=...&state=... in the query string. The backend validates
|
|
108
|
+
* state (single-use), exchanges the code with VK server-to-server
|
|
109
|
+
* using the site's client_secret, fetches the user profile, and
|
|
110
|
+
* mints a normal auth cookie. The VK access token never reaches
|
|
111
|
+
* the client.
|
|
112
|
+
*/
|
|
113
|
+
vkCallback: (code: string, state: string) => Promise<{
|
|
114
|
+
status: string;
|
|
115
|
+
user: User;
|
|
116
|
+
}>;
|
|
117
|
+
/**
|
|
118
|
+
* Verify a VK access token from the deprecated implicit flow.
|
|
119
|
+
* @deprecated Use {@link getVkAuthUrl} + {@link vkCallback} instead.
|
|
120
|
+
* This endpoint is kept alive for backwards compatibility while
|
|
121
|
+
* storefronts migrate to the code flow. It will be removed in a
|
|
122
|
+
* future major release.
|
|
123
|
+
*/
|
|
73
124
|
verifyVk: (accessToken: string, ref?: string) => Promise<{
|
|
74
125
|
status: string;
|
|
75
126
|
user: User;
|
|
76
127
|
}>;
|
|
128
|
+
/** Register with email + password. No auth required. */
|
|
129
|
+
register: (email: string, password: string, firstName?: string, ref?: string) => Promise<{
|
|
130
|
+
success: boolean;
|
|
131
|
+
token: string;
|
|
132
|
+
user: User;
|
|
133
|
+
}>;
|
|
134
|
+
/** Login with email + password. No auth required. */
|
|
135
|
+
login: (email: string, password: string) => Promise<{
|
|
136
|
+
success: boolean;
|
|
137
|
+
token: string;
|
|
138
|
+
user: User;
|
|
139
|
+
}>;
|
|
140
|
+
/** Change password (requires auth). Revokes all other sessions. */
|
|
141
|
+
changePassword: (currentPassword: string, newPassword: string) => Promise<{
|
|
142
|
+
success: boolean;
|
|
143
|
+
}>;
|
|
77
144
|
/** Get current authenticated user */
|
|
78
145
|
getMe: () => Promise<User>;
|
|
79
146
|
/** Logout and clear session */
|
|
@@ -102,15 +169,29 @@ export declare class GameCoreClient {
|
|
|
102
169
|
}>;
|
|
103
170
|
};
|
|
104
171
|
catalog: {
|
|
105
|
-
/**
|
|
172
|
+
/**
|
|
173
|
+
* Get paginated games catalog.
|
|
174
|
+
*
|
|
175
|
+
* Returns `{ data: Game[], pagination: { page, limit, total, totalPages, hasMore } }`.
|
|
176
|
+
*
|
|
177
|
+
* @param params.page - Page number (1-based, default 1)
|
|
178
|
+
* @param params.limit - Items per page (1-200, default 50)
|
|
179
|
+
* @param params.inStockOnly - Only games that have products in stock
|
|
180
|
+
* @param params.include - "meta" to include categories/deliveryTypes
|
|
181
|
+
* @param params.sort - Sort order: "popular" | "name" | "new" | "soldCount"
|
|
182
|
+
* @param params.q - Search query (Meilisearch or fallback)
|
|
183
|
+
*/
|
|
106
184
|
getGames: (params?: {
|
|
185
|
+
page?: number;
|
|
186
|
+
limit?: number;
|
|
107
187
|
locale?: string;
|
|
108
188
|
type?: string;
|
|
109
189
|
deliveryType?: string;
|
|
110
190
|
include?: string;
|
|
111
191
|
inStockOnly?: boolean;
|
|
112
192
|
sort?: "popular" | "name" | "new" | "soldCount";
|
|
113
|
-
|
|
193
|
+
q?: string;
|
|
194
|
+
}) => Promise<PagedGamesResponse>;
|
|
114
195
|
/** Get homepage ranked games */
|
|
115
196
|
getHomepageGames: () => Promise<Game[]>;
|
|
116
197
|
/** Get single game with categories */
|
|
@@ -185,7 +266,14 @@ export declare class GameCoreClient {
|
|
|
185
266
|
clear: () => Promise<void>;
|
|
186
267
|
};
|
|
187
268
|
checkout: {
|
|
188
|
-
/**
|
|
269
|
+
/**
|
|
270
|
+
* Create checkout (payment + orders). Auto-generates idempotency key.
|
|
271
|
+
*
|
|
272
|
+
* **Guest checkout:** This method works WITHOUT authentication when
|
|
273
|
+
* `data.email` is provided and `data.paymentMethod` is a gateway
|
|
274
|
+
* (not "balance"). The API creates a guest order tied to the email.
|
|
275
|
+
* No Telegram/VK login required. Balance payments still require auth.
|
|
276
|
+
*/
|
|
189
277
|
create: (data: CheckoutRequest, idempotencyKey?: string) => Promise<CheckoutResponse>;
|
|
190
278
|
/** Complete payment with balance (no external gateway) */
|
|
191
279
|
completeWithBalance: (paymentCode: string) => Promise<{
|
|
@@ -199,8 +287,17 @@ export declare class GameCoreClient {
|
|
|
199
287
|
list: () => Promise<Order[]>;
|
|
200
288
|
/** Get single order by code (includes items + payment) */
|
|
201
289
|
get: (code: string) => Promise<Order>;
|
|
202
|
-
/**
|
|
203
|
-
|
|
290
|
+
/**
|
|
291
|
+
* Get orders by payment code (route is under /checkout prefix).
|
|
292
|
+
*
|
|
293
|
+
* Authenticated users are verified via the session cookie.
|
|
294
|
+
* Guest callers must pass the `guestEmail` used at checkout — the
|
|
295
|
+
* server enforces a case-insensitive match against the payment
|
|
296
|
+
* email before returning any order data. Without it, a guest
|
|
297
|
+
* request returns 404 (the same response as a missing code, so
|
|
298
|
+
* the endpoint does not leak existence of valid codes).
|
|
299
|
+
*/
|
|
300
|
+
getByPayment: (paymentCode: string, guestEmail?: string) => Promise<{
|
|
204
301
|
payment: unknown;
|
|
205
302
|
orders: Order[];
|
|
206
303
|
}>;
|
package/dist/index.js
CHANGED
|
@@ -105,8 +105,20 @@ class GameCoreClient {
|
|
|
105
105
|
}
|
|
106
106
|
}, intervalMs);
|
|
107
107
|
}),
|
|
108
|
-
|
|
108
|
+
verifyMiniApp: (initData, ref) => this.request("POST", "/auth/telegram/miniapp", { initData, ref }, { rawResponse: true }),
|
|
109
|
+
verifyTelegramWidget: (data, ref) => this.request("POST", "/auth/telegram/widget", { ...data, ref }, { rawResponse: true }),
|
|
110
|
+
getVkAuthUrl: (redirectUri, ref) => {
|
|
111
|
+
const params = new URLSearchParams;
|
|
112
|
+
params.set("redirect", redirectUri);
|
|
113
|
+
if (ref)
|
|
114
|
+
params.set("ref", ref);
|
|
115
|
+
return this.request("GET", `/auth/vk/url?${params.toString()}`, undefined, { rawResponse: true });
|
|
116
|
+
},
|
|
117
|
+
vkCallback: (code, state) => this.request("POST", "/auth/vk/callback", { code, state }, { rawResponse: true }),
|
|
109
118
|
verifyVk: (accessToken, ref) => this.request("POST", "/auth/vk/verify", { accessToken, ref }, { rawResponse: true }),
|
|
119
|
+
register: (email, password, firstName, ref) => this.request("POST", "/auth/register", { email, password, firstName, ref }, { rawResponse: true }),
|
|
120
|
+
login: (email, password) => this.request("POST", "/auth/login", { email, password }, { rawResponse: true }),
|
|
121
|
+
changePassword: (currentPassword, newPassword) => this.request("POST", "/auth/change-password", { currentPassword, newPassword }),
|
|
110
122
|
getMe: () => this.request("GET", "/auth/me", undefined, { rawResponse: true }),
|
|
111
123
|
logout: () => this.request("POST", "/auth/logout"),
|
|
112
124
|
getIdentities: () => this.request("GET", "/auth/identities", undefined, { rawResponse: true }),
|
|
@@ -118,6 +130,10 @@ class GameCoreClient {
|
|
|
118
130
|
catalog = {
|
|
119
131
|
getGames: (params) => {
|
|
120
132
|
const qs = new URLSearchParams;
|
|
133
|
+
if (params?.page)
|
|
134
|
+
qs.set("page", String(params.page));
|
|
135
|
+
if (params?.limit)
|
|
136
|
+
qs.set("limit", String(params.limit));
|
|
121
137
|
if (params?.locale)
|
|
122
138
|
qs.set("locale", params.locale);
|
|
123
139
|
if (params?.type)
|
|
@@ -130,6 +146,8 @@ class GameCoreClient {
|
|
|
130
146
|
qs.set("inStockOnly", "true");
|
|
131
147
|
if (params?.sort)
|
|
132
148
|
qs.set("sort", params.sort);
|
|
149
|
+
if (params?.q)
|
|
150
|
+
qs.set("q", params.q);
|
|
133
151
|
const q = qs.toString();
|
|
134
152
|
return this.request("GET", `/catalog/games${q ? `?${q}` : ""}`);
|
|
135
153
|
},
|
|
@@ -189,7 +207,10 @@ class GameCoreClient {
|
|
|
189
207
|
orders = {
|
|
190
208
|
list: () => this.request("GET", "/orders"),
|
|
191
209
|
get: (code) => this.request("GET", `/orders/${code}`),
|
|
192
|
-
getByPayment: (paymentCode) =>
|
|
210
|
+
getByPayment: (paymentCode, guestEmail) => {
|
|
211
|
+
const qs = guestEmail ? `?email=${encodeURIComponent(guestEmail)}` : "";
|
|
212
|
+
return this.request("GET", `/checkout/orders/payment/${paymentCode}${qs}`, undefined, { rawResponse: true });
|
|
213
|
+
},
|
|
193
214
|
cancelPreview: (code) => this.request("GET", `/orders/${code}/cancel-preview`),
|
|
194
215
|
cancel: (code) => this.request("POST", `/orders/${code}/cancel`)
|
|
195
216
|
};
|
package/dist/types.d.ts
CHANGED
|
@@ -8,6 +8,47 @@ export interface AuthStatusResponse {
|
|
|
8
8
|
status: "pending" | "verified" | "authenticated" | "expired" | "used";
|
|
9
9
|
user?: User;
|
|
10
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* Payload returned by Telegram Login Widget when the user completes
|
|
13
|
+
* authentication. Same shape as Telegram's official docs — you can hand
|
|
14
|
+
* this object directly to auth.verifyTelegramWidget().
|
|
15
|
+
* https://core.telegram.org/widgets/login
|
|
16
|
+
*/
|
|
17
|
+
export interface TelegramWidgetUser {
|
|
18
|
+
id: number;
|
|
19
|
+
first_name: string;
|
|
20
|
+
last_name?: string;
|
|
21
|
+
username?: string;
|
|
22
|
+
photo_url?: string;
|
|
23
|
+
auth_date: number;
|
|
24
|
+
hash: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Narrow user DTO returned by /auth/telegram/miniapp and /auth/telegram/widget.
|
|
28
|
+
* This is intentionally a subset of the full {@link User} type — the auth
|
|
29
|
+
* endpoints only echo identity + role, not balance/level/email fields, so
|
|
30
|
+
* typing it as `User` would lie to SDK consumers. Call auth.getMe() after
|
|
31
|
+
* login if the storefront needs the full profile.
|
|
32
|
+
*/
|
|
33
|
+
export interface TelegramAuthUser {
|
|
34
|
+
id: number;
|
|
35
|
+
telegramId: string | null;
|
|
36
|
+
firstName: string | null;
|
|
37
|
+
lastName: string | null;
|
|
38
|
+
username: string | null;
|
|
39
|
+
photoUrl: string | null;
|
|
40
|
+
role: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Response from the Mini App / Widget POST verification endpoints.
|
|
44
|
+
* Body includes success, status and (on success) the authenticated user.
|
|
45
|
+
*/
|
|
46
|
+
export interface TelegramAuthResponse {
|
|
47
|
+
success: boolean;
|
|
48
|
+
status?: "authenticated";
|
|
49
|
+
user?: TelegramAuthUser;
|
|
50
|
+
error?: string;
|
|
51
|
+
}
|
|
11
52
|
export interface User {
|
|
12
53
|
id: number;
|
|
13
54
|
firstName: string;
|
|
@@ -84,9 +125,17 @@ export interface GameDetail {
|
|
|
84
125
|
name: string;
|
|
85
126
|
icon: string | null;
|
|
86
127
|
localIcon?: string | null;
|
|
128
|
+
/** Landscape hero image (1200x630). Null if no gallery is available. */
|
|
87
129
|
coverImage?: string | null;
|
|
130
|
+
/** Gallery of product screenshots (resized to 800x600). */
|
|
88
131
|
images?: string[];
|
|
89
132
|
description: string | null;
|
|
133
|
+
/** Editorial badges like "hit", "new", "popular", "sale". */
|
|
134
|
+
tags?: string[];
|
|
135
|
+
/** Availability lifecycle. Shares the union from {@link Game}. */
|
|
136
|
+
availabilityStatus?: "available" | "coming_soon" | "maintenance" | "discontinued";
|
|
137
|
+
/** Human-readable message for non-available games. */
|
|
138
|
+
availabilityMessage?: string | null;
|
|
90
139
|
inStock?: boolean;
|
|
91
140
|
productCount?: number;
|
|
92
141
|
categories: Category[];
|
|
@@ -496,6 +545,17 @@ export interface PaginatedResponse<T> {
|
|
|
496
545
|
hasMore: boolean;
|
|
497
546
|
};
|
|
498
547
|
}
|
|
548
|
+
/** Catalog games use page-based pagination (page 1, 2, ...) */
|
|
549
|
+
export interface PagedGamesResponse {
|
|
550
|
+
data: Game[];
|
|
551
|
+
pagination: {
|
|
552
|
+
page: number;
|
|
553
|
+
limit: number;
|
|
554
|
+
total: number;
|
|
555
|
+
totalPages: number;
|
|
556
|
+
hasMore: boolean;
|
|
557
|
+
};
|
|
558
|
+
}
|
|
499
559
|
export declare class GameCoreError extends Error {
|
|
500
560
|
status: number;
|
|
501
561
|
code?: string;
|