squarefi-bff-api-module 1.28.0 → 1.29.1
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/.prettierignore +1 -0
- package/dist/api/orders.d.ts +1 -0
- package/dist/api/orders.js +3 -0
- package/dist/api/types/autogen/apiV2.types.d.ts +2 -0
- package/dist/api/types/types.d.ts +40 -1
- package/dist/constants.d.ts +2 -0
- package/dist/constants.js +2 -0
- package/dist/hooks/useFileUpload.d.ts +34 -0
- package/dist/hooks/useFileUpload.js +98 -0
- package/dist/hooks/useUserFiles.d.ts +49 -0
- package/dist/hooks/useUserFiles.js +118 -0
- package/dist/utils/fileStorage.d.ts +111 -0
- package/dist/utils/fileStorage.js +342 -0
- package/package.json +1 -2
- package/src/api/orders.ts +7 -0
- package/src/api/types/autogen/apiV2.types.ts +2 -0
- package/src/api/types/types.ts +41 -1
- package/src/constants.ts +2 -0
package/.prettierignore
CHANGED
package/dist/api/orders.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export declare const orders: {
|
|
|
12
12
|
TRANSFER_CARD_PREPAID: (data: API.Orders.Create.ByOrderType.TRANSFER_CARD_PREPAID.Request) => Promise<API.Orders.Create.ByOrderType.TRANSFER_CARD_PREPAID.Response>;
|
|
13
13
|
TRANSFER_CARD_WHOLESALE: (data: API.Orders.Create.ByOrderType.TRANSFER_CARD_WHOLESALE.Request) => Promise<API.Orders.Create.ByOrderType.TRANSFER_CARD_WHOLESALE.Response>;
|
|
14
14
|
EXCHANGE_CRYPTO_INTERNAL: (data: API.Orders.Create.ByOrderType.EXCHANGE_CRYPTO_INTERNAL.Request) => Promise<API.Orders.Create.ByOrderType.EXCHANGE_CRYPTO_INTERNAL.Response>;
|
|
15
|
+
EXCHANGE_OMNI: (data: API.Orders.Create.ByOrderType.EXCHANGE_OMNI.Request) => Promise<API.Orders.Create.ByOrderType.EXCHANGE_OMNI.Response>;
|
|
15
16
|
WITHDRAW_CARD_PREPAID: (data: API.Orders.Create.ByOrderType.WITHDRAW_CARD_PREPAID.Request) => Promise<API.Orders.Create.ByOrderType.WITHDRAW_CARD_PREPAID.Response>;
|
|
16
17
|
WITHDRAW_CARD_SUBACCOUNT: (data: API.Orders.Create.ByOrderType.WITHDRAW_CARD_SUBACCOUNT.Request) => Promise<API.Orders.Create.ByOrderType.WITHDRAW_CARD_SUBACCOUNT.Response>;
|
|
17
18
|
};
|
package/dist/api/orders.js
CHANGED
|
@@ -43,6 +43,9 @@ exports.orders = {
|
|
|
43
43
|
data,
|
|
44
44
|
}),
|
|
45
45
|
[constants_1.OrderType.EXCHANGE_CRYPTO_INTERNAL]: (data) => apiClientFactory_1.apiClientV1.postRequest('/orders/EXCHANGE_CRYPTO_INTERNAL', { data }),
|
|
46
|
+
[constants_1.OrderType.EXCHANGE_OMNI]: (data) => apiClientFactory_1.apiClientV1.postRequest('/orders/EXCHANGE_OMNI', {
|
|
47
|
+
data,
|
|
48
|
+
}),
|
|
46
49
|
[constants_1.OrderType.WITHDRAW_CARD_PREPAID]: (data) => apiClientFactory_1.apiClientV1.postRequest('/orders/WITHDRAW_CARD_PREPAID', { data }),
|
|
47
50
|
[constants_1.OrderType.WITHDRAW_CARD_SUBACCOUNT]: (data) => apiClientFactory_1.apiClientV1.postRequest('/orders/WITHDRAW_CARD_SUBACCOUNT', { data }),
|
|
48
51
|
},
|
|
@@ -1771,6 +1771,7 @@ export interface components {
|
|
|
1771
1771
|
usd_value_of_crypto?: string | null;
|
|
1772
1772
|
usd_value_of_fiat?: string | null;
|
|
1773
1773
|
occupation?: string | null;
|
|
1774
|
+
occupation_other?: string | null;
|
|
1774
1775
|
/**
|
|
1775
1776
|
* @default UNVERIFIED
|
|
1776
1777
|
* @enum {string}
|
|
@@ -1874,6 +1875,7 @@ export interface components {
|
|
|
1874
1875
|
usd_value_of_crypto?: string | null;
|
|
1875
1876
|
usd_value_of_fiat?: string | null;
|
|
1876
1877
|
occupation?: string | null;
|
|
1878
|
+
occupation_other?: string | null;
|
|
1877
1879
|
/** @enum {string|null} */
|
|
1878
1880
|
employment_status?: "EMPLOYEE" | "SELF_EMPLOYED" | "RETIRED" | "UNEMPLOYED" | "OTHER" | null;
|
|
1879
1881
|
employment_description?: string | null;
|
|
@@ -1077,6 +1077,38 @@ export declare namespace API {
|
|
|
1077
1077
|
id: number;
|
|
1078
1078
|
};
|
|
1079
1079
|
}
|
|
1080
|
+
namespace EXCHANGE_OMNI {
|
|
1081
|
+
type Request = {
|
|
1082
|
+
amount: number;
|
|
1083
|
+
wallet_uuid: string;
|
|
1084
|
+
from_uuid: string;
|
|
1085
|
+
to_uuid: string;
|
|
1086
|
+
};
|
|
1087
|
+
type Response = {
|
|
1088
|
+
created_at: string;
|
|
1089
|
+
order_uuid: string;
|
|
1090
|
+
wallet_uuid: string;
|
|
1091
|
+
from_uuid: string;
|
|
1092
|
+
to_uuid: string;
|
|
1093
|
+
amount_from: number;
|
|
1094
|
+
order_type: 'EXCHANGE_OMNI';
|
|
1095
|
+
status: OrderStatuses;
|
|
1096
|
+
amount_to: number;
|
|
1097
|
+
info: string;
|
|
1098
|
+
meta: {
|
|
1099
|
+
fee: number;
|
|
1100
|
+
order_uuid: string;
|
|
1101
|
+
to_address: string;
|
|
1102
|
+
fee_currency: string;
|
|
1103
|
+
billing_amount: number;
|
|
1104
|
+
transaction_amount: number;
|
|
1105
|
+
billing_amount_currency: string;
|
|
1106
|
+
transaction_amount_currency: string;
|
|
1107
|
+
network_fee: number;
|
|
1108
|
+
};
|
|
1109
|
+
id: string;
|
|
1110
|
+
};
|
|
1111
|
+
}
|
|
1080
1112
|
namespace TRANSFER_CARD_WHOLESALE {
|
|
1081
1113
|
type Request = {
|
|
1082
1114
|
amount: number;
|
|
@@ -1645,7 +1677,7 @@ export declare namespace API {
|
|
|
1645
1677
|
walletAddress: string;
|
|
1646
1678
|
}
|
|
1647
1679
|
namespace DepositInstruction {
|
|
1648
|
-
type InstructionType = 'ACH' | 'FEDWIRE' | 'SWIFT';
|
|
1680
|
+
type InstructionType = 'ACH' | 'FEDWIRE' | 'SWIFT' | 'SEPA_CT';
|
|
1649
1681
|
interface Address {
|
|
1650
1682
|
city: string;
|
|
1651
1683
|
state: string;
|
|
@@ -1682,6 +1714,13 @@ export declare namespace API {
|
|
|
1682
1714
|
institution_address: Address;
|
|
1683
1715
|
account_holder_address: Address;
|
|
1684
1716
|
}
|
|
1717
|
+
interface SEPA extends Common {
|
|
1718
|
+
instruction_type: 'SEPA_CT';
|
|
1719
|
+
iban: string;
|
|
1720
|
+
swift_bic: string;
|
|
1721
|
+
institution_address: Address;
|
|
1722
|
+
account_holder_address: Address;
|
|
1723
|
+
}
|
|
1685
1724
|
type DepositInstruction = ACH | FEDWIRE | SWIFT | Common;
|
|
1686
1725
|
}
|
|
1687
1726
|
interface OrderType {
|
package/dist/constants.d.ts
CHANGED
|
@@ -56,6 +56,7 @@ export declare enum OrderType {
|
|
|
56
56
|
DEPOSIT_FIAT_SEPA = "DEPOSIT_FIAT_SEPA",
|
|
57
57
|
DEPOSIT_FIAT_SWIFT = "DEPOSIT_FIAT_SWIFT",
|
|
58
58
|
EXCHANGE_CRYPTO_INTERNAL = "EXCHANGE_CRYPTO_INTERNAL",
|
|
59
|
+
EXCHANGE_OMNI = "EXCHANGE_OMNI",
|
|
59
60
|
TRANSFER_CARD_PREPAID = "TRANSFER_CARD_PREPAID",
|
|
60
61
|
CARD_ISSUING_FEE = "CARD_ISSUING_FEE",
|
|
61
62
|
TRANSFER_CARD_SUBACCOUNT = "TRANSFER_CARD_SUBACCOUNT",
|
|
@@ -95,6 +96,7 @@ export declare enum WalletTransactionRecordType {
|
|
|
95
96
|
DEPOSIT_INTERNAL = "DEPOSIT_INTERNAL",
|
|
96
97
|
DEPOSIT_MANUAL = "DEPOSIT_MANUAL",
|
|
97
98
|
EXCHANGE_CRYPTO_INTERNAL = "EXCHANGE_CRYPTO_INTERNAL",
|
|
99
|
+
EXCHANGE_OMNI = "EXCHANGE_OMNI",
|
|
98
100
|
EXT_EXCHANGE = "EXT_EXCHANGE",
|
|
99
101
|
FEE = "FEE",
|
|
100
102
|
HIFI_ACH_OFFRAMP = "HIFI_ACH_OFFRAMP",
|
package/dist/constants.js
CHANGED
|
@@ -61,6 +61,7 @@ var OrderType;
|
|
|
61
61
|
OrderType["DEPOSIT_FIAT_SEPA"] = "DEPOSIT_FIAT_SEPA";
|
|
62
62
|
OrderType["DEPOSIT_FIAT_SWIFT"] = "DEPOSIT_FIAT_SWIFT";
|
|
63
63
|
OrderType["EXCHANGE_CRYPTO_INTERNAL"] = "EXCHANGE_CRYPTO_INTERNAL";
|
|
64
|
+
OrderType["EXCHANGE_OMNI"] = "EXCHANGE_OMNI";
|
|
64
65
|
OrderType["TRANSFER_CARD_PREPAID"] = "TRANSFER_CARD_PREPAID";
|
|
65
66
|
OrderType["CARD_ISSUING_FEE"] = "CARD_ISSUING_FEE";
|
|
66
67
|
OrderType["TRANSFER_CARD_SUBACCOUNT"] = "TRANSFER_CARD_SUBACCOUNT";
|
|
@@ -101,6 +102,7 @@ var WalletTransactionRecordType;
|
|
|
101
102
|
WalletTransactionRecordType["DEPOSIT_INTERNAL"] = "DEPOSIT_INTERNAL";
|
|
102
103
|
WalletTransactionRecordType["DEPOSIT_MANUAL"] = "DEPOSIT_MANUAL";
|
|
103
104
|
WalletTransactionRecordType["EXCHANGE_CRYPTO_INTERNAL"] = "EXCHANGE_CRYPTO_INTERNAL";
|
|
105
|
+
WalletTransactionRecordType["EXCHANGE_OMNI"] = "EXCHANGE_OMNI";
|
|
104
106
|
WalletTransactionRecordType["EXT_EXCHANGE"] = "EXT_EXCHANGE";
|
|
105
107
|
WalletTransactionRecordType["FEE"] = "FEE";
|
|
106
108
|
WalletTransactionRecordType["HIFI_ACH_OFFRAMP"] = "HIFI_ACH_OFFRAMP";
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { UploadFileResult } from '../utils/fileStorage';
|
|
2
|
+
interface UseFileUploadOptions {
|
|
3
|
+
userId: string;
|
|
4
|
+
bucket?: string;
|
|
5
|
+
authToken?: string;
|
|
6
|
+
onSuccess?: (result: UploadFileResult) => void;
|
|
7
|
+
onError?: (error: string) => void;
|
|
8
|
+
}
|
|
9
|
+
interface UseFileUploadReturn {
|
|
10
|
+
upload: (file: File, fileName?: string) => Promise<UploadFileResult>;
|
|
11
|
+
uploading: boolean;
|
|
12
|
+
progress: number;
|
|
13
|
+
error: string | null;
|
|
14
|
+
result: UploadFileResult | null;
|
|
15
|
+
reset: () => void;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* React хук для загрузки файлов в Supabase Storage
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```tsx
|
|
22
|
+
* const { upload, uploading, error, result } = useFileUpload({
|
|
23
|
+
* userId: 'user-123',
|
|
24
|
+
* onSuccess: (result) => console.log('Загружено:', result.path),
|
|
25
|
+
* });
|
|
26
|
+
*
|
|
27
|
+
* const handleFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
28
|
+
* const file = e.target.files?.[0];
|
|
29
|
+
* if (file) await upload(file);
|
|
30
|
+
* };
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare const useFileUpload: (options: UseFileUploadOptions) => UseFileUploadReturn;
|
|
34
|
+
export {};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.useFileUpload = void 0;
|
|
13
|
+
const react_1 = require("react");
|
|
14
|
+
const fileStorage_1 = require("../utils/fileStorage");
|
|
15
|
+
/**
|
|
16
|
+
* React хук для загрузки файлов в Supabase Storage
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```tsx
|
|
20
|
+
* const { upload, uploading, error, result } = useFileUpload({
|
|
21
|
+
* userId: 'user-123',
|
|
22
|
+
* onSuccess: (result) => console.log('Загружено:', result.path),
|
|
23
|
+
* });
|
|
24
|
+
*
|
|
25
|
+
* const handleFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
26
|
+
* const file = e.target.files?.[0];
|
|
27
|
+
* if (file) await upload(file);
|
|
28
|
+
* };
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
const useFileUpload = (options) => {
|
|
32
|
+
const { userId, bucket, authToken, onSuccess, onError } = options;
|
|
33
|
+
const [uploading, setUploading] = (0, react_1.useState)(false);
|
|
34
|
+
const [progress, setProgress] = (0, react_1.useState)(0);
|
|
35
|
+
const [error, setError] = (0, react_1.useState)(null);
|
|
36
|
+
const [result, setResult] = (0, react_1.useState)(null);
|
|
37
|
+
const upload = (0, react_1.useCallback)((file, customFileName) => __awaiter(void 0, void 0, void 0, function* () {
|
|
38
|
+
setUploading(true);
|
|
39
|
+
setProgress(0);
|
|
40
|
+
setError(null);
|
|
41
|
+
setResult(null);
|
|
42
|
+
try {
|
|
43
|
+
// Симулируем прогресс (Supabase не предоставляет реальный progress)
|
|
44
|
+
const progressInterval = setInterval(() => {
|
|
45
|
+
setProgress((prev) => Math.min(prev + 10, 90));
|
|
46
|
+
}, 100);
|
|
47
|
+
const uploadOptions = {
|
|
48
|
+
file,
|
|
49
|
+
fileName: customFileName || `${Date.now()}-${file.name}`,
|
|
50
|
+
userId,
|
|
51
|
+
bucket,
|
|
52
|
+
contentType: file.type,
|
|
53
|
+
authToken,
|
|
54
|
+
};
|
|
55
|
+
const uploadResult = yield (0, fileStorage_1.uploadFile)(uploadOptions);
|
|
56
|
+
clearInterval(progressInterval);
|
|
57
|
+
setProgress(100);
|
|
58
|
+
setResult(uploadResult);
|
|
59
|
+
if (uploadResult.success) {
|
|
60
|
+
onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess(uploadResult);
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
const errorMsg = uploadResult.error || 'Ошибка загрузки файла';
|
|
64
|
+
setError(errorMsg);
|
|
65
|
+
onError === null || onError === void 0 ? void 0 : onError(errorMsg);
|
|
66
|
+
}
|
|
67
|
+
return uploadResult;
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
const errorMsg = err instanceof Error ? err.message : 'Непредвиденная ошибка';
|
|
71
|
+
setError(errorMsg);
|
|
72
|
+
onError === null || onError === void 0 ? void 0 : onError(errorMsg);
|
|
73
|
+
setProgress(0);
|
|
74
|
+
return {
|
|
75
|
+
success: false,
|
|
76
|
+
error: errorMsg,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
finally {
|
|
80
|
+
setUploading(false);
|
|
81
|
+
}
|
|
82
|
+
}), [userId, bucket, authToken, onSuccess, onError]);
|
|
83
|
+
const reset = (0, react_1.useCallback)(() => {
|
|
84
|
+
setUploading(false);
|
|
85
|
+
setProgress(0);
|
|
86
|
+
setError(null);
|
|
87
|
+
setResult(null);
|
|
88
|
+
}, []);
|
|
89
|
+
return {
|
|
90
|
+
upload,
|
|
91
|
+
uploading,
|
|
92
|
+
progress,
|
|
93
|
+
error,
|
|
94
|
+
result,
|
|
95
|
+
reset,
|
|
96
|
+
};
|
|
97
|
+
};
|
|
98
|
+
exports.useFileUpload = useFileUpload;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
interface FileItem {
|
|
2
|
+
name: string;
|
|
3
|
+
id: string;
|
|
4
|
+
created_at: string;
|
|
5
|
+
updated_at: string;
|
|
6
|
+
signedUrl?: string;
|
|
7
|
+
}
|
|
8
|
+
interface UseUserFilesOptions {
|
|
9
|
+
userId: string;
|
|
10
|
+
bucket?: string;
|
|
11
|
+
autoLoad?: boolean;
|
|
12
|
+
autoGenerateUrls?: boolean;
|
|
13
|
+
urlExpiresIn?: number;
|
|
14
|
+
authToken?: string;
|
|
15
|
+
}
|
|
16
|
+
interface UseUserFilesReturn {
|
|
17
|
+
files: FileItem[];
|
|
18
|
+
loading: boolean;
|
|
19
|
+
error: string | null;
|
|
20
|
+
reload: () => Promise<void>;
|
|
21
|
+
deleteOne: (fileName: string) => Promise<boolean>;
|
|
22
|
+
deleteMultiple: (fileNames: string[]) => Promise<boolean>;
|
|
23
|
+
getFileUrl: (fileName: string) => Promise<string | null>;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* React хук для работы со списком файлов пользователя
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```tsx
|
|
30
|
+
* const { files, loading, deleteOne, getFileUrl } = useUserFiles({
|
|
31
|
+
* userId: 'user-123',
|
|
32
|
+
* autoLoad: true,
|
|
33
|
+
* autoGenerateUrls: true,
|
|
34
|
+
* });
|
|
35
|
+
*
|
|
36
|
+
* return (
|
|
37
|
+
* <ul>
|
|
38
|
+
* {files.map(file => (
|
|
39
|
+
* <li key={file.id}>
|
|
40
|
+
* <a href={file.signedUrl} target="_blank">{file.name}</a>
|
|
41
|
+
* <button onClick={() => deleteOne(file.name)}>Удалить</button>
|
|
42
|
+
* </li>
|
|
43
|
+
* ))}
|
|
44
|
+
* </ul>
|
|
45
|
+
* );
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export declare const useUserFiles: (options: UseUserFilesOptions) => UseUserFilesReturn;
|
|
49
|
+
export {};
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.useUserFiles = void 0;
|
|
13
|
+
const react_1 = require("react");
|
|
14
|
+
const fileStorage_1 = require("../utils/fileStorage");
|
|
15
|
+
/**
|
|
16
|
+
* React хук для работы со списком файлов пользователя
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```tsx
|
|
20
|
+
* const { files, loading, deleteOne, getFileUrl } = useUserFiles({
|
|
21
|
+
* userId: 'user-123',
|
|
22
|
+
* autoLoad: true,
|
|
23
|
+
* autoGenerateUrls: true,
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* return (
|
|
27
|
+
* <ul>
|
|
28
|
+
* {files.map(file => (
|
|
29
|
+
* <li key={file.id}>
|
|
30
|
+
* <a href={file.signedUrl} target="_blank">{file.name}</a>
|
|
31
|
+
* <button onClick={() => deleteOne(file.name)}>Удалить</button>
|
|
32
|
+
* </li>
|
|
33
|
+
* ))}
|
|
34
|
+
* </ul>
|
|
35
|
+
* );
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
const useUserFiles = (options) => {
|
|
39
|
+
const { userId, bucket, autoLoad = true, autoGenerateUrls = false, urlExpiresIn = 3600, authToken, } = options;
|
|
40
|
+
const [files, setFiles] = (0, react_1.useState)([]);
|
|
41
|
+
const [loading, setLoading] = (0, react_1.useState)(false);
|
|
42
|
+
const [error, setError] = (0, react_1.useState)(null);
|
|
43
|
+
const reload = (0, react_1.useCallback)(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
44
|
+
setLoading(true);
|
|
45
|
+
setError(null);
|
|
46
|
+
try {
|
|
47
|
+
const userFiles = yield (0, fileStorage_1.listUserFiles)(userId, bucket, authToken);
|
|
48
|
+
let filesWithUrls = userFiles.map((file) => ({
|
|
49
|
+
name: file.name,
|
|
50
|
+
id: file.id,
|
|
51
|
+
created_at: file.created_at,
|
|
52
|
+
updated_at: file.updated_at,
|
|
53
|
+
}));
|
|
54
|
+
// Генерируем signed URLs если нужно
|
|
55
|
+
if (autoGenerateUrls) {
|
|
56
|
+
const filesWithSignedUrls = yield Promise.all(filesWithUrls.map((file) => __awaiter(void 0, void 0, void 0, function* () {
|
|
57
|
+
const signedUrl = yield (0, fileStorage_1.getSignedUrl)({
|
|
58
|
+
path: `${userId}/${file.name}`,
|
|
59
|
+
bucket,
|
|
60
|
+
expiresIn: urlExpiresIn,
|
|
61
|
+
authToken,
|
|
62
|
+
});
|
|
63
|
+
return Object.assign(Object.assign({}, file), { signedUrl: signedUrl || undefined });
|
|
64
|
+
})));
|
|
65
|
+
filesWithUrls = filesWithSignedUrls;
|
|
66
|
+
}
|
|
67
|
+
setFiles(filesWithUrls);
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
const errorMsg = err instanceof Error ? err.message : 'Ошибка загрузки файлов';
|
|
71
|
+
setError(errorMsg);
|
|
72
|
+
console.error('Error loading files:', err);
|
|
73
|
+
}
|
|
74
|
+
finally {
|
|
75
|
+
setLoading(false);
|
|
76
|
+
}
|
|
77
|
+
}), [userId, bucket, autoGenerateUrls, urlExpiresIn, authToken]);
|
|
78
|
+
const deleteOne = (0, react_1.useCallback)((fileName) => __awaiter(void 0, void 0, void 0, function* () {
|
|
79
|
+
const filePath = `${userId}/${fileName}`;
|
|
80
|
+
const success = yield (0, fileStorage_1.deleteFile)(filePath, bucket, authToken);
|
|
81
|
+
if (success) {
|
|
82
|
+
setFiles((prev) => prev.filter((file) => file.name !== fileName));
|
|
83
|
+
}
|
|
84
|
+
return success;
|
|
85
|
+
}), [userId, bucket, authToken]);
|
|
86
|
+
const deleteMultiple = (0, react_1.useCallback)((fileNames) => __awaiter(void 0, void 0, void 0, function* () {
|
|
87
|
+
const filePaths = fileNames.map((name) => `${userId}/${name}`);
|
|
88
|
+
const success = yield (0, fileStorage_1.deleteFiles)(filePaths, bucket, authToken);
|
|
89
|
+
if (success) {
|
|
90
|
+
setFiles((prev) => prev.filter((file) => !fileNames.includes(file.name)));
|
|
91
|
+
}
|
|
92
|
+
return success;
|
|
93
|
+
}), [userId, bucket, authToken]);
|
|
94
|
+
const getFileUrl = (0, react_1.useCallback)((fileName) => __awaiter(void 0, void 0, void 0, function* () {
|
|
95
|
+
const filePath = `${userId}/${fileName}`;
|
|
96
|
+
return yield (0, fileStorage_1.getSignedUrl)({
|
|
97
|
+
path: filePath,
|
|
98
|
+
bucket,
|
|
99
|
+
expiresIn: urlExpiresIn,
|
|
100
|
+
authToken,
|
|
101
|
+
});
|
|
102
|
+
}), [userId, bucket, urlExpiresIn, authToken]);
|
|
103
|
+
(0, react_1.useEffect)(() => {
|
|
104
|
+
if (autoLoad) {
|
|
105
|
+
reload();
|
|
106
|
+
}
|
|
107
|
+
}, [autoLoad, reload]);
|
|
108
|
+
return {
|
|
109
|
+
files,
|
|
110
|
+
loading,
|
|
111
|
+
error,
|
|
112
|
+
reload,
|
|
113
|
+
deleteOne,
|
|
114
|
+
deleteMultiple,
|
|
115
|
+
getFileUrl,
|
|
116
|
+
};
|
|
117
|
+
};
|
|
118
|
+
exports.useUserFiles = useUserFiles;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Типы для работы с файловым хранилищем
|
|
3
|
+
*/
|
|
4
|
+
export interface UploadFileOptions {
|
|
5
|
+
file: File | Blob;
|
|
6
|
+
fileName: string;
|
|
7
|
+
bucket?: string;
|
|
8
|
+
userId: string;
|
|
9
|
+
contentType?: string;
|
|
10
|
+
cacheControl?: string;
|
|
11
|
+
upsert?: boolean;
|
|
12
|
+
authToken?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface UploadFileResult {
|
|
15
|
+
success: boolean;
|
|
16
|
+
publicUrl?: string;
|
|
17
|
+
signedUrl?: string;
|
|
18
|
+
path?: string;
|
|
19
|
+
error?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface GetFileUrlOptions {
|
|
22
|
+
path: string;
|
|
23
|
+
bucket?: string;
|
|
24
|
+
expiresIn?: number;
|
|
25
|
+
authToken?: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Названия бакетов по умолчанию
|
|
29
|
+
*/
|
|
30
|
+
export declare const DEFAULT_BUCKET = "user-files";
|
|
31
|
+
export declare const DOCUMENTS_BUCKET = "documents";
|
|
32
|
+
export declare const IMAGES_BUCKET = "images";
|
|
33
|
+
/**
|
|
34
|
+
* Загружает файл в Supabase Storage
|
|
35
|
+
* Файл сохраняется по пути: {userId}/{fileName}
|
|
36
|
+
*
|
|
37
|
+
* @param options - параметры загрузки файла
|
|
38
|
+
* @returns результат загрузки с ссылкой на файл
|
|
39
|
+
*/
|
|
40
|
+
export declare const uploadFile: (options: UploadFileOptions) => Promise<UploadFileResult>;
|
|
41
|
+
/**
|
|
42
|
+
* Получает подписанный URL для доступа к файлу
|
|
43
|
+
*
|
|
44
|
+
* @param options - параметры получения URL
|
|
45
|
+
* @returns подписанный URL или null при ошибке
|
|
46
|
+
*/
|
|
47
|
+
export declare const getSignedUrl: (options: GetFileUrlOptions) => Promise<string | null>;
|
|
48
|
+
/**
|
|
49
|
+
* Получает публичный URL для файла
|
|
50
|
+
*
|
|
51
|
+
* Для ПРИВАТНЫХ бакетов:
|
|
52
|
+
* - URL постоянный (не истекает)
|
|
53
|
+
* - Требует Authorization header с service role key для доступа
|
|
54
|
+
* - Используется на backend для суперадмина
|
|
55
|
+
*
|
|
56
|
+
* Для ПУБЛИЧНЫХ бакетов:
|
|
57
|
+
* - URL доступен всем без аутентификации
|
|
58
|
+
*
|
|
59
|
+
* @example Backend usage for private buckets:
|
|
60
|
+
* ```typescript
|
|
61
|
+
* const url = getPublicUrl(filePath, bucket);
|
|
62
|
+
*
|
|
63
|
+
* // Access with service role key:
|
|
64
|
+
* fetch(url, {
|
|
65
|
+
* headers: {
|
|
66
|
+
* 'Authorization': `Bearer ${SUPABASE_SERVICE_ROLE_KEY}`
|
|
67
|
+
* }
|
|
68
|
+
* })
|
|
69
|
+
* ```
|
|
70
|
+
*
|
|
71
|
+
* @param path - путь к файлу
|
|
72
|
+
* @param bucket - название бакета
|
|
73
|
+
* @returns постоянный URL
|
|
74
|
+
*/
|
|
75
|
+
export declare const getPublicUrl: (path: string, bucket?: string) => string | null;
|
|
76
|
+
/**
|
|
77
|
+
* Удаляет файл из хранилища
|
|
78
|
+
*
|
|
79
|
+
* @param path - путь к файлу
|
|
80
|
+
* @param bucket - название бакета
|
|
81
|
+
* @param authToken - JWT token для авторизации
|
|
82
|
+
* @returns true при успешном удалении
|
|
83
|
+
*/
|
|
84
|
+
export declare const deleteFile: (path: string, bucket?: string, authToken?: string) => Promise<boolean>;
|
|
85
|
+
/**
|
|
86
|
+
* Удаляет несколько файлов из хранилища
|
|
87
|
+
*
|
|
88
|
+
* @param paths - массив путей к файлам
|
|
89
|
+
* @param bucket - название бакета
|
|
90
|
+
* @param authToken - JWT token для авторизации
|
|
91
|
+
* @returns true при успешном удалении всех файлов
|
|
92
|
+
*/
|
|
93
|
+
export declare const deleteFiles: (paths: string[], bucket?: string, authToken?: string) => Promise<boolean>;
|
|
94
|
+
/**
|
|
95
|
+
* Получает список файлов пользователя
|
|
96
|
+
*
|
|
97
|
+
* @param userId - ID пользователя
|
|
98
|
+
* @param bucket - название бакета
|
|
99
|
+
* @param authToken - JWT token для авторизации
|
|
100
|
+
* @returns список файлов или пустой массив при ошибке
|
|
101
|
+
*/
|
|
102
|
+
export declare const listUserFiles: (userId: string, bucket?: string, authToken?: string) => Promise<import("@supabase/storage-js").FileObject[]>;
|
|
103
|
+
/**
|
|
104
|
+
* Скачивает файл из хранилища
|
|
105
|
+
*
|
|
106
|
+
* @param path - путь к файлу
|
|
107
|
+
* @param bucket - название бакета
|
|
108
|
+
* @param authToken - JWT token для авторизации
|
|
109
|
+
* @returns Blob файла или null при ошибке
|
|
110
|
+
*/
|
|
111
|
+
export declare const downloadFile: (path: string, bucket?: string, authToken?: string) => Promise<Blob | null>;
|
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.downloadFile = exports.listUserFiles = exports.deleteFiles = exports.deleteFile = exports.getPublicUrl = exports.getSignedUrl = exports.uploadFile = exports.IMAGES_BUCKET = exports.DOCUMENTS_BUCKET = exports.DEFAULT_BUCKET = void 0;
|
|
46
|
+
const supabase_1 = require("./supabase");
|
|
47
|
+
/**
|
|
48
|
+
* Названия бакетов по умолчанию
|
|
49
|
+
*/
|
|
50
|
+
exports.DEFAULT_BUCKET = 'user-files';
|
|
51
|
+
exports.DOCUMENTS_BUCKET = 'documents';
|
|
52
|
+
exports.IMAGES_BUCKET = 'images';
|
|
53
|
+
/**
|
|
54
|
+
* Загружает файл в Supabase Storage
|
|
55
|
+
* Файл сохраняется по пути: {userId}/{fileName}
|
|
56
|
+
*
|
|
57
|
+
* @param options - параметры загрузки файла
|
|
58
|
+
* @returns результат загрузки с ссылкой на файл
|
|
59
|
+
*/
|
|
60
|
+
const uploadFile = (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
61
|
+
const { file, fileName, bucket = exports.DEFAULT_BUCKET, userId, contentType, cacheControl = '3600', upsert = false, authToken, } = options;
|
|
62
|
+
if (!supabase_1.supabaseClient) {
|
|
63
|
+
return {
|
|
64
|
+
success: false,
|
|
65
|
+
error: 'Supabase client is not initialized',
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
// Если передан authToken, создаем клиент с токеном
|
|
70
|
+
let client = supabase_1.supabaseClient;
|
|
71
|
+
if (authToken) {
|
|
72
|
+
const { createClient } = yield Promise.resolve().then(() => __importStar(require('@supabase/supabase-js')));
|
|
73
|
+
client = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_PUBLIC_KEY, {
|
|
74
|
+
global: {
|
|
75
|
+
headers: {
|
|
76
|
+
Authorization: `Bearer ${authToken}`,
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
// Путь к файлу: userId/fileName
|
|
82
|
+
const filePath = `${userId}/${fileName}`;
|
|
83
|
+
const { data, error } = yield client.storage.from(bucket).upload(filePath, file, {
|
|
84
|
+
contentType,
|
|
85
|
+
cacheControl,
|
|
86
|
+
upsert,
|
|
87
|
+
});
|
|
88
|
+
if (error) {
|
|
89
|
+
console.error('Error uploading file:', error);
|
|
90
|
+
return {
|
|
91
|
+
success: false,
|
|
92
|
+
error: error.message,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
// Получаем публичный URL
|
|
96
|
+
const { data: urlData } = client.storage.from(bucket).getPublicUrl(data.path);
|
|
97
|
+
// Получаем подписанный URL (действителен 1 час по умолчанию)
|
|
98
|
+
const { data: signedUrlData, error: signedUrlError } = yield client.storage
|
|
99
|
+
.from(bucket)
|
|
100
|
+
.createSignedUrl(data.path, 3600);
|
|
101
|
+
return {
|
|
102
|
+
success: true,
|
|
103
|
+
publicUrl: urlData.publicUrl,
|
|
104
|
+
signedUrl: signedUrlError ? undefined : signedUrlData.signedUrl,
|
|
105
|
+
path: data.path,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
console.error('Unexpected error uploading file:', error);
|
|
110
|
+
return {
|
|
111
|
+
success: false,
|
|
112
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
exports.uploadFile = uploadFile;
|
|
117
|
+
/**
|
|
118
|
+
* Получает подписанный URL для доступа к файлу
|
|
119
|
+
*
|
|
120
|
+
* @param options - параметры получения URL
|
|
121
|
+
* @returns подписанный URL или null при ошибке
|
|
122
|
+
*/
|
|
123
|
+
const getSignedUrl = (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
124
|
+
const { path, bucket = exports.DEFAULT_BUCKET, expiresIn = 3600, authToken } = options;
|
|
125
|
+
if (!supabase_1.supabaseClient) {
|
|
126
|
+
console.error('Supabase client is not initialized');
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
try {
|
|
130
|
+
// Если передан authToken, создаем клиент с токеном
|
|
131
|
+
let client = supabase_1.supabaseClient;
|
|
132
|
+
if (authToken) {
|
|
133
|
+
const { createClient } = yield Promise.resolve().then(() => __importStar(require('@supabase/supabase-js')));
|
|
134
|
+
client = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_PUBLIC_KEY, {
|
|
135
|
+
global: {
|
|
136
|
+
headers: {
|
|
137
|
+
Authorization: `Bearer ${authToken}`,
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
const { data, error } = yield client.storage.from(bucket).createSignedUrl(path, expiresIn);
|
|
143
|
+
if (error) {
|
|
144
|
+
console.error('Error creating signed URL:', error);
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
return data.signedUrl;
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
console.error('Unexpected error creating signed URL:', error);
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
exports.getSignedUrl = getSignedUrl;
|
|
155
|
+
/**
|
|
156
|
+
* Получает публичный URL для файла
|
|
157
|
+
*
|
|
158
|
+
* Для ПРИВАТНЫХ бакетов:
|
|
159
|
+
* - URL постоянный (не истекает)
|
|
160
|
+
* - Требует Authorization header с service role key для доступа
|
|
161
|
+
* - Используется на backend для суперадмина
|
|
162
|
+
*
|
|
163
|
+
* Для ПУБЛИЧНЫХ бакетов:
|
|
164
|
+
* - URL доступен всем без аутентификации
|
|
165
|
+
*
|
|
166
|
+
* @example Backend usage for private buckets:
|
|
167
|
+
* ```typescript
|
|
168
|
+
* const url = getPublicUrl(filePath, bucket);
|
|
169
|
+
*
|
|
170
|
+
* // Access with service role key:
|
|
171
|
+
* fetch(url, {
|
|
172
|
+
* headers: {
|
|
173
|
+
* 'Authorization': `Bearer ${SUPABASE_SERVICE_ROLE_KEY}`
|
|
174
|
+
* }
|
|
175
|
+
* })
|
|
176
|
+
* ```
|
|
177
|
+
*
|
|
178
|
+
* @param path - путь к файлу
|
|
179
|
+
* @param bucket - название бакета
|
|
180
|
+
* @returns постоянный URL
|
|
181
|
+
*/
|
|
182
|
+
const getPublicUrl = (path, bucket = exports.DEFAULT_BUCKET) => {
|
|
183
|
+
if (!supabase_1.supabaseClient) {
|
|
184
|
+
console.error('Supabase client is not initialized');
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
const { data } = supabase_1.supabaseClient.storage.from(bucket).getPublicUrl(path);
|
|
188
|
+
return data.publicUrl;
|
|
189
|
+
};
|
|
190
|
+
exports.getPublicUrl = getPublicUrl;
|
|
191
|
+
/**
|
|
192
|
+
* Удаляет файл из хранилища
|
|
193
|
+
*
|
|
194
|
+
* @param path - путь к файлу
|
|
195
|
+
* @param bucket - название бакета
|
|
196
|
+
* @param authToken - JWT token для авторизации
|
|
197
|
+
* @returns true при успешном удалении
|
|
198
|
+
*/
|
|
199
|
+
const deleteFile = (path_1, ...args_1) => __awaiter(void 0, [path_1, ...args_1], void 0, function* (path, bucket = exports.DEFAULT_BUCKET, authToken) {
|
|
200
|
+
if (!supabase_1.supabaseClient) {
|
|
201
|
+
console.error('Supabase client is not initialized');
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
try {
|
|
205
|
+
let client = supabase_1.supabaseClient;
|
|
206
|
+
if (authToken) {
|
|
207
|
+
const { createClient } = yield Promise.resolve().then(() => __importStar(require('@supabase/supabase-js')));
|
|
208
|
+
client = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_PUBLIC_KEY, {
|
|
209
|
+
global: {
|
|
210
|
+
headers: {
|
|
211
|
+
Authorization: `Bearer ${authToken}`,
|
|
212
|
+
},
|
|
213
|
+
},
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
const { error } = yield client.storage.from(bucket).remove([path]);
|
|
217
|
+
if (error) {
|
|
218
|
+
console.error('Error deleting file:', error);
|
|
219
|
+
return false;
|
|
220
|
+
}
|
|
221
|
+
return true;
|
|
222
|
+
}
|
|
223
|
+
catch (error) {
|
|
224
|
+
console.error('Unexpected error deleting file:', error);
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
exports.deleteFile = deleteFile;
|
|
229
|
+
/**
|
|
230
|
+
* Удаляет несколько файлов из хранилища
|
|
231
|
+
*
|
|
232
|
+
* @param paths - массив путей к файлам
|
|
233
|
+
* @param bucket - название бакета
|
|
234
|
+
* @param authToken - JWT token для авторизации
|
|
235
|
+
* @returns true при успешном удалении всех файлов
|
|
236
|
+
*/
|
|
237
|
+
const deleteFiles = (paths_1, ...args_1) => __awaiter(void 0, [paths_1, ...args_1], void 0, function* (paths, bucket = exports.DEFAULT_BUCKET, authToken) {
|
|
238
|
+
if (!supabase_1.supabaseClient) {
|
|
239
|
+
console.error('Supabase client is not initialized');
|
|
240
|
+
return false;
|
|
241
|
+
}
|
|
242
|
+
try {
|
|
243
|
+
let client = supabase_1.supabaseClient;
|
|
244
|
+
if (authToken) {
|
|
245
|
+
const { createClient } = yield Promise.resolve().then(() => __importStar(require('@supabase/supabase-js')));
|
|
246
|
+
client = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_PUBLIC_KEY, {
|
|
247
|
+
global: {
|
|
248
|
+
headers: {
|
|
249
|
+
Authorization: `Bearer ${authToken}`,
|
|
250
|
+
},
|
|
251
|
+
},
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
const { error } = yield client.storage.from(bucket).remove(paths);
|
|
255
|
+
if (error) {
|
|
256
|
+
console.error('Error deleting files:', error);
|
|
257
|
+
return false;
|
|
258
|
+
}
|
|
259
|
+
return true;
|
|
260
|
+
}
|
|
261
|
+
catch (error) {
|
|
262
|
+
console.error('Unexpected error deleting files:', error);
|
|
263
|
+
return false;
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
exports.deleteFiles = deleteFiles;
|
|
267
|
+
/**
|
|
268
|
+
* Получает список файлов пользователя
|
|
269
|
+
*
|
|
270
|
+
* @param userId - ID пользователя
|
|
271
|
+
* @param bucket - название бакета
|
|
272
|
+
* @param authToken - JWT token для авторизации
|
|
273
|
+
* @returns список файлов или пустой массив при ошибке
|
|
274
|
+
*/
|
|
275
|
+
const listUserFiles = (userId_1, ...args_1) => __awaiter(void 0, [userId_1, ...args_1], void 0, function* (userId, bucket = exports.DEFAULT_BUCKET, authToken) {
|
|
276
|
+
if (!supabase_1.supabaseClient) {
|
|
277
|
+
console.error('Supabase client is not initialized');
|
|
278
|
+
return [];
|
|
279
|
+
}
|
|
280
|
+
try {
|
|
281
|
+
let client = supabase_1.supabaseClient;
|
|
282
|
+
if (authToken) {
|
|
283
|
+
const { createClient } = yield Promise.resolve().then(() => __importStar(require('@supabase/supabase-js')));
|
|
284
|
+
client = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_PUBLIC_KEY, {
|
|
285
|
+
global: {
|
|
286
|
+
headers: {
|
|
287
|
+
Authorization: `Bearer ${authToken}`,
|
|
288
|
+
},
|
|
289
|
+
},
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
const { data, error } = yield client.storage.from(bucket).list(userId);
|
|
293
|
+
if (error) {
|
|
294
|
+
console.error('Error listing files:', error);
|
|
295
|
+
return [];
|
|
296
|
+
}
|
|
297
|
+
return data || [];
|
|
298
|
+
}
|
|
299
|
+
catch (error) {
|
|
300
|
+
console.error('Unexpected error listing files:', error);
|
|
301
|
+
return [];
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
exports.listUserFiles = listUserFiles;
|
|
305
|
+
/**
|
|
306
|
+
* Скачивает файл из хранилища
|
|
307
|
+
*
|
|
308
|
+
* @param path - путь к файлу
|
|
309
|
+
* @param bucket - название бакета
|
|
310
|
+
* @param authToken - JWT token для авторизации
|
|
311
|
+
* @returns Blob файла или null при ошибке
|
|
312
|
+
*/
|
|
313
|
+
const downloadFile = (path_1, ...args_1) => __awaiter(void 0, [path_1, ...args_1], void 0, function* (path, bucket = exports.DEFAULT_BUCKET, authToken) {
|
|
314
|
+
if (!supabase_1.supabaseClient) {
|
|
315
|
+
console.error('Supabase client is not initialized');
|
|
316
|
+
return null;
|
|
317
|
+
}
|
|
318
|
+
try {
|
|
319
|
+
let client = supabase_1.supabaseClient;
|
|
320
|
+
if (authToken) {
|
|
321
|
+
const { createClient } = yield Promise.resolve().then(() => __importStar(require('@supabase/supabase-js')));
|
|
322
|
+
client = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_PUBLIC_KEY, {
|
|
323
|
+
global: {
|
|
324
|
+
headers: {
|
|
325
|
+
Authorization: `Bearer ${authToken}`,
|
|
326
|
+
},
|
|
327
|
+
},
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
const { data, error } = yield client.storage.from(bucket).download(path);
|
|
331
|
+
if (error) {
|
|
332
|
+
console.error('Error downloading file:', error);
|
|
333
|
+
return null;
|
|
334
|
+
}
|
|
335
|
+
return data;
|
|
336
|
+
}
|
|
337
|
+
catch (error) {
|
|
338
|
+
console.error('Unexpected error downloading file:', error);
|
|
339
|
+
return null;
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
exports.downloadFile = downloadFile;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "squarefi-bff-api-module",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.29.1",
|
|
4
4
|
"description": "Squarefi BFF API client module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -41,7 +41,6 @@
|
|
|
41
41
|
"husky": "^9.1.7",
|
|
42
42
|
"jest": "^29.x.x",
|
|
43
43
|
"openapi-typescript": "^7.8.0",
|
|
44
|
-
"prettier": "^3.6.2",
|
|
45
44
|
"ts-jest": "^29.x.x",
|
|
46
45
|
"ts-node": "^10.9.2",
|
|
47
46
|
"typescript": "^5.x.x"
|
package/src/api/orders.ts
CHANGED
|
@@ -70,6 +70,13 @@ export const orders = {
|
|
|
70
70
|
{ data },
|
|
71
71
|
),
|
|
72
72
|
|
|
73
|
+
[OrderType.EXCHANGE_OMNI]: (
|
|
74
|
+
data: API.Orders.Create.ByOrderType.EXCHANGE_OMNI.Request,
|
|
75
|
+
): Promise<API.Orders.Create.ByOrderType.EXCHANGE_OMNI.Response> =>
|
|
76
|
+
apiClientV1.postRequest<API.Orders.Create.ByOrderType.EXCHANGE_OMNI.Response>('/orders/EXCHANGE_OMNI', {
|
|
77
|
+
data,
|
|
78
|
+
}),
|
|
79
|
+
|
|
73
80
|
[OrderType.WITHDRAW_CARD_PREPAID]: (
|
|
74
81
|
data: API.Orders.Create.ByOrderType.WITHDRAW_CARD_PREPAID.Request,
|
|
75
82
|
): Promise<API.Orders.Create.ByOrderType.WITHDRAW_CARD_PREPAID.Response> =>
|
|
@@ -1772,6 +1772,7 @@ export interface components {
|
|
|
1772
1772
|
usd_value_of_crypto?: string | null;
|
|
1773
1773
|
usd_value_of_fiat?: string | null;
|
|
1774
1774
|
occupation?: string | null;
|
|
1775
|
+
occupation_other?: string | null;
|
|
1775
1776
|
/**
|
|
1776
1777
|
* @default UNVERIFIED
|
|
1777
1778
|
* @enum {string}
|
|
@@ -1875,6 +1876,7 @@ export interface components {
|
|
|
1875
1876
|
usd_value_of_crypto?: string | null;
|
|
1876
1877
|
usd_value_of_fiat?: string | null;
|
|
1877
1878
|
occupation?: string | null;
|
|
1879
|
+
occupation_other?: string | null;
|
|
1878
1880
|
/** @enum {string|null} */
|
|
1879
1881
|
employment_status?: "EMPLOYEE" | "SELF_EMPLOYED" | "RETIRED" | "UNEMPLOYED" | "OTHER" | null;
|
|
1880
1882
|
employment_description?: string | null;
|
package/src/api/types/types.ts
CHANGED
|
@@ -1417,6 +1417,39 @@ export namespace API {
|
|
|
1417
1417
|
};
|
|
1418
1418
|
}
|
|
1419
1419
|
|
|
1420
|
+
export namespace EXCHANGE_OMNI {
|
|
1421
|
+
export type Request = {
|
|
1422
|
+
amount: number;
|
|
1423
|
+
wallet_uuid: string;
|
|
1424
|
+
from_uuid: string;
|
|
1425
|
+
to_uuid: string;
|
|
1426
|
+
};
|
|
1427
|
+
export type Response = {
|
|
1428
|
+
created_at: string;
|
|
1429
|
+
order_uuid: string;
|
|
1430
|
+
wallet_uuid: string;
|
|
1431
|
+
from_uuid: string;
|
|
1432
|
+
to_uuid: string;
|
|
1433
|
+
amount_from: number;
|
|
1434
|
+
order_type: 'EXCHANGE_OMNI';
|
|
1435
|
+
status: OrderStatuses;
|
|
1436
|
+
amount_to: number;
|
|
1437
|
+
info: string;
|
|
1438
|
+
meta: {
|
|
1439
|
+
fee: number;
|
|
1440
|
+
order_uuid: string;
|
|
1441
|
+
to_address: string;
|
|
1442
|
+
fee_currency: string;
|
|
1443
|
+
billing_amount: number;
|
|
1444
|
+
transaction_amount: number;
|
|
1445
|
+
billing_amount_currency: string;
|
|
1446
|
+
transaction_amount_currency: string;
|
|
1447
|
+
network_fee: number;
|
|
1448
|
+
};
|
|
1449
|
+
id: string;
|
|
1450
|
+
};
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1420
1453
|
export namespace TRANSFER_CARD_WHOLESALE {
|
|
1421
1454
|
export type Request = {
|
|
1422
1455
|
amount: number;
|
|
@@ -2130,7 +2163,7 @@ export namespace API {
|
|
|
2130
2163
|
}
|
|
2131
2164
|
|
|
2132
2165
|
export namespace DepositInstruction {
|
|
2133
|
-
export type InstructionType = 'ACH' | 'FEDWIRE' | 'SWIFT';
|
|
2166
|
+
export type InstructionType = 'ACH' | 'FEDWIRE' | 'SWIFT' | 'SEPA_CT';
|
|
2134
2167
|
|
|
2135
2168
|
export interface Address {
|
|
2136
2169
|
city: string;
|
|
@@ -2170,6 +2203,13 @@ export namespace API {
|
|
|
2170
2203
|
institution_address: Address;
|
|
2171
2204
|
account_holder_address: Address;
|
|
2172
2205
|
}
|
|
2206
|
+
export interface SEPA extends Common {
|
|
2207
|
+
instruction_type: 'SEPA_CT';
|
|
2208
|
+
iban: string;
|
|
2209
|
+
swift_bic: string;
|
|
2210
|
+
institution_address: Address;
|
|
2211
|
+
account_holder_address: Address;
|
|
2212
|
+
}
|
|
2173
2213
|
|
|
2174
2214
|
export type DepositInstruction = ACH | FEDWIRE | SWIFT | Common;
|
|
2175
2215
|
}
|
package/src/constants.ts
CHANGED
|
@@ -67,6 +67,7 @@ export enum OrderType {
|
|
|
67
67
|
DEPOSIT_FIAT_SEPA = 'DEPOSIT_FIAT_SEPA',
|
|
68
68
|
DEPOSIT_FIAT_SWIFT = 'DEPOSIT_FIAT_SWIFT',
|
|
69
69
|
EXCHANGE_CRYPTO_INTERNAL = 'EXCHANGE_CRYPTO_INTERNAL',
|
|
70
|
+
EXCHANGE_OMNI = 'EXCHANGE_OMNI',
|
|
70
71
|
TRANSFER_CARD_PREPAID = 'TRANSFER_CARD_PREPAID',
|
|
71
72
|
CARD_ISSUING_FEE = 'CARD_ISSUING_FEE',
|
|
72
73
|
TRANSFER_CARD_SUBACCOUNT = 'TRANSFER_CARD_SUBACCOUNT',
|
|
@@ -107,6 +108,7 @@ export enum WalletTransactionRecordType {
|
|
|
107
108
|
DEPOSIT_INTERNAL = 'DEPOSIT_INTERNAL',
|
|
108
109
|
DEPOSIT_MANUAL = 'DEPOSIT_MANUAL',
|
|
109
110
|
EXCHANGE_CRYPTO_INTERNAL = 'EXCHANGE_CRYPTO_INTERNAL',
|
|
111
|
+
EXCHANGE_OMNI = 'EXCHANGE_OMNI',
|
|
110
112
|
EXT_EXCHANGE = 'EXT_EXCHANGE',
|
|
111
113
|
FEE = 'FEE',
|
|
112
114
|
HIFI_ACH_OFFRAMP = 'HIFI_ACH_OFFRAMP',
|