@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 +84 -0
- package/dist/multicard-api.js +13 -2
- package/dist/types.d.ts +11 -25
- package/package.json +1 -1
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
|
+
```
|
package/dist/multicard-api.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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>;
|