@hexclave/next 1.0.125 → 1.0.126

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.
Files changed (161) hide show
  1. package/dist/{admin-app-impl-Bxad6t8m.d.ts → admin-app-impl-CjDjJ3PS.d.ts} +29 -13
  2. package/dist/admin-app-impl-CjDjJ3PS.d.ts.map +1 -0
  3. package/dist/clickmap/clickmap-core.d.ts +1 -1
  4. package/dist/clickmap/index.d.ts +1 -1
  5. package/dist/{client-app-B0cTytS5.d.ts → client-app-jAjrgwSh.d.ts} +34 -6
  6. package/dist/client-app-jAjrgwSh.d.ts.map +1 -0
  7. package/dist/{common-B2gkWlXX.d.ts → common-BjAI7WW6.d.ts} +15 -3
  8. package/dist/common-BjAI7WW6.d.ts.map +1 -0
  9. package/dist/{common-BK_sydxF.d.ts → common-DWfeER0s.d.ts} +2 -2
  10. package/dist/{common-BK_sydxF.d.ts.map → common-DWfeER0s.d.ts.map} +1 -1
  11. package/dist/components/message-cards/predefined-message-card.js +4 -2
  12. package/dist/components/message-cards/predefined-message-card.js.map +1 -1
  13. package/dist/components/selected-team-switcher.d.ts +1 -1
  14. package/dist/components/team-icon.d.ts +1 -1
  15. package/dist/components/team-switcher.d.ts +1 -1
  16. package/dist/components/user-button.js +9 -9
  17. package/dist/components/user-button.js.map +1 -1
  18. package/dist/components/user-button.test.d.ts +1 -0
  19. package/dist/components/user-button.test.js +71 -0
  20. package/dist/components/user-button.test.js.map +1 -0
  21. package/dist/components-page/account-settings/payments/payments-page.d.ts +1 -1
  22. package/dist/components-page/account-settings/payments/payments-panel.d.ts +1 -1
  23. package/dist/components-page/account-settings/settings/sign-out-section.d.ts +1 -1
  24. package/dist/components-page/account-settings/settings/sign-out-section.d.ts.map +1 -1
  25. package/dist/components-page/account-settings/settings/sign-out-section.js +4 -1
  26. package/dist/components-page/account-settings/settings/sign-out-section.js.map +1 -1
  27. package/dist/components-page/account-settings/teams/leave-team-section.d.ts +1 -1
  28. package/dist/components-page/account-settings/teams/team-api-keys-section.d.ts +1 -1
  29. package/dist/components-page/account-settings/teams/team-display-name-section.d.ts +1 -1
  30. package/dist/components-page/account-settings/teams/team-member-invitation-section.d.ts +1 -1
  31. package/dist/components-page/account-settings/teams/team-member-list-section.d.ts +1 -1
  32. package/dist/components-page/account-settings/teams/team-page.d.ts +1 -1
  33. package/dist/components-page/account-settings/teams/team-profile-image-section.d.ts +1 -1
  34. package/dist/components-page/account-settings/teams/team-profile-user-section.d.ts +1 -1
  35. package/dist/components-page/hexclave-handler-client.d.ts +1 -1
  36. package/dist/components-page/hexclave-handler.d.ts +1 -1
  37. package/dist/components-page/onboarding.js +15 -13
  38. package/dist/components-page/onboarding.js.map +1 -1
  39. package/dist/components-page/onboarding.test.js +2 -1
  40. package/dist/components-page/onboarding.test.js.map +1 -1
  41. package/dist/dev-tool/dev-tool-core.d.ts +1 -1
  42. package/dist/dev-tool/index.d.ts +1 -1
  43. package/dist/esm/components/message-cards/predefined-message-card.js +4 -2
  44. package/dist/esm/components/message-cards/predefined-message-card.js.map +1 -1
  45. package/dist/esm/components/user-button.js +9 -9
  46. package/dist/esm/components/user-button.js.map +1 -1
  47. package/dist/esm/components/user-button.test.d.ts +1 -0
  48. package/dist/esm/components/user-button.test.js +70 -0
  49. package/dist/esm/components/user-button.test.js.map +1 -0
  50. package/dist/esm/components-page/account-settings/settings/sign-out-section.d.ts +1 -1
  51. package/dist/esm/components-page/account-settings/settings/sign-out-section.d.ts.map +1 -1
  52. package/dist/esm/components-page/account-settings/settings/sign-out-section.js +4 -1
  53. package/dist/esm/components-page/account-settings/settings/sign-out-section.js.map +1 -1
  54. package/dist/esm/components-page/onboarding.js +15 -13
  55. package/dist/esm/components-page/onboarding.js.map +1 -1
  56. package/dist/esm/components-page/onboarding.test.js +2 -1
  57. package/dist/esm/components-page/onboarding.test.js.map +1 -1
  58. package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +4 -4
  59. package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts.map +1 -1
  60. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.d.ts +18 -2
  61. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.d.ts.map +1 -1
  62. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.external-token-store.test.d.ts +1 -0
  63. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.external-token-store.test.js +382 -0
  64. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.external-token-store.test.js.map +1 -0
  65. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.init-analytics.test.d.ts +1 -0
  66. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.init-analytics.test.js +66 -0
  67. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.init-analytics.test.js.map +1 -0
  68. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js +66 -14
  69. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
  70. package/dist/esm/lib/hexclave-app/apps/implementations/common.js +2 -2
  71. package/dist/esm/lib/hexclave-app/apps/implementations/external-token-store-session-adapter.d.ts +31 -0
  72. package/dist/esm/lib/hexclave-app/apps/implementations/external-token-store-session-adapter.d.ts.map +1 -0
  73. package/dist/esm/lib/hexclave-app/apps/implementations/external-token-store-session-adapter.js +115 -0
  74. package/dist/esm/lib/hexclave-app/apps/implementations/external-token-store-session-adapter.js.map +1 -0
  75. package/dist/esm/lib/hexclave-app/apps/interfaces/client-app.d.ts +16 -1
  76. package/dist/esm/lib/hexclave-app/apps/interfaces/client-app.d.ts.map +1 -1
  77. package/dist/esm/lib/hexclave-app/apps/interfaces/client-app.js.map +1 -1
  78. package/dist/esm/lib/hexclave-app/common.d.ts +14 -2
  79. package/dist/esm/lib/hexclave-app/common.d.ts.map +1 -1
  80. package/dist/esm/lib/hexclave-app/common.js +17 -1
  81. package/dist/esm/lib/hexclave-app/common.js.map +1 -1
  82. package/dist/esm/lib/hexclave-app/index.d.ts +2 -2
  83. package/dist/esm/lib/hexclave-app/index.js +2 -2
  84. package/dist/esm/lib/hexclave-app/users/index.d.ts +14 -1
  85. package/dist/esm/lib/hexclave-app/users/index.d.ts.map +1 -1
  86. package/dist/esm/lib/hexclave-app/users/index.js.map +1 -1
  87. package/dist/{hexclave-provider-w8nX8KDv.d.ts → hexclave-provider-Br8j6WHN.d.ts} +2 -2
  88. package/dist/{hexclave-provider-w8nX8KDv.d.ts.map → hexclave-provider-Br8j6WHN.d.ts.map} +1 -1
  89. package/dist/{hooks-nqzRtl9S.d.ts → hooks-DyC8t1Sh.d.ts} +3 -3
  90. package/dist/{hooks-nqzRtl9S.d.ts.map → hooks-DyC8t1Sh.d.ts.map} +1 -1
  91. package/dist/{index-DbiyXho6.d.ts → index-CQ4kC6Cu.d.ts} +2 -2
  92. package/dist/{index-DbiyXho6.d.ts.map → index-CQ4kC6Cu.d.ts.map} +1 -1
  93. package/dist/{index-BDzsJvkD.d.ts → index-CWaynElx.d.ts} +3 -3
  94. package/dist/{index-BDzsJvkD.d.ts.map → index-CWaynElx.d.ts.map} +1 -1
  95. package/dist/{index-BSr2pd22.d.ts → index-FsS-NA9c.d.ts} +2 -2
  96. package/dist/{index-BSr2pd22.d.ts.map → index-FsS-NA9c.d.ts.map} +1 -1
  97. package/dist/index.d.ts +7 -7
  98. package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +1 -1
  99. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.d.ts +1 -1
  100. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.external-token-store.test.d.ts +1 -0
  101. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.external-token-store.test.js +381 -0
  102. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.external-token-store.test.js.map +1 -0
  103. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.init-analytics.test.d.ts +1 -0
  104. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.init-analytics.test.js +65 -0
  105. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.init-analytics.test.js.map +1 -0
  106. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js +65 -13
  107. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
  108. package/dist/lib/hexclave-app/apps/implementations/common.d.ts +1 -1
  109. package/dist/lib/hexclave-app/apps/implementations/common.js +2 -2
  110. package/dist/lib/hexclave-app/apps/implementations/external-token-store-session-adapter.d.ts +31 -0
  111. package/dist/lib/hexclave-app/apps/implementations/external-token-store-session-adapter.d.ts.map +1 -0
  112. package/dist/lib/hexclave-app/apps/implementations/external-token-store-session-adapter.js +117 -0
  113. package/dist/lib/hexclave-app/apps/implementations/external-token-store-session-adapter.js.map +1 -0
  114. package/dist/lib/hexclave-app/apps/implementations/index.d.ts +1 -1
  115. package/dist/lib/hexclave-app/apps/implementations/redirect-page-urls.d.ts +1 -1
  116. package/dist/lib/hexclave-app/apps/implementations/server-app-impl.d.ts +1 -1
  117. package/dist/lib/hexclave-app/apps/index.d.ts +1 -1
  118. package/dist/lib/hexclave-app/apps/interfaces/admin-app.d.ts +1 -1
  119. package/dist/lib/hexclave-app/apps/interfaces/client-app.d.ts +1 -1
  120. package/dist/lib/hexclave-app/apps/interfaces/client-app.js.map +1 -1
  121. package/dist/lib/hexclave-app/apps/interfaces/server-app.d.ts +1 -1
  122. package/dist/lib/hexclave-app/common.d.ts +2 -2
  123. package/dist/lib/hexclave-app/common.js +19 -0
  124. package/dist/lib/hexclave-app/common.js.map +1 -1
  125. package/dist/lib/hexclave-app/customers/index.d.ts +1 -1
  126. package/dist/lib/hexclave-app/data-vault/index.d.ts +1 -1
  127. package/dist/lib/hexclave-app/index.d.ts +4 -4
  128. package/dist/lib/hexclave-app/index.js +18 -0
  129. package/dist/lib/hexclave-app/projects/index.d.ts +1 -1
  130. package/dist/lib/hexclave-app/teams/index.d.ts +1 -1
  131. package/dist/lib/hexclave-app/url-targets.d.ts +1 -1
  132. package/dist/lib/hexclave-app/users/index.d.ts +1 -1
  133. package/dist/lib/hexclave-app/users/index.js.map +1 -1
  134. package/dist/lib/hooks.d.ts +1 -1
  135. package/dist/providers/hexclave-context.d.ts +1 -1
  136. package/dist/providers/hexclave-provider-client.d.ts +1 -1
  137. package/dist/providers/hexclave-provider.d.ts +1 -1
  138. package/dist/pushed-config-error-overlay/index.d.ts +1 -1
  139. package/dist/{redirect-page-urls-ofcg3AYr.d.ts → redirect-page-urls-CnGvn0UJ.d.ts} +2 -2
  140. package/dist/{redirect-page-urls-ofcg3AYr.d.ts.map → redirect-page-urls-CnGvn0UJ.d.ts.map} +1 -1
  141. package/dist/tanstack-start-server-context.d.ts.map +1 -1
  142. package/dist/{url-targets-CWO0mjTr.d.ts → url-targets-DbhzuQtY.d.ts} +2 -2
  143. package/dist/{url-targets-CWO0mjTr.d.ts.map → url-targets-DbhzuQtY.d.ts.map} +1 -1
  144. package/package.json +4 -4
  145. package/src/components/message-cards/predefined-message-card.tsx +4 -2
  146. package/src/components/user-button.test.tsx +87 -0
  147. package/src/components/user-button.tsx +9 -9
  148. package/src/components-page/account-settings/settings/sign-out-section.tsx +9 -1
  149. package/src/components-page/onboarding.test.tsx +1 -0
  150. package/src/components-page/onboarding.tsx +16 -13
  151. package/src/lib/hexclave-app/apps/implementations/client-app-impl.external-token-store.test.ts +425 -0
  152. package/src/lib/hexclave-app/apps/implementations/client-app-impl.init-analytics.test.ts +79 -0
  153. package/src/lib/hexclave-app/apps/implementations/client-app-impl.ts +124 -13
  154. package/src/lib/hexclave-app/apps/implementations/external-token-store-session-adapter.ts +190 -0
  155. package/src/lib/hexclave-app/apps/interfaces/client-app.ts +17 -0
  156. package/src/lib/hexclave-app/common.ts +33 -0
  157. package/src/lib/hexclave-app/index.ts +4 -0
  158. package/src/lib/hexclave-app/users/index.ts +13 -1
  159. package/dist/admin-app-impl-Bxad6t8m.d.ts.map +0 -1
  160. package/dist/client-app-B0cTytS5.d.ts.map +0 -1
  161. package/dist/common-B2gkWlXX.d.ts.map +0 -1
@@ -14,7 +14,6 @@ import { getTrustedParentDomain, validateRedirectUrl } from "@hexclave/shared/di
14
14
  import { decodeBase32, decodeBase64, encodeBase32, encodeBase64 } from "@hexclave/shared/dist/utils/bytes";
15
15
  import { hexclaveAppInternalsSymbol } from "../../common.js";
16
16
  import { adminProjectCreateOptionsToCrud } from "../../projects/index.js";
17
- import { InternalSession } from "@hexclave/shared/dist/sessions";
18
17
  import { Store } from "@hexclave/shared/dist/utils/stores";
19
18
  import { crossDomainAuthQueryParams, getCrossDomainHandoffParamsFromCurrentUrl, planRedirectToHandler } from "./redirect-page-urls.js";
20
19
  import { BROWSER_ACTION_QUERY_PARAM } from "@hexclave/shared/dist/utils/browser-action-snippets";
@@ -37,10 +36,11 @@ import { teamCreateOptionsToCrud, teamUpdateOptionsToCrud } from "../../teams/in
37
36
  import { buildCliAuthConfirmUrl, getHostedHandlerUrl, isHostedHandlerUrlForProject, resolveHandlerUrls } from "../../url-targets.js";
38
37
  import { userUpdateOptionsToCrud, withUserDestructureGuard } from "../../users/index.js";
39
38
  import { EventTracker } from "./event-tracker.js";
39
+ import { ExternalTokenStoreSessionAdapter, isExternalTokenStore } from "./external-token-store-session-adapter.js";
40
40
  import { augmentUrlWithPersistedRedirectBackState, getRawAfterAuthReturnTo, saveRedirectBackStateFromUrl } from "./redirect-back-state.js";
41
41
  import { recordRedirectAndThrowIfLoopDetected } from "./redirect-loop-breaker.js";
42
42
  import { subscribeSessionRefresh } from "./session-refresh-subscription.js";
43
- import { SessionRecorder, analyticsOptionsFromJson, analyticsOptionsToJson, getSessionReplayOptions } from "./session-replay.js";
43
+ import { SessionRecorder, analyticsOptionsFromJson, analyticsOptionsToJson, getSessionReplayOptions, isAnalyticsNotEnabledError } from "./session-replay.js";
44
44
  import { mountClickmapOverlay } from "../../../../clickmap/index.js";
45
45
  import { mountDevTool } from "../../../../dev-tool/index.js";
46
46
  import { mountPushedConfigErrorOverlay } from "../../../../pushed-config-error-overlay/index.js";
@@ -145,6 +145,9 @@ function throwSetupError(error) {
145
145
  showSetupErrorOverlay(error);
146
146
  throw error;
147
147
  }
148
+ function createAnalyticsAppDisabledOnProjectError() {
149
+ return /* @__PURE__ */ new Error("initAnalytics() was called, but the Analytics app is not enabled on this Hexclave project, so the backend rejects all analytics uploads. Enable the Analytics app in the Hexclave dashboard (or in hexclave.config.ts), or remove the initAnalytics() call if this is intentional.");
150
+ }
148
151
  function getRedirectHelperInstruction(handlerName) {
149
152
  if (handlerName === "handler") return "Use a page-specific redirect helper such as app.redirectToSignIn() instead.";
150
153
  return `Use app.${`redirectTo${handlerName.slice(0, 1).toUpperCase()}${handlerName.slice(1)}`}() instead.`;
@@ -305,6 +308,8 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
305
308
  this._uniqueIdentifier = void 0;
306
309
  this._sessionRecorder = null;
307
310
  this._eventTracker = null;
311
+ this._initAnalyticsCalled = false;
312
+ this._analyticsAppDisabledOnProject = false;
308
313
  this._pendingSignOut = null;
309
314
  this.__DEMO_ENABLE_SLIGHT_FETCH_DELAY = false;
310
315
  this._ownedAdminApps = new DependenciesMap();
@@ -511,6 +516,10 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
511
516
  }
512
517
  });
513
518
  }
519
+ this._externalTokenStoreSessionAdapter = new ExternalTokenStoreSessionAdapter((sessionOptions) => this._interface.createSession(sessionOptions), async (providerId, token) => {
520
+ const exchange = await this._interface.exchangeExternalAuthToken(providerId, token);
521
+ return Result.orThrow(exchange).accessToken;
522
+ });
514
523
  this._tokenStoreInit = resolvedOptions.tokenStore;
515
524
  this._redirectMethod = resolvedOptions.redirectMethod || (isBrowserLike() ? "window" : "none");
516
525
  this._redirectMethod = resolvedOptions.redirectMethod || "nextjs";
@@ -535,22 +544,22 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
535
544
  })) return await this._getSession();
536
545
  return (await this.getUser({ or: "anonymous" }))._internalSession;
537
546
  };
538
- const analyticsEnabled = this._analyticsOptions?.enabled !== false;
547
+ const recordsAnalytics = this._getAnalyticsDisabledReason() == null && isBrowserLike();
539
548
  const sessionReplayOptions = getSessionReplayOptions(this._analyticsOptions);
540
- if (analyticsEnabled && isBrowserLike() && this._hasPersistentTokenStore() && sessionReplayOptions.enabled) {
549
+ if (recordsAnalytics && sessionReplayOptions.enabled) {
541
550
  this._sessionRecorder = new SessionRecorder({
542
551
  projectId: this.projectId,
543
552
  sendBatch: async (body, opts) => {
544
- return await this._interface.sendSessionReplayBatch(body, await getAnalyticsSession(), opts);
553
+ return this._handleAnalyticsUploadResult(await this._interface.sendSessionReplayBatch(body, await getAnalyticsSession(), opts));
545
554
  }
546
555
  }, sessionReplayOptions);
547
556
  this._sessionRecorder.start();
548
557
  }
549
- if (analyticsEnabled && isBrowserLike() && this._hasPersistentTokenStore()) {
558
+ if (recordsAnalytics) {
550
559
  this._eventTracker = new EventTracker({
551
560
  projectId: this.projectId,
552
561
  sendBatch: async (body, opts) => {
553
- return await this._interface.sendAnalyticsEventBatch(body, await getAnalyticsSession(), opts);
562
+ return this._handleAnalyticsUploadResult(await this._interface.sendAnalyticsEventBatch(body, await getAnalyticsSession(), opts));
554
563
  }
555
564
  });
556
565
  this._eventTracker.start();
@@ -1125,6 +1134,9 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
1125
1134
  case "memory": return this._memoryTokenStore;
1126
1135
  default:
1127
1136
  if (tokenStoreInit === null) return createEmptyTokenStore();
1137
+ else if (typeof tokenStoreInit === "object" && isExternalTokenStore(tokenStoreInit)) return this._externalTokenStoreSessionAdapter.getOrCreateTokenStore(tokenStoreInit, (store, previousSessionKey) => {
1138
+ this._sessionsByTokenStoreAndSessionKey.get(store)?.get(previousSessionKey)?.suggestAccessTokenExpired();
1139
+ });
1128
1140
  else if (typeof tokenStoreInit === "object" && "headers" in tokenStoreInit) {
1129
1141
  if (this._requestTokenStores.has(tokenStoreInit)) return this._requestTokenStores.get(tokenStoreInit);
1130
1142
  const authorizationHeader = getHeaderValueFromRequestLikeHeaders(tokenStoreInit.headers, "authorization");
@@ -1171,27 +1183,27 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
1171
1183
  const cookieHelper = createBrowserCookieHelper();
1172
1184
  return this._getOrCreateTokenStore(cookieHelper, overrideTokenStoreInit);
1173
1185
  }
1186
+ _getSessionKeyForTokenStore(tokenStore, tokenObj) {
1187
+ return this._externalTokenStoreSessionAdapter.getSessionKey(tokenStore, tokenObj);
1188
+ }
1174
1189
  /**
1175
1190
  * @param overrideTokenObj The tokens to build the session for, if they haven't been written to the token store yet
1176
1191
  * (so we can warm a sign-in's session before the token store publishes it).
1177
1192
  */
1178
1193
  _getSessionFromTokenStore(tokenStore, overrideTokenObj) {
1179
1194
  const tokenObj = overrideTokenObj ?? tokenStore.get();
1180
- const sessionKey = InternalSession.calculateSessionKey(tokenObj);
1195
+ const sessionKey = this._getSessionKeyForTokenStore(tokenStore, tokenObj);
1181
1196
  const existing = sessionKey ? this._sessionsByTokenStoreAndSessionKey.get(tokenStore)?.get(sessionKey) : null;
1182
1197
  if (existing) return existing;
1183
- const session = this._interface.createSession({
1184
- refreshToken: tokenObj.refreshToken,
1185
- accessToken: tokenObj.accessToken
1186
- });
1198
+ const session = this._externalTokenStoreSessionAdapter.createSessionForTokenStore(tokenStore, tokenObj, sessionKey);
1187
1199
  session.onAccessTokenChange((newAccessToken) => {
1188
- tokenStore.update((old) => InternalSession.calculateSessionKey(old) === sessionKey ? {
1200
+ tokenStore.update((old) => this._getSessionKeyForTokenStore(tokenStore, old) === sessionKey ? {
1189
1201
  ...old,
1190
1202
  accessToken: newAccessToken?.token ?? null
1191
1203
  } : old);
1192
1204
  });
1193
1205
  session.onInvalidate(() => {
1194
- tokenStore.update((old) => InternalSession.calculateSessionKey(old) === sessionKey ? {
1206
+ tokenStore.update((old) => this._getSessionKeyForTokenStore(tokenStore, old) === sessionKey ? {
1195
1207
  ...old,
1196
1208
  accessToken: null,
1197
1209
  refreshToken: null
@@ -1222,6 +1234,7 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
1222
1234
  }
1223
1235
  async _signInToAccountWithTokens(tokens) {
1224
1236
  if (!("accessToken" in tokens) || !("refreshToken" in tokens)) throw new HexclaveAssertionError("Invalid tokens object; can't sign in with this", { tokens });
1237
+ if (this.isExternalAuthApp()) throw new Error("This app authenticates through an external provider and cannot sign in with Hexclave tokens. Sign in through the provider instead.");
1225
1238
  const attemptId = ++this._signInAttemptCounter;
1226
1239
  const tokenStore = this._getOrCreateTokenStore(await this._createCookieHelper());
1227
1240
  const session = this._getSessionFromTokenStore(tokenStore, tokens);
@@ -1615,6 +1628,7 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
1615
1628
  emailAuthEnabled: crud.auth_with_email,
1616
1629
  otpAuthEnabled: crud.otp_auth_enabled,
1617
1630
  oauthProviders: crud.oauth_providers,
1631
+ externalAuthProviders: crud.external_auth_providers,
1618
1632
  passkeyAuthEnabled: crud.passkey_auth_enabled,
1619
1633
  isMultiFactorRequired: crud.requires_totp_mfa,
1620
1634
  isAnonymous: crud.is_anonymous,
@@ -2577,6 +2591,37 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
2577
2591
  }
2578
2592
  return crud && this._currentUserFromCrud(crud, session);
2579
2593
  }
2594
+ isExternalAuthApp() {
2595
+ return typeof this._tokenStoreInit === "object" && this._tokenStoreInit != null && isExternalTokenStore(this._tokenStoreInit);
2596
+ }
2597
+ initAnalytics() {
2598
+ this._initAnalyticsCalled = true;
2599
+ const disabledReason = this._getAnalyticsDisabledReason();
2600
+ if (disabledReason != null) throw new Error(`initAnalytics() was called, but this Hexclave app will not record analytics because ${disabledReason}. Remove the initAnalytics() call if this is intentional.`);
2601
+ if (this._analyticsAppDisabledOnProject) throw createAnalyticsAppDisabledOnProjectError();
2602
+ if (isBrowserLike() && this._eventTracker == null) throw new HexclaveAssertionError("initAnalytics() was called in the browser and _getAnalyticsDisabledReason() returned null, but the constructor did not start the event tracker. The two must agree on when analytics are recorded.");
2603
+ }
2604
+ /**
2605
+ * Returns why this app will never record analytics, or null if it records them whenever it runs in a browser. The
2606
+ * constructor and initAnalytics() both use this, so that the conditions under which analytics start and the
2607
+ * conditions under which initAnalytics() throws can't drift apart.
2608
+ *
2609
+ * Whether the Analytics app is enabled on the project is not part of this, as the client only learns that once the
2610
+ * backend rejects an upload; see _handleAnalyticsUploadResult.
2611
+ */
2612
+ _getAnalyticsDisabledReason() {
2613
+ if (this._analyticsOptions?.enabled === false) return "the `analytics.enabled` constructor option is set to false";
2614
+ if (this._options.automaticSideEffects === false) return "the `automaticSideEffects` constructor option is set to false, which also disables analytics";
2615
+ if (!this._hasPersistentTokenStore()) return "the `tokenStore` constructor option is null; analytics require a persistent token store such as \"cookie\" (or \"nextjs-cookie\" in Next.js)";
2616
+ return null;
2617
+ }
2618
+ _handleAnalyticsUploadResult(result) {
2619
+ if (result.status === "error" && isAnalyticsNotEnabledError(result.error) && !this._analyticsAppDisabledOnProject) {
2620
+ this._analyticsAppDisabledOnProject = true;
2621
+ if (this._initAnalyticsCalled) captureError("initAnalytics", createAnalyticsAppDisabledOnProjectError());
2622
+ }
2623
+ return result;
2624
+ }
2580
2625
  useUser(options) {
2581
2626
  if (options?.or === "anonymous" && options.includeRestricted === false) throw new Error("Cannot use { or: 'anonymous' } with { includeRestricted: false }. Anonymous users implicitly include restricted users.");
2582
2627
  this._ensurePersistentTokenStore(options?.tokenStore);
@@ -2626,6 +2671,7 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
2626
2671
  primaryEmail: accessToken.payload.email,
2627
2672
  displayName: accessToken.payload.name,
2628
2673
  primaryEmailVerified: accessToken.payload.email_verified,
2674
+ selectedTeamId: accessToken.payload.selected_team_id,
2629
2675
  isAnonymous,
2630
2676
  isMultiFactorRequired: accessToken.payload.requires_totp_mfa,
2631
2677
  isRestricted: accessToken.payload.is_restricted,
@@ -2635,11 +2681,14 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
2635
2681
  async _getPartialUserFromConvex(ctx) {
2636
2682
  const auth = await ctx.auth.getUserIdentity();
2637
2683
  if (!auth) return null;
2684
+ const selectedTeamId = auth.selected_team_id ?? null;
2685
+ if (selectedTeamId !== null && typeof selectedTeamId !== "string") throw new HexclaveAssertionError("Expected the Convex selected_team_id claim to be a string or null.");
2638
2686
  return {
2639
2687
  id: auth.subject,
2640
2688
  displayName: auth.name ?? null,
2641
2689
  primaryEmail: auth.email ?? null,
2642
2690
  primaryEmailVerified: auth.email_verified,
2691
+ selectedTeamId,
2643
2692
  isAnonymous: auth.is_anonymous,
2644
2693
  isMultiFactorRequired: auth.requires_totp_mfa,
2645
2694
  isRestricted: auth.is_restricted,
@@ -2990,6 +3039,8 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
2990
3039
  const previousSignOut = this._pendingSignOut;
2991
3040
  const signOutOperation = (async () => {
2992
3041
  await previousSignOut;
3042
+ const externalTokenStore = this._externalTokenStoreSessionAdapter.getExternalTokenStoreForSession(session);
3043
+ if (externalTokenStore != null) throw new HexclaveAssertionError(`Cannot sign out an externally authenticated session through Hexclave. Sign out through the ${externalTokenStore.providerId} provider instead.`);
2993
3044
  await this._interface.signOut(session);
2994
3045
  if (options?.redirectUrl) await this._redirectTo({
2995
3046
  url: options.redirectUrl,
@@ -3143,6 +3194,7 @@ var _HexclaveClientAppImplIncomplete = class _HexclaveClientAppImplIncomplete {
3143
3194
  return {
3144
3195
  toClientJson: () => {
3145
3196
  if (typeof this._redirectMethod !== "string") throw new HexclaveAssertionError("Cannot serialize to JSON from an application with a non-string redirect method");
3197
+ if (typeof this._tokenStoreInit === "object" && this._tokenStoreInit != null && isExternalTokenStore(this._tokenStoreInit)) throw new HexclaveAssertionError("Cannot serialize an app with an external token store because its callbacks are not serializable. Construct this app in the client runtime instead.");
3146
3198
  const publishableClientKey = "publishableClientKey" in this._interface.options ? this._interface.options.publishableClientKey : void 0;
3147
3199
  return {
3148
3200
  baseUrl: this._options.baseUrl,