@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 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
- /** Verify VK access token and login/register */
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
- /** Get all games. Use inStockOnly:true for only games with products. include:"meta" for categories/deliveryTypes. */
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
- }) => Promise<Game[]>;
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
- /** Create checkout (payment + orders). Auto-generates idempotency key. */
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
- /** Get orders by payment code (route is under /checkout prefix) */
186
- getByPayment: (paymentCode: string) => Promise<{
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) => this.request("GET", `/checkout/orders/payment/${paymentCode}`, undefined, { rawResponse: true }),
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gamecore-api/sdk",
3
- "version": "0.8.0",
3
+ "version": "0.12.0",
4
4
  "description": "TypeScript SDK for GameCore API — browser-safe, zero dependencies",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",