@dynamic-labs/utils 0.0.0-exp20240808.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/CHANGELOG.md +3746 -0
- package/LICENSE +21 -0
- package/README.md +0 -0
- package/_virtual/_tslib.cjs +51 -0
- package/_virtual/_tslib.js +45 -0
- package/package.json +37 -0
- package/src/CancellablePromise/CancellablePromise.cjs +136 -0
- package/src/CancellablePromise/CancellablePromise.d.ts +54 -0
- package/src/CancellablePromise/CancellablePromise.js +132 -0
- package/src/CancellablePromise/index.d.ts +1 -0
- package/src/DeferredPromise/DeferredPromise.cjs +22 -0
- package/src/DeferredPromise/DeferredPromise.d.ts +13 -0
- package/src/DeferredPromise/DeferredPromise.js +18 -0
- package/src/DeferredPromise/index.d.ts +1 -0
- package/src/bufferPolyfill.cjs +15 -0
- package/src/bufferPolyfill.d.ts +1 -0
- package/src/bufferPolyfill.js +13 -0
- package/src/bufferToBase64.cjs +15 -0
- package/src/bufferToBase64.d.ts +2 -0
- package/src/bufferToBase64.js +11 -0
- package/src/ceil/ceil.cjs +11 -0
- package/src/ceil/ceil.d.ts +1 -0
- package/src/ceil/ceil.js +7 -0
- package/src/ceil/index.d.ts +1 -0
- package/src/eip6963/eip6963Provider.cjs +40 -0
- package/src/eip6963/eip6963Provider.d.ts +34 -0
- package/src/eip6963/eip6963Provider.js +35 -0
- package/src/eip6963/index.d.ts +1 -0
- package/src/errors/AccessBlockedError.cjs +11 -0
- package/src/errors/AccessBlockedError.d.ts +3 -0
- package/src/errors/AccessBlockedError.js +7 -0
- package/src/errors/AccountExistsError.cjs +16 -0
- package/src/errors/AccountExistsError.d.ts +14 -0
- package/src/errors/AccountExistsError.js +12 -0
- package/src/errors/ChainalysisError.cjs +15 -0
- package/src/errors/ChainalysisError.d.ts +5 -0
- package/src/errors/ChainalysisError.js +11 -0
- package/src/errors/CookieInvalidError.cjs +14 -0
- package/src/errors/CookieInvalidError.d.ts +4 -0
- package/src/errors/CookieInvalidError.js +10 -0
- package/src/errors/CustomError.cjs +24 -0
- package/src/errors/CustomError.d.ts +11 -0
- package/src/errors/CustomError.js +20 -0
- package/src/errors/CustomFieldNotUniqueError.cjs +14 -0
- package/src/errors/CustomFieldNotUniqueError.d.ts +4 -0
- package/src/errors/CustomFieldNotUniqueError.js +10 -0
- package/src/errors/DynamicError.cjs +11 -0
- package/src/errors/DynamicError.d.ts +3 -0
- package/src/errors/DynamicError.js +7 -0
- package/src/errors/EmailAlreadyExistsError.cjs +14 -0
- package/src/errors/EmailAlreadyExistsError.d.ts +4 -0
- package/src/errors/EmailAlreadyExistsError.js +10 -0
- package/src/errors/EmailProviderError.cjs +14 -0
- package/src/errors/EmailProviderError.d.ts +4 -0
- package/src/errors/EmailProviderError.js +10 -0
- package/src/errors/EmailVerificationError.cjs +14 -0
- package/src/errors/EmailVerificationError.d.ts +4 -0
- package/src/errors/EmailVerificationError.js +10 -0
- package/src/errors/EmbeddedWalletException.cjs +14 -0
- package/src/errors/EmbeddedWalletException.d.ts +4 -0
- package/src/errors/EmbeddedWalletException.js +10 -0
- package/src/errors/ExternalAuthError.cjs +14 -0
- package/src/errors/ExternalAuthError.d.ts +4 -0
- package/src/errors/ExternalAuthError.js +10 -0
- package/src/errors/GateBlockedError.cjs +15 -0
- package/src/errors/GateBlockedError.d.ts +5 -0
- package/src/errors/GateBlockedError.js +11 -0
- package/src/errors/InsufficientFundsError.cjs +25 -0
- package/src/errors/InsufficientFundsError.d.ts +9 -0
- package/src/errors/InsufficientFundsError.js +21 -0
- package/src/errors/InvalidPhoneNumberError.cjs +14 -0
- package/src/errors/InvalidPhoneNumberError.d.ts +4 -0
- package/src/errors/InvalidPhoneNumberError.js +10 -0
- package/src/errors/MergeAccountsConfirmationError.cjs +16 -0
- package/src/errors/MergeAccountsConfirmationError.d.ts +12 -0
- package/src/errors/MergeAccountsConfirmationError.js +12 -0
- package/src/errors/MfaInvalidOtpError.cjs +14 -0
- package/src/errors/MfaInvalidOtpError.d.ts +4 -0
- package/src/errors/MfaInvalidOtpError.js +10 -0
- package/src/errors/MissingEnvironmentIdError.cjs +14 -0
- package/src/errors/MissingEnvironmentIdError.d.ts +4 -0
- package/src/errors/MissingEnvironmentIdError.js +10 -0
- package/src/errors/MissingPublicAddressError.cjs +14 -0
- package/src/errors/MissingPublicAddressError.d.ts +4 -0
- package/src/errors/MissingPublicAddressError.js +10 -0
- package/src/errors/NoAccessError.cjs +19 -0
- package/src/errors/NoAccessError.d.ts +15 -0
- package/src/errors/NoAccessError.js +15 -0
- package/src/errors/NotSupportedError.cjs +11 -0
- package/src/errors/NotSupportedError.d.ts +3 -0
- package/src/errors/NotSupportedError.js +7 -0
- package/src/errors/PasskeyError.d.ts +8 -0
- package/src/errors/SmsVerificationError.cjs +11 -0
- package/src/errors/SmsVerificationError.d.ts +3 -0
- package/src/errors/SmsVerificationError.js +7 -0
- package/src/errors/SocialAccountAlreadyExistsError.cjs +14 -0
- package/src/errors/SocialAccountAlreadyExistsError.d.ts +4 -0
- package/src/errors/SocialAccountAlreadyExistsError.js +10 -0
- package/src/errors/TooManyEmailVerificationsError.cjs +14 -0
- package/src/errors/TooManyEmailVerificationsError.d.ts +4 -0
- package/src/errors/TooManyEmailVerificationsError.js +10 -0
- package/src/errors/TransactionGasCannotBeSponsoredError.cjs +25 -0
- package/src/errors/TransactionGasCannotBeSponsoredError.d.ts +9 -0
- package/src/errors/TransactionGasCannotBeSponsoredError.js +21 -0
- package/src/errors/UserHasAccountWithEmailError.cjs +15 -0
- package/src/errors/UserHasAccountWithEmailError.d.ts +5 -0
- package/src/errors/UserHasAccountWithEmailError.js +11 -0
- package/src/errors/UserRejectedTransactionError.cjs +14 -0
- package/src/errors/UserRejectedTransactionError.d.ts +4 -0
- package/src/errors/UserRejectedTransactionError.js +10 -0
- package/src/errors/UsernameAlreadyExistsError.cjs +14 -0
- package/src/errors/UsernameAlreadyExistsError.d.ts +4 -0
- package/src/errors/UsernameAlreadyExistsError.js +10 -0
- package/src/errors/VerificationDataCollectionError.cjs +15 -0
- package/src/errors/VerificationDataCollectionError.d.ts +5 -0
- package/src/errors/VerificationDataCollectionError.js +11 -0
- package/src/errors/WalletAddressMismatchError.cjs +17 -0
- package/src/errors/WalletAddressMismatchError.d.ts +11 -0
- package/src/errors/WalletAddressMismatchError.js +13 -0
- package/src/errors/WalletNotDeployedError.cjs +14 -0
- package/src/errors/WalletNotDeployedError.d.ts +4 -0
- package/src/errors/WalletNotDeployedError.js +10 -0
- package/src/errors/WalletUsedError.cjs +14 -0
- package/src/errors/WalletUsedError.d.ts +4 -0
- package/src/errors/WalletUsedError.js +10 -0
- package/src/errors/index.d.ts +33 -0
- package/src/formatNumberText/formatNumberText.cjs +20 -0
- package/src/formatNumberText/formatNumberText.d.ts +5 -0
- package/src/formatNumberText/formatNumberText.js +16 -0
- package/src/formatNumberText/index.d.ts +1 -0
- package/src/get/get.cjs +24 -0
- package/src/get/get.d.ts +7 -0
- package/src/get/get.js +20 -0
- package/src/get/index.d.ts +1 -0
- package/src/getProvidersFromWindow.cjs +39 -0
- package/src/getProvidersFromWindow.d.ts +7 -0
- package/src/getProvidersFromWindow.js +35 -0
- package/src/getTLD/getTLD.cjs +12 -0
- package/src/getTLD/getTLD.d.ts +1 -0
- package/src/getTLD/getTLD.js +8 -0
- package/src/getTLD/index.d.ts +1 -0
- package/src/handleMobileWalletRedirect/handleMobileWalletRedirect.cjs +20 -0
- package/src/handleMobileWalletRedirect/handleMobileWalletRedirect.d.ts +4 -0
- package/src/handleMobileWalletRedirect/handleMobileWalletRedirect.js +16 -0
- package/src/handleMobileWalletRedirect/index.d.ts +1 -0
- package/src/hexToString/hexToString.cjs +32 -0
- package/src/hexToString/hexToString.d.ts +12 -0
- package/src/hexToString/hexToString.js +28 -0
- package/src/hexToString/index.d.ts +1 -0
- package/src/index.cjs +151 -0
- package/src/index.d.ts +32 -0
- package/src/index.js +66 -0
- package/src/isFunction/index.d.ts +1 -0
- package/src/isFunction/isFunction.cjs +9 -0
- package/src/isFunction/isFunction.d.ts +1 -0
- package/src/isFunction/isFunction.js +5 -0
- package/src/isHex/index.d.ts +1 -0
- package/src/isHex/isHex.cjs +20 -0
- package/src/isHex/isHex.d.ts +6 -0
- package/src/isHex/isHex.js +16 -0
- package/src/isLedgerAddressViaVerifiedCredentials.cjs +13 -0
- package/src/isLedgerAddressViaVerifiedCredentials.d.ts +2 -0
- package/src/isLedgerAddressViaVerifiedCredentials.js +9 -0
- package/src/isMobile.cjs +146 -0
- package/src/isMobile.d.ts +18 -0
- package/src/isMobile.js +133 -0
- package/src/last.cjs +22 -0
- package/src/last.d.ts +15 -0
- package/src/last.js +18 -0
- package/src/localStorageAsync.cjs +38 -0
- package/src/localStorageAsync.d.ts +3 -0
- package/src/localStorageAsync.js +32 -0
- package/src/logger/index.d.ts +1 -0
- package/src/logger/logger.cjs +10 -0
- package/src/logger/logger.d.ts +2 -0
- package/src/logger/logger.js +6 -0
- package/src/nativeMobileOauthStateParam.cjs +13 -0
- package/src/nativeMobileOauthStateParam.d.ts +14 -0
- package/src/nativeMobileOauthStateParam.js +9 -0
- package/src/parseChainId.cjs +8 -0
- package/src/parseChainId.d.ts +1 -0
- package/src/parseChainId.js +4 -0
- package/src/parseEvmNetworks.cjs +17 -0
- package/src/parseEvmNetworks.d.ts +2 -0
- package/src/parseEvmNetworks.js +13 -0
- package/src/pipe/index.d.ts +1 -0
- package/src/pipe/pipe.cjs +40 -0
- package/src/pipe/pipe.d.ts +27 -0
- package/src/pipe/pipe.js +36 -0
- package/src/retryableFn.cjs +73 -0
- package/src/retryableFn.d.ts +19 -0
- package/src/retryableFn.js +68 -0
- package/src/runSafe/index.d.ts +1 -0
- package/src/runSafe/runSafe.cjs +25 -0
- package/src/runSafe/runSafe.d.ts +8 -0
- package/src/runSafe/runSafe.js +21 -0
- package/src/services/FetchService/FetchService.cjs +29 -0
- package/src/services/FetchService/FetchService.d.ts +10 -0
- package/src/services/FetchService/FetchService.js +25 -0
- package/src/services/FetchService/index.d.ts +2 -0
- package/src/services/FetchService/types.d.ts +3 -0
- package/src/services/Oauth2Service/Oauth2Service.cjs +38 -0
- package/src/services/Oauth2Service/Oauth2Service.d.ts +34 -0
- package/src/services/Oauth2Service/Oauth2Service.js +34 -0
- package/src/services/Oauth2Service/createWindowOauth2Service/createWindowOauth2Service.cjs +192 -0
- package/src/services/Oauth2Service/createWindowOauth2Service/createWindowOauth2Service.d.ts +2 -0
- package/src/services/Oauth2Service/createWindowOauth2Service/createWindowOauth2Service.js +188 -0
- package/src/services/Oauth2Service/createWindowOauth2Service/index.d.ts +1 -0
- package/src/services/Oauth2Service/index.d.ts +2 -0
- package/src/services/PlatformService/PlatformService.cjs +40 -0
- package/src/services/PlatformService/PlatformService.d.ts +11 -0
- package/src/services/PlatformService/PlatformService.js +36 -0
- package/src/services/PlatformService/createBrowserPlatformService/createBrowserPlatformService.cjs +30 -0
- package/src/services/PlatformService/createBrowserPlatformService/createBrowserPlatformService.d.ts +2 -0
- package/src/services/PlatformService/createBrowserPlatformService/createBrowserPlatformService.js +26 -0
- package/src/services/PlatformService/createBrowserPlatformService/index.d.ts +1 -0
- package/src/services/PlatformService/index.d.ts +3 -0
- package/src/services/PlatformService/types.d.ts +25 -0
- package/src/sleep/index.d.ts +1 -0
- package/src/sleep/sleep.cjs +13 -0
- package/src/sleep/sleep.d.ts +11 -0
- package/src/sleep/sleep.js +9 -0
- package/src/template/index.d.ts +1 -0
- package/src/template/template.cjs +25 -0
- package/src/template/template.d.ts +18 -0
- package/src/template/template.js +21 -0
- package/src/trimEnd/index.d.ts +1 -0
- package/src/trimEnd/trimEnd.cjs +14 -0
- package/src/trimEnd/trimEnd.d.ts +1 -0
- package/src/trimEnd/trimEnd.js +10 -0
- package/src/uniq/index.d.ts +1 -0
- package/src/uniq/uniq.cjs +33 -0
- package/src/uniq/uniq.d.ts +17 -0
- package/src/uniq/uniq.js +29 -0
- package/src/wrapMethodWithCallback/index.d.ts +1 -0
- package/src/wrapMethodWithCallback/wrapMethodWithCallback.cjs +47 -0
- package/src/wrapMethodWithCallback/wrapMethodWithCallback.d.ts +36 -0
- package/src/wrapMethodWithCallback/wrapMethodWithCallback.js +43 -0
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
5
|
+
|
|
6
|
+
var _tslib = require('../../../../_virtual/_tslib.cjs');
|
|
7
|
+
var types = require('@dynamic-labs/types');
|
|
8
|
+
var sdkApiCore = require('@dynamic-labs/sdk-api-core');
|
|
9
|
+
var logger = require('../../../logger/logger.cjs');
|
|
10
|
+
|
|
11
|
+
const providersWithoutWindowOpenerReference = ['twitter'];
|
|
12
|
+
let authWindowInterval;
|
|
13
|
+
const createWindowOauth2Service = () => ({
|
|
14
|
+
getOauthCode: ({ apiProvider, provider, setIsProcessing, state, oauthLoginUrl, getOAuthResultFromApi, sessionTimeout, isMobile, onSettled, }) => new Promise((resolve, _reject) => {
|
|
15
|
+
// When we catch this error we assume it follows this type, so we must enforce it
|
|
16
|
+
// here to ensure the assumption is correct
|
|
17
|
+
const typedReject = (params) => _reject(params);
|
|
18
|
+
// Clear any potential pending timeouts and intervals
|
|
19
|
+
clearInterval(authWindowInterval);
|
|
20
|
+
const providersWaitingOauthMessage = {};
|
|
21
|
+
let shouldPool = false;
|
|
22
|
+
const authWindow = window.open('', '_blank', 'width=500,height=600');
|
|
23
|
+
const clearListeners = () => {
|
|
24
|
+
window.removeEventListener('message', handleWindowMessage);
|
|
25
|
+
providersWaitingOauthMessage[provider] = false;
|
|
26
|
+
};
|
|
27
|
+
const handleWindowMessage = (event) => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
28
|
+
const message = event.data;
|
|
29
|
+
const expectedOrigin = getExpectedOrigin(apiProvider, provider);
|
|
30
|
+
if (!expectedOrigin) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
if ((message === null || message === void 0 ? void 0 : message.type) === 'origin_check' && authWindow) {
|
|
34
|
+
logger.logger.debug('Origin check message received. Sending response now.', {
|
|
35
|
+
data: message,
|
|
36
|
+
expectedOrigin,
|
|
37
|
+
});
|
|
38
|
+
authWindow.postMessage('origin_check_response', expectedOrigin);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const isTelegramCompletedMessage = (message === null || message === void 0 ? void 0 : message.type) === 'telegram_completed';
|
|
42
|
+
const isAuthorizationMessage = (message === null || message === void 0 ? void 0 : message.type) === 'authorization_response';
|
|
43
|
+
if (isAuthorizationMessage || isTelegramCompletedMessage) {
|
|
44
|
+
logger.logger.debug('Message received', { data: message });
|
|
45
|
+
}
|
|
46
|
+
const isExpectedOrigin = event.origin === expectedOrigin;
|
|
47
|
+
const isValidMessage = ((isAuthorizationMessage && (message === null || message === void 0 ? void 0 : message.provider) === provider) ||
|
|
48
|
+
isTelegramCompletedMessage) &&
|
|
49
|
+
isExpectedOrigin;
|
|
50
|
+
// don't process invalid messages for provider
|
|
51
|
+
if (!isValidMessage) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
setIsProcessing(true);
|
|
55
|
+
if (!providersWaitingOauthMessage[provider]) {
|
|
56
|
+
typedReject({
|
|
57
|
+
code: types.SocialOAuthErrorCode.SESSION_TIMEOUT,
|
|
58
|
+
message: `Connecting ${provider} account session timeout.`,
|
|
59
|
+
});
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
clearListeners();
|
|
63
|
+
if (isTelegramCompletedMessage) {
|
|
64
|
+
handleTelegramCompletionMessage(message);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
handleAuthorizationMessage(message, provider, state);
|
|
68
|
+
});
|
|
69
|
+
const getExpectedOrigin = (apiProvider, provider) => {
|
|
70
|
+
if (!(apiProvider === null || apiProvider === void 0 ? void 0 : apiProvider.redirectUrl)) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
let expectedOrigin = window.location.origin;
|
|
74
|
+
if (!providersWithoutWindowOpenerReference.includes(provider)) {
|
|
75
|
+
try {
|
|
76
|
+
const redirectUri = new URL(apiProvider.redirectUrl);
|
|
77
|
+
expectedOrigin = redirectUri.origin;
|
|
78
|
+
}
|
|
79
|
+
catch (e) {
|
|
80
|
+
logger.logger.error('Failed to parse social provider redirect url', {
|
|
81
|
+
error: e,
|
|
82
|
+
});
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return expectedOrigin;
|
|
87
|
+
};
|
|
88
|
+
const handleTelegramCompletionMessage = (message) => {
|
|
89
|
+
logger.logger.debug('Telegram completion message received', {
|
|
90
|
+
data: message,
|
|
91
|
+
});
|
|
92
|
+
resolve('telegram_completed');
|
|
93
|
+
setIsProcessing(false);
|
|
94
|
+
};
|
|
95
|
+
const handleAuthorizationMessage = (message, provider, state) => {
|
|
96
|
+
const { code, error, state: authState } = message;
|
|
97
|
+
if (error && error !== 'undefined') {
|
|
98
|
+
typedReject({
|
|
99
|
+
code: types.SocialOAuthErrorCode.OAUTH_ERROR,
|
|
100
|
+
message: `Failed to connect ${provider} social account: ${error}`,
|
|
101
|
+
});
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
// check that the state we receive from message is the same state we calculated earlier
|
|
105
|
+
// this could be an attack
|
|
106
|
+
// this state check is used only by providers with an open window opener reference (eg, not twitter)
|
|
107
|
+
if (!providersWithoutWindowOpenerReference.includes(provider) &&
|
|
108
|
+
state !== authState) {
|
|
109
|
+
typedReject({
|
|
110
|
+
code: types.SocialOAuthErrorCode.OAUTH_ERROR,
|
|
111
|
+
message: `Failed to connect ${provider} social account: Invalid random state`,
|
|
112
|
+
});
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
if (!code) {
|
|
116
|
+
typedReject({
|
|
117
|
+
code: types.SocialOAuthErrorCode.NO_AUTH_CODE,
|
|
118
|
+
message: `Failed to connect ${provider} social account: no authorization code`,
|
|
119
|
+
});
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
resolve(code);
|
|
123
|
+
setIsProcessing(false);
|
|
124
|
+
};
|
|
125
|
+
if (!providersWaitingOauthMessage[provider]) {
|
|
126
|
+
window.addEventListener('message', handleWindowMessage);
|
|
127
|
+
providersWaitingOauthMessage[provider] = true;
|
|
128
|
+
}
|
|
129
|
+
authWindow === null || authWindow === void 0 ? void 0 : authWindow.location.assign(oauthLoginUrl);
|
|
130
|
+
if (!providersWithoutWindowOpenerReference.includes(provider)) {
|
|
131
|
+
// For provider that support window.opener, we need to clear all states/listeners when the window is closed
|
|
132
|
+
authWindowInterval = setInterval(() => {
|
|
133
|
+
if (!(authWindow === null || authWindow === void 0 ? void 0 : authWindow.closed))
|
|
134
|
+
return;
|
|
135
|
+
clearInterval(authWindowInterval);
|
|
136
|
+
setIsProcessing(false);
|
|
137
|
+
// user didn't complete oauth
|
|
138
|
+
if (providersWaitingOauthMessage[provider])
|
|
139
|
+
typedReject('user-cancelled');
|
|
140
|
+
}, 2000);
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
// For provider that don't support window.opener, we need to use a timeout to pool the oauth result
|
|
144
|
+
// If we don't get a valid result in {async sessionTimeout} ms, we'll assume the user closed the window
|
|
145
|
+
// and we'll clear all states/listeners
|
|
146
|
+
const poolOauthResult = () => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
147
|
+
if (!shouldPool)
|
|
148
|
+
return;
|
|
149
|
+
const result = yield getOAuthResultFromApi();
|
|
150
|
+
if (!shouldPool)
|
|
151
|
+
return;
|
|
152
|
+
if ((result === null || result === void 0 ? void 0 : result.status) !== sdkApiCore.OauthResultStatus.Completed) {
|
|
153
|
+
authWindowInterval = setTimeout(() => {
|
|
154
|
+
poolOauthResult();
|
|
155
|
+
}, 1000);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
shouldPool = false;
|
|
159
|
+
const authMessage = {
|
|
160
|
+
code: result === null || result === void 0 ? void 0 : result.code,
|
|
161
|
+
error: result === null || result === void 0 ? void 0 : result.error,
|
|
162
|
+
provider,
|
|
163
|
+
type: 'authorization_response',
|
|
164
|
+
};
|
|
165
|
+
window.postMessage(authMessage, '*');
|
|
166
|
+
});
|
|
167
|
+
// start pooling oauth result
|
|
168
|
+
shouldPool = true;
|
|
169
|
+
poolOauthResult();
|
|
170
|
+
// if this is mobile, set a longer timeout to allow the user to login to the provider in the browser
|
|
171
|
+
let authWindowTimeout = sessionTimeout;
|
|
172
|
+
if (isMobile) {
|
|
173
|
+
authWindowTimeout = authWindowTimeout * 3;
|
|
174
|
+
}
|
|
175
|
+
authWindowInterval = setTimeout(() => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
176
|
+
shouldPool = false;
|
|
177
|
+
// clear all states/listeners, assuming user closed the window before completing oauth
|
|
178
|
+
if (providersWaitingOauthMessage[provider]) {
|
|
179
|
+
clearListeners();
|
|
180
|
+
typedReject({
|
|
181
|
+
code: types.SocialOAuthErrorCode.OAUTH_WINDOW_TIMEOUT,
|
|
182
|
+
message: `Connecting ${provider} account window timeout.`,
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
setIsProcessing(false);
|
|
186
|
+
onSettled === null || onSettled === void 0 ? void 0 : onSettled();
|
|
187
|
+
}), authWindowTimeout);
|
|
188
|
+
}
|
|
189
|
+
}),
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
exports.createWindowOauth2Service = createWindowOauth2Service;
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import { __awaiter } from '../../../../_virtual/_tslib.js';
|
|
3
|
+
import { SocialOAuthErrorCode } from '@dynamic-labs/types';
|
|
4
|
+
import { OauthResultStatus } from '@dynamic-labs/sdk-api-core';
|
|
5
|
+
import { logger } from '../../../logger/logger.js';
|
|
6
|
+
|
|
7
|
+
const providersWithoutWindowOpenerReference = ['twitter'];
|
|
8
|
+
let authWindowInterval;
|
|
9
|
+
const createWindowOauth2Service = () => ({
|
|
10
|
+
getOauthCode: ({ apiProvider, provider, setIsProcessing, state, oauthLoginUrl, getOAuthResultFromApi, sessionTimeout, isMobile, onSettled, }) => new Promise((resolve, _reject) => {
|
|
11
|
+
// When we catch this error we assume it follows this type, so we must enforce it
|
|
12
|
+
// here to ensure the assumption is correct
|
|
13
|
+
const typedReject = (params) => _reject(params);
|
|
14
|
+
// Clear any potential pending timeouts and intervals
|
|
15
|
+
clearInterval(authWindowInterval);
|
|
16
|
+
const providersWaitingOauthMessage = {};
|
|
17
|
+
let shouldPool = false;
|
|
18
|
+
const authWindow = window.open('', '_blank', 'width=500,height=600');
|
|
19
|
+
const clearListeners = () => {
|
|
20
|
+
window.removeEventListener('message', handleWindowMessage);
|
|
21
|
+
providersWaitingOauthMessage[provider] = false;
|
|
22
|
+
};
|
|
23
|
+
const handleWindowMessage = (event) => __awaiter(void 0, void 0, void 0, function* () {
|
|
24
|
+
const message = event.data;
|
|
25
|
+
const expectedOrigin = getExpectedOrigin(apiProvider, provider);
|
|
26
|
+
if (!expectedOrigin) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
if ((message === null || message === void 0 ? void 0 : message.type) === 'origin_check' && authWindow) {
|
|
30
|
+
logger.debug('Origin check message received. Sending response now.', {
|
|
31
|
+
data: message,
|
|
32
|
+
expectedOrigin,
|
|
33
|
+
});
|
|
34
|
+
authWindow.postMessage('origin_check_response', expectedOrigin);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const isTelegramCompletedMessage = (message === null || message === void 0 ? void 0 : message.type) === 'telegram_completed';
|
|
38
|
+
const isAuthorizationMessage = (message === null || message === void 0 ? void 0 : message.type) === 'authorization_response';
|
|
39
|
+
if (isAuthorizationMessage || isTelegramCompletedMessage) {
|
|
40
|
+
logger.debug('Message received', { data: message });
|
|
41
|
+
}
|
|
42
|
+
const isExpectedOrigin = event.origin === expectedOrigin;
|
|
43
|
+
const isValidMessage = ((isAuthorizationMessage && (message === null || message === void 0 ? void 0 : message.provider) === provider) ||
|
|
44
|
+
isTelegramCompletedMessage) &&
|
|
45
|
+
isExpectedOrigin;
|
|
46
|
+
// don't process invalid messages for provider
|
|
47
|
+
if (!isValidMessage) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
setIsProcessing(true);
|
|
51
|
+
if (!providersWaitingOauthMessage[provider]) {
|
|
52
|
+
typedReject({
|
|
53
|
+
code: SocialOAuthErrorCode.SESSION_TIMEOUT,
|
|
54
|
+
message: `Connecting ${provider} account session timeout.`,
|
|
55
|
+
});
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
clearListeners();
|
|
59
|
+
if (isTelegramCompletedMessage) {
|
|
60
|
+
handleTelegramCompletionMessage(message);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
handleAuthorizationMessage(message, provider, state);
|
|
64
|
+
});
|
|
65
|
+
const getExpectedOrigin = (apiProvider, provider) => {
|
|
66
|
+
if (!(apiProvider === null || apiProvider === void 0 ? void 0 : apiProvider.redirectUrl)) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
let expectedOrigin = window.location.origin;
|
|
70
|
+
if (!providersWithoutWindowOpenerReference.includes(provider)) {
|
|
71
|
+
try {
|
|
72
|
+
const redirectUri = new URL(apiProvider.redirectUrl);
|
|
73
|
+
expectedOrigin = redirectUri.origin;
|
|
74
|
+
}
|
|
75
|
+
catch (e) {
|
|
76
|
+
logger.error('Failed to parse social provider redirect url', {
|
|
77
|
+
error: e,
|
|
78
|
+
});
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return expectedOrigin;
|
|
83
|
+
};
|
|
84
|
+
const handleTelegramCompletionMessage = (message) => {
|
|
85
|
+
logger.debug('Telegram completion message received', {
|
|
86
|
+
data: message,
|
|
87
|
+
});
|
|
88
|
+
resolve('telegram_completed');
|
|
89
|
+
setIsProcessing(false);
|
|
90
|
+
};
|
|
91
|
+
const handleAuthorizationMessage = (message, provider, state) => {
|
|
92
|
+
const { code, error, state: authState } = message;
|
|
93
|
+
if (error && error !== 'undefined') {
|
|
94
|
+
typedReject({
|
|
95
|
+
code: SocialOAuthErrorCode.OAUTH_ERROR,
|
|
96
|
+
message: `Failed to connect ${provider} social account: ${error}`,
|
|
97
|
+
});
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
// check that the state we receive from message is the same state we calculated earlier
|
|
101
|
+
// this could be an attack
|
|
102
|
+
// this state check is used only by providers with an open window opener reference (eg, not twitter)
|
|
103
|
+
if (!providersWithoutWindowOpenerReference.includes(provider) &&
|
|
104
|
+
state !== authState) {
|
|
105
|
+
typedReject({
|
|
106
|
+
code: SocialOAuthErrorCode.OAUTH_ERROR,
|
|
107
|
+
message: `Failed to connect ${provider} social account: Invalid random state`,
|
|
108
|
+
});
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (!code) {
|
|
112
|
+
typedReject({
|
|
113
|
+
code: SocialOAuthErrorCode.NO_AUTH_CODE,
|
|
114
|
+
message: `Failed to connect ${provider} social account: no authorization code`,
|
|
115
|
+
});
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
resolve(code);
|
|
119
|
+
setIsProcessing(false);
|
|
120
|
+
};
|
|
121
|
+
if (!providersWaitingOauthMessage[provider]) {
|
|
122
|
+
window.addEventListener('message', handleWindowMessage);
|
|
123
|
+
providersWaitingOauthMessage[provider] = true;
|
|
124
|
+
}
|
|
125
|
+
authWindow === null || authWindow === void 0 ? void 0 : authWindow.location.assign(oauthLoginUrl);
|
|
126
|
+
if (!providersWithoutWindowOpenerReference.includes(provider)) {
|
|
127
|
+
// For provider that support window.opener, we need to clear all states/listeners when the window is closed
|
|
128
|
+
authWindowInterval = setInterval(() => {
|
|
129
|
+
if (!(authWindow === null || authWindow === void 0 ? void 0 : authWindow.closed))
|
|
130
|
+
return;
|
|
131
|
+
clearInterval(authWindowInterval);
|
|
132
|
+
setIsProcessing(false);
|
|
133
|
+
// user didn't complete oauth
|
|
134
|
+
if (providersWaitingOauthMessage[provider])
|
|
135
|
+
typedReject('user-cancelled');
|
|
136
|
+
}, 2000);
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
// For provider that don't support window.opener, we need to use a timeout to pool the oauth result
|
|
140
|
+
// If we don't get a valid result in {async sessionTimeout} ms, we'll assume the user closed the window
|
|
141
|
+
// and we'll clear all states/listeners
|
|
142
|
+
const poolOauthResult = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
143
|
+
if (!shouldPool)
|
|
144
|
+
return;
|
|
145
|
+
const result = yield getOAuthResultFromApi();
|
|
146
|
+
if (!shouldPool)
|
|
147
|
+
return;
|
|
148
|
+
if ((result === null || result === void 0 ? void 0 : result.status) !== OauthResultStatus.Completed) {
|
|
149
|
+
authWindowInterval = setTimeout(() => {
|
|
150
|
+
poolOauthResult();
|
|
151
|
+
}, 1000);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
shouldPool = false;
|
|
155
|
+
const authMessage = {
|
|
156
|
+
code: result === null || result === void 0 ? void 0 : result.code,
|
|
157
|
+
error: result === null || result === void 0 ? void 0 : result.error,
|
|
158
|
+
provider,
|
|
159
|
+
type: 'authorization_response',
|
|
160
|
+
};
|
|
161
|
+
window.postMessage(authMessage, '*');
|
|
162
|
+
});
|
|
163
|
+
// start pooling oauth result
|
|
164
|
+
shouldPool = true;
|
|
165
|
+
poolOauthResult();
|
|
166
|
+
// if this is mobile, set a longer timeout to allow the user to login to the provider in the browser
|
|
167
|
+
let authWindowTimeout = sessionTimeout;
|
|
168
|
+
if (isMobile) {
|
|
169
|
+
authWindowTimeout = authWindowTimeout * 3;
|
|
170
|
+
}
|
|
171
|
+
authWindowInterval = setTimeout(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
172
|
+
shouldPool = false;
|
|
173
|
+
// clear all states/listeners, assuming user closed the window before completing oauth
|
|
174
|
+
if (providersWaitingOauthMessage[provider]) {
|
|
175
|
+
clearListeners();
|
|
176
|
+
typedReject({
|
|
177
|
+
code: SocialOAuthErrorCode.OAUTH_WINDOW_TIMEOUT,
|
|
178
|
+
message: `Connecting ${provider} account window timeout.`,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
setIsProcessing(false);
|
|
182
|
+
onSettled === null || onSettled === void 0 ? void 0 : onSettled();
|
|
183
|
+
}), authWindowTimeout);
|
|
184
|
+
}
|
|
185
|
+
}),
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
export { createWindowOauth2Service };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './createWindowOauth2Service';
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
5
|
+
|
|
6
|
+
var _tslib = require('../../../_virtual/_tslib.cjs');
|
|
7
|
+
var createBrowserPlatformService = require('./createBrowserPlatformService/createBrowserPlatformService.cjs');
|
|
8
|
+
|
|
9
|
+
var _a, _PlatformService_implementation;
|
|
10
|
+
class PlatformService {
|
|
11
|
+
static get implementation() {
|
|
12
|
+
if (!_tslib.__classPrivateFieldGet(_a, _a, "f", _PlatformService_implementation)) {
|
|
13
|
+
return createBrowserPlatformService.createBrowserPlatformService(window);
|
|
14
|
+
}
|
|
15
|
+
return _tslib.__classPrivateFieldGet(_a, _a, "f", _PlatformService_implementation);
|
|
16
|
+
}
|
|
17
|
+
static set implementation(implementation) {
|
|
18
|
+
_tslib.__classPrivateFieldSet(_a, _a, implementation, "f", _PlatformService_implementation);
|
|
19
|
+
}
|
|
20
|
+
static get getOrigin() {
|
|
21
|
+
return _a.implementation.getOrigin;
|
|
22
|
+
}
|
|
23
|
+
static get getHost() {
|
|
24
|
+
return _a.implementation.getHost;
|
|
25
|
+
}
|
|
26
|
+
static get getHostname() {
|
|
27
|
+
return _a.implementation.getHostname;
|
|
28
|
+
}
|
|
29
|
+
static get getTLD() {
|
|
30
|
+
return _a.implementation.getTLD;
|
|
31
|
+
}
|
|
32
|
+
// Deeplink handling
|
|
33
|
+
static get openURL() {
|
|
34
|
+
return _a.implementation.openURL;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
_a = PlatformService;
|
|
38
|
+
_PlatformService_implementation = { value: void 0 };
|
|
39
|
+
|
|
40
|
+
exports.PlatformService = PlatformService;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { IPlatformService } from './types';
|
|
2
|
+
export declare class PlatformService {
|
|
3
|
+
#private;
|
|
4
|
+
static get implementation(): IPlatformService;
|
|
5
|
+
static set implementation(implementation: IPlatformService);
|
|
6
|
+
static get getOrigin(): () => string;
|
|
7
|
+
static get getHost(): () => string;
|
|
8
|
+
static get getHostname(): () => string;
|
|
9
|
+
static get getTLD(): () => string | undefined;
|
|
10
|
+
static get openURL(): (url: string) => Promise<void>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import { __classPrivateFieldGet, __classPrivateFieldSet } from '../../../_virtual/_tslib.js';
|
|
3
|
+
import { createBrowserPlatformService } from './createBrowserPlatformService/createBrowserPlatformService.js';
|
|
4
|
+
|
|
5
|
+
var _a, _PlatformService_implementation;
|
|
6
|
+
class PlatformService {
|
|
7
|
+
static get implementation() {
|
|
8
|
+
if (!__classPrivateFieldGet(_a, _a, "f", _PlatformService_implementation)) {
|
|
9
|
+
return createBrowserPlatformService(window);
|
|
10
|
+
}
|
|
11
|
+
return __classPrivateFieldGet(_a, _a, "f", _PlatformService_implementation);
|
|
12
|
+
}
|
|
13
|
+
static set implementation(implementation) {
|
|
14
|
+
__classPrivateFieldSet(_a, _a, implementation, "f", _PlatformService_implementation);
|
|
15
|
+
}
|
|
16
|
+
static get getOrigin() {
|
|
17
|
+
return _a.implementation.getOrigin;
|
|
18
|
+
}
|
|
19
|
+
static get getHost() {
|
|
20
|
+
return _a.implementation.getHost;
|
|
21
|
+
}
|
|
22
|
+
static get getHostname() {
|
|
23
|
+
return _a.implementation.getHostname;
|
|
24
|
+
}
|
|
25
|
+
static get getTLD() {
|
|
26
|
+
return _a.implementation.getTLD;
|
|
27
|
+
}
|
|
28
|
+
// Deeplink handling
|
|
29
|
+
static get openURL() {
|
|
30
|
+
return _a.implementation.openURL;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
_a = PlatformService;
|
|
34
|
+
_PlatformService_implementation = { value: void 0 };
|
|
35
|
+
|
|
36
|
+
export { PlatformService };
|
package/src/services/PlatformService/createBrowserPlatformService/createBrowserPlatformService.cjs
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
5
|
+
|
|
6
|
+
var _tslib = require('../../../../_virtual/_tslib.cjs');
|
|
7
|
+
var tldts = require('tldts');
|
|
8
|
+
|
|
9
|
+
const createBrowserPlatformService = (window) => ({
|
|
10
|
+
getHost: () => window.location.host,
|
|
11
|
+
getHostname: () => window.location.hostname,
|
|
12
|
+
getOrigin: () => window.location.origin,
|
|
13
|
+
getTLD: () => {
|
|
14
|
+
// Passing the allowPrivateDomains option prevents returning the actual TLD
|
|
15
|
+
// for domains that have delegated subdomains like herokuapp.com or s3.amazonaws.com
|
|
16
|
+
// full list is contained here https://publicsuffix.org/list/effective_tld_names.dat
|
|
17
|
+
// separated by ICANN DOMAINS and PRIVATE DOMAINS
|
|
18
|
+
// so for instance parse('someapp.herokuapp.com') will return 'someapp.herokuapp.com' as the domain
|
|
19
|
+
// whereas parse('app.dynamic.xyz') will return 'dynamic.xyz'
|
|
20
|
+
const data = tldts.parse(window.location.hostname, {
|
|
21
|
+
allowPrivateDomains: true,
|
|
22
|
+
});
|
|
23
|
+
return data.domain || undefined;
|
|
24
|
+
},
|
|
25
|
+
openURL: (url) => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
26
|
+
window.location.assign(url);
|
|
27
|
+
}),
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
exports.createBrowserPlatformService = createBrowserPlatformService;
|
package/src/services/PlatformService/createBrowserPlatformService/createBrowserPlatformService.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import { __awaiter } from '../../../../_virtual/_tslib.js';
|
|
3
|
+
import { parse } from 'tldts';
|
|
4
|
+
|
|
5
|
+
const createBrowserPlatformService = (window) => ({
|
|
6
|
+
getHost: () => window.location.host,
|
|
7
|
+
getHostname: () => window.location.hostname,
|
|
8
|
+
getOrigin: () => window.location.origin,
|
|
9
|
+
getTLD: () => {
|
|
10
|
+
// Passing the allowPrivateDomains option prevents returning the actual TLD
|
|
11
|
+
// for domains that have delegated subdomains like herokuapp.com or s3.amazonaws.com
|
|
12
|
+
// full list is contained here https://publicsuffix.org/list/effective_tld_names.dat
|
|
13
|
+
// separated by ICANN DOMAINS and PRIVATE DOMAINS
|
|
14
|
+
// so for instance parse('someapp.herokuapp.com') will return 'someapp.herokuapp.com' as the domain
|
|
15
|
+
// whereas parse('app.dynamic.xyz') will return 'dynamic.xyz'
|
|
16
|
+
const data = parse(window.location.hostname, {
|
|
17
|
+
allowPrivateDomains: true,
|
|
18
|
+
});
|
|
19
|
+
return data.domain || undefined;
|
|
20
|
+
},
|
|
21
|
+
openURL: (url) => __awaiter(void 0, void 0, void 0, function* () {
|
|
22
|
+
window.location.assign(url);
|
|
23
|
+
}),
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
export { createBrowserPlatformService };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createBrowserPlatformService } from './createBrowserPlatformService';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface IPlatformService {
|
|
2
|
+
/**
|
|
3
|
+
* Gets the hostname of the current location.
|
|
4
|
+
*
|
|
5
|
+
* @example window.location.hostname
|
|
6
|
+
*/
|
|
7
|
+
getHostname(): string;
|
|
8
|
+
/**
|
|
9
|
+
* Gets the host of the current location.
|
|
10
|
+
*
|
|
11
|
+
* @example window.location.host
|
|
12
|
+
*/
|
|
13
|
+
getHost(): string;
|
|
14
|
+
/**
|
|
15
|
+
* Gets the origin of the current location.
|
|
16
|
+
*
|
|
17
|
+
* @example window.location.origin
|
|
18
|
+
*/
|
|
19
|
+
getOrigin(): string;
|
|
20
|
+
getTLD(): string | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* Opens a URL. If possible, should avoid new windows.
|
|
23
|
+
*/
|
|
24
|
+
openURL(url: string): Promise<void>;
|
|
25
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { sleep } from './sleep';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
5
|
+
|
|
6
|
+
// eslint-disable-next-line prefer-arrow/prefer-arrow-functions
|
|
7
|
+
function sleep(timeoutMs, valueToResolve) {
|
|
8
|
+
return new Promise((resolve) => {
|
|
9
|
+
setTimeout(() => resolve(valueToResolve), timeoutMs);
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
exports.sleep = sleep;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Delays the execution of subsequent code by a specified amount of time.
|
|
3
|
+
* If a value is provided, the promise will resolve with that value after the timeout.
|
|
4
|
+
*
|
|
5
|
+
* @template T - The type of the value to resolve with.
|
|
6
|
+
* @param {number} timeoutMs - The number of milliseconds to delay.
|
|
7
|
+
* @param {T} [valueToResolve] - Optional value to resolve the promise with after the timeout.
|
|
8
|
+
* @returns {Promise<T | void>} - Resolves after the specified timeout with valueToResolve or void.
|
|
9
|
+
*/
|
|
10
|
+
export declare function sleep(timeoutMs: number): Promise<void>;
|
|
11
|
+
export declare function sleep<T>(timeoutMs: number, valueToResolve: T): Promise<T>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { template } from './template';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Creates a template function that replaces placeholders with corresponding values from a data object.
|
|
8
|
+
* @param {string} templateText - The template string containing placeholders in the form {{placeholder}}.
|
|
9
|
+
* @returns {(data) => string} - A function that replaces the placeholders with the values from the data object.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* // Basic usage
|
|
13
|
+
* const compiled = template('Test text {{placeholder}} value');
|
|
14
|
+
* console.log(compiled({ placeholder: 'test' })); // Output: 'Test text test value'
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* // Multiple placeholders
|
|
18
|
+
* const compiled = template('Test text {{placeholder}} value {{placeholder2}}');
|
|
19
|
+
* console.log(compiled({ placeholder: 'test', placeholder2: 'test2' })); // Output: 'Test text test value test2'
|
|
20
|
+
*/
|
|
21
|
+
const template = (templateText) => {
|
|
22
|
+
return (data) => templateText.replace(/{{(\w+?)}}/g, (match, key) => key in data ? data[key] : match);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
exports.template = template;
|