@hexclave/js 1.0.2 → 1.0.5

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 (450) hide show
  1. package/dist/dev-tool/dev-tool-core.d.ts +1 -1
  2. package/dist/dev-tool/dev-tool-core.js +11 -11
  3. package/dist/dev-tool/dev-tool-core.js.map +1 -1
  4. package/dist/dev-tool/dev-tool-styles.d.ts +1 -1
  5. package/dist/dev-tool/dev-tool-styles.js +371 -371
  6. package/dist/dev-tool/dev-tool-styles.js.map +1 -1
  7. package/dist/dev-tool/dev-tool-trigger-position.js.map +1 -1
  8. package/dist/dev-tool/dev-tool-trigger-position.test.js.map +1 -1
  9. package/dist/dev-tool/index.d.ts +4 -4
  10. package/dist/dev-tool/index.js +4 -4
  11. package/dist/dev-tool/index.js.map +1 -1
  12. package/dist/esm/dev-tool/dev-tool-core.d.ts +1 -1
  13. package/dist/esm/dev-tool/dev-tool-core.js +10 -10
  14. package/dist/esm/dev-tool/dev-tool-core.js.map +1 -1
  15. package/dist/esm/dev-tool/dev-tool-styles.d.ts +1 -1
  16. package/dist/esm/dev-tool/dev-tool-styles.js +371 -371
  17. package/dist/esm/dev-tool/dev-tool-styles.js.map +1 -1
  18. package/dist/esm/dev-tool/dev-tool-trigger-position.js.map +1 -1
  19. package/dist/esm/dev-tool/dev-tool-trigger-position.test.js.map +1 -1
  20. package/dist/esm/dev-tool/index.d.ts +4 -4
  21. package/dist/esm/dev-tool/index.js +4 -4
  22. package/dist/esm/dev-tool/index.js.map +1 -1
  23. package/dist/esm/index.d.ts +1 -1
  24. package/dist/esm/index.js +1 -1
  25. package/dist/esm/integrations/convex/component/convex.config.js.map +1 -1
  26. package/dist/esm/integrations/convex.js +1 -1
  27. package/dist/esm/integrations/convex.js.map +1 -1
  28. package/dist/esm/lib/auth.js.map +1 -1
  29. package/dist/esm/lib/auth.test.js.map +1 -1
  30. package/dist/esm/lib/cookie.js.map +1 -1
  31. package/dist/esm/lib/env.js.map +1 -1
  32. package/dist/esm/lib/{stack-app → hexclave-app}/api-keys/index.d.ts +1 -1
  33. package/dist/esm/lib/hexclave-app/api-keys/index.d.ts.map +1 -0
  34. package/dist/esm/lib/{stack-app → hexclave-app}/api-keys/index.js +1 -1
  35. package/dist/esm/lib/hexclave-app/api-keys/index.js.map +1 -0
  36. package/dist/esm/lib/{stack-app → hexclave-app}/apps/implementations/admin-app-impl.d.ts +6 -6
  37. package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts.map +1 -0
  38. package/dist/esm/lib/{stack-app → hexclave-app}/apps/implementations/admin-app-impl.js +7 -7
  39. package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.js.map +1 -0
  40. package/dist/esm/lib/{stack-app → hexclave-app}/apps/implementations/client-app-impl.cross-domain.test.js +2 -2
  41. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js.map +1 -0
  42. package/dist/esm/lib/{stack-app → hexclave-app}/apps/implementations/client-app-impl.d.ts +13 -13
  43. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.d.ts.map +1 -0
  44. package/dist/esm/lib/{stack-app → hexclave-app}/apps/implementations/client-app-impl.js +23 -30
  45. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -0
  46. package/dist/esm/lib/{stack-app → hexclave-app}/apps/implementations/client-app-impl.oauth-prefetch.test.js +1 -1
  47. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.oauth-prefetch.test.js.map +1 -0
  48. package/dist/{lib/stack-app → esm/lib/hexclave-app}/apps/implementations/common.d.ts +3 -3
  49. package/dist/esm/lib/hexclave-app/apps/implementations/common.d.ts.map +1 -0
  50. package/dist/esm/lib/{stack-app → hexclave-app}/apps/implementations/common.js +6 -6
  51. package/dist/esm/lib/hexclave-app/apps/implementations/common.js.map +1 -0
  52. package/dist/esm/lib/{stack-app → hexclave-app}/apps/implementations/event-tracker.d.ts +1 -1
  53. package/dist/esm/lib/hexclave-app/apps/implementations/event-tracker.d.ts.map +1 -0
  54. package/dist/esm/lib/{stack-app → hexclave-app}/apps/implementations/event-tracker.js +1 -1
  55. package/dist/esm/lib/hexclave-app/apps/implementations/event-tracker.js.map +1 -0
  56. package/dist/esm/lib/{stack-app → hexclave-app}/apps/implementations/event-tracker.test.js +1 -1
  57. package/dist/esm/lib/hexclave-app/apps/implementations/event-tracker.test.js.map +1 -0
  58. package/dist/esm/lib/hexclave-app/apps/implementations/index.d.ts +9 -0
  59. package/dist/esm/lib/hexclave-app/apps/implementations/index.d.ts.map +1 -0
  60. package/dist/esm/lib/hexclave-app/apps/implementations/index.js +27 -0
  61. package/dist/esm/lib/hexclave-app/apps/implementations/index.js.map +1 -0
  62. package/dist/esm/lib/{stack-app → hexclave-app}/apps/implementations/redirect-page-urls.d.ts +1 -1
  63. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-page-urls.d.ts.map +1 -0
  64. package/dist/esm/lib/{stack-app → hexclave-app}/apps/implementations/redirect-page-urls.js +1 -1
  65. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-page-urls.js.map +1 -0
  66. package/dist/esm/lib/{stack-app → hexclave-app}/apps/implementations/server-app-impl.d.ts +4 -4
  67. package/dist/esm/lib/hexclave-app/apps/implementations/server-app-impl.d.ts.map +1 -0
  68. package/dist/esm/lib/{stack-app → hexclave-app}/apps/implementations/server-app-impl.js +5 -5
  69. package/dist/esm/lib/hexclave-app/apps/implementations/server-app-impl.js.map +1 -0
  70. package/dist/{lib/stack-app → esm/lib/hexclave-app}/apps/implementations/session-refresh-subscription.d.ts +1 -1
  71. package/dist/esm/lib/hexclave-app/apps/implementations/session-refresh-subscription.d.ts.map +1 -0
  72. package/dist/esm/lib/{stack-app → hexclave-app}/apps/implementations/session-refresh-subscription.js +1 -1
  73. package/dist/esm/lib/hexclave-app/apps/implementations/session-refresh-subscription.js.map +1 -0
  74. package/dist/esm/lib/{stack-app → hexclave-app}/apps/implementations/session-refresh-subscription.test.js +1 -1
  75. package/dist/esm/lib/hexclave-app/apps/implementations/session-refresh-subscription.test.js.map +1 -0
  76. package/dist/esm/lib/{stack-app → hexclave-app}/apps/implementations/session-replay.d.ts +1 -1
  77. package/dist/esm/lib/hexclave-app/apps/implementations/session-replay.d.ts.map +1 -0
  78. package/dist/esm/lib/{stack-app → hexclave-app}/apps/implementations/session-replay.js +1 -1
  79. package/dist/esm/lib/hexclave-app/apps/implementations/session-replay.js.map +1 -0
  80. package/dist/esm/lib/{stack-app → hexclave-app}/apps/implementations/session-replay.test.js +1 -1
  81. package/dist/esm/lib/hexclave-app/apps/implementations/session-replay.test.js.map +1 -0
  82. package/dist/esm/lib/{stack-app → hexclave-app}/apps/interfaces/admin-app.d.ts +1 -1
  83. package/dist/esm/lib/hexclave-app/apps/interfaces/admin-app.d.ts.map +1 -0
  84. package/dist/esm/lib/{stack-app → hexclave-app}/apps/interfaces/admin-app.js +3 -3
  85. package/dist/esm/lib/hexclave-app/apps/interfaces/admin-app.js.map +1 -0
  86. package/dist/esm/lib/{stack-app → hexclave-app}/apps/interfaces/client-app.d.ts +4 -4
  87. package/dist/esm/lib/hexclave-app/apps/interfaces/client-app.d.ts.map +1 -0
  88. package/dist/esm/lib/{stack-app → hexclave-app}/apps/interfaces/client-app.js +3 -3
  89. package/dist/esm/lib/hexclave-app/apps/interfaces/client-app.js.map +1 -0
  90. package/dist/esm/lib/{stack-app → hexclave-app}/apps/interfaces/server-app.d.ts +1 -1
  91. package/dist/esm/lib/hexclave-app/apps/interfaces/server-app.d.ts.map +1 -0
  92. package/dist/esm/lib/{stack-app → hexclave-app}/apps/interfaces/server-app.js +3 -3
  93. package/dist/esm/lib/hexclave-app/apps/interfaces/server-app.js.map +1 -0
  94. package/dist/esm/lib/{stack-app → hexclave-app}/common.d.ts +7 -7
  95. package/dist/esm/lib/hexclave-app/common.d.ts.map +1 -0
  96. package/dist/esm/lib/hexclave-app/common.js +7 -0
  97. package/dist/esm/lib/hexclave-app/common.js.map +1 -0
  98. package/dist/{lib/stack-app → esm/lib/hexclave-app}/connected-accounts/index.d.ts +1 -1
  99. package/dist/esm/lib/hexclave-app/connected-accounts/index.d.ts.map +1 -0
  100. package/dist/{lib/stack-app → esm/lib/hexclave-app}/contact-channels/index.d.ts +1 -1
  101. package/dist/esm/lib/hexclave-app/contact-channels/index.d.ts.map +1 -0
  102. package/dist/esm/lib/{stack-app → hexclave-app}/contact-channels/index.js +1 -1
  103. package/dist/esm/lib/hexclave-app/contact-channels/index.js.map +1 -0
  104. package/dist/esm/lib/{stack-app → hexclave-app}/customers/index.d.ts +1 -1
  105. package/dist/esm/lib/hexclave-app/customers/index.d.ts.map +1 -0
  106. package/dist/esm/lib/{stack-app → hexclave-app}/data-vault/index.d.ts +1 -1
  107. package/dist/esm/lib/hexclave-app/data-vault/index.d.ts.map +1 -0
  108. package/dist/esm/lib/{stack-app → hexclave-app}/email/index.d.ts +1 -1
  109. package/dist/esm/lib/hexclave-app/email/index.d.ts.map +1 -0
  110. package/dist/{lib/stack-app → esm/lib/hexclave-app}/email-templates/index.d.ts +1 -1
  111. package/dist/esm/lib/hexclave-app/email-templates/index.d.ts.map +1 -0
  112. package/dist/esm/lib/{stack-app → hexclave-app}/email-templates/index.js +1 -1
  113. package/dist/esm/lib/hexclave-app/email-templates/index.js.map +1 -0
  114. package/dist/esm/lib/{stack-app → hexclave-app}/index.d.ts +2 -2
  115. package/dist/esm/lib/{stack-app → hexclave-app}/index.js +2 -2
  116. package/dist/{lib/stack-app → esm/lib/hexclave-app}/internal-api-keys/index.d.ts +1 -1
  117. package/dist/esm/lib/hexclave-app/internal-api-keys/index.d.ts.map +1 -0
  118. package/dist/esm/lib/{stack-app → hexclave-app}/internal-api-keys/index.js +1 -1
  119. package/dist/esm/lib/hexclave-app/internal-api-keys/index.js.map +1 -0
  120. package/dist/{lib/stack-app → esm/lib/hexclave-app}/notification-categories/index.d.ts +1 -1
  121. package/dist/esm/lib/hexclave-app/notification-categories/index.d.ts.map +1 -0
  122. package/dist/esm/lib/{stack-app → hexclave-app}/permissions/index.d.ts +1 -1
  123. package/dist/esm/lib/hexclave-app/permissions/index.d.ts.map +1 -0
  124. package/dist/esm/lib/{stack-app → hexclave-app}/permissions/index.js +1 -1
  125. package/dist/esm/lib/hexclave-app/permissions/index.js.map +1 -0
  126. package/dist/esm/lib/{stack-app → hexclave-app}/project-configs/index.d.ts +1 -1
  127. package/dist/esm/lib/hexclave-app/project-configs/index.d.ts.map +1 -0
  128. package/dist/esm/lib/{stack-app → hexclave-app}/projects/index.d.ts +1 -1
  129. package/dist/esm/lib/hexclave-app/projects/index.d.ts.map +1 -0
  130. package/dist/esm/lib/{stack-app → hexclave-app}/projects/index.js +1 -1
  131. package/dist/esm/lib/hexclave-app/projects/index.js.map +1 -0
  132. package/dist/{lib/stack-app → esm/lib/hexclave-app}/session-replays/index.d.ts +1 -1
  133. package/dist/esm/lib/hexclave-app/session-replays/index.d.ts.map +1 -0
  134. package/dist/esm/lib/{stack-app → hexclave-app}/teams/index.d.ts +1 -1
  135. package/dist/esm/lib/hexclave-app/teams/index.d.ts.map +1 -0
  136. package/dist/esm/lib/{stack-app → hexclave-app}/teams/index.js +1 -1
  137. package/dist/esm/lib/hexclave-app/teams/index.js.map +1 -0
  138. package/dist/esm/lib/{stack-app → hexclave-app}/url-targets.d.ts +1 -1
  139. package/dist/esm/lib/hexclave-app/url-targets.d.ts.map +1 -0
  140. package/dist/esm/lib/{stack-app → hexclave-app}/url-targets.js +2 -2
  141. package/dist/esm/lib/hexclave-app/url-targets.js.map +1 -0
  142. package/dist/esm/lib/{stack-app → hexclave-app}/url-targets.test.js +1 -1
  143. package/dist/esm/lib/hexclave-app/url-targets.test.js.map +1 -0
  144. package/dist/esm/lib/{stack-app → hexclave-app}/users/index.d.ts +1 -1
  145. package/dist/esm/lib/hexclave-app/users/index.d.ts.map +1 -0
  146. package/dist/esm/lib/{stack-app → hexclave-app}/users/index.js +1 -1
  147. package/dist/esm/lib/hexclave-app/users/index.js.map +1 -0
  148. package/dist/esm/utils/url.js.map +1 -1
  149. package/dist/index.d.ts +15 -15
  150. package/dist/index.js +3 -3
  151. package/dist/integrations/convex/component/convex.config.js.map +1 -1
  152. package/dist/integrations/convex.js +2 -2
  153. package/dist/integrations/convex.js.map +1 -1
  154. package/dist/lib/auth.js.map +1 -1
  155. package/dist/lib/auth.test.js.map +1 -1
  156. package/dist/lib/cookie.js.map +1 -1
  157. package/dist/lib/env.js.map +1 -1
  158. package/dist/lib/{stack-app → hexclave-app}/api-keys/index.d.ts +1 -1
  159. package/dist/{esm/lib/stack-app → lib/hexclave-app}/api-keys/index.d.ts.map +1 -1
  160. package/dist/lib/{stack-app → hexclave-app}/api-keys/index.js +1 -1
  161. package/dist/lib/hexclave-app/api-keys/index.js.map +1 -0
  162. package/dist/lib/{stack-app → hexclave-app}/apps/implementations/admin-app-impl.d.ts +6 -6
  163. package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts.map +1 -0
  164. package/dist/lib/{stack-app → hexclave-app}/apps/implementations/admin-app-impl.js +5 -5
  165. package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.js.map +1 -0
  166. package/dist/lib/{stack-app → hexclave-app}/apps/implementations/client-app-impl.cross-domain.test.js +2 -2
  167. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js.map +1 -0
  168. package/dist/lib/{stack-app → hexclave-app}/apps/implementations/client-app-impl.d.ts +13 -13
  169. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.d.ts.map +1 -0
  170. package/dist/lib/{stack-app → hexclave-app}/apps/implementations/client-app-impl.js +22 -29
  171. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -0
  172. package/dist/lib/{stack-app → hexclave-app}/apps/implementations/client-app-impl.oauth-prefetch.test.js +1 -1
  173. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.oauth-prefetch.test.js.map +1 -0
  174. package/dist/{esm/lib/stack-app → lib/hexclave-app}/apps/implementations/common.d.ts +3 -3
  175. package/dist/{esm/lib/stack-app → lib/hexclave-app}/apps/implementations/common.d.ts.map +1 -1
  176. package/dist/lib/{stack-app → hexclave-app}/apps/implementations/common.js +5 -5
  177. package/dist/lib/hexclave-app/apps/implementations/common.js.map +1 -0
  178. package/dist/lib/{stack-app → hexclave-app}/apps/implementations/event-tracker.d.ts +1 -1
  179. package/dist/{esm/lib/stack-app → lib/hexclave-app}/apps/implementations/event-tracker.d.ts.map +1 -1
  180. package/dist/lib/{stack-app → hexclave-app}/apps/implementations/event-tracker.js +1 -1
  181. package/dist/lib/hexclave-app/apps/implementations/event-tracker.js.map +1 -0
  182. package/dist/lib/{stack-app → hexclave-app}/apps/implementations/event-tracker.test.js +1 -1
  183. package/dist/lib/hexclave-app/apps/implementations/event-tracker.test.js.map +1 -0
  184. package/dist/lib/hexclave-app/apps/implementations/index.d.ts +9 -0
  185. package/dist/lib/hexclave-app/apps/implementations/index.d.ts.map +1 -0
  186. package/dist/lib/hexclave-app/apps/implementations/index.js +31 -0
  187. package/dist/lib/hexclave-app/apps/implementations/index.js.map +1 -0
  188. package/dist/lib/{stack-app → hexclave-app}/apps/implementations/redirect-page-urls.d.ts +1 -1
  189. package/dist/{esm/lib/stack-app → lib/hexclave-app}/apps/implementations/redirect-page-urls.d.ts.map +1 -1
  190. package/dist/lib/{stack-app → hexclave-app}/apps/implementations/redirect-page-urls.js +1 -1
  191. package/dist/lib/hexclave-app/apps/implementations/redirect-page-urls.js.map +1 -0
  192. package/dist/lib/{stack-app → hexclave-app}/apps/implementations/server-app-impl.d.ts +4 -4
  193. package/dist/{esm/lib/stack-app → lib/hexclave-app}/apps/implementations/server-app-impl.d.ts.map +1 -1
  194. package/dist/lib/{stack-app → hexclave-app}/apps/implementations/server-app-impl.js +4 -4
  195. package/dist/lib/hexclave-app/apps/implementations/server-app-impl.js.map +1 -0
  196. package/dist/{esm/lib/stack-app → lib/hexclave-app}/apps/implementations/session-refresh-subscription.d.ts +1 -1
  197. package/dist/{esm/lib/stack-app → lib/hexclave-app}/apps/implementations/session-refresh-subscription.d.ts.map +1 -1
  198. package/dist/lib/{stack-app → hexclave-app}/apps/implementations/session-refresh-subscription.js +1 -1
  199. package/dist/lib/hexclave-app/apps/implementations/session-refresh-subscription.js.map +1 -0
  200. package/dist/lib/{stack-app → hexclave-app}/apps/implementations/session-refresh-subscription.test.js +1 -1
  201. package/dist/lib/hexclave-app/apps/implementations/session-refresh-subscription.test.js.map +1 -0
  202. package/dist/lib/{stack-app → hexclave-app}/apps/implementations/session-replay.d.ts +1 -1
  203. package/dist/{esm/lib/stack-app → lib/hexclave-app}/apps/implementations/session-replay.d.ts.map +1 -1
  204. package/dist/lib/{stack-app → hexclave-app}/apps/implementations/session-replay.js +1 -1
  205. package/dist/lib/hexclave-app/apps/implementations/session-replay.js.map +1 -0
  206. package/dist/lib/{stack-app → hexclave-app}/apps/implementations/session-replay.test.js +1 -1
  207. package/dist/lib/hexclave-app/apps/implementations/session-replay.test.js.map +1 -0
  208. package/dist/lib/{stack-app → hexclave-app}/apps/interfaces/admin-app.d.ts +1 -1
  209. package/dist/{esm/lib/stack-app → lib/hexclave-app}/apps/interfaces/admin-app.d.ts.map +1 -1
  210. package/dist/lib/{stack-app → hexclave-app}/apps/interfaces/admin-app.js +2 -2
  211. package/dist/lib/hexclave-app/apps/interfaces/admin-app.js.map +1 -0
  212. package/dist/lib/{stack-app → hexclave-app}/apps/interfaces/client-app.d.ts +4 -4
  213. package/dist/{esm/lib/stack-app → lib/hexclave-app}/apps/interfaces/client-app.d.ts.map +1 -1
  214. package/dist/lib/{stack-app → hexclave-app}/apps/interfaces/client-app.js +2 -2
  215. package/dist/lib/hexclave-app/apps/interfaces/client-app.js.map +1 -0
  216. package/dist/lib/{stack-app → hexclave-app}/apps/interfaces/server-app.d.ts +1 -1
  217. package/dist/{esm/lib/stack-app → lib/hexclave-app}/apps/interfaces/server-app.d.ts.map +1 -1
  218. package/dist/lib/{stack-app → hexclave-app}/apps/interfaces/server-app.js +2 -2
  219. package/dist/lib/hexclave-app/apps/interfaces/server-app.js.map +1 -0
  220. package/dist/lib/{stack-app → hexclave-app}/common.d.ts +7 -7
  221. package/dist/{esm/lib/stack-app → lib/hexclave-app}/common.d.ts.map +1 -1
  222. package/dist/lib/hexclave-app/common.js +9 -0
  223. package/dist/lib/hexclave-app/common.js.map +1 -0
  224. package/dist/{esm/lib/stack-app → lib/hexclave-app}/connected-accounts/index.d.ts +1 -1
  225. package/dist/{esm/lib/stack-app → lib/hexclave-app}/connected-accounts/index.d.ts.map +1 -1
  226. package/dist/{esm/lib/stack-app → lib/hexclave-app}/contact-channels/index.d.ts +1 -1
  227. package/dist/{esm/lib/stack-app → lib/hexclave-app}/contact-channels/index.d.ts.map +1 -1
  228. package/dist/lib/{stack-app → hexclave-app}/contact-channels/index.js +1 -1
  229. package/dist/lib/hexclave-app/contact-channels/index.js.map +1 -0
  230. package/dist/lib/{stack-app → hexclave-app}/customers/index.d.ts +1 -1
  231. package/dist/{esm/lib/stack-app → lib/hexclave-app}/customers/index.d.ts.map +1 -1
  232. package/dist/lib/{stack-app → hexclave-app}/data-vault/index.d.ts +1 -1
  233. package/dist/{esm/lib/stack-app → lib/hexclave-app}/data-vault/index.d.ts.map +1 -1
  234. package/dist/lib/{stack-app → hexclave-app}/email/index.d.ts +1 -1
  235. package/dist/{esm/lib/stack-app → lib/hexclave-app}/email/index.d.ts.map +1 -1
  236. package/dist/{esm/lib/stack-app → lib/hexclave-app}/email-templates/index.d.ts +1 -1
  237. package/dist/{esm/lib/stack-app → lib/hexclave-app}/email-templates/index.d.ts.map +1 -1
  238. package/dist/lib/{stack-app → hexclave-app}/email-templates/index.js +1 -1
  239. package/dist/lib/hexclave-app/email-templates/index.js.map +1 -0
  240. package/dist/lib/{stack-app → hexclave-app}/index.d.ts +2 -2
  241. package/dist/lib/{stack-app → hexclave-app}/index.js +2 -2
  242. package/dist/{esm/lib/stack-app → lib/hexclave-app}/internal-api-keys/index.d.ts +1 -1
  243. package/dist/{esm/lib/stack-app → lib/hexclave-app}/internal-api-keys/index.d.ts.map +1 -1
  244. package/dist/lib/{stack-app → hexclave-app}/internal-api-keys/index.js +1 -1
  245. package/dist/lib/hexclave-app/internal-api-keys/index.js.map +1 -0
  246. package/dist/{esm/lib/stack-app → lib/hexclave-app}/notification-categories/index.d.ts +1 -1
  247. package/dist/{esm/lib/stack-app → lib/hexclave-app}/notification-categories/index.d.ts.map +1 -1
  248. package/dist/lib/{stack-app → hexclave-app}/permissions/index.d.ts +1 -1
  249. package/dist/{esm/lib/stack-app → lib/hexclave-app}/permissions/index.d.ts.map +1 -1
  250. package/dist/lib/{stack-app → hexclave-app}/permissions/index.js +1 -1
  251. package/dist/lib/hexclave-app/permissions/index.js.map +1 -0
  252. package/dist/lib/{stack-app → hexclave-app}/project-configs/index.d.ts +1 -1
  253. package/dist/{esm/lib/stack-app → lib/hexclave-app}/project-configs/index.d.ts.map +1 -1
  254. package/dist/lib/{stack-app → hexclave-app}/projects/index.d.ts +1 -1
  255. package/dist/{esm/lib/stack-app → lib/hexclave-app}/projects/index.d.ts.map +1 -1
  256. package/dist/lib/{stack-app → hexclave-app}/projects/index.js +1 -1
  257. package/dist/lib/hexclave-app/projects/index.js.map +1 -0
  258. package/dist/{esm/lib/stack-app → lib/hexclave-app}/session-replays/index.d.ts +1 -1
  259. package/dist/{esm/lib/stack-app → lib/hexclave-app}/session-replays/index.d.ts.map +1 -1
  260. package/dist/lib/{stack-app → hexclave-app}/teams/index.d.ts +1 -1
  261. package/dist/{esm/lib/stack-app → lib/hexclave-app}/teams/index.d.ts.map +1 -1
  262. package/dist/lib/{stack-app → hexclave-app}/teams/index.js +1 -1
  263. package/dist/lib/hexclave-app/teams/index.js.map +1 -0
  264. package/dist/lib/{stack-app → hexclave-app}/url-targets.d.ts +1 -1
  265. package/dist/{esm/lib/stack-app → lib/hexclave-app}/url-targets.d.ts.map +1 -1
  266. package/dist/lib/{stack-app → hexclave-app}/url-targets.js +2 -2
  267. package/dist/lib/hexclave-app/url-targets.js.map +1 -0
  268. package/dist/lib/{stack-app → hexclave-app}/url-targets.test.js +1 -1
  269. package/dist/lib/hexclave-app/url-targets.test.js.map +1 -0
  270. package/dist/lib/{stack-app → hexclave-app}/users/index.d.ts +1 -1
  271. package/dist/{esm/lib/stack-app → lib/hexclave-app}/users/index.d.ts.map +1 -1
  272. package/dist/lib/{stack-app → hexclave-app}/users/index.js +1 -1
  273. package/dist/lib/hexclave-app/users/index.js.map +1 -0
  274. package/dist/utils/url.js.map +1 -1
  275. package/package.json +4 -3
  276. package/src/dev-tool/dev-tool-core.ts +2460 -0
  277. package/src/dev-tool/dev-tool-styles.ts +2758 -0
  278. package/src/dev-tool/dev-tool-trigger-position.test.ts +113 -0
  279. package/src/dev-tool/dev-tool-trigger-position.ts +109 -0
  280. package/src/dev-tool/index.ts +149 -0
  281. package/src/index.ts +12 -0
  282. package/src/integrations/convex/component/README.md +74 -0
  283. package/src/integrations/convex/component/convex.config.ts +9 -0
  284. package/src/integrations/convex.ts +28 -0
  285. package/src/lib/auth.test.ts +67 -0
  286. package/src/lib/auth.ts +175 -0
  287. package/src/lib/cookie.ts +327 -0
  288. package/src/lib/env.ts +93 -0
  289. package/src/lib/hexclave-app/api-keys/index.ts +73 -0
  290. package/src/lib/hexclave-app/apps/implementations/admin-app-impl.ts +1159 -0
  291. package/src/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.ts +141 -0
  292. package/src/lib/hexclave-app/apps/implementations/client-app-impl.oauth-prefetch.test.ts +36 -0
  293. package/src/lib/hexclave-app/apps/implementations/client-app-impl.ts +3525 -0
  294. package/src/lib/hexclave-app/apps/implementations/common.ts +190 -0
  295. package/src/lib/hexclave-app/apps/implementations/event-tracker.test.ts +105 -0
  296. package/src/lib/hexclave-app/apps/implementations/event-tracker.ts +306 -0
  297. package/src/lib/hexclave-app/apps/implementations/index.ts +35 -0
  298. package/src/lib/hexclave-app/apps/implementations/redirect-page-urls.ts +342 -0
  299. package/src/lib/hexclave-app/apps/implementations/server-app-impl.ts +1322 -0
  300. package/src/lib/hexclave-app/apps/implementations/session-refresh-subscription.test.ts +106 -0
  301. package/src/lib/hexclave-app/apps/implementations/session-refresh-subscription.ts +52 -0
  302. package/src/lib/hexclave-app/apps/implementations/session-replay.test.ts +33 -0
  303. package/src/lib/hexclave-app/apps/implementations/session-replay.ts +356 -0
  304. package/src/lib/hexclave-app/apps/index.ts +40 -0
  305. package/src/lib/hexclave-app/apps/interfaces/admin-app.ts +189 -0
  306. package/src/lib/hexclave-app/apps/interfaces/client-app.ts +172 -0
  307. package/src/lib/hexclave-app/apps/interfaces/server-app.ts +114 -0
  308. package/src/lib/hexclave-app/common.ts +209 -0
  309. package/src/lib/hexclave-app/connected-accounts/index.ts +47 -0
  310. package/src/lib/hexclave-app/contact-channels/index.ts +80 -0
  311. package/src/lib/hexclave-app/customers/index.ts +158 -0
  312. package/src/lib/hexclave-app/data-vault/index.ts +12 -0
  313. package/src/lib/hexclave-app/email/index.ts +280 -0
  314. package/src/lib/hexclave-app/email-templates/index.ts +24 -0
  315. package/src/lib/hexclave-app/index.ts +146 -0
  316. package/src/lib/hexclave-app/internal-api-keys/index.ts +55 -0
  317. package/src/lib/hexclave-app/notification-categories/index.ts +12 -0
  318. package/src/lib/hexclave-app/permissions/index.ts +75 -0
  319. package/src/lib/hexclave-app/project-configs/index.ts +103 -0
  320. package/src/lib/hexclave-app/projects/index.ts +234 -0
  321. package/src/lib/hexclave-app/session-replays/index.ts +72 -0
  322. package/src/lib/hexclave-app/teams/index.ts +203 -0
  323. package/src/lib/hexclave-app/url-targets.test.ts +253 -0
  324. package/src/lib/hexclave-app/url-targets.ts +395 -0
  325. package/src/lib/hexclave-app/users/index.ts +495 -0
  326. package/src/utils/url.ts +24 -0
  327. package/dist/esm/lib/stack-app/api-keys/index.js.map +0 -1
  328. package/dist/esm/lib/stack-app/apps/implementations/admin-app-impl.d.ts.map +0 -1
  329. package/dist/esm/lib/stack-app/apps/implementations/admin-app-impl.js.map +0 -1
  330. package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.cross-domain.test.js.map +0 -1
  331. package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.d.ts.map +0 -1
  332. package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.js.map +0 -1
  333. package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.oauth-prefetch.test.js.map +0 -1
  334. package/dist/esm/lib/stack-app/apps/implementations/common.js.map +0 -1
  335. package/dist/esm/lib/stack-app/apps/implementations/event-tracker.js.map +0 -1
  336. package/dist/esm/lib/stack-app/apps/implementations/event-tracker.test.js.map +0 -1
  337. package/dist/esm/lib/stack-app/apps/implementations/index.d.ts +0 -9
  338. package/dist/esm/lib/stack-app/apps/implementations/index.d.ts.map +0 -1
  339. package/dist/esm/lib/stack-app/apps/implementations/index.js +0 -27
  340. package/dist/esm/lib/stack-app/apps/implementations/index.js.map +0 -1
  341. package/dist/esm/lib/stack-app/apps/implementations/redirect-page-urls.js.map +0 -1
  342. package/dist/esm/lib/stack-app/apps/implementations/server-app-impl.js.map +0 -1
  343. package/dist/esm/lib/stack-app/apps/implementations/session-refresh-subscription.js.map +0 -1
  344. package/dist/esm/lib/stack-app/apps/implementations/session-refresh-subscription.test.js.map +0 -1
  345. package/dist/esm/lib/stack-app/apps/implementations/session-replay.js.map +0 -1
  346. package/dist/esm/lib/stack-app/apps/implementations/session-replay.test.js.map +0 -1
  347. package/dist/esm/lib/stack-app/apps/interfaces/admin-app.js.map +0 -1
  348. package/dist/esm/lib/stack-app/apps/interfaces/client-app.js.map +0 -1
  349. package/dist/esm/lib/stack-app/apps/interfaces/server-app.js.map +0 -1
  350. package/dist/esm/lib/stack-app/common.js +0 -7
  351. package/dist/esm/lib/stack-app/common.js.map +0 -1
  352. package/dist/esm/lib/stack-app/contact-channels/index.js.map +0 -1
  353. package/dist/esm/lib/stack-app/email-templates/index.js.map +0 -1
  354. package/dist/esm/lib/stack-app/internal-api-keys/index.js.map +0 -1
  355. package/dist/esm/lib/stack-app/permissions/index.js.map +0 -1
  356. package/dist/esm/lib/stack-app/projects/index.js.map +0 -1
  357. package/dist/esm/lib/stack-app/teams/index.js.map +0 -1
  358. package/dist/esm/lib/stack-app/url-targets.js.map +0 -1
  359. package/dist/esm/lib/stack-app/url-targets.test.js.map +0 -1
  360. package/dist/esm/lib/stack-app/users/index.js.map +0 -1
  361. package/dist/lib/stack-app/api-keys/index.d.ts.map +0 -1
  362. package/dist/lib/stack-app/api-keys/index.js.map +0 -1
  363. package/dist/lib/stack-app/apps/implementations/admin-app-impl.d.ts.map +0 -1
  364. package/dist/lib/stack-app/apps/implementations/admin-app-impl.js.map +0 -1
  365. package/dist/lib/stack-app/apps/implementations/client-app-impl.cross-domain.test.js.map +0 -1
  366. package/dist/lib/stack-app/apps/implementations/client-app-impl.d.ts.map +0 -1
  367. package/dist/lib/stack-app/apps/implementations/client-app-impl.js.map +0 -1
  368. package/dist/lib/stack-app/apps/implementations/client-app-impl.oauth-prefetch.test.js.map +0 -1
  369. package/dist/lib/stack-app/apps/implementations/common.d.ts.map +0 -1
  370. package/dist/lib/stack-app/apps/implementations/common.js.map +0 -1
  371. package/dist/lib/stack-app/apps/implementations/event-tracker.d.ts.map +0 -1
  372. package/dist/lib/stack-app/apps/implementations/event-tracker.js.map +0 -1
  373. package/dist/lib/stack-app/apps/implementations/event-tracker.test.js.map +0 -1
  374. package/dist/lib/stack-app/apps/implementations/index.d.ts +0 -9
  375. package/dist/lib/stack-app/apps/implementations/index.d.ts.map +0 -1
  376. package/dist/lib/stack-app/apps/implementations/index.js +0 -31
  377. package/dist/lib/stack-app/apps/implementations/index.js.map +0 -1
  378. package/dist/lib/stack-app/apps/implementations/redirect-page-urls.d.ts.map +0 -1
  379. package/dist/lib/stack-app/apps/implementations/redirect-page-urls.js.map +0 -1
  380. package/dist/lib/stack-app/apps/implementations/server-app-impl.d.ts.map +0 -1
  381. package/dist/lib/stack-app/apps/implementations/server-app-impl.js.map +0 -1
  382. package/dist/lib/stack-app/apps/implementations/session-refresh-subscription.d.ts.map +0 -1
  383. package/dist/lib/stack-app/apps/implementations/session-refresh-subscription.js.map +0 -1
  384. package/dist/lib/stack-app/apps/implementations/session-refresh-subscription.test.js.map +0 -1
  385. package/dist/lib/stack-app/apps/implementations/session-replay.d.ts.map +0 -1
  386. package/dist/lib/stack-app/apps/implementations/session-replay.js.map +0 -1
  387. package/dist/lib/stack-app/apps/implementations/session-replay.test.js.map +0 -1
  388. package/dist/lib/stack-app/apps/interfaces/admin-app.d.ts.map +0 -1
  389. package/dist/lib/stack-app/apps/interfaces/admin-app.js.map +0 -1
  390. package/dist/lib/stack-app/apps/interfaces/client-app.d.ts.map +0 -1
  391. package/dist/lib/stack-app/apps/interfaces/client-app.js.map +0 -1
  392. package/dist/lib/stack-app/apps/interfaces/server-app.d.ts.map +0 -1
  393. package/dist/lib/stack-app/apps/interfaces/server-app.js.map +0 -1
  394. package/dist/lib/stack-app/common.d.ts.map +0 -1
  395. package/dist/lib/stack-app/common.js +0 -9
  396. package/dist/lib/stack-app/common.js.map +0 -1
  397. package/dist/lib/stack-app/connected-accounts/index.d.ts.map +0 -1
  398. package/dist/lib/stack-app/contact-channels/index.d.ts.map +0 -1
  399. package/dist/lib/stack-app/contact-channels/index.js.map +0 -1
  400. package/dist/lib/stack-app/customers/index.d.ts.map +0 -1
  401. package/dist/lib/stack-app/data-vault/index.d.ts.map +0 -1
  402. package/dist/lib/stack-app/email/index.d.ts.map +0 -1
  403. package/dist/lib/stack-app/email-templates/index.d.ts.map +0 -1
  404. package/dist/lib/stack-app/email-templates/index.js.map +0 -1
  405. package/dist/lib/stack-app/internal-api-keys/index.d.ts.map +0 -1
  406. package/dist/lib/stack-app/internal-api-keys/index.js.map +0 -1
  407. package/dist/lib/stack-app/notification-categories/index.d.ts.map +0 -1
  408. package/dist/lib/stack-app/permissions/index.d.ts.map +0 -1
  409. package/dist/lib/stack-app/permissions/index.js.map +0 -1
  410. package/dist/lib/stack-app/project-configs/index.d.ts.map +0 -1
  411. package/dist/lib/stack-app/projects/index.d.ts.map +0 -1
  412. package/dist/lib/stack-app/projects/index.js.map +0 -1
  413. package/dist/lib/stack-app/session-replays/index.d.ts.map +0 -1
  414. package/dist/lib/stack-app/teams/index.d.ts.map +0 -1
  415. package/dist/lib/stack-app/teams/index.js.map +0 -1
  416. package/dist/lib/stack-app/url-targets.d.ts.map +0 -1
  417. package/dist/lib/stack-app/url-targets.js.map +0 -1
  418. package/dist/lib/stack-app/url-targets.test.js.map +0 -1
  419. package/dist/lib/stack-app/users/index.d.ts.map +0 -1
  420. package/dist/lib/stack-app/users/index.js.map +0 -1
  421. /package/dist/esm/lib/{stack-app → hexclave-app}/apps/implementations/client-app-impl.cross-domain.test.d.ts +0 -0
  422. /package/dist/esm/lib/{stack-app → hexclave-app}/apps/implementations/client-app-impl.oauth-prefetch.test.d.ts +0 -0
  423. /package/dist/esm/lib/{stack-app → hexclave-app}/apps/implementations/event-tracker.test.d.ts +0 -0
  424. /package/dist/esm/lib/{stack-app → hexclave-app}/apps/implementations/session-refresh-subscription.test.d.ts +0 -0
  425. /package/dist/esm/lib/{stack-app → hexclave-app}/apps/implementations/session-replay.test.d.ts +0 -0
  426. /package/dist/esm/lib/{stack-app → hexclave-app}/apps/index.d.ts +0 -0
  427. /package/dist/esm/lib/{stack-app → hexclave-app}/apps/index.js +0 -0
  428. /package/dist/esm/lib/{stack-app → hexclave-app}/connected-accounts/index.js +0 -0
  429. /package/dist/esm/lib/{stack-app → hexclave-app}/customers/index.js +0 -0
  430. /package/dist/esm/lib/{stack-app → hexclave-app}/data-vault/index.js +0 -0
  431. /package/dist/esm/lib/{stack-app → hexclave-app}/email/index.js +0 -0
  432. /package/dist/esm/lib/{stack-app → hexclave-app}/notification-categories/index.js +0 -0
  433. /package/dist/esm/lib/{stack-app → hexclave-app}/project-configs/index.js +0 -0
  434. /package/dist/esm/lib/{stack-app → hexclave-app}/session-replays/index.js +0 -0
  435. /package/dist/esm/lib/{stack-app → hexclave-app}/url-targets.test.d.ts +0 -0
  436. /package/dist/lib/{stack-app → hexclave-app}/apps/implementations/client-app-impl.cross-domain.test.d.ts +0 -0
  437. /package/dist/lib/{stack-app → hexclave-app}/apps/implementations/client-app-impl.oauth-prefetch.test.d.ts +0 -0
  438. /package/dist/lib/{stack-app → hexclave-app}/apps/implementations/event-tracker.test.d.ts +0 -0
  439. /package/dist/lib/{stack-app → hexclave-app}/apps/implementations/session-refresh-subscription.test.d.ts +0 -0
  440. /package/dist/lib/{stack-app → hexclave-app}/apps/implementations/session-replay.test.d.ts +0 -0
  441. /package/dist/lib/{stack-app → hexclave-app}/apps/index.d.ts +0 -0
  442. /package/dist/lib/{stack-app → hexclave-app}/apps/index.js +0 -0
  443. /package/dist/lib/{stack-app → hexclave-app}/connected-accounts/index.js +0 -0
  444. /package/dist/lib/{stack-app → hexclave-app}/customers/index.js +0 -0
  445. /package/dist/lib/{stack-app → hexclave-app}/data-vault/index.js +0 -0
  446. /package/dist/lib/{stack-app → hexclave-app}/email/index.js +0 -0
  447. /package/dist/lib/{stack-app → hexclave-app}/notification-categories/index.js +0 -0
  448. /package/dist/lib/{stack-app → hexclave-app}/project-configs/index.js +0 -0
  449. /package/dist/lib/{stack-app → hexclave-app}/session-replays/index.js +0 -0
  450. /package/dist/lib/{stack-app → hexclave-app}/url-targets.test.d.ts +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"file":"event-tracker.js","names":[],"sources":["../../../../../../src/lib/stack-app/apps/implementations/event-tracker.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { isBrowserLike } from \"@hexclave/shared/dist/utils/env\";\nimport { runAsynchronously } from \"@hexclave/shared/dist/utils/promises\";\nimport { Result } from \"@hexclave/shared/dist/utils/results\";\nimport { generateUuid } from \"./session-replay\";\n\nconst FLUSH_INTERVAL_MS = 10_000;\nconst MAX_EVENTS_PER_BATCH = 50;\nconst MAX_APPROX_BYTES_PER_BATCH = 64_000;\n\nfunction hasScreenDimensions(value: unknown): value is { width: number, height: number } {\n if (value == null || typeof value !== \"object\") {\n return false;\n }\n if (!(\"width\" in value) || !(\"height\" in value)) {\n return false;\n }\n return typeof value.width === \"number\" && typeof value.height === \"number\";\n}\n\nfunction hasHistoryMethods(value: unknown): value is { pushState: History[\"pushState\"], replaceState: History[\"replaceState\"] } {\n if (value == null || typeof value !== \"object\") {\n return false;\n }\n if (!(\"pushState\" in value) || !(\"replaceState\" in value)) {\n return false;\n }\n return typeof value.pushState === \"function\" && typeof value.replaceState === \"function\";\n}\n\nexport type EventTrackerDeps = {\n projectId: string,\n sendBatch: (body: string, options: { keepalive: boolean }) => Promise<Result<Response, Error>>,\n};\n\ntype TrackedEvent = {\n event_type: \"$page-view\" | \"$click\",\n event_at_ms: number,\n data: Record<string, unknown>,\n};\n\nexport class EventTracker {\n private _started = false;\n private _cancelled = false;\n private _detachListeners: (() => void) | null = null;\n private _flushTimer: ReturnType<typeof setInterval> | null = null;\n private _events: TrackedEvent[] = [];\n private _approxBytes = 0;\n private _lastUrl: string | null = null;\n private readonly _sessionReplaySegmentId: string;\n private readonly _deps: EventTrackerDeps;\n\n private _originalPushState: History[\"pushState\"] | null = null;\n private _originalReplaceState: History[\"replaceState\"] | null = null;\n\n constructor(deps: EventTrackerDeps) {\n this._deps = deps;\n this._sessionReplaySegmentId = generateUuid();\n }\n\n start() {\n if (this._started) return;\n if (!isBrowserLike()) return;\n if (\n typeof window.addEventListener !== \"function\"\n || typeof window.removeEventListener !== \"function\"\n || typeof document.addEventListener !== \"function\"\n || typeof document.removeEventListener !== \"function\"\n || !hasScreenDimensions(window.screen)\n ) {\n return;\n }\n this._started = true;\n\n this._setupPageViewCapture();\n this._setupClickCapture();\n this._setupPageHideListeners();\n\n this._flushTimer = setInterval(() => this._tick(), FLUSH_INTERVAL_MS);\n }\n\n stop() {\n this._cancelled = true;\n if (this._flushTimer !== null) {\n clearInterval(this._flushTimer);\n this._flushTimer = null;\n }\n runAsynchronously(() => this._flush({ keepalive: true }));\n this._teardown();\n }\n\n clearBuffer() {\n this._events = [];\n this._approxBytes = 0;\n }\n\n private _pushEvent(event: TrackedEvent) {\n this._events.push(event);\n this._approxBytes += JSON.stringify(event).length;\n if (this._events.length >= MAX_EVENTS_PER_BATCH || this._approxBytes >= MAX_APPROX_BYTES_PER_BATCH) {\n runAsynchronously(() => this._flush({ keepalive: false }));\n }\n }\n\n private _capturePageView(entryType: \"initial\" | \"push\" | \"replace\" | \"pop\") {\n const screenObject = window.screen;\n if (!hasScreenDimensions(screenObject)) {\n return;\n }\n\n const url = window.location.href;\n if (url === this._lastUrl && entryType !== \"initial\") return;\n this._lastUrl = url;\n\n this._pushEvent({\n event_type: \"$page-view\",\n event_at_ms: Date.now(),\n data: {\n url,\n path: window.location.pathname,\n referrer: document.referrer,\n title: document.title,\n entry_type: entryType,\n viewport_width: window.innerWidth,\n viewport_height: window.innerHeight,\n screen_width: screenObject.width,\n screen_height: screenObject.height,\n },\n });\n }\n\n private _setupPageViewCapture() {\n // Fire initial page-view\n this._capturePageView(\"initial\");\n const historyObject = window.history;\n if (!hasHistoryMethods(historyObject)) {\n return;\n }\n const originalPushState = historyObject.pushState;\n const originalReplaceState = historyObject.replaceState;\n\n // Monkey-patch history.pushState\n this._originalPushState = (...args: Parameters<History[\"pushState\"]>) => originalPushState.apply(historyObject, args);\n historyObject.pushState = (...args: Parameters<History[\"pushState\"]>) => {\n this._originalPushState!(...args);\n this._capturePageView(\"push\");\n };\n\n // Monkey-patch history.replaceState\n this._originalReplaceState = (...args: Parameters<History[\"replaceState\"]>) => originalReplaceState.apply(historyObject, args);\n historyObject.replaceState = (...args: Parameters<History[\"replaceState\"]>) => {\n this._originalReplaceState!(...args);\n this._capturePageView(\"replace\");\n };\n\n // Listen for popstate (back/forward navigation)\n window.addEventListener(\"popstate\", this._onPopState);\n }\n\n private readonly _onPopState = () => {\n this._capturePageView(\"pop\");\n };\n\n private _buildSelector(element: Element): string {\n const parts: string[] = [];\n let current: Element | null = element;\n let depth = 0;\n\n while (current && depth < 5) {\n let part = current.tagName.toLowerCase();\n if (current.id) {\n part += `#${current.id}`;\n parts.unshift(part);\n break;\n }\n if (current.className && typeof current.className === \"string\") {\n const classes = current.className.trim().split(/\\s+/).filter(Boolean);\n if (classes.length > 0) {\n part += `.${classes.join(\".\")}`;\n }\n }\n parts.unshift(part);\n current = current.parentElement;\n depth++;\n }\n\n return parts.join(\" > \");\n }\n\n private _findNearestAnchorHref(element: Element): string | null {\n let current: Element | null = element;\n while (current) {\n if (current.tagName === \"A\" && current.hasAttribute(\"href\")) {\n return current.getAttribute(\"href\");\n }\n current = current.parentElement;\n }\n return null;\n }\n\n private readonly _onClickCapture = (event: MouseEvent) => {\n const target = event.target;\n if (!(target instanceof Element)) return;\n\n this._pushEvent({\n event_type: \"$click\",\n event_at_ms: Date.now(),\n data: {\n tag_name: target.tagName.toLowerCase(),\n text: target.textContent.trim().substring(0, 200),\n href: this._findNearestAnchorHref(target),\n selector: this._buildSelector(target),\n x: event.clientX,\n y: event.clientY,\n page_x: event.pageX,\n page_y: event.pageY,\n viewport_width: window.innerWidth,\n viewport_height: window.innerHeight,\n },\n });\n };\n\n private _setupClickCapture() {\n document.addEventListener(\"click\", this._onClickCapture, { capture: true });\n }\n\n private readonly _onPageHide = () => {\n runAsynchronously(() => this._flush({ keepalive: true }));\n };\n\n private _setupPageHideListeners() {\n window.addEventListener(\"pagehide\", this._onPageHide);\n document.addEventListener(\"visibilitychange\", this._onPageHide);\n this._detachListeners = () => {\n window.removeEventListener(\"pagehide\", this._onPageHide);\n document.removeEventListener(\"visibilitychange\", this._onPageHide);\n };\n }\n\n private _teardown() {\n if (this._detachListeners) {\n this._detachListeners();\n this._detachListeners = null;\n }\n\n // Restore history methods\n const historyObject = window.history;\n if (hasHistoryMethods(historyObject)) {\n if (this._originalPushState) {\n historyObject.pushState = this._originalPushState;\n }\n if (this._originalReplaceState) {\n historyObject.replaceState = this._originalReplaceState;\n }\n }\n this._originalPushState = null;\n this._originalReplaceState = null;\n\n window.removeEventListener(\"popstate\", this._onPopState);\n document.removeEventListener(\"click\", this._onClickCapture, { capture: true });\n\n this._events = [];\n this._approxBytes = 0;\n }\n\n private async _flush(options: { keepalive: boolean }) {\n if (this._events.length === 0) return;\n\n const nowMs = Date.now();\n\n const batchId = generateUuid();\n const payload = {\n session_replay_segment_id: this._sessionReplaySegmentId,\n batch_id: batchId,\n sent_at_ms: nowMs,\n events: this._events,\n };\n\n this._events = [];\n this._approxBytes = 0;\n\n const res = await this._deps.sendBatch(\n JSON.stringify(payload),\n { keepalive: options.keepalive },\n );\n\n if (res.status === \"error\") {\n console.warn(\"EventTracker flush failed:\", res.error);\n return;\n }\n\n if (!res.data.ok) {\n console.warn(\"EventTracker flush failed:\", res.data.status, await res.data.text());\n }\n }\n\n private _tick() {\n if (this._cancelled) return;\n if (this._events.length > 0) {\n runAsynchronously(() => this._flush({ keepalive: false }));\n }\n }\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"event-tracker.test.js","names":[],"sources":["../../../../../../src/lib/stack-app/apps/implementations/event-tracker.test.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n// @vitest-environment jsdom\n\nimport { Result } from \"@hexclave/shared/dist/utils/results\";\nimport { afterEach, describe, expect, it, vi } from \"vitest\";\nimport { EventTracker } from \"./event-tracker\";\n\nasync function advancePastFlush() {\n await vi.advanceTimersByTimeAsync(10_000);\n await Promise.resolve();\n}\n\nfunction getSentEventTypes(sentBodies: string[]) {\n const [body] = sentBodies;\n\n const payload = JSON.parse(body);\n if (typeof payload !== \"object\" || payload === null || !(\"events\" in payload) || !Array.isArray(payload.events)) {\n throw new Error(\"Expected analytics batch payload to include an events array.\");\n }\n\n return (payload.events as { event_type: string }[]).map((event) => event.event_type);\n}\n\ndescribe(\"EventTracker\", () => {\n afterEach(() => {\n vi.useRealTimers();\n });\n\n it(\"captures events when browser globals are exposed as accessor descriptors\", async () => {\n vi.useFakeTimers();\n document.body.innerHTML = \"<button>Open project</button>\";\n\n const screenDescriptor = Object.getOwnPropertyDescriptor(window, \"screen\");\n const historyDescriptor = Object.getOwnPropertyDescriptor(window, \"history\");\n expect(screenDescriptor?.value).toBeUndefined();\n expect(historyDescriptor?.value).toBeUndefined();\n expect(screenDescriptor?.get).toBeTypeOf(\"function\");\n expect(historyDescriptor?.get).toBeTypeOf(\"function\");\n\n const sentBodies: string[] = [];\n const tracker = new EventTracker({\n projectId: \"internal\",\n sendBatch: async (body) => {\n sentBodies.push(body);\n return Result.ok(new Response());\n },\n });\n\n try {\n tracker.start();\n document.querySelector(\"button\")?.dispatchEvent(new MouseEvent(\"click\", {\n bubbles: true,\n clientX: 12,\n clientY: 34,\n }));\n\n await advancePastFlush();\n\n expect(getSentEventTypes(sentBodies)).toMatchInlineSnapshot(`\n [\n \"$page-view\",\n \"$click\",\n ]\n `);\n } finally {\n tracker.stop();\n }\n });\n\n it(\"captures client-side navigations when history is exposed as an accessor descriptor\", async () => {\n vi.useFakeTimers();\n\n const historyDescriptor = Object.getOwnPropertyDescriptor(window, \"history\");\n expect(historyDescriptor?.value).toBeUndefined();\n expect(historyDescriptor?.get).toBeTypeOf(\"function\");\n\n const sentBodies: string[] = [];\n const tracker = new EventTracker({\n projectId: \"internal\",\n sendBatch: async (body) => {\n sentBodies.push(body);\n return Result.ok(new Response());\n },\n });\n\n try {\n tracker.start();\n window.history.pushState({}, \"\", \"/projects/test-project\");\n\n await advancePastFlush();\n\n expect(getSentEventTypes(sentBodies)).toMatchInlineSnapshot(`\n [\n \"$page-view\",\n \"$page-view\",\n ]\n `);\n } finally {\n tracker.stop();\n }\n });\n});\n"],"mappings":";;;;;;AAUA,eAAe,mBAAmB;AAChC,OAAM,GAAG,yBAAyB,IAAO;AACzC,OAAM,QAAQ,SAAS;;AAGzB,SAAS,kBAAkB,YAAsB;CAC/C,MAAM,CAAC,QAAQ;CAEf,MAAM,UAAU,KAAK,MAAM,KAAK;AAChC,KAAI,OAAO,YAAY,YAAY,YAAY,QAAQ,EAAE,YAAY,YAAY,CAAC,MAAM,QAAQ,QAAQ,OAAO,CAC7G,OAAM,IAAI,MAAM,+DAA+D;AAGjF,QAAQ,QAAQ,OAAoC,KAAK,UAAU,MAAM,WAAW;;AAGtF,SAAS,sBAAsB;AAC7B,iBAAgB;AACd,KAAG,eAAe;GAClB;AAEF,IAAG,4EAA4E,YAAY;AACzF,KAAG,eAAe;AAClB,WAAS,KAAK,YAAY;EAE1B,MAAM,mBAAmB,OAAO,yBAAyB,QAAQ,SAAS;EAC1E,MAAM,oBAAoB,OAAO,yBAAyB,QAAQ,UAAU;AAC5E,SAAO,kBAAkB,MAAM,CAAC,eAAe;AAC/C,SAAO,mBAAmB,MAAM,CAAC,eAAe;AAChD,SAAO,kBAAkB,IAAI,CAAC,WAAW,WAAW;AACpD,SAAO,mBAAmB,IAAI,CAAC,WAAW,WAAW;EAErD,MAAM,aAAuB,EAAE;EAC/B,MAAM,UAAU,IAAI,aAAa;GAC/B,WAAW;GACX,WAAW,OAAO,SAAS;AACzB,eAAW,KAAK,KAAK;AACrB,WAAO,OAAO,GAAG,IAAI,UAAU,CAAC;;GAEnC,CAAC;AAEF,MAAI;AACF,WAAQ,OAAO;AACf,YAAS,cAAc,SAAS,EAAE,cAAc,IAAI,WAAW,SAAS;IACtE,SAAS;IACT,SAAS;IACT,SAAS;IACV,CAAC,CAAC;AAEH,SAAM,kBAAkB;AAExB,UAAO,kBAAkB,WAAW,CAAC,CAAC,sBAAsB;;;;;QAK1D;YACM;AACR,WAAQ,MAAM;;GAEhB;AAEF,IAAG,sFAAsF,YAAY;AACnG,KAAG,eAAe;EAElB,MAAM,oBAAoB,OAAO,yBAAyB,QAAQ,UAAU;AAC5E,SAAO,mBAAmB,MAAM,CAAC,eAAe;AAChD,SAAO,mBAAmB,IAAI,CAAC,WAAW,WAAW;EAErD,MAAM,aAAuB,EAAE;EAC/B,MAAM,UAAU,IAAI,aAAa;GAC/B,WAAW;GACX,WAAW,OAAO,SAAS;AACzB,eAAW,KAAK,KAAK;AACrB,WAAO,OAAO,GAAG,IAAI,UAAU,CAAC;;GAEnC,CAAC;AAEF,MAAI;AACF,WAAQ,OAAO;AACf,UAAO,QAAQ,UAAU,EAAE,EAAE,IAAI,yBAAyB;AAE1D,SAAM,kBAAkB;AAExB,UAAO,kBAAkB,WAAW,CAAC,CAAC,sBAAsB;;;;;QAK1D;YACM;AACR,WAAQ,MAAM;;GAEhB;EACF"}
@@ -1,9 +0,0 @@
1
- import { _StackServerAppImplIncomplete } from "./server-app-impl";
2
- import { _StackAdminAppImplIncomplete } from "./admin-app-impl";
3
- import { _StackClientAppImplIncomplete } from "./client-app-impl";
4
-
5
- //#region src/lib/stack-app/apps/implementations/index.d.ts
6
- declare const _StackAdminAppImpl: typeof _StackAdminAppImplIncomplete, _StackClientAppImpl: typeof _StackClientAppImplIncomplete, _StackServerAppImpl: typeof _StackServerAppImplIncomplete;
7
- //#endregion
8
- export { _StackAdminAppImpl, _StackClientAppImpl, _StackServerAppImpl };
9
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../../../../../src/lib/stack-app/apps/implementations/index.ts"],"mappings":";;;;;cA8BE,kBAAA,SAAkB,4BAAA,EAAA,mBAAA,SACC,6BAAA,EAAA,mBAAA,SACA,6BAAA"}
@@ -1,27 +0,0 @@
1
- import { _StackServerAppImplIncomplete } from "./server-app-impl.js";
2
- import { scrambleDuringCompileTime } from "@hexclave/shared/dist/utils/compile-time";
3
- import { _StackAdminAppImplIncomplete } from "./admin-app-impl.js";
4
- import { _StackClientAppImplIncomplete } from "./client-app-impl.js";
5
-
6
- //#region src/lib/stack-app/apps/implementations/index.ts
7
- /**
8
- * Prevents a circular dependency between the client and admin apps. For more information, see the documentation comment
9
- * of `_StackClientAppImplIncomplete.LazyStackAdminAppImpl`.
10
- *
11
- * Note: This is an explicitly defined function that returns the new values (and not a barrel file with top-level side
12
- * effects) because we have `sideEffects: false` in the package.json, and so it would be tree-shaken away if we just
13
- * exported the values directly.
14
- */
15
- function complete() {
16
- _StackClientAppImplIncomplete.LazyStackAdminAppImpl.value = _StackAdminAppImplIncomplete;
17
- return {
18
- _StackAdminAppImpl: scrambleDuringCompileTime(_StackAdminAppImplIncomplete),
19
- _StackClientAppImpl: scrambleDuringCompileTime(_StackClientAppImplIncomplete),
20
- _StackServerAppImpl: scrambleDuringCompileTime(_StackServerAppImplIncomplete)
21
- };
22
- }
23
- const { _StackAdminAppImpl, _StackClientAppImpl, _StackServerAppImpl } = complete();
24
-
25
- //#endregion
26
- export { _StackAdminAppImpl, _StackClientAppImpl, _StackServerAppImpl };
27
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../../../../src/lib/stack-app/apps/implementations/index.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { scrambleDuringCompileTime } from \"@hexclave/shared/dist/utils/compile-time\";\nimport { _StackAdminAppImplIncomplete } from \"./admin-app-impl\";\nimport { _StackClientAppImplIncomplete } from \"./client-app-impl\";\nimport { _StackServerAppImplIncomplete } from \"./server-app-impl\";\n\n\n/**\n * Prevents a circular dependency between the client and admin apps. For more information, see the documentation comment\n * of `_StackClientAppImplIncomplete.LazyStackAdminAppImpl`.\n *\n * Note: This is an explicitly defined function that returns the new values (and not a barrel file with top-level side\n * effects) because we have `sideEffects: false` in the package.json, and so it would be tree-shaken away if we just\n * exported the values directly.\n */\nfunction complete() {\n _StackClientAppImplIncomplete.LazyStackAdminAppImpl.value = _StackAdminAppImplIncomplete;\n\n return {\n _StackAdminAppImpl: scrambleDuringCompileTime(_StackAdminAppImplIncomplete),\n _StackClientAppImpl: scrambleDuringCompileTime(_StackClientAppImplIncomplete),\n _StackServerAppImpl: scrambleDuringCompileTime(_StackServerAppImplIncomplete),\n };\n}\n\nexport const {\n _StackAdminAppImpl,\n _StackClientAppImpl,\n _StackServerAppImpl\n} = complete();\n\n"],"mappings":";;;;;;;;;;;;;;AAmBA,SAAS,WAAW;AAClB,+BAA8B,sBAAsB,QAAQ;AAE5D,QAAO;EACL,oBAAoB,0BAA0B,6BAA6B;EAC3E,qBAAqB,0BAA0B,8BAA8B;EAC7E,qBAAqB,0BAA0B,8BAA8B;EAC9E;;AAGH,MAAa,EACX,oBACA,qBACA,wBACE,UAAU"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"redirect-page-urls.js","names":[],"sources":["../../../../../../src/lib/stack-app/apps/implementations/redirect-page-urls.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { HexclaveAssertionError } from \"@hexclave/shared/dist/utils/errors\";\nimport { getRelativePart } from \"@hexclave/shared/dist/utils/urls\";\nimport { HandlerUrls } from \"../../common\";\n\nexport const crossDomainAuthQueryParams = {\n marker: \"hexclave_cross_domain_auth\",\n state: \"hexclave_cross_domain_state\",\n codeChallenge: \"hexclave_cross_domain_code_challenge\",\n afterCallbackRedirectUrl: \"hexclave_cross_domain_after_callback_redirect_url\",\n} as const;\n\ntype CrossDomainAuthQueryParamKey = keyof typeof crossDomainAuthQueryParams;\n\nfunction getCrossDomainParam(params: URLSearchParams, key: CrossDomainAuthQueryParamKey): string | null {\n return params.get(crossDomainAuthQueryParams[key]);\n}\n\nfunction hasCrossDomainParam(params: URLSearchParams, key: CrossDomainAuthQueryParamKey): boolean {\n return params.has(crossDomainAuthQueryParams[key]);\n}\n\nfunction setCrossDomainParam(params: URLSearchParams, key: CrossDomainAuthQueryParamKey, value: string): void {\n params.set(crossDomainAuthQueryParams[key], value);\n}\n\nexport type CrossDomainHandoffParams = {\n state: string,\n codeChallenge: string,\n};\n\nexport function getCrossDomainHandoffParamsFromCurrentUrl(currentUrl: URL): CrossDomainHandoffParams | null {\n const state = getCrossDomainParam(currentUrl.searchParams, \"state\");\n const codeChallenge = getCrossDomainParam(currentUrl.searchParams, \"codeChallenge\");\n if (state == null || codeChallenge == null) {\n return null;\n }\n return { state, codeChallenge };\n}\n\ntype RedirectBackAwareHandlerName = \"signIn\" | \"signUp\" | \"onboarding\" | \"signOut\";\ntype HandlerRedirectPolicy = \"none\" | \"redirect-back-aware\" | \"after-auth-return\";\n\ntype CrossDomainHandoffParamsMaybeMissing = {\n state: string | null,\n codeChallenge: string | null,\n afterCallbackRedirectUrl: string | null,\n};\n\nfunction isRedirectBackAwareHandlerName(handlerName: keyof HandlerUrls): handlerName is RedirectBackAwareHandlerName {\n return handlerName === \"signIn\"\n || handlerName === \"signUp\"\n || handlerName === \"onboarding\"\n || handlerName === \"signOut\";\n}\n\nfunction hasCrossDomainHandoffParams(url: URL): boolean {\n return (\n hasCrossDomainParam(url.searchParams, \"state\")\n && hasCrossDomainParam(url.searchParams, \"codeChallenge\")\n && hasCrossDomainParam(url.searchParams, \"afterCallbackRedirectUrl\")\n );\n}\n\nfunction buildCrossDomainAuthCallbackUrl(options: {\n currentUrl: URL,\n localOAuthCallbackUrl: string,\n state?: string,\n codeChallenge?: string,\n afterCallbackRedirectUrl?: string,\n}): URL {\n const localOAuthCallbackUrl = new URL(options.localOAuthCallbackUrl, options.currentUrl);\n if (localOAuthCallbackUrl.origin !== options.currentUrl.origin) {\n throw new HexclaveAssertionError(\"Cross-domain auth callback URL must stay on the current origin\", {\n localOAuthCallbackUrl: localOAuthCallbackUrl.toString(),\n currentUrl: options.currentUrl.toString(),\n });\n }\n setCrossDomainParam(localOAuthCallbackUrl.searchParams, \"marker\", \"1\");\n if (options.state != null) {\n setCrossDomainParam(localOAuthCallbackUrl.searchParams, \"state\", options.state);\n }\n if (options.codeChallenge != null) {\n setCrossDomainParam(localOAuthCallbackUrl.searchParams, \"codeChallenge\", options.codeChallenge);\n }\n if (options.afterCallbackRedirectUrl != null) {\n setCrossDomainParam(localOAuthCallbackUrl.searchParams, \"afterCallbackRedirectUrl\", options.afterCallbackRedirectUrl);\n }\n return localOAuthCallbackUrl;\n}\n\nfunction buildRedirectBackAwareHandlerUrl(options: {\n handlerName: RedirectBackAwareHandlerName,\n rawHandlerUrl: string,\n currentUrl: URL,\n crossDomainHandoffParams: CrossDomainHandoffParams | null,\n localOAuthCallbackUrl: string,\n}): string {\n const nextUrl = new URL(options.rawHandlerUrl, options.currentUrl);\n // Preserve after_auth_return_to verbatim (not a rebranded param).\n const currentAfterAuthReturnTo = options.currentUrl.searchParams.get(\"after_auth_return_to\");\n if (currentAfterAuthReturnTo != null && !nextUrl.searchParams.has(\"after_auth_return_to\")) {\n nextUrl.searchParams.set(\"after_auth_return_to\", currentAfterAuthReturnTo);\n }\n for (const preservedParam of [\"state\", \"codeChallenge\", \"afterCallbackRedirectUrl\"] as const) {\n const currentValue = getCrossDomainParam(options.currentUrl.searchParams, preservedParam);\n if (currentValue != null && !hasCrossDomainParam(nextUrl.searchParams, preservedParam)) {\n setCrossDomainParam(nextUrl.searchParams, preservedParam, currentValue);\n }\n }\n\n if (options.handlerName === \"signOut\") {\n if (!nextUrl.searchParams.has(\"after_auth_return_to\")) {\n if (options.currentUrl.protocol === nextUrl.protocol && options.currentUrl.host === nextUrl.host) {\n nextUrl.searchParams.set(\"after_auth_return_to\", getRelativePart(options.currentUrl));\n } else {\n nextUrl.searchParams.set(\"after_auth_return_to\", options.currentUrl.toString());\n }\n }\n return nextUrl.origin === options.currentUrl.origin ? getRelativePart(nextUrl) : nextUrl.toString();\n }\n\n const isCrossDomainHandlerRedirect = options.currentUrl.origin !== nextUrl.origin;\n if (isCrossDomainHandlerRedirect) {\n if (!hasCrossDomainHandoffParams(nextUrl)) {\n const inheritedAfterAuthReturnTo = options.currentUrl.searchParams.get(\"after_auth_return_to\");\n const afterCallbackRedirectUrl = inheritedAfterAuthReturnTo\n ? new URL(inheritedAfterAuthReturnTo, options.currentUrl).toString()\n : options.currentUrl.toString();\n const callbackUrl = buildCrossDomainAuthCallbackUrl({\n currentUrl: options.currentUrl,\n localOAuthCallbackUrl: options.localOAuthCallbackUrl,\n state: options.crossDomainHandoffParams?.state,\n codeChallenge: options.crossDomainHandoffParams?.codeChallenge,\n afterCallbackRedirectUrl,\n });\n\n nextUrl.searchParams.set(\"after_auth_return_to\", callbackUrl.toString());\n setCrossDomainParam(nextUrl.searchParams, \"afterCallbackRedirectUrl\", afterCallbackRedirectUrl);\n if (options.crossDomainHandoffParams != null) {\n setCrossDomainParam(nextUrl.searchParams, \"state\", options.crossDomainHandoffParams.state);\n setCrossDomainParam(nextUrl.searchParams, \"codeChallenge\", options.crossDomainHandoffParams.codeChallenge);\n }\n }\n } else if (options.currentUrl.protocol === nextUrl.protocol && options.currentUrl.host === nextUrl.host && !nextUrl.searchParams.has(\"after_auth_return_to\")) {\n nextUrl.searchParams.set(\"after_auth_return_to\", getRelativePart(options.currentUrl));\n }\n\n return nextUrl.origin === options.currentUrl.origin ? getRelativePart(nextUrl) : nextUrl.toString();\n}\n\nfunction getHandlerRedirectPolicy(handlerName: keyof HandlerUrls): HandlerRedirectPolicy {\n if (handlerName === \"afterSignIn\" || handlerName === \"afterSignUp\") {\n return \"after-auth-return\";\n }\n if (isRedirectBackAwareHandlerName(handlerName)) {\n return \"redirect-back-aware\";\n }\n return \"none\";\n}\n\ntype RedirectToHandlerPlan =\n | { type: \"redirect\", url: string }\n | {\n type: \"cross-domain-authorize\",\n redirectUri: string,\n state: string,\n codeChallenge: string,\n afterCallbackRedirectUrl: string,\n };\n\n\nasync function resolveRedirectBackAwareHandlerUrlForRedirect(options: {\n handlerName: RedirectBackAwareHandlerName,\n rawHandlerUrl: string,\n currentUrl: URL,\n localOAuthCallbackUrl: string,\n getCrossDomainHandoffParams: (currentUrl: URL) => Promise<CrossDomainHandoffParams>,\n}): Promise<string> {\n const initial = buildRedirectBackAwareHandlerUrl({\n handlerName: options.handlerName,\n rawHandlerUrl: options.rawHandlerUrl,\n currentUrl: options.currentUrl,\n crossDomainHandoffParams: null,\n localOAuthCallbackUrl: options.localOAuthCallbackUrl,\n });\n if (options.handlerName === \"signOut\") {\n return initial;\n }\n\n const initialTarget = new URL(initial, options.currentUrl);\n const isCrossDomainHandlerRedirect = options.currentUrl.origin !== initialTarget.origin;\n if (!isCrossDomainHandlerRedirect || hasCrossDomainHandoffParams(initialTarget)) {\n return initial;\n }\n\n const crossDomainHandoffParams = await options.getCrossDomainHandoffParams(options.currentUrl);\n return buildRedirectBackAwareHandlerUrl({\n handlerName: options.handlerName,\n rawHandlerUrl: options.rawHandlerUrl,\n currentUrl: options.currentUrl,\n crossDomainHandoffParams,\n localOAuthCallbackUrl: options.localOAuthCallbackUrl,\n });\n}\n\nexport async function planRedirectToHandler(options: {\n handlerName: keyof HandlerUrls,\n rawHandlerUrl: string,\n noRedirectBack: boolean,\n currentUrl: URL | null,\n localOAuthCallbackUrl: string,\n getCrossDomainHandoffParams: (currentUrl: URL) => Promise<CrossDomainHandoffParams>,\n}): Promise<RedirectToHandlerPlan> {\n if (options.noRedirectBack || options.currentUrl == null) {\n return { type: \"redirect\", url: options.rawHandlerUrl };\n }\n\n const policy = getHandlerRedirectPolicy(options.handlerName);\n if (policy === \"none\") {\n return { type: \"redirect\", url: options.rawHandlerUrl };\n }\n\n if (policy === \"after-auth-return\") {\n const redirectBackUrl = options.currentUrl.searchParams.get(\"after_auth_return_to\");\n if (redirectBackUrl == null) {\n return { type: \"redirect\", url: options.rawHandlerUrl };\n }\n const redirectBackTarget = new URL(redirectBackUrl, options.currentUrl);\n const crossDomainHandoff = getCrossDomainHandoffForRedirect({\n currentUrl: options.currentUrl,\n redirectBackTarget,\n });\n if (crossDomainHandoff == null) {\n return { type: \"redirect\", url: redirectBackUrl };\n }\n let state = crossDomainHandoff.handoffParams.state;\n let codeChallenge = crossDomainHandoff.handoffParams.codeChallenge;\n let afterCallbackRedirectUrl = crossDomainHandoff.handoffParams.afterCallbackRedirectUrl;\n if (state == null || codeChallenge == null) {\n const generatedHandoffParams = await options.getCrossDomainHandoffParams(options.currentUrl);\n state ??= generatedHandoffParams.state;\n codeChallenge ??= generatedHandoffParams.codeChallenge;\n }\n afterCallbackRedirectUrl ??= options.currentUrl.toString();\n return {\n type: \"cross-domain-authorize\",\n redirectUri: crossDomainHandoff.redirectBackTarget.toString(),\n state,\n codeChallenge,\n afterCallbackRedirectUrl,\n };\n }\n\n if (\n options.handlerName !== \"signIn\"\n && options.handlerName !== \"signUp\"\n && options.handlerName !== \"onboarding\"\n && options.handlerName !== \"signOut\"\n ) {\n throw new HexclaveAssertionError(\"Unexpected redirect-back-aware handler policy mismatch\", {\n handlerName: options.handlerName,\n policy,\n });\n }\n\n return {\n type: \"redirect\",\n url: await resolveRedirectBackAwareHandlerUrlForRedirect({\n handlerName: options.handlerName,\n rawHandlerUrl: options.rawHandlerUrl,\n currentUrl: options.currentUrl,\n localOAuthCallbackUrl: options.localOAuthCallbackUrl,\n getCrossDomainHandoffParams: options.getCrossDomainHandoffParams,\n }),\n };\n}\n\nfunction readCrossDomainHandoffParams(currentUrl: URL, redirectBackTarget: URL): CrossDomainHandoffParamsMaybeMissing {\n // Hexclave rebrand: accept either param name from both URLs.\n const state = getCrossDomainParam(currentUrl.searchParams, \"state\")\n ?? getCrossDomainParam(redirectBackTarget.searchParams, \"state\");\n const codeChallenge = getCrossDomainParam(currentUrl.searchParams, \"codeChallenge\")\n ?? getCrossDomainParam(redirectBackTarget.searchParams, \"codeChallenge\");\n const afterCallbackRedirectUrl = getCrossDomainParam(currentUrl.searchParams, \"afterCallbackRedirectUrl\")\n ?? getCrossDomainParam(redirectBackTarget.searchParams, \"afterCallbackRedirectUrl\");\n return {\n state,\n codeChallenge,\n afterCallbackRedirectUrl,\n };\n}\n\nfunction resolveCrossDomainRedirectBackTarget(options: {\n currentUrl: URL,\n redirectBackTarget: URL,\n handoffParams: CrossDomainHandoffParamsMaybeMissing,\n}): URL | null {\n if (options.redirectBackTarget.origin !== options.currentUrl.origin) {\n return options.redirectBackTarget;\n }\n if (\n options.handoffParams.state == null\n || options.handoffParams.codeChallenge == null\n || options.handoffParams.afterCallbackRedirectUrl == null\n ) {\n return null;\n }\n const afterCallbackRedirectTarget = new URL(options.handoffParams.afterCallbackRedirectUrl, options.currentUrl);\n if (afterCallbackRedirectTarget.origin === options.currentUrl.origin) {\n return null;\n }\n return new URL(\n `${options.redirectBackTarget.pathname}${options.redirectBackTarget.search}${options.redirectBackTarget.hash}`,\n afterCallbackRedirectTarget.origin,\n );\n}\n\nfunction getCrossDomainHandoffForRedirect(options: {\n currentUrl: URL,\n redirectBackTarget: URL,\n}): {\n redirectBackTarget: URL,\n handoffParams: CrossDomainHandoffParamsMaybeMissing,\n} | null {\n const handoffParams = readCrossDomainHandoffParams(options.currentUrl, options.redirectBackTarget);\n const crossDomainRedirectBackTarget = resolveCrossDomainRedirectBackTarget({\n currentUrl: options.currentUrl,\n redirectBackTarget: options.redirectBackTarget,\n handoffParams,\n });\n if (crossDomainRedirectBackTarget == null) {\n return null;\n }\n return {\n redirectBackTarget: crossDomainRedirectBackTarget,\n handoffParams,\n };\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"server-app-impl.js","names":[],"sources":["../../../../../../src/lib/stack-app/apps/implementations/server-app-impl.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { WebAuthnError, startRegistration } from \"@simplewebauthn/browser\";\nimport { KnownErrors, HexclaveServerInterface } from \"@hexclave/shared\";\nimport { ContactChannelsCrud } from \"@hexclave/shared/dist/interface/crud/contact-channels\";\nimport { ItemCrud } from \"@hexclave/shared/dist/interface/crud/items\";\nimport { NotificationPreferenceCrud } from \"@hexclave/shared/dist/interface/crud/notification-preferences\";\nimport { OAuthProviderCrud } from \"@hexclave/shared/dist/interface/crud/oauth-providers\";\nimport type { CustomerProductsListResponse } from \"@hexclave/shared/dist/interface/crud/products\";\nimport { TeamApiKeysCrud, UserApiKeysCrud, teamApiKeysCreateOutputSchema, userApiKeysCreateOutputSchema } from \"@hexclave/shared/dist/interface/crud/project-api-keys\";\nimport { ProjectPermissionDefinitionsCrud, ProjectPermissionsCrud } from \"@hexclave/shared/dist/interface/crud/project-permissions\";\nimport { TeamInvitationCrud } from \"@hexclave/shared/dist/interface/crud/team-invitation\";\nimport { TeamMemberProfilesCrud } from \"@hexclave/shared/dist/interface/crud/team-member-profiles\";\nimport { TeamPermissionDefinitionsCrud, TeamPermissionsCrud } from \"@hexclave/shared/dist/interface/crud/team-permissions\";\nimport { TeamsCrud } from \"@hexclave/shared/dist/interface/crud/teams\";\nimport { UsersCrud } from \"@hexclave/shared/dist/interface/crud/users\";\nimport { InternalSession } from \"@hexclave/shared/dist/sessions\";\nimport type { AsyncCache } from \"@hexclave/shared/dist/utils/caches\";\nimport { HexclaveAssertionError, captureError, throwErr } from \"@hexclave/shared/dist/utils/errors\";\nimport { ProviderType } from \"@hexclave/shared/dist/utils/oauth\";\nimport { runAsynchronously } from \"@hexclave/shared/dist/utils/promises\";\nimport { suspend } from \"@hexclave/shared/dist/utils/react\";\nimport { Result } from \"@hexclave/shared/dist/utils/results\";\nimport * as yup from \"yup\";\nimport { constructRedirectUrl } from \"../../../../utils/url\";\nimport { ApiKey, ApiKeyCreationOptions, ApiKeyUpdateOptions, apiKeyCreationOptionsToCrud, apiKeyUpdateOptionsToCrud } from \"../../api-keys\";\nimport { ConvexCtx, GetCurrentUserOptions } from \"../../common\";\nimport { DeprecatedOAuthConnection, OAuthConnection } from \"../../connected-accounts\";\nimport { ServerContactChannel, ServerContactChannelCreateOptions, ServerContactChannelUpdateOptions, serverContactChannelCreateOptionsToCrud, serverContactChannelUpdateOptionsToCrud } from \"../../contact-channels\";\nimport { Customer, CustomerProductsList, CustomerProductsRequestOptions, InlineProduct, ServerItem } from \"../../customers\";\nimport { DataVaultStore } from \"../../data-vault\";\nimport { EmailDeliveryInfo, SendEmailOptions } from \"../../email\";\nimport { NotificationCategory } from \"../../notification-categories\";\nimport { AdminProjectPermissionDefinition, AdminTeamPermission, AdminTeamPermissionDefinition } from \"../../permissions\";\nimport { EditableTeamMemberProfile, ReceivedTeamInvitation, SentTeamInvitation, ServerListTeamsOptions, ServerListUsersOptions, ServerTeam, ServerTeamCreateOptions, ServerTeamUpdateOptions, ServerTeamUser, Team, serverTeamCreateOptionsToCrud, serverTeamUpdateOptionsToCrud } from \"../../teams\";\nimport { ProjectCurrentServerUser, ServerOAuthProvider, ServerUser, ServerUserCreateOptions, ServerUserUpdateOptions, serverUserCreateOptionsToCrud, serverUserUpdateOptionsToCrud, withUserDestructureGuard } from \"../../users\";\nimport { StackServerAppConstructorOptions } from \"../interfaces/server-app\";\nimport { _StackClientAppImplIncomplete } from \"./client-app-impl\";\nimport { clientVersion, createCache, createCacheBySession, getDefaultExtraRequestHeaders, getDefaultProjectId, getDefaultPublishableClientKey, getDefaultSecretServerKey, resolveApiUrls, resolveConstructorOptions } from \"./common\";\n\n\nexport class _StackServerAppImplIncomplete<HasTokenStore extends boolean, ProjectId extends string> extends _StackClientAppImplIncomplete<HasTokenStore, ProjectId> {\n declare protected _interface: HexclaveServerInterface;\n\n // TODO override the client user cache to use the server user cache, so we save some requests\n private readonly _currentServerUserCache = createCacheBySession(async (session) => {\n if (session.isKnownToBeInvalid()) {\n // see comment in _currentUserCache for more details on why we do this\n return null;\n }\n return await this._interface.getServerUserByToken(session);\n });\n private readonly _serverUsersCache = createCache<[\n cursor?: string,\n limit?: number,\n orderBy?: 'signedUpAt' | 'lastActiveAt',\n desc?: boolean,\n query?: string,\n includeRestricted?: boolean,\n includeAnonymous?: boolean,\n onlyAnonymous?: boolean,\n teamId?: string,\n ], UsersCrud['Server']['List']>(async ([cursor, limit, orderBy, desc, query, includeRestricted, includeAnonymous, onlyAnonymous, teamId]) => {\n if (onlyAnonymous && !includeAnonymous) {\n throw new HexclaveAssertionError(\"onlyAnonymous=true requires includeAnonymous=true\");\n }\n if (onlyAnonymous) {\n return await this._interface.listServerUsers({ cursor, limit, orderBy, desc, query, includeRestricted, includeAnonymous: true, onlyAnonymous: true, teamId });\n }\n return await this._interface.listServerUsers({ cursor, limit, orderBy, desc, query, includeRestricted, includeAnonymous, teamId });\n });\n private readonly _serverUserCache = createCache<string[], UsersCrud['Server']['Read'] | null>(async ([userId]) => {\n const user = await this._interface.getServerUserById(userId);\n return Result.or(user, null);\n });\n private readonly _serverTeamsCache = createCache<[\n userId?: string,\n orderBy?: 'createdAt',\n desc?: boolean,\n cursor?: string,\n limit?: number,\n query?: string,\n ], TeamsCrud['Server']['List']>(async ([userId, orderBy, desc, cursor, limit, query]) => {\n return await this._interface.listServerTeamsPaginated({ userId, orderBy, desc, cursor, limit, query });\n });\n\n protected async _refreshTeamMembership(teamId: string, userId: string) {\n await Promise.all([\n this._serverTeamMemberProfilesCache.refresh([teamId]),\n this._serverTeamsCache.refreshWhere(([u]) => u === userId || u === undefined),\n this._serverUsersCache.refreshWhere((key) => key[8] === teamId),\n ]);\n }\n private readonly _serverUserTeamInvitationsCache = createCache<string[], TeamInvitationCrud['Client']['Read'][]>(async ([userId]) => {\n return await this._interface.listServerUserTeamInvitations(userId);\n });\n private readonly _serverTeamUserPermissionsCache = createCache<\n [string, string, boolean],\n TeamPermissionsCrud['Server']['Read'][]\n >(async ([teamId, userId, recursive]) => {\n return await this._interface.listServerTeamPermissions({ teamId, userId, recursive }, null);\n });\n // Bulk variant: one request returning permissions for every member of a\n // team. Used by the dashboard's team-member table to avoid N per-row\n // calls. Keyed without userId so it's a distinct cache entry from the\n // per-user lookup above.\n private readonly _serverAllTeamMemberPermissionsCache = createCache<\n [string, boolean],\n TeamPermissionsCrud['Server']['Read'][]\n >(async ([teamId, recursive]) => {\n return await this._interface.listServerTeamPermissions({ teamId, recursive }, null);\n });\n private readonly _serverUserProjectPermissionsCache = createCache<\n [string, boolean],\n ProjectPermissionsCrud['Server']['Read'][]\n >(async ([userId, recursive]) => {\n return await this._interface.listServerProjectPermissions({ userId, recursive }, null);\n });\n /** @deprecated Used by legacy getConnectedAccount(providerId) — uses old per-provider access token endpoint */\n private readonly _serverUserOAuthConnectionAccessTokensCache = createCache<[string, string, string], { accessToken: string } | null>(\n async ([userId, providerId, scope]) => {\n try {\n const result = await this._interface.createServerProviderAccessToken(userId, providerId, scope || \"\");\n return { accessToken: result.access_token };\n } catch (err) {\n if (!(KnownErrors.OAuthAccessTokenNotAvailable.isInstance(err) || KnownErrors.OAuthConnectionDoesNotHaveRequiredScope.isInstance(err) || KnownErrors.OAuthConnectionNotConnectedToUser.isInstance(err))) {\n throw err;\n }\n }\n return null;\n }\n );\n /** @deprecated Used by legacy getConnectedAccount(providerId) — combines token check + redirect */\n private readonly _serverUserOAuthConnectionCache = createCache<[string, ProviderType, string, boolean], DeprecatedOAuthConnection | null>(\n async ([userId, providerId, scope, redirect]) => {\n return await this._getUserOAuthConnectionCacheFn({\n getUser: async () => Result.orThrow(await this._serverUserCache.getOrWait([userId], \"write-only\")),\n getOrWaitOAuthToken: async () => Result.orThrow(await this._serverUserOAuthConnectionAccessTokensCache.getOrWait([userId, providerId, scope || \"\"] as const, \"write-only\")),\n providerId,\n scope,\n redirect,\n session: null,\n });\n }\n );\n private readonly _serverUserConnectedAccountsCache = createCache<[string], OAuthConnection[]>(\n async ([userId]) => {\n const result = await this._interface.listServerConnectedAccounts(userId);\n return result.items.map((item) => this._createServerOAuthConnectionFromCrudItem(userId, item));\n }\n );\n private readonly _serverUserOAuthConnectionAccessTokensByAccountCache = createCache<[string, string, string, string], { accessToken: string } | null>(\n async ([userId, providerId, providerAccountId, scope]) => {\n try {\n const result = await this._interface.createServerProviderAccessTokenByAccount(userId, providerId, providerAccountId, scope || \"\");\n return { accessToken: result.access_token };\n } catch (err) {\n if (!(KnownErrors.OAuthAccessTokenNotAvailable.isInstance(err) || KnownErrors.OAuthConnectionDoesNotHaveRequiredScope.isInstance(err) || KnownErrors.OAuthConnectionNotConnectedToUser.isInstance(err))) {\n throw err;\n }\n }\n return null;\n }\n );\n private readonly _serverTeamMemberProfilesCache = createCache<[string], TeamMemberProfilesCrud['Server']['Read'][]>(\n async ([teamId]) => {\n return await this._interface.listServerTeamMemberProfiles({ teamId });\n }\n );\n private readonly _serverTeamInvitationsCache = createCache<[string], TeamInvitationCrud['Server']['Read'][]>(\n async ([teamId]) => {\n return await this._interface.listServerTeamInvitations({ teamId });\n }\n );\n private readonly _serverUserTeamProfileCache = createCache<[string, string], TeamMemberProfilesCrud['Client']['Read']>(\n async ([teamId, userId]) => {\n return await this._interface.getServerTeamMemberProfile({ teamId, userId });\n }\n );\n private readonly _serverContactChannelsCache = createCache<[string], ContactChannelsCrud['Server']['Read'][]>(\n async ([userId]) => {\n return await this._interface.listServerContactChannels(userId);\n }\n );\n private readonly _serverNotificationCategoriesCache = createCache<[string], NotificationPreferenceCrud['Server']['Read'][]>(\n async ([userId]) => {\n return await this._interface.listServerNotificationCategories(userId);\n }\n );\n private readonly _serverDataVaultStoreValueCache = createCache<[string, string, string], string | null>(async ([storeId, key, secret]) => {\n return await this._interface.getDataVaultStoreValue(secret, storeId, key);\n });\n\n private readonly _emailDeliveryInfoCache = createCache(async () => {\n return await this._interface.getEmailDeliveryInfo();\n });\n\n private readonly _serverUserApiKeysCache = createCache<[string], UserApiKeysCrud['Server']['Read'][]>(\n async ([userId]) => {\n const result = await this._interface.listProjectApiKeys({\n user_id: userId,\n }, null, \"server\");\n return result as UserApiKeysCrud['Server']['Read'][];\n }\n );\n\n private readonly _serverTeamApiKeysCache = createCache<[string], TeamApiKeysCrud['Server']['Read'][]>(\n async ([teamId]) => {\n const result = await this._interface.listProjectApiKeys({\n team_id: teamId,\n }, null, \"server\");\n return result as TeamApiKeysCrud['Server']['Read'][];\n }\n );\n\n private readonly _convexIdentitySubjectCache = createCache<[ConvexCtx], string | null>(\n async ([ctx]) => {\n const identity = await ctx.auth.getUserIdentity();\n return identity ? identity.subject : null;\n }\n );\n\n private readonly _serverCheckApiKeyCache = createCache<[\"user\" | \"team\", string], UserApiKeysCrud['Server']['Read'] | TeamApiKeysCrud['Server']['Read'] | null>(async ([type, apiKey]) => {\n const result = await this._interface.checkProjectApiKey(\n type,\n apiKey,\n null,\n \"server\",\n );\n return result;\n });\n\n private readonly _serverOAuthProvidersCache = createCache<[string], OAuthProviderCrud['Server']['Read'][]>(\n async ([userId]) => {\n return await this._interface.listServerOAuthProviders({ user_id: userId });\n }\n );\n\n private readonly _serverTeamItemsCache = createCache<[string, string], ItemCrud['Client']['Read']>(\n async ([teamId, itemId]) => {\n return await this._interface.getItem({ teamId, itemId }, null, \"server\");\n }\n );\n\n private readonly _serverUserItemsCache = createCache<[string, string], ItemCrud['Client']['Read']>(\n async ([userId, itemId]) => {\n return await this._interface.getItem({ userId, itemId }, null, \"server\");\n }\n );\n\n private readonly _serverCustomItemsCache = createCache<[string, string], ItemCrud['Client']['Read']>(\n async ([customCustomerId, itemId]) => {\n return await this._interface.getItem({ customCustomerId, itemId }, null, \"server\");\n }\n );\n\n private readonly _serverUserProductsCache = createCache<[string, string | null, number | null], CustomerProductsListResponse>(\n async ([userId, cursor, limit]) => {\n return await this._interface.listProducts({\n customer_type: \"user\",\n customer_id: userId,\n cursor: cursor ?? undefined,\n limit: limit ?? undefined,\n }, null, \"server\");\n }\n );\n\n private readonly _serverTeamProductsCache = createCache<[string, string | null, number | null], CustomerProductsListResponse>(\n async ([teamId, cursor, limit]) => {\n return await this._interface.listProducts({\n customer_type: \"team\",\n customer_id: teamId,\n cursor: cursor ?? undefined,\n limit: limit ?? undefined,\n }, null, \"server\");\n }\n );\n\n private readonly _serverCustomProductsCache = createCache<[string, string | null, number | null], CustomerProductsListResponse>(\n async ([customCustomerId, cursor, limit]) => {\n return await this._interface.listProducts({\n customer_type: \"custom\",\n customer_id: customCustomerId,\n cursor: cursor ?? undefined,\n limit: limit ?? undefined,\n }, null, \"server\");\n }\n );\n\n protected _createServerCustomer(userIdOrTeamId: string, type: \"user\" | \"team\"): Omit<Customer<true>, \"id\"> {\n const app = this;\n const productsCache = type === \"user\" ? app._serverUserProductsCache : app._serverTeamProductsCache;\n const customerOptions = type === \"user\" ? { userId: userIdOrTeamId } : { teamId: userIdOrTeamId };\n return {\n ...this._createCustomer(userIdOrTeamId, type, null),\n async getItem(itemId: string) {\n return await app.getItem({ itemId, ...customerOptions });\n },\n async grantProduct(productOptions: { productId: string, quantity?: number } | { product: InlineProduct, quantity?: number }) {\n if (type === \"user\") {\n if (\"productId\" in productOptions) {\n await app.grantProduct({ userId: userIdOrTeamId, productId: productOptions.productId, quantity: productOptions.quantity });\n } else {\n await app.grantProduct({ userId: userIdOrTeamId, product: productOptions.product, quantity: productOptions.quantity });\n }\n } else {\n if (\"productId\" in productOptions) {\n await app.grantProduct({ teamId: userIdOrTeamId, productId: productOptions.productId, quantity: productOptions.quantity });\n } else {\n await app.grantProduct({ teamId: userIdOrTeamId, product: productOptions.product, quantity: productOptions.quantity });\n }\n }\n await productsCache.refresh([userIdOrTeamId, null, null]);\n },\n async createCheckoutUrl(options: { productId: string, returnUrl?: string } | { product: InlineProduct, returnUrl?: string }) {\n const productIdOrInline = \"productId\" in options ? options.productId : options.product;\n return await app._interface.createCheckoutUrl(type, userIdOrTeamId, productIdOrInline, null, options.returnUrl, \"server\");\n },\n };\n }\n\n private async _updateServerUser(userId: string, update: ServerUserUpdateOptions): Promise<UsersCrud['Server']['Read']> {\n const result = await this._interface.updateServerUser(userId, serverUserUpdateOptionsToCrud(update));\n await this._refreshUsers();\n return result;\n }\n\n protected _serverEditableTeamProfileFromCrud(crud: TeamMemberProfilesCrud['Client']['Read']): EditableTeamMemberProfile {\n const app = this;\n return {\n displayName: crud.display_name,\n profileImageUrl: crud.profile_image_url,\n async update(update: { displayName?: string, profileImageUrl?: string }) {\n await app._interface.updateServerTeamMemberProfile({\n teamId: crud.team_id,\n userId: crud.user_id,\n profile: {\n display_name: update.displayName,\n profile_image_url: update.profileImageUrl,\n },\n });\n await app._serverUserTeamProfileCache.refresh([crud.team_id, crud.user_id]);\n }\n };\n }\n\n protected _serverContactChannelFromCrud(userId: string, crud: ContactChannelsCrud['Server']['Read']): ServerContactChannel {\n const app = this;\n return {\n id: crud.id,\n value: crud.value,\n type: crud.type,\n isVerified: crud.is_verified,\n isPrimary: crud.is_primary,\n usedForAuth: crud.used_for_auth,\n async sendVerificationEmail(options?: { callbackUrl?: string }) {\n await app._interface.sendServerContactChannelVerificationEmail(userId, crud.id, options?.callbackUrl ?? constructRedirectUrl(app.urls.emailVerification, \"callbackUrl\"));\n },\n async update(data: ServerContactChannelUpdateOptions) {\n await app._interface.updateServerContactChannel(userId, crud.id, serverContactChannelUpdateOptionsToCrud(data));\n await Promise.all([\n app._serverContactChannelsCache.refresh([userId]),\n app._serverUserCache.refresh([userId])\n ]);\n },\n async delete() {\n await app._interface.deleteServerContactChannel(userId, crud.id);\n await Promise.all([\n app._serverContactChannelsCache.refresh([userId]),\n app._serverUserCache.refresh([userId])\n ]);\n },\n };\n }\n\n protected _serverNotificationCategoryFromCrud(userId: string, crud: NotificationPreferenceCrud['Server']['Read']): NotificationCategory {\n const app = this;\n return {\n id: crud.notification_category_id,\n name: crud.notification_category_name,\n enabled: crud.enabled,\n canDisable: crud.can_disable,\n\n async setEnabled(enabled: boolean) {\n await app._interface.setServerNotificationsEnabled(userId, crud.notification_category_id, enabled);\n await app._serverNotificationCategoriesCache.refresh([userId]);\n },\n };\n }\n\n protected _serverOAuthProviderFromCrud(crud: OAuthProviderCrud['Server']['Read']) {\n const app = this;\n return {\n id: crud.id,\n type: crud.type,\n userId: crud.user_id,\n accountId: crud.account_id,\n email: crud.email,\n allowSignIn: crud.allow_sign_in,\n allowConnectedAccounts: crud.allow_connected_accounts,\n\n async update(data: { accountId?: string, email?: string, allowSignIn?: boolean, allowConnectedAccounts?: boolean }): Promise<Result<void,\n InstanceType<typeof KnownErrors.OAuthProviderAccountIdAlreadyUsedForSignIn>\n >> {\n try {\n await app._interface.updateServerOAuthProvider(crud.user_id, crud.id, {\n account_id: data.accountId,\n email: data.email,\n allow_sign_in: data.allowSignIn,\n allow_connected_accounts: data.allowConnectedAccounts,\n });\n await Promise.all([\n app._serverOAuthProvidersCache.refresh([crud.user_id]),\n app._serverUserConnectedAccountsCache.refresh([crud.user_id]),\n ]);\n return Result.ok(undefined);\n } catch (error) {\n if (KnownErrors.OAuthProviderAccountIdAlreadyUsedForSignIn.isInstance(error)) {\n return Result.error(error);\n }\n throw error;\n }\n },\n\n async delete() {\n await app._interface.deleteServerOAuthProvider(crud.user_id, crud.id);\n await Promise.all([\n app._serverOAuthProvidersCache.refresh([crud.user_id]),\n app._serverUserConnectedAccountsCache.refresh([crud.user_id]),\n ]);\n },\n };\n }\n\n constructor(options: StackServerAppConstructorOptions<HasTokenStore, ProjectId>, extraOptions?: { uniqueIdentifier?: string, checkString?: string, interface?: HexclaveServerInterface }) {\n const resolvedOptions = resolveConstructorOptions(options);\n\n const publishableClientKey = resolvedOptions.publishableClientKey ?? getDefaultPublishableClientKey();\n\n super(resolvedOptions, {\n ...extraOptions,\n interface: extraOptions?.interface ?? (() => {\n const apiUrls = resolveApiUrls(resolvedOptions.baseUrl);\n return new HexclaveServerInterface({\n getBaseUrl: () => apiUrls()[0],\n getApiUrls: apiUrls,\n projectId: resolvedOptions.projectId ?? getDefaultProjectId(),\n extraRequestHeaders: resolvedOptions.extraRequestHeaders ?? getDefaultExtraRequestHeaders(),\n clientVersion,\n ...(publishableClientKey != null ? { publishableClientKey } : {}),\n secretServerKey: resolvedOptions.secretServerKey ?? getDefaultSecretServerKey(),\n });\n })(),\n });\n }\n\n\n protected _serverApiKeyFromCrud(crud: TeamApiKeysCrud['Client']['Read']): ApiKey<\"team\">;\n protected _serverApiKeyFromCrud(crud: UserApiKeysCrud['Client']['Read']): ApiKey<\"user\">;\n protected _serverApiKeyFromCrud(crud: yup.InferType<typeof teamApiKeysCreateOutputSchema>): ApiKey<\"team\", true>;\n protected _serverApiKeyFromCrud(crud: yup.InferType<typeof userApiKeysCreateOutputSchema>): ApiKey<\"user\", true>;\n protected _serverApiKeyFromCrud(crud: TeamApiKeysCrud['Client']['Read'] | UserApiKeysCrud['Client']['Read'] | yup.InferType<typeof teamApiKeysCreateOutputSchema> | yup.InferType<typeof userApiKeysCreateOutputSchema>): ApiKey<\"user\" | \"team\", boolean> {\n return {\n ...this._baseApiKeyFromCrud(crud),\n async revoke() {\n await this.update({ revoked: true });\n },\n update: async (options: ApiKeyUpdateOptions) => {\n await this._interface.updateProjectApiKey(\n crud.type === \"team\" ? { team_id: crud.team_id } : { user_id: crud.user_id },\n crud.id,\n await apiKeyUpdateOptionsToCrud(crud.type, options),\n null,\n \"server\");\n if (crud.type === \"team\") {\n await this._serverTeamApiKeysCache.refresh([crud.team_id]);\n } else {\n await this._serverUserApiKeysCache.refresh([crud.user_id]);\n }\n },\n };\n }\n\n protected _createServerOAuthConnectionFromCrudItem(\n userId: string,\n item: { provider: string, provider_account_id: string },\n ): OAuthConnection {\n const app = this;\n const providerId = item.provider;\n const providerAccountId = item.provider_account_id;\n return {\n id: providerId, // deprecated, for backward compat\n provider: providerId,\n providerAccountId,\n async getAccessToken(options?: { scopes?: string[] }) {\n const scopeString = options?.scopes?.join(\" \") ?? \"\";\n const result = Result.orThrow(await app._serverUserOAuthConnectionAccessTokensByAccountCache.getOrWait([userId, providerId, providerAccountId, scopeString], \"write-only\"));\n if (!result) {\n const scopeDetail = scopeString ? `The requested scopes [${scopeString}] are not available on the existing token.` : \"The OAuth refresh token has likely been revoked or expired.\";\n return Result.error(new KnownErrors.OAuthAccessTokenNotAvailable(providerId, `${scopeDetail} The user needs to re-authorize by calling \\`linkConnectedAccount\\` or using \\`getOrLinkConnectedAccount\\`.`));\n }\n return Result.ok(result);\n },\n };\n }\n\n protected _serverUserFromCrud(crud: UsersCrud['Server']['Read']): ServerUser {\n const app = this;\n\n /** @deprecated The string-based overloads are deprecated. Use `getConnectedAccount({ provider, providerAccountId })` for existence check. */\n async function getConnectedAccount(id: ProviderType, options?: { scopes?: string[] }): Promise<DeprecatedOAuthConnection | null>;\n async function getConnectedAccount(id: ProviderType, options: { or: 'redirect', scopes?: string[] }): Promise<DeprecatedOAuthConnection>;\n async function getConnectedAccount(account: { provider: string, providerAccountId: string }): Promise<OAuthConnection | null>;\n async function getConnectedAccount(\n idOrAccount: ProviderType | { provider: string, providerAccountId: string },\n options?: { or?: 'redirect', scopes?: string[] }\n ): Promise<DeprecatedOAuthConnection | OAuthConnection | null> {\n const scopeString = options?.scopes?.join(\" \") ?? \"\";\n\n // Check if it's the new object-based API\n if (typeof idOrAccount === 'object' && 'provider' in idOrAccount && 'providerAccountId' in idOrAccount) {\n const { provider, providerAccountId } = idOrAccount;\n // Check if the account exists in the connected accounts list\n const connectedAccounts = Result.orThrow(await app._serverUserConnectedAccountsCache.getOrWait([crud.id], \"write-only\"));\n const found = connectedAccounts.find(\n a => a.provider === provider && a.providerAccountId === providerAccountId\n );\n if (!found) {\n return null;\n }\n return found;\n }\n\n // Original behavior: by provider ID (returns first match)\n return Result.orThrow(await app._serverUserOAuthConnectionCache.getOrWait([crud.id, idOrAccount, scopeString, options?.or === 'redirect'], \"write-only\"));\n }\n\n\n // Type assertion needed because the new restricted_by_admin fields may not be reflected in TypeScript types yet\n // after schema changes - the runtime values are present after the schema is updated\n const crudWithAdminRestriction = crud as typeof crud & {\n restricted_by_admin: boolean,\n restricted_by_admin_reason: string | null,\n restricted_by_admin_private_details: string | null,\n };\n const serverUser = withUserDestructureGuard({\n ...super._createBaseUser(crud),\n lastActiveAt: new Date(crud.last_active_at_millis),\n serverMetadata: crud.server_metadata,\n restrictedByAdmin: crudWithAdminRestriction.restricted_by_admin,\n restrictedByAdminReason: crudWithAdminRestriction.restricted_by_admin_reason,\n restrictedByAdminPrivateDetails: crudWithAdminRestriction.restricted_by_admin_private_details,\n countryCode: crud.country_code,\n riskScores: {\n signUp: {\n bot: crud.risk_scores.sign_up.bot,\n freeTrialAbuse: crud.risk_scores.sign_up.free_trial_abuse,\n },\n },\n async setPrimaryEmail(email: string | null, options?: { verified?: boolean }) {\n await app._updateServerUser(crud.id, { primaryEmail: email, primaryEmailVerified: options?.verified });\n },\n async grantPermission(scopeOrPermissionId: Team | string, permissionId?: string): Promise<void> {\n if (scopeOrPermissionId && typeof scopeOrPermissionId !== 'string' && permissionId) {\n const scope = scopeOrPermissionId;\n await app._interface.grantServerTeamUserPermission(scope.id, crud.id, permissionId);\n\n for (const recursive of [true, false]) {\n await app._serverTeamUserPermissionsCache.refresh([scope.id, crud.id, recursive]);\n await app._serverAllTeamMemberPermissionsCache.refresh([scope.id, recursive]);\n }\n } else {\n const pId = scopeOrPermissionId as string;\n await app._interface.grantServerProjectPermission(crud.id, pId);\n\n for (const recursive of [true, false]) {\n await app._serverUserProjectPermissionsCache.refresh([crud.id, recursive]);\n }\n }\n },\n async revokePermission(scopeOrPermissionId: Team | string, permissionId?: string): Promise<void> {\n if (scopeOrPermissionId && typeof scopeOrPermissionId !== 'string' && permissionId) {\n const scope = scopeOrPermissionId;\n await app._interface.revokeServerTeamUserPermission(scope.id, crud.id, permissionId);\n\n for (const recursive of [true, false]) {\n await app._serverTeamUserPermissionsCache.refresh([scope.id, crud.id, recursive]);\n await app._serverAllTeamMemberPermissionsCache.refresh([scope.id, recursive]);\n }\n } else {\n const pId = scopeOrPermissionId as string;\n await app._interface.revokeServerProjectPermission(crud.id, pId);\n\n for (const recursive of [true, false]) {\n await app._serverUserProjectPermissionsCache.refresh([crud.id, recursive]);\n }\n }\n },\n async delete() {\n const res = await app._interface.deleteServerUser(crud.id);\n await app._refreshUsers();\n return res;\n },\n async createSession(options: { expiresInMillis?: number, isImpersonation?: boolean }) {\n // TODO this should also refresh the access token when it expires (like InternalSession)\n const tokens = await app._interface.createServerUserSession(crud.id, options.expiresInMillis ?? 1000 * 60 * 60 * 24 * 365, options.isImpersonation ?? false);\n return {\n async getTokens() {\n return tokens;\n },\n };\n },\n\n async getActiveSessions() {\n const sessions = await app._interface.listServerSessions(crud.id);\n return sessions.items.map((session) => app._clientSessionFromCrud(session));\n },\n\n async revokeSession(sessionId: string) {\n await app._interface.deleteServerSession(sessionId);\n },\n async setDisplayName(displayName: string | null) {\n return await this.update({ displayName });\n },\n async setClientMetadata(metadata: Record<string, any>) {\n return await this.update({ clientMetadata: metadata });\n },\n async setClientReadOnlyMetadata(metadata: Record<string, any>) {\n return await this.update({ clientReadOnlyMetadata: metadata });\n },\n async setServerMetadata(metadata: Record<string, any>) {\n return await this.update({ serverMetadata: metadata });\n },\n async setSelectedTeam(team: Team | string | null) {\n return await this.update({ selectedTeamId: typeof team === 'string' ? team : team?.id ?? null });\n },\n getConnectedAccount,\n async listConnectedAccounts() {\n return Result.orThrow(await app._serverUserConnectedAccountsCache.getOrWait([crud.id], \"write-only\"));\n },\n async linkConnectedAccount(): Promise<void> {\n throw new HexclaveAssertionError(\"linkConnectedAccount is not available for server users. OAuth flows must be initiated on the client side.\");\n },\n async getOrLinkConnectedAccount(): Promise<OAuthConnection> {\n throw new HexclaveAssertionError(\"getOrLinkConnectedAccount is not available for server users. OAuth flows must be initiated on the client side.\");\n },\n selectedTeam: crud.selected_team ? app._serverTeamFromCrud(crud.selected_team) : null,\n async getTeam(teamId: string) {\n const teams = await this.listTeams();\n return teams.find((t) => t.id === teamId) ?? null;\n },\n async listTeams(options?: ServerListTeamsOptions): Promise<ServerTeam[] & { nextCursor: string | null }> {\n const result = Result.orThrow(await app._serverTeamsCache.getOrWait([crud.id, options?.orderBy, options?.desc, options?.cursor, options?.limit, options?.query] as const, \"write-only\"));\n const teams: any = result.items.map((t) => app._serverTeamFromCrud(t));\n teams.nextCursor = result.pagination?.next_cursor ?? null;\n return teams as any;\n },\n createTeam: async (data: Omit<ServerTeamCreateOptions, \"creatorUserId\">) => {\n const team = await app._interface.createServerTeam(serverTeamCreateOptionsToCrud({\n creatorUserId: crud.id,\n ...data,\n }));\n await app._serverTeamsCache.refreshWhere(() => true);\n await app._updateServerUser(crud.id, { selectedTeamId: team.id });\n return app._serverTeamFromCrud(team);\n },\n leaveTeam: async (team: Team) => {\n await app._interface.leaveServerTeam({ teamId: team.id, userId: crud.id });\n await app._refreshTeamMembership(team.id, crud.id);\n },\n async listTeamInvitations() {\n const invitations = Result.orThrow(await app._serverUserTeamInvitationsCache.getOrWait([crud.id], \"write-only\"));\n return invitations.map((inv) => app._serverReceivedTeamInvitationFromCrud(crud.id, inv));\n },\n async listPermissions(scopeOrOptions?: Team | { recursive?: boolean }, options?: { recursive?: boolean }): Promise<AdminTeamPermission[]> {\n if (scopeOrOptions && 'id' in scopeOrOptions) {\n const scope = scopeOrOptions;\n const recursive = options?.recursive ?? true;\n const permissions = Result.orThrow(await app._serverTeamUserPermissionsCache.getOrWait([scope.id, crud.id, recursive], \"write-only\"));\n return permissions.map((crud) => app._serverPermissionFromCrud(crud));\n } else {\n const opts = scopeOrOptions;\n const recursive = opts?.recursive ?? true;\n const permissions = Result.orThrow(await app._serverUserProjectPermissionsCache.getOrWait([crud.id, recursive], \"write-only\"));\n return permissions.map((crud) => app._serverPermissionFromCrud(crud));\n }\n },\n async getPermission(scopeOrPermissionId: Team | string, permissionId?: string): Promise<AdminTeamPermission | null> {\n if (scopeOrPermissionId && typeof scopeOrPermissionId !== 'string') {\n const scope = scopeOrPermissionId;\n const permissions = await this.listPermissions(scope);\n return permissions.find((p) => p.id === permissionId) ?? null;\n } else {\n const pid = scopeOrPermissionId;\n const permissions = await this.listPermissions();\n return permissions.find((p) => p.id === pid) ?? null;\n }\n },\n async hasPermission(scopeOrPermissionId: Team | string, permissionId?: string): Promise<boolean> {\n if (scopeOrPermissionId && typeof scopeOrPermissionId !== 'string') {\n const scope = scopeOrPermissionId;\n return (await this.getPermission(scope, permissionId as string)) !== null;\n } else {\n const pid = scopeOrPermissionId;\n return (await this.getPermission(pid)) !== null;\n }\n },\n async update(update: ServerUserUpdateOptions) {\n await app._updateServerUser(crud.id, update);\n },\n async sendVerificationEmail() {\n return await app._checkFeatureSupport(\"sendVerificationEmail() on ServerUser\", {});\n },\n async updatePassword(options: { oldPassword: string, newPassword: string }) {\n const result = await app._interface.updatePassword(options);\n await app._serverUserCache.refresh([crud.id]);\n return result;\n },\n async setPassword(options: { password: string }) {\n const result = await this.update(options);\n await app._serverUserCache.refresh([crud.id]);\n return result;\n },\n async getTeamProfile(team: Team) {\n const result = Result.orThrow(await app._serverUserTeamProfileCache.getOrWait([team.id, crud.id], \"write-only\"));\n return app._serverEditableTeamProfileFromCrud(result);\n },\n async listContactChannels() {\n const result = Result.orThrow(await app._serverContactChannelsCache.getOrWait([crud.id], \"write-only\"));\n return result.map((data) => app._serverContactChannelFromCrud(crud.id, data));\n },\n createContactChannel: async (data: ServerContactChannelCreateOptions) => {\n const contactChannel = await app._interface.createServerContactChannel(serverContactChannelCreateOptionsToCrud(crud.id, data));\n await Promise.all([\n app._serverContactChannelsCache.refresh([crud.id]),\n app._serverUserCache.refresh([crud.id])\n ]);\n return app._serverContactChannelFromCrud(crud.id, contactChannel);\n },\n async listNotificationCategories() {\n const results = Result.orThrow(await app._serverNotificationCategoriesCache.getOrWait([crud.id], \"write-only\"));\n return results.map((category) => app._serverNotificationCategoryFromCrud(crud.id, category));\n },\n async listApiKeys() {\n const result = Result.orThrow(await app._serverUserApiKeysCache.getOrWait([crud.id], \"write-only\"));\n return result.map((apiKey) => app._serverApiKeyFromCrud(apiKey));\n },\n async createApiKey(options: ApiKeyCreationOptions<\"user\">) {\n const result = await app._interface.createProjectApiKey(\n await apiKeyCreationOptionsToCrud(\"user\", crud.id, options),\n null,\n \"server\",\n );\n await app._serverUserApiKeysCache.refresh([crud.id]);\n return app._serverApiKeyFromCrud(result);\n },\n\n async listOAuthProviders() {\n const results = Result.orThrow(await app._serverOAuthProvidersCache.getOrWait([crud.id], \"write-only\"));\n return results.map((oauthCrud) => app._serverOAuthProviderFromCrud(oauthCrud));\n },\n\n async getOAuthProvider(id: string) {\n const providers = await this.listOAuthProviders();\n return providers.find((p) => p.id === id) ?? null;\n },\n async registerPasskey(options?: { hostname?: string }): Promise<Result<undefined, KnownErrors[\"PasskeyRegistrationFailed\"] | KnownErrors[\"PasskeyWebAuthnError\"]>> {\n // TODO remove duplicated code between this and the function in client-app-impl.ts\n const hostname = options?.hostname || (await app._getCurrentUrl())?.hostname;\n if (!hostname) {\n throw new HexclaveAssertionError(\"hostname must be provided if the Stack App does not have a redirect method\");\n }\n\n // Use server interface to initiate passkey registration for this specific user\n const initiationResult = await app._interface.initiateServerPasskeyRegistration(crud.id);\n\n if (initiationResult.status !== \"ok\") {\n return Result.error(new KnownErrors.PasskeyRegistrationFailed(\"Failed to get initiation options for passkey registration\"));\n }\n\n const { options_json, code } = initiationResult.data;\n\n // HACK: Override the rpID to be the actual domain\n if (options_json.rp.id !== \"THIS_VALUE_WILL_BE_REPLACED.example.com\") {\n throw new HexclaveAssertionError(`Expected returned RP ID from server to equal sentinel, but found ${options_json.rp.id}`);\n }\n\n options_json.rp.id = hostname;\n\n let attResp;\n try {\n attResp = await startRegistration({ optionsJSON: options_json });\n } catch (error: any) {\n if (error instanceof WebAuthnError) {\n return Result.error(new KnownErrors.PasskeyWebAuthnError(error.message, error.name));\n } else {\n // This should never happen\n captureError(\"passkey-registration-failed\", error);\n return Result.error(new KnownErrors.PasskeyRegistrationFailed(\"Failed to start passkey registration due to unknown error\"));\n }\n }\n\n // Create a temporary session to complete the registration\n // TODO instead of creating a new session, this should just call the endpoint in a way in which it doesn't require a session\n // (currently this shows up on session history etc... not ideal)\n const { accessToken, refreshToken } = await app._interface.createServerUserSession(crud.id, 60000 * 2, false);\n const tempSession = new InternalSession({\n accessToken,\n refreshToken,\n refreshAccessTokenCallback: async () => null,\n });\n\n const registrationResult = await app._interface.registerPasskey({ credential: attResp, code }, tempSession);\n\n await app._serverUserCache.refresh([crud.id]);\n return registrationResult;\n },\n ...app._createServerCustomer(crud.id, \"user\"),\n } satisfies ServerUser);\n\n return serverUser;\n }\n\n protected _serverTeamUserFromCrud(crud: TeamMemberProfilesCrud[\"Server\"][\"Read\"]): ServerTeamUser {\n const teamUser = withUserDestructureGuard({\n ...this._serverUserFromCrud(crud.user),\n teamProfile: {\n displayName: crud.display_name,\n profileImageUrl: crud.profile_image_url,\n },\n } satisfies ServerTeamUser);\n\n return teamUser;\n }\n\n protected _serverSentTeamInvitationFromCrud(crud: TeamInvitationCrud['Server']['Read']): SentTeamInvitation {\n return {\n id: crud.id,\n recipientEmail: crud.recipient_email,\n expiresAt: new Date(crud.expires_at_millis),\n revoke: async () => {\n await this._interface.revokeServerTeamInvitation(crud.id, crud.team_id);\n await this._serverTeamInvitationsCache.refresh([crud.team_id]);\n },\n };\n }\n\n protected _serverReceivedTeamInvitationFromCrud(userId: string, crud: TeamInvitationCrud['Client']['Read']): ReceivedTeamInvitation {\n const app = this;\n return {\n id: crud.id,\n teamId: crud.team_id,\n teamDisplayName: crud.team_display_name,\n recipientEmail: crud.recipient_email,\n expiresAt: new Date(crud.expires_at_millis),\n accept: async () => {\n await app._interface.acceptServerTeamInvitationById(crud.id, userId);\n await Promise.all([\n app._serverUserTeamInvitationsCache.refresh([userId]),\n app._serverTeamInvitationsCache.refresh([crud.team_id]),\n app._refreshTeamMembership(crud.team_id, userId),\n ]);\n },\n };\n }\n\n protected override _currentUserFromCrud(crud: UsersCrud['Server']['Read'], session: InternalSession): ProjectCurrentServerUser<ProjectId> {\n const currentUser = withUserDestructureGuard({\n ...this._serverUserFromCrud(crud),\n ...this._createAuth(session),\n ...this._isInternalProject() ? this._createInternalUserExtra(session) : {},\n } satisfies ServerUser);\n\n return currentUser as ProjectCurrentServerUser<ProjectId>;\n }\n\n protected _serverTeamFromCrud(crud: TeamsCrud['Server']['Read']): ServerTeam {\n const app = this;\n return {\n id: crud.id,\n displayName: crud.display_name,\n profileImageUrl: crud.profile_image_url,\n createdAt: new Date(crud.created_at_millis),\n clientMetadata: crud.client_metadata,\n clientReadOnlyMetadata: crud.client_read_only_metadata,\n serverMetadata: crud.server_metadata,\n async update(update: Partial<ServerTeamUpdateOptions>) {\n await app._interface.updateServerTeam(crud.id, serverTeamUpdateOptionsToCrud(update));\n await Promise.all([\n app._serverTeamsCache.refreshWhere(() => true),\n app._serverUsersCache.refreshWhere(() => true),\n ]);\n },\n async delete() {\n await app._interface.deleteServerTeam(crud.id);\n await Promise.all([\n app._serverTeamsCache.refreshWhere(() => true),\n app._serverUsersCache.refreshWhere(() => true),\n ]);\n },\n async listUsers() {\n const result = Result.orThrow(await app._serverTeamMemberProfilesCache.getOrWait([crud.id], \"write-only\"));\n return result.map(u => app._serverTeamUserFromCrud(u));\n },\n async addUser(userId) {\n await app._interface.addServerUserToTeam({\n teamId: crud.id,\n userId,\n });\n await app._refreshTeamMembership(crud.id, userId);\n },\n async removeUser(userId) {\n await app._interface.removeServerUserFromTeam({\n teamId: crud.id,\n userId,\n });\n await app._refreshTeamMembership(crud.id, userId);\n },\n async inviteUser(options: { email: string, callbackUrl?: string }) {\n await app._interface.sendServerTeamInvitation({\n teamId: crud.id,\n email: options.email,\n callbackUrl: options.callbackUrl ?? constructRedirectUrl(app.urls.teamInvitation, \"callbackUrl\"),\n });\n await app._serverTeamInvitationsCache.refresh([crud.id]);\n },\n async listInvitations() {\n const result = Result.orThrow(await app._serverTeamInvitationsCache.getOrWait([crud.id], \"write-only\"));\n return result.map((crud) => app._serverSentTeamInvitationFromCrud(crud));\n },\n async listApiKeys() {\n const result = Result.orThrow(await app._serverTeamApiKeysCache.getOrWait([crud.id], \"write-only\"));\n return result.map((apiKey) => app._serverApiKeyFromCrud(apiKey));\n },\n async createApiKey(options: ApiKeyCreationOptions<\"team\">) {\n const result = await app._interface.createProjectApiKey(\n await apiKeyCreationOptionsToCrud(\"team\", crud.id, options),\n null,\n \"server\",\n );\n await app._serverTeamApiKeysCache.refresh([crud.id]);\n return app._serverApiKeyFromCrud(result);\n },\n ...app._createServerCustomer(crud.id, \"team\"),\n };\n }\n\n protected _serverItemFromCrud(customer: { type: \"user\" | \"team\" | \"custom\", id: string }, crud: ItemCrud['Client']['Read']): ServerItem {\n const app = this;\n return {\n displayName: crud.display_name,\n quantity: crud.quantity,\n nonNegativeQuantity: Math.max(0, crud.quantity),\n increaseQuantity: async (delta: number) => {\n const updateOptions = customer.type === \"user\"\n ? { itemId: crud.id, userId: customer.id }\n : customer.type === \"team\"\n ? { itemId: crud.id, teamId: customer.id }\n : { itemId: crud.id, customCustomerId: customer.id };\n await app._interface.updateItemQuantity(updateOptions, { delta });\n if (customer.type === \"user\") await app._serverUserItemsCache.refresh([customer.id, crud.id]);\n else if (customer.type === \"team\") await app._serverTeamItemsCache.refresh([customer.id, crud.id]);\n else await app._serverCustomItemsCache.refresh([customer.id, crud.id]);\n },\n decreaseQuantity: async (delta: number) => {\n const updateOptions = customer.type === \"user\"\n ? { itemId: crud.id, userId: customer.id }\n : customer.type === \"team\"\n ? { itemId: crud.id, teamId: customer.id }\n : { itemId: crud.id, customCustomerId: customer.id };\n await app._interface.updateItemQuantity(updateOptions, { delta: -delta, allow_negative: true });\n if (customer.type === \"user\") await app._serverUserItemsCache.refresh([customer.id, crud.id]);\n else if (customer.type === \"team\") await app._serverTeamItemsCache.refresh([customer.id, crud.id]);\n else await app._serverCustomItemsCache.refresh([customer.id, crud.id]);\n },\n tryDecreaseQuantity: async (delta: number) => {\n try {\n const updateOptions = customer.type === \"user\"\n ? { itemId: crud.id, userId: customer.id }\n : customer.type === \"team\"\n ? { itemId: crud.id, teamId: customer.id }\n : { itemId: crud.id, customCustomerId: customer.id };\n await app._interface.updateItemQuantity(updateOptions, { delta: -delta });\n if (customer.type === \"user\") await app._serverUserItemsCache.refresh([customer.id, crud.id]);\n else if (customer.type === \"team\") await app._serverTeamItemsCache.refresh([customer.id, crud.id]);\n else await app._serverCustomItemsCache.refresh([customer.id, crud.id]);\n return true;\n } catch (error) {\n if (error instanceof KnownErrors.ItemQuantityInsufficientAmount) {\n return false;\n }\n throw error;\n }\n },\n };\n }\n\n protected async _getUserApiKey(options: { apiKey: string }): Promise<ApiKey<\"user\"> | null> {\n const crud = Result.orThrow(await this._serverCheckApiKeyCache.getOrWait([\"user\", options.apiKey], \"write-only\")) as UserApiKeysCrud['Server']['Read'] | null;\n return crud ? this._serverApiKeyFromCrud(crud) : null;\n }\n\n protected async _getTeamApiKey(options: { apiKey: string }): Promise<ApiKey<\"team\"> | null> {\n const crud = Result.orThrow(await this._serverCheckApiKeyCache.getOrWait([\"team\", options.apiKey], \"write-only\")) as TeamApiKeysCrud['Server']['Read'] | null;\n return crud ? this._serverApiKeyFromCrud(crud) : null;\n }\n protected async _getUserByApiKey(apiKey: string): Promise<ServerUser | null> {\n const apiKeyObject = await this._getUserApiKey({ apiKey });\n if (apiKeyObject === null) {\n return null;\n }\n return await this.getServerUserById(apiKeyObject.userId);\n }\n\n protected async _getUserByConvex(ctx: ConvexCtx, includeAnonymous: boolean): Promise<ServerUser | null> {\n const identity = await ctx.auth.getUserIdentity();\n if (identity === null) {\n return null;\n }\n const user = await this.getServerUserById(identity.subject);\n if (user?.isAnonymous && !includeAnonymous) {\n return null;\n }\n return user;\n }\n\n protected async _getTeamByApiKey(apiKey: string): Promise<ServerTeam | null> {\n const apiKeyObject = await this._getTeamApiKey({ apiKey });\n if (apiKeyObject === null) {\n return null;\n }\n return await this.getTeam(apiKeyObject.teamId);\n }\n\n async createUser(options: ServerUserCreateOptions): Promise<ServerUser> {\n const crud = await this._interface.createServerUser(serverUserCreateOptionsToCrud(options));\n await this._refreshUsers();\n return this._serverUserFromCrud(crud);\n }\n\n async getUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'redirect' }): Promise<ProjectCurrentServerUser<ProjectId>>;\n async getUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'throw' }): Promise<ProjectCurrentServerUser<ProjectId>>;\n async getUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'anonymous' }): Promise<ProjectCurrentServerUser<ProjectId>>;\n async getUser(options?: GetCurrentUserOptions<HasTokenStore>): Promise<ProjectCurrentServerUser<ProjectId> | null>;\n async getUser(id: string): Promise<ServerUser | null>;\n async getUser(options: { apiKey: string }): Promise<ServerUser | null>;\n async getUser(options: { from: \"convex\", ctx: ConvexCtx, or?: \"return-null\" | \"anonymous\" }): Promise<ServerUser | null>;\n async getUser(options?: string | GetCurrentUserOptions<HasTokenStore> | { apiKey: string } | { from: \"convex\", ctx: ConvexCtx }): Promise<ProjectCurrentServerUser<ProjectId> | ServerUser | null> {\n if (typeof options === \"string\") {\n return await this.getServerUserById(options);\n } else if (typeof options === \"object\" && \"apiKey\" in options) {\n return await this._getUserByApiKey(options.apiKey);\n } else if (typeof options === \"object\" && \"from\" in options && options.from as string === \"convex\") {\n return await this._getUserByConvex(options.ctx, \"or\" in options && options.or === \"anonymous\");\n } else {\n options = options as GetCurrentUserOptions<HasTokenStore> | undefined;\n\n // Validate that includeRestricted: false and or: 'anonymous' are mutually exclusive\n if (options?.or === 'anonymous' && options.includeRestricted === false) {\n throw new Error(\"Cannot use { or: 'anonymous' } with { includeRestricted: false }. Anonymous users implicitly include restricted users.\");\n }\n\n // TODO this code is duplicated from the client app; fix that\n this._ensurePersistentTokenStore(options?.tokenStore);\n const session = await this._getSession(options?.tokenStore);\n let crud = Result.orThrow(await this._currentServerUserCache.getOrWait([session], \"write-only\"));\n const includeAnonymous = options?.or === \"anonymous\" || options?.or === \"anonymous-if-exists[deprecated]\";\n const includeRestricted = options?.includeRestricted === true || includeAnonymous;\n\n if (crud === null || (crud.is_anonymous && !includeAnonymous) || (crud.is_restricted && !includeRestricted)) {\n switch (options?.or) {\n case 'redirect': {\n if (!crud?.is_anonymous && crud?.is_restricted) {\n await this.redirectToOnboarding({ replace: true });\n } else {\n await this.redirectToSignIn({ replace: true });\n }\n // TODO: see client-app-impl. We probably want to `await neverResolve()` here instead of returning null\n break;\n }\n case 'throw': {\n throw new Error(\"User is not signed in but getUser was called with { or: 'throw' }\");\n }\n case 'anonymous': {\n const tokens = await this._signUpAnonymously();\n return await this.getUser({ tokenStore: tokens, or: \"anonymous-if-exists[deprecated]\", includeRestricted: true }) ?? throwErr(\"Something went wrong while signing up anonymously\");\n }\n case undefined:\n case \"anonymous-if-exists[deprecated]\":\n case \"return-null\": {\n return null;\n }\n }\n }\n\n return crud && this._currentUserFromCrud(crud, session);\n }\n }\n\n async getServerUser(): Promise<ProjectCurrentServerUser<ProjectId> | null> {\n console.warn(\"stackServerApp.getServerUser is deprecated; use stackServerApp.getUser instead\");\n return await this.getUser();\n }\n\n async getServerUserById(userId: string): Promise<ServerUser | null> {\n const crud = Result.orThrow(await this._serverUserCache.getOrWait([userId], \"write-only\"));\n return crud && this._serverUserFromCrud(crud);\n }\n\n\n async listUsers(options?: ServerListUsersOptions): Promise<ServerUser[] & { nextCursor: string | null }> {\n const crud = Result.orThrow(await this._serverUsersCache.getOrWait([options?.cursor, options?.limit, options?.orderBy, options?.desc, options?.query, options?.includeRestricted, options?.includeAnonymous, options?.onlyAnonymous, options?.teamId], \"write-only\"));\n const result: any = crud.items.map((j) => this._serverUserFromCrud(j));\n result.nextCursor = crud.pagination?.next_cursor ?? null;\n return result as any;\n }\n\n\n _serverPermissionFromCrud(crud: TeamPermissionsCrud['Server']['Read'] | ProjectPermissionsCrud['Server']['Read']): AdminTeamPermission {\n return {\n id: crud.id,\n };\n }\n\n _serverTeamPermissionDefinitionFromCrud(crud: TeamPermissionDefinitionsCrud['Admin']['Read']): AdminTeamPermissionDefinition {\n return {\n id: crud.id,\n description: crud.description,\n containedPermissionIds: crud.contained_permission_ids,\n };\n }\n\n _serverProjectPermissionDefinitionFromCrud(crud: ProjectPermissionDefinitionsCrud['Admin']['Read']): AdminProjectPermissionDefinition {\n return {\n id: crud.id,\n description: crud.description,\n containedPermissionIds: crud.contained_permission_ids,\n };\n }\n\n async getItem(options: { itemId: string, userId: string } | { itemId: string, teamId: string } | { itemId: string, customCustomerId: string }): Promise<ServerItem> {\n if (\"userId\" in options) {\n const result = Result.orThrow(await this._serverUserItemsCache.getOrWait([options.userId, options.itemId], \"write-only\"));\n return this._serverItemFromCrud({ type: \"user\", id: options.userId }, result);\n } else if (\"teamId\" in options) {\n const result = Result.orThrow(await this._serverTeamItemsCache.getOrWait([options.teamId, options.itemId], \"write-only\"));\n return this._serverItemFromCrud({ type: \"team\", id: options.teamId }, result);\n } else {\n const result = Result.orThrow(await this._serverCustomItemsCache.getOrWait([options.customCustomerId, options.itemId], \"write-only\"));\n return this._serverItemFromCrud({ type: \"custom\", id: options.customCustomerId }, result);\n }\n }\n\n async listProducts(options: CustomerProductsRequestOptions): Promise<CustomerProductsList> {\n if (\"userId\" in options) {\n const response = Result.orThrow(await this._serverUserProductsCache.getOrWait([options.userId, options.cursor ?? null, options.limit ?? null], \"write-only\"));\n return this._customerProductsFromResponse(response);\n } else if (\"teamId\" in options) {\n const response = Result.orThrow(await this._serverTeamProductsCache.getOrWait([options.teamId, options.cursor ?? null, options.limit ?? null], \"write-only\"));\n return this._customerProductsFromResponse(response);\n }\n const response = Result.orThrow(await this._serverCustomProductsCache.getOrWait([options.customCustomerId, options.cursor ?? null, options.limit ?? null], \"write-only\"));\n return this._customerProductsFromResponse(response);\n }\n\n async grantProduct(options: (\n ({ userId: string } | { teamId: string } | { customCustomerId: string }) &\n ({ productId: string } | { product: InlineProduct }) &\n { quantity?: number }\n )): Promise<void> {\n let customerType: \"user\" | \"team\" | \"custom\";\n let customerId: string;\n if (\"userId\" in options) {\n customerType = \"user\";\n customerId = options.userId;\n } else if (\"teamId\" in options) {\n customerType = \"team\";\n customerId = options.teamId;\n } else {\n customerType = \"custom\";\n customerId = options.customCustomerId;\n }\n\n await this._interface.grantProduct({\n customerType,\n customerId,\n productId: \"productId\" in options ? options.productId : undefined,\n product: \"product\" in options ? options.product : undefined,\n quantity: options.quantity,\n });\n\n const cache = customerType === \"user\"\n ? this._serverUserProductsCache\n : customerType === \"team\"\n ? this._serverTeamProductsCache\n : this._serverCustomProductsCache;\n await cache.refresh([customerId, null, null]);\n }\n\n async createTeam(data: ServerTeamCreateOptions): Promise<ServerTeam> {\n const team = await this._interface.createServerTeam(serverTeamCreateOptionsToCrud(data));\n await this._serverTeamsCache.refreshWhere(() => true);\n return this._serverTeamFromCrud(team);\n }\n\n async listTeams(options?: ServerListTeamsOptions): Promise<ServerTeam[] & { nextCursor: string | null }> {\n const crud = Result.orThrow(await this._serverTeamsCache.getOrWait([undefined, options?.orderBy, options?.desc, options?.cursor, options?.limit, options?.query] as const, \"write-only\"));\n const teams: any = crud.items.map((t) => this._serverTeamFromCrud(t));\n teams.nextCursor = crud.pagination?.next_cursor ?? null;\n return teams as any;\n }\n\n\n async listTeamMemberPermissions(teamId: string, options?: { recursive?: boolean }): Promise<{ userId: string, permissionId: string }[]> {\n const recursive = options?.recursive ?? false;\n const rows = Result.orThrow(await this._serverAllTeamMemberPermissionsCache.getOrWait([teamId, recursive] as const, \"write-only\"));\n return rows.map((r) => ({ userId: r.user_id, permissionId: r.id }));\n }\n\n\n async getTeam(options: { apiKey: string }): Promise<ServerTeam | null>;\n async getTeam(teamId: string): Promise<ServerTeam | null>;\n async getTeam(options?: { apiKey: string } | string): Promise<ServerTeam | null> {\n if (typeof options === \"object\" && \"apiKey\" in options) {\n return await this._getTeamByApiKey(options.apiKey);\n } else {\n const teamId = options;\n const teams = await this.listTeams();\n return teams.find((t) => t.id === teamId) ?? null;\n }\n }\n\n\n protected _createServerDataVaultStore(id: string): DataVaultStore {\n const validateOptions = (options: { secret: string }) => {\n if (typeof options.secret !== \"string\") throw new Error(\"secret must be a string, got \" + typeof options.secret);\n };\n return {\n id,\n setValue: async (key, value, options) => {\n validateOptions(options);\n await this._interface.setDataVaultStoreValue(options.secret, id, key, value);\n },\n getValue: async (key, options) => {\n validateOptions(options);\n return Result.orThrow(await this._serverDataVaultStoreValueCache.getOrWait([id, key, options.secret], \"write-only\"));\n },\n };\n }\n\n async getDataVaultStore(id: string): Promise<DataVaultStore> {\n return this._createServerDataVaultStore(id);\n }\n\n\n async sendEmail(options: SendEmailOptions): Promise<void> {\n await this._interface.sendEmail(options);\n await this._emailDeliveryInfoCache.refresh([]);\n }\n\n async getEmailDeliveryStats(): Promise<EmailDeliveryInfo> {\n return Result.orThrow(await this._emailDeliveryInfoCache.getOrWait([], \"write-only\"));\n }\n\n\n async activateEmailCapacityBoost(): Promise<void> {\n await this._interface.activateEmailCapacityBoost();\n // Refresh the cache so UI updates immediately\n await this._emailDeliveryInfoCache.refresh([]);\n }\n\n protected override async _refreshSession(session: InternalSession) {\n await Promise.all([\n super._refreshUser(session),\n this._currentServerUserCache.refresh([session]),\n ]);\n }\n\n protected override async _refreshUsers() {\n await Promise.all([\n super._refreshUsers(),\n this._serverUserCache.refreshWhere(() => true),\n this._serverUsersCache.refreshWhere(() => true),\n this._serverContactChannelsCache.refreshWhere(() => true),\n this._serverOAuthProvidersCache.refreshWhere(() => true),\n this._serverUserConnectedAccountsCache.refreshWhere(() => true),\n ]);\n }\n\n async createOAuthProvider(options: {\n userId: string,\n providerConfigId: string,\n accountId: string,\n email: string,\n allowSignIn: boolean,\n allowConnectedAccounts: boolean,\n }): Promise<Result<ServerOAuthProvider, InstanceType<typeof KnownErrors.OAuthProviderAccountIdAlreadyUsedForSignIn>>> {\n try {\n const crud = await this._interface.createServerOAuthProvider({\n user_id: options.userId,\n provider_config_id: options.providerConfigId,\n account_id: options.accountId,\n email: options.email,\n allow_sign_in: options.allowSignIn,\n allow_connected_accounts: options.allowConnectedAccounts,\n });\n\n await Promise.all([\n this._serverOAuthProvidersCache.refresh([options.userId]),\n this._serverUserConnectedAccountsCache.refresh([options.userId]),\n ]);\n return Result.ok(this._serverOAuthProviderFromCrud(crud));\n } catch (error) {\n if (KnownErrors.OAuthProviderAccountIdAlreadyUsedForSignIn.isInstance(error)) {\n return Result.error(error);\n }\n throw error;\n }\n }\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"session-refresh-subscription.js","names":[],"sources":["../../../../../../src/lib/stack-app/apps/implementations/session-refresh-subscription.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\ntype TokenStoreSubscription = {\n unsubscribe: () => void,\n};\n\ntype TokenStoreLike = {\n onChange: (callback: () => void) => TokenStoreSubscription,\n};\n\ntype SessionRefreshLike = {\n sessionKey: string,\n startRefreshingAccessToken: (minMillisUntilExpiration: number, maxMillisSinceIssued: number | null) => TokenStoreSubscription,\n};\n\n/**\n * Keeps the currently mounted React session fresh while `useSyncExternalStore`\n * has an active subscriber. The token store owns which session is current; when\n * it changes to a different session key, we stop refreshing the old session and\n * start refreshing the new one. The caller still receives every token-store\n * change through `onTokenStoreChange` so React can re-read the session snapshot.\n */\nexport function subscribeSessionRefresh(options: {\n tokenStore: TokenStoreLike,\n getSession: () => SessionRefreshLike,\n onTokenStoreChange: () => void,\n minMillisUntilExpiration?: number,\n maxMillisSinceIssued?: number | null,\n}): () => void {\n const minMillisUntilExpiration = options.minMillisUntilExpiration ?? 30_000;\n const maxMillisSinceIssued = options.maxMillisSinceIssued ?? 60_000;\n\n let refreshedSession = options.getSession();\n let refreshSubscription = refreshedSession.startRefreshingAccessToken(minMillisUntilExpiration, maxMillisSinceIssued);\n\n const tokenStoreSubscription = options.tokenStore.onChange(() => {\n const nextSession = options.getSession();\n if (nextSession.sessionKey !== refreshedSession.sessionKey) {\n refreshSubscription.unsubscribe();\n refreshedSession = nextSession;\n refreshSubscription = refreshedSession.startRefreshingAccessToken(minMillisUntilExpiration, maxMillisSinceIssued);\n }\n options.onTokenStoreChange();\n });\n\n return () => {\n tokenStoreSubscription.unsubscribe();\n refreshSubscription.unsubscribe();\n };\n}\n"],"mappings":";;;;;;;;AAwBA,SAAgB,wBAAwB,SAMzB;CACb,MAAM,2BAA2B,QAAQ,4BAA4B;CACrE,MAAM,uBAAuB,QAAQ,wBAAwB;CAE7D,IAAI,mBAAmB,QAAQ,YAAY;CAC3C,IAAI,sBAAsB,iBAAiB,2BAA2B,0BAA0B,qBAAqB;CAErH,MAAM,yBAAyB,QAAQ,WAAW,eAAe;EAC/D,MAAM,cAAc,QAAQ,YAAY;AACxC,MAAI,YAAY,eAAe,iBAAiB,YAAY;AAC1D,uBAAoB,aAAa;AACjC,sBAAmB;AACnB,yBAAsB,iBAAiB,2BAA2B,0BAA0B,qBAAqB;;AAEnH,UAAQ,oBAAoB;GAC5B;AAEF,cAAa;AACX,yBAAuB,aAAa;AACpC,sBAAoB,aAAa"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"session-refresh-subscription.test.js","names":[],"sources":["../../../../../../src/lib/stack-app/apps/implementations/session-refresh-subscription.test.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { describe, expect, it, vi } from \"vitest\";\nimport { subscribeSessionRefresh } from \"./session-refresh-subscription\";\n\ntype Listener = () => void;\n\nfunction createTokenStoreTestDouble() {\n const listeners = new Set<Listener>();\n const unsubscribe = vi.fn((listener: Listener) => {\n listeners.delete(listener);\n });\n\n return {\n tokenStore: {\n onChange: vi.fn((listener: Listener) => {\n listeners.add(listener);\n return {\n unsubscribe: () => unsubscribe(listener),\n };\n }),\n },\n emitChange: () => {\n for (const listener of [...listeners]) {\n listener();\n }\n },\n unsubscribe,\n };\n}\n\nfunction createSessionTestDouble(sessionKey: string) {\n const refreshUnsubscribe = vi.fn();\n return {\n session: {\n sessionKey,\n startRefreshingAccessToken: vi.fn(() => ({\n unsubscribe: refreshUnsubscribe,\n })),\n },\n refreshUnsubscribe,\n };\n}\n\ndescribe(\"subscribeSessionRefresh\", () => {\n it(\"starts token refresh while subscribed and stops it on unsubscribe\", () => {\n const tokenStore = createTokenStoreTestDouble();\n const firstSession = createSessionTestDouble(\"refresh-token-1\");\n const onTokenStoreChange = vi.fn();\n\n const unsubscribe = subscribeSessionRefresh({\n tokenStore: tokenStore.tokenStore,\n getSession: () => firstSession.session,\n onTokenStoreChange,\n });\n\n expect(firstSession.session.startRefreshingAccessToken).toHaveBeenCalledWith(30_000, 60_000);\n expect(tokenStore.tokenStore.onChange).toHaveBeenCalledOnce();\n\n unsubscribe();\n\n expect(tokenStore.unsubscribe).toHaveBeenCalledOnce();\n expect(firstSession.refreshUnsubscribe).toHaveBeenCalledOnce();\n });\n\n it(\"keeps the existing refresh loop when the token store changes within the same session\", () => {\n const tokenStore = createTokenStoreTestDouble();\n const firstSession = createSessionTestDouble(\"refresh-token-1\");\n const onTokenStoreChange = vi.fn();\n\n subscribeSessionRefresh({\n tokenStore: tokenStore.tokenStore,\n getSession: () => firstSession.session,\n onTokenStoreChange,\n });\n\n tokenStore.emitChange();\n\n expect(onTokenStoreChange).toHaveBeenCalledOnce();\n expect(firstSession.session.startRefreshingAccessToken).toHaveBeenCalledOnce();\n expect(firstSession.refreshUnsubscribe).not.toHaveBeenCalled();\n });\n\n it(\"moves the refresh loop when the token store changes to a different session\", () => {\n const tokenStore = createTokenStoreTestDouble();\n const firstSession = createSessionTestDouble(\"refresh-token-1\");\n const secondSession = createSessionTestDouble(\"refresh-token-2\");\n const sessions = [firstSession.session, secondSession.session];\n const onTokenStoreChange = vi.fn();\n\n subscribeSessionRefresh({\n tokenStore: tokenStore.tokenStore,\n getSession: () => sessions[0] ?? secondSession.session,\n onTokenStoreChange,\n });\n\n sessions.shift();\n tokenStore.emitChange();\n\n expect(onTokenStoreChange).toHaveBeenCalledOnce();\n expect(firstSession.refreshUnsubscribe).toHaveBeenCalledOnce();\n expect(secondSession.session.startRefreshingAccessToken).toHaveBeenCalledWith(30_000, 60_000);\n });\n});\n"],"mappings":";;;;AASA,SAAS,6BAA6B;CACpC,MAAM,4BAAY,IAAI,KAAe;CACrC,MAAM,cAAc,GAAG,IAAI,aAAuB;AAChD,YAAU,OAAO,SAAS;GAC1B;AAEF,QAAO;EACL,YAAY,EACV,UAAU,GAAG,IAAI,aAAuB;AACtC,aAAU,IAAI,SAAS;AACvB,UAAO,EACL,mBAAmB,YAAY,SAAS,EACzC;IACD,EACH;EACD,kBAAkB;AAChB,QAAK,MAAM,YAAY,CAAC,GAAG,UAAU,CACnC,WAAU;;EAGd;EACD;;AAGH,SAAS,wBAAwB,YAAoB;CACnD,MAAM,qBAAqB,GAAG,IAAI;AAClC,QAAO;EACL,SAAS;GACP;GACA,4BAA4B,GAAG,UAAU,EACvC,aAAa,oBACd,EAAE;GACJ;EACD;EACD;;AAGH,SAAS,iCAAiC;AACxC,IAAG,2EAA2E;EAC5E,MAAM,aAAa,4BAA4B;EAC/C,MAAM,eAAe,wBAAwB,kBAAkB;EAC/D,MAAM,qBAAqB,GAAG,IAAI;EAElC,MAAM,cAAc,wBAAwB;GAC1C,YAAY,WAAW;GACvB,kBAAkB,aAAa;GAC/B;GACD,CAAC;AAEF,SAAO,aAAa,QAAQ,2BAA2B,CAAC,qBAAqB,KAAQ,IAAO;AAC5F,SAAO,WAAW,WAAW,SAAS,CAAC,sBAAsB;AAE7D,eAAa;AAEb,SAAO,WAAW,YAAY,CAAC,sBAAsB;AACrD,SAAO,aAAa,mBAAmB,CAAC,sBAAsB;GAC9D;AAEF,IAAG,8FAA8F;EAC/F,MAAM,aAAa,4BAA4B;EAC/C,MAAM,eAAe,wBAAwB,kBAAkB;EAC/D,MAAM,qBAAqB,GAAG,IAAI;AAElC,0BAAwB;GACtB,YAAY,WAAW;GACvB,kBAAkB,aAAa;GAC/B;GACD,CAAC;AAEF,aAAW,YAAY;AAEvB,SAAO,mBAAmB,CAAC,sBAAsB;AACjD,SAAO,aAAa,QAAQ,2BAA2B,CAAC,sBAAsB;AAC9E,SAAO,aAAa,mBAAmB,CAAC,IAAI,kBAAkB;GAC9D;AAEF,IAAG,oFAAoF;EACrF,MAAM,aAAa,4BAA4B;EAC/C,MAAM,eAAe,wBAAwB,kBAAkB;EAC/D,MAAM,gBAAgB,wBAAwB,kBAAkB;EAChE,MAAM,WAAW,CAAC,aAAa,SAAS,cAAc,QAAQ;EAC9D,MAAM,qBAAqB,GAAG,IAAI;AAElC,0BAAwB;GACtB,YAAY,WAAW;GACvB,kBAAkB,SAAS,MAAM,cAAc;GAC/C;GACD,CAAC;AAEF,WAAS,OAAO;AAChB,aAAW,YAAY;AAEvB,SAAO,mBAAmB,CAAC,sBAAsB;AACjD,SAAO,aAAa,mBAAmB,CAAC,sBAAsB;AAC9D,SAAO,cAAc,QAAQ,2BAA2B,CAAC,qBAAqB,KAAQ,IAAO;GAC7F;EACF"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"session-replay.js","names":[],"sources":["../../../../../../src/lib/stack-app/apps/implementations/session-replay.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { isBrowserLike } from \"@hexclave/shared/dist/utils/env\";\nimport { captureWarning } from \"@hexclave/shared/dist/utils/errors\";\nimport { runAsynchronously } from \"@hexclave/shared/dist/utils/promises\";\nimport { Result } from \"@hexclave/shared/dist/utils/results\";\n\nexport type AnalyticsReplayOptions = {\n /**\n * Whether session replays are enabled.\n *\n * @default false\n */\n enabled?: boolean,\n /**\n * Whether to mask the content of all `<input>` elements.\n *\n * @default true\n */\n maskAllInputs?: boolean,\n /**\n * A CSS class name or RegExp. Elements with a matching class will be blocked\n * (replaced with a placeholder in the recording).\n *\n * @default undefined\n */\n blockClass?: string | RegExp,\n /**\n * A CSS selector string. Elements matching this selector will be blocked\n * (replaced with a placeholder in the recording).\n *\n * @default undefined\n */\n blockSelector?: string,\n};\n\nexport type AnalyticsOptions = {\n /**\n * Whether SDK-managed analytics capture is enabled.\n *\n * @default true\n */\n enabled?: boolean,\n /**\n * Options for session replay recording. Replays are disabled by default;\n * set `enabled: true` to opt in.\n */\n replays?: AnalyticsReplayOptions,\n};\n\n/**\n * Converts AnalyticsOptions to a JSON-safe representation.\n * RegExp blockClass values are serialized as `{ __regexp, __flags }` objects.\n * The return type is AnalyticsOptions to keep StackClientAppJson simple;\n * the actual runtime value is JSON-safe.\n */\nexport function analyticsOptionsToJson(options: AnalyticsOptions | undefined): AnalyticsOptions | undefined {\n if (!options?.replays?.blockClass) return options;\n const { blockClass, ...rest } = options.replays;\n if (!(blockClass instanceof RegExp)) return options;\n return {\n ...options,\n replays: {\n ...rest,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n blockClass: { __regexp: blockClass.source, __flags: blockClass.flags } as any,\n },\n };\n}\n\n/**\n * Reconstructs AnalyticsOptions from a JSON-deserialized value.\n * Converts `{ __regexp, __flags }` objects back to RegExp instances.\n */\nexport function analyticsOptionsFromJson(json: AnalyticsOptions | undefined): AnalyticsOptions | undefined {\n if (!json?.replays?.blockClass) return json;\n const { blockClass, ...rest } = json.replays;\n if (typeof blockClass === 'object' && '__regexp' in blockClass) {\n const bc = blockClass as unknown as { __regexp: string, __flags: string };\n return {\n ...json,\n replays: {\n ...rest,\n blockClass: new RegExp(bc.__regexp, bc.__flags),\n },\n };\n }\n return json;\n}\n\n// ---------- Recording internals ----------\n\n// Hexclave rebrand: canonical localStorage prefix (colon delimiters preserved).\nconst LOCAL_STORAGE_PREFIX = \"hexclave:session-replay:v1\";\n// Hexclave rebrand: legacy prefix — dual-read only, so a recording session active\n// across an SDK upgrade is not orphaned. Never written.\nconst LEGACY_LOCAL_STORAGE_PREFIX = \"stack:session-replay:v1\";\nconst IDLE_TTL_MS = 3 * 60 * 1000;\n\nconst FLUSH_INTERVAL_MS = 5_000;\nconst MAX_EVENTS_PER_BATCH = 200;\nconst MAX_APPROX_BYTES_PER_BATCH = 512_000;\n\nexport type StoredSession = {\n session_id: string,\n created_at_ms: number,\n last_activity_ms: number,\n};\n\nexport function safeParseStoredSession(raw: string | null): StoredSession | null {\n if (!raw) return null;\n try {\n const parsed = JSON.parse(raw);\n if (typeof parsed !== \"object\" || parsed === null) return null;\n if (typeof parsed.session_id !== \"string\") return null;\n if (typeof parsed.created_at_ms !== \"number\") return null;\n if (typeof parsed.last_activity_ms !== \"number\") return null;\n return parsed as StoredSession;\n } catch {\n return null;\n }\n}\n\nexport function makeStorageKey(projectId: string) {\n return `${LOCAL_STORAGE_PREFIX}:${projectId}`;\n}\n\n// Hexclave rebrand: legacy key, dual-read only (never written).\nexport function makeLegacyStorageKey(projectId: string) {\n return `${LEGACY_LOCAL_STORAGE_PREFIX}:${projectId}`;\n}\n\nexport function generateUuid() {\n return crypto.randomUUID();\n}\n\nexport function getOrRotateSession(options: { key: string, legacyKey?: string, nowMs: number }): StoredSession {\n // Hexclave rebrand: prefer the new key; fall back to the legacy key so a\n // recording session active across an SDK upgrade is not orphaned.\n const existing = safeParseStoredSession(localStorage.getItem(options.key))\n ?? (options.legacyKey ? safeParseStoredSession(localStorage.getItem(options.legacyKey)) : null);\n if (existing && options.nowMs - existing.last_activity_ms <= IDLE_TTL_MS) {\n return existing;\n }\n const next: StoredSession = {\n session_id: generateUuid(),\n created_at_ms: options.nowMs,\n last_activity_ms: options.nowMs,\n };\n localStorage.setItem(options.key, JSON.stringify(next));\n return next;\n}\n\nexport type SessionRecorderDeps = {\n projectId: string,\n sendBatch: (body: string, options: { keepalive: boolean }) => Promise<Result<Response, Error>>,\n};\n\nexport class SessionRecorder {\n private _started = false;\n private _cancelled = false;\n private _stopRecording: (() => void) | null = null;\n private _detachListeners: (() => void) | null = null;\n private _flushTimer: ReturnType<typeof setInterval> | null = null;\n private _events: unknown[] = [];\n private _approxBytes = 0;\n private _lastPersistActivity = 0;\n private _recording = false;\n private _rrwebModule: typeof import(\"rrweb\") | null = null;\n private _lastBrowserSessionId: string | null = null;\n private _takingSnapshot = false;\n private _flushInProgress = false;\n private readonly _sessionReplaySegmentId: string;\n private readonly _storageKey: string;\n // Hexclave rebrand: legacy key used for dual-read fallback only.\n private readonly _legacyStorageKey: string;\n private readonly _deps: SessionRecorderDeps;\n private readonly _replayOptions: AnalyticsReplayOptions;\n\n constructor(deps: SessionRecorderDeps, replayOptions: AnalyticsReplayOptions) {\n this._deps = deps;\n this._replayOptions = replayOptions;\n this._sessionReplaySegmentId = generateUuid();\n this._storageKey = makeStorageKey(deps.projectId);\n this._legacyStorageKey = makeLegacyStorageKey(deps.projectId);\n }\n\n /**\n * Starts recording. Idempotent — calling multiple times is safe.\n */\n start() {\n if (this._started) return;\n if (!isBrowserLike()) return;\n this._started = true;\n\n // Kick off rrweb recording\n runAsynchronously(() => this._startRecording(), { noErrorLogging: true });\n\n // Periodic flush\n this._flushTimer = setInterval(() => this._tick(), FLUSH_INTERVAL_MS);\n }\n\n stop() {\n this._cancelled = true;\n if (this._flushTimer !== null) {\n clearInterval(this._flushTimer);\n this._flushTimer = null;\n }\n // Flush remaining events before cleanup\n runAsynchronously(() => this._flush({ keepalive: true }));\n this._stopCurrentRecording();\n }\n\n clearBuffer() {\n this._events = [];\n this._approxBytes = 0;\n }\n\n private _persistActivity(nowMs: number): StoredSession {\n const stored = getOrRotateSession({ key: this._storageKey, legacyKey: this._legacyStorageKey, nowMs });\n if (nowMs - this._lastPersistActivity < 5_000) return stored;\n this._lastPersistActivity = nowMs;\n const updated: StoredSession = { ...stored, last_activity_ms: nowMs };\n localStorage.setItem(this._storageKey, JSON.stringify(updated));\n return stored;\n }\n\n private async _flush(options: { keepalive: boolean }) {\n if (this._events.length === 0) return;\n // Prevent concurrent in-flight HTTP requests. When a flush is already\n // in-flight, a second batch could race on the server (both call\n // findRecentSessionReplay before either upsert commits) and create\n // duplicate SessionReplay records. Events stay in _events and will be\n // picked up by the next tick or batch-size check.\n if (this._flushInProgress) return;\n\n const nowMs = Date.now();\n const stored = getOrRotateSession({ key: this._storageKey, legacyKey: this._legacyStorageKey, nowMs });\n\n const batchId = generateUuid();\n const payload = {\n browser_session_id: stored.session_id,\n session_replay_segment_id: this._sessionReplaySegmentId,\n batch_id: batchId,\n started_at_ms: stored.created_at_ms,\n sent_at_ms: nowMs,\n events: this._events,\n };\n\n this._events = [];\n this._approxBytes = 0;\n\n this._flushInProgress = true;\n try {\n const res = await this._deps.sendBatch(\n JSON.stringify(payload),\n { keepalive: options.keepalive },\n );\n\n if (res.status === \"error\") {\n captureWarning(\"SessionRecorder.flush\", res.error);\n return;\n }\n\n if (!res.data.ok) {\n captureWarning(\"SessionRecorder.flush\", new Error(`SessionRecorder flush failed: ${res.data.status} ${await res.data.text()}`));\n }\n } finally {\n this._flushInProgress = false;\n }\n }\n\n private async _startRecording() {\n if (this._recording || this._cancelled) return;\n\n if (!this._rrwebModule) {\n const rrwebImport = await Result.fromPromise(import(\"rrweb\"));\n if (rrwebImport.status === \"error\") {\n console.warn(\"SessionRecorder: rrweb import failed. Is rrweb installed?\", rrwebImport.error);\n return;\n }\n this._rrwebModule = rrwebImport.data;\n }\n\n // cancelled may change during the await above\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (this._cancelled) return;\n\n this._stopRecording = this._rrwebModule.record({\n emit: (event) => {\n const nowMs = Date.now();\n const stored = this._persistActivity(nowMs);\n\n // Detect session rotation: after 3+ minutes idle, getOrRotateSession\n // creates a new session ID. We need to inject a FullSnapshot so the\n // new server-side SessionReplay record is playable.\n if (this._lastBrowserSessionId === null) {\n this._lastBrowserSessionId = stored.session_id;\n } else if (stored.session_id !== this._lastBrowserSessionId && !this._takingSnapshot) {\n this._lastBrowserSessionId = stored.session_id;\n // Inject a FullSnapshot for the new session (calls emit synchronously)\n this._takingSnapshot = true;\n try {\n this._rrwebModule!.record.takeFullSnapshot();\n } finally {\n this._takingSnapshot = false;\n }\n }\n\n this._events.push(event);\n this._approxBytes += JSON.stringify(event).length;\n if (this._events.length >= MAX_EVENTS_PER_BATCH || this._approxBytes >= MAX_APPROX_BYTES_PER_BATCH) {\n runAsynchronously(() => this._flush({ keepalive: false }));\n }\n },\n maskAllInputs: this._replayOptions.maskAllInputs ?? true,\n ...(this._replayOptions.blockClass !== undefined ? { blockClass: this._replayOptions.blockClass } : {}),\n ...(this._replayOptions.blockSelector !== undefined ? { blockSelector: this._replayOptions.blockSelector } : {}),\n }) ?? null;\n\n this._recording = true;\n\n const onPageHide = () => {\n runAsynchronously(() => this._flush({ keepalive: true }));\n };\n window.addEventListener(\"pagehide\", onPageHide);\n document.addEventListener(\"visibilitychange\", onPageHide);\n this._detachListeners = () => {\n window.removeEventListener(\"pagehide\", onPageHide);\n document.removeEventListener(\"visibilitychange\", onPageHide);\n };\n }\n\n private _stopCurrentRecording() {\n if (this._detachListeners) {\n this._detachListeners();\n this._detachListeners = null;\n }\n if (this._stopRecording) {\n this._stopRecording();\n this._stopRecording = null;\n }\n this._events = [];\n this._approxBytes = 0;\n this._recording = false;\n }\n\n private _tick() {\n if (this._cancelled) return;\n if (this._events.length > 0) {\n runAsynchronously(() => this._flush({ keepalive: false }));\n }\n }\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"session-replay.test.js","names":[],"sources":["../../../../../../src/lib/stack-app/apps/implementations/session-replay.test.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { describe, expect, it } from \"vitest\";\nimport { analyticsOptionsFromJson, analyticsOptionsToJson } from \"./session-replay\";\n\ndescribe(\"analytics option JSON conversion\", () => {\n it(\"preserves top-level analytics options when serializing replay block classes\", () => {\n const json = analyticsOptionsToJson({\n enabled: false,\n replays: {\n enabled: true,\n blockClass: /stack-sensitive/u,\n },\n });\n\n expect(json?.enabled).toBe(false);\n expect(json?.replays?.enabled).toBe(true);\n });\n\n it(\"preserves top-level analytics options when deserializing replay block classes\", () => {\n const roundTripped = analyticsOptionsFromJson(analyticsOptionsToJson({\n enabled: false,\n replays: {\n blockClass: /stack-sensitive/u,\n },\n }));\n\n expect(roundTripped?.enabled).toBe(false);\n expect(roundTripped?.replays?.blockClass).toEqual(/stack-sensitive/u);\n });\n});\n"],"mappings":";;;;AAOA,SAAS,0CAA0C;AACjD,IAAG,qFAAqF;EACtF,MAAM,OAAO,uBAAuB;GAClC,SAAS;GACT,SAAS;IACP,SAAS;IACT,YAAY;IACb;GACF,CAAC;AAEF,SAAO,MAAM,QAAQ,CAAC,KAAK,MAAM;AACjC,SAAO,MAAM,SAAS,QAAQ,CAAC,KAAK,KAAK;GACzC;AAEF,IAAG,uFAAuF;EACxF,MAAM,eAAe,yBAAyB,uBAAuB;GACnE,SAAS;GACT,SAAS,EACP,YAAY,oBACb;GACF,CAAC,CAAC;AAEH,SAAO,cAAc,QAAQ,CAAC,KAAK,MAAM;AACzC,SAAO,cAAc,SAAS,WAAW,CAAC,QAAQ,mBAAmB;GACrE;EACF"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"admin-app.js","names":[],"sources":["../../../../../../src/lib/stack-app/apps/interfaces/admin-app.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { AnalyticsQueryOptions, AnalyticsQueryResponse } from \"@hexclave/shared/dist/interface/crud/analytics\";\nimport type { AdminGetSessionReplayChunkEventsResponse, AdminGetSessionReplayAllEventsResponse } from \"@hexclave/shared/dist/interface/crud/session-replays\";\nimport type { Transaction, TransactionType } from \"@hexclave/shared/dist/interface/crud/transactions\";\nimport { InternalSession } from \"@hexclave/shared/dist/sessions\";\nimport type { MoneyAmount } from \"@hexclave/shared/dist/utils/currency-constants\";\nimport { Result } from \"@hexclave/shared/dist/utils/results\";\nimport { AsyncStoreProperty, EmailConfig } from \"../../common\";\nimport { AdminEmailOutbox, AdminSentEmail } from \"../../email\";\nimport { InternalApiKey, InternalApiKeyCreateOptions, InternalApiKeyFirstView } from \"../../internal-api-keys\";\nimport { AdminProjectPermission, AdminProjectPermissionDefinition, AdminProjectPermissionDefinitionCreateOptions, AdminProjectPermissionDefinitionUpdateOptions, AdminTeamPermission, AdminTeamPermissionDefinition, AdminTeamPermissionDefinitionCreateOptions, AdminTeamPermissionDefinitionUpdateOptions } from \"../../permissions\";\nimport { AdminProject } from \"../../projects\";\nimport { _StackAdminAppImpl } from \"../implementations\";\nimport { StackServerApp, StackServerAppConstructorOptions } from \"./server-app\";\n\nexport type EmailOutboxListOptions = {\n status?: string,\n simpleStatus?: string,\n limit?: number,\n cursor?: string,\n};\n\nexport type EmailOutboxListResult = {\n items: AdminEmailOutbox[],\n nextCursor: string | null,\n};\n\nexport type EmailOutboxUpdateOptions = {\n isPaused?: boolean,\n scheduledAtMillis?: number,\n cancel?: boolean,\n tsxSource?: string,\n themeId?: string | null,\n};\n\nexport type ManagedEmailProviderSetupResult = {\n domainId: string,\n subdomain: string,\n senderLocalPart: string,\n nameServerRecords: string[],\n status: ManagedEmailProviderStatus[\"status\"],\n};\n\nexport type ManagedEmailProviderStatus = {\n status: \"pending_dns\" | \"pending_verification\" | \"verified\" | \"applied\" | \"failed\",\n};\n\nexport type ManagedEmailProviderListItem = {\n domainId: string,\n subdomain: string,\n senderLocalPart: string,\n status: ManagedEmailProviderStatus[\"status\"],\n nameServerRecords: string[],\n};\n\nimport type { AdminSessionReplay, ListSessionReplayChunksOptions, ListSessionReplayChunksResult, ListSessionReplaysOptions, ListSessionReplaysResult, SessionReplayAllEventsResult } from \"../../session-replays\";\nexport type { AdminSessionReplay, AdminSessionReplayChunk, ListSessionReplaysOptions, ListSessionReplaysResult, ListSessionReplayChunksOptions, ListSessionReplayChunksResult, SessionReplayAllEventsResult } from \"../../session-replays\";\n\n\n/** @deprecated Use `HexclaveAdminAppConstructorOptions` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackAdminAppConstructorOptions<HasTokenStore extends boolean, ProjectId extends string> = (\n & StackServerAppConstructorOptions<HasTokenStore, ProjectId>\n & {\n superSecretAdminKey?: string,\n projectOwnerSession?: InternalSession | (() => Promise<string | null>),\n }\n);\n\n\n/** @deprecated Use `HexclaveAdminApp` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackAdminApp<HasTokenStore extends boolean = boolean, ProjectId extends string = string> = (\n & AsyncStoreProperty<\"project\", [], AdminProject, false>\n & AsyncStoreProperty<\"internalApiKeys\", [], InternalApiKey[], true>\n & AsyncStoreProperty<\"teamPermissionDefinitions\", [], AdminTeamPermissionDefinition[], true>\n & AsyncStoreProperty<\"projectPermissionDefinitions\", [], AdminProjectPermissionDefinition[], true>\n & AsyncStoreProperty<\"emailThemes\", [], { id: string, displayName: string }[], true>\n & AsyncStoreProperty<\"emailPreview\", [{ themeId?: string | null | false, themeTsxSource?: string, templateId?: string, templateTsxSource?: string }], string, false>\n & AsyncStoreProperty<\"emailTemplates\", [], { id: string, displayName: string, themeId?: string, tsxSource: string }[], true>\n & AsyncStoreProperty<\"emailDrafts\", [], { id: string, displayName: string, themeId: string | undefined | false, tsxSource: string, sentAt: Date | null }[], true>\n & AsyncStoreProperty<\"stripeAccountInfo\", [], { account_id: string, charges_enabled: boolean, details_submitted: boolean, payouts_enabled: boolean } | null, false>\n & AsyncStoreProperty<\n \"transactions\",\n [{\n cursor?: string,\n limit?: number,\n type?: TransactionType,\n customerType?: 'user' | 'team' | 'custom',\n customerId?: string,\n }],\n { transactions: Transaction[], nextCursor: string | null },\n true\n >\n & {\n createInternalApiKey(options: InternalApiKeyCreateOptions): Promise<InternalApiKeyFirstView>,\n\n createTeamPermissionDefinition(data: AdminTeamPermissionDefinitionCreateOptions): Promise<AdminTeamPermission>,\n updateTeamPermissionDefinition(permissionId: string, data: AdminTeamPermissionDefinitionUpdateOptions): Promise<void>,\n deleteTeamPermissionDefinition(permissionId: string): Promise<void>,\n /**\n * @param options.query Free-text search; matches against permission ID and description.\n */\n listTeamPermissionDefinitionsPaginated(options: { limit: number, cursor?: string, query?: string }): Promise<{ items: AdminTeamPermissionDefinition[], nextCursor: string | null }>,\n\n createProjectPermissionDefinition(data: AdminProjectPermissionDefinitionCreateOptions): Promise<AdminProjectPermission>,\n updateProjectPermissionDefinition(permissionId: string, data: AdminProjectPermissionDefinitionUpdateOptions): Promise<void>,\n deleteProjectPermissionDefinition(permissionId: string): Promise<void>,\n\n\n sendTestEmail(options: {\n recipientEmail: string,\n emailConfig: EmailConfig,\n }): Promise<Result<undefined, { errorMessage: string }>>,\n\n sendTestWebhook(options: { endpointId: string }): Promise<Result<undefined, { errorMessage: string }>>,\n\n sendSignInInvitationEmail(email: string, callbackUrl: string): Promise<void>,\n\n listSentEmails(): Promise<AdminSentEmail[]>,\n setupManagedEmailProvider(options: { subdomain: string, senderLocalPart: string }): Promise<ManagedEmailProviderSetupResult>,\n checkManagedEmailStatus(options: { domainId: string, subdomain: string, senderLocalPart: string }): Promise<ManagedEmailProviderStatus>,\n listManagedEmailDomains(): Promise<ManagedEmailProviderListItem[]>,\n applyManagedEmailProvider(options: { domainId: string }): Promise<{ status: \"applied\" }>,\n deleteManagedEmailDomain(options: { resendDomainId: string }): Promise<{ status: \"deleted\" }>,\n\n createEmailTheme(displayName: string): Promise<{ id: string }>,\n updateEmailTheme(id: string, tsxSource: string): Promise<void>,\n deleteEmailTheme(id: string): Promise<void>,\n saveChatMessage(threadId: string, message: any): Promise<void>,\n listChatMessages(threadId: string): Promise<{ messages: Array<any> }>,\n rewriteTemplateSourceWithAI(templateTsxSource: string): Promise<{ tsxSource: string }>,\n updateEmailTemplate(id: string, tsxSource: string, themeId: string | null | false): Promise<{ renderedHtml: string }>,\n createEmailTemplate(displayName: string): Promise<{ id: string }>,\n deleteEmailTemplate(id: string): Promise<void>,\n\n setupPayments(): Promise<{ url: string }>,\n createStripeWidgetAccountSession(): Promise<{ client_secret: string }>,\n getPaymentMethodConfigs(): Promise<{ configId: string, methods: Array<{ id: string, name: string, enabled: boolean, available: boolean, overridable: boolean }> } | null>,\n updatePaymentMethodConfigs(configId: string, updates: Record<string, 'on' | 'off'>): Promise<void>,\n createEmailDraft(options: { displayName: string, themeId?: string | undefined | false, tsxSource?: string }): Promise<{ id: string }>,\n updateEmailDraft(id: string, data: { displayName?: string, themeId?: string | undefined | false, tsxSource?: string }): Promise<void>,\n deleteEmailDraft(id: string): Promise<void>,\n refreshEmailDrafts(): Promise<void>,\n createItemQuantityChange(options: (\n { userId: string, itemId: string, quantity: number, expiresAt?: string, description?: string } |\n { teamId: string, itemId: string, quantity: number, expiresAt?: string, description?: string } |\n { customCustomerId: string, itemId: string, quantity: number, expiresAt?: string, description?: string }\n )): Promise<void>,\n refundTransaction(options: {\n type: \"subscription\" | \"one-time-purchase\",\n id: string,\n invoiceId?: string,\n amountUsd: MoneyAmount,\n endAction?: \"now\" | \"at-period-end\",\n }): Promise<{ refundTransactionId: string }>,\n queryAnalytics(options: AnalyticsQueryOptions): Promise<AnalyticsQueryResponse>,\n\n listSessionReplays(options?: ListSessionReplaysOptions): Promise<ListSessionReplaysResult>,\n getSessionReplay(sessionReplayId: string): Promise<AdminSessionReplay>,\n listSessionReplayChunks(sessionReplayId: string, options?: ListSessionReplayChunksOptions): Promise<ListSessionReplayChunksResult>,\n getSessionReplayChunkEvents(sessionReplayId: string, chunkId: string): Promise<AdminGetSessionReplayChunkEventsResponse>,\n getSessionReplayEvents(sessionReplayId: string, options?: { offset?: number, limit?: number }): Promise<SessionReplayAllEventsResult>,\n\n // Email Outbox methods\n listOutboxEmails(options?: EmailOutboxListOptions): Promise<EmailOutboxListResult>,\n getOutboxEmail(id: string): Promise<AdminEmailOutbox>,\n updateOutboxEmail(id: string, options: EmailOutboxUpdateOptions): Promise<AdminEmailOutbox>,\n pauseOutboxEmail(id: string): Promise<AdminEmailOutbox>,\n unpauseOutboxEmail(id: string): Promise<AdminEmailOutbox>,\n cancelOutboxEmail(id: string): Promise<AdminEmailOutbox>,\n }\n & StackServerApp<HasTokenStore, ProjectId>\n);\n/** @deprecated Use `HexclaveAdminAppConstructor` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackAdminAppConstructor = {\n new <\n HasTokenStore extends boolean,\n ProjectId extends string\n >(options: StackAdminAppConstructorOptions<HasTokenStore, ProjectId>): StackAdminApp<HasTokenStore, ProjectId>,\n new(options: StackAdminAppConstructorOptions<boolean, string>): StackAdminApp<boolean, string>,\n};\nexport type HexclaveAdminAppConstructorOptions<HasTokenStore extends boolean, ProjectId extends string> = StackAdminAppConstructorOptions<HasTokenStore, ProjectId>;\nexport type HexclaveAdminApp<HasTokenStore extends boolean = boolean, ProjectId extends string = string> = StackAdminApp<HasTokenStore, ProjectId>;\nexport type HexclaveAdminAppConstructor = StackAdminAppConstructor;\nexport const HexclaveAdminApp: HexclaveAdminAppConstructor = _StackAdminAppImpl;\n/** @deprecated Use `HexclaveAdminApp` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport const StackAdminApp: StackAdminAppConstructor = HexclaveAdminApp;\n"],"mappings":";;;AA0LA,MAAa,mBAAgD;;AAE7D,MAAa,gBAA0C"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"client-app.js","names":[],"sources":["../../../../../../src/lib/stack-app/apps/interfaces/client-app.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD 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, stackAppInternalsSymbol, 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 { _StackClientAppImpl } 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 development environments.\n *\n * Defaults to true.\n */\n devTool?: boolean,\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 disabled by default;\n * set `{ replays: { enabled: true } }` to opt in.\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 `app.urls` is static and does not include runtime redirect-back parameters.\n * For navigation, prefer `redirectToXyz()` methods (for example `redirectToSignIn()`).\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\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\n [stackAppInternalsSymbol]: {\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 getRedirectMethod(): RedirectMethod,\n redirectToUrl(url: string | URL, options?: { replace?: boolean }): Promise<void>,\n redirectToHandler(handlerName: keyof HandlerUrls, options?: RedirectToOptions): Promise<void>,\n signInWithTokens(tokens: { accessToken: string, refreshToken: string }): 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 [stackAppInternalsSymbol]: {\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 = _StackClientAppImpl;\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":";;;AAyKA,MAAa,oBAAkD;;AAE/D,MAAa,iBAA4C"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"server-app.js","names":[],"sources":["../../../../../../src/lib/stack-app/apps/interfaces/server-app.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { KnownErrors } from \"@hexclave/shared\";\nimport { Result } from \"@hexclave/shared/dist/utils/results\";\nimport type { GenericQueryCtx } from \"convex/server\";\nimport { AsyncStoreProperty, GetCurrentPartialUserOptions, GetCurrentUserOptions } from \"../../common\";\nimport { CustomerProductsList, CustomerProductsRequestOptions, InlineProduct, ServerItem } from \"../../customers\";\nimport { DataVaultStore } from \"../../data-vault\";\nimport { EmailDeliveryInfo, SendEmailOptions } from \"../../email\";\nimport { ServerListTeamsOptions, ServerListUsersOptions, ServerTeam, ServerTeamCreateOptions } from \"../../teams\";\nimport { ProjectCurrentServerUser, ServerOAuthProvider, ServerUser, ServerUserCreateOptions, SyncedPartialServerUser, TokenPartialUser } from \"../../users\";\nimport { _StackServerAppImpl } from \"../implementations\";\nimport { StackClientApp, StackClientAppConstructorOptions } from \"./client-app\";\n\n\n/** @deprecated Use `HexclaveServerAppConstructorOptions` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackServerAppConstructorOptions<HasTokenStore extends boolean, ProjectId extends string> = StackClientAppConstructorOptions<HasTokenStore, ProjectId> & {\n secretServerKey?: string,\n};\n\n/** @deprecated Use `HexclaveServerApp` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackServerApp<HasTokenStore extends boolean = boolean, ProjectId extends string = string> = (\n & {\n createTeam(data: ServerTeamCreateOptions): Promise<ServerTeam>,\n /**\n * @deprecated use `getUser()` instead\n */\n getServerUser(): Promise<ProjectCurrentServerUser<ProjectId> | null>,\n\n createUser(options: ServerUserCreateOptions): Promise<ServerUser>,\n grantProduct(options: (\n ({ userId: string } | { teamId: string } | { customCustomerId: string }) &\n ({ productId: string } | { product: InlineProduct }) &\n { quantity?: number }\n )): Promise<void>,\n\n\n getUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'redirect' }): Promise<ProjectCurrentServerUser<ProjectId>>,\n getUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'throw' }): Promise<ProjectCurrentServerUser<ProjectId>>,\n getUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'anonymous' }): Promise<ProjectCurrentServerUser<ProjectId>>,\n getUser(options?: GetCurrentUserOptions<HasTokenStore>): Promise<ProjectCurrentServerUser<ProjectId> | null>,\n getUser(id: string): Promise<ServerUser | null>,\n getUser(options: { apiKey: string, or?: \"return-null\" | \"anonymous\" }): Promise<ServerUser | null>,\n getUser(options: { from: \"convex\", ctx: GenericQueryCtx<any>, or?: \"return-null\" | \"anonymous\" }): Promise<ServerUser | null>,\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<SyncedPartialServerUser | TokenPartialUser | null>,\n getTeam(id: string): Promise<ServerTeam | null>,\n getTeam(options: { apiKey: string }): Promise<ServerTeam | null>,\n\n\n listUsers(options?: ServerListUsersOptions): Promise<ServerUser[] & { nextCursor: string | null }>,\n\n /**\n * Returns every direct (or recursive) team permission grant for every\n * member of the given team in one request. Use this instead of calling\n * `user.listPermissions(team)` per row when rendering a roster — that\n * pattern produces an N+1 over the team-member endpoint.\n */\n listTeamMemberPermissions(teamId: string, options?: { recursive?: boolean }): Promise<{ userId: string, permissionId: string }[]>,\n\n // TODO this should actually be on ServerUser\n createOAuthProvider(options: {\n userId: string,\n accountId: string,\n providerConfigId: string,\n email: string,\n allowSignIn: boolean,\n allowConnectedAccounts: boolean,\n }): Promise<Result<ServerOAuthProvider, InstanceType<typeof KnownErrors.OAuthProviderAccountIdAlreadyUsedForSignIn>>>,\n\n sendEmail(options: SendEmailOptions): Promise<void>,\n\n getEmailDeliveryStats(): Promise<EmailDeliveryInfo>,\n\n activateEmailCapacityBoost(): Promise<void>,\n }\n & AsyncStoreProperty<\"user\", [id: string], ServerUser | null, false>\n & Omit<AsyncStoreProperty<\"users\", [], ServerUser[], true>, \"listUsers\" | \"useUsers\">\n & AsyncStoreProperty<\"teams\", [options?: ServerListTeamsOptions], ServerTeam[] & { nextCursor: string | null }, true>\n & AsyncStoreProperty<\"dataVaultStore\", [id: string], DataVaultStore, false>\n & AsyncStoreProperty<\n \"item\",\n [{ itemId: string, userId: string } | { itemId: string, teamId: string } | { itemId: string, customCustomerId: string }],\n ServerItem,\n false\n >\n & AsyncStoreProperty<\n \"products\",\n [options: CustomerProductsRequestOptions],\n CustomerProductsList,\n true\n >\n & StackClientApp<HasTokenStore, ProjectId>\n);\n/** @deprecated Use `HexclaveServerAppConstructor` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackServerAppConstructor = {\n new <\n TokenStoreType extends string,\n HasTokenStore extends (TokenStoreType extends {} ? true : boolean),\n ProjectId extends string\n >(options: StackServerAppConstructorOptions<HasTokenStore, ProjectId>): StackServerApp<HasTokenStore, ProjectId>,\n new (options: StackServerAppConstructorOptions<boolean, string>): StackServerApp<boolean, string>,\n};\nexport type HexclaveServerAppConstructorOptions<HasTokenStore extends boolean, ProjectId extends string> = StackServerAppConstructorOptions<HasTokenStore, ProjectId>;\nexport type HexclaveServerApp<HasTokenStore extends boolean = boolean, ProjectId extends string = string> = StackServerApp<HasTokenStore, ProjectId>;\nexport type HexclaveServerAppConstructor = StackServerAppConstructor;\nexport const HexclaveServerApp: HexclaveServerAppConstructor = _StackServerAppImpl;\n/** @deprecated Use `HexclaveServerApp` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport const StackServerApp: StackServerAppConstructor = HexclaveServerApp;\n"],"mappings":";;;AA+GA,MAAa,oBAAkD;;AAE/D,MAAa,iBAA4C"}
@@ -1,7 +0,0 @@
1
- //#region src/lib/stack-app/common.ts
2
- /** @internal */
3
- const stackAppInternalsSymbol = Symbol.for("StackAuth--DO-NOT-USE-OR-YOU-WILL-BE-FIRED--StackAppInternals");
4
-
5
- //#endregion
6
- export { stackAppInternalsSymbol };
7
- //# sourceMappingURL=common.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"common.js","names":[],"sources":["../../../../src/lib/stack-app/common.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { ProviderType } from \"@hexclave/shared/dist/utils/oauth\";\nimport type { GenericQueryCtx, UserIdentity } from \"convex/server\";\nexport type {\n DefaultHandlerUrlTarget,\n HandlerPageUrls,\n HandlerRedirectUrls,\n HandlerUrlOptions,\n HandlerUrlTarget,\n HandlerUrls,\n ResolvedHandlerUrls,\n} from \"@hexclave/shared/dist/interface/handler-urls\";\n\nexport type RedirectToOptions = {\n replace?: boolean,\n noRedirectBack?: boolean,\n};\n\nexport type AsyncStoreProperty<Name extends string, Args extends any[], Value, IsMultiple extends boolean> =\n & { [key in `${IsMultiple extends true ? \"list\" : \"get\"}${Capitalize<Name>}`]: (...args: Args) => Promise<Value> }\n\nexport type EmailConfig = {\n host: string,\n port: number,\n username: string,\n password: string,\n senderEmail: string,\n senderName: string,\n}\n\nexport type RedirectMethod = \"window\"\n | \"none\"\n | {\n useNavigate: () => (to: string) => void,\n navigate?: (to: string) => void,\n }\n\n\nexport type GetCurrentUserOptions<HasTokenStore> =\n & {\n or?: 'redirect' | 'throw' | 'return-null' | 'anonymous' | /** @deprecated */ 'anonymous-if-exists[deprecated]',\n /**\n * Whether to include restricted users (users who haven't completed onboarding requirements like email verification).\n * By default, restricted users are filtered out (treated similar to anonymous users).\n *\n * Note: This option cannot be set to false when `or: 'anonymous'` is used, as all anonymous users are also restricted.\n *\n * @default false\n */\n includeRestricted?: boolean,\n tokenStore?: TokenStoreInit,\n }\n & (HasTokenStore extends false ? {\n tokenStore: TokenStoreInit,\n } : {});\n\nexport type ConvexCtx =\n| GenericQueryCtx<any>\n| { auth: { getUserIdentity: () => Promise<UserIdentity | null> } };\n\nexport type GetCurrentPartialUserOptions<HasTokenStore> =\n & {\n or?: 'return-null' | 'anonymous-if-exists', // note: unlike normal getUser, 'anonymous' still returns null sometimes (eg. if no token is present)\n tokenStore?: TokenStoreInit,\n }\n & (\n | {\n from: 'token',\n }\n | {\n from: 'convex',\n ctx: ConvexCtx,\n }\n )\n & (HasTokenStore extends false ? {\n tokenStore: TokenStoreInit,\n } : {});\n\nexport type RequestLike = {\n headers:\n | {\n get: (name: string) => string | null,\n }\n | Record<string, string | null>,\n};\n\nexport type TokenStoreInit<HasTokenStore extends boolean = boolean> =\n HasTokenStore extends true ? (\n | \"cookie\"\n | \"nextjs-cookie\"\n | \"memory\"\n | RequestLike\n | { accessToken: string, refreshToken: string }\n )\n : HasTokenStore extends false ? null\n : TokenStoreInit<true> | TokenStoreInit<false>;\n\nexport type OAuthScopesOnSignIn = {\n [key in ProviderType]: string[];\n};\n\n/**\n * Contains the authentication methods without session-related fields.\n * Used for apps that have token storage capabilities.\n */\nexport type AuthLike<ExtraOptions = {}> = {\n signOut(options?: { redirectUrl?: URL | string } & ExtraOptions): Promise<void>,\n signOut(options?: { redirectUrl?: URL | string }): Promise<void>,\n\n /**\n * Returns the current access token, or null if the user is not signed in.\n *\n * The access token is a short-lived JWT that can be used to authenticate requests to external servers.\n * It will be automatically refreshed when it expires.\n */\n getAccessToken(options?: {} & ExtraOptions): Promise<string | null>,\n\n /**\n * Returns the current refresh token, or null if the user is not signed in.\n *\n * The refresh token is a long-lived token that can be used to obtain new access tokens.\n * It should be kept secret and never exposed to the client.\n */\n getRefreshToken(options?: {} & ExtraOptions): Promise<string | null>,\n\n /**\n * Returns the value for the HTTP `Authorization` header for authenticated requests to external servers.\n * Most commonly used in cross-origin requests. Similar to `getAuthJson`, but specifically for HTTP requests.\n *\n * If you are using `tokenStore: \"cookie\"`, you don't need this for same-origin requests. However, most\n * browsers now disable third-party cookies by default, so we must pass authentication tokens by header instead\n * if the client and server are on different origins.\n *\n * This function returns the header value in this format:\n * `Bearer stackauth_<base64(getAuthJson())>`, or `null` if the user is not signed in.\n * You can use this with `fetch` or other HTTP request libraries to send authenticated requests.\n *\n * On the server, you can then pass in the `Request` object to the `tokenStore` option\n * of your Stack app. Please note that CORS does not allow most headers by default, so you\n * must include `authorization` in the [`Access-Control-Allow-Headers` header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers)\n * of the CORS preflight response.\n *\n * If you are not using HTTP (and hence cannot set headers), use `getAuthJson()` instead.\n *\n * Example:\n *\n * ```ts\n * // client\n * const authorizationHeader = await stackApp.getAuthorizationHeader();\n * const res = await fetch(\"https://api.example.com\", {\n * headers: {\n * ...(authorizationHeader ? { Authorization: authorizationHeader } : {})\n * // you can also add your own headers here\n * },\n * });\n *\n * // server\n * function handleRequest(req: Request) {\n * const user = await stackServerApp.getUser({ tokenStore: req });\n * return new Response(\"Welcome, \" + user.displayName);\n * }\n * ```\n */\n getAuthorizationHeader(options?: {} & ExtraOptions): Promise<string | null>,\n\n /**\n * @deprecated Use `getAuthorizationHeader()` instead.\n *\n * Returns the legacy `x-stack-auth` headers for authenticated HTTP requests. This remains for backwards\n * compatibility with existing integrations.\n */\n getAuthHeaders(options?: {} & ExtraOptions): Promise<{ \"x-stack-auth\": string }>,\n /** @deprecated Use `useAuthorizationHeader()` instead. */\n\n /**\n * Creates a JSON-serializable object containing the information to authenticate a user on an external server.\n * Similar to `getAuthorizationHeader`, but returns an object that can be sent over any protocol instead of just\n * HTTP headers.\n *\n * While `getAuthorizationHeader` is the recommended way to send authentication tokens over HTTP, your app may use\n * a different protocol, for example WebSockets or gRPC. This function returns a token object that can be JSON-serialized and sent to the server in any way you like.\n *\n * On the server, you can pass in this token object into the `tokenStore` option to fetch user details.\n *\n * Example:\n *\n * ```ts\n * // client\n * const res = await rpcCall(rpcEndpoint, {\n * data: {\n * auth: await stackApp.getAuthJson(),\n * },\n * });\n *\n * // server\n * function handleRequest(data) {\n * const user = await stackServerApp.getUser({ tokenStore: data.auth });\n * return new Response(\"Welcome, \" + user.displayName);\n * }\n * ```\n */\n getAuthJson(options?: {} & ExtraOptions): Promise<{ accessToken: string | null, refreshToken: string | null }>,\n};\n\n/** @internal */\nexport const stackAppInternalsSymbol = Symbol.for(\"StackAuth--DO-NOT-USE-OR-YOU-WILL-BE-FIRED--StackAppInternals\");\n"],"mappings":";;AAgNA,MAAa,0BAA0B,OAAO,IAAI,gEAAgE"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../../../src/lib/stack-app/contact-channels/index.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { ContactChannelsCrud } from \"@hexclave/shared/dist/interface/crud/contact-channels\";\n\n\nexport type ContactChannel = {\n id: string,\n value: string,\n type: 'email',\n isPrimary: boolean,\n isVerified: boolean,\n usedForAuth: boolean,\n\n sendVerificationEmail(options?: { callbackUrl?: string }): Promise<void>,\n update(data: ContactChannelUpdateOptions): Promise<void>,\n delete(): Promise<void>,\n}\n\nexport type ContactChannelCreateOptions = {\n value: string,\n type: 'email',\n usedForAuth: boolean,\n isPrimary?: boolean,\n}\n\nexport function contactChannelCreateOptionsToCrud(userId: string, options: ContactChannelCreateOptions): ContactChannelsCrud[\"Client\"][\"Create\"] {\n return {\n value: options.value,\n type: options.type,\n used_for_auth: options.usedForAuth,\n is_primary: options.isPrimary,\n user_id: userId,\n };\n}\n\nexport type ContactChannelUpdateOptions = {\n usedForAuth?: boolean,\n value?: string,\n isPrimary?: boolean,\n}\n\nexport function contactChannelUpdateOptionsToCrud(options: ContactChannelUpdateOptions): ContactChannelsCrud[\"Client\"][\"Update\"] {\n return {\n value: options.value,\n used_for_auth: options.usedForAuth,\n is_primary: options.isPrimary,\n };\n}\n\nexport type ServerContactChannel = ContactChannel & {\n update(data: ServerContactChannelUpdateOptions): Promise<void>,\n}\nexport type ServerContactChannelUpdateOptions = ContactChannelUpdateOptions & {\n isVerified?: boolean,\n}\n\nexport function serverContactChannelUpdateOptionsToCrud(options: ServerContactChannelUpdateOptions): ContactChannelsCrud[\"Server\"][\"Update\"] {\n return {\n value: options.value,\n is_verified: options.isVerified,\n used_for_auth: options.usedForAuth,\n is_primary: options.isPrimary,\n };\n}\n\nexport type ServerContactChannelCreateOptions = ContactChannelCreateOptions & {\n isVerified?: boolean,\n}\nexport function serverContactChannelCreateOptionsToCrud(userId: string, options: ServerContactChannelCreateOptions): ContactChannelsCrud[\"Server\"][\"Create\"] {\n return {\n type: options.type,\n value: options.value,\n is_verified: options.isVerified,\n user_id: userId,\n used_for_auth: options.usedForAuth,\n is_primary: options.isPrimary,\n };\n}\n"],"mappings":";AA2BA,SAAgB,kCAAkC,QAAgB,SAA+E;AAC/I,QAAO;EACL,OAAO,QAAQ;EACf,MAAM,QAAQ;EACd,eAAe,QAAQ;EACvB,YAAY,QAAQ;EACpB,SAAS;EACV;;AASH,SAAgB,kCAAkC,SAA+E;AAC/H,QAAO;EACL,OAAO,QAAQ;EACf,eAAe,QAAQ;EACvB,YAAY,QAAQ;EACrB;;AAUH,SAAgB,wCAAwC,SAAqF;AAC3I,QAAO;EACL,OAAO,QAAQ;EACf,aAAa,QAAQ;EACrB,eAAe,QAAQ;EACvB,YAAY,QAAQ;EACrB;;AAMH,SAAgB,wCAAwC,QAAgB,SAAqF;AAC3J,QAAO;EACL,MAAM,QAAQ;EACd,OAAO,QAAQ;EACf,aAAa,QAAQ;EACrB,SAAS;EACT,eAAe,QAAQ;EACvB,YAAY,QAAQ;EACrB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../../../src/lib/stack-app/email-templates/index.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { EmailTemplateCrud, EmailTemplateType } from \"@hexclave/shared/dist/interface/crud/email-templates\";\n\n\nexport type AdminEmailTemplate = {\n type: EmailTemplateType,\n subject: string,\n content: any,\n isDefault: boolean,\n}\n\nexport type AdminEmailTemplateUpdateOptions = {\n subject?: string,\n content?: any,\n};\nexport function adminEmailTemplateUpdateOptionsToCrud(options: AdminEmailTemplateUpdateOptions): EmailTemplateCrud['Admin']['Update'] {\n return {\n subject: options.subject,\n content: options.content,\n };\n}\n"],"mappings":";AAkBA,SAAgB,sCAAsC,SAAgF;AACpI,QAAO;EACL,SAAS,QAAQ;EACjB,SAAS,QAAQ;EAClB"}