@scalemule/nextjs 0.0.28 → 0.0.30
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/dist/client.d.mts +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/{index-DewTyMF2.d.mts → index-BoENfro3.d.mts} +1 -1
- package/dist/{index-DewTyMF2.d.ts → index-BoENfro3.d.ts} +1 -1
- package/dist/index.d.mts +57 -3
- package/dist/index.d.ts +57 -3
- package/dist/index.js +262 -0
- package/dist/index.mjs +261 -1
- package/dist/server/index.d.mts +46 -9
- package/dist/server/index.d.ts +46 -9
- package/dist/server/index.js +137 -1
- package/dist/server/index.mjs +137 -2
- package/dist/server/webhook-handler.d.mts +2 -2
- package/dist/server/webhook-handler.d.ts +2 -2
- package/dist/testing.d.mts +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/{webhook-handler-CQ2lZgy0.d.ts → webhook-handler-CjSSCdvI.d.ts} +2 -2
- package/dist/{webhook-handler-DS0r_w4M.d.mts → webhook-handler-Cz9jtet2.d.mts} +2 -2
- package/package.json +2 -2
package/dist/client.d.mts
CHANGED
package/dist/client.d.ts
CHANGED
|
@@ -842,4 +842,4 @@ interface UseBillingReturn {
|
|
|
842
842
|
}) => Promise<string | null>;
|
|
843
843
|
}
|
|
844
844
|
|
|
845
|
-
export { type
|
|
845
|
+
export { type ResetPasswordRequest as $, type ApiError as A, type BatchTrackRequest as B, type ChangeEmailRequest as C, type DeviceFingerprint as D, type EnhancedAnalyticsEvent as E, type ForgotPasswordRequest as F, type MFASetupRequest as G, type MFAStatus as H, type MFATOTPSetupResponse as I, type MFAVerifyRequest as J, type OAuthCallbackResponse as K, type LoginResponse as L, type MFAChallengeResponse as M, type OAuthConfig as N, type OAuthCallbackRequest as O, type OAuthProvider as P, type OAuthStartResponse as Q, type PageViewData as R, type ScaleMuleConfig as S, type PayoutSchedule as T, type User as U, type PhoneLoginRequest as V, type PhoneSendCodeRequest as W, type PhoneVerifyRequest as X, type Profile as Y, type RefreshResponse as Z, type RegisterRequest as _, type UseAuthReturn as a, ScaleMuleApiError as a0, type ScaleMuleEnvironment as a1, type Session as a2, type SignedUploadCompleteRequest as a3, type SignedUploadRequest as a4, type SignedUploadResponse as a5, type SignedUploadUrl as a6, type StorageAdapter as a7, type StorageFile as a8, type TrackEventResponse as a9, type TransactionSummary as aa, type UTMParams as ab, type UpdateProfileRequest as ac, type UploadOptions as ad, type UploadResponse as ae, type VerifyEmailRequest as af, type UseBillingReturn as b, type ListFilesParams as c, type UseContentReturn as d, type UseUserReturn as e, type UseAnalyticsOptions as f, type UseAnalyticsReturn as g, type AccountBalance as h, type AnalyticsEvent as i, type ApiResponse as j, type BillingPayment as k, type BillingPayout as l, type BillingRefund as m, type BillingTransaction as n, type ChangePasswordRequest as o, type ClientContext as p, type ConnectedAccount as q, type DeviceInfo as r, type LinkedAccount as s, type ListFilesResponse as t, type LoginDeviceInfo as u, type LoginRequest as v, type LoginResponseWithMFA as w, type LoginRiskInfo as x, type MFAMethod as y, type MFASMSSetupResponse as z };
|
|
@@ -842,4 +842,4 @@ interface UseBillingReturn {
|
|
|
842
842
|
}) => Promise<string | null>;
|
|
843
843
|
}
|
|
844
844
|
|
|
845
|
-
export { type
|
|
845
|
+
export { type ResetPasswordRequest as $, type ApiError as A, type BatchTrackRequest as B, type ChangeEmailRequest as C, type DeviceFingerprint as D, type EnhancedAnalyticsEvent as E, type ForgotPasswordRequest as F, type MFASetupRequest as G, type MFAStatus as H, type MFATOTPSetupResponse as I, type MFAVerifyRequest as J, type OAuthCallbackResponse as K, type LoginResponse as L, type MFAChallengeResponse as M, type OAuthConfig as N, type OAuthCallbackRequest as O, type OAuthProvider as P, type OAuthStartResponse as Q, type PageViewData as R, type ScaleMuleConfig as S, type PayoutSchedule as T, type User as U, type PhoneLoginRequest as V, type PhoneSendCodeRequest as W, type PhoneVerifyRequest as X, type Profile as Y, type RefreshResponse as Z, type RegisterRequest as _, type UseAuthReturn as a, ScaleMuleApiError as a0, type ScaleMuleEnvironment as a1, type Session as a2, type SignedUploadCompleteRequest as a3, type SignedUploadRequest as a4, type SignedUploadResponse as a5, type SignedUploadUrl as a6, type StorageAdapter as a7, type StorageFile as a8, type TrackEventResponse as a9, type TransactionSummary as aa, type UTMParams as ab, type UpdateProfileRequest as ac, type UploadOptions as ad, type UploadResponse as ae, type VerifyEmailRequest as af, type UseBillingReturn as b, type ListFilesParams as c, type UseContentReturn as d, type UseUserReturn as e, type UseAnalyticsOptions as f, type UseAnalyticsReturn as g, type AccountBalance as h, type AnalyticsEvent as i, type ApiResponse as j, type BillingPayment as k, type BillingPayout as l, type BillingRefund as m, type BillingTransaction as n, type ChangePasswordRequest as o, type ClientContext as p, type ConnectedAccount as q, type DeviceInfo as r, type LinkedAccount as s, type ListFilesResponse as t, type LoginDeviceInfo as u, type LoginRequest as v, type LoginResponseWithMFA as w, type LoginRiskInfo as x, type MFAMethod as y, type MFASMSSetupResponse as z };
|
package/dist/index.d.mts
CHANGED
|
@@ -2,8 +2,8 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
import { ScaleMuleClient } from './client.mjs';
|
|
4
4
|
export { ClientConfig, RequestOptions, createClient } from './client.mjs';
|
|
5
|
-
import { S as ScaleMuleConfig, U as User, L as LoginResponse, A as ApiError, a as UseAuthReturn, b as UseBillingReturn, c as ListFilesParams, d as UseContentReturn, e as UseUserReturn, f as UseAnalyticsOptions, g as UseAnalyticsReturn } from './index-
|
|
6
|
-
export {
|
|
5
|
+
import { S as ScaleMuleConfig, U as User, L as LoginResponse, A as ApiError, a as UseAuthReturn, b as UseBillingReturn, c as ListFilesParams, d as UseContentReturn, e as UseUserReturn, f as UseAnalyticsOptions, g as UseAnalyticsReturn } from './index-BoENfro3.mjs';
|
|
6
|
+
export { h as AccountBalance, i as AnalyticsEvent, j as ApiResponse, B as BatchTrackRequest, k as BillingPayment, l as BillingPayout, m as BillingRefund, n as BillingTransaction, C as ChangeEmailRequest, o as ChangePasswordRequest, p as ClientContext, q as ConnectedAccount, D as DeviceFingerprint, r as DeviceInfo, E as EnhancedAnalyticsEvent, F as ForgotPasswordRequest, s as LinkedAccount, t as ListFilesResponse, u as LoginDeviceInfo, v as LoginRequest, w as LoginResponseWithMFA, x as LoginRiskInfo, M as MFAChallengeResponse, y as MFAMethod, z as MFASMSSetupResponse, G as MFASetupRequest, H as MFAStatus, I as MFATOTPSetupResponse, J as MFAVerifyRequest, O as OAuthCallbackRequest, K as OAuthCallbackResponse, N as OAuthConfig, P as OAuthProvider, Q as OAuthStartResponse, R as PageViewData, T as PayoutSchedule, V as PhoneLoginRequest, W as PhoneSendCodeRequest, X as PhoneVerifyRequest, Y as Profile, Z as RefreshResponse, _ as RegisterRequest, $ as ResetPasswordRequest, a0 as ScaleMuleApiError, a1 as ScaleMuleEnvironment, a2 as Session, a3 as SignedUploadCompleteRequest, a4 as SignedUploadRequest, a5 as SignedUploadResponse, a6 as SignedUploadUrl, a7 as StorageAdapter, a8 as StorageFile, a9 as TrackEventResponse, aa as TransactionSummary, ab as UTMParams, ac as UpdateProfileRequest, ad as UploadOptions, ae as UploadResponse, af as VerifyEmailRequest } from './index-BoENfro3.mjs';
|
|
7
7
|
|
|
8
8
|
interface ScaleMuleContextValue {
|
|
9
9
|
/** The API client instance */
|
|
@@ -289,6 +289,60 @@ interface UseFeatureFlagsReturn {
|
|
|
289
289
|
}
|
|
290
290
|
declare function useFeatureFlags(options?: UseFeatureFlagsOptions): UseFeatureFlagsReturn;
|
|
291
291
|
|
|
292
|
+
interface UsePushNotificationsOptions {
|
|
293
|
+
/** Service worker URL (default: '/sw.js') */
|
|
294
|
+
serviceWorkerUrl?: string;
|
|
295
|
+
/** Push proxy URL (default: '/api/push') */
|
|
296
|
+
pushProxyUrl?: string;
|
|
297
|
+
/** Called when a push notification is received while app is in foreground */
|
|
298
|
+
onNotification?: (data: unknown) => void;
|
|
299
|
+
}
|
|
300
|
+
interface UsePushNotificationsReturn {
|
|
301
|
+
/** Whether the browser supports Web Push */
|
|
302
|
+
isSupported: boolean;
|
|
303
|
+
/** Current notification permission state */
|
|
304
|
+
permission: NotificationPermission | 'unsupported';
|
|
305
|
+
/** Whether push is currently subscribed */
|
|
306
|
+
isSubscribed: boolean;
|
|
307
|
+
/** Whether an operation is in progress */
|
|
308
|
+
isLoading: boolean;
|
|
309
|
+
/** Last error */
|
|
310
|
+
error: ApiError | null;
|
|
311
|
+
/** Request permission and subscribe to push notifications */
|
|
312
|
+
subscribe: () => Promise<void>;
|
|
313
|
+
/** Unsubscribe from push notifications */
|
|
314
|
+
unsubscribe: () => Promise<void>;
|
|
315
|
+
/** Clear user association (call before logout) */
|
|
316
|
+
disassociateUser: () => Promise<void>;
|
|
317
|
+
/** The push token ID from backend registration */
|
|
318
|
+
tokenId: string | null;
|
|
319
|
+
}
|
|
320
|
+
declare function usePushNotifications(options?: UsePushNotificationsOptions): UsePushNotificationsReturn;
|
|
321
|
+
|
|
322
|
+
interface UseShareOptions {
|
|
323
|
+
/** The canonical URL to share. Defaults to current page URL.
|
|
324
|
+
* IMPORTANT: Pass the content's canonical URL, not window.location.href,
|
|
325
|
+
* to avoid re-sharing someone else's referral code. */
|
|
326
|
+
url?: string;
|
|
327
|
+
/** Manual referral code override (skips fetch) */
|
|
328
|
+
referralCode?: string;
|
|
329
|
+
/** Auto-fetch referral code from /v1/referrals/me when authenticated */
|
|
330
|
+
autoFetchReferral?: boolean;
|
|
331
|
+
}
|
|
332
|
+
interface UseShareReturn {
|
|
333
|
+
/** Share URL — absolute, with ?rc= appended if referral code available */
|
|
334
|
+
shareUrl: string;
|
|
335
|
+
/** User's referral code, or null if unauthenticated/not fetched */
|
|
336
|
+
referralCode: string | null;
|
|
337
|
+
/** Copy shareUrl to clipboard. Returns true on success. */
|
|
338
|
+
copyLink: () => Promise<boolean>;
|
|
339
|
+
/** Whether link was recently copied (auto-resets after 2s) */
|
|
340
|
+
copied: boolean;
|
|
341
|
+
/** Loading state for referral code fetch */
|
|
342
|
+
loading: boolean;
|
|
343
|
+
}
|
|
344
|
+
declare function useShare(options?: UseShareOptions): UseShareReturn;
|
|
345
|
+
|
|
292
346
|
/**
|
|
293
347
|
* Client-side validation helpers
|
|
294
348
|
*
|
|
@@ -447,4 +501,4 @@ declare function createSafeLogger(prefix: string): {
|
|
|
447
501
|
error: (message: string, data?: unknown) => void;
|
|
448
502
|
};
|
|
449
503
|
|
|
450
|
-
export { ApiError, type FeatureFlagEvaluation, type FeatureFlagEvaluation as FeatureFlagResult, ListFilesParams, LoginResponse, type PasswordValidationResult, type PhoneCountry, type PhoneValidationResult, type RealtimeEvent, type RealtimeMessage, type RealtimeStatus, ScaleMuleClient, ScaleMuleConfig, ScaleMuleProvider, type ScaleMuleProviderProps, UseAnalyticsOptions, UseAnalyticsReturn, UseAuthReturn, UseBillingReturn, UseContentReturn, type UseFeatureFlagsOptions, type UseFeatureFlagsReturn, type UseFeatureFlagsOptions as UseFlagsOptions, type UseFeatureFlagsReturn as UseFlagsReturn, type UseRealtimeOptions, type UseRealtimeReturn, UseUserReturn, User, type UsernameValidationResult, composePhone, createSafeLogger, normalizePhone, phoneCountries, sanitizeForLog, useAnalytics, useAuth, useBilling, useContent, useFeatureFlags, useRealtime, useScaleMule, useScaleMuleClient, useUser, validateForm, validators };
|
|
504
|
+
export { ApiError, type FeatureFlagEvaluation, type FeatureFlagEvaluation as FeatureFlagResult, ListFilesParams, LoginResponse, type PasswordValidationResult, type PhoneCountry, type PhoneValidationResult, type RealtimeEvent, type RealtimeMessage, type RealtimeStatus, ScaleMuleClient, ScaleMuleConfig, ScaleMuleProvider, type ScaleMuleProviderProps, UseAnalyticsOptions, UseAnalyticsReturn, UseAuthReturn, UseBillingReturn, UseContentReturn, type UseFeatureFlagsOptions, type UseFeatureFlagsReturn, type UseFeatureFlagsOptions as UseFlagsOptions, type UseFeatureFlagsReturn as UseFlagsReturn, type UsePushNotificationsOptions, type UsePushNotificationsReturn, type UseRealtimeOptions, type UseRealtimeReturn, type UseShareOptions, type UseShareReturn, UseUserReturn, User, type UsernameValidationResult, composePhone, createSafeLogger, normalizePhone, phoneCountries, sanitizeForLog, useAnalytics, useAuth, useBilling, useContent, useFeatureFlags, usePushNotifications, useRealtime, useScaleMule, useScaleMuleClient, useShare, useUser, validateForm, validators };
|
package/dist/index.d.ts
CHANGED
|
@@ -2,8 +2,8 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
import { ScaleMuleClient } from './client.js';
|
|
4
4
|
export { ClientConfig, RequestOptions, createClient } from './client.js';
|
|
5
|
-
import { S as ScaleMuleConfig, U as User, L as LoginResponse, A as ApiError, a as UseAuthReturn, b as UseBillingReturn, c as ListFilesParams, d as UseContentReturn, e as UseUserReturn, f as UseAnalyticsOptions, g as UseAnalyticsReturn } from './index-
|
|
6
|
-
export {
|
|
5
|
+
import { S as ScaleMuleConfig, U as User, L as LoginResponse, A as ApiError, a as UseAuthReturn, b as UseBillingReturn, c as ListFilesParams, d as UseContentReturn, e as UseUserReturn, f as UseAnalyticsOptions, g as UseAnalyticsReturn } from './index-BoENfro3.js';
|
|
6
|
+
export { h as AccountBalance, i as AnalyticsEvent, j as ApiResponse, B as BatchTrackRequest, k as BillingPayment, l as BillingPayout, m as BillingRefund, n as BillingTransaction, C as ChangeEmailRequest, o as ChangePasswordRequest, p as ClientContext, q as ConnectedAccount, D as DeviceFingerprint, r as DeviceInfo, E as EnhancedAnalyticsEvent, F as ForgotPasswordRequest, s as LinkedAccount, t as ListFilesResponse, u as LoginDeviceInfo, v as LoginRequest, w as LoginResponseWithMFA, x as LoginRiskInfo, M as MFAChallengeResponse, y as MFAMethod, z as MFASMSSetupResponse, G as MFASetupRequest, H as MFAStatus, I as MFATOTPSetupResponse, J as MFAVerifyRequest, O as OAuthCallbackRequest, K as OAuthCallbackResponse, N as OAuthConfig, P as OAuthProvider, Q as OAuthStartResponse, R as PageViewData, T as PayoutSchedule, V as PhoneLoginRequest, W as PhoneSendCodeRequest, X as PhoneVerifyRequest, Y as Profile, Z as RefreshResponse, _ as RegisterRequest, $ as ResetPasswordRequest, a0 as ScaleMuleApiError, a1 as ScaleMuleEnvironment, a2 as Session, a3 as SignedUploadCompleteRequest, a4 as SignedUploadRequest, a5 as SignedUploadResponse, a6 as SignedUploadUrl, a7 as StorageAdapter, a8 as StorageFile, a9 as TrackEventResponse, aa as TransactionSummary, ab as UTMParams, ac as UpdateProfileRequest, ad as UploadOptions, ae as UploadResponse, af as VerifyEmailRequest } from './index-BoENfro3.js';
|
|
7
7
|
|
|
8
8
|
interface ScaleMuleContextValue {
|
|
9
9
|
/** The API client instance */
|
|
@@ -289,6 +289,60 @@ interface UseFeatureFlagsReturn {
|
|
|
289
289
|
}
|
|
290
290
|
declare function useFeatureFlags(options?: UseFeatureFlagsOptions): UseFeatureFlagsReturn;
|
|
291
291
|
|
|
292
|
+
interface UsePushNotificationsOptions {
|
|
293
|
+
/** Service worker URL (default: '/sw.js') */
|
|
294
|
+
serviceWorkerUrl?: string;
|
|
295
|
+
/** Push proxy URL (default: '/api/push') */
|
|
296
|
+
pushProxyUrl?: string;
|
|
297
|
+
/** Called when a push notification is received while app is in foreground */
|
|
298
|
+
onNotification?: (data: unknown) => void;
|
|
299
|
+
}
|
|
300
|
+
interface UsePushNotificationsReturn {
|
|
301
|
+
/** Whether the browser supports Web Push */
|
|
302
|
+
isSupported: boolean;
|
|
303
|
+
/** Current notification permission state */
|
|
304
|
+
permission: NotificationPermission | 'unsupported';
|
|
305
|
+
/** Whether push is currently subscribed */
|
|
306
|
+
isSubscribed: boolean;
|
|
307
|
+
/** Whether an operation is in progress */
|
|
308
|
+
isLoading: boolean;
|
|
309
|
+
/** Last error */
|
|
310
|
+
error: ApiError | null;
|
|
311
|
+
/** Request permission and subscribe to push notifications */
|
|
312
|
+
subscribe: () => Promise<void>;
|
|
313
|
+
/** Unsubscribe from push notifications */
|
|
314
|
+
unsubscribe: () => Promise<void>;
|
|
315
|
+
/** Clear user association (call before logout) */
|
|
316
|
+
disassociateUser: () => Promise<void>;
|
|
317
|
+
/** The push token ID from backend registration */
|
|
318
|
+
tokenId: string | null;
|
|
319
|
+
}
|
|
320
|
+
declare function usePushNotifications(options?: UsePushNotificationsOptions): UsePushNotificationsReturn;
|
|
321
|
+
|
|
322
|
+
interface UseShareOptions {
|
|
323
|
+
/** The canonical URL to share. Defaults to current page URL.
|
|
324
|
+
* IMPORTANT: Pass the content's canonical URL, not window.location.href,
|
|
325
|
+
* to avoid re-sharing someone else's referral code. */
|
|
326
|
+
url?: string;
|
|
327
|
+
/** Manual referral code override (skips fetch) */
|
|
328
|
+
referralCode?: string;
|
|
329
|
+
/** Auto-fetch referral code from /v1/referrals/me when authenticated */
|
|
330
|
+
autoFetchReferral?: boolean;
|
|
331
|
+
}
|
|
332
|
+
interface UseShareReturn {
|
|
333
|
+
/** Share URL — absolute, with ?rc= appended if referral code available */
|
|
334
|
+
shareUrl: string;
|
|
335
|
+
/** User's referral code, or null if unauthenticated/not fetched */
|
|
336
|
+
referralCode: string | null;
|
|
337
|
+
/** Copy shareUrl to clipboard. Returns true on success. */
|
|
338
|
+
copyLink: () => Promise<boolean>;
|
|
339
|
+
/** Whether link was recently copied (auto-resets after 2s) */
|
|
340
|
+
copied: boolean;
|
|
341
|
+
/** Loading state for referral code fetch */
|
|
342
|
+
loading: boolean;
|
|
343
|
+
}
|
|
344
|
+
declare function useShare(options?: UseShareOptions): UseShareReturn;
|
|
345
|
+
|
|
292
346
|
/**
|
|
293
347
|
* Client-side validation helpers
|
|
294
348
|
*
|
|
@@ -447,4 +501,4 @@ declare function createSafeLogger(prefix: string): {
|
|
|
447
501
|
error: (message: string, data?: unknown) => void;
|
|
448
502
|
};
|
|
449
503
|
|
|
450
|
-
export { ApiError, type FeatureFlagEvaluation, type FeatureFlagEvaluation as FeatureFlagResult, ListFilesParams, LoginResponse, type PasswordValidationResult, type PhoneCountry, type PhoneValidationResult, type RealtimeEvent, type RealtimeMessage, type RealtimeStatus, ScaleMuleClient, ScaleMuleConfig, ScaleMuleProvider, type ScaleMuleProviderProps, UseAnalyticsOptions, UseAnalyticsReturn, UseAuthReturn, UseBillingReturn, UseContentReturn, type UseFeatureFlagsOptions, type UseFeatureFlagsReturn, type UseFeatureFlagsOptions as UseFlagsOptions, type UseFeatureFlagsReturn as UseFlagsReturn, type UseRealtimeOptions, type UseRealtimeReturn, UseUserReturn, User, type UsernameValidationResult, composePhone, createSafeLogger, normalizePhone, phoneCountries, sanitizeForLog, useAnalytics, useAuth, useBilling, useContent, useFeatureFlags, useRealtime, useScaleMule, useScaleMuleClient, useUser, validateForm, validators };
|
|
504
|
+
export { ApiError, type FeatureFlagEvaluation, type FeatureFlagEvaluation as FeatureFlagResult, ListFilesParams, LoginResponse, type PasswordValidationResult, type PhoneCountry, type PhoneValidationResult, type RealtimeEvent, type RealtimeMessage, type RealtimeStatus, ScaleMuleClient, ScaleMuleConfig, ScaleMuleProvider, type ScaleMuleProviderProps, UseAnalyticsOptions, UseAnalyticsReturn, UseAuthReturn, UseBillingReturn, UseContentReturn, type UseFeatureFlagsOptions, type UseFeatureFlagsReturn, type UseFeatureFlagsOptions as UseFlagsOptions, type UseFeatureFlagsReturn as UseFlagsReturn, type UsePushNotificationsOptions, type UsePushNotificationsReturn, type UseRealtimeOptions, type UseRealtimeReturn, type UseShareOptions, type UseShareReturn, UseUserReturn, User, type UsernameValidationResult, composePhone, createSafeLogger, normalizePhone, phoneCountries, sanitizeForLog, useAnalytics, useAuth, useBilling, useContent, useFeatureFlags, usePushNotifications, useRealtime, useScaleMule, useScaleMuleClient, useShare, useUser, validateForm, validators };
|
package/dist/index.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var react = require('react');
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
+
var sdk = require('@scalemule/sdk');
|
|
5
6
|
|
|
6
7
|
// src/provider.tsx
|
|
7
8
|
|
|
@@ -3053,6 +3054,265 @@ function useFeatureFlags(options = {}) {
|
|
|
3053
3054
|
getFlag
|
|
3054
3055
|
};
|
|
3055
3056
|
}
|
|
3057
|
+
function getCsrfToken() {
|
|
3058
|
+
if (typeof document === "undefined") return "";
|
|
3059
|
+
const match = document.cookie.match(/(?:^|;\s*)sm_csrf=([^;]*)/);
|
|
3060
|
+
return match ? decodeURIComponent(match[1]) : "";
|
|
3061
|
+
}
|
|
3062
|
+
function usePushNotifications(options = {}) {
|
|
3063
|
+
const { serviceWorkerUrl = "/sw.js", pushProxyUrl = "/api/push", onNotification } = options;
|
|
3064
|
+
const { user } = useScaleMule();
|
|
3065
|
+
const [isSupported, setIsSupported] = react.useState(false);
|
|
3066
|
+
const [permission, setPermission] = react.useState("unsupported");
|
|
3067
|
+
const [isSubscribed, setIsSubscribed] = react.useState(false);
|
|
3068
|
+
const [isLoading, setIsLoading] = react.useState(false);
|
|
3069
|
+
const [error, setError] = react.useState(null);
|
|
3070
|
+
const [tokenId, setTokenId] = react.useState(null);
|
|
3071
|
+
const onNotificationRef = react.useRef(onNotification);
|
|
3072
|
+
react.useEffect(() => {
|
|
3073
|
+
onNotificationRef.current = onNotification;
|
|
3074
|
+
}, [onNotification]);
|
|
3075
|
+
const prevUserRef = react.useRef(null);
|
|
3076
|
+
const fetcher = react.useMemo(() => {
|
|
3077
|
+
async function proxyGet(path) {
|
|
3078
|
+
const res = await fetch(`${pushProxyUrl}/${path}`);
|
|
3079
|
+
const json = await res.json();
|
|
3080
|
+
if (!json.success) throw new Error(json.error?.message || "Request failed");
|
|
3081
|
+
return json.data;
|
|
3082
|
+
}
|
|
3083
|
+
async function proxyPost(path, body) {
|
|
3084
|
+
const res = await fetch(`${pushProxyUrl}/${path}`, {
|
|
3085
|
+
method: "POST",
|
|
3086
|
+
headers: {
|
|
3087
|
+
"Content-Type": "application/json",
|
|
3088
|
+
"x-csrf-token": getCsrfToken()
|
|
3089
|
+
},
|
|
3090
|
+
body: body ? JSON.stringify(body) : void 0
|
|
3091
|
+
});
|
|
3092
|
+
const json = await res.json();
|
|
3093
|
+
if (!json.success) throw new Error(json.error?.message || "Request failed");
|
|
3094
|
+
return json.data;
|
|
3095
|
+
}
|
|
3096
|
+
async function proxyPut(path, body) {
|
|
3097
|
+
const res = await fetch(`${pushProxyUrl}/${path}`, {
|
|
3098
|
+
method: "PUT",
|
|
3099
|
+
headers: {
|
|
3100
|
+
"Content-Type": "application/json",
|
|
3101
|
+
"x-csrf-token": getCsrfToken()
|
|
3102
|
+
},
|
|
3103
|
+
body: body ? JSON.stringify(body) : void 0
|
|
3104
|
+
});
|
|
3105
|
+
const json = await res.json();
|
|
3106
|
+
if (!json.success) throw new Error(json.error?.message || "Request failed");
|
|
3107
|
+
return json.data;
|
|
3108
|
+
}
|
|
3109
|
+
async function proxyDelete(path) {
|
|
3110
|
+
const res = await fetch(`${pushProxyUrl}/${path}`, {
|
|
3111
|
+
method: "DELETE",
|
|
3112
|
+
headers: {
|
|
3113
|
+
"x-csrf-token": getCsrfToken()
|
|
3114
|
+
}
|
|
3115
|
+
});
|
|
3116
|
+
const json = await res.json();
|
|
3117
|
+
if (!json.success) throw new Error(json.error?.message || "Request failed");
|
|
3118
|
+
}
|
|
3119
|
+
return {
|
|
3120
|
+
getSettings: () => proxyGet("settings/me"),
|
|
3121
|
+
registerToken: (data) => proxyPost("register", data),
|
|
3122
|
+
unregisterToken: (id) => proxyDelete(`tokens/by-id/${id}`),
|
|
3123
|
+
associateUser: (id) => proxyPut(`tokens/by-id/${id}/user`, {}),
|
|
3124
|
+
disassociateUser: (id) => proxyDelete(`tokens/by-id/${id}/user`)
|
|
3125
|
+
};
|
|
3126
|
+
}, [pushProxyUrl]);
|
|
3127
|
+
const manager = react.useMemo(() => {
|
|
3128
|
+
if (typeof window === "undefined") return null;
|
|
3129
|
+
try {
|
|
3130
|
+
return new sdk.WebPushManager({ fetcher, serviceWorkerUrl });
|
|
3131
|
+
} catch {
|
|
3132
|
+
return null;
|
|
3133
|
+
}
|
|
3134
|
+
}, [fetcher, serviceWorkerUrl]);
|
|
3135
|
+
react.useEffect(() => {
|
|
3136
|
+
if (!manager) return;
|
|
3137
|
+
const supported = manager.isSupported();
|
|
3138
|
+
setIsSupported(supported);
|
|
3139
|
+
setPermission(manager.getPermissionState());
|
|
3140
|
+
if (supported) {
|
|
3141
|
+
const storedTokenId = manager.getTokenId();
|
|
3142
|
+
manager.isSubscribed().then((sub) => {
|
|
3143
|
+
if (!sub && storedTokenId) {
|
|
3144
|
+
manager.unsubscribe().catch(() => {
|
|
3145
|
+
});
|
|
3146
|
+
setIsSubscribed(false);
|
|
3147
|
+
setTokenId(null);
|
|
3148
|
+
setPermission(manager.getPermissionState());
|
|
3149
|
+
} else {
|
|
3150
|
+
setIsSubscribed(sub);
|
|
3151
|
+
setTokenId(manager.getTokenId());
|
|
3152
|
+
}
|
|
3153
|
+
});
|
|
3154
|
+
}
|
|
3155
|
+
}, [manager]);
|
|
3156
|
+
react.useEffect(() => {
|
|
3157
|
+
if (typeof navigator === "undefined" || !("serviceWorker" in navigator)) return;
|
|
3158
|
+
function handleMessage(event) {
|
|
3159
|
+
if (event.data?.type === "push-received") {
|
|
3160
|
+
onNotificationRef.current?.(event.data.payload);
|
|
3161
|
+
}
|
|
3162
|
+
if (event.data?.type === "push-subscription-expired") {
|
|
3163
|
+
if (manager) {
|
|
3164
|
+
manager.unsubscribe().catch(() => {
|
|
3165
|
+
});
|
|
3166
|
+
}
|
|
3167
|
+
setIsSubscribed(false);
|
|
3168
|
+
setTokenId(null);
|
|
3169
|
+
setPermission(typeof Notification !== "undefined" ? Notification.permission : "unsupported");
|
|
3170
|
+
}
|
|
3171
|
+
}
|
|
3172
|
+
navigator.serviceWorker.addEventListener("message", handleMessage);
|
|
3173
|
+
return () => navigator.serviceWorker.removeEventListener("message", handleMessage);
|
|
3174
|
+
}, [manager]);
|
|
3175
|
+
react.useEffect(() => {
|
|
3176
|
+
if (!manager) return;
|
|
3177
|
+
const currentUserId = user?.id || null;
|
|
3178
|
+
const prevUserId = prevUserRef.current;
|
|
3179
|
+
if (currentUserId && !prevUserId && isSubscribed) {
|
|
3180
|
+
manager.associateUser().catch(() => {
|
|
3181
|
+
});
|
|
3182
|
+
}
|
|
3183
|
+
prevUserRef.current = currentUserId;
|
|
3184
|
+
}, [user?.id, manager, isSubscribed]);
|
|
3185
|
+
const subscribe = react.useCallback(async () => {
|
|
3186
|
+
if (!manager) return;
|
|
3187
|
+
setIsLoading(true);
|
|
3188
|
+
setError(null);
|
|
3189
|
+
try {
|
|
3190
|
+
const result = await manager.subscribe();
|
|
3191
|
+
if (result) {
|
|
3192
|
+
setIsSubscribed(true);
|
|
3193
|
+
setTokenId(result.tokenId);
|
|
3194
|
+
setPermission("granted");
|
|
3195
|
+
} else {
|
|
3196
|
+
setPermission(manager.getPermissionState());
|
|
3197
|
+
}
|
|
3198
|
+
} catch (e) {
|
|
3199
|
+
setError({
|
|
3200
|
+
code: "PUSH_SUBSCRIBE_ERROR",
|
|
3201
|
+
message: e instanceof Error ? e.message : "Failed to subscribe"
|
|
3202
|
+
});
|
|
3203
|
+
} finally {
|
|
3204
|
+
setIsLoading(false);
|
|
3205
|
+
}
|
|
3206
|
+
}, [manager]);
|
|
3207
|
+
const unsubscribe = react.useCallback(async () => {
|
|
3208
|
+
if (!manager) return;
|
|
3209
|
+
setIsLoading(true);
|
|
3210
|
+
setError(null);
|
|
3211
|
+
try {
|
|
3212
|
+
await manager.unsubscribe();
|
|
3213
|
+
setIsSubscribed(false);
|
|
3214
|
+
setTokenId(null);
|
|
3215
|
+
} catch (e) {
|
|
3216
|
+
setError({
|
|
3217
|
+
code: "PUSH_UNSUBSCRIBE_ERROR",
|
|
3218
|
+
message: e instanceof Error ? e.message : "Failed to unsubscribe"
|
|
3219
|
+
});
|
|
3220
|
+
} finally {
|
|
3221
|
+
setIsLoading(false);
|
|
3222
|
+
}
|
|
3223
|
+
}, [manager]);
|
|
3224
|
+
const disassociateUser = react.useCallback(async () => {
|
|
3225
|
+
if (!manager) return;
|
|
3226
|
+
try {
|
|
3227
|
+
await manager.disassociateUser();
|
|
3228
|
+
} catch {
|
|
3229
|
+
}
|
|
3230
|
+
}, [manager]);
|
|
3231
|
+
return {
|
|
3232
|
+
isSupported,
|
|
3233
|
+
permission,
|
|
3234
|
+
isSubscribed,
|
|
3235
|
+
isLoading,
|
|
3236
|
+
error,
|
|
3237
|
+
subscribe,
|
|
3238
|
+
unsubscribe,
|
|
3239
|
+
disassociateUser,
|
|
3240
|
+
tokenId
|
|
3241
|
+
};
|
|
3242
|
+
}
|
|
3243
|
+
function useShare(options) {
|
|
3244
|
+
const { client, user } = useScaleMule();
|
|
3245
|
+
const [referralCode, setReferralCode] = react.useState(
|
|
3246
|
+
options?.referralCode ?? null
|
|
3247
|
+
);
|
|
3248
|
+
const [loading, setLoading] = react.useState(false);
|
|
3249
|
+
const [copied, setCopied] = react.useState(false);
|
|
3250
|
+
react.useEffect(() => {
|
|
3251
|
+
if (!user) {
|
|
3252
|
+
setReferralCode(options?.referralCode ?? null);
|
|
3253
|
+
setLoading(false);
|
|
3254
|
+
return;
|
|
3255
|
+
}
|
|
3256
|
+
if (!options?.autoFetchReferral) {
|
|
3257
|
+
setLoading(false);
|
|
3258
|
+
return;
|
|
3259
|
+
}
|
|
3260
|
+
if (options?.referralCode) {
|
|
3261
|
+
setReferralCode(options.referralCode);
|
|
3262
|
+
setLoading(false);
|
|
3263
|
+
return;
|
|
3264
|
+
}
|
|
3265
|
+
setReferralCode(null);
|
|
3266
|
+
let cancelled = false;
|
|
3267
|
+
setLoading(true);
|
|
3268
|
+
client.get("/v1/referrals/me").then((data) => {
|
|
3269
|
+
if (!cancelled) setReferralCode(data.referral_code);
|
|
3270
|
+
}).catch(() => {
|
|
3271
|
+
if (!cancelled) setReferralCode(null);
|
|
3272
|
+
}).finally(() => {
|
|
3273
|
+
if (!cancelled) setLoading(false);
|
|
3274
|
+
});
|
|
3275
|
+
return () => {
|
|
3276
|
+
cancelled = true;
|
|
3277
|
+
};
|
|
3278
|
+
}, [user?.id, options?.url, options?.referralCode, options?.autoFetchReferral, client]);
|
|
3279
|
+
const shareUrl = react.useMemo(() => {
|
|
3280
|
+
const raw = options?.url || (typeof window !== "undefined" ? window.location.href : "");
|
|
3281
|
+
if (!raw) return raw;
|
|
3282
|
+
try {
|
|
3283
|
+
const base = typeof window !== "undefined" ? window.location.origin : void 0;
|
|
3284
|
+
const u = new URL(raw, base);
|
|
3285
|
+
if (referralCode) {
|
|
3286
|
+
u.searchParams.set("rc", referralCode);
|
|
3287
|
+
}
|
|
3288
|
+
return u.toString();
|
|
3289
|
+
} catch {
|
|
3290
|
+
return raw;
|
|
3291
|
+
}
|
|
3292
|
+
}, [options?.url, referralCode]);
|
|
3293
|
+
const copyLink = react.useCallback(async () => {
|
|
3294
|
+
try {
|
|
3295
|
+
await navigator.clipboard.writeText(shareUrl);
|
|
3296
|
+
} catch {
|
|
3297
|
+
try {
|
|
3298
|
+
const textarea = document.createElement("textarea");
|
|
3299
|
+
textarea.value = shareUrl;
|
|
3300
|
+
textarea.style.position = "fixed";
|
|
3301
|
+
textarea.style.opacity = "0";
|
|
3302
|
+
document.body.appendChild(textarea);
|
|
3303
|
+
textarea.select();
|
|
3304
|
+
document.execCommand("copy");
|
|
3305
|
+
document.body.removeChild(textarea);
|
|
3306
|
+
} catch {
|
|
3307
|
+
return false;
|
|
3308
|
+
}
|
|
3309
|
+
}
|
|
3310
|
+
setCopied(true);
|
|
3311
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
3312
|
+
return true;
|
|
3313
|
+
}, [shareUrl]);
|
|
3314
|
+
return { shareUrl, referralCode, copyLink, copied, loading };
|
|
3315
|
+
}
|
|
3056
3316
|
|
|
3057
3317
|
// src/validation.ts
|
|
3058
3318
|
var phoneCountries = [
|
|
@@ -3359,9 +3619,11 @@ exports.useAuth = useAuth;
|
|
|
3359
3619
|
exports.useBilling = useBilling;
|
|
3360
3620
|
exports.useContent = useContent;
|
|
3361
3621
|
exports.useFeatureFlags = useFeatureFlags;
|
|
3622
|
+
exports.usePushNotifications = usePushNotifications;
|
|
3362
3623
|
exports.useRealtime = useRealtime;
|
|
3363
3624
|
exports.useScaleMule = useScaleMule;
|
|
3364
3625
|
exports.useScaleMuleClient = useScaleMuleClient;
|
|
3626
|
+
exports.useShare = useShare;
|
|
3365
3627
|
exports.useUser = useUser;
|
|
3366
3628
|
exports.validateForm = validateForm;
|
|
3367
3629
|
exports.validators = validators;
|