@gamecore-api/sdk 0.8.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 +141 -7
- package/dist/index.js +28 -1
- package/dist/types.d.ts +62 -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;
|
|
@@ -22,6 +22,19 @@ export declare class GameCoreClient {
|
|
|
22
22
|
getLegal: (type: string, locale?: string) => Promise<LegalDocument>;
|
|
23
23
|
/** Get site statistics for trust signals (cached 5 min on server) */
|
|
24
24
|
getStats: () => Promise<SiteStats>;
|
|
25
|
+
/** Get social proof — recent purchases for trust display */
|
|
26
|
+
getSocialProof: () => Promise<{
|
|
27
|
+
recentPurchases: Array<{
|
|
28
|
+
gameName: string;
|
|
29
|
+
timeAgo: string;
|
|
30
|
+
}>;
|
|
31
|
+
}>;
|
|
32
|
+
/** Get theme config (white-label colors, fonts, borderRadius) */
|
|
33
|
+
getThemeConfig: () => Promise<{
|
|
34
|
+
colors: Record<string, string>;
|
|
35
|
+
borderRadius: string;
|
|
36
|
+
font: string;
|
|
37
|
+
}>;
|
|
25
38
|
/** Get site translations for a locale (Record<key, value>) */
|
|
26
39
|
getTranslations: (locale?: string) => Promise<Record<string, string>>;
|
|
27
40
|
/** Get site UI config (header, footer, nav, trust pills) */
|
|
@@ -52,11 +65,82 @@ export declare class GameCoreClient {
|
|
|
52
65
|
initTelegram: () => Promise<TelegramInitResponse>;
|
|
53
66
|
/** Poll Telegram auth status until authenticated or expired */
|
|
54
67
|
pollTelegramStatus: (token: string, intervalMs?: number) => Promise<User>;
|
|
55
|
-
/**
|
|
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<{
|
|
101
|
+
url: string;
|
|
102
|
+
state: string;
|
|
103
|
+
}>;
|
|
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
|
+
*/
|
|
56
124
|
verifyVk: (accessToken: string, ref?: string) => Promise<{
|
|
57
125
|
status: string;
|
|
58
126
|
user: User;
|
|
59
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
|
+
}>;
|
|
60
144
|
/** Get current authenticated user */
|
|
61
145
|
getMe: () => Promise<User>;
|
|
62
146
|
/** Logout and clear session */
|
|
@@ -85,15 +169,29 @@ export declare class GameCoreClient {
|
|
|
85
169
|
}>;
|
|
86
170
|
};
|
|
87
171
|
catalog: {
|
|
88
|
-
/**
|
|
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
|
+
*/
|
|
89
184
|
getGames: (params?: {
|
|
185
|
+
page?: number;
|
|
186
|
+
limit?: number;
|
|
90
187
|
locale?: string;
|
|
91
188
|
type?: string;
|
|
92
189
|
deliveryType?: string;
|
|
93
190
|
include?: string;
|
|
94
191
|
inStockOnly?: boolean;
|
|
95
192
|
sort?: "popular" | "name" | "new" | "soldCount";
|
|
96
|
-
|
|
193
|
+
q?: string;
|
|
194
|
+
}) => Promise<PagedGamesResponse>;
|
|
97
195
|
/** Get homepage ranked games */
|
|
98
196
|
getHomepageGames: () => Promise<Game[]>;
|
|
99
197
|
/** Get single game with categories */
|
|
@@ -168,7 +266,14 @@ export declare class GameCoreClient {
|
|
|
168
266
|
clear: () => Promise<void>;
|
|
169
267
|
};
|
|
170
268
|
checkout: {
|
|
171
|
-
/**
|
|
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
|
+
*/
|
|
172
277
|
create: (data: CheckoutRequest, idempotencyKey?: string) => Promise<CheckoutResponse>;
|
|
173
278
|
/** Complete payment with balance (no external gateway) */
|
|
174
279
|
completeWithBalance: (paymentCode: string) => Promise<{
|
|
@@ -182,11 +287,28 @@ export declare class GameCoreClient {
|
|
|
182
287
|
list: () => Promise<Order[]>;
|
|
183
288
|
/** Get single order by code (includes items + payment) */
|
|
184
289
|
get: (code: string) => Promise<Order>;
|
|
185
|
-
/**
|
|
186
|
-
|
|
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<{
|
|
187
301
|
payment: unknown;
|
|
188
302
|
orders: Order[];
|
|
189
303
|
}>;
|
|
304
|
+
/** Preview cancel — check if cancellable and refund amount */
|
|
305
|
+
cancelPreview: (code: string) => Promise<{
|
|
306
|
+
canCancel: boolean;
|
|
307
|
+
reason?: string;
|
|
308
|
+
refundAmount?: number;
|
|
309
|
+
refundTo?: string;
|
|
310
|
+
message?: string;
|
|
311
|
+
}>;
|
|
190
312
|
/** Cancel a pending order */
|
|
191
313
|
cancel: (code: string) => Promise<{
|
|
192
314
|
status: string;
|
|
@@ -218,6 +340,18 @@ export declare class GameCoreClient {
|
|
|
218
340
|
deleteAccount: () => Promise<void>;
|
|
219
341
|
/** Export user data (GDPR) */
|
|
220
342
|
exportData: () => Promise<Record<string, unknown>>;
|
|
343
|
+
/** Get user preferences (language, currency, notifications) */
|
|
344
|
+
getSettings: () => Promise<{
|
|
345
|
+
language: string;
|
|
346
|
+
currency: string;
|
|
347
|
+
emailNotifications: boolean;
|
|
348
|
+
}>;
|
|
349
|
+
/** Update user preferences */
|
|
350
|
+
updateSettings: (data: {
|
|
351
|
+
language?: string;
|
|
352
|
+
currency?: string;
|
|
353
|
+
emailNotifications?: boolean;
|
|
354
|
+
}) => Promise<void>;
|
|
221
355
|
/** Subscribe to broadcast notifications */
|
|
222
356
|
subscribeBroadcast: () => Promise<void>;
|
|
223
357
|
/** Unsubscribe from broadcast notifications */
|
package/dist/index.js
CHANGED
|
@@ -77,6 +77,8 @@ class GameCoreClient {
|
|
|
77
77
|
getRates: () => this.request("GET", "/rates"),
|
|
78
78
|
getLegal: (type, locale) => this.request("GET", `/legal/${type}${locale ? `?locale=${locale}` : ""}`),
|
|
79
79
|
getStats: () => this.request("GET", "/site/stats"),
|
|
80
|
+
getSocialProof: () => this.request("GET", "/site/social-proof"),
|
|
81
|
+
getThemeConfig: () => this.request("GET", "/site/theme"),
|
|
80
82
|
getTranslations: (locale = "ru") => this.request("GET", `/site/translations?locale=${locale}`),
|
|
81
83
|
getUIConfig: () => this.request("GET", "/site/ui-config"),
|
|
82
84
|
getCookieConsent: () => this.request("GET", "/site/cookie-consent"),
|
|
@@ -103,7 +105,20 @@ class GameCoreClient {
|
|
|
103
105
|
}
|
|
104
106
|
}, intervalMs);
|
|
105
107
|
}),
|
|
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 }),
|
|
106
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 }),
|
|
107
122
|
getMe: () => this.request("GET", "/auth/me", undefined, { rawResponse: true }),
|
|
108
123
|
logout: () => this.request("POST", "/auth/logout"),
|
|
109
124
|
getIdentities: () => this.request("GET", "/auth/identities", undefined, { rawResponse: true }),
|
|
@@ -115,6 +130,10 @@ class GameCoreClient {
|
|
|
115
130
|
catalog = {
|
|
116
131
|
getGames: (params) => {
|
|
117
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));
|
|
118
137
|
if (params?.locale)
|
|
119
138
|
qs.set("locale", params.locale);
|
|
120
139
|
if (params?.type)
|
|
@@ -127,6 +146,8 @@ class GameCoreClient {
|
|
|
127
146
|
qs.set("inStockOnly", "true");
|
|
128
147
|
if (params?.sort)
|
|
129
148
|
qs.set("sort", params.sort);
|
|
149
|
+
if (params?.q)
|
|
150
|
+
qs.set("q", params.q);
|
|
130
151
|
const q = qs.toString();
|
|
131
152
|
return this.request("GET", `/catalog/games${q ? `?${q}` : ""}`);
|
|
132
153
|
},
|
|
@@ -186,7 +207,11 @@ class GameCoreClient {
|
|
|
186
207
|
orders = {
|
|
187
208
|
list: () => this.request("GET", "/orders"),
|
|
188
209
|
get: (code) => this.request("GET", `/orders/${code}`),
|
|
189
|
-
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
|
+
},
|
|
214
|
+
cancelPreview: (code) => this.request("GET", `/orders/${code}/cancel-preview`),
|
|
190
215
|
cancel: (code) => this.request("POST", `/orders/${code}/cancel`)
|
|
191
216
|
};
|
|
192
217
|
profile = {
|
|
@@ -208,6 +233,8 @@ class GameCoreClient {
|
|
|
208
233
|
markAllRead: () => this.request("POST", "/profile/notifications/read-all"),
|
|
209
234
|
deleteAccount: () => this.request("POST", "/profile/delete-account"),
|
|
210
235
|
exportData: () => this.request("GET", "/profile/export"),
|
|
236
|
+
getSettings: () => this.request("GET", "/profile/settings"),
|
|
237
|
+
updateSettings: (data) => this.request("PUT", "/profile/settings", data),
|
|
211
238
|
subscribeBroadcast: () => this.request("POST", "/profile/broadcast/subscribe"),
|
|
212
239
|
unsubscribeBroadcast: () => this.request("POST", "/profile/broadcast/unsubscribe"),
|
|
213
240
|
getBroadcastStatus: () => this.request("GET", "/profile/broadcast/status")
|
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;
|
|
@@ -69,6 +110,8 @@ export interface Game {
|
|
|
69
110
|
inStock: boolean;
|
|
70
111
|
soldCount?: number;
|
|
71
112
|
tags?: string[];
|
|
113
|
+
availabilityStatus?: "available" | "coming_soon" | "maintenance" | "discontinued";
|
|
114
|
+
availabilityMessage?: string | null;
|
|
72
115
|
minPrice?: number | null;
|
|
73
116
|
type?: string;
|
|
74
117
|
deliveryTypes?: string[];
|
|
@@ -82,9 +125,17 @@ export interface GameDetail {
|
|
|
82
125
|
name: string;
|
|
83
126
|
icon: string | null;
|
|
84
127
|
localIcon?: string | null;
|
|
128
|
+
/** Landscape hero image (1200x630). Null if no gallery is available. */
|
|
85
129
|
coverImage?: string | null;
|
|
130
|
+
/** Gallery of product screenshots (resized to 800x600). */
|
|
86
131
|
images?: string[];
|
|
87
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;
|
|
88
139
|
inStock?: boolean;
|
|
89
140
|
productCount?: number;
|
|
90
141
|
categories: Category[];
|
|
@@ -494,6 +545,17 @@ export interface PaginatedResponse<T> {
|
|
|
494
545
|
hasMore: boolean;
|
|
495
546
|
};
|
|
496
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
|
+
}
|
|
497
559
|
export declare class GameCoreError extends Error {
|
|
498
560
|
status: number;
|
|
499
561
|
code?: string;
|