@hexclave/next 1.0.49 → 1.0.52

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 (164) hide show
  1. package/dist/{admin-app-impl-Cmhx-Gnk.d.ts → admin-app-impl-Bga0o6cL.d.ts} +5 -2
  2. package/dist/{admin-app-impl-Cmhx-Gnk.d.ts.map → admin-app-impl-Bga0o6cL.d.ts.map} +1 -1
  3. package/dist/clickmap/clickmap-core.d.ts +1 -1
  4. package/dist/clickmap/index.d.ts +1 -1
  5. package/dist/{client-app-Majjw8Xp.d.ts → client-app-B0kBC67Z.d.ts} +2 -1
  6. package/dist/{client-app-Majjw8Xp.d.ts.map → client-app-B0kBC67Z.d.ts.map} +1 -1
  7. package/dist/common-BK_sydxF.d.ts.map +1 -1
  8. package/dist/components/selected-team-switcher.d.ts +1 -1
  9. package/dist/components/team-icon.d.ts +1 -1
  10. package/dist/components/team-switcher.d.ts +1 -1
  11. package/dist/components-page/account-settings/active-sessions/active-sessions-page.js +1 -1
  12. package/dist/components-page/account-settings/api-keys/api-keys-page.js +2 -2
  13. package/dist/components-page/account-settings/payments/payments-page.d.ts +1 -1
  14. package/dist/components-page/account-settings/teams/leave-team-section.d.ts +1 -1
  15. package/dist/components-page/account-settings/teams/team-api-keys-section.d.ts +1 -1
  16. package/dist/components-page/account-settings/teams/team-api-keys-section.js +2 -2
  17. package/dist/components-page/account-settings/teams/team-display-name-section.d.ts +1 -1
  18. package/dist/components-page/account-settings/teams/team-member-invitation-section.d.ts +1 -1
  19. package/dist/components-page/account-settings/teams/team-member-list-section.d.ts +1 -1
  20. package/dist/components-page/account-settings/teams/team-page.d.ts +1 -1
  21. package/dist/components-page/account-settings/teams/team-profile-image-section.d.ts +1 -1
  22. package/dist/components-page/account-settings/teams/team-profile-user-section.d.ts +1 -1
  23. package/dist/components-page/hexclave-handler-client.d.ts +1 -1
  24. package/dist/components-page/hexclave-handler.d.ts +1 -1
  25. package/dist/components-page/sign-out.js +11 -2
  26. package/dist/components-page/sign-out.js.map +1 -1
  27. package/dist/components-page/sign-out.test.d.ts +1 -0
  28. package/dist/components-page/sign-out.test.js +157 -0
  29. package/dist/components-page/sign-out.test.js.map +1 -0
  30. package/dist/dev-tool/dev-tool-core.d.ts +1 -1
  31. package/dist/dev-tool/dev-tool-core.d.ts.map +1 -1
  32. package/dist/dev-tool/dev-tool-core.js +58 -28
  33. package/dist/dev-tool/dev-tool-core.js.map +1 -1
  34. package/dist/dev-tool/dev-tool-styles.js +35 -0
  35. package/dist/dev-tool/dev-tool-styles.js.map +1 -1
  36. package/dist/dev-tool/index.d.ts +1 -1
  37. package/dist/esm/components-page/account-settings/active-sessions/active-sessions-page.js +1 -1
  38. package/dist/esm/components-page/account-settings/api-keys/api-keys-page.js +2 -2
  39. package/dist/esm/components-page/account-settings/teams/team-api-keys-section.js +2 -2
  40. package/dist/esm/components-page/sign-out.d.ts.map +1 -1
  41. package/dist/esm/components-page/sign-out.js +12 -3
  42. package/dist/esm/components-page/sign-out.js.map +1 -1
  43. package/dist/esm/components-page/sign-out.test.d.ts +1 -0
  44. package/dist/esm/components-page/sign-out.test.js +156 -0
  45. package/dist/esm/components-page/sign-out.test.js.map +1 -0
  46. package/dist/esm/dev-tool/dev-tool-core.d.ts.map +1 -1
  47. package/dist/esm/dev-tool/dev-tool-core.js +58 -28
  48. package/dist/esm/dev-tool/dev-tool-core.js.map +1 -1
  49. package/dist/esm/dev-tool/dev-tool-styles.js +35 -0
  50. package/dist/esm/dev-tool/dev-tool-styles.js.map +1 -1
  51. package/dist/esm/generated/global-css.d.ts +1 -1
  52. package/dist/esm/generated/global-css.js +1 -1
  53. package/dist/esm/generated/global-css.js.map +1 -1
  54. package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +1 -0
  55. package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts.map +1 -1
  56. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js +97 -0
  57. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js.map +1 -1
  58. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.d.ts +1 -0
  59. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.d.ts.map +1 -1
  60. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js +26 -1
  61. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
  62. package/dist/esm/lib/hexclave-app/apps/implementations/common.d.ts.map +1 -1
  63. package/dist/esm/lib/hexclave-app/apps/implementations/common.js +21 -4
  64. package/dist/esm/lib/hexclave-app/apps/implementations/common.js.map +1 -1
  65. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-back-state.d.ts +37 -0
  66. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-back-state.d.ts.map +1 -0
  67. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-back-state.js +89 -0
  68. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-back-state.js.map +1 -0
  69. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-back-state.test.d.ts +1 -0
  70. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-back-state.test.js +134 -0
  71. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-back-state.test.js.map +1 -0
  72. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-loop-breaker.d.ts +8 -0
  73. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-loop-breaker.d.ts.map +1 -0
  74. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-loop-breaker.js +73 -0
  75. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-loop-breaker.js.map +1 -0
  76. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-loop-breaker.test.d.ts +1 -0
  77. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-loop-breaker.test.js +92 -0
  78. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-loop-breaker.test.js.map +1 -0
  79. package/dist/esm/lib/hexclave-app/apps/implementations/server-app-impl.d.ts +1 -0
  80. package/dist/esm/lib/hexclave-app/apps/implementations/server-app-impl.d.ts.map +1 -1
  81. package/dist/esm/lib/hexclave-app/apps/implementations/server-app-impl.js +27 -6
  82. package/dist/esm/lib/hexclave-app/apps/implementations/server-app-impl.js.map +1 -1
  83. package/dist/esm/lib/hexclave-app/apps/interfaces/client-app.d.ts +1 -0
  84. package/dist/esm/lib/hexclave-app/apps/interfaces/client-app.d.ts.map +1 -1
  85. package/dist/esm/lib/hexclave-app/apps/interfaces/client-app.js.map +1 -1
  86. package/dist/esm/pushed-config-error-overlay/index.js +1 -1
  87. package/dist/esm/pushed-config-error-overlay/index.js.map +1 -1
  88. package/dist/esm/utils/session-storage.d.ts +12 -0
  89. package/dist/esm/utils/session-storage.d.ts.map +1 -0
  90. package/dist/esm/utils/session-storage.js +30 -0
  91. package/dist/esm/utils/session-storage.js.map +1 -0
  92. package/dist/generated/global-css.d.ts +1 -1
  93. package/dist/generated/global-css.js +1 -1
  94. package/dist/generated/global-css.js.map +1 -1
  95. package/dist/{hexclave-provider-IAd7nlbi.d.ts → hexclave-provider-BQ9wrtBt.d.ts} +2 -2
  96. package/dist/{hexclave-provider-IAd7nlbi.d.ts.map → hexclave-provider-BQ9wrtBt.d.ts.map} +1 -1
  97. package/dist/{hooks-BKXOF6jh.d.ts → hooks-ykQ7Wsco.d.ts} +2 -2
  98. package/dist/{hooks-BKXOF6jh.d.ts.map → hooks-ykQ7Wsco.d.ts.map} +1 -1
  99. package/dist/{index-Ck1qKoin.d.ts → index-DwE1cNLH.d.ts} +2 -2
  100. package/dist/{index-Ck1qKoin.d.ts.map → index-DwE1cNLH.d.ts.map} +1 -1
  101. package/dist/index.d.ts +4 -4
  102. package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +1 -1
  103. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js +97 -0
  104. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js.map +1 -1
  105. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.d.ts +1 -1
  106. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js +26 -1
  107. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
  108. package/dist/lib/hexclave-app/apps/implementations/common.js +21 -4
  109. package/dist/lib/hexclave-app/apps/implementations/common.js.map +1 -1
  110. package/dist/lib/hexclave-app/apps/implementations/index.d.ts +1 -1
  111. package/dist/lib/hexclave-app/apps/implementations/redirect-back-state.d.ts +37 -0
  112. package/dist/lib/hexclave-app/apps/implementations/redirect-back-state.d.ts.map +1 -0
  113. package/dist/lib/hexclave-app/apps/implementations/redirect-back-state.js +92 -0
  114. package/dist/lib/hexclave-app/apps/implementations/redirect-back-state.js.map +1 -0
  115. package/dist/lib/hexclave-app/apps/implementations/redirect-back-state.test.d.ts +1 -0
  116. package/dist/lib/hexclave-app/apps/implementations/redirect-back-state.test.js +133 -0
  117. package/dist/lib/hexclave-app/apps/implementations/redirect-back-state.test.js.map +1 -0
  118. package/dist/lib/hexclave-app/apps/implementations/redirect-loop-breaker.d.ts +8 -0
  119. package/dist/lib/hexclave-app/apps/implementations/redirect-loop-breaker.d.ts.map +1 -0
  120. package/dist/lib/hexclave-app/apps/implementations/redirect-loop-breaker.js +74 -0
  121. package/dist/lib/hexclave-app/apps/implementations/redirect-loop-breaker.js.map +1 -0
  122. package/dist/lib/hexclave-app/apps/implementations/redirect-loop-breaker.test.d.ts +1 -0
  123. package/dist/lib/hexclave-app/apps/implementations/redirect-loop-breaker.test.js +91 -0
  124. package/dist/lib/hexclave-app/apps/implementations/redirect-loop-breaker.test.js.map +1 -0
  125. package/dist/lib/hexclave-app/apps/implementations/server-app-impl.d.ts +1 -1
  126. package/dist/lib/hexclave-app/apps/implementations/server-app-impl.js +27 -6
  127. package/dist/lib/hexclave-app/apps/implementations/server-app-impl.js.map +1 -1
  128. package/dist/lib/hexclave-app/apps/index.d.ts +1 -1
  129. package/dist/lib/hexclave-app/apps/interfaces/admin-app.d.ts +1 -1
  130. package/dist/lib/hexclave-app/apps/interfaces/client-app.d.ts +1 -1
  131. package/dist/lib/hexclave-app/apps/interfaces/client-app.js.map +1 -1
  132. package/dist/lib/hexclave-app/apps/interfaces/server-app.d.ts +1 -1
  133. package/dist/lib/hexclave-app/index.d.ts +1 -1
  134. package/dist/lib/hexclave-app/projects/index.d.ts +1 -1
  135. package/dist/lib/hexclave-app/teams/index.d.ts +1 -1
  136. package/dist/lib/hexclave-app/users/index.d.ts +1 -1
  137. package/dist/lib/hooks.d.ts +1 -1
  138. package/dist/providers/hexclave-context.d.ts +1 -1
  139. package/dist/providers/hexclave-provider-client.d.ts +1 -1
  140. package/dist/providers/hexclave-provider.d.ts +1 -1
  141. package/dist/pushed-config-error-overlay/index.d.ts +1 -1
  142. package/dist/pushed-config-error-overlay/index.js +1 -1
  143. package/dist/pushed-config-error-overlay/index.js.map +1 -1
  144. package/dist/sign-out-DBnSkfDz.d.ts.map +1 -1
  145. package/dist/utils/session-storage.d.ts +12 -0
  146. package/dist/utils/session-storage.d.ts.map +1 -0
  147. package/dist/utils/session-storage.js +33 -0
  148. package/dist/utils/session-storage.js.map +1 -0
  149. package/package.json +4 -4
  150. package/src/components-page/sign-out.test.tsx +190 -0
  151. package/src/components-page/sign-out.tsx +22 -3
  152. package/src/dev-tool/dev-tool-core.ts +100 -35
  153. package/src/dev-tool/dev-tool-styles.ts +35 -0
  154. package/src/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.ts +127 -0
  155. package/src/lib/hexclave-app/apps/implementations/client-app-impl.ts +34 -1
  156. package/src/lib/hexclave-app/apps/implementations/common.ts +18 -1
  157. package/src/lib/hexclave-app/apps/implementations/redirect-back-state.test.ts +134 -0
  158. package/src/lib/hexclave-app/apps/implementations/redirect-back-state.ts +140 -0
  159. package/src/lib/hexclave-app/apps/implementations/redirect-loop-breaker.test.ts +127 -0
  160. package/src/lib/hexclave-app/apps/implementations/redirect-loop-breaker.ts +117 -0
  161. package/src/lib/hexclave-app/apps/implementations/server-app-impl.ts +31 -5
  162. package/src/lib/hexclave-app/apps/interfaces/client-app.ts +1 -0
  163. package/src/pushed-config-error-overlay/index.ts +1 -1
  164. package/src/utils/session-storage.ts +45 -0
@@ -1,2 +1,2 @@
1
- import { A as HexclaveServerApp, C as HexclaveAdminAppConstructorOptions, D as StackAdminApp, F as StackServerAppConstructorOptions, M as HexclaveServerAppConstructorOptions, N as StackServerApp, O as StackAdminAppConstructor, P as StackServerAppConstructor, S as HexclaveAdminAppConstructor, a as StackClientApp, c as StackClientAppJson, i as HexclaveClientAppJson, j as HexclaveServerAppConstructor, k as StackAdminAppConstructorOptions, n as HexclaveClientAppConstructor, o as StackClientAppConstructor, r as HexclaveClientAppConstructorOptions, s as StackClientAppConstructorOptions, t as HexclaveClientApp, x as HexclaveAdminApp } from "../../../client-app-Majjw8Xp.js";
1
+ import { A as HexclaveServerApp, C as HexclaveAdminAppConstructorOptions, D as StackAdminApp, F as StackServerAppConstructorOptions, M as HexclaveServerAppConstructorOptions, N as StackServerApp, O as StackAdminAppConstructor, P as StackServerAppConstructor, S as HexclaveAdminAppConstructor, a as StackClientApp, c as StackClientAppJson, i as HexclaveClientAppJson, j as HexclaveServerAppConstructor, k as StackAdminAppConstructorOptions, n as HexclaveClientAppConstructor, o as StackClientAppConstructor, r as HexclaveClientAppConstructorOptions, s as StackClientAppConstructorOptions, t as HexclaveClientApp, x as HexclaveAdminApp } from "../../../client-app-B0kBC67Z.js";
2
2
  export { HexclaveAdminApp, type HexclaveAdminAppConstructor, type HexclaveAdminAppConstructorOptions, HexclaveClientApp, type HexclaveClientAppConstructor, type HexclaveClientAppConstructorOptions, type HexclaveClientAppJson, HexclaveServerApp, type HexclaveServerAppConstructor, type HexclaveServerAppConstructorOptions, StackAdminApp, type StackAdminAppConstructor, type StackAdminAppConstructorOptions, StackClientApp, type StackClientAppConstructor, type StackClientAppConstructorOptions, type StackClientAppJson, StackServerApp, type StackServerAppConstructor, type StackServerAppConstructorOptions };
@@ -1,3 +1,3 @@
1
- import { C as HexclaveAdminAppConstructorOptions, D as StackAdminApp, E as ManagedEmailProviderStatus, O as StackAdminAppConstructor, S as HexclaveAdminAppConstructor, T as ManagedEmailProviderSetupResult, b as EmailOutboxUpdateOptions, k as StackAdminAppConstructorOptions, v as EmailOutboxListOptions, w as ManagedEmailProviderListItem, x as HexclaveAdminApp, y as EmailOutboxListResult } from "../../../../client-app-Majjw8Xp.js";
1
+ import { C as HexclaveAdminAppConstructorOptions, D as StackAdminApp, E as ManagedEmailProviderStatus, O as StackAdminAppConstructor, S as HexclaveAdminAppConstructor, T as ManagedEmailProviderSetupResult, b as EmailOutboxUpdateOptions, k as StackAdminAppConstructorOptions, v as EmailOutboxListOptions, w as ManagedEmailProviderListItem, x as HexclaveAdminApp, y as EmailOutboxListResult } from "../../../../client-app-B0kBC67Z.js";
2
2
  import { a as ListSessionReplaysOptions, i as ListSessionReplayChunksResult, n as AdminSessionReplayChunk, o as ListSessionReplaysResult, r as ListSessionReplayChunksOptions, s as SessionReplayAllEventsResult, t as AdminSessionReplay } from "../../../../index-hYjsGKNc.js";
3
3
  export { type AdminSessionReplay, type AdminSessionReplayChunk, EmailOutboxListOptions, EmailOutboxListResult, EmailOutboxUpdateOptions, HexclaveAdminApp, HexclaveAdminAppConstructor, HexclaveAdminAppConstructorOptions, type ListSessionReplayChunksOptions, type ListSessionReplayChunksResult, type ListSessionReplaysOptions, type ListSessionReplaysResult, ManagedEmailProviderListItem, ManagedEmailProviderSetupResult, ManagedEmailProviderStatus, type SessionReplayAllEventsResult, StackAdminApp, StackAdminAppConstructor, StackAdminAppConstructorOptions };
@@ -1,2 +1,2 @@
1
- import { a as StackClientApp, c as StackClientAppJson, i as HexclaveClientAppJson, n as HexclaveClientAppConstructor, o as StackClientAppConstructor, r as HexclaveClientAppConstructorOptions, s as StackClientAppConstructorOptions, t as HexclaveClientApp } from "../../../../client-app-Majjw8Xp.js";
1
+ import { a as StackClientApp, c as StackClientAppJson, i as HexclaveClientAppJson, n as HexclaveClientAppConstructor, o as StackClientAppConstructor, r as HexclaveClientAppConstructorOptions, s as StackClientAppConstructorOptions, t as HexclaveClientApp } from "../../../../client-app-B0kBC67Z.js";
2
2
  export { HexclaveClientApp, HexclaveClientAppConstructor, HexclaveClientAppConstructorOptions, HexclaveClientAppJson, StackClientApp, StackClientAppConstructor, StackClientAppConstructorOptions, StackClientAppJson };
@@ -1 +1 @@
1
- {"version":3,"file":"client-app.js","names":["_HexclaveClientAppImpl"],"sources":["../../../../../src/lib/hexclave-app/apps/interfaces/client-app.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { KnownErrors } from \"@hexclave/shared\";\nimport { CurrentUserCrud } from \"@hexclave/shared/dist/interface/crud/current-user\";\nimport { Result } from \"@hexclave/shared/dist/utils/results\";\nimport { AsyncStoreProperty, AuthLike, GetCurrentPartialUserOptions, GetCurrentUserOptions, HandlerUrlOptions, HandlerUrls, OAuthScopesOnSignIn, RedirectMethod, RedirectToOptions, ResolvedHandlerUrls, hexclaveAppInternalsSymbol, TokenStoreInit } from \"../../common\";\nimport type { RequestListener } from \"@hexclave/shared/dist/interface/client-interface\";\nimport { CustomerInvoicesList, CustomerInvoicesRequestOptions, CustomerProductsList, CustomerProductsRequestOptions, Item } from \"../../customers\";\nimport { Project } from \"../../projects\";\nimport { ProjectCurrentUser, SyncedPartialUser, TokenPartialUser } from \"../../users\";\nimport { _HexclaveClientAppImpl } from \"../implementations\";\nimport { AnalyticsOptions } from \"../implementations/session-replay\";\n\n/** @deprecated Use `HexclaveClientAppConstructorOptions` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackClientAppConstructorOptions<HasTokenStore extends boolean, ProjectId extends string> = {\n baseUrl?: string | { browser: string, server: string },\n extraRequestHeaders?: Record<string, string>,\n projectId?: ProjectId,\n publishableClientKey?: string,\n urls?: HandlerUrlOptions,\n oauthScopesOnSignIn?: Partial<OAuthScopesOnSignIn>,\n tokenStore?: TokenStoreInit<HasTokenStore>,\n redirectMethod?: RedirectMethod,\n inheritsFrom?: StackClientApp<any, any>,\n\n /**\n * Whether to show the Hexclave dev tool indicator in browser-like environments.\n *\n * - `true`: always show\n * - `false`: never show\n * - `\"auto\"` (default): show based on NODE_ENV or origin heuristics\n */\n devTool?: boolean | \"auto\",\n\n /**\n * By default, the Stack app will automatically prefetch some data from Stack's server when this app is first\n * constructed. This improves the performance of your app, but will create network requests that are unnecessary if\n * the app is never used or disposed of immediately. To disable this behavior, set this option to true.\n */\n noAutomaticPrefetch?: boolean,\n\n /**\n * Options for analytics and session recording. Replays are enabled by default;\n * set `{ replays: { enabled: false } }` to opt out.\n */\n analytics?: AnalyticsOptions,\n} & (\n { tokenStore: TokenStoreInit<HasTokenStore> } | { tokenStore?: undefined, inheritsFrom: StackClientApp<HasTokenStore, any> }\n) & (\n string extends ProjectId ? unknown : ({ projectId: ProjectId } | { inheritsFrom: StackClientApp<any, ProjectId> })\n);\n\n\n/** @deprecated Use `HexclaveClientAppJson` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackClientAppJson<HasTokenStore extends boolean, ProjectId extends string> = StackClientAppConstructorOptions<HasTokenStore, ProjectId> & { inheritsFrom?: undefined } & {\n uniqueIdentifier: string,\n // note: if you add more fields here, make sure to ensure the checkString in the constructor has/doesn't have them\n};\n\n/** @deprecated Use `HexclaveClientApp` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackClientApp<HasTokenStore extends boolean = boolean, ProjectId extends string = string> = (\n & {\n readonly projectId: ProjectId,\n\n /**\n * The version of the Hexclave SDK.\n */\n readonly version: string,\n\n /**\n * @deprecated Do not use `app.urls` for navigation. It is static and does not include runtime redirect-back,\n * cross-domain auth, or sign-out state. Use the matching `redirectToXyz()` method instead, for example\n * `redirectToSignIn()`, `redirectToSignUp()`, `redirectToSignOut()`, or `redirectToAccountSettings()`.\n */\n readonly urls: Readonly<ResolvedHandlerUrls>,\n\n signInWithOAuth(provider: string, options?: { returnTo?: string }): Promise<void>,\n signInWithCredential(options: { email: string, password: string, noRedirect?: boolean }): Promise<Result<undefined, KnownErrors[\"EmailPasswordMismatch\"] | KnownErrors[\"InvalidTotpCode\"]>>,\n signUpWithCredential(options: {\n email: string,\n password: string,\n noRedirect?: boolean,\n } & ({ noVerificationCallback: true } | { noVerificationCallback?: false, verificationCallbackUrl?: string })): Promise<Result<undefined, KnownErrors[\"UserWithEmailAlreadyExists\"] | KnownErrors[\"PasswordRequirementsNotMet\"] | KnownErrors[\"BotChallengeFailed\"]>>,\n signInWithPasskey(): Promise<Result<undefined, KnownErrors[\"PasskeyAuthenticationFailed\"] | KnownErrors[\"InvalidTotpCode\"] | KnownErrors[\"PasskeyWebAuthnError\"]>>,\n callOAuthCallback(): Promise<boolean>,\n promptCliLogin(options: { appUrl: string, expiresInMillis?: number, anonRefreshToken?: string, promptLink?: (url: string, loginCode: string) => void }): Promise<Result<string, KnownErrors[\"CliAuthError\"] | KnownErrors[\"CliAuthExpiredError\"] | KnownErrors[\"CliAuthUsedError\"]>>,\n sendForgotPasswordEmail(email: string, options?: { callbackUrl?: string }): Promise<Result<undefined, KnownErrors[\"UserNotFound\"]>>,\n sendMagicLinkEmail(email: string, options?: { callbackUrl?: string }): Promise<Result<{ nonce: string }, KnownErrors[\"RedirectUrlNotWhitelisted\"] | KnownErrors[\"BotChallengeFailed\"]>>,\n resetPassword(options: { code: string, password: string }): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"]>>,\n verifyPasswordResetCode(code: string): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"]>>,\n verifyTeamInvitationCode(code: string): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"] | KnownErrors[\"TeamInvitationEmailMismatch\"]>>,\n acceptTeamInvitation(code: string): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"] | KnownErrors[\"TeamInvitationEmailMismatch\"]>>,\n getTeamInvitationDetails(code: string): Promise<Result<{ teamDisplayName: string }, KnownErrors[\"VerificationCodeError\"] | KnownErrors[\"TeamInvitationEmailMismatch\"]>>,\n verifyEmail(code: string): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"]>>,\n signInWithMagicLink(code: string, options?: { noRedirect?: boolean }): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"] | KnownErrors[\"InvalidTotpCode\"]>>,\n signInWithMfa(otp: string, code: string, options?: { noRedirect?: boolean }): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"] | KnownErrors[\"InvalidTotpCode\"]>>,\n\n redirectToOAuthCallback(): Promise<void>,\n\n getConvexClientAuth(options: HasTokenStore extends false ? { tokenStore: TokenStoreInit } : { tokenStore?: TokenStoreInit }): (args: { forceRefreshToken: boolean }) => Promise<string | null>,\n getConvexHttpClientAuth(options: { tokenStore: TokenStoreInit }): Promise<string>,\n\n useUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'redirect' }): ProjectCurrentUser<ProjectId>,\n useUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'throw' }): ProjectCurrentUser<ProjectId>,\n useUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'anonymous' }): ProjectCurrentUser<ProjectId>,\n useUser(options?: GetCurrentUserOptions<HasTokenStore>): ProjectCurrentUser<ProjectId> | null,\n\n getUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'redirect' }): Promise<ProjectCurrentUser<ProjectId>>,\n getUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'throw' }): Promise<ProjectCurrentUser<ProjectId>>,\n getUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'anonymous' }): Promise<ProjectCurrentUser<ProjectId>>,\n getUser(options?: GetCurrentUserOptions<HasTokenStore>): Promise<ProjectCurrentUser<ProjectId> | null>,\n\n cancelSubscription(options: { productId: string, subscriptionId?: string } | { productId: string, subscriptionId?: string, teamId: string }): Promise<void>,\n\n // note: we don't special-case 'anonymous' here to return non-null, see GetPartialUserOptions for more details\n getPartialUser(options: GetCurrentPartialUserOptions<HasTokenStore> & { from: 'token' }): Promise<TokenPartialUser | null>,\n getPartialUser(options: GetCurrentPartialUserOptions<HasTokenStore> & { from: 'convex' }): Promise<TokenPartialUser | null>,\n getPartialUser(options: GetCurrentPartialUserOptions<HasTokenStore>): Promise<SyncedPartialUser | TokenPartialUser | null>,\n usePartialUser(options: GetCurrentPartialUserOptions<HasTokenStore> & { from: 'token' }): TokenPartialUser | null,\n usePartialUser(options: GetCurrentPartialUserOptions<HasTokenStore> & { from: 'convex' }): TokenPartialUser | null,\n usePartialUser(options: GetCurrentPartialUserOptions<HasTokenStore>): SyncedPartialUser | TokenPartialUser | null,\n useNavigate(): (to: string) => void, // THIS_LINE_PLATFORM react-like\n\n [hexclaveAppInternalsSymbol]: {\n toClientJson(): StackClientAppJson<HasTokenStore, ProjectId>,\n setCurrentUser(userJsonPromise: Promise<CurrentUserCrud['Client']['Read'] | null>): void,\n getConstructorOptions(): StackClientAppConstructorOptions<HasTokenStore, ProjectId> & { inheritsFrom?: undefined },\n sendSessionReplayBatch(body: string, options: { keepalive: boolean }): Promise<Result<Response, Error>>,\n sendAnalyticsEventBatch(body: string, options: { keepalive: boolean }): Promise<Result<Response, Error>>,\n addRequestListener(listener: RequestListener): () => void,\n sendRequest(path: string, requestOptions: RequestInit, requestType?: \"client\" | \"server\" | \"admin\"): Promise<Response>,\n getUrls(): Readonly<ResolvedHandlerUrls>,\n getRedirectMethod(): RedirectMethod,\n redirectToUrl(url: string | URL, options?: { replace?: boolean }): Promise<void>,\n getRedirectToHandlerUrl(handlerName: keyof HandlerUrls, options?: RedirectToOptions): Promise<string>,\n redirectToHandler(handlerName: keyof HandlerUrls, options?: RedirectToOptions): Promise<void>,\n signInWithTokens(tokens: { accessToken: string, refreshToken: string }): Promise<void>,\n awaitPendingAuthResolutions(): Promise<void>,\n },\n }\n & AsyncStoreProperty<\"project\", [], Project, false>\n & AsyncStoreProperty<\n \"item\",\n [{ itemId: string, userId: string } | { itemId: string, teamId: string } | { itemId: string, customCustomerId: string }],\n Item,\n false\n >\n & AsyncStoreProperty<\n \"products\",\n [options: CustomerProductsRequestOptions],\n CustomerProductsList,\n true\n >\n & AsyncStoreProperty<\n \"invoices\",\n [options: CustomerInvoicesRequestOptions],\n CustomerInvoicesList,\n true\n >\n & { [K in `redirectTo${Capitalize<keyof Omit<HandlerUrls, 'handler' | 'oauthCallback'>>}`]: (options?: RedirectToOptions) => Promise<void> }\n & AuthLike<HasTokenStore extends false ? { tokenStore: TokenStoreInit } : { tokenStore?: TokenStoreInit }>\n);\n/** @deprecated Use `HexclaveClientAppConstructor` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackClientAppConstructor = {\n new <\n TokenStoreType extends string,\n HasTokenStore extends (TokenStoreType extends {} ? true : boolean),\n ProjectId extends string\n >(options: StackClientAppConstructorOptions<HasTokenStore, ProjectId>): StackClientApp<HasTokenStore, ProjectId>,\n new(options: StackClientAppConstructorOptions<boolean, string>): StackClientApp<boolean, string>,\n\n [hexclaveAppInternalsSymbol]: {\n fromClientJson<HasTokenStore extends boolean, ProjectId extends string>(\n json: StackClientAppJson<HasTokenStore, ProjectId>\n ): StackClientApp<HasTokenStore, ProjectId>,\n },\n};\nexport type HexclaveClientAppConstructorOptions<HasTokenStore extends boolean, ProjectId extends string> = StackClientAppConstructorOptions<HasTokenStore, ProjectId>;\nexport type HexclaveClientAppJson<HasTokenStore extends boolean, ProjectId extends string> = StackClientAppJson<HasTokenStore, ProjectId>;\nexport type HexclaveClientApp<HasTokenStore extends boolean = boolean, ProjectId extends string = string> = StackClientApp<HasTokenStore, ProjectId>;\nexport type HexclaveClientAppConstructor = StackClientAppConstructor;\nexport const HexclaveClientApp: HexclaveClientAppConstructor = _HexclaveClientAppImpl;\n/** @deprecated Use `HexclaveClientApp` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport const StackClientApp: StackClientAppConstructor = HexclaveClientApp;\n"],"mappings":";;AAuLA,MAAa,yDAAkDA,CAAAA,CAAAA;;AAE/D,MAAa,iBAA4C"}
1
+ {"version":3,"file":"client-app.js","names":["_HexclaveClientAppImpl"],"sources":["../../../../../src/lib/hexclave-app/apps/interfaces/client-app.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { KnownErrors } from \"@hexclave/shared\";\nimport { CurrentUserCrud } from \"@hexclave/shared/dist/interface/crud/current-user\";\nimport { Result } from \"@hexclave/shared/dist/utils/results\";\nimport { AsyncStoreProperty, AuthLike, GetCurrentPartialUserOptions, GetCurrentUserOptions, HandlerUrlOptions, HandlerUrls, OAuthScopesOnSignIn, RedirectMethod, RedirectToOptions, ResolvedHandlerUrls, hexclaveAppInternalsSymbol, TokenStoreInit } from \"../../common\";\nimport type { RequestListener } from \"@hexclave/shared/dist/interface/client-interface\";\nimport { CustomerInvoicesList, CustomerInvoicesRequestOptions, CustomerProductsList, CustomerProductsRequestOptions, Item } from \"../../customers\";\nimport { Project } from \"../../projects\";\nimport { ProjectCurrentUser, SyncedPartialUser, TokenPartialUser } from \"../../users\";\nimport { _HexclaveClientAppImpl } from \"../implementations\";\nimport { AnalyticsOptions } from \"../implementations/session-replay\";\n\n/** @deprecated Use `HexclaveClientAppConstructorOptions` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackClientAppConstructorOptions<HasTokenStore extends boolean, ProjectId extends string> = {\n baseUrl?: string | { browser: string, server: string },\n extraRequestHeaders?: Record<string, string>,\n projectId?: ProjectId,\n publishableClientKey?: string,\n urls?: HandlerUrlOptions,\n oauthScopesOnSignIn?: Partial<OAuthScopesOnSignIn>,\n tokenStore?: TokenStoreInit<HasTokenStore>,\n redirectMethod?: RedirectMethod,\n inheritsFrom?: StackClientApp<any, any>,\n\n /**\n * Whether to show the Hexclave dev tool indicator in browser-like environments.\n *\n * - `true`: always show\n * - `false`: never show\n * - `\"auto\"` (default): show based on NODE_ENV or origin heuristics\n */\n devTool?: boolean | \"auto\",\n\n /**\n * By default, the Stack app will automatically prefetch some data from Stack's server when this app is first\n * constructed. This improves the performance of your app, but will create network requests that are unnecessary if\n * the app is never used or disposed of immediately. To disable this behavior, set this option to true.\n */\n noAutomaticPrefetch?: boolean,\n\n /**\n * Options for analytics and session recording. Replays are enabled by default;\n * set `{ replays: { enabled: false } }` to opt out.\n */\n analytics?: AnalyticsOptions,\n} & (\n { tokenStore: TokenStoreInit<HasTokenStore> } | { tokenStore?: undefined, inheritsFrom: StackClientApp<HasTokenStore, any> }\n) & (\n string extends ProjectId ? unknown : ({ projectId: ProjectId } | { inheritsFrom: StackClientApp<any, ProjectId> })\n);\n\n\n/** @deprecated Use `HexclaveClientAppJson` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackClientAppJson<HasTokenStore extends boolean, ProjectId extends string> = StackClientAppConstructorOptions<HasTokenStore, ProjectId> & { inheritsFrom?: undefined } & {\n uniqueIdentifier: string,\n // note: if you add more fields here, make sure to ensure the checkString in the constructor has/doesn't have them\n};\n\n/** @deprecated Use `HexclaveClientApp` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackClientApp<HasTokenStore extends boolean = boolean, ProjectId extends string = string> = (\n & {\n readonly projectId: ProjectId,\n\n /**\n * The version of the Hexclave SDK.\n */\n readonly version: string,\n\n /**\n * @deprecated Do not use `app.urls` for navigation. It is static and does not include runtime redirect-back,\n * cross-domain auth, or sign-out state. Use the matching `redirectToXyz()` method instead, for example\n * `redirectToSignIn()`, `redirectToSignUp()`, `redirectToSignOut()`, or `redirectToAccountSettings()`.\n */\n readonly urls: Readonly<ResolvedHandlerUrls>,\n\n signInWithOAuth(provider: string, options?: { returnTo?: string }): Promise<void>,\n signInWithCredential(options: { email: string, password: string, noRedirect?: boolean }): Promise<Result<undefined, KnownErrors[\"EmailPasswordMismatch\"] | KnownErrors[\"InvalidTotpCode\"]>>,\n signUpWithCredential(options: {\n email: string,\n password: string,\n noRedirect?: boolean,\n } & ({ noVerificationCallback: true } | { noVerificationCallback?: false, verificationCallbackUrl?: string })): Promise<Result<undefined, KnownErrors[\"UserWithEmailAlreadyExists\"] | KnownErrors[\"PasswordRequirementsNotMet\"] | KnownErrors[\"BotChallengeFailed\"]>>,\n signInWithPasskey(): Promise<Result<undefined, KnownErrors[\"PasskeyAuthenticationFailed\"] | KnownErrors[\"InvalidTotpCode\"] | KnownErrors[\"PasskeyWebAuthnError\"]>>,\n callOAuthCallback(): Promise<boolean>,\n promptCliLogin(options: { appUrl: string, expiresInMillis?: number, anonRefreshToken?: string, promptLink?: (url: string, loginCode: string) => void }): Promise<Result<string, KnownErrors[\"CliAuthError\"] | KnownErrors[\"CliAuthExpiredError\"] | KnownErrors[\"CliAuthUsedError\"]>>,\n sendForgotPasswordEmail(email: string, options?: { callbackUrl?: string }): Promise<Result<undefined, KnownErrors[\"UserNotFound\"]>>,\n sendMagicLinkEmail(email: string, options?: { callbackUrl?: string }): Promise<Result<{ nonce: string }, KnownErrors[\"RedirectUrlNotWhitelisted\"] | KnownErrors[\"BotChallengeFailed\"]>>,\n resetPassword(options: { code: string, password: string }): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"]>>,\n verifyPasswordResetCode(code: string): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"]>>,\n verifyTeamInvitationCode(code: string): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"] | KnownErrors[\"TeamInvitationEmailMismatch\"]>>,\n acceptTeamInvitation(code: string): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"] | KnownErrors[\"TeamInvitationEmailMismatch\"]>>,\n getTeamInvitationDetails(code: string): Promise<Result<{ teamDisplayName: string }, KnownErrors[\"VerificationCodeError\"] | KnownErrors[\"TeamInvitationEmailMismatch\"]>>,\n verifyEmail(code: string): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"]>>,\n signInWithMagicLink(code: string, options?: { noRedirect?: boolean }): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"] | KnownErrors[\"InvalidTotpCode\"]>>,\n signInWithMfa(otp: string, code: string, options?: { noRedirect?: boolean }): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"] | KnownErrors[\"InvalidTotpCode\"]>>,\n\n redirectToOAuthCallback(): Promise<void>,\n\n getConvexClientAuth(options: HasTokenStore extends false ? { tokenStore: TokenStoreInit } : { tokenStore?: TokenStoreInit }): (args: { forceRefreshToken: boolean }) => Promise<string | null>,\n getConvexHttpClientAuth(options: { tokenStore: TokenStoreInit }): Promise<string>,\n\n useUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'redirect' }): ProjectCurrentUser<ProjectId>,\n useUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'throw' }): ProjectCurrentUser<ProjectId>,\n useUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'anonymous' }): ProjectCurrentUser<ProjectId>,\n useUser(options?: GetCurrentUserOptions<HasTokenStore>): ProjectCurrentUser<ProjectId> | null,\n\n getUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'redirect' }): Promise<ProjectCurrentUser<ProjectId>>,\n getUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'throw' }): Promise<ProjectCurrentUser<ProjectId>>,\n getUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'anonymous' }): Promise<ProjectCurrentUser<ProjectId>>,\n getUser(options?: GetCurrentUserOptions<HasTokenStore>): Promise<ProjectCurrentUser<ProjectId> | null>,\n\n cancelSubscription(options: { productId: string, subscriptionId?: string } | { productId: string, subscriptionId?: string, teamId: string }): Promise<void>,\n\n // note: we don't special-case 'anonymous' here to return non-null, see GetPartialUserOptions for more details\n getPartialUser(options: GetCurrentPartialUserOptions<HasTokenStore> & { from: 'token' }): Promise<TokenPartialUser | null>,\n getPartialUser(options: GetCurrentPartialUserOptions<HasTokenStore> & { from: 'convex' }): Promise<TokenPartialUser | null>,\n getPartialUser(options: GetCurrentPartialUserOptions<HasTokenStore>): Promise<SyncedPartialUser | TokenPartialUser | null>,\n usePartialUser(options: GetCurrentPartialUserOptions<HasTokenStore> & { from: 'token' }): TokenPartialUser | null,\n usePartialUser(options: GetCurrentPartialUserOptions<HasTokenStore> & { from: 'convex' }): TokenPartialUser | null,\n usePartialUser(options: GetCurrentPartialUserOptions<HasTokenStore>): SyncedPartialUser | TokenPartialUser | null,\n useNavigate(): (to: string) => void, // THIS_LINE_PLATFORM react-like\n\n [hexclaveAppInternalsSymbol]: {\n toClientJson(): StackClientAppJson<HasTokenStore, ProjectId>,\n setCurrentUser(userJsonPromise: Promise<CurrentUserCrud['Client']['Read'] | null>): void,\n getConstructorOptions(): StackClientAppConstructorOptions<HasTokenStore, ProjectId> & { inheritsFrom?: undefined },\n sendSessionReplayBatch(body: string, options: { keepalive: boolean }): Promise<Result<Response, Error>>,\n sendAnalyticsEventBatch(body: string, options: { keepalive: boolean }): Promise<Result<Response, Error>>,\n addRequestListener(listener: RequestListener): () => void,\n sendRequest(path: string, requestOptions: RequestInit, requestType?: \"client\" | \"server\" | \"admin\"): Promise<Response>,\n getUrls(): Readonly<ResolvedHandlerUrls>,\n getRedirectMethod(): RedirectMethod,\n redirectToUrl(url: string | URL, options?: { replace?: boolean }): Promise<void>,\n getRedirectToHandlerUrl(handlerName: keyof HandlerUrls, options?: RedirectToOptions): Promise<string>,\n redirectToHandler(handlerName: keyof HandlerUrls, options?: RedirectToOptions): Promise<void>,\n signInWithTokens(tokens: { accessToken: string, refreshToken: string }): Promise<void>,\n awaitPendingAuthResolutions(): Promise<void>,\n isTrustedRedirectUrl(url: string): Promise<boolean>,\n },\n }\n & AsyncStoreProperty<\"project\", [], Project, false>\n & AsyncStoreProperty<\n \"item\",\n [{ itemId: string, userId: string } | { itemId: string, teamId: string } | { itemId: string, customCustomerId: string }],\n Item,\n false\n >\n & AsyncStoreProperty<\n \"products\",\n [options: CustomerProductsRequestOptions],\n CustomerProductsList,\n true\n >\n & AsyncStoreProperty<\n \"invoices\",\n [options: CustomerInvoicesRequestOptions],\n CustomerInvoicesList,\n true\n >\n & { [K in `redirectTo${Capitalize<keyof Omit<HandlerUrls, 'handler' | 'oauthCallback'>>}`]: (options?: RedirectToOptions) => Promise<void> }\n & AuthLike<HasTokenStore extends false ? { tokenStore: TokenStoreInit } : { tokenStore?: TokenStoreInit }>\n);\n/** @deprecated Use `HexclaveClientAppConstructor` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackClientAppConstructor = {\n new <\n TokenStoreType extends string,\n HasTokenStore extends (TokenStoreType extends {} ? true : boolean),\n ProjectId extends string\n >(options: StackClientAppConstructorOptions<HasTokenStore, ProjectId>): StackClientApp<HasTokenStore, ProjectId>,\n new(options: StackClientAppConstructorOptions<boolean, string>): StackClientApp<boolean, string>,\n\n [hexclaveAppInternalsSymbol]: {\n fromClientJson<HasTokenStore extends boolean, ProjectId extends string>(\n json: StackClientAppJson<HasTokenStore, ProjectId>\n ): StackClientApp<HasTokenStore, ProjectId>,\n },\n};\nexport type HexclaveClientAppConstructorOptions<HasTokenStore extends boolean, ProjectId extends string> = StackClientAppConstructorOptions<HasTokenStore, ProjectId>;\nexport type HexclaveClientAppJson<HasTokenStore extends boolean, ProjectId extends string> = StackClientAppJson<HasTokenStore, ProjectId>;\nexport type HexclaveClientApp<HasTokenStore extends boolean = boolean, ProjectId extends string = string> = StackClientApp<HasTokenStore, ProjectId>;\nexport type HexclaveClientAppConstructor = StackClientAppConstructor;\nexport const HexclaveClientApp: HexclaveClientAppConstructor = _HexclaveClientAppImpl;\n/** @deprecated Use `HexclaveClientApp` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport const StackClientApp: StackClientAppConstructor = HexclaveClientApp;\n"],"mappings":";;AAwLA,MAAa,yDAAkDA,CAAAA,CAAAA;;AAE/D,MAAa,iBAA4C"}
@@ -1,2 +1,2 @@
1
- import { A as HexclaveServerApp, F as StackServerAppConstructorOptions, M as HexclaveServerAppConstructorOptions, N as StackServerApp, P as StackServerAppConstructor, j as HexclaveServerAppConstructor } from "../../../../client-app-Majjw8Xp.js";
1
+ import { A as HexclaveServerApp, F as StackServerAppConstructorOptions, M as HexclaveServerAppConstructorOptions, N as StackServerApp, P as StackServerAppConstructor, j as HexclaveServerAppConstructor } from "../../../../client-app-B0kBC67Z.js";
2
2
  export { HexclaveServerApp, HexclaveServerAppConstructor, HexclaveServerAppConstructorOptions, StackServerApp, StackServerAppConstructor, StackServerAppConstructorOptions };
@@ -5,7 +5,7 @@ import { a as AdminTeamPermission, c as AdminTeamPermissionDefinitionUpdateOptio
5
5
  import { a as PlanUsageRow, i as PlanUsagePlanId, n as PlanUsageKind, r as PlanUsageNextPlanId, t as PlanUsage } from "../../index-B594jg4e.js";
6
6
  import { r as OAuthConnection, t as Connection } from "../../index-C_kxyHao.js";
7
7
  import { i as ServerContactChannel, t as ContactChannel } from "../../index-DN04TjLM.js";
8
- import { A as HexclaveServerApp, B as ServerListUsersOptions, C as HexclaveAdminAppConstructorOptions, D as StackAdminApp, F as StackServerAppConstructorOptions, G as ServerTeamUser, H as ServerTeamCreateOptions, I as EditableTeamMemberProfile, J as TeamInvitation, K as Team, L as ReceivedTeamInvitation, M as HexclaveServerAppConstructorOptions, N as StackServerApp, O as StackAdminAppConstructor, P as StackServerAppConstructor, Q as TeamUser, R as SentTeamInvitation, S as HexclaveAdminAppConstructor, St as User, U as ServerTeamMemberProfile, V as ServerTeam, W as ServerTeamUpdateOptions, Y as TeamMemberProfile, Z as TeamUpdateOptions, a as StackClientApp, b as EmailOutboxUpdateOptions, c as StackClientAppJson, ct as CurrentServerUser, d as AdminProjectCreateOptions, dt as OAuthProvider, f as AdminProjectUpdateOptions, gt as ServerUser, h as PushedConfigSource, ht as ServerOAuthProvider, i as HexclaveClientAppJson, it as Auth, j as HexclaveServerAppConstructor, k as StackAdminAppConstructorOptions, l as AdminOwnedProject, lt as CurrentUser, n as HexclaveClientAppConstructor, o as StackClientAppConstructor, ot as CurrentInternalServerUser, p as Project, q as TeamCreateOptions, r as HexclaveClientAppConstructorOptions, s as StackClientAppConstructorOptions, st as CurrentInternalUser, t as HexclaveClientApp, u as AdminProject, v as EmailOutboxListOptions, x as HexclaveAdminApp, y as EmailOutboxListResult } from "../../client-app-Majjw8Xp.js";
8
+ import { A as HexclaveServerApp, B as ServerListUsersOptions, C as HexclaveAdminAppConstructorOptions, D as StackAdminApp, F as StackServerAppConstructorOptions, G as ServerTeamUser, H as ServerTeamCreateOptions, I as EditableTeamMemberProfile, J as TeamInvitation, K as Team, L as ReceivedTeamInvitation, M as HexclaveServerAppConstructorOptions, N as StackServerApp, O as StackAdminAppConstructor, P as StackServerAppConstructor, Q as TeamUser, R as SentTeamInvitation, S as HexclaveAdminAppConstructor, St as User, U as ServerTeamMemberProfile, V as ServerTeam, W as ServerTeamUpdateOptions, Y as TeamMemberProfile, Z as TeamUpdateOptions, a as StackClientApp, b as EmailOutboxUpdateOptions, c as StackClientAppJson, ct as CurrentServerUser, d as AdminProjectCreateOptions, dt as OAuthProvider, f as AdminProjectUpdateOptions, gt as ServerUser, h as PushedConfigSource, ht as ServerOAuthProvider, i as HexclaveClientAppJson, it as Auth, j as HexclaveServerAppConstructor, k as StackAdminAppConstructorOptions, l as AdminOwnedProject, lt as CurrentUser, n as HexclaveClientAppConstructor, o as StackClientAppConstructor, ot as CurrentInternalServerUser, p as Project, q as TeamCreateOptions, r as HexclaveClientAppConstructorOptions, s as StackClientAppConstructorOptions, st as CurrentInternalUser, t as HexclaveClientApp, u as AdminProject, v as EmailOutboxListOptions, x as HexclaveAdminApp, y as EmailOutboxListResult } from "../../client-app-B0kBC67Z.js";
9
9
  import { a as AdminProjectConfigUpdateOptions, i as AdminProjectConfig, n as AdminEmailConfig, o as OAuthProviderConfig, r as AdminOAuthProviderConfig, s as ProjectConfig, t as AdminDomainConfig } from "../../index-Dq4xsW7_.js";
10
10
  import { r as getPagePrompt } from "../../url-targets-CWO0mjTr.js";
11
11
  export { type AdminDomainConfig, type AdminEmailConfig, type AdminEmailOutbox, type AdminEmailOutboxRecipient, type AdminEmailOutboxSimpleStatus, type AdminEmailOutboxStatus, type AdminOAuthProviderConfig, type AdminOwnedProject, type AdminProject, type AdminProjectConfig, type AdminProjectConfigUpdateOptions, type AdminProjectCreateOptions, type AdminProjectPermission, type AdminProjectPermissionDefinition, type AdminProjectPermissionDefinitionCreateOptions, type AdminProjectPermissionDefinitionUpdateOptions, type AdminProjectUpdateOptions, type AdminSendAttemptError, type AdminSentEmail, type AdminTeamPermission, type AdminTeamPermissionDefinition, type AdminTeamPermissionDefinitionCreateOptions, type AdminTeamPermissionDefinitionUpdateOptions, type Auth, type Connection, type ContactChannel, type CurrentInternalServerUser, type CurrentInternalUser, type CurrentServerUser, type CurrentUser, type EditableTeamMemberProfile, type EmailOutboxListOptions, type EmailOutboxListResult, type EmailOutboxUpdateOptions, type GetCurrentUserOptions, type GetCurrentUserOptions as GetUserOptions, type HandlerUrlOptions, type HandlerUrls, HexclaveAdminApp, type HexclaveAdminAppConstructor, type HexclaveAdminAppConstructorOptions, HexclaveClientApp, type HexclaveClientAppConstructor, type HexclaveClientAppConstructorOptions, type HexclaveClientAppJson, HexclaveServerApp, type HexclaveServerAppConstructor, type HexclaveServerAppConstructorOptions, type InternalApiKey, type InternalApiKeyBase, type InternalApiKeyBaseCrudRead, type InternalApiKeyCreateOptions, type InternalApiKeyFirstView, type OAuthConnection, type OAuthProvider, type OAuthProviderConfig, type OAuthScopesOnSignIn, type PlanUsage, type PlanUsageKind, type PlanUsageNextPlanId, type PlanUsagePlanId, type PlanUsageRow, type Project, type ProjectConfig, type PushedConfigSource, type ReceivedTeamInvitation, type ResolvedHandlerUrls, type SentTeamInvitation, type ServerContactChannel, type ServerListUsersOptions, type ServerOAuthProvider, type ServerTeam, type ServerTeamCreateOptions, type ServerTeamMemberProfile, type ServerTeamUpdateOptions, type ServerTeamUser, type ServerUser, StackAdminApp, type StackAdminAppConstructor, type StackAdminAppConstructorOptions, StackClientApp, type StackClientAppConstructor, type StackClientAppConstructorOptions, type StackClientAppJson, StackServerApp, type StackServerAppConstructor, type StackServerAppConstructorOptions, type Team, type TeamCreateOptions, type TeamInvitation, type TeamMemberProfile, type TeamUpdateOptions, type TeamUser, type User, getPagePrompt, hexclaveAppInternalsSymbol };
@@ -1,2 +1,2 @@
1
- import { _ as adminProjectUpdateOptionsToCrud, d as AdminProjectCreateOptions, f as AdminProjectUpdateOptions, g as adminProjectCreateOptionsToCrud, h as PushedConfigSource, l as AdminOwnedProject, m as PushConfigOptions, p as Project, u as AdminProject } from "../../../client-app-Majjw8Xp.js";
1
+ import { _ as adminProjectUpdateOptionsToCrud, d as AdminProjectCreateOptions, f as AdminProjectUpdateOptions, g as adminProjectCreateOptionsToCrud, h as PushedConfigSource, l as AdminOwnedProject, m as PushConfigOptions, p as Project, u as AdminProject } from "../../../client-app-B0kBC67Z.js";
2
2
  export { AdminOwnedProject, AdminProject, AdminProjectCreateOptions, AdminProjectUpdateOptions, Project, PushConfigOptions, PushedConfigSource, adminProjectCreateOptionsToCrud, adminProjectUpdateOptionsToCrud };
@@ -1,2 +1,2 @@
1
- import { $ as serverTeamCreateOptionsToCrud, B as ServerListUsersOptions, G as ServerTeamUser, H as ServerTeamCreateOptions, I as EditableTeamMemberProfile, J as TeamInvitation, K as Team, L as ReceivedTeamInvitation, Q as TeamUser, R as SentTeamInvitation, U as ServerTeamMemberProfile, V as ServerTeam, W as ServerTeamUpdateOptions, X as TeamMemberProfileUpdateOptions, Y as TeamMemberProfile, Z as TeamUpdateOptions, et as serverTeamUpdateOptionsToCrud, nt as teamUpdateOptionsToCrud, q as TeamCreateOptions, tt as teamCreateOptionsToCrud, z as ServerListTeamsOptions } from "../../../client-app-Majjw8Xp.js";
1
+ import { $ as serverTeamCreateOptionsToCrud, B as ServerListUsersOptions, G as ServerTeamUser, H as ServerTeamCreateOptions, I as EditableTeamMemberProfile, J as TeamInvitation, K as Team, L as ReceivedTeamInvitation, Q as TeamUser, R as SentTeamInvitation, U as ServerTeamMemberProfile, V as ServerTeam, W as ServerTeamUpdateOptions, X as TeamMemberProfileUpdateOptions, Y as TeamMemberProfile, Z as TeamUpdateOptions, et as serverTeamUpdateOptionsToCrud, nt as teamUpdateOptionsToCrud, q as TeamCreateOptions, tt as teamCreateOptionsToCrud, z as ServerListTeamsOptions } from "../../../client-app-B0kBC67Z.js";
2
2
  export { EditableTeamMemberProfile, ReceivedTeamInvitation, SentTeamInvitation, ServerListTeamsOptions, ServerListUsersOptions, ServerTeam, ServerTeamCreateOptions, ServerTeamMemberProfile, ServerTeamUpdateOptions, ServerTeamUser, Team, TeamCreateOptions, TeamInvitation, TeamMemberProfile, TeamMemberProfileUpdateOptions, TeamUpdateOptions, TeamUser, serverTeamCreateOptionsToCrud, serverTeamUpdateOptionsToCrud, teamCreateOptionsToCrud, teamUpdateOptionsToCrud };
@@ -1,2 +1,2 @@
1
- import { Ct as UserExtra, Dt as userUpdateOptionsToCrud, Et as serverUserUpdateOptionsToCrud, Ot as withUserDestructureGuard, St as User, Tt as serverUserCreateOptionsToCrud, _t as ServerUserCreateOptions, at as BaseUser, bt as SyncedPartialUser, ct as CurrentServerUser, dt as OAuthProvider, ft as ProjectCurrentServerUser, gt as ServerUser, ht as ServerOAuthProvider, it as Auth, lt as CurrentUser, mt as ServerBaseUser, ot as CurrentInternalServerUser, pt as ProjectCurrentUser, rt as ActiveSession, st as CurrentInternalUser, ut as InternalUserExtra, vt as ServerUserUpdateOptions, wt as UserUpdateOptions, xt as TokenPartialUser, yt as SyncedPartialServerUser } from "../../../client-app-Majjw8Xp.js";
1
+ import { Ct as UserExtra, Dt as userUpdateOptionsToCrud, Et as serverUserUpdateOptionsToCrud, Ot as withUserDestructureGuard, St as User, Tt as serverUserCreateOptionsToCrud, _t as ServerUserCreateOptions, at as BaseUser, bt as SyncedPartialUser, ct as CurrentServerUser, dt as OAuthProvider, ft as ProjectCurrentServerUser, gt as ServerUser, ht as ServerOAuthProvider, it as Auth, lt as CurrentUser, mt as ServerBaseUser, ot as CurrentInternalServerUser, pt as ProjectCurrentUser, rt as ActiveSession, st as CurrentInternalUser, ut as InternalUserExtra, vt as ServerUserUpdateOptions, wt as UserUpdateOptions, xt as TokenPartialUser, yt as SyncedPartialServerUser } from "../../../client-app-B0kBC67Z.js";
2
2
  export { ActiveSession, Auth, BaseUser, CurrentInternalServerUser, CurrentInternalUser, CurrentServerUser, CurrentUser, InternalUserExtra, OAuthProvider, ProjectCurrentServerUser, ProjectCurrentUser, ServerBaseUser, ServerOAuthProvider, ServerUser, ServerUserCreateOptions, ServerUserUpdateOptions, SyncedPartialServerUser, SyncedPartialUser, TokenPartialUser, User, UserExtra, UserUpdateOptions, serverUserCreateOptionsToCrud, serverUserUpdateOptionsToCrud, userUpdateOptionsToCrud, withUserDestructureGuard };
@@ -1,2 +1,2 @@
1
- import { n as useStackApp, r as useUser, t as useHexclaveApp } from "../hooks-BKXOF6jh.js";
1
+ import { n as useStackApp, r as useUser, t as useHexclaveApp } from "../hooks-ykQ7Wsco.js";
2
2
  export { useHexclaveApp, useStackApp, useUser };
@@ -1,4 +1,4 @@
1
- import { a as StackClientApp } from "../client-app-Majjw8Xp.js";
1
+ import { a as StackClientApp } from "../client-app-B0kBC67Z.js";
2
2
  import React from "react";
3
3
 
4
4
  //#region src/providers/hexclave-context.d.ts
@@ -1,4 +1,4 @@
1
- import { a as StackClientApp, c as StackClientAppJson } from "../client-app-Majjw8Xp.js";
1
+ import { a as StackClientApp, c as StackClientAppJson } from "../client-app-B0kBC67Z.js";
2
2
  import { CurrentUserCrud } from "@hexclave/shared/dist/interface/crud/current-user";
3
3
  import React from "react";
4
4
 
@@ -1,2 +1,2 @@
1
- import { n as HexclaveProvider, r as StackProvider, t as ActiveProvider } from "../hexclave-provider-IAd7nlbi.js";
1
+ import { n as HexclaveProvider, r as StackProvider, t as ActiveProvider } from "../hexclave-provider-BQ9wrtBt.js";
2
2
  export { HexclaveProvider, StackProvider, ActiveProvider as default };
@@ -1,4 +1,4 @@
1
- import { a as StackClientApp } from "../client-app-Majjw8Xp.js";
1
+ import { a as StackClientApp } from "../client-app-B0kBC67Z.js";
2
2
  //#region src/pushed-config-error-overlay/index.d.ts
3
3
  declare function mountPushedConfigErrorOverlay(app: StackClientApp<true>): () => void;
4
4
  //#endregion
@@ -329,7 +329,7 @@ function mountPushedConfigErrorOverlay(app) {
329
329
  minimized = false;
330
330
  return;
331
331
  }
332
- const issueMessage = issue.messages.join("\n");
332
+ const issueMessage = "Hexclave config " + issue.kind + ": " + issue.messages.join("\n");
333
333
  const issueKey = `${app.projectId}:${issue.kind}:${issueMessage}`;
334
334
  const issueLabel = issue.kind === "error" ? "error" : "warning";
335
335
  const issueTitle = issue.kind === "error" ? "Your Hexclave config has been saved, but contains errors" : "Your Hexclave config has been saved, but has warnings";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["envVars"],"sources":["../../src/pushed-config-error-overlay/index.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { captureError } from \"@hexclave/shared/dist/utils/errors\";\nimport { runAsynchronously } from \"@hexclave/shared/dist/utils/promises\";\nimport { isLocalhost } from \"@hexclave/shared/dist/utils/urls\";\nimport { envVars } from \"../generated/env\";\nimport { getInPageUiBaseCSS } from \"../in-page-ui/base-styles\";\nimport { canMountIntoDom, getGlobalUiInstance, h, setGlobalUiInstance, setHtml } from \"../in-page-ui/dom\";\nimport type { StackClientApp } from \"../lib/hexclave-app\";\n\nconst GLOBAL_INSTANCE_KEY = \"__hexclave-pushed-config-error-overlay\";\nconst MINIMIZED_STORAGE_KEY = \"hexclave-pushed-config-error-minimized-key\";\nconst REFRESH_INTERVAL_MS = 5_000;\nconst HEXCLAVE_LOGO_SVG = '<svg width=\"16\" height=\"16\" viewBox=\"0 0 48 48\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3\" stroke-linejoin=\"miter\"><path d=\"M 24 4 L 41.32 14 L 41.32 34 L 24 44 L 6.68 34 L 6.68 14 Z\"/><path d=\"M 11 16.87 L 14 15.13 L 14 32.87 L 11 31.13 Z\" fill=\"currentColor\" stroke=\"none\"/><path d=\"M 11 16.87 L 14 15.13 L 14 32.87 L 11 31.13 Z\" fill=\"currentColor\" stroke=\"none\" transform=\"rotate(120 24 24)\"/><path d=\"M 11 16.87 L 14 15.13 L 14 32.87 L 11 31.13 Z\" fill=\"currentColor\" stroke=\"none\" transform=\"rotate(240 24 24)\"/></svg>';\nconst COPY_ICON_SVG = '<svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.25\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\"/><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"/></svg>';\n\ntype ConfigIssue = {\n kind: \"error\" | \"warning\",\n messages: string[],\n};\n\nconst css = getInPageUiBaseCSS(\".hexclave-config-error-overlay\") + `\n .hexclave-config-error-overlay .hce-backdrop {\n position: fixed;\n inset: 0;\n z-index: 2147483647;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 24px;\n background: rgba(0, 0, 0, 0.46);\n backdrop-filter: blur(6px);\n overflow: auto;\n }\n\n .hexclave-config-error-overlay .hce-card {\n --hce-status: var(--sdt-error);\n width: min(720px, calc(100vw - 32px));\n max-height: min(640px, calc(100dvh - 48px));\n border: 1px solid color-mix(in srgb, var(--hce-status) 35%, var(--sdt-border));\n border-radius: 18px;\n background: var(--sdt-overlay-bg);\n box-shadow: var(--sdt-shadow);\n backdrop-filter: blur(18px);\n display: flex;\n overflow: hidden;\n }\n\n .hexclave-config-error-overlay .hce-card-warning {\n --hce-status: var(--sdt-warning);\n }\n\n .hexclave-config-error-overlay .hce-card-inner {\n padding: 18px;\n width: 100%;\n overflow: auto;\n }\n\n .hexclave-config-error-overlay .hce-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 12px;\n margin-bottom: 12px;\n }\n\n .hexclave-config-error-overlay .hce-title-row {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n min-width: 0;\n }\n\n .hexclave-config-error-overlay .hce-logo {\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 34px;\n height: 34px;\n border-radius: 10px;\n background: var(--hce-status);\n color: white;\n box-shadow: 0 10px 30px color-mix(in srgb, var(--hce-status) 32%, transparent);\n }\n\n .hexclave-config-error-overlay .hce-badge {\n display: inline-flex;\n flex-shrink: 0;\n padding: 2px 6px;\n border-radius: 999px;\n background: var(--hce-status);\n color: white;\n font-size: 10px;\n font-weight: 700;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n }\n\n .hexclave-config-error-overlay .hce-title {\n color: var(--sdt-text);\n margin-top: 4px;\n font-size: 18px;\n font-weight: 700;\n line-height: 1.25;\n }\n\n .hexclave-config-error-overlay .hce-actions {\n display: flex;\n gap: 4px;\n }\n\n .hexclave-config-error-overlay .hce-icon-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: 1px solid var(--sdt-border);\n border-radius: 8px;\n background: var(--sdt-bg-elevated);\n color: var(--sdt-text-secondary);\n cursor: pointer;\n font: inherit;\n line-height: 1;\n vertical-align: top;\n }\n\n .hexclave-config-error-overlay .hce-icon-btn svg {\n display: block;\n flex-shrink: 0;\n }\n\n .hexclave-config-error-overlay .hce-text-btn {\n align-items: center;\n gap: 6px;\n min-height: 28px;\n padding: 0 10px;\n width: auto;\n font-size: 12px;\n line-height: 1;\n }\n\n .hexclave-config-error-overlay .hce-icon-btn:hover {\n background: var(--sdt-bg-hover);\n color: var(--sdt-text);\n }\n\n .hexclave-config-error-overlay .hce-body {\n color: var(--sdt-text-secondary);\n font-size: 14px;\n line-height: 1.5;\n }\n\n .hexclave-config-error-overlay .hce-message-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 10px;\n margin-top: 14px;\n margin-bottom: 8px;\n }\n\n .hexclave-config-error-overlay .hce-message-label {\n color: var(--sdt-text);\n font-size: 12px;\n font-weight: 650;\n }\n\n .hexclave-config-error-overlay .hce-message {\n padding: 12px;\n max-height: min(260px, max(96px, 30dvh));\n overflow: auto;\n border: 1px solid var(--sdt-border-subtle);\n border-radius: 10px;\n background: var(--sdt-bg-subtle);\n color: var(--sdt-text);\n font-family: var(--sdt-font-mono);\n font-size: 12px;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n }\n\n .hexclave-config-error-overlay .hce-footer {\n margin-top: 10px;\n color: var(--sdt-text-tertiary);\n font-size: 12px;\n }\n\n .hexclave-config-error-overlay .hce-pill {\n position: fixed;\n right: 18px;\n bottom: 18px;\n z-index: 2147483647;\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px 8px 8px;\n --hce-status: var(--sdt-error);\n border: 1px solid color-mix(in srgb, var(--hce-status) 35%, var(--sdt-border));\n border-radius: 999px;\n background: var(--sdt-overlay-bg);\n box-shadow: var(--sdt-trigger-shadow);\n color: var(--sdt-text);\n cursor: pointer;\n font: inherit;\n backdrop-filter: blur(18px);\n }\n\n .hexclave-config-error-overlay .hce-pill-warning {\n --hce-status: var(--sdt-warning);\n }\n\n .hexclave-config-error-overlay .hce-pill-logo {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 26px;\n height: 26px;\n border-radius: 999px;\n background: var(--hce-status);\n color: white;\n }\n\n @media (max-height: 520px) {\n .hexclave-config-error-overlay .hce-backdrop {\n align-items: flex-start;\n padding: 12px;\n }\n\n .hexclave-config-error-overlay .hce-card {\n width: min(720px, calc(100vw - 24px));\n max-height: calc(100dvh - 24px);\n }\n\n .hexclave-config-error-overlay .hce-card-inner {\n padding: 12px;\n }\n\n .hexclave-config-error-overlay .hce-header {\n margin-bottom: 8px;\n }\n\n .hexclave-config-error-overlay .hce-title {\n font-size: 16px;\n }\n\n .hexclave-config-error-overlay .hce-body {\n font-size: 13px;\n }\n\n .hexclave-config-error-overlay .hce-message {\n max-height: max(80px, 24dvh);\n }\n }\n`;\n\nfunction storageGet(key: string): string | null {\n try {\n return localStorage.getItem(key);\n } catch {\n return null;\n }\n}\n\nfunction storageSet(key: string, value: string): void {\n try {\n localStorage.setItem(key, value);\n } catch {\n // Storage may be unavailable in private or embedded contexts.\n }\n}\n\nfunction storageRemove(key: string): void {\n try {\n localStorage.removeItem(key);\n } catch {\n // Storage may be unavailable in private or embedded contexts.\n }\n}\n\nfunction shouldMount(): boolean {\n if (!canMountIntoDom()) {\n return false;\n }\n\n const nodeEnv = envVars.NODE_ENV;\n if (nodeEnv !== undefined) {\n return nodeEnv === \"development\";\n }\n\n try {\n const url = new URL(window.location.href);\n if (url.protocol === \"file:\") {\n return true;\n }\n } catch {\n return false;\n }\n return isLocalhost(window.location.href);\n}\n\nasync function copyTextToClipboard(text: string): Promise<void> {\n const clipboard: unknown = Reflect.get(navigator, \"clipboard\");\n const writeText = clipboard != null && typeof clipboard === \"object\"\n ? Reflect.get(clipboard, \"writeText\")\n : null;\n if (typeof writeText === \"function\") {\n await writeText.call(clipboard, text);\n return;\n }\n\n const textarea = h(\"textarea\", {\n style: {\n position: \"fixed\",\n left: \"-9999px\",\n top: \"0\",\n opacity: \"0\",\n },\n readonly: \"true\",\n }) as HTMLTextAreaElement;\n textarea.value = text;\n document.body.appendChild(textarea);\n textarea.select();\n const copied = document.execCommand(\"copy\");\n textarea.remove();\n if (!copied) {\n throw new Error(\"Browser refused to copy the config error message.\");\n }\n}\n\nfunction buildConfigIssueAiPrompt(issue: ConfigIssue): string {\n const issueLabel = issue.kind === \"error\" ? \"error\" : \"warning\";\n return [\n `Help me fix this Hexclave config ${issueLabel}.`,\n \"\",\n \"Hexclave reminder:\",\n `This ${issueLabel} comes from a pushed Hexclave config file. The app may keep running with the synced Hexclave config, but I need to fix the config file mentioned in the message and save it again so Hexclave can sync the config successfully and clear the dialog. Use your web fetch tool to read https://skill.hexclave.com to learn more about Hexclave.`,\n \"\",\n issue.kind === \"error\" ? \"Error message:\" : \"Warning message:\",\n issue.messages.join(\"\\n\"),\n \"\",\n \"Please explain the likely cause, identify the config key or value I should change, and suggest the smallest safe fix.\",\n ].join(\"\\n\");\n}\n\nexport function mountPushedConfigErrorOverlay(app: StackClientApp<true>): () => void {\n if (!shouldMount()) {\n return () => {};\n }\n\n getGlobalUiInstance(GLOBAL_INSTANCE_KEY)?.cleanup();\n\n const root = h(\"div\", { className: \"hexclave-config-error-overlay\" });\n const style = h(\"style\", null, css);\n root.appendChild(style);\n document.body.appendChild(root);\n\n let disposed = false;\n let lastErrorKey: string | null = null;\n let lastConsoleErrorKey: string | null = null;\n let minimized = false;\n\n const render = (issue: ConfigIssue | null) => {\n root.replaceChildren(style);\n if (issue == null) {\n lastErrorKey = null;\n minimized = false;\n return;\n }\n\n const issueMessage = issue.messages.join(\"\\n\");\n const issueKey = `${app.projectId}:${issue.kind}:${issueMessage}`;\n const issueLabel = issue.kind === \"error\" ? \"error\" : \"warning\";\n const issueTitle = issue.kind === \"error\"\n ? \"Your Hexclave config has been saved, but contains errors\"\n : \"Your Hexclave config has been saved, but has warnings\";\n const bodyText = issue.kind === \"error\"\n ? \"Your app can keep running, but Hexclave is still using the last valid config until this is fixed.\"\n : \"Your app can keep running, but part of your Hexclave config may not behave the way you expect until this is fixed.\";\n const footerText = issue.kind === \"error\"\n ? \"Fix the config file mentioned above and save it again. This message will disappear after the config sync succeeds.\"\n : \"Fix the config file mentioned above and save it again. This warning will disappear after Hexclave syncs a config without warnings.\";\n if (issueKey !== lastConsoleErrorKey) {\n lastConsoleErrorKey = issueKey;\n const consoleMessage = `[Hexclave] Config ${issueLabel}: ${issueMessage}`;\n if (issue.kind === \"error\") {\n console.error(consoleMessage);\n } else {\n console.warn(consoleMessage);\n }\n }\n\n if (issueKey !== lastErrorKey) {\n lastErrorKey = issueKey;\n minimized = storageGet(MINIMIZED_STORAGE_KEY) === issueKey;\n }\n\n if (minimized) {\n const logoSpan = h(\"span\", { className: \"hce-pill-logo\" });\n setHtml(logoSpan, HEXCLAVE_LOGO_SVG);\n root.appendChild(h(\"button\", {\n className: issue.kind === \"error\" ? \"hce-pill\" : \"hce-pill hce-pill-warning\",\n type: \"button\",\n onClick: () => {\n minimized = false;\n storageRemove(MINIMIZED_STORAGE_KEY);\n render(issue);\n },\n },\n logoSpan,\n h(\"span\", null, issue.kind === \"error\" ? \"Config error\" : \"Config warning\")));\n return;\n }\n\n const logoSpan = h(\"span\", { className: \"hce-logo\" });\n setHtml(logoSpan, HEXCLAVE_LOGO_SVG);\n const copyButton = h(\"button\", {\n className: \"hce-icon-btn hce-text-btn\",\n type: \"button\",\n title: issue.kind === \"error\" ? \"Copy error message\" : \"Copy warning message\",\n \"aria-label\": issue.kind === \"error\" ? \"Copy config error message\" : \"Copy config warning message\",\n onClick: () => {\n runAsynchronously(async () => {\n await copyTextToClipboard(issueMessage);\n copyButton.textContent = \"Copied\";\n setTimeout(() => {\n setHtml(copyButton, `${COPY_ICON_SVG}Copy`);\n }, 1500);\n }, {\n noErrorLogging: true,\n onError: (copyError) => {\n captureError(\"pushed-config-error-overlay-copy\", copyError);\n copyButton.textContent = \"Copy failed\";\n setTimeout(() => {\n setHtml(copyButton, `${COPY_ICON_SVG}Copy`);\n }, 1500);\n },\n });\n },\n });\n setHtml(copyButton, `${COPY_ICON_SVG}Copy`);\n\n const aiPromptCopyButton = h(\"button\", {\n className: \"hce-icon-btn\",\n type: \"button\",\n title: \"Copy AI prompt\",\n \"aria-label\": issue.kind === \"error\" ? \"Copy AI prompt for config error\" : \"Copy AI prompt for config warning\",\n onClick: () => {\n runAsynchronously(async () => {\n await copyTextToClipboard(buildConfigIssueAiPrompt(issue));\n aiPromptCopyButton.textContent = \"✓\";\n setTimeout(() => {\n setHtml(aiPromptCopyButton, COPY_ICON_SVG);\n }, 1500);\n }, {\n noErrorLogging: true,\n onError: (copyError) => {\n captureError(\"pushed-config-error-overlay-copy-ai-prompt\", copyError);\n aiPromptCopyButton.textContent = \"!\";\n setTimeout(() => {\n setHtml(aiPromptCopyButton, COPY_ICON_SVG);\n }, 1500);\n },\n });\n },\n });\n setHtml(aiPromptCopyButton, COPY_ICON_SVG);\n\n root.appendChild(h(\"div\", { className: \"hce-backdrop\" },\n h(\"div\", { className: issue.kind === \"error\" ? \"hce-card\" : \"hce-card hce-card-warning\", role: \"alertdialog\", \"aria-modal\": \"true\", \"aria-label\": `Hexclave config ${issueLabel}` },\n h(\"div\", { className: \"hce-card-inner\" },\n h(\"div\", { className: \"hce-header\" },\n h(\"div\", { className: \"hce-title-row\" },\n logoSpan,\n h(\"div\", null,\n h(\"span\", { className: \"hce-badge\" }, `Config ${issueLabel}`),\n h(\"div\", { className: \"hce-title\" }, issueTitle),\n ),\n ),\n h(\"div\", { className: \"hce-actions\" },\n aiPromptCopyButton,\n h(\"button\", {\n className: \"hce-icon-btn\",\n type: \"button\",\n title: \"Minimize\",\n \"aria-label\": issue.kind === \"error\" ? \"Minimize config error\" : \"Minimize config warning\",\n onClick: () => {\n minimized = true;\n storageSet(MINIMIZED_STORAGE_KEY, issueKey);\n render(issue);\n },\n }, \"–\"),\n ),\n ),\n h(\"div\", { className: \"hce-body\" },\n bodyText,\n h(\"div\", { className: \"hce-message-header\" },\n h(\"div\", { className: \"hce-message-label\" }, issue.kind === \"error\" ? \"Error message\" : \"Warning message\"),\n copyButton,\n ),\n h(\"div\", { className: \"hce-message\" }, issueMessage),\n h(\"div\", { className: \"hce-footer\" }, footerText),\n ),\n ),\n )));\n };\n\n const refresh = () => {\n if (disposed || !canMountIntoDom()) {\n return;\n }\n runAsynchronously(async () => {\n const project = await app.getProject();\n if (disposed) {\n return;\n }\n render(project.pushedConfigError == null\n ? project.configWarnings.length === 0\n ? null\n : { kind: \"warning\", messages: project.configWarnings.map((warning) => warning.message) }\n : { kind: \"error\", messages: [project.pushedConfigError.message] });\n }, {\n noErrorLogging: true,\n onError: (error) => {\n captureError(\"pushed-config-error-overlay-refresh\", error);\n },\n });\n };\n\n // This is mounted from the base client-app constructor, which also runs\n // before subclass field initializers. Defer the first app call so overridden\n // methods like adminApp.getProject() can safely touch subclass caches.\n queueMicrotask(refresh);\n const interval = setInterval(refresh, REFRESH_INTERVAL_MS);\n\n const cleanup = () => {\n disposed = true;\n clearInterval(interval);\n root.remove();\n if (getGlobalUiInstance(GLOBAL_INSTANCE_KEY)?.cleanup === cleanup) {\n setGlobalUiInstance(GLOBAL_INSTANCE_KEY, null);\n }\n };\n setGlobalUiInstance(GLOBAL_INSTANCE_KEY, { cleanup });\n return cleanup;\n}\n\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["envVars"],"sources":["../../src/pushed-config-error-overlay/index.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { captureError } from \"@hexclave/shared/dist/utils/errors\";\nimport { runAsynchronously } from \"@hexclave/shared/dist/utils/promises\";\nimport { isLocalhost } from \"@hexclave/shared/dist/utils/urls\";\nimport { envVars } from \"../generated/env\";\nimport { getInPageUiBaseCSS } from \"../in-page-ui/base-styles\";\nimport { canMountIntoDom, getGlobalUiInstance, h, setGlobalUiInstance, setHtml } from \"../in-page-ui/dom\";\nimport type { StackClientApp } from \"../lib/hexclave-app\";\n\nconst GLOBAL_INSTANCE_KEY = \"__hexclave-pushed-config-error-overlay\";\nconst MINIMIZED_STORAGE_KEY = \"hexclave-pushed-config-error-minimized-key\";\nconst REFRESH_INTERVAL_MS = 5_000;\nconst HEXCLAVE_LOGO_SVG = '<svg width=\"16\" height=\"16\" viewBox=\"0 0 48 48\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3\" stroke-linejoin=\"miter\"><path d=\"M 24 4 L 41.32 14 L 41.32 34 L 24 44 L 6.68 34 L 6.68 14 Z\"/><path d=\"M 11 16.87 L 14 15.13 L 14 32.87 L 11 31.13 Z\" fill=\"currentColor\" stroke=\"none\"/><path d=\"M 11 16.87 L 14 15.13 L 14 32.87 L 11 31.13 Z\" fill=\"currentColor\" stroke=\"none\" transform=\"rotate(120 24 24)\"/><path d=\"M 11 16.87 L 14 15.13 L 14 32.87 L 11 31.13 Z\" fill=\"currentColor\" stroke=\"none\" transform=\"rotate(240 24 24)\"/></svg>';\nconst COPY_ICON_SVG = '<svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.25\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\"/><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"/></svg>';\n\ntype ConfigIssue = {\n kind: \"error\" | \"warning\",\n messages: string[],\n};\n\nconst css = getInPageUiBaseCSS(\".hexclave-config-error-overlay\") + `\n .hexclave-config-error-overlay .hce-backdrop {\n position: fixed;\n inset: 0;\n z-index: 2147483647;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 24px;\n background: rgba(0, 0, 0, 0.46);\n backdrop-filter: blur(6px);\n overflow: auto;\n }\n\n .hexclave-config-error-overlay .hce-card {\n --hce-status: var(--sdt-error);\n width: min(720px, calc(100vw - 32px));\n max-height: min(640px, calc(100dvh - 48px));\n border: 1px solid color-mix(in srgb, var(--hce-status) 35%, var(--sdt-border));\n border-radius: 18px;\n background: var(--sdt-overlay-bg);\n box-shadow: var(--sdt-shadow);\n backdrop-filter: blur(18px);\n display: flex;\n overflow: hidden;\n }\n\n .hexclave-config-error-overlay .hce-card-warning {\n --hce-status: var(--sdt-warning);\n }\n\n .hexclave-config-error-overlay .hce-card-inner {\n padding: 18px;\n width: 100%;\n overflow: auto;\n }\n\n .hexclave-config-error-overlay .hce-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 12px;\n margin-bottom: 12px;\n }\n\n .hexclave-config-error-overlay .hce-title-row {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n min-width: 0;\n }\n\n .hexclave-config-error-overlay .hce-logo {\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 34px;\n height: 34px;\n border-radius: 10px;\n background: var(--hce-status);\n color: white;\n box-shadow: 0 10px 30px color-mix(in srgb, var(--hce-status) 32%, transparent);\n }\n\n .hexclave-config-error-overlay .hce-badge {\n display: inline-flex;\n flex-shrink: 0;\n padding: 2px 6px;\n border-radius: 999px;\n background: var(--hce-status);\n color: white;\n font-size: 10px;\n font-weight: 700;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n }\n\n .hexclave-config-error-overlay .hce-title {\n color: var(--sdt-text);\n margin-top: 4px;\n font-size: 18px;\n font-weight: 700;\n line-height: 1.25;\n }\n\n .hexclave-config-error-overlay .hce-actions {\n display: flex;\n gap: 4px;\n }\n\n .hexclave-config-error-overlay .hce-icon-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: 1px solid var(--sdt-border);\n border-radius: 8px;\n background: var(--sdt-bg-elevated);\n color: var(--sdt-text-secondary);\n cursor: pointer;\n font: inherit;\n line-height: 1;\n vertical-align: top;\n }\n\n .hexclave-config-error-overlay .hce-icon-btn svg {\n display: block;\n flex-shrink: 0;\n }\n\n .hexclave-config-error-overlay .hce-text-btn {\n align-items: center;\n gap: 6px;\n min-height: 28px;\n padding: 0 10px;\n width: auto;\n font-size: 12px;\n line-height: 1;\n }\n\n .hexclave-config-error-overlay .hce-icon-btn:hover {\n background: var(--sdt-bg-hover);\n color: var(--sdt-text);\n }\n\n .hexclave-config-error-overlay .hce-body {\n color: var(--sdt-text-secondary);\n font-size: 14px;\n line-height: 1.5;\n }\n\n .hexclave-config-error-overlay .hce-message-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 10px;\n margin-top: 14px;\n margin-bottom: 8px;\n }\n\n .hexclave-config-error-overlay .hce-message-label {\n color: var(--sdt-text);\n font-size: 12px;\n font-weight: 650;\n }\n\n .hexclave-config-error-overlay .hce-message {\n padding: 12px;\n max-height: min(260px, max(96px, 30dvh));\n overflow: auto;\n border: 1px solid var(--sdt-border-subtle);\n border-radius: 10px;\n background: var(--sdt-bg-subtle);\n color: var(--sdt-text);\n font-family: var(--sdt-font-mono);\n font-size: 12px;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n }\n\n .hexclave-config-error-overlay .hce-footer {\n margin-top: 10px;\n color: var(--sdt-text-tertiary);\n font-size: 12px;\n }\n\n .hexclave-config-error-overlay .hce-pill {\n position: fixed;\n right: 18px;\n bottom: 18px;\n z-index: 2147483647;\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px 8px 8px;\n --hce-status: var(--sdt-error);\n border: 1px solid color-mix(in srgb, var(--hce-status) 35%, var(--sdt-border));\n border-radius: 999px;\n background: var(--sdt-overlay-bg);\n box-shadow: var(--sdt-trigger-shadow);\n color: var(--sdt-text);\n cursor: pointer;\n font: inherit;\n backdrop-filter: blur(18px);\n }\n\n .hexclave-config-error-overlay .hce-pill-warning {\n --hce-status: var(--sdt-warning);\n }\n\n .hexclave-config-error-overlay .hce-pill-logo {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 26px;\n height: 26px;\n border-radius: 999px;\n background: var(--hce-status);\n color: white;\n }\n\n @media (max-height: 520px) {\n .hexclave-config-error-overlay .hce-backdrop {\n align-items: flex-start;\n padding: 12px;\n }\n\n .hexclave-config-error-overlay .hce-card {\n width: min(720px, calc(100vw - 24px));\n max-height: calc(100dvh - 24px);\n }\n\n .hexclave-config-error-overlay .hce-card-inner {\n padding: 12px;\n }\n\n .hexclave-config-error-overlay .hce-header {\n margin-bottom: 8px;\n }\n\n .hexclave-config-error-overlay .hce-title {\n font-size: 16px;\n }\n\n .hexclave-config-error-overlay .hce-body {\n font-size: 13px;\n }\n\n .hexclave-config-error-overlay .hce-message {\n max-height: max(80px, 24dvh);\n }\n }\n`;\n\nfunction storageGet(key: string): string | null {\n try {\n return localStorage.getItem(key);\n } catch {\n return null;\n }\n}\n\nfunction storageSet(key: string, value: string): void {\n try {\n localStorage.setItem(key, value);\n } catch {\n // Storage may be unavailable in private or embedded contexts.\n }\n}\n\nfunction storageRemove(key: string): void {\n try {\n localStorage.removeItem(key);\n } catch {\n // Storage may be unavailable in private or embedded contexts.\n }\n}\n\nfunction shouldMount(): boolean {\n if (!canMountIntoDom()) {\n return false;\n }\n\n const nodeEnv = envVars.NODE_ENV;\n if (nodeEnv !== undefined) {\n return nodeEnv === \"development\";\n }\n\n try {\n const url = new URL(window.location.href);\n if (url.protocol === \"file:\") {\n return true;\n }\n } catch {\n return false;\n }\n return isLocalhost(window.location.href);\n}\n\nasync function copyTextToClipboard(text: string): Promise<void> {\n const clipboard: unknown = Reflect.get(navigator, \"clipboard\");\n const writeText = clipboard != null && typeof clipboard === \"object\"\n ? Reflect.get(clipboard, \"writeText\")\n : null;\n if (typeof writeText === \"function\") {\n await writeText.call(clipboard, text);\n return;\n }\n\n const textarea = h(\"textarea\", {\n style: {\n position: \"fixed\",\n left: \"-9999px\",\n top: \"0\",\n opacity: \"0\",\n },\n readonly: \"true\",\n }) as HTMLTextAreaElement;\n textarea.value = text;\n document.body.appendChild(textarea);\n textarea.select();\n const copied = document.execCommand(\"copy\");\n textarea.remove();\n if (!copied) {\n throw new Error(\"Browser refused to copy the config error message.\");\n }\n}\n\nfunction buildConfigIssueAiPrompt(issue: ConfigIssue): string {\n const issueLabel = issue.kind === \"error\" ? \"error\" : \"warning\";\n return [\n `Help me fix this Hexclave config ${issueLabel}.`,\n \"\",\n \"Hexclave reminder:\",\n `This ${issueLabel} comes from a pushed Hexclave config file. The app may keep running with the synced Hexclave config, but I need to fix the config file mentioned in the message and save it again so Hexclave can sync the config successfully and clear the dialog. Use your web fetch tool to read https://skill.hexclave.com to learn more about Hexclave.`,\n \"\",\n issue.kind === \"error\" ? \"Error message:\" : \"Warning message:\",\n issue.messages.join(\"\\n\"),\n \"\",\n \"Please explain the likely cause, identify the config key or value I should change, and suggest the smallest safe fix.\",\n ].join(\"\\n\");\n}\n\nexport function mountPushedConfigErrorOverlay(app: StackClientApp<true>): () => void {\n if (!shouldMount()) {\n return () => {};\n }\n\n getGlobalUiInstance(GLOBAL_INSTANCE_KEY)?.cleanup();\n\n const root = h(\"div\", { className: \"hexclave-config-error-overlay\" });\n const style = h(\"style\", null, css);\n root.appendChild(style);\n document.body.appendChild(root);\n\n let disposed = false;\n let lastErrorKey: string | null = null;\n let lastConsoleErrorKey: string | null = null;\n let minimized = false;\n\n const render = (issue: ConfigIssue | null) => {\n root.replaceChildren(style);\n if (issue == null) {\n lastErrorKey = null;\n minimized = false;\n return;\n }\n\n const issueMessage = \"Hexclave config \" + issue.kind + \": \" + issue.messages.join(\"\\n\");\n const issueKey = `${app.projectId}:${issue.kind}:${issueMessage}`;\n const issueLabel = issue.kind === \"error\" ? \"error\" : \"warning\";\n const issueTitle = issue.kind === \"error\"\n ? \"Your Hexclave config has been saved, but contains errors\"\n : \"Your Hexclave config has been saved, but has warnings\";\n const bodyText = issue.kind === \"error\"\n ? \"Your app can keep running, but Hexclave is still using the last valid config until this is fixed.\"\n : \"Your app can keep running, but part of your Hexclave config may not behave the way you expect until this is fixed.\";\n const footerText = issue.kind === \"error\"\n ? \"Fix the config file mentioned above and save it again. This message will disappear after the config sync succeeds.\"\n : \"Fix the config file mentioned above and save it again. This warning will disappear after Hexclave syncs a config without warnings.\";\n if (issueKey !== lastConsoleErrorKey) {\n lastConsoleErrorKey = issueKey;\n const consoleMessage = `[Hexclave] Config ${issueLabel}: ${issueMessage}`;\n if (issue.kind === \"error\") {\n console.error(consoleMessage);\n } else {\n console.warn(consoleMessage);\n }\n }\n\n if (issueKey !== lastErrorKey) {\n lastErrorKey = issueKey;\n minimized = storageGet(MINIMIZED_STORAGE_KEY) === issueKey;\n }\n\n if (minimized) {\n const logoSpan = h(\"span\", { className: \"hce-pill-logo\" });\n setHtml(logoSpan, HEXCLAVE_LOGO_SVG);\n root.appendChild(h(\"button\", {\n className: issue.kind === \"error\" ? \"hce-pill\" : \"hce-pill hce-pill-warning\",\n type: \"button\",\n onClick: () => {\n minimized = false;\n storageRemove(MINIMIZED_STORAGE_KEY);\n render(issue);\n },\n },\n logoSpan,\n h(\"span\", null, issue.kind === \"error\" ? \"Config error\" : \"Config warning\")));\n return;\n }\n\n const logoSpan = h(\"span\", { className: \"hce-logo\" });\n setHtml(logoSpan, HEXCLAVE_LOGO_SVG);\n const copyButton = h(\"button\", {\n className: \"hce-icon-btn hce-text-btn\",\n type: \"button\",\n title: issue.kind === \"error\" ? \"Copy error message\" : \"Copy warning message\",\n \"aria-label\": issue.kind === \"error\" ? \"Copy config error message\" : \"Copy config warning message\",\n onClick: () => {\n runAsynchronously(async () => {\n await copyTextToClipboard(issueMessage);\n copyButton.textContent = \"Copied\";\n setTimeout(() => {\n setHtml(copyButton, `${COPY_ICON_SVG}Copy`);\n }, 1500);\n }, {\n noErrorLogging: true,\n onError: (copyError) => {\n captureError(\"pushed-config-error-overlay-copy\", copyError);\n copyButton.textContent = \"Copy failed\";\n setTimeout(() => {\n setHtml(copyButton, `${COPY_ICON_SVG}Copy`);\n }, 1500);\n },\n });\n },\n });\n setHtml(copyButton, `${COPY_ICON_SVG}Copy`);\n\n const aiPromptCopyButton = h(\"button\", {\n className: \"hce-icon-btn\",\n type: \"button\",\n title: \"Copy AI prompt\",\n \"aria-label\": issue.kind === \"error\" ? \"Copy AI prompt for config error\" : \"Copy AI prompt for config warning\",\n onClick: () => {\n runAsynchronously(async () => {\n await copyTextToClipboard(buildConfigIssueAiPrompt(issue));\n aiPromptCopyButton.textContent = \"✓\";\n setTimeout(() => {\n setHtml(aiPromptCopyButton, COPY_ICON_SVG);\n }, 1500);\n }, {\n noErrorLogging: true,\n onError: (copyError) => {\n captureError(\"pushed-config-error-overlay-copy-ai-prompt\", copyError);\n aiPromptCopyButton.textContent = \"!\";\n setTimeout(() => {\n setHtml(aiPromptCopyButton, COPY_ICON_SVG);\n }, 1500);\n },\n });\n },\n });\n setHtml(aiPromptCopyButton, COPY_ICON_SVG);\n\n root.appendChild(h(\"div\", { className: \"hce-backdrop\" },\n h(\"div\", { className: issue.kind === \"error\" ? \"hce-card\" : \"hce-card hce-card-warning\", role: \"alertdialog\", \"aria-modal\": \"true\", \"aria-label\": `Hexclave config ${issueLabel}` },\n h(\"div\", { className: \"hce-card-inner\" },\n h(\"div\", { className: \"hce-header\" },\n h(\"div\", { className: \"hce-title-row\" },\n logoSpan,\n h(\"div\", null,\n h(\"span\", { className: \"hce-badge\" }, `Config ${issueLabel}`),\n h(\"div\", { className: \"hce-title\" }, issueTitle),\n ),\n ),\n h(\"div\", { className: \"hce-actions\" },\n aiPromptCopyButton,\n h(\"button\", {\n className: \"hce-icon-btn\",\n type: \"button\",\n title: \"Minimize\",\n \"aria-label\": issue.kind === \"error\" ? \"Minimize config error\" : \"Minimize config warning\",\n onClick: () => {\n minimized = true;\n storageSet(MINIMIZED_STORAGE_KEY, issueKey);\n render(issue);\n },\n }, \"–\"),\n ),\n ),\n h(\"div\", { className: \"hce-body\" },\n bodyText,\n h(\"div\", { className: \"hce-message-header\" },\n h(\"div\", { className: \"hce-message-label\" }, issue.kind === \"error\" ? \"Error message\" : \"Warning message\"),\n copyButton,\n ),\n h(\"div\", { className: \"hce-message\" }, issueMessage),\n h(\"div\", { className: \"hce-footer\" }, footerText),\n ),\n ),\n )));\n };\n\n const refresh = () => {\n if (disposed || !canMountIntoDom()) {\n return;\n }\n runAsynchronously(async () => {\n const project = await app.getProject();\n if (disposed) {\n return;\n }\n render(project.pushedConfigError == null\n ? project.configWarnings.length === 0\n ? null\n : { kind: \"warning\", messages: project.configWarnings.map((warning) => warning.message) }\n : { kind: \"error\", messages: [project.pushedConfigError.message] });\n }, {\n noErrorLogging: true,\n onError: (error) => {\n captureError(\"pushed-config-error-overlay-refresh\", error);\n },\n });\n };\n\n // This is mounted from the base client-app constructor, which also runs\n // before subclass field initializers. Defer the first app call so overridden\n // methods like adminApp.getProject() can safely touch subclass caches.\n queueMicrotask(refresh);\n const interval = setInterval(refresh, REFRESH_INTERVAL_MS);\n\n const cleanup = () => {\n disposed = true;\n clearInterval(interval);\n root.remove();\n if (getGlobalUiInstance(GLOBAL_INSTANCE_KEY)?.cleanup === cleanup) {\n setGlobalUiInstance(GLOBAL_INSTANCE_KEY, null);\n }\n };\n setGlobalUiInstance(GLOBAL_INSTANCE_KEY, { cleanup });\n return cleanup;\n}\n\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"sign-out-DBnSkfDz.d.ts","names":[],"sources":["../src/components-page/sign-out.tsx"],"mappings":";iBAyBgB,OAAA,CAAQ,KAAA;EAAS,QAAA;EAAoB,YAAA,GAAe,MAAM;AAAA,gCAAkB,GAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"sign-out-DBnSkfDz.d.ts","names":[],"sources":["../src/components-page/sign-out.tsx"],"mappings":";iBA0CgB,OAAA,CAAQ,KAAA;EAAS,QAAA;EAAoB,YAAA,GAAe,MAAM;AAAA,gCAAkB,GAAA,CAAA,OAAA"}
@@ -0,0 +1,12 @@
1
+ //#region src/utils/session-storage.d.ts
2
+ /**
3
+ * Guarded sessionStorage access for resilience layers (redirect loop breaking, redirect-back state
4
+ * mirroring). These layers must degrade to "no stored value" when storage is unavailable, instead
5
+ * of breaking the auth flow they are trying to protect.
6
+ */
7
+ declare function readSessionStorageItem(key: string): string | null;
8
+ declare function writeSessionStorageItem(key: string, value: string): void;
9
+ declare function removeSessionStorageItem(key: string): void;
10
+ //#endregion
11
+ export { readSessionStorageItem, removeSessionStorageItem, writeSessionStorageItem };
12
+ //# sourceMappingURL=session-storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-storage.d.ts","names":[],"sources":["../../src/utils/session-storage.ts"],"mappings":";;AAUA;;;;iBAAgB,sBAAA,CAAuB,GAAW;AAAA,iBAalC,uBAAA,CAAwB,GAAA,UAAa,KAAa;AAAA,iBAYlD,wBAAA,CAAyB,GAAW"}
@@ -0,0 +1,33 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region src/utils/session-storage.ts
3
+ /**
4
+ * Guarded sessionStorage access for resilience layers (redirect loop breaking, redirect-back state
5
+ * mirroring). These layers must degrade to "no stored value" when storage is unavailable, instead
6
+ * of breaking the auth flow they are trying to protect.
7
+ */
8
+ function readSessionStorageItem(key) {
9
+ if (typeof window === "undefined") return null;
10
+ try {
11
+ return window.sessionStorage.getItem(key);
12
+ } catch {
13
+ return null;
14
+ }
15
+ }
16
+ function writeSessionStorageItem(key, value) {
17
+ if (typeof window === "undefined") return;
18
+ try {
19
+ window.sessionStorage.setItem(key, value);
20
+ } catch {}
21
+ }
22
+ function removeSessionStorageItem(key) {
23
+ if (typeof window === "undefined") return;
24
+ try {
25
+ window.sessionStorage.removeItem(key);
26
+ } catch {}
27
+ }
28
+ //#endregion
29
+ exports.readSessionStorageItem = readSessionStorageItem;
30
+ exports.removeSessionStorageItem = removeSessionStorageItem;
31
+ exports.writeSessionStorageItem = writeSessionStorageItem;
32
+
33
+ //# sourceMappingURL=session-storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-storage.js","names":[],"sources":["../../src/utils/session-storage.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n/**\n * Guarded sessionStorage access for resilience layers (redirect loop breaking, redirect-back state\n * mirroring). These layers must degrade to \"no stored value\" when storage is unavailable, instead\n * of breaking the auth flow they are trying to protect.\n */\n\nexport function readSessionStorageItem(key: string): string | null {\n if (typeof window === \"undefined\") {\n return null;\n }\n try {\n return window.sessionStorage.getItem(key);\n } catch {\n // Storage can be blocked entirely (private browsing, sandboxed iframes, disabled cookies), in\n // which case accessing window.sessionStorage throws. Treat that as \"nothing stored\".\n return null;\n }\n}\n\nexport function writeSessionStorageItem(key: string, value: string): void {\n if (typeof window === \"undefined\") {\n return;\n }\n try {\n window.sessionStorage.setItem(key, value);\n } catch {\n // Storage can be blocked or full; see readSessionStorageItem. Values written here are only\n // used as a fallback, so failing to persist must not fail the caller.\n }\n}\n\nexport function removeSessionStorageItem(key: string): void {\n if (typeof window === \"undefined\") {\n return;\n }\n try {\n window.sessionStorage.removeItem(key);\n } catch {\n // See readSessionStorageItem.\n }\n}\n"],"mappings":";;;;;;;AAUA,SAAgB,uBAAuB,KAA4B;CACjE,IAAI,OAAO,WAAW,aACpB,OAAO;CAET,IAAI;EACF,OAAO,OAAO,eAAe,QAAQ,GAAG;CAC1C,QAAQ;EAGN,OAAO;CACT;AACF;AAEA,SAAgB,wBAAwB,KAAa,OAAqB;CACxE,IAAI,OAAO,WAAW,aACpB;CAEF,IAAI;EACF,OAAO,eAAe,QAAQ,KAAK,KAAK;CAC1C,QAAQ,CAGR;AACF;AAEA,SAAgB,yBAAyB,KAAmB;CAC1D,IAAI,OAAO,WAAW,aACpB;CAEF,IAAI;EACF,OAAO,eAAe,WAAW,GAAG;CACtC,QAAQ,CAER;AACF"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "//": "THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template (FOR package.json FILES, PLEASE EDIT package-template.json)",
3
3
  "name": "@hexclave/next",
4
- "version": "1.0.49",
4
+ "version": "1.0.52",
5
5
  "repository": "https://github.com/hexclave/hexclave",
6
6
  "sideEffects": false,
7
7
  "main": "./dist/index.js",
@@ -74,9 +74,9 @@
74
74
  "tailwindcss-animate": "^1.0.7",
75
75
  "rrweb": "^1.1.3",
76
76
  "yup": "^1.7.1",
77
- "@hexclave/sc": "1.0.49",
78
- "@hexclave/shared": "1.0.49",
79
- "@hexclave/ui": "1.0.49"
77
+ "@hexclave/shared": "1.0.52",
78
+ "@hexclave/sc": "1.0.52",
79
+ "@hexclave/ui": "1.0.52"
80
80
  },
81
81
  "peerDependencies": {
82
82
  "@types/react": ">=18.0.0",
@@ -0,0 +1,190 @@
1
+
2
+ //===========================================
3
+ // THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template
4
+ //===========================================
5
+ // @vitest-environment jsdom
6
+
7
+ import React, { act } from "react";
8
+ import { createRoot, type Root } from "react-dom/client";
9
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
10
+ import type { CurrentUser } from "../lib/hexclave-app";
11
+ import type { StackClientApp } from "../lib/hexclave-app/apps/interfaces/client-app";
12
+ import { hexclaveAppInternalsSymbol } from "../lib/hexclave-app/common";
13
+ import { TranslationProviderClient } from "../providers/translation-provider-client";
14
+ import { SignOut } from "./sign-out";
15
+
16
+ const appMockState = vi.hoisted(() => ({
17
+ app: null as unknown,
18
+ user: null as unknown,
19
+ }));
20
+
21
+ vi.mock("..", () => ({
22
+ useStackApp: () => {
23
+ if (appMockState.app == null) {
24
+ throw new Error("Expected test app to be set before rendering.");
25
+ }
26
+ return appMockState.app;
27
+ },
28
+ useUser: () => appMockState.user,
29
+ }));
30
+
31
+ // The real `use` delegates to React.use, which breaks in this test setup because the shared
32
+ // package and react-dom resolve different React instances. Replace it with an equivalent
33
+ // Suspense-compatible implementation that doesn't depend on the React dispatcher.
34
+ vi.mock("@hexclave/shared/dist/utils/react", async (importOriginal) => {
35
+ const original = await importOriginal<typeof import("@hexclave/shared/dist/utils/react")>();
36
+ type PromiseState = { status: "pending" } | { status: "ok", value: unknown } | { status: "error", error: unknown };
37
+ const promiseStates = new WeakMap<Promise<unknown>, PromiseState>();
38
+ return {
39
+ ...original,
40
+ use: <T,>(promise: Promise<T>): T => {
41
+ const state = promiseStates.get(promise);
42
+ if (state == null) {
43
+ promiseStates.set(promise, { status: "pending" });
44
+ promise.then(
45
+ (value) => promiseStates.set(promise, { status: "ok", value }),
46
+ (error) => promiseStates.set(promise, { status: "error", error }),
47
+ );
48
+ throw promise;
49
+ }
50
+ switch (state.status) {
51
+ case "pending": {
52
+ throw promise;
53
+ }
54
+ case "error": {
55
+ throw state.error;
56
+ }
57
+ case "ok": {
58
+ // This cast is safe because the value was stored from this exact promise's resolution;
59
+ // the WeakMap just can't express the per-key type relationship.
60
+ return state.value as T;
61
+ }
62
+ }
63
+ },
64
+ };
65
+ });
66
+
67
+ vi.mock("@hexclave/ui", async () => {
68
+ const React = await import("react");
69
+ return {
70
+ Button: (props: { children: React.ReactNode, onClick?: () => void }) => (
71
+ <button type="button" onClick={props.onClick}>{props.children}</button>
72
+ ),
73
+ Typography: (props: { children: React.ReactNode }) => <div>{props.children}</div>,
74
+ cn: (...classes: (string | false | null | undefined)[]) => classes.filter(Boolean).join(" "),
75
+ };
76
+ });
77
+
78
+ const previousActEnvironment = Reflect.get(globalThis, "IS_REACT_ACT_ENVIRONMENT");
79
+
80
+ function createAppTestDouble(options: {
81
+ trustedUrls: string[],
82
+ }) {
83
+ const app = {
84
+ redirectToSignIn: vi.fn(async () => {}),
85
+ [hexclaveAppInternalsSymbol]: {
86
+ isTrustedRedirectUrl: vi.fn(async (url: string) => options.trustedUrls.includes(url)),
87
+ },
88
+ };
89
+
90
+ // This test double intentionally implements only the StackClientApp surface that SignOut and
91
+ // the rendered signed-out card touch.
92
+ return app as unknown as StackClientApp<true>;
93
+ }
94
+
95
+ function createUserTestDouble() {
96
+ const user = {
97
+ signOut: vi.fn(async () => {}),
98
+ };
99
+ // Same as the app test double: only the surface SignOut touches.
100
+ return user as unknown as CurrentUser & { signOut: ReturnType<typeof vi.fn> };
101
+ }
102
+
103
+ // jsdom's window.location is not configurable, so it can't be spied on; replace it wholesale.
104
+ const originalLocation = window.location;
105
+ let locationReplaceMock = vi.fn();
106
+
107
+ let root: Root | null = null;
108
+ let container: HTMLDivElement | null = null;
109
+
110
+ async function renderSignOut(options: {
111
+ app: StackClientApp<true>,
112
+ user: unknown,
113
+ searchParams?: Record<string, string>,
114
+ }) {
115
+ appMockState.app = options.app;
116
+ appMockState.user = options.user;
117
+ container = document.createElement("div");
118
+ document.body.append(container);
119
+ root = createRoot(container);
120
+ await act(async () => {
121
+ root?.render(
122
+ <TranslationProviderClient quetzalKeys={new Map()} quetzalLocale={new Map()}>
123
+ <React.Suspense fallback={<div data-testid="suspense-fallback" />}>
124
+ <SignOut searchParams={options.searchParams} />
125
+ </React.Suspense>
126
+ </TranslationProviderClient>
127
+ );
128
+ });
129
+ await act(async () => {
130
+ await new Promise((resolve) => setTimeout(resolve, 0));
131
+ });
132
+ }
133
+
134
+ describe("SignOut", () => {
135
+ beforeEach(() => {
136
+ Reflect.set(globalThis, "IS_REACT_ACT_ENVIRONMENT", true);
137
+ locationReplaceMock = vi.fn();
138
+ Reflect.deleteProperty(window, "location");
139
+ Reflect.set(window, "location", { href: "https://demo.example.test/handler/sign-out", replace: locationReplaceMock });
140
+ });
141
+
142
+ afterEach(() => {
143
+ act(() => {
144
+ root?.unmount();
145
+ });
146
+ container?.remove();
147
+ root = null;
148
+ container = null;
149
+ appMockState.app = null;
150
+ appMockState.user = null;
151
+ Reflect.set(window, "location", originalLocation);
152
+ vi.restoreAllMocks();
153
+ Reflect.set(globalThis, "IS_REACT_ACT_ENVIRONMENT", previousActEnvironment);
154
+ });
155
+
156
+ it("signs out with a trusted after_auth_return_to redirect URL", async () => {
157
+ const app = createAppTestDouble({ trustedUrls: ["/dashboard"] });
158
+ const user = createUserTestDouble();
159
+
160
+ await renderSignOut({ app, user, searchParams: { after_auth_return_to: "/dashboard" } });
161
+
162
+ expect(user.signOut).toHaveBeenCalledWith({ redirectUrl: "/dashboard" });
163
+ });
164
+
165
+ it("ignores an untrusted after_auth_return_to and falls back to the default sign-out redirect", async () => {
166
+ const app = createAppTestDouble({ trustedUrls: [] });
167
+ const user = createUserTestDouble();
168
+
169
+ await renderSignOut({ app, user, searchParams: { after_auth_return_to: "https://evil.example.test/phishing" } });
170
+
171
+ // The untrusted URL is dropped entirely; sign-out proceeds with the default destination.
172
+ expect(user.signOut).toHaveBeenCalledWith({ redirectUrl: undefined });
173
+ });
174
+
175
+ it("does not follow an untrusted after_auth_return_to when already signed out", async () => {
176
+ const app = createAppTestDouble({ trustedUrls: [] });
177
+
178
+ await renderSignOut({ app, user: null, searchParams: { after_auth_return_to: "https://evil.example.test/phishing-signed-out" } });
179
+
180
+ expect(locationReplaceMock).not.toHaveBeenCalled();
181
+ });
182
+
183
+ it("follows a trusted after_auth_return_to when already signed out", async () => {
184
+ const app = createAppTestDouble({ trustedUrls: ["/trusted-dashboard"] });
185
+
186
+ await renderSignOut({ app, user: null, searchParams: { after_auth_return_to: "/trusted-dashboard" } });
187
+
188
+ expect(locationReplaceMock).toHaveBeenCalledWith("/trusted-dashboard");
189
+ });
190
+ });