@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 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
- /** Get VK OAuth redirect URL */
69
- getVkAuthUrl: (redirectUri: string) => Promise<{
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
- /** Verify VK access token and login/register */
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
- /** 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
+ */
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
- }) => Promise<Game[]>;
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
- /** 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
+ */
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
- /** Get orders by payment code (route is under /checkout prefix) */
203
- 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<{
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
- getVkAuthUrl: (redirectUri) => this.request("GET", `/auth/vk/url?redirect=${encodeURIComponent(redirectUri)}`),
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) => 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
+ },
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gamecore-api/sdk",
3
- "version": "0.9.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",