@rabbitio/ui-kit 1.0.0-beta.4 → 1.0.0-beta.40
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/CHANGELOG.md +0 -0
- package/README.md +23 -16
- package/dist/index.cjs +5336 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +4480 -1635
- package/dist/index.css.map +1 -1
- package/dist/index.modern.js +3766 -11
- package/dist/index.modern.js.map +1 -1
- package/dist/index.module.js +5298 -11
- package/dist/index.module.js.map +1 -1
- package/dist/index.umd.js +5335 -12
- package/dist/index.umd.js.map +1 -1
- package/index.js +1 -1
- package/package.json +16 -22
- package/src/common/adapters/axiosAdapter.js +35 -0
- package/src/common/amountUtils.js +434 -0
- package/src/common/errorUtils.js +42 -0
- package/src/common/external-apis/apiGroups.js +55 -0
- package/src/common/fiatCurrenciesService.js +161 -0
- package/src/common/models/blockchain.js +10 -0
- package/src/common/models/coin.js +157 -0
- package/src/common/models/protocol.js +5 -0
- package/src/common/utils/cache.js +268 -0
- package/src/common/utils/emailAPI.js +18 -0
- package/src/common/utils/logging/logger.js +48 -0
- package/src/common/utils/logging/logsStorage.js +61 -0
- package/src/common/utils/postponeExecution.js +11 -0
- package/src/common/utils/safeStringify.js +50 -0
- package/src/components/atoms/AssetIcon/AssetIcon.jsx +55 -0
- package/src/components/atoms/AssetIcon/asset-icon.module.scss +42 -0
- package/{stories → src/components}/atoms/LoadingDots/LoadingDots.module.scss +1 -1
- package/src/components/atoms/SupportChat/SupportChat.jsx +48 -0
- package/{stories → src/components}/atoms/buttons/Button/Button.jsx +11 -7
- package/{stories → src/components}/atoms/buttons/Button/Button.module.scss +6 -1
- package/src/components/hooks/useCallHandlingErrors.js +26 -0
- package/src/components/hooks/useReferredState.js +24 -0
- package/src/components/utils/uiUtils.js +14 -0
- package/src/components/utils/urlQueryUtils.js +87 -0
- package/src/index.js +52 -0
- package/src/robustExteranlApiCallerService/cacheAndConcurrentRequestsResolver.js +559 -0
- package/src/robustExteranlApiCallerService/cachedRobustExternalApiCallerService.js +188 -0
- package/src/robustExteranlApiCallerService/cancelProcessing.js +29 -0
- package/src/robustExteranlApiCallerService/concurrentCalculationsMetadataHolder.js +103 -0
- package/src/robustExteranlApiCallerService/externalApiProvider.js +156 -0
- package/src/robustExteranlApiCallerService/externalServicesStatsCollector.js +82 -0
- package/src/robustExteranlApiCallerService/robustExternalAPICallerService.js +386 -0
- package/src/swaps-lib/external-apis/swapProvider.js +201 -0
- package/src/swaps-lib/external-apis/swapspaceSwapProvider.js +877 -0
- package/src/swaps-lib/models/baseSwapCreationInfo.js +40 -0
- package/src/swaps-lib/models/existingSwap.js +70 -0
- package/src/swaps-lib/models/existingSwapWithFiatData.js +130 -0
- package/src/swaps-lib/services/publicSwapService.js +674 -0
- package/src/swaps-lib/utils/swapUtils.js +219 -0
- package/stories/index.js +0 -2
- /package/{stories → src/components}/atoms/LoadingDots/LoadingDots.jsx +0 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
export class LogsStorage {
|
|
2
|
+
static _inMemoryStorage = [];
|
|
3
|
+
static _logsStorageId = "clietnLogs_j203fj2D0n-d1";
|
|
4
|
+
|
|
5
|
+
static saveLog(log) {
|
|
6
|
+
this._inMemoryStorage.push(log);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
static getInMemoryLogs() {
|
|
10
|
+
return this._inMemoryStorage;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
static getAllLogs() {
|
|
14
|
+
let storedLogs = "";
|
|
15
|
+
if (typeof window !== "undefined") {
|
|
16
|
+
storedLogs = localStorage.getItem(this._logsStorageId);
|
|
17
|
+
}
|
|
18
|
+
return `${storedLogs}\n${this._inMemoryStorage.join("\n")}`;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @param logger {Logger}
|
|
23
|
+
*/
|
|
24
|
+
static saveToTheDisk(logger) {
|
|
25
|
+
try {
|
|
26
|
+
const MAX_LOCAL_STORAGE_VOLUME_BYTES = 5 * 1024 * 1024;
|
|
27
|
+
const MAX_LOGS_STORAGE_BYTES = MAX_LOCAL_STORAGE_VOLUME_BYTES * 0.65;
|
|
28
|
+
if (typeof window !== "undefined") {
|
|
29
|
+
const existingLogs = localStorage.getItem(this._logsStorageId);
|
|
30
|
+
const logsString = `${existingLogs}\n${this._inMemoryStorage.join("\n")}`;
|
|
31
|
+
const lettersCountToRemove = logsString.length - Math.round(MAX_LOGS_STORAGE_BYTES / 2);
|
|
32
|
+
if (lettersCountToRemove > 0) {
|
|
33
|
+
localStorage.setItem(
|
|
34
|
+
this._logsStorageId,
|
|
35
|
+
logsString.slice(lettersCountToRemove, logsString.length)
|
|
36
|
+
);
|
|
37
|
+
} else {
|
|
38
|
+
localStorage.setItem(this._logsStorageId, logsString);
|
|
39
|
+
}
|
|
40
|
+
this._inMemoryStorage = [];
|
|
41
|
+
}
|
|
42
|
+
} catch (e) {
|
|
43
|
+
logger?.logError(e, "saveToTheDisk", "Failed to save logs to disk");
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
static removeAllClientLogs() {
|
|
48
|
+
if (typeof window !== "undefined") {
|
|
49
|
+
if (localStorage.getItem("doNotRemoveClientLogsWhenSignedOut") !== "true") {
|
|
50
|
+
localStorage.removeItem(this._logsStorageId);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
this._inMemoryStorage = [];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
static setDoNotRemoveClientLogsWhenSignedOut(value) {
|
|
57
|
+
if (typeof window !== "undefined") {
|
|
58
|
+
localStorage.setItem("doNotRemoveClientLogsWhenSignedOut", value);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stringify given object by use of JSON.stringify but handles circular structures and "response", "request" properties
|
|
3
|
+
* to avoid stringing redundant data when printing errors containing request/response objects.
|
|
4
|
+
*
|
|
5
|
+
* @param object - object to be stringed
|
|
6
|
+
* @param indent - custom indentation
|
|
7
|
+
* @return {string} - stringed object
|
|
8
|
+
*/
|
|
9
|
+
export function safeStringify(object, indent = 2) {
|
|
10
|
+
let cache = [];
|
|
11
|
+
if (
|
|
12
|
+
typeof object === "string" ||
|
|
13
|
+
typeof object === "function" ||
|
|
14
|
+
typeof object === "number" ||
|
|
15
|
+
typeof object === "undefined" ||
|
|
16
|
+
typeof object === "boolean"
|
|
17
|
+
) {
|
|
18
|
+
return String(object);
|
|
19
|
+
}
|
|
20
|
+
const retVal = JSON.stringify(
|
|
21
|
+
object,
|
|
22
|
+
(key, value) => {
|
|
23
|
+
if (key.toLowerCase().includes("request")) {
|
|
24
|
+
return JSON.stringify({
|
|
25
|
+
body: value?.body,
|
|
26
|
+
query: value?.query,
|
|
27
|
+
headers: value?.headers,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (key.toLowerCase().includes("response")) {
|
|
32
|
+
return JSON.stringify({
|
|
33
|
+
statusText: value?.statusText,
|
|
34
|
+
status: value?.status,
|
|
35
|
+
data: value?.data,
|
|
36
|
+
headers: value?.headers,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return typeof value === "object" && value !== null
|
|
41
|
+
? cache.includes(value)
|
|
42
|
+
? "duplicated reference" // Duplicated references were found, discarding this key
|
|
43
|
+
: cache.push(value) && value // Store value in our collection
|
|
44
|
+
: value;
|
|
45
|
+
},
|
|
46
|
+
indent
|
|
47
|
+
);
|
|
48
|
+
cache = null;
|
|
49
|
+
return retVal;
|
|
50
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
|
|
4
|
+
import s from "./asset-icon.module.scss";
|
|
5
|
+
|
|
6
|
+
export const AssetIcon = ({
|
|
7
|
+
assetIconSrc,
|
|
8
|
+
assetIconProtocolSrc = null,
|
|
9
|
+
fallbackSrc = null,
|
|
10
|
+
small = false,
|
|
11
|
+
}) => {
|
|
12
|
+
const handleFailedLoad = (e) => {
|
|
13
|
+
e.target.onerror = null;
|
|
14
|
+
e.target.src = fallbackSrc;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<div className={s["asset-icon"] + (small ? " " + s["small"] : "")}>
|
|
19
|
+
<img
|
|
20
|
+
src={assetIconSrc}
|
|
21
|
+
className={
|
|
22
|
+
s["asset-icon-primary"] + (small ? " " + s["small"] : "")
|
|
23
|
+
}
|
|
24
|
+
alt={" "}
|
|
25
|
+
onError={handleFailedLoad}
|
|
26
|
+
/>
|
|
27
|
+
{assetIconProtocolSrc ? (
|
|
28
|
+
<img
|
|
29
|
+
src={assetIconProtocolSrc}
|
|
30
|
+
className={
|
|
31
|
+
s["asset-icon-secondary"] +
|
|
32
|
+
(small ? " " + s["small"] : "")
|
|
33
|
+
}
|
|
34
|
+
alt={" "}
|
|
35
|
+
onError={handleFailedLoad}
|
|
36
|
+
/>
|
|
37
|
+
) : (
|
|
38
|
+
""
|
|
39
|
+
)}
|
|
40
|
+
</div>
|
|
41
|
+
);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
AssetIcon.propTypes = {
|
|
45
|
+
assetIconSrc: PropTypes.string.isRequired,
|
|
46
|
+
assetIconProtocolSrc: PropTypes.string,
|
|
47
|
+
fallbackSrc: PropTypes.string,
|
|
48
|
+
small: PropTypes.bool,
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
AssetIcon.defaultProps = {
|
|
52
|
+
assetIconProtocolSrc: null,
|
|
53
|
+
fallbackSrc: null,
|
|
54
|
+
small: false,
|
|
55
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
@import "../../../../styles/index";
|
|
2
|
+
|
|
3
|
+
.asset-icon {
|
|
4
|
+
width: 34px;
|
|
5
|
+
height: 34px;
|
|
6
|
+
position: relative;
|
|
7
|
+
|
|
8
|
+
&.small {
|
|
9
|
+
width: 24px;
|
|
10
|
+
height: 24px;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
&-primary {
|
|
14
|
+
height: 34px;
|
|
15
|
+
width: 34px;
|
|
16
|
+
|
|
17
|
+
&.small {
|
|
18
|
+
width: 24px;
|
|
19
|
+
height: 24px;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
&-secondary {
|
|
24
|
+
width: 17px;
|
|
25
|
+
height: 17px;
|
|
26
|
+
|
|
27
|
+
position: absolute;
|
|
28
|
+
right: -3px;
|
|
29
|
+
bottom: -3px;
|
|
30
|
+
box-shadow: -2px -2px 4px 1px rgba(SolidColor("dark"), 0.3);
|
|
31
|
+
border-radius: 100%;
|
|
32
|
+
|
|
33
|
+
&.small {
|
|
34
|
+
width: 12px;
|
|
35
|
+
height: 12px;
|
|
36
|
+
|
|
37
|
+
right: -2px;
|
|
38
|
+
bottom: -2px;
|
|
39
|
+
box-shadow: -1px -1px 8px 1px rgba(SolidColor("dark"), 0.3);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
|
|
4
|
+
export const SupportChat = ({
|
|
5
|
+
url,
|
|
6
|
+
websiteToken,
|
|
7
|
+
welcomeMessage = "",
|
|
8
|
+
locale = "en",
|
|
9
|
+
}) => {
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
window.chatwootSettings = {
|
|
12
|
+
position: "right",
|
|
13
|
+
type: "standard",
|
|
14
|
+
launcherTitle: welcomeMessage,
|
|
15
|
+
locale: locale,
|
|
16
|
+
};
|
|
17
|
+
(function (d, t) {
|
|
18
|
+
var BASE_URL = url;
|
|
19
|
+
var g = d.createElement(t),
|
|
20
|
+
s = d.getElementsByTagName(t)[0];
|
|
21
|
+
g.src = BASE_URL + "/packs/js/sdk.js";
|
|
22
|
+
g.defer = true;
|
|
23
|
+
g.async = true;
|
|
24
|
+
s.parentNode.insertBefore(g, s);
|
|
25
|
+
g.onload = function () {
|
|
26
|
+
window.chatwootSDK.run({
|
|
27
|
+
websiteToken: websiteToken,
|
|
28
|
+
baseUrl: BASE_URL,
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
})(document, "script");
|
|
32
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
33
|
+
}, []);
|
|
34
|
+
|
|
35
|
+
return null;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
SupportChat.propTypes = {
|
|
39
|
+
url: PropTypes.string.isRequired,
|
|
40
|
+
websiteToken: PropTypes.string.isRequired,
|
|
41
|
+
welcomeMessage: PropTypes.string,
|
|
42
|
+
locale: PropTypes.string,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
SupportChat.defaultProps = {
|
|
46
|
+
welcomeMessage: "",
|
|
47
|
+
locale: "en",
|
|
48
|
+
};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React, { useEffect, useRef, useState } from "react";
|
|
2
|
-
import { Link } from "react-router-dom";
|
|
3
2
|
import PropTypes from "prop-types";
|
|
4
3
|
|
|
5
4
|
import styles from "./Button.module.scss";
|
|
@@ -9,7 +8,7 @@ import { LoadingDots } from "../../LoadingDots/LoadingDots.jsx";
|
|
|
9
8
|
/**
|
|
10
9
|
* Button component - A versatile and customizable button for React applications.
|
|
11
10
|
* It supports various sizes, styles, and functionalities, including loaders, icons, and handling of click events.
|
|
12
|
-
* This component can also be used as a link
|
|
11
|
+
* This component can also be used as a link if "to" is provided.
|
|
13
12
|
*
|
|
14
13
|
* @component
|
|
15
14
|
* @param {Object} props
|
|
@@ -85,7 +84,11 @@ export const Button = ({
|
|
|
85
84
|
}, 2000);
|
|
86
85
|
}
|
|
87
86
|
|
|
88
|
-
e
|
|
87
|
+
if (e?.persist) {
|
|
88
|
+
// Persisting React's SyntheticEvent to be able to use it in any async context
|
|
89
|
+
e.persist();
|
|
90
|
+
}
|
|
91
|
+
|
|
89
92
|
!propagatePrimaryButtonClick && e.stopPropagation();
|
|
90
93
|
if (loader) {
|
|
91
94
|
setIsLoading(true);
|
|
@@ -108,11 +111,11 @@ export const Button = ({
|
|
|
108
111
|
<>
|
|
109
112
|
{isFormSubmittingButton ? <input type="submit" hidden /> : null}
|
|
110
113
|
{to ? (
|
|
111
|
-
<
|
|
114
|
+
<a
|
|
112
115
|
className={classNames}
|
|
113
116
|
onClick={(e) => handleError(buttonClick, e)}
|
|
114
|
-
|
|
115
|
-
|
|
117
|
+
href={to}
|
|
118
|
+
ref={buttonRef}
|
|
116
119
|
>
|
|
117
120
|
{icon ? (
|
|
118
121
|
<div
|
|
@@ -129,7 +132,7 @@ export const Button = ({
|
|
|
129
132
|
) : (
|
|
130
133
|
content
|
|
131
134
|
)}
|
|
132
|
-
</
|
|
135
|
+
</a>
|
|
133
136
|
) : (
|
|
134
137
|
<div
|
|
135
138
|
className={classNames}
|
|
@@ -188,6 +191,7 @@ Button.propTypes = {
|
|
|
188
191
|
mode: PropTypes.oneOf([
|
|
189
192
|
"transparent",
|
|
190
193
|
"white",
|
|
194
|
+
"white-flat",
|
|
191
195
|
"primary",
|
|
192
196
|
"primary-bordered",
|
|
193
197
|
"primary-transparent",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
@import "
|
|
1
|
+
@import "../../../../../styles/index";
|
|
2
2
|
|
|
3
3
|
.button {
|
|
4
4
|
@extend %text-very-bold;
|
|
@@ -122,6 +122,11 @@
|
|
|
122
122
|
box-shadow: 0 20px 20px rgba(15, 24, 75, 0.2);
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
+
&.white-flat {
|
|
126
|
+
background: $white;
|
|
127
|
+
color: SolidColor("dark");
|
|
128
|
+
}
|
|
129
|
+
|
|
125
130
|
&-primary-dots-wrapper {
|
|
126
131
|
position: absolute;
|
|
127
132
|
top: 50%;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { useCallback, useState } from "react";
|
|
2
|
+
|
|
3
|
+
import { Logger } from "../../common/utils/logging/logger.js";
|
|
4
|
+
|
|
5
|
+
export function useCallHandlingErrors() {
|
|
6
|
+
const [, setState] = useState();
|
|
7
|
+
return useCallback(
|
|
8
|
+
async (functionToBeCalled, event) => {
|
|
9
|
+
try {
|
|
10
|
+
await functionToBeCalled(event);
|
|
11
|
+
} catch (error) {
|
|
12
|
+
Logger.logError(
|
|
13
|
+
error,
|
|
14
|
+
functionToBeCalled?.name || "errorBoundaryTrigger",
|
|
15
|
+
"Caught by ErrorBoundary"
|
|
16
|
+
);
|
|
17
|
+
// Triggering ErrorBoundary
|
|
18
|
+
setState(() => {
|
|
19
|
+
throw error;
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
[]
|
|
25
|
+
);
|
|
26
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Adds reference to standard state variable. It is helpful to be able to use state variable value inside
|
|
5
|
+
* event handlers and other callbacks without the need to call setState(prev => { value = prev; return prev; }).
|
|
6
|
+
*
|
|
7
|
+
* @param initialValue {any} to be passed to useState
|
|
8
|
+
* @return {[React.Ref, function]} reference to state variable and its setter
|
|
9
|
+
*/
|
|
10
|
+
export function useReferredState(initialValue) {
|
|
11
|
+
const [state, setState] = React.useState(initialValue);
|
|
12
|
+
const reference = React.useRef(state);
|
|
13
|
+
|
|
14
|
+
const setReferredState = (value) => {
|
|
15
|
+
if (value && {}.toString.call(value) === "[object Function]") {
|
|
16
|
+
value = value(reference.current);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
reference.current = value;
|
|
20
|
+
setState(value);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
return [reference, setReferredState];
|
|
24
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export const handleClickOutside = (exceptionsRefs, callback) => {
|
|
2
|
+
function handleClick(event) {
|
|
3
|
+
const isExceptionClicked = exceptionsRefs.find(
|
|
4
|
+
(ref) => ref?.current && ref.current.contains(event.target)
|
|
5
|
+
);
|
|
6
|
+
if (!isExceptionClicked) {
|
|
7
|
+
callback();
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
document.addEventListener("click", handleClick);
|
|
12
|
+
|
|
13
|
+
return () => document.removeEventListener("click", handleClick);
|
|
14
|
+
};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
const PARAMETER_VALUES_SEPARATOR = "|*|"; // Sting that with high probability will not be in the user's data
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Adds specified parameter with values to the URL query string
|
|
5
|
+
*
|
|
6
|
+
* @param parameterName - String - name of the parameter
|
|
7
|
+
* @param values - Array of String values
|
|
8
|
+
* @param updateURLCallback - callback that will be called with the updated query string. Can be used to save it to URL
|
|
9
|
+
*/
|
|
10
|
+
export function saveQueryParameterAndValues(
|
|
11
|
+
parameterName,
|
|
12
|
+
values,
|
|
13
|
+
updateURLCallback = (newQueryString) => {}
|
|
14
|
+
) {
|
|
15
|
+
let parametersAndValues = parseSearchString();
|
|
16
|
+
parametersAndValues = parametersAndValues.filter(
|
|
17
|
+
(parameterAndValues) => parameterAndValues[0] !== parameterName
|
|
18
|
+
);
|
|
19
|
+
const parameterValuesForURL = encodeURIComponent(
|
|
20
|
+
values.join(PARAMETER_VALUES_SEPARATOR)
|
|
21
|
+
);
|
|
22
|
+
parametersAndValues.push([parameterName, parameterValuesForURL]);
|
|
23
|
+
const newQueryString = `?${parametersAndValues
|
|
24
|
+
.map((parameterAndValues) => parameterAndValues.join("="))
|
|
25
|
+
.join("&")}`;
|
|
26
|
+
updateURLCallback(newQueryString);
|
|
27
|
+
|
|
28
|
+
return newQueryString;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Removes specified parameter with values from the URL query string
|
|
33
|
+
*
|
|
34
|
+
* @param parameterName - String - name of the parameter
|
|
35
|
+
* @param updateURLCallback - callback that will be called with the updated query string. Can be used to save it to URL
|
|
36
|
+
*/
|
|
37
|
+
// TODO: [tests, moderate] units required the same as or other functions in this module
|
|
38
|
+
export function removeQueryParameterAndValues(
|
|
39
|
+
parameterName,
|
|
40
|
+
updateURLCallback = (newQueryString) => {}
|
|
41
|
+
) {
|
|
42
|
+
let parametersAndValues = parseSearchString();
|
|
43
|
+
parametersAndValues = parametersAndValues.filter(
|
|
44
|
+
(parameterAndValues) => parameterAndValues[0] !== parameterName
|
|
45
|
+
);
|
|
46
|
+
const newQueryString = `?${parametersAndValues
|
|
47
|
+
.map((parameterAndValues) => parameterAndValues.join("="))
|
|
48
|
+
.join("&")}`;
|
|
49
|
+
updateURLCallback(newQueryString);
|
|
50
|
+
|
|
51
|
+
return newQueryString;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Retrieves parameter values from the URL query string.
|
|
56
|
+
*
|
|
57
|
+
* If there are several parameters with the same name in the URL then all their values are returned
|
|
58
|
+
*
|
|
59
|
+
* @param name {string} - parameter name
|
|
60
|
+
* @return {string[]} [] - if the parameter is not present in URL. [""] - if parameter present but has empty value
|
|
61
|
+
*/
|
|
62
|
+
export function getQueryParameterValues(name) {
|
|
63
|
+
return parseSearchString()
|
|
64
|
+
.filter((parameterAndValue) => parameterAndValue[0] === name)
|
|
65
|
+
.reduce((allValues, parameterAndValue) => {
|
|
66
|
+
const values = decodeURIComponent(parameterAndValue[1] || "").split(
|
|
67
|
+
PARAMETER_VALUES_SEPARATOR
|
|
68
|
+
);
|
|
69
|
+
return [...allValues, ...values];
|
|
70
|
+
}, []);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function parseSearchString() {
|
|
74
|
+
const trimmed = (window.location.search?.slice(1) || "").trim();
|
|
75
|
+
|
|
76
|
+
return (
|
|
77
|
+
(trimmed &&
|
|
78
|
+
trimmed
|
|
79
|
+
.split("&")
|
|
80
|
+
.map((parameterAndValue) => parameterAndValue.split("="))) ||
|
|
81
|
+
[]
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function getQueryParameterSingleValue(name) {
|
|
86
|
+
return (getQueryParameterValues(name) || [])[0];
|
|
87
|
+
}
|
package/src/index.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// UI-KIT components
|
|
2
|
+
export { Button } from "./components/atoms/buttons/Button/Button.jsx";
|
|
3
|
+
export { LoadingDots } from "./components/atoms/LoadingDots/LoadingDots.jsx";
|
|
4
|
+
export { SupportChat } from "./components/atoms/SupportChat/SupportChat.jsx";
|
|
5
|
+
export { AssetIcon } from "./components/atoms/AssetIcon/AssetIcon.jsx";
|
|
6
|
+
|
|
7
|
+
export { useCallHandlingErrors } from "./components/hooks/useCallHandlingErrors.js";
|
|
8
|
+
export { useReferredState } from "./components/hooks/useReferredState.js";
|
|
9
|
+
export { handleClickOutside } from "./components/utils/uiUtils.js";
|
|
10
|
+
|
|
11
|
+
export { saveQueryParameterAndValues } from "./components/utils/urlQueryUtils.js";
|
|
12
|
+
export { removeQueryParameterAndValues } from "./components/utils/urlQueryUtils.js";
|
|
13
|
+
export { getQueryParameterSingleValue } from "./components/utils/urlQueryUtils.js";
|
|
14
|
+
export { getQueryParameterValues } from "./components/utils/urlQueryUtils.js";
|
|
15
|
+
|
|
16
|
+
// Common code lib (to be extracted later to dedicated lib)
|
|
17
|
+
export { improveAndRethrow } from "./common/errorUtils.js";
|
|
18
|
+
export { logErrorOrOutputToConsole } from "./common/errorUtils.js";
|
|
19
|
+
export { FiatCurrenciesService } from "./common/fiatCurrenciesService.js";
|
|
20
|
+
export { AmountUtils } from "./common/amountUtils.js";
|
|
21
|
+
|
|
22
|
+
export { Blockchain } from "./common/models/blockchain.js";
|
|
23
|
+
export { Protocol } from "./common/models/protocol.js";
|
|
24
|
+
export { Coin } from "./common/models/coin.js";
|
|
25
|
+
|
|
26
|
+
export { Cache } from "./common/utils/cache.js";
|
|
27
|
+
export { safeStringify } from "./common/utils/safeStringify.js";
|
|
28
|
+
export { LogsStorage } from "./common/utils/logging/logsStorage.js";
|
|
29
|
+
export { Logger } from "./common/utils/logging/logger.js";
|
|
30
|
+
export { postponeExecution } from "./common/utils/postponeExecution.js";
|
|
31
|
+
export { AxiosAdapter } from "./common/adapters/axiosAdapter.js";
|
|
32
|
+
|
|
33
|
+
export { EmailsApi } from "./common/utils/emailAPI.js";
|
|
34
|
+
|
|
35
|
+
// Robust data retriever service and related APIs
|
|
36
|
+
export { CacheAndConcurrentRequestsResolver } from "./robustExteranlApiCallerService/cacheAndConcurrentRequestsResolver.js";
|
|
37
|
+
export { CachedRobustExternalApiCallerService } from "./robustExteranlApiCallerService/cachedRobustExternalApiCallerService.js";
|
|
38
|
+
export { CancelProcessing } from "./robustExteranlApiCallerService/cancelProcessing.js";
|
|
39
|
+
export { ExternalApiProvider } from "./robustExteranlApiCallerService/externalApiProvider.js";
|
|
40
|
+
export { RobustExternalAPICallerService } from "./robustExteranlApiCallerService/robustExternalAPICallerService.js";
|
|
41
|
+
|
|
42
|
+
export { ApiGroups } from "./common/external-apis/apiGroups.js";
|
|
43
|
+
export { ApiGroup } from "./common/external-apis/apiGroups.js";
|
|
44
|
+
|
|
45
|
+
// Swaps lib (to be extracted later to dedicated lib)
|
|
46
|
+
export { ExistingSwap } from "./swaps-lib/models/existingSwap.js";
|
|
47
|
+
export { ExistingSwapWithFiatData } from "./swaps-lib/models/existingSwapWithFiatData.js";
|
|
48
|
+
export { BaseSwapCreationInfo } from "./swaps-lib/models/baseSwapCreationInfo.js";
|
|
49
|
+
export { SwapProvider } from "./swaps-lib/external-apis/swapProvider.js";
|
|
50
|
+
export { SwapspaceSwapProvider } from "./swaps-lib/external-apis/swapspaceSwapProvider.js";
|
|
51
|
+
export { SwapUtils } from "./swaps-lib/utils/swapUtils.js";
|
|
52
|
+
export { PublicSwapService } from "./swaps-lib/services/publicSwapService.js";
|