@rixl/sdk 0.9.0 → 0.10.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/dist/index.js CHANGED
@@ -1,7 +1,6 @@
1
1
  import { atom } from "nanostores";
2
2
  import { decodeJwt } from "jose";
3
3
  import * as v from "valibot";
4
- import "ky";
5
4
 
6
5
  //#region src/generated/core/bodySerializer.gen.ts
7
6
  const jsonBodySerializer = { bodySerializer: (body) => JSON.stringify(body, (_key, value) => typeof value === "bigint" ? value.toString() : value) };
@@ -352,9 +351,7 @@ const setAuthParams = async ({ security, ...options }) => {
352
351
  case "cookie":
353
352
  options.headers.append("Cookie", `${name}=${token}`);
354
353
  break;
355
- default:
356
- options.headers.set(name, token);
357
- break;
354
+ default: options.headers.set(name, token);
358
355
  }
359
356
  }
360
357
  };
@@ -515,9 +512,7 @@ const createClient = (config = {}) => {
515
512
  case "stream":
516
513
  emptyData = response.body;
517
514
  break;
518
- default:
519
- emptyData = {};
520
- break;
515
+ default: emptyData = {};
521
516
  }
522
517
  return opts.responseStyle === "data" ? emptyData : {
523
518
  data: emptyData,
@@ -757,6 +752,17 @@ const analyticsV1DashboardServiceQueryChart = (options) => (options.client ?? cl
757
752
  }
758
753
  });
759
754
  /**
755
+ * BatchQueryChart
756
+ */
757
+ const analyticsV1DashboardServiceBatchQueryChart = (options) => (options.client ?? client).post({
758
+ url: "/analytics/v1/dashboard/chart-query/batch",
759
+ ...options,
760
+ headers: {
761
+ "Content-Type": "application/json",
762
+ ...options.headers
763
+ }
764
+ });
765
+ /**
760
766
  * ListDatasets
761
767
  */
762
768
  const analyticsV1DashboardServiceListDatasets = (options) => (options?.client ?? client).get({
@@ -775,6 +781,107 @@ const analyticsV1DashboardServiceGetFilterOptions = (options) => (options.client
775
781
  }
776
782
  });
777
783
  /**
784
+ * GetScopeTree
785
+ */
786
+ const analyticsV1DashboardServiceGetScopeTree = (options) => (options.client ?? client).post({
787
+ url: "/analytics/v1/dashboard/scope-tree",
788
+ ...options,
789
+ headers: {
790
+ "Content-Type": "application/json",
791
+ ...options.headers
792
+ }
793
+ });
794
+ /**
795
+ * ListDashboards
796
+ */
797
+ const analyticsV1DashboardServiceListDashboards = (options) => (options?.client ?? client).get({
798
+ url: "/analytics/v1/dashboards",
799
+ ...options
800
+ });
801
+ /**
802
+ * CreateDashboard
803
+ */
804
+ const analyticsV1DashboardServiceCreateDashboard = (options) => (options.client ?? client).post({
805
+ url: "/analytics/v1/dashboards",
806
+ ...options,
807
+ headers: {
808
+ "Content-Type": "application/json",
809
+ ...options.headers
810
+ }
811
+ });
812
+ /**
813
+ * DeleteWidget
814
+ */
815
+ const analyticsV1DashboardServiceDeleteWidget = (options) => (options.client ?? client).delete({
816
+ url: "/analytics/v1/dashboards/widgets/{id}",
817
+ ...options
818
+ });
819
+ /**
820
+ * UpdateWidget
821
+ */
822
+ const analyticsV1DashboardServiceUpdateWidget = (options) => (options.client ?? client).patch({
823
+ url: "/analytics/v1/dashboards/widgets/{id}",
824
+ ...options,
825
+ headers: {
826
+ "Content-Type": "application/json",
827
+ ...options.headers
828
+ }
829
+ });
830
+ /**
831
+ * UpdateDashboardLayout
832
+ */
833
+ const analyticsV1DashboardServiceUpdateDashboardLayout = (options) => (options.client ?? client).post({
834
+ url: "/analytics/v1/dashboards/{dashboard_id}/layout",
835
+ ...options,
836
+ headers: {
837
+ "Content-Type": "application/json",
838
+ ...options.headers
839
+ }
840
+ });
841
+ /**
842
+ * CreateWidget
843
+ */
844
+ const analyticsV1DashboardServiceCreateWidget = (options) => (options.client ?? client).post({
845
+ url: "/analytics/v1/dashboards/{dashboard_id}/widgets",
846
+ ...options,
847
+ headers: {
848
+ "Content-Type": "application/json",
849
+ ...options.headers
850
+ }
851
+ });
852
+ /**
853
+ * DeleteDashboard
854
+ */
855
+ const analyticsV1DashboardServiceDeleteDashboard = (options) => (options.client ?? client).delete({
856
+ url: "/analytics/v1/dashboards/{id}",
857
+ ...options
858
+ });
859
+ /**
860
+ * GetDashboard
861
+ */
862
+ const analyticsV1DashboardServiceGetDashboard = (options) => (options.client ?? client).get({
863
+ url: "/analytics/v1/dashboards/{id}",
864
+ ...options
865
+ });
866
+ /**
867
+ * UpdateDashboard
868
+ */
869
+ const analyticsV1DashboardServiceUpdateDashboard = (options) => (options.client ?? client).patch({
870
+ url: "/analytics/v1/dashboards/{id}",
871
+ ...options,
872
+ headers: {
873
+ "Content-Type": "application/json",
874
+ ...options.headers
875
+ }
876
+ });
877
+ /**
878
+ * SetDefaultDashboard
879
+ */
880
+ const analyticsV1DashboardServiceSetDefaultDashboard = (options) => (options.client ?? client).post({
881
+ url: "/analytics/v1/dashboards/{id}/default",
882
+ ...options
883
+ });
884
+ /**
778
885
  * TrackEvents
779
886
  */
780
887
  const analyticsV1EventsServiceTrackEvents = (options) => (options.client ?? client).post({
@@ -836,6 +943,20 @@ const analyticsV1HeatmapServiceGetHotSegments = (options) => (options.client ??
836
943
  ...options
837
944
  });
838
945
  /**
946
+ * GetImageStats
947
+ */
948
+ const analyticsV1ImagesServiceGetImageStats = (options) => (options.client ?? client).get({
949
+ url: "/analytics/v1/images/{image_id}/stats",
950
+ ...options
951
+ });
952
+ /**
953
+ * GetTopImages
954
+ */
955
+ const analyticsV1ImagesServiceGetTopImages = (options) => (options?.client ?? client).get({
956
+ url: "/analytics/v1/top/images",
957
+ ...options
958
+ });
959
+ /**
839
960
  * GetPostStats
840
961
  */
841
962
  const analyticsV1PostsServiceGetPostStats = (options) => (options.client ?? client).get({
@@ -1157,6 +1278,13 @@ const authV1MembershipServiceUpdateOrgUsername = (options) => (options.client ??
1157
1278
  }
1158
1279
  });
1159
1280
  /**
1281
+ * RegenerateBackupCodes
1282
+ */
1283
+ const authV1OtpServiceRegenerateBackupCodes = (options) => (options?.client ?? client).post({
1284
+ url: "/auth/v1/users/current/totp/backup-codes/regenerate",
1285
+ ...options
1286
+ });
1287
+ /**
1160
1288
  * DeleteOTP
1161
1289
  */
1162
1290
  const authV1OtpServiceDeleteOtp = (options) => (options?.client ?? client).delete({
@@ -1312,6 +1440,13 @@ const authV1PolicyServiceDetachPolicy = (options) => (options.client ?? client).
1312
1440
  ...options
1313
1441
  });
1314
1442
  /**
1443
+ * ListPermissionRegistry
1444
+ */
1445
+ const authV1PolicyServiceListPermissionRegistry = (options) => (options.client ?? client).get({
1446
+ url: "/auth/v1/memberships/{user.org_id}/policies/permissions",
1447
+ ...options
1448
+ });
1449
+ /**
1315
1450
  * DeletePolicy
1316
1451
  */
1317
1452
  const authV1PolicyServiceDeletePolicy = (options) => (options.client ?? client).delete({
@@ -1355,13 +1490,6 @@ const authV1PolicyServiceAttachPolicy = (options) => (options.client ?? client).
1355
1490
  }
1356
1491
  });
1357
1492
  /**
1358
- * ListPermissionRegistry
1359
- */
1360
- const authV1PolicyServiceListPermissionRegistry = (options) => (options?.client ?? client).get({
1361
- url: "/auth/v1/policies/permissions",
1362
- ...options
1363
- });
1364
- /**
1365
1493
  * ListProviders
1366
1494
  */
1367
1495
  const authV1ProvidersServiceListProviders = (options) => (options?.client ?? client).get({
@@ -2324,6 +2452,15 @@ function validateOAuthState(provider, state) {
2324
2452
  return sessionStorage.getItem(storagePath(provider)) === state;
2325
2453
  }
2326
2454
  /**
2455
+ * Discards the stored state for a provider so the next login round-trip mints a
2456
+ * fresh one. The state doubles as the OAuth `nonce`, so reusing it across logins
2457
+ * would replay a nonce the provider has already issued a token for.
2458
+ * @param provider The provider identifier
2459
+ */
2460
+ function clearOauthState(provider) {
2461
+ sessionStorage.removeItem(storagePath(provider));
2462
+ }
2463
+ /**
2327
2464
  * Gets or Generates a complete state parameter for OAuth requests
2328
2465
  * @param provider The identifier for the provider (e.g., 'google', 'apple')
2329
2466
  * @returns A state string containing the provider identifier and random data
@@ -2347,9 +2484,10 @@ function generateOauthState(provider) {
2347
2484
  * Builds an OAuth URL from configuration and metadata
2348
2485
  */
2349
2486
  const buildOAuthUrl = (config, metadata, state) => {
2487
+ const redirectUri = config.redirectUri ?? window.location.origin;
2350
2488
  const params = new URLSearchParams({
2351
2489
  client_id: config.clientId,
2352
- redirect_uri: window.location.origin,
2490
+ redirect_uri: redirectUri,
2353
2491
  response_type: metadata.responseType,
2354
2492
  scope: [...metadata.defaultScopes, ...config.scope ? [config.scope] : []].join(" "),
2355
2493
  state
@@ -2372,8 +2510,8 @@ const warnProviderNotConfigured = (providerName) => {
2372
2510
  * This factory reduces code duplication across OAuth providers
2373
2511
  */
2374
2512
  const createOAuthProvider = ({ provider, metadata }) => {
2375
- const config = atom(null);
2376
- const authUrl = atom(null);
2513
+ const config = shared(`provider.${provider}.config`, () => atom(null));
2514
+ const authUrl = shared(`provider.${provider}.authUrl`, () => atom(null));
2377
2515
  const updateAuthUrl = () => {
2378
2516
  const currentConfig = config.get();
2379
2517
  if (!currentConfig) {
@@ -2449,8 +2587,8 @@ const updateAppleAuthUrl = appleProvider.updateAuthUrl;
2449
2587
 
2450
2588
  //#endregion
2451
2589
  //#region src/auth/providers/telegram.ts
2452
- const telegramConfig = atom(null);
2453
- const telegramAuthUrl = atom(null);
2590
+ const telegramConfig = shared("provider.telegram.config", () => atom(null));
2591
+ const telegramAuthUrl = shared("provider.telegram.authUrl", () => atom(null));
2454
2592
  /**
2455
2593
  * Updates the Telegram authentication URL using the configured settings
2456
2594
  */
@@ -2483,7 +2621,7 @@ function extractProviderFromState(state) {
2483
2621
  const parts = state.split("_");
2484
2622
  if (parts.length >= 1) return parts[0];
2485
2623
  }
2486
- const OAUTH_PROVIDERS = [
2624
+ const OAUTH_PROVIDERS$1 = [
2487
2625
  "google",
2488
2626
  "apple",
2489
2627
  "microsoft"
@@ -2499,7 +2637,7 @@ function detectProvider() {
2499
2637
  const state = urlParams.get("state");
2500
2638
  if (id_token && state) {
2501
2639
  const providerFromState = extractProviderFromState(state);
2502
- return OAUTH_PROVIDERS.find((p) => providerFromState === p && validateOAuthState(p, state));
2640
+ return OAUTH_PROVIDERS$1.find((p) => providerFromState === p && validateOAuthState(p, state));
2503
2641
  }
2504
2642
  }
2505
2643
  /**
@@ -2513,20 +2651,210 @@ function getProviderToken(provider) {
2513
2651
  }
2514
2652
 
2515
2653
  //#endregion
2516
- //#region src/auth/api/refresh-tokens.ts
2517
- const refreshTokens = async (provider, token, options) => {
2518
- const { data } = await authV1TokenServiceRefreshToken({
2519
- body: {
2654
+ //#region src/auth/providers/callback.ts
2655
+ /** Params that carry the credential itself their presence marks a callback response. */
2656
+ const CREDENTIAL_PARAMS = [
2657
+ "id_token",
2658
+ "code",
2659
+ "access_token",
2660
+ "tgAuthResult",
2661
+ "tgWebAppData"
2662
+ ];
2663
+ /** Everything the providers append to the redirect URL, credential and bookkeeping alike. */
2664
+ const OAUTH_RESPONSE_PARAMS = [
2665
+ ...CREDENTIAL_PARAMS,
2666
+ "state",
2667
+ "token_type",
2668
+ "expires_in",
2669
+ "scope",
2670
+ "session_state",
2671
+ "authuser",
2672
+ "prompt",
2673
+ "hd"
2674
+ ];
2675
+ /**
2676
+ * Whether the URL this page loaded with carries a provider response at all —
2677
+ * unlike `detectProvider()`, this does not require the state to validate. The
2678
+ * gap between the two is the case where a login round-trip came back but cannot
2679
+ * be used, which otherwise ends the flow in silence.
2680
+ */
2681
+ const hasProviderResponse = () => CREDENTIAL_PARAMS.some((key) => urlParams.has(key));
2682
+ const AUTH_URL_UPDATERS = {
2683
+ ["google"]: updateGoogleAuthUrl,
2684
+ ["apple"]: updateAppleAuthUrl,
2685
+ ["microsoft"]: updateMicrosoftAuthUrl
2686
+ };
2687
+ /** Returns undefined when the half holds no credential, meaning it is the app's own and must not be touched. */
2688
+ const stripped = (query) => {
2689
+ const params = new URLSearchParams(query);
2690
+ if (!CREDENTIAL_PARAMS.some((key) => params.has(key))) return void 0;
2691
+ OAUTH_RESPONSE_PARAMS.forEach((key) => params.delete(key));
2692
+ return params.toString();
2693
+ };
2694
+ /**
2695
+ * Providers put their response in the query string or the fragment depending on
2696
+ * `response_mode`, and either half may also hold params the app itself put
2697
+ * there. Only the half actually carrying the credential is rewritten.
2698
+ */
2699
+ const withoutOAuthResponse = (href) => {
2700
+ const url = new URL(href);
2701
+ url.search = stripped(url.search) ?? url.search;
2702
+ url.hash = stripped(url.hash.slice(1)) ?? url.hash;
2703
+ return url.toString();
2704
+ };
2705
+ /**
2706
+ * Retires the provider response after `initClient` is done with it.
2707
+ *
2708
+ * Left in place, the credential stays in the address bar and every reload — or
2709
+ * Vite's HMR full reload — replays an already-consumed `id_token`, which the
2710
+ * gateway rejects. Clearing the stored state on the way out also stops the next
2711
+ * login from reusing this round-trip's `nonce`.
2712
+ *
2713
+ * The `urlParams` snapshot is taken at import time and is intentionally left
2714
+ * untouched, so callers that already read the credential out of it keep working
2715
+ * for the rest of this page load.
2716
+ */
2717
+ const completeOAuthCallback = () => {
2718
+ const provider = detectProvider();
2719
+ if (!provider) return;
2720
+ clearOauthState(provider);
2721
+ AUTH_URL_UPDATERS[provider]?.();
2722
+ window.history.replaceState(window.history.state, "", withoutOAuthResponse(window.location.href));
2723
+ };
2724
+
2725
+ //#endregion
2726
+ //#region src/auth/api/types.ts
2727
+ /**
2728
+ * Generic API error class - wraps ky's HTTPError for consistency
2729
+ */
2730
+ var ApiError = class extends Error {
2731
+ status;
2732
+ endpoint;
2733
+ data;
2734
+ constructor(message, ...rest) {
2735
+ super(message);
2736
+ this.name = "ApiError";
2737
+ const firstArg = rest[0];
2738
+ if (typeof firstArg === "number") {
2739
+ this.status = firstArg;
2740
+ this.endpoint = rest[1] ?? "";
2741
+ this.data = rest[2];
2742
+ return;
2743
+ }
2744
+ this.status = firstArg.status;
2745
+ this.endpoint = firstArg.endpoint;
2746
+ this.data = firstArg.data;
2747
+ }
2748
+ };
2749
+
2750
+ //#endregion
2751
+ //#region src/auth/providers/diagnostics.ts
2752
+ const claimsOf = (token) => {
2753
+ try {
2754
+ const { iss, aud, exp, nonce, email } = decodeJwt(token);
2755
+ return {
2756
+ iss: String(iss ?? ""),
2757
+ aud: String(aud ?? ""),
2758
+ exp: exp ? (/* @__PURE__ */ new Date(Number(exp) * 1e3)).toISOString() : void 0,
2759
+ expired: typeof exp === "number" && Date.now() >= exp * 1e3,
2760
+ nonce: String(nonce ?? ""),
2761
+ email: String(email ?? "")
2762
+ };
2763
+ } catch {
2764
+ return { note: "not a JWT — expected for Telegram, unexpected for Google/Apple/Microsoft" };
2765
+ }
2766
+ };
2767
+ const verdictFor = (error) => {
2768
+ if ((typeof error.data === "object" && error.data !== null ? error.data : void 0)?.error === "invalid token type") return "CLIENT: the gateway does not accept this token_type. Expected one of Bearer, google, apple, microsoft, tgAuthResult, tgWebAppData.";
2769
+ if (error.status === HTTP_STATUS.UNAUTHORIZED) return "BACKEND or CONFIG: the gateway could not verify the credential. Compare `aud` above with the client ID the gateway is configured with, and check `expired`.";
2770
+ if (error.status === HTTP_STATUS.CONFLICT) return "EXPECTED: this email already belongs to an account created with a different provider.";
2771
+ if (error.status === HTTP_STATUS.BAD_REQUEST) return "BACKEND: the gateway rejected the request body. Read `response.body` for its reason.";
2772
+ return "UNKNOWN: see `response` below.";
2773
+ };
2774
+ const describe = (error) => {
2775
+ if (!(error instanceof ApiError)) return {
2776
+ response: {
2777
+ status: "none — the request never completed",
2778
+ detail: String(error)
2779
+ },
2780
+ verdict: "NETWORK or CORS: the browser never got a response. Check the gateway is reachable and its CORS headers allow this origin."
2781
+ };
2782
+ return {
2783
+ response: {
2784
+ status: error.status,
2785
+ body: error.data,
2786
+ message: error.message
2787
+ },
2788
+ verdict: verdictFor(error)
2789
+ };
2790
+ };
2791
+ const OAUTH_PROVIDERS = [
2792
+ "google",
2793
+ "apple",
2794
+ "microsoft"
2795
+ ];
2796
+ const storedStates = () => Object.fromEntries(OAUTH_PROVIDERS.map((p) => [p, sessionStorage.getItem("__rixl_auth_state_" + p) ?? "(none)"]));
2797
+ /**
2798
+ * Reports a provider response that arrived but could not be used, which ends the
2799
+ * login without a request ever being sent — the case that otherwise looks like
2800
+ * "it just went back to the login page".
2801
+ *
2802
+ * `detectProvider()` requires the `state` in the URL to equal the one stored when
2803
+ * the login started, so the two states below are the thing to compare.
2804
+ */
2805
+ const logUnusableProviderResponse = () => {
2806
+ const state = urlParams.get("state") ?? "(none)";
2807
+ console.error("[@rixl/sdk] a provider response is in the URL but no login was attempted", {
2808
+ urlState: state,
2809
+ storedStates: storedStates(),
2810
+ credentialParams: [
2811
+ "id_token",
2812
+ "code",
2813
+ "access_token"
2814
+ ].filter((key) => urlParams.has(key)),
2815
+ verdict: state === "(none)" ? "CLIENT: the provider returned no `state`, so the response cannot be matched to a login attempt." : "CLIENT: `urlState` does not match the stored state for its provider. sessionStorage was cleared, the login started in a different tab, or the response was replayed after the state had already been retired."
2816
+ });
2817
+ };
2818
+ /**
2819
+ * Reports a failed provider token exchange. `provider` doubles as the `token_type`
2820
+ * sent on the wire, so it is printed as-is.
2821
+ */
2822
+ const logProviderExchangeFailure = (provider, credential, error) => {
2823
+ console.error("[@rixl/sdk] provider login failed at POST /auth/v1/token", {
2824
+ request: {
2520
2825
  token_type: provider,
2521
- refresh_token: token,
2522
- country_code: options?.countryCode,
2523
- origin: options?.origin
2826
+ credential: claimsOf(credential)
2524
2827
  },
2525
- throwOnError: true
2828
+ ...describe(error)
2526
2829
  });
2527
- return data;
2528
2830
  };
2529
2831
 
2832
+ //#endregion
2833
+ //#region src/auth/social/socialState.ts
2834
+ const socialStoragePath = (provider) => SOCIAL_CONNECT_KEY_PREFIX + provider;
2835
+ /**
2836
+ * Sets a flag indicating that a social provider connection is being attempted
2837
+ * @param provider The provider identifier
2838
+ */
2839
+ function setSocialConnectAttempt(provider) {
2840
+ sessionStorage.setItem(socialStoragePath(provider), "true");
2841
+ }
2842
+ /**
2843
+ * Checks if there's a pending social provider connection attempt
2844
+ * @param provider The provider identifier
2845
+ * @returns True if there's a pending connection attempt, false otherwise
2846
+ */
2847
+ function hasSocialConnectAttempt(provider) {
2848
+ return sessionStorage.getItem(socialStoragePath(provider)) === "true";
2849
+ }
2850
+ /**
2851
+ * Clears the social provider connection attempt flag
2852
+ * @param provider The provider identifier
2853
+ */
2854
+ function clearSocialConnectAttempt(provider) {
2855
+ sessionStorage.removeItem(socialStoragePath(provider));
2856
+ }
2857
+
2530
2858
  //#endregion
2531
2859
  //#region src/auth/initialization.ts
2532
2860
  /**
@@ -2546,482 +2874,42 @@ function createDeferred() {
2546
2874
  };
2547
2875
  }
2548
2876
  /**
2549
- * Global deferred promise that tracks the initialization status of the auth library
2550
- * This is resolved when initClient is called
2877
+ * Global deferred promise that tracks the initialization status of the auth library.
2878
+ * This is resolved when initClient is called.
2879
+ *
2880
+ * Shared across copies of this package. `connect()` runs in exactly one copy, so
2881
+ * a per-copy deferred leaves every other copy awaiting a promise nothing will
2882
+ * ever resolve — and because getToken() and the request interceptor both await
2883
+ * it, that is not a slow path but a permanent hang.
2551
2884
  */
2552
- const initDeferred = createDeferred();
2885
+ const initDeferred = shared("initDeferred", createDeferred);
2553
2886
 
2554
2887
  //#endregion
2555
- //#region src/auth/cookie/util.ts
2556
- const getAllCookiesStartWith = (startWithKey) => {
2557
- if (typeof document === "undefined") return {};
2558
- return document.cookie.split(";").map((cv) => cv.split("=").map((v) => v.trim())).filter(([key]) => key && key !== startWithKey && key.startsWith(startWithKey)).reduce((ac, [key, value]) => Object.assign(ac, { [key.slice(startWithKey.length + 1)]: value }), {});
2888
+ //#region src/auth/api/error-handlers.ts
2889
+ /**
2890
+ * Helper to create error functions - reduces bundle size by reusing error creation logic
2891
+ */
2892
+ const err = (message) => () => new Error(message);
2893
+ /** Reusable error handlers for common cases - reduces repetitive error messages */
2894
+ const commonErrors = {
2895
+ unauthorized: err("User is not authorized"),
2896
+ badRequest: err("Bad request"),
2897
+ notFound: err("Not found"),
2898
+ conflict: err("Resource already exists"),
2899
+ forbidden: err("Forbidden"),
2900
+ tooManyRequests: err("Too many requests")
2559
2901
  };
2560
- function setCookie(name, value, options) {
2561
- if (typeof document === "undefined") return;
2562
- let cookieString = `${encodeName(name)}=${encodeValue(value)}`;
2563
- if (options) {
2564
- if (options.expires) if (typeof options.expires === "number") {
2565
- const date = /* @__PURE__ */ new Date();
2566
- date.setTime(date.getTime() + options.expires * 24 * 60 * 60 * 1e3);
2567
- cookieString += `; expires=${date.toUTCString()}`;
2568
- } else cookieString += `; expires=${options.expires.toUTCString()}`;
2569
- if (options.path) cookieString += `; path=${options.path}`;
2570
- if (options.domain) cookieString += `; domain=${options.domain}`;
2571
- if (options.secure) cookieString += `; secure`;
2572
- if (options.sameSite) cookieString += `; samesite=${options.sameSite}`;
2902
+ /**
2903
+ * Standard error handler for API errors with custom status code handling
2904
+ */
2905
+ const handleApiError = (error, statusHandlers) => {
2906
+ if (error instanceof ApiError) {
2907
+ const handler = statusHandlers[error.status];
2908
+ if (handler) throw new ApiError(handler().message, error.status, error.endpoint, error.data);
2909
+ throw error;
2573
2910
  }
2574
- document.cookie = cookieString;
2575
- }
2576
- function deleteCookie(name) {
2577
- if (typeof document === "undefined") return;
2578
- document.cookie = name + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
2579
- }
2580
- const encodeName = (name) => encodeURIComponent(name).replace(/%(2[346B]|5E|60|7C)/g, decodeURIComponent);
2581
- const encodeValue = (value) => encodeURIComponent(value).replace(/%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g, decodeURIComponent);
2582
-
2583
- //#endregion
2584
- //#region src/auth/cookie/index.ts
2585
- const initVals = getAllCookiesStartWith(GLOBAL_PREFIX);
2586
- const setStoreCookie = (key, value) => {
2587
- const expires = /* @__PURE__ */ new Date();
2588
- expires.setTime(expires.getTime() + 30 * 24 * 60 * 60 * 1e3);
2589
- const cookieKey = `${GLOBAL_PREFIX}_${key}`;
2590
- if (!value || value === "") {
2591
- deleteCookie(cookieKey);
2592
- return;
2593
- }
2594
- const stringValue = typeof value === "string" ? value : JSON.stringify(value);
2595
- setCookie(`${GLOBAL_PREFIX}_${key}`, stringValue, {
2596
- expires,
2597
- path: "/",
2598
- sameSite: "Lax"
2599
- });
2600
- };
2601
-
2602
- //#endregion
2603
- //#region src/auth/userStore.ts
2604
- const userPath = GLOBAL_PREFIX + "_user";
2605
- const parseUser = () => {
2606
- if (typeof localStorage === "undefined" || !localStorage || typeof localStorage.getItem !== "function") return;
2607
- const value = localStorage.getItem(userPath);
2608
- if (value && value != "undefined") try {
2609
- return JSON.parse(value);
2610
- } catch (err) {
2611
- console.warn("Can't parse user data, error: ", err);
2612
- return;
2613
- }
2614
- };
2615
- const user = shared("user", () => {
2616
- const store = atom(parseUser());
2617
- store.subscribe((value) => {
2618
- if (typeof localStorage === "undefined" || !localStorage || typeof localStorage.setItem !== "function") return;
2619
- if (value) localStorage.setItem(userPath, JSON.stringify(value));
2620
- else localStorage.removeItem(userPath);
2621
- });
2622
- return store;
2623
- });
2624
-
2625
- //#endregion
2626
- //#region src/auth/utils/jwt.ts
2627
- /**
2628
- * Decodes a JWT token and extracts user information
2629
- * Uses jose library for modern, secure JWT handling
2630
- * @param token The JWT token to decode
2631
- * @returns The decoded user data or undefined if decoding fails
2632
- */
2633
- const decodeToken = (token) => {
2634
- try {
2635
- const decodedUser = decodeJwt(token);
2636
- return {
2637
- id: decodedUser.id,
2638
- email: decodedUser.email,
2639
- first_name: decodedUser.first_name,
2640
- last_name: decodedUser.last_name,
2641
- username: decodedUser.username,
2642
- image_url: decodedUser.image_url,
2643
- language_code: decodedUser.language_code,
2644
- org_id: decodedUser.org_id
2645
- };
2646
- } catch (error) {
2647
- console.warn("Failed to decode JWT token. Error: ", error);
2648
- return;
2649
- }
2650
- };
2651
- /**
2652
- * Decodes a JWT token and sets the user in the store
2653
- * @param token The JWT token to decode
2654
- * @returns True if user was successfully decoded and set, false otherwise
2655
- */
2656
- const decodeAndSetUser = (token) => {
2657
- const userData = decodeToken(token);
2658
- if (userData) {
2659
- user.set(userData);
2660
- return true;
2661
- }
2662
- return false;
2663
- };
2664
- /**
2665
- * Checks if a token is expired based on the expiration timestamp
2666
- * @param expireAt The expiration timestamp in milliseconds
2667
- * @returns True if the token is expired, false otherwise
2668
- */
2669
- const isTokenExpired = (expireAt) => {
2670
- if (!expireAt) return true;
2671
- return Date.now() >= expireAt;
2672
- };
2673
-
2674
- //#endregion
2675
- //#region src/auth/authStore.ts
2676
- const isLogged = shared("isLogged", () => atom(initVals["isLogged"] === "true" || detectProvider() !== void 0));
2677
- const accessToken = shared("accessToken", () => atom(initVals["accessToken"]));
2678
- const refreshToken = shared("refreshToken", () => atom(initVals["refreshToken"]));
2679
- const expireAt = shared("expireAt", () => atom(Number(initVals["expireAt"])));
2680
- const authError = shared("authError", () => atom(null));
2681
- const requiresAction = shared("requiresAction", () => atom(initVals["requiresAction"] || null));
2682
- const limitedAccessToken = shared("limitedAccessToken", () => atom(initVals["limitedAccessToken"] || null));
2683
- let currentTokenPromise = null;
2684
- const PROVIDER_URL_MAP = {
2685
- google: googleAuthUrl,
2686
- apple: appleAuthUrl,
2687
- microsoft: microsoftAuthUrl,
2688
- telegram: telegramAuthUrl
2689
- };
2690
- const login = async (provider) => {
2691
- await initDeferred.promise;
2692
- const authUrlAtom = PROVIDER_URL_MAP[provider];
2693
- if (!authUrlAtom) throw new Error(`Unsupported provider: ${provider}`);
2694
- const authUrl = authUrlAtom.get();
2695
- if (authUrl) window.location.href = authUrl;
2696
- else throw new Error(`${provider} provider is not configured. Please check your initClient configuration.`);
2697
- };
2698
- const refreshAccessToken = async (refresh) => {
2699
- const result = await refreshTokens("Bearer", refresh);
2700
- if (!("requires_action" in result)) setTokens(result.access_token, result.refresh_token, result.expires_in);
2701
- };
2702
- const ensureValidAccessToken = async (refresh) => {
2703
- if (accessToken.get() && !isTokenExpired(expireAt.get())) return;
2704
- try {
2705
- await refreshAccessToken(refresh);
2706
- } catch (refreshError) {
2707
- console.error("Token refresh failed in getToken:", refreshError);
2708
- removeTokens();
2709
- throw refreshError;
2710
- }
2711
- };
2712
- const getToken = async () => {
2713
- if (currentTokenPromise) return currentTokenPromise;
2714
- currentTokenPromise = (async () => {
2715
- try {
2716
- await initDeferred.promise;
2717
- if (requiresAction.get()) return void 0;
2718
- const currentRefreshToken = refreshToken.get();
2719
- if (!currentRefreshToken) return void 0;
2720
- await ensureValidAccessToken(currentRefreshToken);
2721
- const token = accessToken.get();
2722
- if (token) decodeAndSetUser(token);
2723
- return token;
2724
- } catch (error) {
2725
- console.warn("Failed to getToken(). Error: ", error);
2726
- throw error;
2727
- } finally {
2728
- currentTokenPromise = null;
2729
- }
2730
- })();
2731
- return currentTokenPromise;
2732
- };
2733
- /**
2734
- * Sets authentication tokens in the store
2735
- * @param access The access token
2736
- * @param refresh The refresh token
2737
- * @param expiresIn The token expiration time in seconds
2738
- */
2739
- const setTokens = (access, refresh, expiresIn) => {
2740
- accessToken.set(access);
2741
- refreshToken.set(refresh);
2742
- expireAt.set(Date.now() + expiresIn * 1e3);
2743
- isLogged.set(true);
2744
- limitedAccessToken.set(null);
2745
- requiresAction.set(null);
2746
- authError.set(null);
2747
- decodeAndSetUser(access);
2748
- };
2749
- /**
2750
- * Removes authentication tokens from the store
2751
- */
2752
- const removeTokens = () => {
2753
- accessToken.set("");
2754
- refreshToken.set("");
2755
- expireAt.set(0);
2756
- isLogged.set(false);
2757
- user.set(void 0);
2758
- limitedAccessToken.set(null);
2759
- requiresAction.set(null);
2760
- authError.set(null);
2761
- };
2762
- /**
2763
- * Clears the auth error from the store
2764
- */
2765
- const clearAuthError = () => {
2766
- authError.set(null);
2767
- };
2768
- /**
2769
- * Sets limited access state for users requiring additional action (e.g., Telegram users without email)
2770
- * @param token The limited scope access token
2771
- * @param action The required action (e.g., "add_email")
2772
- */
2773
- const setLimitedAccessState = (token, action) => {
2774
- limitedAccessToken.set(token);
2775
- requiresAction.set(action);
2776
- authError.set(null);
2777
- isLogged.set(true);
2778
- };
2779
- /**
2780
- * Clears the limited access state (after email verification completes or user logs out)
2781
- */
2782
- const clearLimitedAccessState = () => {
2783
- limitedAccessToken.set(null);
2784
- requiresAction.set(null);
2785
- if (!(!!accessToken.get() && !!refreshToken.get())) isLogged.set(false);
2786
- };
2787
- isLogged.subscribe((value) => setStoreCookie("isLogged", value));
2788
- accessToken.subscribe((value) => setStoreCookie("accessToken", value));
2789
- refreshToken.subscribe((value) => setStoreCookie("refreshToken", value));
2790
- expireAt.subscribe((value) => setStoreCookie("expireAt", value));
2791
- requiresAction.subscribe((value) => setStoreCookie("requiresAction", value));
2792
- limitedAccessToken.subscribe((value) => setStoreCookie("limitedAccessToken", value));
2793
-
2794
- //#endregion
2795
- //#region src/auth/api/types.ts
2796
- /**
2797
- * Generic API error class - wraps ky's HTTPError for consistency
2798
- */
2799
- var ApiError = class extends Error {
2800
- status;
2801
- endpoint;
2802
- data;
2803
- constructor(message, ...rest) {
2804
- super(message);
2805
- this.name = "ApiError";
2806
- const firstArg = rest[0];
2807
- if (typeof firstArg === "number") {
2808
- this.status = firstArg;
2809
- this.endpoint = rest[1] ?? "";
2810
- this.data = rest[2];
2811
- return;
2812
- }
2813
- this.status = firstArg.status;
2814
- this.endpoint = firstArg.endpoint;
2815
- this.data = firstArg.data;
2816
- }
2817
- };
2818
-
2819
- //#endregion
2820
- //#region src/auth/api-url.ts
2821
- /**
2822
- * Global API base URL store
2823
- */
2824
- const apiURL = shared("apiURL", () => atom(""));
2825
-
2826
- //#endregion
2827
- //#region src/auth/api/sdk-client.ts
2828
- function isWireErrorBody(error) {
2829
- return typeof error === "object" && error !== null;
2830
- }
2831
- const state = shared("sdkClientState", () => ({
2832
- configured: false,
2833
- tokenResolver: getToken
2834
- }));
2835
- function setTokenResolver(resolver) {
2836
- state.tokenResolver = resolver;
2837
- }
2838
- /**
2839
- * Routes that do not require a Bearer token at the gateway edge. These
2840
- * authenticate via credentials in the request body (or are webhooks verified by
2841
- * signature), so attaching an Authorization header here would make the gateway
2842
- * attempt to validate a stale/absent token and reject the request with 401.
2843
- * Mirrors `publicRoutes` in backend/gateway/internal/routes/routes.go.
2844
- */
2845
- const publicRoutes = [
2846
- {
2847
- method: "POST",
2848
- path: "/auth/v1/token"
2849
- },
2850
- {
2851
- method: "POST",
2852
- path: "/auth/v1/register"
2853
- },
2854
- {
2855
- method: "POST",
2856
- path: "/auth/v1/login"
2857
- },
2858
- {
2859
- method: "POST",
2860
- path: "/auth/v1/email/verify"
2861
- },
2862
- {
2863
- method: "POST",
2864
- path: "/auth/v1/email/verify/resend"
2865
- },
2866
- {
2867
- method: "POST",
2868
- path: "/auth/v1/password/reset"
2869
- },
2870
- {
2871
- method: "POST",
2872
- path: "/auth/v1/password/reset/confirm"
2873
- },
2874
- {
2875
- method: "POST",
2876
- path: "/auth/v1/verify-totp"
2877
- },
2878
- {
2879
- method: "POST",
2880
- path: "/auth/v1/verify-passkey"
2881
- },
2882
- {
2883
- method: "POST",
2884
- path: "/auth/v1/invitations/",
2885
- prefix: true
2886
- },
2887
- {
2888
- method: "POST",
2889
- path: "/auth/v1/passkey/login/begin"
2890
- },
2891
- {
2892
- method: "POST",
2893
- path: "/auth/v1/passkey/login/finish"
2894
- },
2895
- {
2896
- method: "POST",
2897
- path: "/auth/v1/logout"
2898
- },
2899
- {
2900
- method: "POST",
2901
- path: "/auth/v1/blog/unsubscribe/email"
2902
- },
2903
- {
2904
- method: "POST",
2905
- path: "/auth/v1/blog/broadcast"
2906
- },
2907
- {
2908
- method: "GET",
2909
- path: "/media/v1/videos/",
2910
- prefix: true
2911
- },
2912
- {
2913
- method: "GET",
2914
- path: "/media/v1/images/",
2915
- prefix: true
2916
- },
2917
- {
2918
- method: "GET",
2919
- path: "/media/v1/languages"
2920
- },
2921
- {
2922
- method: "GET",
2923
- path: "/posts/v1/feeds/",
2924
- prefix: true
2925
- },
2926
- {
2927
- method: "POST",
2928
- path: "/billing/webhooks/stripe"
2929
- },
2930
- {
2931
- method: "POST",
2932
- path: "/webhooks/storage"
2933
- },
2934
- {
2935
- method: "POST",
2936
- path: "/platform/auth/v1/token"
2937
- },
2938
- {
2939
- method: "POST",
2940
- path: "/platform/auth/v1/refresh"
2941
- }
2942
- ];
2943
- function isPublicRoute(method, pathname) {
2944
- const match = method.toUpperCase();
2945
- return publicRoutes.some(({ method: m, path, prefix }) => match === m && (prefix ? pathname.startsWith(path) : pathname === path));
2946
- }
2947
- function configureSdkClient() {
2948
- if (state.configured) return;
2949
- state.configured = true;
2950
- configureAllClients(apiURL.get());
2951
- apiURL.subscribe((url) => {
2952
- configureAllClients(url);
2953
- });
2954
- addClientInitializer((client) => {
2955
- client.interceptors.request.use(async (request) => {
2956
- if (request.headers.has("Authorization")) return request;
2957
- const { pathname } = new URL(request.url);
2958
- if (isPublicRoute(request.method, pathname)) return request;
2959
- const token = await state.tokenResolver();
2960
- if (!token) throw new ApiError("No access token available for an authenticated request", HTTP_STATUS.UNAUTHORIZED, pathname);
2961
- request.headers.set("Authorization", `Bearer ${token}`);
2962
- return request;
2963
- });
2964
- client.interceptors.error.use((error, response, request) => {
2965
- if (error instanceof Error) return error;
2966
- const body = isWireErrorBody(error) ? error : void 0;
2967
- const status = response?.status ?? body?.code ?? 0;
2968
- return new ApiError(body?.error || body?.details || (typeof error === "string" ? error : "Request failed"), status, request ? new URL(request.url).pathname : "", error);
2969
- });
2970
- });
2971
- }
2972
-
2973
- //#endregion
2974
- //#region src/auth/social/socialState.ts
2975
- const socialStoragePath = (provider) => SOCIAL_CONNECT_KEY_PREFIX + provider;
2976
- /**
2977
- * Sets a flag indicating that a social provider connection is being attempted
2978
- * @param provider The provider identifier
2979
- */
2980
- function setSocialConnectAttempt(provider) {
2981
- sessionStorage.setItem(socialStoragePath(provider), "true");
2982
- }
2983
- /**
2984
- * Checks if there's a pending social provider connection attempt
2985
- * @param provider The provider identifier
2986
- * @returns True if there's a pending connection attempt, false otherwise
2987
- */
2988
- function hasSocialConnectAttempt(provider) {
2989
- return sessionStorage.getItem(socialStoragePath(provider)) === "true";
2990
- }
2991
- /**
2992
- * Clears the social provider connection attempt flag
2993
- * @param provider The provider identifier
2994
- */
2995
- function clearSocialConnectAttempt(provider) {
2996
- sessionStorage.removeItem(socialStoragePath(provider));
2997
- }
2998
-
2999
- //#endregion
3000
- //#region src/auth/api/error-handlers.ts
3001
- /**
3002
- * Helper to create error functions - reduces bundle size by reusing error creation logic
3003
- */
3004
- const err = (message) => () => new Error(message);
3005
- /** Reusable error handlers for common cases - reduces repetitive error messages */
3006
- const commonErrors = {
3007
- unauthorized: err("User is not authorized"),
3008
- badRequest: err("Bad request"),
3009
- notFound: err("Not found"),
3010
- conflict: err("Resource already exists"),
3011
- forbidden: err("Forbidden"),
3012
- tooManyRequests: err("Too many requests")
3013
- };
3014
- /**
3015
- * Standard error handler for API errors with custom status code handling
3016
- */
3017
- const handleApiError = (error, statusHandlers) => {
3018
- if (error instanceof ApiError) {
3019
- const handler = statusHandlers[error.status];
3020
- if (handler) throw new ApiError(handler().message, error.status, error.endpoint, error.data);
3021
- throw error;
3022
- }
3023
- throw error;
3024
- };
2911
+ throw error;
2912
+ };
3025
2913
 
3026
2914
  //#endregion
3027
2915
  //#region src/auth/api/utils.ts
@@ -3169,55 +3057,493 @@ const listSocials = async () => {
3169
3057
  });
3170
3058
  }, { [HTTP_STATUS.UNAUTHORIZED]: () => /* @__PURE__ */ new Error("User is not authorized to list providers!") });
3171
3059
  };
3172
- const connectSocialInternal = async (provider, token) => {
3173
- return apiCall(async () => {
3174
- const requestBody = validateInput(ConnectProviderSchema, {
3175
- provider,
3176
- token
3177
- });
3178
- const { data } = await authV1ProvidersServiceConnectProvider({
3179
- body: {
3180
- provider: toProtoProvider(normalizeProviderType(requestBody.provider)),
3181
- token: requestBody.token
3182
- },
3183
- throwOnError: true
3184
- });
3185
- persistTokens(data);
3186
- }, { [HTTP_STATUS.UNAUTHORIZED]: () => /* @__PURE__ */ new Error("User is not authorized to connect provider!") });
3060
+ const connectSocialInternal = async (provider, token) => {
3061
+ return apiCall(async () => {
3062
+ const requestBody = validateInput(ConnectProviderSchema, {
3063
+ provider,
3064
+ token
3065
+ });
3066
+ const sessionToken = await getToken();
3067
+ const headers = sessionToken ? { Authorization: `Bearer ${sessionToken}` } : {};
3068
+ const { data } = await authV1ProvidersServiceConnectProvider({
3069
+ body: {
3070
+ provider: toProtoProvider(normalizeProviderType(requestBody.provider)),
3071
+ token: requestBody.token
3072
+ },
3073
+ headers,
3074
+ throwOnError: true
3075
+ });
3076
+ persistTokens(data);
3077
+ }, { [HTTP_STATUS.UNAUTHORIZED]: () => /* @__PURE__ */ new Error("User is not authorized to connect provider!") });
3078
+ };
3079
+ const disconnectSocial = async (provider) => {
3080
+ return apiCall(async () => {
3081
+ await authV1ProvidersServiceDisconnectProvider({
3082
+ path: { provider: toProtoProvider(provider) },
3083
+ throwOnError: true
3084
+ });
3085
+ }, {
3086
+ [HTTP_STATUS.UNAUTHORIZED]: () => /* @__PURE__ */ new Error("User is not authorized to disconnect provider!"),
3087
+ [HTTP_STATUS.NOT_FOUND]: () => /* @__PURE__ */ new Error("Provider not found!"),
3088
+ [HTTP_STATUS.BAD_REQUEST]: () => /* @__PURE__ */ new Error("Cannot disconnect the last social provider!")
3089
+ });
3090
+ };
3091
+ const connectSocial = (provider) => {
3092
+ setSocialConnectAttempt(provider);
3093
+ login(provider);
3094
+ };
3095
+
3096
+ //#endregion
3097
+ //#region src/auth/api/refresh-tokens.ts
3098
+ /**
3099
+ * Exchange a provider credential for a Rixl session, or refresh an existing
3100
+ * Rixl session with a Bearer refresh token.
3101
+ *
3102
+ * - For `AuthProvider.BEARER`, the call hits `/auth/v1/token` with the stored
3103
+ * Rixl refresh token.
3104
+ * - For OAuth/Telegram providers, the call hits `/auth/v1/providers/connect`
3105
+ * with the provider's `id_token` or Telegram payload. The wire `provider`
3106
+ * value is the `auth.v1.ExternalAccountProvider` enum (e.g.
3107
+ * `EXTERNAL_ACCOUNT_PROVIDER_GOOGLE`), not the short SDK name.
3108
+ */
3109
+ const refreshTokens = async (provider, token, options) => {
3110
+ if (provider === "Bearer") {
3111
+ const { data } = await authV1TokenServiceRefreshToken({
3112
+ body: {
3113
+ token_type: "Bearer",
3114
+ refresh_token: token,
3115
+ country_code: options?.countryCode,
3116
+ origin: options?.origin
3117
+ },
3118
+ throwOnError: true
3119
+ });
3120
+ return data;
3121
+ }
3122
+ const requestProvider = normalizeProviderType(provider);
3123
+ const { data } = await authV1ProvidersServiceConnectProvider({
3124
+ body: {
3125
+ provider: toProtoProvider(requestProvider),
3126
+ token,
3127
+ country_code: options?.countryCode,
3128
+ origin: options?.origin
3129
+ },
3130
+ throwOnError: true
3131
+ });
3132
+ return data;
3133
+ };
3134
+
3135
+ //#endregion
3136
+ //#region src/auth/cookie/util.ts
3137
+ const splitOnFirstEquals = (pair) => {
3138
+ const trimmed = pair.trim();
3139
+ const separator = trimmed.indexOf("=");
3140
+ return separator === -1 ? [trimmed, ""] : [trimmed.slice(0, separator), trimmed.slice(separator + 1).trim()];
3141
+ };
3142
+ const getAllCookiesStartWith = (startWithKey) => {
3143
+ if (typeof document === "undefined") return {};
3144
+ return document.cookie.split(";").map(splitOnFirstEquals).filter(([key]) => key && key !== startWithKey && key.startsWith(startWithKey)).reduce((ac, [key, value]) => Object.assign(ac, { [key.slice(startWithKey.length + 1)]: value }), {});
3145
+ };
3146
+ function setCookie(name, value, options) {
3147
+ if (typeof document === "undefined") return;
3148
+ let cookieString = `${encodeName(name)}=${encodeValue(value)}`;
3149
+ if (options) {
3150
+ if (options.expires) {
3151
+ if (typeof options.expires === "number") {
3152
+ const date = /* @__PURE__ */ new Date();
3153
+ date.setTime(date.getTime() + options.expires * 24 * 60 * 60 * 1e3);
3154
+ cookieString += `; expires=${date.toUTCString()}`;
3155
+ } else cookieString += `; expires=${options.expires.toUTCString()}`;
3156
+ }
3157
+ if (options.path) cookieString += `; path=${options.path}`;
3158
+ if (options.domain) cookieString += `; domain=${options.domain}`;
3159
+ if (options.secure) cookieString += `; secure`;
3160
+ if (options.sameSite) cookieString += `; samesite=${options.sameSite}`;
3161
+ }
3162
+ document.cookie = cookieString;
3163
+ }
3164
+ function deleteCookie(name) {
3165
+ if (typeof document === "undefined") return;
3166
+ document.cookie = name + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
3167
+ }
3168
+ const encodeName = (name) => encodeURIComponent(name).replace(/%(2[346B]|5E|60|7C)/g, decodeURIComponent);
3169
+ const encodeValue = (value) => encodeURIComponent(value).replace(/%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g, decodeURIComponent);
3170
+
3171
+ //#endregion
3172
+ //#region src/auth/cookie/index.ts
3173
+ const initVals = getAllCookiesStartWith(GLOBAL_PREFIX);
3174
+ const setStoreCookie = (key, value) => {
3175
+ const expires = /* @__PURE__ */ new Date();
3176
+ expires.setTime(expires.getTime() + 30 * 24 * 60 * 60 * 1e3);
3177
+ const cookieKey = `${GLOBAL_PREFIX}_${key}`;
3178
+ if (!value || value === "") {
3179
+ deleteCookie(cookieKey);
3180
+ return;
3181
+ }
3182
+ const stringValue = typeof value === "string" ? value : JSON.stringify(value);
3183
+ setCookie(`${GLOBAL_PREFIX}_${key}`, stringValue, {
3184
+ expires,
3185
+ path: "/",
3186
+ sameSite: "Lax"
3187
+ });
3188
+ };
3189
+
3190
+ //#endregion
3191
+ //#region src/auth/userStore.ts
3192
+ const userPath = GLOBAL_PREFIX + "_user";
3193
+ const parseUser = () => {
3194
+ if (typeof localStorage === "undefined" || !localStorage || typeof localStorage.getItem !== "function") return;
3195
+ const value = localStorage.getItem(userPath);
3196
+ if (value && value != "undefined") try {
3197
+ return JSON.parse(value);
3198
+ } catch (err) {
3199
+ console.warn("Can't parse user data, error: ", err);
3200
+ return;
3201
+ }
3202
+ };
3203
+ const user = shared("user", () => {
3204
+ const store = atom(parseUser());
3205
+ store.subscribe((value) => {
3206
+ if (typeof localStorage === "undefined" || !localStorage || typeof localStorage.setItem !== "function") return;
3207
+ if (value) localStorage.setItem(userPath, JSON.stringify(value));
3208
+ else localStorage.removeItem(userPath);
3209
+ });
3210
+ return store;
3211
+ });
3212
+
3213
+ //#endregion
3214
+ //#region src/auth/utils/jwt.ts
3215
+ /**
3216
+ * Decodes a JWT token and extracts user information
3217
+ * Uses jose library for modern, secure JWT handling
3218
+ * @param token The JWT token to decode
3219
+ * @returns The decoded user data or undefined if decoding fails
3220
+ */
3221
+ const decodeToken = (token) => {
3222
+ try {
3223
+ const decodedUser = decodeJwt(token);
3224
+ return {
3225
+ id: decodedUser.id,
3226
+ email: decodedUser.email,
3227
+ first_name: decodedUser.first_name,
3228
+ last_name: decodedUser.last_name,
3229
+ username: decodedUser.username,
3230
+ image_url: decodedUser.image_url,
3231
+ language_code: decodedUser.language_code,
3232
+ org_id: decodedUser.org_id
3233
+ };
3234
+ } catch (error) {
3235
+ console.warn("Failed to decode JWT token. Error: ", error);
3236
+ return;
3237
+ }
3238
+ };
3239
+ /**
3240
+ * Decodes a JWT token and sets the user in the store
3241
+ * @param token The JWT token to decode
3242
+ * @returns True if user was successfully decoded and set, false otherwise
3243
+ */
3244
+ const decodeAndSetUser = (token) => {
3245
+ const userData = decodeToken(token);
3246
+ if (userData) {
3247
+ user.set(userData);
3248
+ return true;
3249
+ }
3250
+ return false;
3251
+ };
3252
+ /**
3253
+ * Checks if a token is expired based on the expiration timestamp
3254
+ * @param expireAt The expiration timestamp in milliseconds
3255
+ * @returns True if the token is expired, false otherwise
3256
+ */
3257
+ const isTokenExpired = (expireAt) => {
3258
+ if (!expireAt) return true;
3259
+ return Date.now() >= expireAt;
3260
+ };
3261
+
3262
+ //#endregion
3263
+ //#region src/auth/authStore.ts
3264
+ const isLogged = shared("isLogged", () => atom(initVals["isLogged"] === "true"));
3265
+ const accessToken = shared("accessToken", () => atom(initVals["accessToken"]));
3266
+ const refreshToken = shared("refreshToken", () => atom(initVals["refreshToken"]));
3267
+ const expireAt = shared("expireAt", () => atom(Number(initVals["expireAt"])));
3268
+ const authError = shared("authError", () => atom(null));
3269
+ const requiresAction = shared("requiresAction", () => atom(initVals["requiresAction"] || null));
3270
+ const limitedAccessToken = shared("limitedAccessToken", () => atom(initVals["limitedAccessToken"] || null));
3271
+ const inFlight = shared("getTokenPromise", () => ({ promise: null }));
3272
+ const PROVIDER_URL_MAP = {
3273
+ google: googleAuthUrl,
3274
+ apple: appleAuthUrl,
3275
+ microsoft: microsoftAuthUrl,
3276
+ telegram: telegramAuthUrl
3277
+ };
3278
+ const login = async (provider) => {
3279
+ await initDeferred.promise;
3280
+ const authUrlAtom = PROVIDER_URL_MAP[provider];
3281
+ if (!authUrlAtom) throw new Error(`Unsupported provider: ${provider}`);
3282
+ const authUrl = authUrlAtom.get();
3283
+ if (authUrl) window.location.href = authUrl;
3284
+ else throw new Error(`${provider} provider is not configured. Please check your initClient configuration.`);
3285
+ };
3286
+ const refreshAccessToken = async (refresh) => {
3287
+ const result = await refreshTokens("Bearer", refresh);
3288
+ if (!("requires_action" in result)) setTokens(result.access_token, result.refresh_token, result.expires_in);
3289
+ };
3290
+ const ensureValidAccessToken = async (refresh) => {
3291
+ if (accessToken.get() && !isTokenExpired(expireAt.get())) return;
3292
+ try {
3293
+ await refreshAccessToken(refresh);
3294
+ } catch (refreshError) {
3295
+ console.error("Token refresh failed in getToken:", refreshError);
3296
+ removeTokens();
3297
+ throw refreshError;
3298
+ }
3299
+ };
3300
+ const getToken = async () => {
3301
+ if (inFlight.promise) return inFlight.promise;
3302
+ inFlight.promise = (async () => {
3303
+ try {
3304
+ await initDeferred.promise;
3305
+ if (requiresAction.get()) return void 0;
3306
+ const currentRefreshToken = refreshToken.get();
3307
+ if (!currentRefreshToken) return void 0;
3308
+ await ensureValidAccessToken(currentRefreshToken);
3309
+ const token = accessToken.get();
3310
+ if (token) decodeAndSetUser(token);
3311
+ return token;
3312
+ } catch (error) {
3313
+ console.warn("Failed to getToken(). Error: ", error);
3314
+ throw error;
3315
+ } finally {
3316
+ inFlight.promise = null;
3317
+ }
3318
+ })();
3319
+ return inFlight.promise;
3320
+ };
3321
+ /**
3322
+ * Sets authentication tokens in the store
3323
+ * @param access The access token
3324
+ * @param refresh The refresh token
3325
+ * @param expiresIn The token expiration time in seconds
3326
+ */
3327
+ const setTokens = (access, refresh, expiresIn) => {
3328
+ accessToken.set(access);
3329
+ refreshToken.set(refresh);
3330
+ expireAt.set(Date.now() + expiresIn * 1e3);
3331
+ isLogged.set(true);
3332
+ limitedAccessToken.set(null);
3333
+ requiresAction.set(null);
3334
+ authError.set(null);
3335
+ decodeAndSetUser(access);
3336
+ };
3337
+ /**
3338
+ * Removes authentication tokens from the store
3339
+ */
3340
+ const removeTokens = () => {
3341
+ accessToken.set("");
3342
+ refreshToken.set("");
3343
+ expireAt.set(0);
3344
+ isLogged.set(false);
3345
+ user.set(void 0);
3346
+ limitedAccessToken.set(null);
3347
+ requiresAction.set(null);
3348
+ authError.set(null);
3187
3349
  };
3188
- const disconnectSocial = async (provider) => {
3189
- return apiCall(async () => {
3190
- await authV1ProvidersServiceDisconnectProvider({
3191
- path: { provider: toProtoProvider(provider) },
3192
- throwOnError: true
3193
- });
3194
- }, {
3195
- [HTTP_STATUS.UNAUTHORIZED]: () => /* @__PURE__ */ new Error("User is not authorized to disconnect provider!"),
3196
- [HTTP_STATUS.NOT_FOUND]: () => /* @__PURE__ */ new Error("Provider not found!"),
3197
- [HTTP_STATUS.BAD_REQUEST]: () => /* @__PURE__ */ new Error("Cannot disconnect the last social provider!")
3198
- });
3350
+ /**
3351
+ * Clears the auth error from the store
3352
+ */
3353
+ const clearAuthError = () => {
3354
+ authError.set(null);
3199
3355
  };
3200
- const connectSocial = (provider) => {
3201
- setSocialConnectAttempt(provider);
3202
- login(provider);
3356
+ /**
3357
+ * Sets limited access state for users requiring additional action (e.g., Telegram users without email)
3358
+ * @param token The limited scope access token
3359
+ * @param action The required action (e.g., "add_email")
3360
+ */
3361
+ const setLimitedAccessState = (token, action) => {
3362
+ limitedAccessToken.set(token);
3363
+ requiresAction.set(action);
3364
+ authError.set(null);
3365
+ isLogged.set(true);
3203
3366
  };
3367
+ /**
3368
+ * Clears the limited access state (after email verification completes or user logs out)
3369
+ */
3370
+ const clearLimitedAccessState = () => {
3371
+ limitedAccessToken.set(null);
3372
+ requiresAction.set(null);
3373
+ if (!(!!accessToken.get() && !!refreshToken.get())) isLogged.set(false);
3374
+ };
3375
+ isLogged.subscribe((value) => setStoreCookie("isLogged", value));
3376
+ accessToken.subscribe((value) => setStoreCookie("accessToken", value));
3377
+ refreshToken.subscribe((value) => setStoreCookie("refreshToken", value));
3378
+ expireAt.subscribe((value) => setStoreCookie("expireAt", value));
3379
+ requiresAction.subscribe((value) => setStoreCookie("requiresAction", value));
3380
+ limitedAccessToken.subscribe((value) => setStoreCookie("limitedAccessToken", value));
3204
3381
 
3205
3382
  //#endregion
3206
- //#region src/auth/api/client-core.ts
3207
- let tokenRefreshFunction = null;
3383
+ //#region src/auth/api-url.ts
3208
3384
  /**
3209
- * Sets the token refresh function used by the API client
3210
- * This should be called during initialization
3385
+ * Global API base URL store
3211
3386
  */
3212
- const setTokenRefreshFunction = (fn) => {
3213
- tokenRefreshFunction = fn ?? null;
3214
- };
3387
+ const apiURL = shared("apiURL", () => atom(""));
3388
+
3389
+ //#endregion
3390
+ //#region src/auth/api/sdk-client.ts
3391
+ function isWireErrorBody(error) {
3392
+ return typeof error === "object" && error !== null;
3393
+ }
3394
+ const state = shared("sdkClientState", () => ({
3395
+ configured: false,
3396
+ tokenResolver: getToken
3397
+ }));
3398
+ function setTokenResolver(resolver) {
3399
+ state.tokenResolver = resolver;
3400
+ }
3401
+ /**
3402
+ * Routes that do not require a Bearer token at the gateway edge. These
3403
+ * authenticate via credentials in the request body (or are webhooks verified by
3404
+ * signature), so attaching an Authorization header here would make the gateway
3405
+ * attempt to validate a stale/absent token and reject the request with 401.
3406
+ * Mirrors `publicRoutes` in backend/gateway/internal/routes/routes.go.
3407
+ */
3408
+ const publicRoutes = [
3409
+ {
3410
+ method: "POST",
3411
+ path: "/auth/v1/token"
3412
+ },
3413
+ {
3414
+ method: "POST",
3415
+ path: "/auth/v1/register"
3416
+ },
3417
+ {
3418
+ method: "POST",
3419
+ path: "/auth/v1/login"
3420
+ },
3421
+ {
3422
+ method: "POST",
3423
+ path: "/auth/v1/email/verify"
3424
+ },
3425
+ {
3426
+ method: "POST",
3427
+ path: "/auth/v1/email/verify/resend"
3428
+ },
3429
+ {
3430
+ method: "POST",
3431
+ path: "/auth/v1/password/reset"
3432
+ },
3433
+ {
3434
+ method: "POST",
3435
+ path: "/auth/v1/password/reset/confirm"
3436
+ },
3437
+ {
3438
+ method: "POST",
3439
+ path: "/auth/v1/verify-totp"
3440
+ },
3441
+ {
3442
+ method: "POST",
3443
+ path: "/auth/v1/verify-passkey"
3444
+ },
3445
+ {
3446
+ method: "POST",
3447
+ path: "/auth/v1/invitations/",
3448
+ prefix: true
3449
+ },
3450
+ {
3451
+ method: "POST",
3452
+ path: "/auth/v1/passkey/login/begin"
3453
+ },
3454
+ {
3455
+ method: "POST",
3456
+ path: "/auth/v1/passkey/login/finish"
3457
+ },
3458
+ {
3459
+ method: "POST",
3460
+ path: "/auth/v1/logout"
3461
+ },
3462
+ {
3463
+ method: "POST",
3464
+ path: "/auth/v1/providers/connect"
3465
+ },
3466
+ {
3467
+ method: "POST",
3468
+ path: "/auth/v1/blog/unsubscribe/email"
3469
+ },
3470
+ {
3471
+ method: "POST",
3472
+ path: "/auth/v1/blog/broadcast"
3473
+ },
3474
+ {
3475
+ method: "GET",
3476
+ path: "/media/v1/videos/",
3477
+ prefix: true
3478
+ },
3479
+ {
3480
+ method: "GET",
3481
+ path: "/media/v1/images/",
3482
+ prefix: true
3483
+ },
3484
+ {
3485
+ method: "GET",
3486
+ path: "/media/v1/languages"
3487
+ },
3488
+ {
3489
+ method: "GET",
3490
+ path: "/posts/v1/feeds/",
3491
+ prefix: true
3492
+ },
3493
+ {
3494
+ method: "POST",
3495
+ path: "/billing/webhooks/stripe"
3496
+ },
3497
+ {
3498
+ method: "POST",
3499
+ path: "/webhooks/storage"
3500
+ },
3501
+ {
3502
+ method: "POST",
3503
+ path: "/platform/auth/v1/token"
3504
+ },
3505
+ {
3506
+ method: "POST",
3507
+ path: "/platform/auth/v1/refresh"
3508
+ }
3509
+ ];
3510
+ function isPublicRoute(method, pathname) {
3511
+ const match = method.toUpperCase();
3512
+ return publicRoutes.some(({ method: m, path, prefix }) => match === m && (prefix ? pathname.startsWith(path) : pathname === path));
3513
+ }
3514
+ function configureSdkClient() {
3515
+ if (state.configured) return;
3516
+ state.configured = true;
3517
+ configureAllClients(apiURL.get());
3518
+ apiURL.subscribe((url) => {
3519
+ configureAllClients(url);
3520
+ });
3521
+ addClientInitializer((client) => {
3522
+ client.interceptors.request.use(async (request) => {
3523
+ if (request.headers.has("Authorization")) return request;
3524
+ const { pathname } = new URL(request.url);
3525
+ if (isPublicRoute(request.method, pathname)) return request;
3526
+ const token = await state.tokenResolver();
3527
+ if (!token) throw new ApiError("No access token available for an authenticated request", HTTP_STATUS.UNAUTHORIZED, pathname);
3528
+ request.headers.set("Authorization", `Bearer ${token}`);
3529
+ return request;
3530
+ });
3531
+ client.interceptors.error.use((error, response, request) => {
3532
+ if (error instanceof Error) return error;
3533
+ const body = isWireErrorBody(error) ? error : void 0;
3534
+ const status = response?.status ?? body?.code ?? 0;
3535
+ const message = body?.error || body?.details || (typeof error === "string" ? error : "Request failed");
3536
+ const endpoint = request ? new URL(request.url).pathname : "";
3537
+ return new ApiError(message, status, endpoint, error);
3538
+ });
3539
+ });
3540
+ }
3215
3541
 
3216
3542
  //#endregion
3217
3543
  //#region src/auth/authConfig.ts
3218
- let loginRedirectUrl;
3544
+ const config = shared("authConfig", () => ({ loginRedirectUrl: void 0 }));
3219
3545
  const setLoginRedirectUrl = (url) => {
3220
- loginRedirectUrl = url;
3546
+ config.loginRedirectUrl = url;
3221
3547
  };
3222
3548
 
3223
3549
  //#endregion
@@ -3228,24 +3554,26 @@ const setLoginRedirectUrl = (url) => {
3228
3554
  * @returns A promise that resolves to the current access token (if available)
3229
3555
  */
3230
3556
  const initClient = async (config) => {
3231
- await initConfig(config);
3232
- await initPage();
3233
- initDeferred.resolve();
3234
- await initSocials();
3557
+ try {
3558
+ await runInitSequence(config);
3559
+ } finally {
3560
+ completeOAuthCallback();
3561
+ }
3235
3562
  return getToken();
3236
3563
  };
3564
+ const runInitSequence = async (config) => {
3565
+ try {
3566
+ await initConfig(config);
3567
+ await initPage();
3568
+ } finally {
3569
+ initDeferred.resolve();
3570
+ }
3571
+ await initSocials();
3572
+ };
3237
3573
  const initConfig = async (config) => {
3238
3574
  apiURL.set(config.apiUrl);
3239
3575
  configureSdkClient();
3240
3576
  setLoginRedirectUrl(config.loginRedirectUrl);
3241
- setTokenRefreshFunction(async () => {
3242
- const currentRefreshToken = refreshToken.get();
3243
- if (currentRefreshToken) {
3244
- const result = await refreshTokens("Bearer", currentRefreshToken);
3245
- if (result && !("requires_action" in result)) setTokens(result.access_token, result.refresh_token, result.expires_in);
3246
- return getToken();
3247
- }
3248
- });
3249
3577
  if (config.googleProvider) {
3250
3578
  googleConfig.set(config.googleProvider);
3251
3579
  updateGoogleAuthUrl();
@@ -3293,9 +3621,15 @@ const extractAuthErrorInfo = (error) => {
3293
3621
  };
3294
3622
  const handleInitPageApiError = (error) => {
3295
3623
  const info = extractAuthErrorInfo(error);
3296
- if (error.status === HTTP_STATUS.BAD_REQUEST && info.error === "invalid_grant") return setAuthErrorAndClear("email_not_verified", info.description, info.email);
3297
- if (error.status === HTTP_STATUS.CONFLICT) return setAuthErrorAndClear("provider_conflict", info.description, info.email);
3298
- return false;
3624
+ if (error.status === HTTP_STATUS.BAD_REQUEST && info.error === "invalid_grant") {
3625
+ setAuthErrorAndClear("email_not_verified", info.description, info.email);
3626
+ return;
3627
+ }
3628
+ if (error.status === HTTP_STATUS.CONFLICT) {
3629
+ setAuthErrorAndClear("provider_conflict", info.description, info.email);
3630
+ return;
3631
+ }
3632
+ setAuthErrorAndClear("provider_exchange_failed", info.error || info.description, info.email);
3299
3633
  };
3300
3634
  const exchangeProviderToken = async (provider, token) => {
3301
3635
  const result = await refreshTokens(provider, token);
@@ -3303,14 +3637,18 @@ const exchangeProviderToken = async (provider, token) => {
3303
3637
  };
3304
3638
  const initPage = async () => {
3305
3639
  const provider = detectProvider();
3306
- if (!provider) return void 0;
3640
+ if (!provider) {
3641
+ if (hasProviderResponse()) logUnusableProviderResponse();
3642
+ return;
3643
+ }
3307
3644
  const token = getProviderToken(provider);
3308
3645
  if (!token) return void 0;
3309
3646
  try {
3310
3647
  await exchangeProviderToken(provider, token);
3311
3648
  } catch (error) {
3312
- if (error instanceof ApiError && handleInitPageApiError(error)) return;
3313
- throw error;
3649
+ logProviderExchangeFailure(provider, token, error);
3650
+ if (!(error instanceof ApiError)) throw error;
3651
+ handleInitPageApiError(error);
3314
3652
  }
3315
3653
  };
3316
3654
  const initSocials = async () => {
@@ -3734,8 +4072,9 @@ const getUserInfo = async (userId) => {
3734
4072
  };
3735
4073
  const updateFullName = async (fullName) => {
3736
4074
  return apiCall(async () => {
4075
+ const validatedInput = validateInput(UpdateNameSchema, { full_name: fullName });
3737
4076
  await authV1UserServiceUpdateName({
3738
- body: validateInput(UpdateNameSchema, { full_name: fullName }),
4077
+ body: validatedInput,
3739
4078
  throwOnError: true
3740
4079
  });
3741
4080
  }, {
@@ -3746,8 +4085,9 @@ const updateFullName = async (fullName) => {
3746
4085
  };
3747
4086
  const updateUsername = async (username) => {
3748
4087
  return apiCall(async () => {
4088
+ const validatedInput = validateInput(UpdateUsernameSchema, { username });
3749
4089
  await authV1UserServiceUpdateUsername({
3750
- body: validateInput(UpdateUsernameSchema, { username }),
4090
+ body: validatedInput,
3751
4091
  throwOnError: true
3752
4092
  });
3753
4093
  }, {
@@ -3777,8 +4117,9 @@ const setupUserOTP = async () => {
3777
4117
  };
3778
4118
  const verifyUserOTP = async (code) => {
3779
4119
  return apiCall(async () => {
4120
+ const validatedBody = validateInput(VerifyOTPCodeSchema, { code });
3780
4121
  const { data } = await authV1OtpServiceVerifyOtp({
3781
- body: validateInput(VerifyOTPCodeSchema, { code }),
4122
+ body: validatedBody,
3782
4123
  throwOnError: true
3783
4124
  });
3784
4125
  persistTokens(data);
@@ -3861,11 +4202,12 @@ const loginWithEmail = async (email, password) => {
3861
4202
  };
3862
4203
  const verifyTOTPForLogin = async (code, session_id) => {
3863
4204
  return apiCall(async () => {
4205
+ const validatedInput = validateInput(LoginOTPVerifyRequestSchema, {
4206
+ code,
4207
+ session_id
4208
+ });
3864
4209
  const { data } = await authV1OtpServiceVerifyTotpForLogin({
3865
- body: validateInput(LoginOTPVerifyRequestSchema, {
3866
- code,
3867
- session_id
3868
- }),
4210
+ body: validatedInput,
3869
4211
  throwOnError: true
3870
4212
  });
3871
4213
  persistTokens(data);
@@ -3916,13 +4258,14 @@ function isApiErrorBody(error) {
3916
4258
  //#region src/auth/auth/register.ts
3917
4259
  const registerWithEmail = async (email, password, subscribeToBlog, countryCode) => {
3918
4260
  return apiCall(async () => {
4261
+ const validatedInput = validateInput(RegisterRequestSchema, {
4262
+ email,
4263
+ password,
4264
+ country_code: countryCode,
4265
+ subscribe_to_blog: subscribeToBlog
4266
+ });
3919
4267
  const { data } = await authV1EmailServiceRegister({
3920
- body: validateInput(RegisterRequestSchema, {
3921
- email,
3922
- password,
3923
- country_code: countryCode,
3924
- subscribe_to_blog: subscribeToBlog
3925
- }),
4268
+ body: validatedInput,
3926
4269
  throwOnError: true
3927
4270
  });
3928
4271
  if (data.verification_id) return {
@@ -3935,8 +4278,9 @@ const registerWithEmail = async (email, password, subscribeToBlog, countryCode)
3935
4278
  };
3936
4279
  const resendEmailVerificationCode = async (email) => {
3937
4280
  return apiCall(async () => {
4281
+ const validatedInput = validateInput(ResendEmailRequestSchema, { email });
3938
4282
  const { data } = await authV1EmailServiceResendVerification({
3939
- body: validateInput(ResendEmailRequestSchema, { email }),
4283
+ body: validatedInput,
3940
4284
  throwOnError: true
3941
4285
  });
3942
4286
  if (data.verification_id) return {
@@ -3954,19 +4298,21 @@ const resendEmailVerificationCode = async (email) => {
3954
4298
  //#region src/auth/auth/password.ts
3955
4299
  const sendPasswordResetEmail = async (email) => {
3956
4300
  return apiCall(async () => {
4301
+ const validatedInput = validateInput(ResendEmailRequestSchema, { email });
3957
4302
  await authV1EmailServiceSendPasswordReset({
3958
- body: validateInput(ResendEmailRequestSchema, { email }),
4303
+ body: validatedInput,
3959
4304
  throwOnError: true
3960
4305
  });
3961
4306
  }, { [HTTP_STATUS.BAD_REQUEST]: () => /* @__PURE__ */ new Error("Bad request - invalid email or validation error") });
3962
4307
  };
3963
4308
  const confirmPasswordReset = async (token, password) => {
3964
4309
  return apiCall(async () => {
4310
+ const validatedInput = validateInput(ResetPasswordRequestSchema, {
4311
+ token,
4312
+ new_password: password
4313
+ });
3965
4314
  await authV1EmailServiceResetPassword({
3966
- body: validateInput(ResetPasswordRequestSchema, {
3967
- token,
3968
- new_password: password
3969
- }),
4315
+ body: validatedInput,
3970
4316
  throwOnError: true
3971
4317
  });
3972
4318
  }, { [HTTP_STATUS.BAD_REQUEST]: () => /* @__PURE__ */ new Error("Bad request - invalid token or password") });
@@ -3976,8 +4322,9 @@ const confirmPasswordReset = async (token, password) => {
3976
4322
  //#region src/auth/auth/email.ts
3977
4323
  const initiateEmailChange = async (email) => {
3978
4324
  return apiCall(async () => {
4325
+ const validatedInput = validateInput(ChangeEmailRequestSchema, { new_email: email });
3979
4326
  const { data } = await authV1EmailServiceInitiateEmailChange({
3980
- body: validateInput(ChangeEmailRequestSchema, { new_email: email }),
4327
+ body: validatedInput,
3981
4328
  throwOnError: true
3982
4329
  });
3983
4330
  if (data.verification_id) return {
@@ -3994,8 +4341,9 @@ const initiateEmailChange = async (email) => {
3994
4341
  };
3995
4342
  const addEmail = async (email) => {
3996
4343
  return apiCall(async () => {
4344
+ const validatedInput = validateInput(ResendEmailRequestSchema, { email });
3997
4345
  const { data } = await authV1EmailServiceAddEmail({
3998
- body: validateInput(ResendEmailRequestSchema, { email }),
4346
+ body: validatedInput,
3999
4347
  throwOnError: true
4000
4348
  });
4001
4349
  if (data.verification_id) return {
@@ -4289,10 +4637,11 @@ function serializeRegistrationCredential(cred) {
4289
4637
  }
4290
4638
  const finishPasskeyLogin = async (session_id, credential) => {
4291
4639
  return apiCall(async () => {
4640
+ const serialized = serializeLoginCredential(credential);
4292
4641
  const { data } = await authV1PasskeyServicePasskeyLoginFinish({
4293
4642
  body: {
4294
4643
  session_id,
4295
- credential: serializeLoginCredential(credential)
4644
+ credential: serialized
4296
4645
  },
4297
4646
  throwOnError: true
4298
4647
  });
@@ -4332,11 +4681,12 @@ const beginPasskeyRegistration = async () => {
4332
4681
  };
4333
4682
  const finishPasskeyRegistration = async (session_id, name, credential) => {
4334
4683
  return apiCall(async () => {
4684
+ const serialized = serializeRegistrationCredential(credential);
4335
4685
  const { data } = await authV1PasskeyServicePasskeyRegisterFinish({
4336
4686
  body: {
4337
4687
  session_id,
4338
4688
  name,
4339
- credential: serializeRegistrationCredential(credential)
4689
+ credential: serialized
4340
4690
  },
4341
4691
  throwOnError: true
4342
4692
  });
@@ -4383,10 +4733,11 @@ const listPasskeys = async () => {
4383
4733
  };
4384
4734
  const verifyPasskeyForLogin = async (session_id, credential) => {
4385
4735
  return apiCall(async () => {
4736
+ const serialized = serializeLoginCredential(credential);
4386
4737
  const { data } = await authV1PasskeyServiceVerifyPasskeyForLogin({
4387
4738
  body: {
4388
4739
  session_id,
4389
- credential: serializeLoginCredential(credential)
4740
+ credential: serialized
4390
4741
  },
4391
4742
  throwOnError: true
4392
4743
  });
@@ -4399,5 +4750,5 @@ const verifyPasskeyForLogin = async (session_id, credential) => {
4399
4750
  };
4400
4751
 
4401
4752
  //#endregion
4402
- export { DomainStatus, MembershipRole, MembershipState, PasskeyUnavailableError, addEmail, analyticsV1DashboardServiceGetDashboardStats, analyticsV1DashboardServiceGetFilterOptions, analyticsV1DashboardServiceListDatasets, analyticsV1DashboardServiceQueryChart, analyticsV1EventsServiceTrackEvents, analyticsV1FeedsServiceGetFeedStats, analyticsV1FeedsServiceGetTopFeeds, analyticsV1FunnelsServiceGetFunnelAnalytics, analyticsV1FunnelsServiceGetRetentionAnalytics, analyticsV1HeatmapServiceGetHotSegments, analyticsV1HeatmapServiceGetVideoHeatmap, analyticsV1PostsServiceGetPostStats, analyticsV1PostsServiceGetTopPosts, analyticsV1RealtimeServiceGetRealtimeStats, analyticsV1VideosServiceGetTopVideos, analyticsV1VideosServiceGetVideoStats, apikeysV1ApiKeyServiceCreateApiKey, apikeysV1ApiKeyServiceDeleteApiKey, apikeysV1ApiKeyServiceListApiKeys, apikeysV1ApiKeyServiceRotateApiKey, authError, authV1BlogServiceGetBlogSubscription, authV1BlogServiceSendBlogBroadcast, authV1BlogServiceSubscribeBlog, authV1BlogServiceUnsubscribeBlog, authV1BlogServiceUnsubscribeBlogByEmail, authV1DomainServiceCheckDomainVerification, authV1DomainServiceCreateDomainVerification, authV1DomainServiceGetDomainAutoJoin, authV1DomainServiceGetDomainStatus, authV1DomainServiceRemoveDomain, authV1DomainServiceSetDomainAutoJoin, authV1EmailServiceAddEmail, authV1EmailServiceGetUserEmailStatus, authV1EmailServiceInitiateEmailChange, authV1EmailServiceLogin, authV1EmailServiceRegister, authV1EmailServiceResendVerification, authV1EmailServiceResetPassword, authV1EmailServiceSendPasswordReset, authV1EmailServiceVerifyEmail, authV1MembershipServiceAcceptInvitation, authV1MembershipServiceCancelInvitation, authV1MembershipServiceCheckMembership, authV1MembershipServiceDeclineInvitation, authV1MembershipServiceGetInternalMembershipInfo, authV1MembershipServiceInviteMember, authV1MembershipServiceLeaveOrganization, authV1MembershipServiceListMembershipApplications, authV1MembershipServiceListMemberships, authV1MembershipServiceListOrganizationMembers, authV1MembershipServiceReactivateMember, authV1MembershipServiceRemoveMember, authV1MembershipServiceResendInvitation, authV1MembershipServiceSuspendMember, authV1MembershipServiceUpdateActiveMembership, authV1MembershipServiceUpdateMemberRole, authV1MembershipServiceUpdateMembershipState, authV1MembershipServiceUpdateOrgName, authV1MembershipServiceUpdateOrgUsername, authV1OtpServiceDeleteOtp, authV1OtpServiceGetOtpStatus, authV1OtpServiceSetupOtp, authV1OtpServiceVerifyOtp, authV1OtpServiceVerifyTotpForLogin, authV1PasskeyServiceDeletePasskey, authV1PasskeyServiceListPasskeys, authV1PasskeyServicePasskeyLoginBegin, authV1PasskeyServicePasskeyLoginFinish, authV1PasskeyServicePasskeyRegisterBegin, authV1PasskeyServicePasskeyRegisterFinish, authV1PasskeyServiceRenamePasskey, authV1PasskeyServiceVerifyPasskeyForLogin, authV1PolicyServiceAttachPolicy, authV1PolicyServiceCreatePolicy, authV1PolicyServiceDeletePolicy, authV1PolicyServiceDetachPolicy, authV1PolicyServiceGetPolicy, authV1PolicyServiceListPermissionRegistry, authV1PolicyServiceListPolicies, authV1PolicyServiceListPolicyAttachments, authV1PolicyServiceListUserPolicies, authV1PolicyServiceUpdatePolicy, authV1ProvidersServiceConnectProvider, authV1ProvidersServiceDisconnectProvider, authV1ProvidersServiceListProviders, authV1TokenServiceLogout, authV1TokenServiceRefreshToken, authV1UserServiceGetUser, authV1UserServiceGetUserInfo, authV1UserServiceUpdateName, authV1UserServiceUpdateUsername, beginPasskeyLogin, beginPasskeyRegistration, billingV1InvoiceServiceListInvoices, billingV1InvoiceServiceUpdateInvoiceStatus, billingV1PaymentServiceCalculateGenericTax, billingV1PaymentServiceCalculateTax, billingV1PaymentServiceCreateCheckoutSession, billingV1PaymentServiceCreateSetupIntent, billingV1PaymentServiceDeletePaymentMethod, billingV1PaymentServiceGetBillingAddress, billingV1PaymentServiceGetPaymentMethodFromPaymentIntent, billingV1PaymentServiceGetPaymentMethodFromSetupIntent, billingV1PaymentServiceListPaymentMethods, billingV1PaymentServiceUpgradeSubscription, billingV1PaymentServiceUpsertBillingAddress, billingV1PaymentServiceUpsertPaymentMethod, billingV1PlanServiceGetPlan, billingV1PlanServiceListPlans, billingV1SalesServiceContactSales, billingV1SubscriptionServiceCancelSubscription, billingV1SubscriptionServiceCreateSubscription, billingV1SubscriptionServiceGetSubscription, billingV1SubscriptionServiceGetSubscriptionHistory, billingV1SubscriptionServiceReactivateSubscription, billingV1UsageServiceGetBandwidthUsage, billingV1UsageServiceGetBandwidthUsageHistory, billingV1UsageServiceGetStorageUsage, billingV1UsageServiceGetStorageUsageHistory, billingV1UsageServiceRefreshBandwidthUsage, billingV1UsageServiceRefreshStorageUsage, checkDomainVerification, clearAuthError, clearLimitedAccessState, client, clientauthV1ClientCredentialServiceCreateClientCredential, clientauthV1ClientCredentialServiceListClientCredentials, clientauthV1ClientCredentialServiceMintClientToken, clientauthV1ClientCredentialServiceRevokeClientCredential, confirmPasswordReset, connect, connectSocial, createClient, decodeRequestOptions, deleteMember, deletePasskey, deleteUserOTP, disconnectSocial, feedsV1FeedServiceCreateFeed, feedsV1FeedServiceDeleteFeed, feedsV1FeedServiceGetFeed, feedsV1FeedServiceListFeeds, feedsV1FeedServiceUpdateFeed, finishPasskeyLogin, finishPasskeyRegistration, getBlogSubscriptionStatus, getDomainStatus, getEmailVerificationStatus, getOTPStatus, getToken, getUserInfo, imagesV1ImageConversionServiceMarkImageFailed, imagesV1ImageConversionServiceMarkImageProcessed, imagesV1ImageConversionServiceTakeUnprocessedImage, imagesV1ImageServiceCreateImageUpload, imagesV1ImageServiceDeleteImage, imagesV1ImageServiceGetImage, imagesV1ImageServiceListImages, imagesV1ImageServiceUpdateImageVisibility, initClient, initiateDomainVerification, initiateEmailChange, inviteMember, isLogged, leaveOrganization, limitedAccessToken, listActiveMemberships, listOrganizationMembers, listPasskeys, listPendingMemberships, listSocials, login, loginWithEmail, logout, platformauthV1PlatformAuthServiceExchangeApiKey, platformauthV1PlatformAuthServiceRefreshPlatformToken, postsV1PostServiceCreatePost, postsV1PostServiceCreatePostUpload, postsV1PostServiceDeletePost, postsV1PostServiceDeletePost2, postsV1PostServiceGetPost, postsV1PostServiceGetPost2, postsV1PostServiceGetPost3, postsV1PostServiceListPosts, postsV1PostServiceListPosts2, postsV1PostServiceListPosts3, postsV1PostServiceListPosts4, projectV1ProjectServiceCreateProject, projectV1ProjectServiceDeleteProject, projectV1ProjectServiceGetProject, projectV1ProjectServiceListProjects, projectV1ProjectServiceMoveProject, projectV1ProjectServiceRemoveCustomDomain, projectV1ProjectServiceSetCustomDomain, projectV1ProjectServiceUpdateProjectName, projectV1ProjectServiceUpdateVideoQuality, publicRespondToInvitation, registerWithEmail, removeDomain, renamePasskey, requiresAction, resendEmailVerificationCode, resendMemberInvite, respondToInvitation, sendPasswordResetEmail, setLimitedAccessState, setupUserOTP, subscribeToBlog, unsubscribeFromBlog, updateActiveMembership, updateAutoJoin, updateFullName, updateMemberRole, updateOrgName, updateOrgUsername, updateUsername, user, verifyEmailWithCode, verifyPasskeyForLogin, verifyTOTPForLogin, verifyUserOTP, videosV1AudioTrackServiceCreateAudioTrackUpload, videosV1AudioTrackServiceDeleteAllAudioTracks, videosV1AudioTrackServiceDeleteAudioTrack, videosV1AudioTrackServiceDeleteAudioTracksByLanguage, videosV1AudioTrackServiceListAudioTracks, videosV1ChapterServiceDeleteVideoChapter, videosV1ChapterServiceGetVideoChapters, videosV1ChapterServiceUpdateVideoChapters, videosV1LanguageServiceListLanguages, videosV1SubtitleServiceCreateSubtitleUpload, videosV1SubtitleServiceDeleteAllSubtitles, videosV1SubtitleServiceDeleteSubtitle, videosV1SubtitleServiceDeleteSubtitlesByLanguage, videosV1SubtitleServiceListSubtitles, videosV1VideoConversionServiceMarkVideoFailed, videosV1VideoConversionServiceMarkVideoProcessed, videosV1VideoServiceCreateVideoUpload, videosV1VideoServiceDeleteVideo, videosV1VideoServiceGetVideo, videosV1VideoServiceListVideos, videosV1VideoServiceUpdateVideoVisibility };
4753
+ export { DomainStatus, MembershipRole, MembershipState, PasskeyUnavailableError, addEmail, analyticsV1DashboardServiceBatchQueryChart, analyticsV1DashboardServiceCreateDashboard, analyticsV1DashboardServiceCreateWidget, analyticsV1DashboardServiceDeleteDashboard, analyticsV1DashboardServiceDeleteWidget, analyticsV1DashboardServiceGetDashboard, analyticsV1DashboardServiceGetDashboardStats, analyticsV1DashboardServiceGetFilterOptions, analyticsV1DashboardServiceGetScopeTree, analyticsV1DashboardServiceListDashboards, analyticsV1DashboardServiceListDatasets, analyticsV1DashboardServiceQueryChart, analyticsV1DashboardServiceSetDefaultDashboard, analyticsV1DashboardServiceUpdateDashboard, analyticsV1DashboardServiceUpdateDashboardLayout, analyticsV1DashboardServiceUpdateWidget, analyticsV1EventsServiceTrackEvents, analyticsV1FeedsServiceGetFeedStats, analyticsV1FeedsServiceGetTopFeeds, analyticsV1FunnelsServiceGetFunnelAnalytics, analyticsV1FunnelsServiceGetRetentionAnalytics, analyticsV1HeatmapServiceGetHotSegments, analyticsV1HeatmapServiceGetVideoHeatmap, analyticsV1ImagesServiceGetImageStats, analyticsV1ImagesServiceGetTopImages, analyticsV1PostsServiceGetPostStats, analyticsV1PostsServiceGetTopPosts, analyticsV1RealtimeServiceGetRealtimeStats, analyticsV1VideosServiceGetTopVideos, analyticsV1VideosServiceGetVideoStats, apikeysV1ApiKeyServiceCreateApiKey, apikeysV1ApiKeyServiceDeleteApiKey, apikeysV1ApiKeyServiceListApiKeys, apikeysV1ApiKeyServiceRotateApiKey, authError, authV1BlogServiceGetBlogSubscription, authV1BlogServiceSendBlogBroadcast, authV1BlogServiceSubscribeBlog, authV1BlogServiceUnsubscribeBlog, authV1BlogServiceUnsubscribeBlogByEmail, authV1DomainServiceCheckDomainVerification, authV1DomainServiceCreateDomainVerification, authV1DomainServiceGetDomainAutoJoin, authV1DomainServiceGetDomainStatus, authV1DomainServiceRemoveDomain, authV1DomainServiceSetDomainAutoJoin, authV1EmailServiceAddEmail, authV1EmailServiceGetUserEmailStatus, authV1EmailServiceInitiateEmailChange, authV1EmailServiceLogin, authV1EmailServiceRegister, authV1EmailServiceResendVerification, authV1EmailServiceResetPassword, authV1EmailServiceSendPasswordReset, authV1EmailServiceVerifyEmail, authV1MembershipServiceAcceptInvitation, authV1MembershipServiceCancelInvitation, authV1MembershipServiceCheckMembership, authV1MembershipServiceDeclineInvitation, authV1MembershipServiceGetInternalMembershipInfo, authV1MembershipServiceInviteMember, authV1MembershipServiceLeaveOrganization, authV1MembershipServiceListMembershipApplications, authV1MembershipServiceListMemberships, authV1MembershipServiceListOrganizationMembers, authV1MembershipServiceReactivateMember, authV1MembershipServiceRemoveMember, authV1MembershipServiceResendInvitation, authV1MembershipServiceSuspendMember, authV1MembershipServiceUpdateActiveMembership, authV1MembershipServiceUpdateMemberRole, authV1MembershipServiceUpdateMembershipState, authV1MembershipServiceUpdateOrgName, authV1MembershipServiceUpdateOrgUsername, authV1OtpServiceDeleteOtp, authV1OtpServiceGetOtpStatus, authV1OtpServiceRegenerateBackupCodes, authV1OtpServiceSetupOtp, authV1OtpServiceVerifyOtp, authV1OtpServiceVerifyTotpForLogin, authV1PasskeyServiceDeletePasskey, authV1PasskeyServiceListPasskeys, authV1PasskeyServicePasskeyLoginBegin, authV1PasskeyServicePasskeyLoginFinish, authV1PasskeyServicePasskeyRegisterBegin, authV1PasskeyServicePasskeyRegisterFinish, authV1PasskeyServiceRenamePasskey, authV1PasskeyServiceVerifyPasskeyForLogin, authV1PolicyServiceAttachPolicy, authV1PolicyServiceCreatePolicy, authV1PolicyServiceDeletePolicy, authV1PolicyServiceDetachPolicy, authV1PolicyServiceGetPolicy, authV1PolicyServiceListPermissionRegistry, authV1PolicyServiceListPolicies, authV1PolicyServiceListPolicyAttachments, authV1PolicyServiceListUserPolicies, authV1PolicyServiceUpdatePolicy, authV1ProvidersServiceConnectProvider, authV1ProvidersServiceDisconnectProvider, authV1ProvidersServiceListProviders, authV1TokenServiceLogout, authV1TokenServiceRefreshToken, authV1UserServiceGetUser, authV1UserServiceGetUserInfo, authV1UserServiceUpdateName, authV1UserServiceUpdateUsername, beginPasskeyLogin, beginPasskeyRegistration, billingV1InvoiceServiceListInvoices, billingV1InvoiceServiceUpdateInvoiceStatus, billingV1PaymentServiceCalculateGenericTax, billingV1PaymentServiceCalculateTax, billingV1PaymentServiceCreateCheckoutSession, billingV1PaymentServiceCreateSetupIntent, billingV1PaymentServiceDeletePaymentMethod, billingV1PaymentServiceGetBillingAddress, billingV1PaymentServiceGetPaymentMethodFromPaymentIntent, billingV1PaymentServiceGetPaymentMethodFromSetupIntent, billingV1PaymentServiceListPaymentMethods, billingV1PaymentServiceUpgradeSubscription, billingV1PaymentServiceUpsertBillingAddress, billingV1PaymentServiceUpsertPaymentMethod, billingV1PlanServiceGetPlan, billingV1PlanServiceListPlans, billingV1SalesServiceContactSales, billingV1SubscriptionServiceCancelSubscription, billingV1SubscriptionServiceCreateSubscription, billingV1SubscriptionServiceGetSubscription, billingV1SubscriptionServiceGetSubscriptionHistory, billingV1SubscriptionServiceReactivateSubscription, billingV1UsageServiceGetBandwidthUsage, billingV1UsageServiceGetBandwidthUsageHistory, billingV1UsageServiceGetStorageUsage, billingV1UsageServiceGetStorageUsageHistory, billingV1UsageServiceRefreshBandwidthUsage, billingV1UsageServiceRefreshStorageUsage, checkDomainVerification, clearAuthError, clearLimitedAccessState, client, clientauthV1ClientCredentialServiceCreateClientCredential, clientauthV1ClientCredentialServiceListClientCredentials, clientauthV1ClientCredentialServiceMintClientToken, clientauthV1ClientCredentialServiceRevokeClientCredential, confirmPasswordReset, connect, connectSocial, createClient, decodeRequestOptions, deleteMember, deletePasskey, deleteUserOTP, disconnectSocial, feedsV1FeedServiceCreateFeed, feedsV1FeedServiceDeleteFeed, feedsV1FeedServiceGetFeed, feedsV1FeedServiceListFeeds, feedsV1FeedServiceUpdateFeed, finishPasskeyLogin, finishPasskeyRegistration, getBlogSubscriptionStatus, getDomainStatus, getEmailVerificationStatus, getOTPStatus, getToken, getUserInfo, imagesV1ImageConversionServiceMarkImageFailed, imagesV1ImageConversionServiceMarkImageProcessed, imagesV1ImageConversionServiceTakeUnprocessedImage, imagesV1ImageServiceCreateImageUpload, imagesV1ImageServiceDeleteImage, imagesV1ImageServiceGetImage, imagesV1ImageServiceListImages, imagesV1ImageServiceUpdateImageVisibility, initClient, initiateDomainVerification, initiateEmailChange, inviteMember, isLogged, leaveOrganization, limitedAccessToken, listActiveMemberships, listOrganizationMembers, listPasskeys, listPendingMemberships, listSocials, login, loginWithEmail, logout, platformauthV1PlatformAuthServiceExchangeApiKey, platformauthV1PlatformAuthServiceRefreshPlatformToken, postsV1PostServiceCreatePost, postsV1PostServiceCreatePostUpload, postsV1PostServiceDeletePost, postsV1PostServiceDeletePost2, postsV1PostServiceGetPost, postsV1PostServiceGetPost2, postsV1PostServiceGetPost3, postsV1PostServiceListPosts, postsV1PostServiceListPosts2, postsV1PostServiceListPosts3, postsV1PostServiceListPosts4, projectV1ProjectServiceCreateProject, projectV1ProjectServiceDeleteProject, projectV1ProjectServiceGetProject, projectV1ProjectServiceListProjects, projectV1ProjectServiceMoveProject, projectV1ProjectServiceRemoveCustomDomain, projectV1ProjectServiceSetCustomDomain, projectV1ProjectServiceUpdateProjectName, projectV1ProjectServiceUpdateVideoQuality, publicRespondToInvitation, registerWithEmail, removeDomain, renamePasskey, requiresAction, resendEmailVerificationCode, resendMemberInvite, respondToInvitation, sendPasswordResetEmail, setLimitedAccessState, setupUserOTP, subscribeToBlog, unsubscribeFromBlog, updateActiveMembership, updateAutoJoin, updateFullName, updateMemberRole, updateOrgName, updateOrgUsername, updateUsername, user, verifyEmailWithCode, verifyPasskeyForLogin, verifyTOTPForLogin, verifyUserOTP, videosV1AudioTrackServiceCreateAudioTrackUpload, videosV1AudioTrackServiceDeleteAllAudioTracks, videosV1AudioTrackServiceDeleteAudioTrack, videosV1AudioTrackServiceDeleteAudioTracksByLanguage, videosV1AudioTrackServiceListAudioTracks, videosV1ChapterServiceDeleteVideoChapter, videosV1ChapterServiceGetVideoChapters, videosV1ChapterServiceUpdateVideoChapters, videosV1LanguageServiceListLanguages, videosV1SubtitleServiceCreateSubtitleUpload, videosV1SubtitleServiceDeleteAllSubtitles, videosV1SubtitleServiceDeleteSubtitle, videosV1SubtitleServiceDeleteSubtitlesByLanguage, videosV1SubtitleServiceListSubtitles, videosV1VideoConversionServiceMarkVideoFailed, videosV1VideoConversionServiceMarkVideoProcessed, videosV1VideoServiceCreateVideoUpload, videosV1VideoServiceDeleteVideo, videosV1VideoServiceGetVideo, videosV1VideoServiceListVideos, videosV1VideoServiceUpdateVideoVisibility };
4403
4754
  //# sourceMappingURL=index.js.map