@exode-team/multicard-uz.api 1.0.1 → 1.0.3

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/PROMPT.md ADDED
@@ -0,0 +1,84 @@
1
+ # Fix: requestApi error handling — circular structure to JSON
2
+
3
+ ## Problem
4
+
5
+ In `src/multicard-api.ts`, the `requestApi` method re-throws the raw Axios error:
6
+
7
+ ```typescript
8
+ } catch (error) {
9
+ console.error(...);
10
+ throw error; // Raw Axios error with circular refs!
11
+ }
12
+ ```
13
+
14
+ Axios error objects contain `error.request` (ClientRequest) and `error.response.req` (IncomingMessage) which form a circular reference: `ClientRequest.res → IncomingMessage.req → ClientRequest`.
15
+
16
+ When this error bubbles up to Apollo Server (GraphQL), it tries to `JSON.stringify` the error → **"Converting circular structure to JSON"**.
17
+
18
+ ## Fix
19
+
20
+ In `src/multicard-api.ts`, change the `catch` block in `requestApi` to return a `MulticardErrorResponse` instead of throwing:
21
+
22
+ **From:**
23
+ ```typescript
24
+ } catch (error) {
25
+ const response = (error as any)?.response;
26
+
27
+ console.error(
28
+ '[PACKAGE:multicard-uz.api]',
29
+ `status=${response?.status}`,
30
+ `config=[${JSON.stringify(config)}]`,
31
+ JSON.stringify(response?.data),
32
+ );
33
+
34
+ throw error;
35
+ }
36
+ ```
37
+
38
+ **To:**
39
+ ```typescript
40
+ } catch (error) {
41
+ const response = (error as any)?.response;
42
+
43
+ console.error(
44
+ '[PACKAGE:multicard-uz.api]',
45
+ `status=${response?.status}`,
46
+ `config=[${JSON.stringify(config)}]`,
47
+ JSON.stringify(response?.data),
48
+ );
49
+
50
+ return {
51
+ success: false,
52
+ error: {
53
+ code: MulticardErrorCode.ERROR_UNKNOWN,
54
+ details: response?.data?.message
55
+ || response?.data?.error?.details
56
+ || (error as Error).message
57
+ || 'Unknown error',
58
+ },
59
+ } as T;
60
+ }
61
+ ```
62
+
63
+ Also add `MulticardErrorCode` to the imports at the top of the file:
64
+ ```typescript
65
+ import {
66
+ // ... existing imports
67
+ MulticardErrorCode,
68
+ // ...
69
+ } from './types';
70
+ ```
71
+
72
+ ## Why
73
+
74
+ - All Multicard provider methods already check `response.success` before using `response.data`
75
+ - Returning `{ success: false, error: {...} }` lets the consumer handle errors gracefully
76
+ - No circular references in the error object
77
+ - Consistent with the `MulticardResponse` type contract
78
+
79
+ ## After fix
80
+
81
+ Bump version to `1.0.2`, build and publish:
82
+ ```bash
83
+ npm version patch && yarn build && npm publish
84
+ ```
@@ -21,7 +21,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
21
21
  if (v !== undefined) module.exports = v;
22
22
  }
23
23
  else if (typeof define === "function" && define.amd) {
24
- define(["require", "exports", "axios", "./multicard-base"], factory);
24
+ define(["require", "exports", "axios", "./multicard-base", "./types"], factory);
25
25
  }
26
26
  })(function (require, exports) {
27
27
  "use strict";
@@ -29,6 +29,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
29
29
  exports.MulticardApi = void 0;
30
30
  const axios_1 = __importDefault(require("axios"));
31
31
  const multicard_base_1 = require("./multicard-base");
32
+ const types_1 = require("./types");
32
33
  class MulticardApi extends multicard_base_1.MulticardBase {
33
34
  /**
34
35
  * Запрос к API
@@ -41,6 +42,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
41
42
  */
42
43
  requestApi(apiUrl_1) {
43
44
  return __awaiter(this, arguments, void 0, function* (apiUrl, data = {}, headers, httpMethod = 'post') {
45
+ var _a, _b, _c;
44
46
  const config = {
45
47
  timeout: this.timeoutMs,
46
48
  url: `${this.baseUrl}${apiUrl}`,
@@ -60,7 +62,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
60
62
  catch (error) {
61
63
  const response = error === null || error === void 0 ? void 0 : error.response;
62
64
  console.error('[PACKAGE:multicard-uz.api]', `status=${response === null || response === void 0 ? void 0 : response.status}`, `config=[${JSON.stringify(config)}]`, JSON.stringify(response === null || response === void 0 ? void 0 : response.data));
63
- throw error;
65
+ return {
66
+ success: false,
67
+ error: {
68
+ code: types_1.MulticardErrorCode.ERROR_UNKNOWN,
69
+ details: ((_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.message)
70
+ || ((_c = (_b = response === null || response === void 0 ? void 0 : response.data) === null || _b === void 0 ? void 0 : _b.error) === null || _c === void 0 ? void 0 : _c.details)
71
+ || error.message
72
+ || 'Unknown error',
73
+ },
74
+ };
64
75
  }
65
76
  });
66
77
  }
package/dist/types.d.ts CHANGED
@@ -164,32 +164,14 @@ export interface CardBindSession {
164
164
  form_url: string;
165
165
  }
166
166
  export type CardBindCreateResponse = MulticardSuccessResponse<CardBindSession>;
167
- export interface CardBindStatusData {
168
- /** Идентификатор сессии привязки */
169
- session_id: string;
170
- /** Статус привязки */
171
- status: string;
172
- /** Данные карты (при успешной привязке) */
173
- card?: CardModel;
174
- }
167
+ /** Ответ проверки привязки — плоская модель карты (без вложенного card) */
168
+ export type CardBindStatusData = CardModel;
175
169
  export type CardBindGetStatusResponse = MulticardSuccessResponse<CardBindStatusData>;
176
170
  /**
177
171
  * @Card Binding Callback:
178
172
  */
179
- export interface CardBindCallbackPayload {
180
- /** Токен привязанной карты */
181
- card_token: string;
182
- /** Маскированный номер карты */
183
- card_pan: string;
184
- /** Номер телефона держателя карты */
185
- phone: string;
186
- /** Платёжная система */
187
- ps: MulticardPaymentService;
188
- /** Имя держателя карты */
189
- holder_name?: string;
190
- /** Идентификатор пользователя */
191
- payer_id?: string;
192
- }
173
+ /** Тело callback'а привязки совпадает с моделью карты (подписи нет) */
174
+ export type CardBindCallbackPayload = CardModel;
193
175
  /**
194
176
  * @Card Management:
195
177
  */
@@ -198,8 +180,10 @@ export interface CardModel {
198
180
  id: number;
199
181
  /** ID приложения */
200
182
  application_id: number;
201
- /** Идентификатор пользователя */
183
+ /** Идентификатор пользователя (payer_id из запроса привязки) */
202
184
  payer_id: string;
185
+ /** Идентификатор сессии привязки */
186
+ session_id: string;
203
187
  /** Маскированный номер карты */
204
188
  card_pan: string;
205
189
  /** Токен карты */
@@ -220,9 +204,11 @@ export interface CardModel {
220
204
  card_status: {
221
205
  code: number;
222
206
  description: string;
223
- };
207
+ } | null;
224
208
  /** Подключено ли SMS-информирование */
225
- sms_inform: boolean;
209
+ sms_inform: boolean | null;
210
+ /** Карта Multicard */
211
+ is_multicard: boolean;
226
212
  }
227
213
  export type CardGetResponse = MulticardSuccessResponse<CardModel>;
228
214
  export type CardDeleteResponse = MulticardSuccessResponse<void>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exode-team/multicard-uz.api",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "multicard.uz API",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",