@stackframe/react 2.7.20

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 (316) hide show
  1. package/CHANGELOG.md +1415 -0
  2. package/LICENSE +7 -0
  3. package/README.md +26 -0
  4. package/dist/components/credential-sign-in.d.mts +5 -0
  5. package/dist/components/credential-sign-in.d.ts +5 -0
  6. package/dist/components/credential-sign-in.js +103 -0
  7. package/dist/components/credential-sign-in.js.map +1 -0
  8. package/dist/components/credential-sign-up.d.mts +7 -0
  9. package/dist/components/credential-sign-up.d.ts +7 -0
  10. package/dist/components/credential-sign-up.js +138 -0
  11. package/dist/components/credential-sign-up.js.map +1 -0
  12. package/dist/components/elements/form-warning.d.mts +7 -0
  13. package/dist/components/elements/form-warning.d.ts +7 -0
  14. package/dist/components/elements/form-warning.js +39 -0
  15. package/dist/components/elements/form-warning.js.map +1 -0
  16. package/dist/components/elements/maybe-full-page.d.mts +11 -0
  17. package/dist/components/elements/maybe-full-page.d.ts +11 -0
  18. package/dist/components/elements/maybe-full-page.js +74 -0
  19. package/dist/components/elements/maybe-full-page.js.map +1 -0
  20. package/dist/components/elements/separator-with-text.d.mts +7 -0
  21. package/dist/components/elements/separator-with-text.d.ts +7 -0
  22. package/dist/components/elements/separator-with-text.js +41 -0
  23. package/dist/components/elements/separator-with-text.js.map +1 -0
  24. package/dist/components/elements/sidebar-layout.d.mts +19 -0
  25. package/dist/components/elements/sidebar-layout.d.ts +19 -0
  26. package/dist/components/elements/sidebar-layout.js +126 -0
  27. package/dist/components/elements/sidebar-layout.js.map +1 -0
  28. package/dist/components/elements/ssr-layout-effect.d.mts +8 -0
  29. package/dist/components/elements/ssr-layout-effect.d.ts +8 -0
  30. package/dist/components/elements/ssr-layout-effect.js +47 -0
  31. package/dist/components/elements/ssr-layout-effect.js.map +1 -0
  32. package/dist/components/elements/user-avatar.d.mts +13 -0
  33. package/dist/components/elements/user-avatar.d.ts +13 -0
  34. package/dist/components/elements/user-avatar.js +41 -0
  35. package/dist/components/elements/user-avatar.js.map +1 -0
  36. package/dist/components/iframe-preventer.d.mts +8 -0
  37. package/dist/components/iframe-preventer.d.ts +8 -0
  38. package/dist/components/iframe-preventer.js +52 -0
  39. package/dist/components/iframe-preventer.js.map +1 -0
  40. package/dist/components/link.d.mts +14 -0
  41. package/dist/components/link.d.ts +14 -0
  42. package/dist/components/link.js +51 -0
  43. package/dist/components/link.js.map +1 -0
  44. package/dist/components/magic-link-sign-in.d.mts +5 -0
  45. package/dist/components/magic-link-sign-in.d.ts +5 -0
  46. package/dist/components/magic-link-sign-in.js +151 -0
  47. package/dist/components/magic-link-sign-in.js.map +1 -0
  48. package/dist/components/message-cards/known-error-message-card.d.mts +9 -0
  49. package/dist/components/message-cards/known-error-message-card.d.ts +9 -0
  50. package/dist/components/message-cards/known-error-message-card.js +61 -0
  51. package/dist/components/message-cards/known-error-message-card.js.map +1 -0
  52. package/dist/components/message-cards/message-card.d.mts +14 -0
  53. package/dist/components/message-cards/message-card.d.ts +14 -0
  54. package/dist/components/message-cards/message-card.js +45 -0
  55. package/dist/components/message-cards/message-card.js.map +1 -0
  56. package/dist/components/message-cards/predefined-message-card.d.mts +8 -0
  57. package/dist/components/message-cards/predefined-message-card.d.ts +8 -0
  58. package/dist/components/message-cards/predefined-message-card.js +107 -0
  59. package/dist/components/message-cards/predefined-message-card.js.map +1 -0
  60. package/dist/components/oauth-button-group.d.mts +14 -0
  61. package/dist/components/oauth-button-group.d.ts +14 -0
  62. package/dist/components/oauth-button-group.js +43 -0
  63. package/dist/components/oauth-button-group.js.map +1 -0
  64. package/dist/components/oauth-button.d.mts +8 -0
  65. package/dist/components/oauth-button.d.ts +8 -0
  66. package/dist/components/oauth-button.js +210 -0
  67. package/dist/components/oauth-button.js.map +1 -0
  68. package/dist/components/passkey-button.d.mts +7 -0
  69. package/dist/components/passkey-button.d.ts +7 -0
  70. package/dist/components/passkey-button.js +58 -0
  71. package/dist/components/passkey-button.js.map +1 -0
  72. package/dist/components/profile-image-editor.d.mts +11 -0
  73. package/dist/components/profile-image-editor.d.ts +11 -0
  74. package/dist/components/profile-image-editor.js +162 -0
  75. package/dist/components/profile-image-editor.js.map +1 -0
  76. package/dist/components/selected-team-switcher.d.mts +21 -0
  77. package/dist/components/selected-team-switcher.d.ts +21 -0
  78. package/dist/components/selected-team-switcher.js +119 -0
  79. package/dist/components/selected-team-switcher.js.map +1 -0
  80. package/dist/components/team-icon.d.mts +18 -0
  81. package/dist/components/team-icon.d.ts +18 -0
  82. package/dist/components/team-icon.js +39 -0
  83. package/dist/components/team-icon.js.map +1 -0
  84. package/dist/components/user-button.d.mts +15 -0
  85. package/dist/components/user-button.d.ts +15 -0
  86. package/dist/components/user-button.js +120 -0
  87. package/dist/components/user-button.js.map +1 -0
  88. package/dist/components-page/account-settings.d.mts +24 -0
  89. package/dist/components-page/account-settings.d.ts +24 -0
  90. package/dist/components-page/account-settings.js +1095 -0
  91. package/dist/components-page/account-settings.js.map +1 -0
  92. package/dist/components-page/auth-page.d.mts +24 -0
  93. package/dist/components-page/auth-page.d.ts +24 -0
  94. package/dist/components-page/auth-page.js +123 -0
  95. package/dist/components-page/auth-page.js.map +1 -0
  96. package/dist/components-page/email-verification.d.mts +8 -0
  97. package/dist/components-page/email-verification.d.ts +8 -0
  98. package/dist/components-page/email-verification.js +100 -0
  99. package/dist/components-page/email-verification.js.map +1 -0
  100. package/dist/components-page/error-page.d.mts +8 -0
  101. package/dist/components-page/error-page.d.ts +8 -0
  102. package/dist/components-page/error-page.js +97 -0
  103. package/dist/components-page/error-page.js.map +1 -0
  104. package/dist/components-page/forgot-password.d.mts +10 -0
  105. package/dist/components-page/forgot-password.d.ts +10 -0
  106. package/dist/components-page/forgot-password.js +117 -0
  107. package/dist/components-page/forgot-password.js.map +1 -0
  108. package/dist/components-page/magic-link-callback.d.mts +8 -0
  109. package/dist/components-page/magic-link-callback.d.ts +8 -0
  110. package/dist/components-page/magic-link-callback.js +110 -0
  111. package/dist/components-page/magic-link-callback.js.map +1 -0
  112. package/dist/components-page/oauth-callback.d.mts +7 -0
  113. package/dist/components-page/oauth-callback.d.ts +7 -0
  114. package/dist/components-page/oauth-callback.js +75 -0
  115. package/dist/components-page/oauth-callback.js.map +1 -0
  116. package/dist/components-page/password-reset.d.mts +12 -0
  117. package/dist/components-page/password-reset.d.ts +12 -0
  118. package/dist/components-page/password-reset.js +179 -0
  119. package/dist/components-page/password-reset.js.map +1 -0
  120. package/dist/components-page/sign-in.d.mts +10 -0
  121. package/dist/components-page/sign-in.d.ts +10 -0
  122. package/dist/components-page/sign-in.js +44 -0
  123. package/dist/components-page/sign-in.js.map +1 -0
  124. package/dist/components-page/sign-out.d.mts +7 -0
  125. package/dist/components-page/sign-out.d.ts +7 -0
  126. package/dist/components-page/sign-out.js +57 -0
  127. package/dist/components-page/sign-out.js.map +1 -0
  128. package/dist/components-page/sign-up.d.mts +11 -0
  129. package/dist/components-page/sign-up.d.ts +11 -0
  130. package/dist/components-page/sign-up.js +47 -0
  131. package/dist/components-page/sign-up.js.map +1 -0
  132. package/dist/components-page/stack-handler.d.mts +51 -0
  133. package/dist/components-page/stack-handler.d.ts +51 -0
  134. package/dist/components-page/stack-handler.js +244 -0
  135. package/dist/components-page/stack-handler.js.map +1 -0
  136. package/dist/components-page/team-creation.d.mts +7 -0
  137. package/dist/components-page/team-creation.d.ts +7 -0
  138. package/dist/components-page/team-creation.js +92 -0
  139. package/dist/components-page/team-creation.js.map +1 -0
  140. package/dist/components-page/team-invitation.d.mts +8 -0
  141. package/dist/components-page/team-invitation.d.ts +8 -0
  142. package/dist/components-page/team-invitation.js +144 -0
  143. package/dist/components-page/team-invitation.js.map +1 -0
  144. package/dist/esm/components/credential-sign-in.js +79 -0
  145. package/dist/esm/components/credential-sign-in.js.map +1 -0
  146. package/dist/esm/components/credential-sign-up.js +104 -0
  147. package/dist/esm/components/credential-sign-up.js.map +1 -0
  148. package/dist/esm/components/elements/form-warning.js +15 -0
  149. package/dist/esm/components/elements/form-warning.js.map +1 -0
  150. package/dist/esm/components/elements/maybe-full-page.js +50 -0
  151. package/dist/esm/components/elements/maybe-full-page.js.map +1 -0
  152. package/dist/esm/components/elements/separator-with-text.js +17 -0
  153. package/dist/esm/components/elements/separator-with-text.js.map +1 -0
  154. package/dist/esm/components/elements/sidebar-layout.js +102 -0
  155. package/dist/esm/components/elements/sidebar-layout.js.map +1 -0
  156. package/dist/esm/components/elements/ssr-layout-effect.js +23 -0
  157. package/dist/esm/components/elements/ssr-layout-effect.js.map +1 -0
  158. package/dist/esm/components/elements/user-avatar.js +16 -0
  159. package/dist/esm/components/elements/user-avatar.js.map +1 -0
  160. package/dist/esm/components/iframe-preventer.js +28 -0
  161. package/dist/esm/components/iframe-preventer.js.map +1 -0
  162. package/dist/esm/components/link.js +26 -0
  163. package/dist/esm/components/link.js.map +1 -0
  164. package/dist/esm/components/magic-link-sign-in.js +127 -0
  165. package/dist/esm/components/magic-link-sign-in.js.map +1 -0
  166. package/dist/esm/components/message-cards/known-error-message-card.js +37 -0
  167. package/dist/esm/components/message-cards/known-error-message-card.js.map +1 -0
  168. package/dist/esm/components/message-cards/message-card.js +21 -0
  169. package/dist/esm/components/message-cards/message-card.js.map +1 -0
  170. package/dist/esm/components/message-cards/predefined-message-card.js +83 -0
  171. package/dist/esm/components/message-cards/predefined-message-card.js.map +1 -0
  172. package/dist/esm/components/oauth-button-group.js +19 -0
  173. package/dist/esm/components/oauth-button-group.js.map +1 -0
  174. package/dist/esm/components/oauth-button.js +176 -0
  175. package/dist/esm/components/oauth-button.js.map +1 -0
  176. package/dist/esm/components/passkey-button.js +34 -0
  177. package/dist/esm/components/passkey-button.js.map +1 -0
  178. package/dist/esm/components/profile-image-editor.js +126 -0
  179. package/dist/esm/components/profile-image-editor.js.map +1 -0
  180. package/dist/esm/components/selected-team-switcher.js +107 -0
  181. package/dist/esm/components/selected-team-switcher.js.map +1 -0
  182. package/dist/esm/components/team-icon.js +14 -0
  183. package/dist/esm/components/team-icon.js.map +1 -0
  184. package/dist/esm/components/user-button.js +96 -0
  185. package/dist/esm/components/user-button.js.map +1 -0
  186. package/dist/esm/components-page/account-settings.js +1058 -0
  187. package/dist/esm/components-page/account-settings.js.map +1 -0
  188. package/dist/esm/components-page/auth-page.js +99 -0
  189. package/dist/esm/components-page/auth-page.js.map +1 -0
  190. package/dist/esm/components-page/email-verification.js +66 -0
  191. package/dist/esm/components-page/email-verification.js.map +1 -0
  192. package/dist/esm/components-page/error-page.js +73 -0
  193. package/dist/esm/components-page/error-page.js.map +1 -0
  194. package/dist/esm/components-page/forgot-password.js +92 -0
  195. package/dist/esm/components-page/forgot-password.js.map +1 -0
  196. package/dist/esm/components-page/magic-link-callback.js +76 -0
  197. package/dist/esm/components-page/magic-link-callback.js.map +1 -0
  198. package/dist/esm/components-page/oauth-callback.js +51 -0
  199. package/dist/esm/components-page/oauth-callback.js.map +1 -0
  200. package/dist/esm/components-page/password-reset.js +145 -0
  201. package/dist/esm/components-page/password-reset.js.map +1 -0
  202. package/dist/esm/components-page/sign-in.js +19 -0
  203. package/dist/esm/components-page/sign-in.js.map +1 -0
  204. package/dist/esm/components-page/sign-out.js +23 -0
  205. package/dist/esm/components-page/sign-out.js.map +1 -0
  206. package/dist/esm/components-page/sign-up.js +23 -0
  207. package/dist/esm/components-page/sign-up.js.map +1 -0
  208. package/dist/esm/components-page/stack-handler.js +223 -0
  209. package/dist/esm/components-page/stack-handler.js.map +1 -0
  210. package/dist/esm/components-page/team-creation.js +68 -0
  211. package/dist/esm/components-page/team-creation.js.map +1 -0
  212. package/dist/esm/components-page/team-invitation.js +110 -0
  213. package/dist/esm/components-page/team-invitation.js.map +1 -0
  214. package/dist/esm/generated/global-css.js +6 -0
  215. package/dist/esm/generated/global-css.js.map +1 -0
  216. package/dist/esm/generated/quetzal-translations.js +2397 -0
  217. package/dist/esm/generated/quetzal-translations.js.map +1 -0
  218. package/dist/esm/global.d.js +1 -0
  219. package/dist/esm/global.d.js.map +1 -0
  220. package/dist/esm/index.js +46 -0
  221. package/dist/esm/index.js.map +1 -0
  222. package/dist/esm/lib/auth.js +98 -0
  223. package/dist/esm/lib/auth.js.map +1 -0
  224. package/dist/esm/lib/cookie.js +244 -0
  225. package/dist/esm/lib/cookie.js.map +1 -0
  226. package/dist/esm/lib/hooks.js +30 -0
  227. package/dist/esm/lib/hooks.js.map +1 -0
  228. package/dist/esm/lib/stack-app.js +2398 -0
  229. package/dist/esm/lib/stack-app.js.map +1 -0
  230. package/dist/esm/lib/translations.js +23 -0
  231. package/dist/esm/lib/translations.js.map +1 -0
  232. package/dist/esm/providers/stack-provider-client.js +29 -0
  233. package/dist/esm/providers/stack-provider-client.js.map +1 -0
  234. package/dist/esm/providers/stack-provider.js +25 -0
  235. package/dist/esm/providers/stack-provider.js.map +1 -0
  236. package/dist/esm/providers/theme-provider.js +71 -0
  237. package/dist/esm/providers/theme-provider.js.map +1 -0
  238. package/dist/esm/providers/translation-provider-client.js +18 -0
  239. package/dist/esm/providers/translation-provider-client.js.map +1 -0
  240. package/dist/esm/providers/translation-provider.js +18 -0
  241. package/dist/esm/providers/translation-provider.js.map +1 -0
  242. package/dist/esm/utils/browser-script.js +112 -0
  243. package/dist/esm/utils/browser-script.js.map +1 -0
  244. package/dist/esm/utils/constants.js +66 -0
  245. package/dist/esm/utils/constants.js.map +1 -0
  246. package/dist/esm/utils/url.js +30 -0
  247. package/dist/esm/utils/url.js.map +1 -0
  248. package/dist/generated/global-css.d.mts +3 -0
  249. package/dist/generated/global-css.d.ts +3 -0
  250. package/dist/generated/global-css.js +31 -0
  251. package/dist/generated/global-css.js.map +1 -0
  252. package/dist/generated/quetzal-translations.d.mts +4 -0
  253. package/dist/generated/quetzal-translations.d.ts +4 -0
  254. package/dist/generated/quetzal-translations.js +2423 -0
  255. package/dist/generated/quetzal-translations.js.map +1 -0
  256. package/dist/global.d.d.mts +2 -0
  257. package/dist/global.d.d.ts +2 -0
  258. package/dist/global.d.js +2 -0
  259. package/dist/global.d.js.map +1 -0
  260. package/dist/index.d.mts +41 -0
  261. package/dist/index.d.ts +41 -0
  262. package/dist/index.js +103 -0
  263. package/dist/index.js.map +1 -0
  264. package/dist/lib/auth.d.mts +33 -0
  265. package/dist/lib/auth.d.ts +33 -0
  266. package/dist/lib/auth.js +125 -0
  267. package/dist/lib/auth.js.map +1 -0
  268. package/dist/lib/cookie.d.mts +33 -0
  269. package/dist/lib/cookie.d.ts +33 -0
  270. package/dist/lib/cookie.js +291 -0
  271. package/dist/lib/cookie.js.map +1 -0
  272. package/dist/lib/hooks.d.mts +41 -0
  273. package/dist/lib/hooks.d.ts +41 -0
  274. package/dist/lib/hooks.js +56 -0
  275. package/dist/lib/hooks.js.map +1 -0
  276. package/dist/lib/stack-app.d.mts +775 -0
  277. package/dist/lib/stack-app.d.ts +775 -0
  278. package/dist/lib/stack-app.js +2438 -0
  279. package/dist/lib/stack-app.js.map +1 -0
  280. package/dist/lib/translations.d.mts +5 -0
  281. package/dist/lib/translations.d.ts +5 -0
  282. package/dist/lib/translations.js +58 -0
  283. package/dist/lib/translations.js.map +1 -0
  284. package/dist/providers/stack-provider-client.d.mts +27 -0
  285. package/dist/providers/stack-provider-client.d.ts +27 -0
  286. package/dist/providers/stack-provider-client.js +65 -0
  287. package/dist/providers/stack-provider-client.js.map +1 -0
  288. package/dist/providers/stack-provider.d.mts +30 -0
  289. package/dist/providers/stack-provider.d.ts +30 -0
  290. package/dist/providers/stack-provider.js +46 -0
  291. package/dist/providers/stack-provider.js.map +1 -0
  292. package/dist/providers/theme-provider.d.mts +40 -0
  293. package/dist/providers/theme-provider.d.ts +40 -0
  294. package/dist/providers/theme-provider.js +105 -0
  295. package/dist/providers/theme-provider.js.map +1 -0
  296. package/dist/providers/translation-provider-client.d.mts +14 -0
  297. package/dist/providers/translation-provider-client.d.ts +14 -0
  298. package/dist/providers/translation-provider-client.js +43 -0
  299. package/dist/providers/translation-provider-client.js.map +1 -0
  300. package/dist/providers/translation-provider.d.mts +10 -0
  301. package/dist/providers/translation-provider.d.ts +10 -0
  302. package/dist/providers/translation-provider.js +43 -0
  303. package/dist/providers/translation-provider.js.map +1 -0
  304. package/dist/utils/browser-script.d.mts +7 -0
  305. package/dist/utils/browser-script.d.ts +7 -0
  306. package/dist/utils/browser-script.js +137 -0
  307. package/dist/utils/browser-script.js.map +1 -0
  308. package/dist/utils/constants.d.mts +79 -0
  309. package/dist/utils/constants.d.ts +79 -0
  310. package/dist/utils/constants.js +99 -0
  311. package/dist/utils/constants.js.map +1 -0
  312. package/dist/utils/url.d.mts +4 -0
  313. package/dist/utils/url.d.ts +4 -0
  314. package/dist/utils/url.js +56 -0
  315. package/dist/utils/url.js.map +1 -0
  316. package/package.json +96 -0
@@ -0,0 +1,2438 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/lib/stack-app.ts
31
+ var stack_app_exports = {};
32
+ __export(stack_app_exports, {
33
+ StackAdminApp: () => StackAdminApp,
34
+ StackClientApp: () => StackClientApp,
35
+ StackServerApp: () => StackServerApp,
36
+ serverTeamPermissionDefinitionCreateOptionsToCrud: () => serverTeamPermissionDefinitionCreateOptionsToCrud,
37
+ serverTeamPermissionDefinitionUpdateOptionsToCrud: () => serverTeamPermissionDefinitionUpdateOptionsToCrud,
38
+ stackAppInternalsSymbol: () => stackAppInternalsSymbol
39
+ });
40
+ module.exports = __toCommonJS(stack_app_exports);
41
+ var import_browser = require("@simplewebauthn/browser");
42
+ var import_stack_shared = require("@stackframe/stack-shared");
43
+ var import_production_mode = require("@stackframe/stack-shared/dist/helpers/production-mode");
44
+ var import_sessions = require("@stackframe/stack-shared/dist/sessions");
45
+ var import_bytes = require("@stackframe/stack-shared/dist/utils/bytes");
46
+ var import_caches = require("@stackframe/stack-shared/dist/utils/caches");
47
+ var import_env = require("@stackframe/stack-shared/dist/utils/env");
48
+ var import_errors = require("@stackframe/stack-shared/dist/utils/errors");
49
+ var import_maps = require("@stackframe/stack-shared/dist/utils/maps");
50
+ var import_objects = require("@stackframe/stack-shared/dist/utils/objects");
51
+ var import_promises = require("@stackframe/stack-shared/dist/utils/promises");
52
+ var import_react = require("@stackframe/stack-shared/dist/utils/react");
53
+ var import_results = require("@stackframe/stack-shared/dist/utils/results");
54
+ var import_stores = require("@stackframe/stack-shared/dist/utils/stores");
55
+ var import_strings = require("@stackframe/stack-shared/dist/utils/strings");
56
+ var import_urls = require("@stackframe/stack-shared/dist/utils/urls");
57
+ var import_uuids = require("@stackframe/stack-shared/dist/utils/uuids");
58
+ var cookie = __toESM(require("cookie"));
59
+ var import_react2 = __toESM(require("react"));
60
+ var import_url = require("../utils/url");
61
+ var import_auth = require("./auth");
62
+ var import_cookie = require("./cookie");
63
+ var isReactServer = false;
64
+ var clientVersion = "js @stackframe/react@2.7.20";
65
+ if (clientVersion.startsWith("STACK_COMPILE_TIME")) {
66
+ throw new import_errors.StackAssertionError("Client version was not replaced. Something went wrong during build!");
67
+ }
68
+ var process = globalThis.process ?? { env: {} };
69
+ function getUrls(partial) {
70
+ const handler = partial.handler ?? "/handler";
71
+ const home = partial.home ?? "/";
72
+ const afterSignIn = partial.afterSignIn ?? home;
73
+ return {
74
+ handler,
75
+ signIn: `${handler}/sign-in`,
76
+ afterSignIn: home,
77
+ signUp: `${handler}/sign-up`,
78
+ afterSignUp: afterSignIn,
79
+ signOut: `${handler}/sign-out`,
80
+ afterSignOut: home,
81
+ emailVerification: `${handler}/email-verification`,
82
+ passwordReset: `${handler}/password-reset`,
83
+ forgotPassword: `${handler}/forgot-password`,
84
+ oauthCallback: `${handler}/oauth-callback`,
85
+ magicLinkCallback: `${handler}/magic-link-callback`,
86
+ home,
87
+ accountSettings: `${handler}/account-settings`,
88
+ error: `${handler}/error`,
89
+ teamInvitation: `${handler}/team-invitation`,
90
+ ...(0, import_objects.filterUndefined)(partial)
91
+ };
92
+ }
93
+ function getDefaultProjectId() {
94
+ return process.env.NEXT_PUBLIC_STACK_PROJECT_ID || (0, import_errors.throwErr)(new Error("Welcome to Stack Auth! It seems that you haven't provided a project ID. Please create a project on the Stack dashboard at https://app.stack-auth.com and put it in the NEXT_PUBLIC_STACK_PROJECT_ID environment variable."));
95
+ }
96
+ function getDefaultPublishableClientKey() {
97
+ return process.env.NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY || (0, import_errors.throwErr)(new Error("Welcome to Stack Auth! It seems that you haven't provided a publishable client key. Please create an API key for your project on the Stack dashboard at https://app.stack-auth.com and copy your publishable client key into the NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY environment variable."));
98
+ }
99
+ function getDefaultSecretServerKey() {
100
+ return process.env.STACK_SECRET_SERVER_KEY || (0, import_errors.throwErr)(new Error("No secret server key provided. Please copy your key from the Stack dashboard and put your it in the STACK_SECRET_SERVER_KEY environment variable."));
101
+ }
102
+ function getDefaultSuperSecretAdminKey() {
103
+ return process.env.STACK_SUPER_SECRET_ADMIN_KEY || (0, import_errors.throwErr)(new Error("No super secret admin key provided. Please copy your key from the Stack dashboard and put it in the STACK_SUPER_SECRET_ADMIN_KEY environment variable."));
104
+ }
105
+ function getBaseUrl(userSpecifiedBaseUrl) {
106
+ let url;
107
+ if (userSpecifiedBaseUrl) {
108
+ if (typeof userSpecifiedBaseUrl === "string") {
109
+ url = userSpecifiedBaseUrl;
110
+ } else {
111
+ if ((0, import_env.isBrowserLike)()) {
112
+ url = userSpecifiedBaseUrl.browser;
113
+ } else {
114
+ url = userSpecifiedBaseUrl.server;
115
+ }
116
+ }
117
+ } else {
118
+ if ((0, import_env.isBrowserLike)()) {
119
+ url = process.env.NEXT_PUBLIC_BROWSER_STACK_API_URL;
120
+ } else {
121
+ url = process.env.NEXT_PUBLIC_SERVER_STACK_API_URL;
122
+ }
123
+ url = url || process.env.NEXT_PUBLIC_STACK_API_URL || process.env.NEXT_PUBLIC_STACK_URL || defaultBaseUrl;
124
+ }
125
+ return url.endsWith("/") ? url.slice(0, -1) : url;
126
+ }
127
+ var defaultBaseUrl = "https://api.stack-auth.com";
128
+ function createEmptyTokenStore() {
129
+ return new import_stores.Store({
130
+ refreshToken: null,
131
+ accessToken: null
132
+ });
133
+ }
134
+ var cachePromiseByComponentId = /* @__PURE__ */ new Map();
135
+ function useAsyncCache(cache, dependencies, caller) {
136
+ (0, import_react.suspendIfSsr)(caller);
137
+ const id = import_react2.default.useId();
138
+ const subscribe = (0, import_react2.useCallback)((cb) => {
139
+ const { unsubscribe } = cache.onStateChange(dependencies, () => {
140
+ cachePromiseByComponentId.delete(id);
141
+ cb();
142
+ });
143
+ return unsubscribe;
144
+ }, [cache, ...dependencies]);
145
+ const getSnapshot = (0, import_react2.useCallback)(() => {
146
+ if (!cachePromiseByComponentId.has(id)) {
147
+ cachePromiseByComponentId.set(id, cache.getOrWait(dependencies, "read-write"));
148
+ }
149
+ return cachePromiseByComponentId.get(id);
150
+ }, [cache, ...dependencies]);
151
+ const promise = import_react2.default.useSyncExternalStore(
152
+ subscribe,
153
+ getSnapshot,
154
+ () => (0, import_errors.throwErr)(new Error("getServerSnapshot should never be called in useAsyncCache because we restrict to CSR earlier"))
155
+ );
156
+ const result = import_react2.default.use(promise);
157
+ if (result.status === "error") {
158
+ const error = result.error;
159
+ if (error instanceof Error && !error.__stackHasConcatenatedStacktraces) {
160
+ (0, import_errors.concatStacktraces)(error, new Error());
161
+ error.__stackHasConcatenatedStacktraces = true;
162
+ }
163
+ throw error;
164
+ }
165
+ return result.data;
166
+ }
167
+ var stackAppInternalsSymbol = Symbol.for("StackAuth--DO-NOT-USE-OR-YOU-WILL-BE-FIRED--StackAppInternals");
168
+ var allClientApps = /* @__PURE__ */ new Map();
169
+ var createCache = (fetcher) => {
170
+ return new import_caches.AsyncCache(
171
+ async (dependencies) => await import_results.Result.fromThrowingAsync(async () => await fetcher(dependencies)),
172
+ {}
173
+ );
174
+ };
175
+ var createCacheBySession = (fetcher) => {
176
+ return new import_caches.AsyncCache(
177
+ async ([session, ...extraDependencies]) => await import_results.Result.fromThrowingAsync(async () => await fetcher(session, extraDependencies)),
178
+ {
179
+ onSubscribe: ([session], refresh) => {
180
+ const handler = session.onInvalidate(() => refresh());
181
+ return () => handler.unsubscribe();
182
+ }
183
+ }
184
+ );
185
+ };
186
+ var numberOfAppsCreated = 0;
187
+ var _StackClientAppImpl = class __StackClientAppImpl {
188
+ constructor(_options) {
189
+ this._options = _options;
190
+ this._uniqueIdentifier = void 0;
191
+ this.__DEMO_ENABLE_SLIGHT_FETCH_DELAY = false;
192
+ this._ownedAdminApps = new import_maps.DependenciesMap();
193
+ this._currentUserCache = createCacheBySession(async (session) => {
194
+ if (this.__DEMO_ENABLE_SLIGHT_FETCH_DELAY) {
195
+ await (0, import_promises.wait)(2e3);
196
+ }
197
+ if (session.isKnownToBeInvalid()) {
198
+ return null;
199
+ }
200
+ return await this._interface.getClientUserByToken(session);
201
+ });
202
+ this._currentProjectCache = createCache(async () => {
203
+ return import_results.Result.orThrow(await this._interface.getClientProject());
204
+ });
205
+ this._ownedProjectsCache = createCacheBySession(async (session) => {
206
+ return await this._interface.listProjects(session);
207
+ });
208
+ this._currentUserPermissionsCache = createCacheBySession(async (session, [teamId, recursive]) => {
209
+ return await this._interface.listCurrentUserTeamPermissions({ teamId, recursive }, session);
210
+ });
211
+ this._currentUserTeamsCache = createCacheBySession(async (session) => {
212
+ return await this._interface.listCurrentUserTeams(session);
213
+ });
214
+ this._currentUserOAuthConnectionAccessTokensCache = createCacheBySession(
215
+ async (session, [providerId, scope]) => {
216
+ try {
217
+ const result = await this._interface.createProviderAccessToken(providerId, scope || "", session);
218
+ return { accessToken: result.access_token };
219
+ } catch (err) {
220
+ if (!(err instanceof import_stack_shared.KnownErrors.OAuthConnectionDoesNotHaveRequiredScope || err instanceof import_stack_shared.KnownErrors.OAuthConnectionNotConnectedToUser)) {
221
+ throw err;
222
+ }
223
+ }
224
+ return null;
225
+ }
226
+ );
227
+ this._currentUserOAuthConnectionCache = createCacheBySession(
228
+ async (session, [providerId, scope, redirect]) => {
229
+ return await this._getUserOAuthConnectionCacheFn({
230
+ getUser: async () => import_results.Result.orThrow(await this._currentUserCache.getOrWait([session], "write-only")),
231
+ getOrWaitOAuthToken: async () => import_results.Result.orThrow(await this._currentUserOAuthConnectionAccessTokensCache.getOrWait([session, providerId, scope || ""], "write-only")),
232
+ useOAuthToken: () => useAsyncCache(this._currentUserOAuthConnectionAccessTokensCache, [session, providerId, scope || ""], "useOAuthToken"),
233
+ providerId,
234
+ scope,
235
+ redirect,
236
+ session
237
+ });
238
+ }
239
+ );
240
+ this._teamMemberProfilesCache = createCacheBySession(
241
+ async (session, [teamId]) => {
242
+ return await this._interface.listTeamMemberProfiles({ teamId }, session);
243
+ }
244
+ );
245
+ this._teamInvitationsCache = createCacheBySession(
246
+ async (session, [teamId]) => {
247
+ return await this._interface.listTeamInvitations({ teamId }, session);
248
+ }
249
+ );
250
+ this._currentUserTeamProfileCache = createCacheBySession(
251
+ async (session, [teamId]) => {
252
+ return await this._interface.getTeamMemberProfile({ teamId, userId: "me" }, session);
253
+ }
254
+ );
255
+ this._clientContactChannelsCache = createCacheBySession(
256
+ async (session) => {
257
+ return await this._interface.listClientContactChannels(session);
258
+ }
259
+ );
260
+ this._memoryTokenStore = createEmptyTokenStore();
261
+ this._requestTokenStores = /* @__PURE__ */ new WeakMap();
262
+ this._storedBrowserCookieTokenStore = null;
263
+ /**
264
+ * A map from token stores and session keys to sessions.
265
+ *
266
+ * This isn't just a map from session keys to sessions for two reasons:
267
+ *
268
+ * - So we can garbage-collect Session objects when the token store is garbage-collected
269
+ * - So different token stores are separated and don't leak information between each other, eg. if the same user sends two requests to the same server they should get a different session object
270
+ */
271
+ this._sessionsByTokenStoreAndSessionKey = /* @__PURE__ */ new WeakMap();
272
+ if ("interface" in _options) {
273
+ this._interface = _options.interface;
274
+ } else {
275
+ this._interface = new import_stack_shared.StackClientInterface({
276
+ getBaseUrl: () => getBaseUrl(_options.baseUrl),
277
+ projectId: _options.projectId ?? getDefaultProjectId(),
278
+ clientVersion,
279
+ publishableClientKey: _options.publishableClientKey ?? getDefaultPublishableClientKey(),
280
+ prepareRequest: async () => {
281
+ }
282
+ });
283
+ }
284
+ this._tokenStoreInit = _options.tokenStore;
285
+ this._redirectMethod = _options.redirectMethod || "none";
286
+ this._urlOptions = _options.urls ?? {};
287
+ this._oauthScopesOnSignIn = _options.oauthScopesOnSignIn ?? {};
288
+ if (_options.uniqueIdentifier) {
289
+ this._uniqueIdentifier = _options.uniqueIdentifier;
290
+ this._initUniqueIdentifier();
291
+ }
292
+ if (!_options.noAutomaticPrefetch) {
293
+ numberOfAppsCreated++;
294
+ if (numberOfAppsCreated > 10) {
295
+ (process.env.NODE_ENV === "development" ? console.log : console.warn)(`You have created more than 10 Stack apps with automatic pre-fetch enabled (${numberOfAppsCreated}). This is usually a sign of a memory leak, but can sometimes be caused by hot reload of your tech stack. If you are getting this error and it is not caused by hot reload, make sure to minimize the number of Stack apps per page (usually, one per project). (If it is caused by hot reload and does not occur in production, you can safely ignore it.)`);
296
+ }
297
+ }
298
+ }
299
+ async _createCookieHelper() {
300
+ if (this._tokenStoreInit === "nextjs-cookie" || this._tokenStoreInit === "cookie") {
301
+ return await (0, import_cookie.createCookieHelper)();
302
+ } else {
303
+ return await (0, import_cookie.createEmptyCookieHelper)();
304
+ }
305
+ }
306
+ async _getUserOAuthConnectionCacheFn(options) {
307
+ const user = await options.getUser();
308
+ let hasConnection = true;
309
+ if (!user || !user.oauth_providers.find((p) => p.id === options.providerId)) {
310
+ hasConnection = false;
311
+ }
312
+ const token = await options.getOrWaitOAuthToken();
313
+ if (!token) {
314
+ hasConnection = false;
315
+ }
316
+ if (!hasConnection && options.redirect) {
317
+ if (!options.session) {
318
+ throw new Error("No session found. You might be calling getConnectedAccount with redirect without having a user session.");
319
+ }
320
+ await (0, import_auth.addNewOAuthProviderOrScope)(
321
+ this._interface,
322
+ {
323
+ provider: options.providerId,
324
+ redirectUrl: this.urls.oauthCallback,
325
+ errorRedirectUrl: this.urls.error,
326
+ providerScope: (0, import_strings.mergeScopeStrings)(options.scope || "", (this._oauthScopesOnSignIn[options.providerId] ?? []).join(" "))
327
+ },
328
+ options.session
329
+ );
330
+ return await (0, import_promises.neverResolve)();
331
+ } else if (!hasConnection) {
332
+ return null;
333
+ }
334
+ const app = this;
335
+ return {
336
+ id: options.providerId,
337
+ async getAccessToken() {
338
+ const result = await options.getOrWaitOAuthToken();
339
+ if (!result) {
340
+ throw new import_errors.StackAssertionError("No access token available");
341
+ }
342
+ return result;
343
+ },
344
+ useAccessToken() {
345
+ const result = options.useOAuthToken();
346
+ if (!result) {
347
+ throw new import_errors.StackAssertionError("No access token available");
348
+ }
349
+ return result;
350
+ }
351
+ };
352
+ }
353
+ _initUniqueIdentifier() {
354
+ if (!this._uniqueIdentifier) {
355
+ throw new import_errors.StackAssertionError("Unique identifier not initialized");
356
+ }
357
+ if (allClientApps.has(this._uniqueIdentifier)) {
358
+ throw new import_errors.StackAssertionError("A Stack client app with the same unique identifier already exists");
359
+ }
360
+ allClientApps.set(this._uniqueIdentifier, [this._options.checkString ?? "default check string", this]);
361
+ }
362
+ /**
363
+ * Cloudflare workers does not allow use of randomness on the global scope (on which the Stack app is probably
364
+ * initialized). For that reason, we generate the unique identifier lazily when it is first needed instead of in the
365
+ * constructor.
366
+ */
367
+ _getUniqueIdentifier() {
368
+ if (!this._uniqueIdentifier) {
369
+ this._uniqueIdentifier = (0, import_uuids.generateUuid)();
370
+ this._initUniqueIdentifier();
371
+ }
372
+ return this._uniqueIdentifier;
373
+ }
374
+ async _checkFeatureSupport(name, options) {
375
+ return await this._interface.checkFeatureSupport({ ...options, name });
376
+ }
377
+ _useCheckFeatureSupport(name, options) {
378
+ (0, import_promises.runAsynchronously)(this._checkFeatureSupport(name, options));
379
+ throw new import_errors.StackAssertionError(`${name} is not currently supported. Please reach out to Stack support for more information.`);
380
+ }
381
+ get _refreshTokenCookieName() {
382
+ return `stack-refresh-${this.projectId}`;
383
+ }
384
+ _getTokensFromCookies(cookies) {
385
+ const refreshToken = cookies.refreshTokenCookie;
386
+ const accessTokenObject = cookies.accessTokenCookie?.startsWith('["') ? JSON.parse(cookies.accessTokenCookie) : null;
387
+ const accessToken = accessTokenObject && refreshToken === accessTokenObject[0] ? accessTokenObject[1] : null;
388
+ return {
389
+ refreshToken,
390
+ accessToken
391
+ };
392
+ }
393
+ get _accessTokenCookieName() {
394
+ return `stack-access`;
395
+ }
396
+ _getBrowserCookieTokenStore() {
397
+ if (!(0, import_env.isBrowserLike)()) {
398
+ throw new Error("Cannot use cookie token store on the server!");
399
+ }
400
+ if (this._storedBrowserCookieTokenStore === null) {
401
+ const getCurrentValue = (old) => {
402
+ const tokens = this._getTokensFromCookies({
403
+ refreshTokenCookie: (0, import_cookie.getCookieClient)(this._refreshTokenCookieName) ?? (0, import_cookie.getCookieClient)("stack-refresh"),
404
+ // keep old cookie name for backwards-compatibility
405
+ accessTokenCookie: (0, import_cookie.getCookieClient)(this._accessTokenCookieName)
406
+ });
407
+ return {
408
+ refreshToken: tokens.refreshToken,
409
+ accessToken: tokens.accessToken ?? (old?.refreshToken === tokens.refreshToken ? old.accessToken : null)
410
+ };
411
+ };
412
+ this._storedBrowserCookieTokenStore = new import_stores.Store(getCurrentValue(null));
413
+ let hasSucceededInWriting = true;
414
+ setInterval(() => {
415
+ if (hasSucceededInWriting) {
416
+ const oldValue = this._storedBrowserCookieTokenStore.get();
417
+ const currentValue = getCurrentValue(oldValue);
418
+ if (!(0, import_objects.deepPlainEquals)(currentValue, oldValue)) {
419
+ this._storedBrowserCookieTokenStore.set(currentValue);
420
+ }
421
+ }
422
+ }, 100);
423
+ this._storedBrowserCookieTokenStore.onChange((value) => {
424
+ try {
425
+ (0, import_cookie.setOrDeleteCookieClient)(this._refreshTokenCookieName, value.refreshToken, { maxAge: 60 * 60 * 24 * 365 });
426
+ (0, import_cookie.setOrDeleteCookieClient)(this._accessTokenCookieName, value.accessToken ? JSON.stringify([value.refreshToken, value.accessToken]) : null, { maxAge: 60 * 60 * 24 });
427
+ (0, import_cookie.deleteCookieClient)("stack-refresh");
428
+ hasSucceededInWriting = true;
429
+ } catch (e) {
430
+ if (!(0, import_env.isBrowserLike)()) {
431
+ hasSucceededInWriting = false;
432
+ } else {
433
+ throw e;
434
+ }
435
+ }
436
+ });
437
+ }
438
+ return this._storedBrowserCookieTokenStore;
439
+ }
440
+ _getOrCreateTokenStore(cookieHelper, overrideTokenStoreInit) {
441
+ const tokenStoreInit = overrideTokenStoreInit === void 0 ? this._tokenStoreInit : overrideTokenStoreInit;
442
+ switch (tokenStoreInit) {
443
+ case "cookie": {
444
+ return this._getBrowserCookieTokenStore();
445
+ }
446
+ case "nextjs-cookie": {
447
+ if ((0, import_env.isBrowserLike)()) {
448
+ return this._getBrowserCookieTokenStore();
449
+ } else {
450
+ const tokens = this._getTokensFromCookies({
451
+ refreshTokenCookie: cookieHelper.get(this._refreshTokenCookieName) ?? cookieHelper.get("stack-refresh"),
452
+ // keep old cookie name for backwards-compatibility
453
+ accessTokenCookie: cookieHelper.get(this._accessTokenCookieName)
454
+ });
455
+ const store = new import_stores.Store(tokens);
456
+ store.onChange((value) => {
457
+ (0, import_promises.runAsynchronously)(async () => {
458
+ await Promise.all([
459
+ (0, import_cookie.setOrDeleteCookie)(this._refreshTokenCookieName, value.refreshToken, { maxAge: 60 * 60 * 24 * 365, noOpIfServerComponent: true }),
460
+ (0, import_cookie.setOrDeleteCookie)(this._accessTokenCookieName, value.accessToken ? JSON.stringify([value.refreshToken, value.accessToken]) : null, { maxAge: 60 * 60 * 24, noOpIfServerComponent: true })
461
+ ]);
462
+ });
463
+ });
464
+ return store;
465
+ }
466
+ }
467
+ case "memory": {
468
+ return this._memoryTokenStore;
469
+ }
470
+ default: {
471
+ if (tokenStoreInit === null) {
472
+ return createEmptyTokenStore();
473
+ } else if (typeof tokenStoreInit === "object" && "headers" in tokenStoreInit) {
474
+ if (this._requestTokenStores.has(tokenStoreInit)) return this._requestTokenStores.get(tokenStoreInit);
475
+ const stackAuthHeader = tokenStoreInit.headers.get("x-stack-auth");
476
+ if (stackAuthHeader) {
477
+ let parsed2;
478
+ try {
479
+ parsed2 = JSON.parse(stackAuthHeader);
480
+ if (typeof parsed2 !== "object") throw new Error("x-stack-auth header must be a JSON object");
481
+ if (parsed2 === null) throw new Error("x-stack-auth header must not be null");
482
+ } catch (e) {
483
+ throw new Error(`Invalid x-stack-auth header: ${stackAuthHeader}`, { cause: e });
484
+ }
485
+ return this._getOrCreateTokenStore(cookieHelper, {
486
+ accessToken: parsed2.accessToken ?? null,
487
+ refreshToken: parsed2.refreshToken ?? null
488
+ });
489
+ }
490
+ const cookieHeader = tokenStoreInit.headers.get("cookie");
491
+ const parsed = cookie.parse(cookieHeader || "");
492
+ const res = new import_stores.Store({
493
+ refreshToken: parsed[this._refreshTokenCookieName] || parsed["stack-refresh"] || null,
494
+ // keep old cookie name for backwards-compatibility
495
+ accessToken: parsed[this._accessTokenCookieName] || null
496
+ });
497
+ this._requestTokenStores.set(tokenStoreInit, res);
498
+ return res;
499
+ } else if ("accessToken" in tokenStoreInit || "refreshToken" in tokenStoreInit) {
500
+ return new import_stores.Store({
501
+ refreshToken: tokenStoreInit.refreshToken,
502
+ accessToken: tokenStoreInit.accessToken
503
+ });
504
+ }
505
+ throw new Error(`Invalid token store ${tokenStoreInit}`);
506
+ }
507
+ }
508
+ }
509
+ _useTokenStore(overrideTokenStoreInit) {
510
+ (0, import_react.suspendIfSsr)();
511
+ const cookieHelper = (0, import_cookie.createBrowserCookieHelper)();
512
+ const tokenStore = this._getOrCreateTokenStore(cookieHelper, overrideTokenStoreInit);
513
+ return tokenStore;
514
+ }
515
+ _getSessionFromTokenStore(tokenStore) {
516
+ const tokenObj = tokenStore.get();
517
+ const sessionKey = import_sessions.InternalSession.calculateSessionKey(tokenObj);
518
+ const existing = sessionKey ? this._sessionsByTokenStoreAndSessionKey.get(tokenStore)?.get(sessionKey) : null;
519
+ if (existing) return existing;
520
+ const session = this._interface.createSession({
521
+ refreshToken: tokenObj.refreshToken,
522
+ accessToken: tokenObj.accessToken
523
+ });
524
+ session.onAccessTokenChange((newAccessToken) => {
525
+ tokenStore.update((old) => ({
526
+ ...old,
527
+ accessToken: newAccessToken?.token ?? null
528
+ }));
529
+ });
530
+ session.onInvalidate(() => {
531
+ tokenStore.update((old) => ({
532
+ ...old,
533
+ accessToken: null,
534
+ refreshToken: null
535
+ }));
536
+ });
537
+ let sessionsBySessionKey = this._sessionsByTokenStoreAndSessionKey.get(tokenStore) ?? /* @__PURE__ */ new Map();
538
+ this._sessionsByTokenStoreAndSessionKey.set(tokenStore, sessionsBySessionKey);
539
+ sessionsBySessionKey.set(sessionKey, session);
540
+ return session;
541
+ }
542
+ async _getSession(overrideTokenStoreInit) {
543
+ const tokenStore = this._getOrCreateTokenStore(await this._createCookieHelper(), overrideTokenStoreInit);
544
+ return this._getSessionFromTokenStore(tokenStore);
545
+ }
546
+ _useSession(overrideTokenStoreInit) {
547
+ const tokenStore = this._useTokenStore(overrideTokenStoreInit);
548
+ const subscribe = (0, import_react2.useCallback)((cb) => {
549
+ const { unsubscribe } = tokenStore.onChange(() => {
550
+ cb();
551
+ });
552
+ return unsubscribe;
553
+ }, [tokenStore]);
554
+ const getSnapshot = (0, import_react2.useCallback)(() => this._getSessionFromTokenStore(tokenStore), [tokenStore]);
555
+ return import_react2.default.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
556
+ }
557
+ async _signInToAccountWithTokens(tokens) {
558
+ if (!("accessToken" in tokens) || !("refreshToken" in tokens)) {
559
+ throw new import_errors.StackAssertionError("Invalid tokens object; can't sign in with this", { tokens });
560
+ }
561
+ const tokenStore = this._getOrCreateTokenStore(await this._createCookieHelper());
562
+ tokenStore.set(tokens);
563
+ }
564
+ _hasPersistentTokenStore(overrideTokenStoreInit) {
565
+ return (overrideTokenStoreInit !== void 0 ? overrideTokenStoreInit : this._tokenStoreInit) !== null;
566
+ }
567
+ _ensurePersistentTokenStore(overrideTokenStoreInit) {
568
+ if (!this._hasPersistentTokenStore(overrideTokenStoreInit)) {
569
+ throw new Error("Cannot call this function on a Stack app without a persistent token store. Make sure the tokenStore option on the constructor is set to a non-null value when initializing Stack.\n\nStack uses token stores to access access tokens of the current user. For example, on web frontends it is commonly the string value 'cookies' for cookie storage.");
570
+ }
571
+ }
572
+ _isInternalProject() {
573
+ return this.projectId === "internal";
574
+ }
575
+ _ensureInternalProject() {
576
+ if (!this._isInternalProject()) {
577
+ throw new Error("Cannot call this function on a Stack app with a project ID other than 'internal'.");
578
+ }
579
+ }
580
+ _clientProjectFromCrud(crud) {
581
+ return {
582
+ id: crud.id,
583
+ displayName: crud.display_name,
584
+ config: {
585
+ signUpEnabled: crud.config.sign_up_enabled,
586
+ credentialEnabled: crud.config.credential_enabled,
587
+ magicLinkEnabled: crud.config.magic_link_enabled,
588
+ passkeyEnabled: crud.config.passkey_enabled,
589
+ clientTeamCreationEnabled: crud.config.client_team_creation_enabled,
590
+ clientUserDeletionEnabled: crud.config.client_user_deletion_enabled,
591
+ oauthProviders: crud.config.enabled_oauth_providers.map((p) => ({
592
+ id: p.id
593
+ }))
594
+ }
595
+ };
596
+ }
597
+ _clientTeamPermissionFromCrud(crud) {
598
+ return {
599
+ id: crud.id
600
+ };
601
+ }
602
+ _clientTeamUserFromCrud(crud) {
603
+ return {
604
+ id: crud.user_id,
605
+ teamProfile: {
606
+ displayName: crud.display_name,
607
+ profileImageUrl: crud.profile_image_url
608
+ }
609
+ };
610
+ }
611
+ _clientTeamInvitationFromCrud(session, crud) {
612
+ return {
613
+ id: crud.id,
614
+ recipientEmail: crud.recipient_email,
615
+ expiresAt: new Date(crud.expires_at_millis),
616
+ revoke: async () => {
617
+ await this._interface.revokeTeamInvitation(crud.id, crud.team_id, session);
618
+ await this._teamInvitationsCache.refresh([session, crud.team_id]);
619
+ }
620
+ };
621
+ }
622
+ _clientTeamFromCrud(crud, session) {
623
+ const app = this;
624
+ return {
625
+ id: crud.id,
626
+ displayName: crud.display_name,
627
+ profileImageUrl: crud.profile_image_url,
628
+ clientMetadata: crud.client_metadata,
629
+ clientReadOnlyMetadata: crud.client_read_only_metadata,
630
+ async inviteUser(options) {
631
+ if (!options.callbackUrl && !await app._getCurrentUrl()) {
632
+ throw new Error("Cannot invite user without a callback URL from the server or without a redirect method. Make sure you pass the `callbackUrl` option: `inviteUser({ email, callbackUrl: ... })`");
633
+ }
634
+ await app._interface.sendTeamInvitation({
635
+ teamId: crud.id,
636
+ email: options.email,
637
+ session,
638
+ callbackUrl: options.callbackUrl ?? (0, import_url.constructRedirectUrl)(app.urls.teamInvitation)
639
+ });
640
+ await app._teamInvitationsCache.refresh([session, crud.id]);
641
+ },
642
+ async listUsers() {
643
+ const result = import_results.Result.orThrow(await app._teamMemberProfilesCache.getOrWait([session, crud.id], "write-only"));
644
+ return result.map((crud2) => app._clientTeamUserFromCrud(crud2));
645
+ },
646
+ useUsers() {
647
+ const result = useAsyncCache(app._teamMemberProfilesCache, [session, crud.id], "team.useUsers()");
648
+ return result.map((crud2) => app._clientTeamUserFromCrud(crud2));
649
+ },
650
+ async listInvitations() {
651
+ const result = import_results.Result.orThrow(await app._teamInvitationsCache.getOrWait([session, crud.id], "write-only"));
652
+ return result.map((crud2) => app._clientTeamInvitationFromCrud(session, crud2));
653
+ },
654
+ useInvitations() {
655
+ const result = useAsyncCache(app._teamInvitationsCache, [session, crud.id], "team.useInvitations()");
656
+ return result.map((crud2) => app._clientTeamInvitationFromCrud(session, crud2));
657
+ },
658
+ async update(data) {
659
+ await app._interface.updateTeam({ data: teamUpdateOptionsToCrud(data), teamId: crud.id }, session);
660
+ await app._currentUserTeamsCache.refresh([session]);
661
+ },
662
+ async delete() {
663
+ await app._interface.deleteTeam(crud.id, session);
664
+ await app._currentUserTeamsCache.refresh([session]);
665
+ }
666
+ };
667
+ }
668
+ _clientContactChannelFromCrud(crud, session) {
669
+ const app = this;
670
+ return {
671
+ id: crud.id,
672
+ value: crud.value,
673
+ type: crud.type,
674
+ isVerified: crud.is_verified,
675
+ isPrimary: crud.is_primary,
676
+ usedForAuth: crud.used_for_auth,
677
+ async sendVerificationEmail() {
678
+ await app._interface.sendCurrentUserContactChannelVerificationEmail(crud.id, (0, import_url.constructRedirectUrl)(app.urls.emailVerification), session);
679
+ },
680
+ async update(data) {
681
+ await app._interface.updateClientContactChannel(crud.id, contactChannelUpdateOptionsToCrud(data), session);
682
+ await app._clientContactChannelsCache.refresh([session]);
683
+ },
684
+ async delete() {
685
+ await app._interface.deleteClientContactChannel(crud.id, session);
686
+ await app._clientContactChannelsCache.refresh([session]);
687
+ }
688
+ };
689
+ }
690
+ _createAuth(session) {
691
+ const app = this;
692
+ return {
693
+ _internalSession: session,
694
+ currentSession: {
695
+ async getTokens() {
696
+ const tokens = await session.getOrFetchLikelyValidTokens(2e4);
697
+ return {
698
+ accessToken: tokens?.accessToken.token ?? null,
699
+ refreshToken: tokens?.refreshToken?.token ?? null
700
+ };
701
+ }
702
+ },
703
+ async getAuthHeaders() {
704
+ return {
705
+ "x-stack-auth": JSON.stringify(await this.getAuthJson())
706
+ };
707
+ },
708
+ async getAuthJson() {
709
+ const tokens = await this.currentSession.getTokens();
710
+ return tokens;
711
+ },
712
+ async registerPasskey(options) {
713
+ const hostname = (await app._getCurrentUrl())?.hostname;
714
+ if (!hostname) {
715
+ throw new import_errors.StackAssertionError("hostname must be provided if the Stack App does not have a redirect method");
716
+ }
717
+ const initiationResult = await app._interface.initiatePasskeyRegistration({}, session);
718
+ if (initiationResult.status !== "ok") {
719
+ return import_results.Result.error(new import_stack_shared.KnownErrors.PasskeyRegistrationFailed("Failed to get initiation options for passkey registration"));
720
+ }
721
+ const { options_json, code } = initiationResult.data;
722
+ if (options_json.rp.id !== "THIS_VALUE_WILL_BE_REPLACED.example.com") {
723
+ throw new import_errors.StackAssertionError(`Expected returned RP ID from server to equal sentinel, but found ${options_json.rp.id}`);
724
+ }
725
+ options_json.rp.id = hostname;
726
+ let attResp;
727
+ try {
728
+ attResp = await (0, import_browser.startRegistration)({ optionsJSON: options_json });
729
+ debugger;
730
+ } catch (error) {
731
+ if (error instanceof import_browser.WebAuthnError) {
732
+ return import_results.Result.error(new import_stack_shared.KnownErrors.PasskeyWebAuthnError(error.message, error.name));
733
+ } else {
734
+ return import_results.Result.error(new import_stack_shared.KnownErrors.PasskeyRegistrationFailed("Failed to start passkey registration"));
735
+ }
736
+ }
737
+ const registrationResult = await app._interface.registerPasskey({ credential: attResp, code }, session);
738
+ await app._refreshUser(session);
739
+ return registrationResult;
740
+ },
741
+ signOut(options) {
742
+ return app._signOut(session, options);
743
+ }
744
+ };
745
+ }
746
+ _editableTeamProfileFromCrud(crud, session) {
747
+ const app = this;
748
+ return {
749
+ displayName: crud.display_name,
750
+ profileImageUrl: crud.profile_image_url,
751
+ async update(update) {
752
+ await app._interface.updateTeamMemberProfile({
753
+ teamId: crud.team_id,
754
+ userId: crud.user_id,
755
+ profile: {
756
+ display_name: update.displayName,
757
+ profile_image_url: update.profileImageUrl
758
+ }
759
+ }, session);
760
+ await app._currentUserTeamProfileCache.refresh([session, crud.team_id]);
761
+ }
762
+ };
763
+ }
764
+ _createBaseUser(crud) {
765
+ return {
766
+ id: crud.id,
767
+ displayName: crud.display_name,
768
+ primaryEmail: crud.primary_email,
769
+ primaryEmailVerified: crud.primary_email_verified,
770
+ profileImageUrl: crud.profile_image_url,
771
+ signedUpAt: new Date(crud.signed_up_at_millis),
772
+ clientMetadata: crud.client_metadata,
773
+ clientReadOnlyMetadata: crud.client_read_only_metadata,
774
+ hasPassword: crud.has_password,
775
+ emailAuthEnabled: crud.auth_with_email,
776
+ otpAuthEnabled: crud.otp_auth_enabled,
777
+ oauthProviders: crud.oauth_providers,
778
+ passkeyAuthEnabled: crud.passkey_auth_enabled,
779
+ isMultiFactorRequired: crud.requires_totp_mfa,
780
+ toClientJson() {
781
+ return crud;
782
+ }
783
+ };
784
+ }
785
+ _createUserExtraFromCurrent(crud, session) {
786
+ const app = this;
787
+ async function getConnectedAccount(id, options) {
788
+ const scopeString = options?.scopes?.join(" ");
789
+ return import_results.Result.orThrow(await app._currentUserOAuthConnectionCache.getOrWait([session, id, scopeString || "", options?.or === "redirect"], "write-only"));
790
+ }
791
+ function useConnectedAccount(id, options) {
792
+ const scopeString = options?.scopes?.join(" ");
793
+ return useAsyncCache(app._currentUserOAuthConnectionCache, [session, id, scopeString || "", options?.or === "redirect"], "user.useConnectedAccount()");
794
+ }
795
+ return {
796
+ setDisplayName(displayName) {
797
+ return this.update({ displayName });
798
+ },
799
+ setClientMetadata(metadata) {
800
+ return this.update({ clientMetadata: metadata });
801
+ },
802
+ async setSelectedTeam(team) {
803
+ await this.update({ selectedTeamId: team?.id ?? null });
804
+ },
805
+ getConnectedAccount,
806
+ useConnectedAccount,
807
+ async getTeam(teamId) {
808
+ const teams = await this.listTeams();
809
+ return teams.find((t) => t.id === teamId) ?? null;
810
+ },
811
+ useTeam(teamId) {
812
+ const teams = this.useTeams();
813
+ return (0, import_react2.useMemo)(() => {
814
+ return teams.find((t) => t.id === teamId) ?? null;
815
+ }, [teams, teamId]);
816
+ },
817
+ async listTeams() {
818
+ const teams = import_results.Result.orThrow(await app._currentUserTeamsCache.getOrWait([session], "write-only"));
819
+ return teams.map((crud2) => app._clientTeamFromCrud(crud2, session));
820
+ },
821
+ useTeams() {
822
+ const teams = useAsyncCache(app._currentUserTeamsCache, [session], "user.useTeams()");
823
+ return (0, import_react2.useMemo)(() => teams.map((crud2) => app._clientTeamFromCrud(crud2, session)), [teams]);
824
+ },
825
+ async createTeam(data) {
826
+ const crud2 = await app._interface.createClientTeam(teamCreateOptionsToCrud(data, "me"), session);
827
+ await app._currentUserTeamsCache.refresh([session]);
828
+ return app._clientTeamFromCrud(crud2, session);
829
+ },
830
+ async leaveTeam(team) {
831
+ await app._interface.leaveTeam(team.id, session);
832
+ },
833
+ async listPermissions(scope, options) {
834
+ const recursive = options?.recursive ?? true;
835
+ const permissions = import_results.Result.orThrow(await app._currentUserPermissionsCache.getOrWait([session, scope.id, recursive], "write-only"));
836
+ return permissions.map((crud2) => app._clientTeamPermissionFromCrud(crud2));
837
+ },
838
+ usePermissions(scope, options) {
839
+ const recursive = options?.recursive ?? true;
840
+ const permissions = useAsyncCache(app._currentUserPermissionsCache, [session, scope.id, recursive], "user.usePermissions()");
841
+ return (0, import_react2.useMemo)(() => permissions.map((crud2) => app._clientTeamPermissionFromCrud(crud2)), [permissions]);
842
+ },
843
+ usePermission(scope, permissionId) {
844
+ const permissions = this.usePermissions(scope);
845
+ return (0, import_react2.useMemo)(() => permissions.find((p) => p.id === permissionId) ?? null, [permissions, permissionId]);
846
+ },
847
+ async getPermission(scope, permissionId) {
848
+ const permissions = await this.listPermissions(scope);
849
+ return permissions.find((p) => p.id === permissionId) ?? null;
850
+ },
851
+ async hasPermission(scope, permissionId) {
852
+ return await this.getPermission(scope, permissionId) !== null;
853
+ },
854
+ async update(update) {
855
+ return await app._updateClientUser(update, session);
856
+ },
857
+ async sendVerificationEmail(options) {
858
+ if (!crud.primary_email) {
859
+ throw new import_errors.StackAssertionError("User does not have a primary email");
860
+ }
861
+ if (!options?.callbackUrl && !await app._getCurrentUrl()) {
862
+ throw new Error("Cannot send verification email without a callback URL from the server or without a redirect method. Make sure you pass the `callbackUrl` option: `sendVerificationEmail({ callbackUrl: ... })`");
863
+ }
864
+ return await app._interface.sendVerificationEmail(crud.primary_email, options?.callbackUrl ?? (0, import_url.constructRedirectUrl)(app.urls.emailVerification), session);
865
+ },
866
+ async updatePassword(options) {
867
+ const result = await app._interface.updatePassword(options, session);
868
+ await app._currentUserCache.refresh([session]);
869
+ return result;
870
+ },
871
+ async setPassword(options) {
872
+ const result = await app._interface.setPassword(options, session);
873
+ await app._currentUserCache.refresh([session]);
874
+ return result;
875
+ },
876
+ selectedTeam: crud.selected_team && this._clientTeamFromCrud(crud.selected_team, session),
877
+ async getTeamProfile(team) {
878
+ const result = import_results.Result.orThrow(await app._currentUserTeamProfileCache.getOrWait([session, team.id], "write-only"));
879
+ return app._editableTeamProfileFromCrud(result, session);
880
+ },
881
+ useTeamProfile(team) {
882
+ const result = useAsyncCache(app._currentUserTeamProfileCache, [session, team.id], "user.useTeamProfile()");
883
+ return app._editableTeamProfileFromCrud(result, session);
884
+ },
885
+ async delete() {
886
+ await app._interface.deleteCurrentUser(session);
887
+ session.markInvalid();
888
+ },
889
+ async listContactChannels() {
890
+ const result = import_results.Result.orThrow(await app._clientContactChannelsCache.getOrWait([session], "write-only"));
891
+ return result.map((crud2) => app._clientContactChannelFromCrud(crud2, session));
892
+ },
893
+ useContactChannels() {
894
+ const result = useAsyncCache(app._clientContactChannelsCache, [session], "user.useContactChannels()");
895
+ return result.map((crud2) => app._clientContactChannelFromCrud(crud2, session));
896
+ },
897
+ async createContactChannel(data) {
898
+ const crud2 = await app._interface.createClientContactChannel(contactChannelCreateOptionsToCrud("me", data), session);
899
+ await app._clientContactChannelsCache.refresh([session]);
900
+ return app._clientContactChannelFromCrud(crud2, session);
901
+ }
902
+ };
903
+ }
904
+ _createInternalUserExtra(session) {
905
+ const app = this;
906
+ this._ensureInternalProject();
907
+ return {
908
+ createProject(newProject) {
909
+ return app._createProject(session, newProject);
910
+ },
911
+ listOwnedProjects() {
912
+ return app._listOwnedProjects(session);
913
+ },
914
+ useOwnedProjects() {
915
+ return app._useOwnedProjects(session);
916
+ }
917
+ };
918
+ }
919
+ _currentUserFromCrud(crud, session) {
920
+ const currentUser = {
921
+ ...this._createBaseUser(crud),
922
+ ...this._createAuth(session),
923
+ ...this._createUserExtraFromCurrent(crud, session),
924
+ ...this._isInternalProject() ? this._createInternalUserExtra(session) : {}
925
+ };
926
+ Object.freeze(currentUser);
927
+ return currentUser;
928
+ }
929
+ _getOwnedAdminApp(forProjectId, session) {
930
+ if (!this._ownedAdminApps.has([session, forProjectId])) {
931
+ this._ownedAdminApps.set([session, forProjectId], new _StackAdminAppImpl({
932
+ baseUrl: this._interface.options.getBaseUrl(),
933
+ projectId: forProjectId,
934
+ tokenStore: null,
935
+ projectOwnerSession: session,
936
+ noAutomaticPrefetch: true
937
+ }));
938
+ }
939
+ return this._ownedAdminApps.get([session, forProjectId]);
940
+ }
941
+ get projectId() {
942
+ return this._interface.projectId;
943
+ }
944
+ async _isTrusted(url) {
945
+ return (0, import_urls.isRelative)(url);
946
+ }
947
+ get urls() {
948
+ return getUrls(this._urlOptions);
949
+ }
950
+ async _getCurrentUrl() {
951
+ if (this._redirectMethod === "none") {
952
+ return null;
953
+ }
954
+ return new URL(window.location.href);
955
+ }
956
+ async _redirectTo(options) {
957
+ if (this._redirectMethod === "none") {
958
+ return;
959
+ } else if (typeof this._redirectMethod === "object" && this._redirectMethod.navigate) {
960
+ this._redirectMethod.navigate(options.url.toString());
961
+ } else {
962
+ if (options.replace) {
963
+ window.location.replace(options.url);
964
+ } else {
965
+ window.location.assign(options.url);
966
+ }
967
+ }
968
+ await (0, import_promises.wait)(2e3);
969
+ }
970
+ useNavigate() {
971
+ if (typeof this._redirectMethod === "object") {
972
+ return this._redirectMethod.useNavigate();
973
+ } else if (this._redirectMethod === "window") {
974
+ return () => window.location.assign;
975
+ } else {
976
+ return (to) => {
977
+ };
978
+ }
979
+ }
980
+ async _redirectIfTrusted(url, options) {
981
+ if (!await this._isTrusted(url)) {
982
+ throw new Error(`Redirect URL ${url} is not trusted; should be relative.`);
983
+ }
984
+ return await this._redirectTo({ url, ...options });
985
+ }
986
+ async _redirectToHandler(handlerName, options) {
987
+ let url = this.urls[handlerName];
988
+ if (!url) {
989
+ throw new Error(`No URL for handler name ${handlerName}`);
990
+ }
991
+ if (!options?.noRedirectBack) {
992
+ if (handlerName === "afterSignIn" || handlerName === "afterSignUp") {
993
+ if (isReactServer || typeof window === "undefined") {
994
+ try {
995
+ await this._checkFeatureSupport("rsc-handler-" + handlerName, {});
996
+ } catch (e) {
997
+ }
998
+ } else {
999
+ const queryParams = new URLSearchParams(window.location.search);
1000
+ url = queryParams.get("after_auth_return_to") || url;
1001
+ }
1002
+ } else if (handlerName === "signIn" || handlerName === "signUp") {
1003
+ if (isReactServer || typeof window === "undefined") {
1004
+ try {
1005
+ await this._checkFeatureSupport("rsc-handler-" + handlerName, {});
1006
+ } catch (e) {
1007
+ }
1008
+ } else {
1009
+ const currentUrl = new URL(window.location.href);
1010
+ const nextUrl = new URL(url, currentUrl);
1011
+ if (currentUrl.searchParams.has("after_auth_return_to")) {
1012
+ nextUrl.searchParams.set("after_auth_return_to", currentUrl.searchParams.get("after_auth_return_to"));
1013
+ } else if (currentUrl.protocol === nextUrl.protocol && currentUrl.host === nextUrl.host) {
1014
+ nextUrl.searchParams.set("after_auth_return_to", (0, import_urls.getRelativePart)(currentUrl));
1015
+ }
1016
+ url = (0, import_urls.getRelativePart)(nextUrl);
1017
+ }
1018
+ }
1019
+ }
1020
+ await this._redirectIfTrusted(url, options);
1021
+ }
1022
+ async redirectToSignIn(options) {
1023
+ return await this._redirectToHandler("signIn", options);
1024
+ }
1025
+ async redirectToSignUp(options) {
1026
+ return await this._redirectToHandler("signUp", options);
1027
+ }
1028
+ async redirectToSignOut(options) {
1029
+ return await this._redirectToHandler("signOut", options);
1030
+ }
1031
+ async redirectToEmailVerification(options) {
1032
+ return await this._redirectToHandler("emailVerification", options);
1033
+ }
1034
+ async redirectToPasswordReset(options) {
1035
+ return await this._redirectToHandler("passwordReset", options);
1036
+ }
1037
+ async redirectToForgotPassword(options) {
1038
+ return await this._redirectToHandler("forgotPassword", options);
1039
+ }
1040
+ async redirectToHome(options) {
1041
+ return await this._redirectToHandler("home", options);
1042
+ }
1043
+ async redirectToOAuthCallback(options) {
1044
+ return await this._redirectToHandler("oauthCallback", options);
1045
+ }
1046
+ async redirectToMagicLinkCallback(options) {
1047
+ return await this._redirectToHandler("magicLinkCallback", options);
1048
+ }
1049
+ async redirectToAfterSignIn(options) {
1050
+ return await this._redirectToHandler("afterSignIn", options);
1051
+ }
1052
+ async redirectToAfterSignUp(options) {
1053
+ return await this._redirectToHandler("afterSignUp", options);
1054
+ }
1055
+ async redirectToAfterSignOut(options) {
1056
+ return await this._redirectToHandler("afterSignOut", options);
1057
+ }
1058
+ async redirectToAccountSettings(options) {
1059
+ return await this._redirectToHandler("accountSettings", options);
1060
+ }
1061
+ async redirectToError(options) {
1062
+ return await this._redirectToHandler("error", options);
1063
+ }
1064
+ async redirectToTeamInvitation(options) {
1065
+ return await this._redirectToHandler("teamInvitation", options);
1066
+ }
1067
+ async sendForgotPasswordEmail(email, options) {
1068
+ if (!options?.callbackUrl && !await this._getCurrentUrl()) {
1069
+ throw new Error("Cannot send forgot password email without a callback URL from the server or without a redirect method. Make sure you pass the `callbackUrl` option: `sendForgotPasswordEmail({ email, callbackUrl: ... })`");
1070
+ }
1071
+ return await this._interface.sendForgotPasswordEmail(email, options?.callbackUrl ?? (0, import_url.constructRedirectUrl)(this.urls.passwordReset));
1072
+ }
1073
+ async sendMagicLinkEmail(email, options) {
1074
+ if (!options?.callbackUrl && !await this._getCurrentUrl()) {
1075
+ throw new Error("Cannot send magic link email without a callback URL from the server or without a redirect method. Make sure you pass the `callbackUrl` option: `sendMagicLinkEmail({ email, callbackUrl: ... })`");
1076
+ }
1077
+ return await this._interface.sendMagicLinkEmail(email, options?.callbackUrl ?? (0, import_url.constructRedirectUrl)(this.urls.magicLinkCallback));
1078
+ }
1079
+ async resetPassword(options) {
1080
+ return await this._interface.resetPassword(options);
1081
+ }
1082
+ async verifyPasswordResetCode(code) {
1083
+ return await this._interface.verifyPasswordResetCode(code);
1084
+ }
1085
+ async verifyTeamInvitationCode(code) {
1086
+ return await this._interface.acceptTeamInvitation({
1087
+ type: "check",
1088
+ code,
1089
+ session: await this._getSession()
1090
+ });
1091
+ }
1092
+ async acceptTeamInvitation(code) {
1093
+ const result = await this._interface.acceptTeamInvitation({
1094
+ type: "use",
1095
+ code,
1096
+ session: await this._getSession()
1097
+ });
1098
+ if (result.status === "ok") {
1099
+ return import_results.Result.ok(void 0);
1100
+ } else {
1101
+ return import_results.Result.error(result.error);
1102
+ }
1103
+ }
1104
+ async getTeamInvitationDetails(code) {
1105
+ const result = await this._interface.acceptTeamInvitation({
1106
+ type: "details",
1107
+ code,
1108
+ session: await this._getSession()
1109
+ });
1110
+ if (result.status === "ok") {
1111
+ return import_results.Result.ok({ teamDisplayName: result.data.team_display_name });
1112
+ } else {
1113
+ return import_results.Result.error(result.error);
1114
+ }
1115
+ }
1116
+ async verifyEmail(code) {
1117
+ const result = await this._interface.verifyEmail(code);
1118
+ await this._currentUserCache.refresh([await this._getSession()]);
1119
+ await this._clientContactChannelsCache.refresh([await this._getSession()]);
1120
+ return result;
1121
+ }
1122
+ async getUser(options) {
1123
+ this._ensurePersistentTokenStore(options?.tokenStore);
1124
+ const session = await this._getSession(options?.tokenStore);
1125
+ const crud = import_results.Result.orThrow(await this._currentUserCache.getOrWait([session], "write-only"));
1126
+ if (crud === null) {
1127
+ switch (options?.or) {
1128
+ case "redirect": {
1129
+ await this.redirectToSignIn({ replace: true });
1130
+ break;
1131
+ }
1132
+ case "throw": {
1133
+ throw new Error("User is not signed in but getUser was called with { or: 'throw' }");
1134
+ }
1135
+ default: {
1136
+ return null;
1137
+ }
1138
+ }
1139
+ }
1140
+ return crud && this._currentUserFromCrud(crud, session);
1141
+ }
1142
+ useUser(options) {
1143
+ this._ensurePersistentTokenStore(options?.tokenStore);
1144
+ const session = this._useSession(options?.tokenStore);
1145
+ const crud = useAsyncCache(this._currentUserCache, [session], "useUser()");
1146
+ if (crud === null) {
1147
+ switch (options?.or) {
1148
+ case "redirect": {
1149
+ (0, import_promises.runAsynchronously)(this.redirectToSignIn({ replace: true }));
1150
+ (0, import_react.suspend)();
1151
+ throw new import_errors.StackAssertionError("suspend should never return");
1152
+ }
1153
+ case "throw": {
1154
+ throw new Error("User is not signed in but useUser was called with { or: 'throw' }");
1155
+ }
1156
+ case void 0:
1157
+ case "return-null": {
1158
+ }
1159
+ }
1160
+ }
1161
+ return (0, import_react2.useMemo)(() => {
1162
+ return crud && this._currentUserFromCrud(crud, session);
1163
+ }, [crud, session, options?.or]);
1164
+ }
1165
+ async _updateClientUser(update, session) {
1166
+ const res = await this._interface.updateClientUser(userUpdateOptionsToCrud(update), session);
1167
+ await this._refreshUser(session);
1168
+ return res;
1169
+ }
1170
+ async signInWithOAuth(provider) {
1171
+ if (typeof window === "undefined") {
1172
+ throw new Error("signInWithOAuth can currently only be called in a browser environment");
1173
+ }
1174
+ this._ensurePersistentTokenStore();
1175
+ await (0, import_auth.signInWithOAuth)(
1176
+ this._interface,
1177
+ {
1178
+ provider,
1179
+ redirectUrl: this.urls.oauthCallback,
1180
+ errorRedirectUrl: this.urls.error,
1181
+ providerScope: this._oauthScopesOnSignIn[provider]?.join(" ")
1182
+ }
1183
+ );
1184
+ }
1185
+ /**
1186
+ * @deprecated
1187
+ * TODO remove
1188
+ */
1189
+ async _experimentalMfa(error, session) {
1190
+ const otp = prompt("Please enter the six-digit TOTP code from your authenticator app.");
1191
+ if (!otp) {
1192
+ throw new import_stack_shared.KnownErrors.InvalidTotpCode();
1193
+ }
1194
+ return await this._interface.totpMfa(
1195
+ error.details?.attempt_code ?? (0, import_errors.throwErr)("attempt code missing"),
1196
+ otp,
1197
+ session
1198
+ );
1199
+ }
1200
+ /**
1201
+ * @deprecated
1202
+ * TODO remove
1203
+ */
1204
+ async _catchMfaRequiredError(callback) {
1205
+ try {
1206
+ return await callback();
1207
+ } catch (e) {
1208
+ if (e instanceof import_stack_shared.KnownErrors.MultiFactorAuthenticationRequired) {
1209
+ return import_results.Result.ok(await this._experimentalMfa(e, await this._getSession()));
1210
+ }
1211
+ throw e;
1212
+ }
1213
+ }
1214
+ async signInWithCredential(options) {
1215
+ this._ensurePersistentTokenStore();
1216
+ const session = await this._getSession();
1217
+ let result;
1218
+ try {
1219
+ result = await this._catchMfaRequiredError(async () => {
1220
+ return await this._interface.signInWithCredential(options.email, options.password, session);
1221
+ });
1222
+ } catch (e) {
1223
+ if (e instanceof import_stack_shared.KnownErrors.InvalidTotpCode) {
1224
+ return import_results.Result.error(e);
1225
+ }
1226
+ throw e;
1227
+ }
1228
+ if (result.status === "ok") {
1229
+ await this._signInToAccountWithTokens(result.data);
1230
+ if (!options.noRedirect) {
1231
+ await this.redirectToAfterSignIn({ replace: true });
1232
+ }
1233
+ return import_results.Result.ok(void 0);
1234
+ } else {
1235
+ return import_results.Result.error(result.error);
1236
+ }
1237
+ }
1238
+ async signUpWithCredential(options) {
1239
+ this._ensurePersistentTokenStore();
1240
+ const session = await this._getSession();
1241
+ const emailVerificationRedirectUrl = (0, import_url.constructRedirectUrl)(this.urls.emailVerification);
1242
+ const result = await this._interface.signUpWithCredential(
1243
+ options.email,
1244
+ options.password,
1245
+ emailVerificationRedirectUrl,
1246
+ session
1247
+ );
1248
+ if (result.status === "ok") {
1249
+ await this._signInToAccountWithTokens(result.data);
1250
+ if (!options.noRedirect) {
1251
+ await this.redirectToAfterSignUp({ replace: true });
1252
+ }
1253
+ return import_results.Result.ok(void 0);
1254
+ } else {
1255
+ return import_results.Result.error(result.error);
1256
+ }
1257
+ }
1258
+ async signInWithMagicLink(code) {
1259
+ this._ensurePersistentTokenStore();
1260
+ let result;
1261
+ try {
1262
+ result = await this._catchMfaRequiredError(async () => {
1263
+ return await this._interface.signInWithMagicLink(code);
1264
+ });
1265
+ } catch (e) {
1266
+ if (e instanceof import_stack_shared.KnownErrors.InvalidTotpCode) {
1267
+ return import_results.Result.error(e);
1268
+ }
1269
+ throw e;
1270
+ }
1271
+ if (result.status === "ok") {
1272
+ await this._signInToAccountWithTokens(result.data);
1273
+ if (result.data.newUser) {
1274
+ await this.redirectToAfterSignUp({ replace: true });
1275
+ } else {
1276
+ await this.redirectToAfterSignIn({ replace: true });
1277
+ }
1278
+ return import_results.Result.ok(void 0);
1279
+ } else {
1280
+ return import_results.Result.error(result.error);
1281
+ }
1282
+ }
1283
+ async signInWithPasskey() {
1284
+ this._ensurePersistentTokenStore();
1285
+ const session = await this._getSession();
1286
+ let result;
1287
+ try {
1288
+ result = await this._catchMfaRequiredError(async () => {
1289
+ const initiationResult = await this._interface.initiatePasskeyAuthentication({}, session);
1290
+ if (initiationResult.status !== "ok") {
1291
+ return import_results.Result.error(new import_stack_shared.KnownErrors.PasskeyAuthenticationFailed("Failed to get initiation options for passkey authentication"));
1292
+ }
1293
+ const { options_json, code } = initiationResult.data;
1294
+ if (options_json.rpId !== "THIS_VALUE_WILL_BE_REPLACED.example.com") {
1295
+ throw new import_errors.StackAssertionError(`Expected returned RP ID from server to equal sentinel, but found ${options_json.rpId}`);
1296
+ }
1297
+ options_json.rpId = window.location.hostname;
1298
+ const authentication_response = await (0, import_browser.startAuthentication)({ optionsJSON: options_json });
1299
+ return await this._interface.signInWithPasskey({ authentication_response, code });
1300
+ });
1301
+ } catch (error) {
1302
+ if (error instanceof import_browser.WebAuthnError) {
1303
+ return import_results.Result.error(new import_stack_shared.KnownErrors.PasskeyWebAuthnError(error.message, error.name));
1304
+ } else {
1305
+ return import_results.Result.error(new import_stack_shared.KnownErrors.PasskeyAuthenticationFailed("Failed to sign in with passkey"));
1306
+ }
1307
+ }
1308
+ if (result.status === "ok") {
1309
+ await this._signInToAccountWithTokens(result.data);
1310
+ await this.redirectToAfterSignIn({ replace: true });
1311
+ return import_results.Result.ok(void 0);
1312
+ } else {
1313
+ return import_results.Result.error(result.error);
1314
+ }
1315
+ }
1316
+ async callOAuthCallback() {
1317
+ if (typeof window === "undefined") {
1318
+ throw new Error("callOAuthCallback can currently only be called in a browser environment");
1319
+ }
1320
+ this._ensurePersistentTokenStore();
1321
+ let result;
1322
+ try {
1323
+ result = await this._catchMfaRequiredError(async () => {
1324
+ return await (0, import_auth.callOAuthCallback)(this._interface, this.urls.oauthCallback);
1325
+ });
1326
+ } catch (e) {
1327
+ if (e instanceof import_stack_shared.KnownErrors.InvalidTotpCode) {
1328
+ alert("Invalid TOTP code. Please try signing in again.");
1329
+ return false;
1330
+ } else {
1331
+ throw e;
1332
+ }
1333
+ }
1334
+ if (result.status === "ok" && result.data) {
1335
+ await this._signInToAccountWithTokens(result.data);
1336
+ if ("afterCallbackRedirectUrl" in result.data && result.data.afterCallbackRedirectUrl) {
1337
+ await this._redirectTo({ url: result.data.afterCallbackRedirectUrl, replace: true });
1338
+ return true;
1339
+ } else if (result.data.newUser) {
1340
+ await this.redirectToAfterSignUp({ replace: true });
1341
+ return true;
1342
+ } else {
1343
+ await this.redirectToAfterSignIn({ replace: true });
1344
+ return true;
1345
+ }
1346
+ }
1347
+ return false;
1348
+ }
1349
+ async _signOut(session, options) {
1350
+ await import_stores.storeLock.withWriteLock(async () => {
1351
+ await this._interface.signOut(session);
1352
+ if (options?.redirectUrl) {
1353
+ await this._redirectTo({ url: options.redirectUrl, replace: true });
1354
+ } else {
1355
+ await this.redirectToAfterSignOut();
1356
+ }
1357
+ });
1358
+ }
1359
+ async signOut(options) {
1360
+ const user = await this.getUser();
1361
+ if (user) {
1362
+ await user.signOut(options);
1363
+ }
1364
+ }
1365
+ async getProject() {
1366
+ const crud = import_results.Result.orThrow(await this._currentProjectCache.getOrWait([], "write-only"));
1367
+ return this._clientProjectFromCrud(crud);
1368
+ }
1369
+ useProject() {
1370
+ const crud = useAsyncCache(this._currentProjectCache, [], "useProject()");
1371
+ return (0, import_react2.useMemo)(() => this._clientProjectFromCrud(crud), [crud]);
1372
+ }
1373
+ async _listOwnedProjects(session) {
1374
+ this._ensureInternalProject();
1375
+ const crud = import_results.Result.orThrow(await this._ownedProjectsCache.getOrWait([session], "write-only"));
1376
+ return crud.map((j) => this._getOwnedAdminApp(j.id, session)._adminOwnedProjectFromCrud(
1377
+ j,
1378
+ () => this._refreshOwnedProjects(session)
1379
+ ));
1380
+ }
1381
+ _useOwnedProjects(session) {
1382
+ this._ensureInternalProject();
1383
+ const projects = useAsyncCache(this._ownedProjectsCache, [session], "useOwnedProjects()");
1384
+ return (0, import_react2.useMemo)(() => projects.map((j) => this._getOwnedAdminApp(j.id, session)._adminOwnedProjectFromCrud(
1385
+ j,
1386
+ () => this._refreshOwnedProjects(session)
1387
+ )), [projects]);
1388
+ }
1389
+ async _createProject(session, newProject) {
1390
+ this._ensureInternalProject();
1391
+ const crud = await this._interface.createProject(adminProjectCreateOptionsToCrud(newProject), session);
1392
+ const res = this._getOwnedAdminApp(crud.id, session)._adminOwnedProjectFromCrud(
1393
+ crud,
1394
+ () => this._refreshOwnedProjects(session)
1395
+ );
1396
+ await this._refreshOwnedProjects(session);
1397
+ return res;
1398
+ }
1399
+ async _refreshUser(session) {
1400
+ await this._refreshSession(session);
1401
+ }
1402
+ async _refreshSession(session) {
1403
+ await this._currentUserCache.refresh([session]);
1404
+ }
1405
+ async _refreshUsers() {
1406
+ }
1407
+ async _refreshProject() {
1408
+ await this._currentProjectCache.refresh([]);
1409
+ }
1410
+ async _refreshOwnedProjects(session) {
1411
+ await this._ownedProjectsCache.refresh([session]);
1412
+ }
1413
+ static get [stackAppInternalsSymbol]() {
1414
+ return {
1415
+ fromClientJson: (json) => {
1416
+ const providedCheckString = JSON.stringify((0, import_objects.omit)(json, [
1417
+ /* none currently */
1418
+ ]));
1419
+ const existing = allClientApps.get(json.uniqueIdentifier);
1420
+ if (existing) {
1421
+ const [existingCheckString, clientApp] = existing;
1422
+ if (existingCheckString !== providedCheckString) {
1423
+ throw new import_errors.StackAssertionError("The provided app JSON does not match the configuration of the existing client app with the same unique identifier", { providedObj: json, existingString: existingCheckString });
1424
+ }
1425
+ return clientApp;
1426
+ }
1427
+ return new __StackClientAppImpl({
1428
+ ...json,
1429
+ checkString: providedCheckString
1430
+ });
1431
+ }
1432
+ };
1433
+ }
1434
+ get [stackAppInternalsSymbol]() {
1435
+ return {
1436
+ toClientJson: () => {
1437
+ if (!("publishableClientKey" in this._interface.options)) {
1438
+ throw new import_errors.StackAssertionError("Cannot serialize to JSON from an application without a publishable client key");
1439
+ }
1440
+ if (typeof this._redirectMethod !== "string") {
1441
+ throw new import_errors.StackAssertionError("Cannot serialize to JSON from an application with a non-string redirect method");
1442
+ }
1443
+ return {
1444
+ baseUrl: this._options.baseUrl,
1445
+ projectId: this.projectId,
1446
+ publishableClientKey: this._interface.options.publishableClientKey,
1447
+ tokenStore: this._tokenStoreInit,
1448
+ urls: this._urlOptions,
1449
+ oauthScopesOnSignIn: this._oauthScopesOnSignIn,
1450
+ uniqueIdentifier: this._getUniqueIdentifier(),
1451
+ redirectMethod: this._redirectMethod
1452
+ };
1453
+ },
1454
+ setCurrentUser: (userJsonPromise) => {
1455
+ (0, import_promises.runAsynchronously)(async () => {
1456
+ await this._currentUserCache.forceSetCachedValueAsync([await this._getSession()], import_results.Result.fromPromise(userJsonPromise));
1457
+ });
1458
+ },
1459
+ sendRequest: async (path, requestOptions, requestType = "client") => {
1460
+ return await this._interface.sendClientRequest(path, requestOptions, await this._getSession(), requestType);
1461
+ }
1462
+ };
1463
+ }
1464
+ };
1465
+ var _StackServerAppImpl = class extends _StackClientAppImpl {
1466
+ constructor(options) {
1467
+ super("interface" in options ? {
1468
+ interface: options.interface,
1469
+ tokenStore: options.tokenStore,
1470
+ urls: options.urls,
1471
+ oauthScopesOnSignIn: options.oauthScopesOnSignIn
1472
+ } : {
1473
+ interface: new import_stack_shared.StackServerInterface({
1474
+ getBaseUrl: () => getBaseUrl(options.baseUrl),
1475
+ projectId: options.projectId ?? getDefaultProjectId(),
1476
+ clientVersion,
1477
+ publishableClientKey: options.publishableClientKey ?? getDefaultPublishableClientKey(),
1478
+ secretServerKey: options.secretServerKey ?? getDefaultSecretServerKey()
1479
+ }),
1480
+ baseUrl: options.baseUrl,
1481
+ projectId: options.projectId,
1482
+ publishableClientKey: options.publishableClientKey,
1483
+ tokenStore: options.tokenStore,
1484
+ urls: options.urls ?? {},
1485
+ oauthScopesOnSignIn: options.oauthScopesOnSignIn ?? {},
1486
+ redirectMethod: options.redirectMethod
1487
+ });
1488
+ // TODO override the client user cache to use the server user cache, so we save some requests
1489
+ this._currentServerUserCache = createCacheBySession(async (session) => {
1490
+ if (session.isKnownToBeInvalid()) {
1491
+ return null;
1492
+ }
1493
+ return await this._interface.getServerUserByToken(session);
1494
+ });
1495
+ this._serverUsersCache = createCache(async ([cursor, limit, orderBy, desc, query]) => {
1496
+ return await this._interface.listServerUsers({ cursor, limit, orderBy, desc, query });
1497
+ });
1498
+ this._serverUserCache = createCache(async ([userId]) => {
1499
+ const user = await this._interface.getServerUserById(userId);
1500
+ return import_results.Result.or(user, null);
1501
+ });
1502
+ this._serverTeamsCache = createCache(async ([userId]) => {
1503
+ return await this._interface.listServerTeams({ userId });
1504
+ });
1505
+ this._serverTeamUserPermissionsCache = createCache(async ([teamId, userId, recursive]) => {
1506
+ return await this._interface.listServerTeamPermissions({ teamId, userId, recursive }, null);
1507
+ });
1508
+ this._serverUserOAuthConnectionAccessTokensCache = createCache(
1509
+ async ([userId, providerId, scope]) => {
1510
+ try {
1511
+ const result = await this._interface.createServerProviderAccessToken(userId, providerId, scope || "");
1512
+ return { accessToken: result.access_token };
1513
+ } catch (err) {
1514
+ if (!(err instanceof import_stack_shared.KnownErrors.OAuthConnectionDoesNotHaveRequiredScope || err instanceof import_stack_shared.KnownErrors.OAuthConnectionNotConnectedToUser)) {
1515
+ throw err;
1516
+ }
1517
+ }
1518
+ return null;
1519
+ }
1520
+ );
1521
+ this._serverUserOAuthConnectionCache = createCache(
1522
+ async ([userId, providerId, scope, redirect]) => {
1523
+ return await this._getUserOAuthConnectionCacheFn({
1524
+ getUser: async () => import_results.Result.orThrow(await this._serverUserCache.getOrWait([userId], "write-only")),
1525
+ getOrWaitOAuthToken: async () => import_results.Result.orThrow(await this._serverUserOAuthConnectionAccessTokensCache.getOrWait([userId, providerId, scope || ""], "write-only")),
1526
+ useOAuthToken: () => useAsyncCache(this._serverUserOAuthConnectionAccessTokensCache, [userId, providerId, scope || ""], "user.useConnectedAccount()"),
1527
+ providerId,
1528
+ scope,
1529
+ redirect,
1530
+ session: null
1531
+ });
1532
+ }
1533
+ );
1534
+ this._serverTeamMemberProfilesCache = createCache(
1535
+ async ([teamId]) => {
1536
+ return await this._interface.listServerTeamMemberProfiles({ teamId });
1537
+ }
1538
+ );
1539
+ this._serverTeamInvitationsCache = createCache(
1540
+ async ([teamId]) => {
1541
+ return await this._interface.listServerTeamInvitations({ teamId });
1542
+ }
1543
+ );
1544
+ this._serverUserTeamProfileCache = createCache(
1545
+ async ([teamId, userId]) => {
1546
+ return await this._interface.getServerTeamMemberProfile({ teamId, userId });
1547
+ }
1548
+ );
1549
+ this._serverContactChannelsCache = createCache(
1550
+ async ([userId]) => {
1551
+ return await this._interface.listServerContactChannels(userId);
1552
+ }
1553
+ );
1554
+ }
1555
+ async _updateServerUser(userId, update) {
1556
+ const result = await this._interface.updateServerUser(userId, serverUserUpdateOptionsToCrud(update));
1557
+ await this._refreshUsers();
1558
+ return result;
1559
+ }
1560
+ _serverEditableTeamProfileFromCrud(crud) {
1561
+ const app = this;
1562
+ return {
1563
+ displayName: crud.display_name,
1564
+ profileImageUrl: crud.profile_image_url,
1565
+ async update(update) {
1566
+ await app._interface.updateServerTeamMemberProfile({
1567
+ teamId: crud.team_id,
1568
+ userId: crud.user_id,
1569
+ profile: {
1570
+ display_name: update.displayName,
1571
+ profile_image_url: update.profileImageUrl
1572
+ }
1573
+ });
1574
+ await app._serverUserTeamProfileCache.refresh([crud.team_id, crud.user_id]);
1575
+ }
1576
+ };
1577
+ }
1578
+ _serverContactChannelFromCrud(userId, crud) {
1579
+ const app = this;
1580
+ return {
1581
+ id: crud.id,
1582
+ value: crud.value,
1583
+ type: crud.type,
1584
+ isVerified: crud.is_verified,
1585
+ isPrimary: crud.is_primary,
1586
+ usedForAuth: crud.used_for_auth,
1587
+ async sendVerificationEmail(options) {
1588
+ if (!options?.callbackUrl && !await app._getCurrentUrl()) {
1589
+ throw new Error("Cannot send verification email without a callback URL from the server or without a redirect method. Make sure you pass the `callbackUrl` option: `sendVerificationEmail({ callbackUrl: ... })`");
1590
+ }
1591
+ await app._interface.sendServerContactChannelVerificationEmail(userId, crud.id, options?.callbackUrl ?? (0, import_url.constructRedirectUrl)(app.urls.emailVerification));
1592
+ },
1593
+ async update(data) {
1594
+ await app._interface.updateServerContactChannel(userId, crud.id, serverContactChannelUpdateOptionsToCrud(data));
1595
+ },
1596
+ async delete() {
1597
+ await app._interface.deleteServerContactChannel(userId, crud.id);
1598
+ }
1599
+ };
1600
+ }
1601
+ _serverUserFromCrud(crud) {
1602
+ const app = this;
1603
+ async function getConnectedAccount(id, options) {
1604
+ const scopeString = options?.scopes?.join(" ");
1605
+ return import_results.Result.orThrow(await app._serverUserOAuthConnectionCache.getOrWait([crud.id, id, scopeString || "", options?.or === "redirect"], "write-only"));
1606
+ }
1607
+ function useConnectedAccount(id, options) {
1608
+ const scopeString = options?.scopes?.join(" ");
1609
+ return useAsyncCache(app._serverUserOAuthConnectionCache, [crud.id, id, scopeString || "", options?.or === "redirect"], "user.useConnectedAccount()");
1610
+ }
1611
+ return {
1612
+ ...super._createBaseUser(crud),
1613
+ lastActiveAt: new Date(crud.last_active_at_millis),
1614
+ serverMetadata: crud.server_metadata,
1615
+ async setPrimaryEmail(email, options) {
1616
+ await app._updateServerUser(crud.id, { primaryEmail: email, primaryEmailVerified: options?.verified });
1617
+ },
1618
+ async grantPermission(scope, permissionId) {
1619
+ await app._interface.grantServerTeamUserPermission(scope.id, crud.id, permissionId);
1620
+ for (const recursive of [true, false]) {
1621
+ await app._serverTeamUserPermissionsCache.refresh([scope.id, crud.id, recursive]);
1622
+ }
1623
+ },
1624
+ async revokePermission(scope, permissionId) {
1625
+ await app._interface.revokeServerTeamUserPermission(scope.id, crud.id, permissionId);
1626
+ for (const recursive of [true, false]) {
1627
+ await app._serverTeamUserPermissionsCache.refresh([scope.id, crud.id, recursive]);
1628
+ }
1629
+ },
1630
+ async delete() {
1631
+ const res = await app._interface.deleteServerServerUser(crud.id);
1632
+ await app._refreshUsers();
1633
+ return res;
1634
+ },
1635
+ async createSession(options) {
1636
+ const tokens = await app._interface.createServerUserSession(crud.id, options.expiresInMillis ?? 1e3 * 60 * 60 * 24 * 365);
1637
+ return {
1638
+ async getTokens() {
1639
+ return tokens;
1640
+ }
1641
+ };
1642
+ },
1643
+ async setDisplayName(displayName) {
1644
+ return await this.update({ displayName });
1645
+ },
1646
+ async setClientMetadata(metadata) {
1647
+ return await this.update({ clientMetadata: metadata });
1648
+ },
1649
+ async setClientReadOnlyMetadata(metadata) {
1650
+ return await this.update({ clientReadOnlyMetadata: metadata });
1651
+ },
1652
+ async setServerMetadata(metadata) {
1653
+ return await this.update({ serverMetadata: metadata });
1654
+ },
1655
+ async setSelectedTeam(team) {
1656
+ return await this.update({ selectedTeamId: team?.id ?? null });
1657
+ },
1658
+ getConnectedAccount,
1659
+ useConnectedAccount,
1660
+ selectedTeam: crud.selected_team ? app._serverTeamFromCrud(crud.selected_team) : null,
1661
+ async getTeam(teamId) {
1662
+ const teams = await this.listTeams();
1663
+ return teams.find((t) => t.id === teamId) ?? null;
1664
+ },
1665
+ useTeam(teamId) {
1666
+ const teams = this.useTeams();
1667
+ return (0, import_react2.useMemo)(() => {
1668
+ return teams.find((t) => t.id === teamId) ?? null;
1669
+ }, [teams, teamId]);
1670
+ },
1671
+ async listTeams() {
1672
+ const teams = import_results.Result.orThrow(await app._serverTeamsCache.getOrWait([crud.id], "write-only"));
1673
+ return teams.map((t) => app._serverTeamFromCrud(t));
1674
+ },
1675
+ useTeams() {
1676
+ const teams = useAsyncCache(app._serverTeamsCache, [crud.id], "user.useTeams()");
1677
+ return (0, import_react2.useMemo)(() => teams.map((t) => app._serverTeamFromCrud(t)), [teams]);
1678
+ },
1679
+ createTeam: async (data) => {
1680
+ const team = await app._interface.createServerTeam(serverTeamCreateOptionsToCrud({
1681
+ creatorUserId: crud.id,
1682
+ ...data
1683
+ }));
1684
+ await app._serverTeamsCache.refresh([void 0]);
1685
+ return app._serverTeamFromCrud(team);
1686
+ },
1687
+ leaveTeam: async (team) => {
1688
+ await app._interface.leaveServerTeam({ teamId: team.id, userId: crud.id });
1689
+ },
1690
+ async listPermissions(scope, options) {
1691
+ const recursive = options?.recursive ?? true;
1692
+ const permissions = import_results.Result.orThrow(await app._serverTeamUserPermissionsCache.getOrWait([scope.id, crud.id, recursive], "write-only"));
1693
+ return permissions.map((crud2) => app._serverPermissionFromCrud(crud2));
1694
+ },
1695
+ usePermissions(scope, options) {
1696
+ const recursive = options?.recursive ?? true;
1697
+ const permissions = useAsyncCache(app._serverTeamUserPermissionsCache, [scope.id, crud.id, recursive], "user.usePermissions()");
1698
+ return (0, import_react2.useMemo)(() => permissions.map((crud2) => app._serverPermissionFromCrud(crud2)), [permissions]);
1699
+ },
1700
+ async getPermission(scope, permissionId) {
1701
+ const permissions = await this.listPermissions(scope);
1702
+ return permissions.find((p) => p.id === permissionId) ?? null;
1703
+ },
1704
+ usePermission(scope, permissionId) {
1705
+ const permissions = this.usePermissions(scope);
1706
+ return (0, import_react2.useMemo)(() => permissions.find((p) => p.id === permissionId) ?? null, [permissions, permissionId]);
1707
+ },
1708
+ async hasPermission(scope, permissionId) {
1709
+ return await this.getPermission(scope, permissionId) !== null;
1710
+ },
1711
+ async update(update) {
1712
+ await app._updateServerUser(crud.id, update);
1713
+ },
1714
+ async sendVerificationEmail() {
1715
+ return await app._checkFeatureSupport("sendVerificationEmail() on ServerUser", {});
1716
+ },
1717
+ async updatePassword(options) {
1718
+ const result = await this.update({ password: options.newPassword });
1719
+ await app._serverUserCache.refresh([crud.id]);
1720
+ return result;
1721
+ },
1722
+ async setPassword(options) {
1723
+ const result = await this.update(options);
1724
+ await app._serverUserCache.refresh([crud.id]);
1725
+ return result;
1726
+ },
1727
+ async getTeamProfile(team) {
1728
+ const result = import_results.Result.orThrow(await app._serverUserTeamProfileCache.getOrWait([team.id, crud.id], "write-only"));
1729
+ return app._serverEditableTeamProfileFromCrud(result);
1730
+ },
1731
+ useTeamProfile(team) {
1732
+ const result = useAsyncCache(app._serverUserTeamProfileCache, [team.id, crud.id], "user.useTeamProfile()");
1733
+ return (0, import_react2.useMemo)(() => app._serverEditableTeamProfileFromCrud(result), [result]);
1734
+ },
1735
+ async listContactChannels() {
1736
+ const result = import_results.Result.orThrow(await app._serverContactChannelsCache.getOrWait([crud.id], "write-only"));
1737
+ return result.map((data) => app._serverContactChannelFromCrud(crud.id, data));
1738
+ },
1739
+ useContactChannels() {
1740
+ const result = useAsyncCache(app._serverContactChannelsCache, [crud.id], "user.useContactChannels()");
1741
+ return (0, import_react2.useMemo)(() => result.map((data) => app._serverContactChannelFromCrud(crud.id, data)), [result]);
1742
+ },
1743
+ createContactChannel: async (data) => {
1744
+ const contactChannel = await app._interface.createServerContactChannel(serverContactChannelCreateOptionsToCrud(crud.id, data));
1745
+ await app._serverContactChannelsCache.refresh([crud.id]);
1746
+ return app._serverContactChannelFromCrud(crud.id, contactChannel);
1747
+ }
1748
+ };
1749
+ }
1750
+ _serverTeamUserFromCrud(crud) {
1751
+ return {
1752
+ ...this._serverUserFromCrud(crud.user),
1753
+ teamProfile: {
1754
+ displayName: crud.display_name,
1755
+ profileImageUrl: crud.profile_image_url
1756
+ }
1757
+ };
1758
+ }
1759
+ _serverTeamInvitationFromCrud(crud) {
1760
+ return {
1761
+ id: crud.id,
1762
+ recipientEmail: crud.recipient_email,
1763
+ expiresAt: new Date(crud.expires_at_millis),
1764
+ revoke: async () => {
1765
+ await this._interface.revokeServerTeamInvitation(crud.id, crud.team_id);
1766
+ }
1767
+ };
1768
+ }
1769
+ _currentUserFromCrud(crud, session) {
1770
+ const app = this;
1771
+ const currentUser = {
1772
+ ...this._serverUserFromCrud(crud),
1773
+ ...this._createAuth(session),
1774
+ ...this._isInternalProject() ? this._createInternalUserExtra(session) : {}
1775
+ };
1776
+ Object.freeze(currentUser);
1777
+ return currentUser;
1778
+ }
1779
+ _serverTeamFromCrud(crud) {
1780
+ const app = this;
1781
+ return {
1782
+ id: crud.id,
1783
+ displayName: crud.display_name,
1784
+ profileImageUrl: crud.profile_image_url,
1785
+ createdAt: new Date(crud.created_at_millis),
1786
+ clientMetadata: crud.client_metadata,
1787
+ clientReadOnlyMetadata: crud.client_read_only_metadata,
1788
+ serverMetadata: crud.server_metadata,
1789
+ async update(update) {
1790
+ await app._interface.updateServerTeam(crud.id, serverTeamUpdateOptionsToCrud(update));
1791
+ await app._serverTeamsCache.refresh([void 0]);
1792
+ },
1793
+ async delete() {
1794
+ await app._interface.deleteServerTeam(crud.id);
1795
+ await app._serverTeamsCache.refresh([void 0]);
1796
+ },
1797
+ async listUsers() {
1798
+ const result = import_results.Result.orThrow(await app._serverTeamMemberProfilesCache.getOrWait([crud.id], "write-only"));
1799
+ return result.map((u) => app._serverTeamUserFromCrud(u));
1800
+ },
1801
+ useUsers() {
1802
+ const result = useAsyncCache(app._serverTeamMemberProfilesCache, [crud.id], "team.useUsers()");
1803
+ return (0, import_react2.useMemo)(() => result.map((u) => app._serverTeamUserFromCrud(u)), [result]);
1804
+ },
1805
+ async addUser(userId) {
1806
+ await app._interface.addServerUserToTeam({
1807
+ teamId: crud.id,
1808
+ userId
1809
+ });
1810
+ await app._serverTeamMemberProfilesCache.refresh([crud.id]);
1811
+ },
1812
+ async removeUser(userId) {
1813
+ await app._interface.removeServerUserFromTeam({
1814
+ teamId: crud.id,
1815
+ userId
1816
+ });
1817
+ await app._serverTeamMemberProfilesCache.refresh([crud.id]);
1818
+ },
1819
+ async inviteUser(options) {
1820
+ if (!options.callbackUrl && !await app._getCurrentUrl()) {
1821
+ throw new Error("Cannot invite user without a callback URL from the server or without a redirect method. Make sure you pass the `callbackUrl` option: `inviteUser({ email, callbackUrl: ... })`");
1822
+ }
1823
+ await app._interface.sendServerTeamInvitation({
1824
+ teamId: crud.id,
1825
+ email: options.email,
1826
+ callbackUrl: options.callbackUrl ?? (0, import_url.constructRedirectUrl)(app.urls.teamInvitation)
1827
+ });
1828
+ await app._serverTeamInvitationsCache.refresh([crud.id]);
1829
+ },
1830
+ async listInvitations() {
1831
+ const result = import_results.Result.orThrow(await app._serverTeamInvitationsCache.getOrWait([crud.id], "write-only"));
1832
+ return result.map((crud2) => app._serverTeamInvitationFromCrud(crud2));
1833
+ },
1834
+ useInvitations() {
1835
+ const result = useAsyncCache(app._serverTeamInvitationsCache, [crud.id], "team.useInvitations()");
1836
+ return (0, import_react2.useMemo)(() => result.map((crud2) => app._serverTeamInvitationFromCrud(crud2)), [result]);
1837
+ }
1838
+ };
1839
+ }
1840
+ async createUser(options) {
1841
+ const crud = await this._interface.createServerUser(serverUserCreateOptionsToCrud(options));
1842
+ await this._refreshUsers();
1843
+ return this._serverUserFromCrud(crud);
1844
+ }
1845
+ async getUser(options) {
1846
+ if (typeof options === "string") {
1847
+ return await this.getServerUserById(options);
1848
+ } else {
1849
+ this._ensurePersistentTokenStore(options?.tokenStore);
1850
+ const session = await this._getSession(options?.tokenStore);
1851
+ const crud = import_results.Result.orThrow(await this._currentServerUserCache.getOrWait([session], "write-only"));
1852
+ if (crud === null) {
1853
+ switch (options?.or) {
1854
+ case "redirect": {
1855
+ await this.redirectToSignIn({ replace: true });
1856
+ break;
1857
+ }
1858
+ case "throw": {
1859
+ throw new Error("User is not signed in but getUser was called with { or: 'throw' }");
1860
+ }
1861
+ default: {
1862
+ return null;
1863
+ }
1864
+ }
1865
+ }
1866
+ return crud && this._currentUserFromCrud(crud, session);
1867
+ }
1868
+ }
1869
+ async getServerUser() {
1870
+ console.warn("stackServerApp.getServerUser is deprecated; use stackServerApp.getUser instead");
1871
+ return await this.getUser();
1872
+ }
1873
+ async getServerUserById(userId) {
1874
+ const crud = import_results.Result.orThrow(await this._serverUserCache.getOrWait([userId], "write-only"));
1875
+ return crud && this._serverUserFromCrud(crud);
1876
+ }
1877
+ useUser(options) {
1878
+ if (typeof options === "string") {
1879
+ return this.useUserById(options);
1880
+ } else {
1881
+ this._ensurePersistentTokenStore(options?.tokenStore);
1882
+ const session = this._useSession(options?.tokenStore);
1883
+ const crud = useAsyncCache(this._currentServerUserCache, [session], "useUser()");
1884
+ if (crud === null) {
1885
+ switch (options?.or) {
1886
+ case "redirect": {
1887
+ (0, import_promises.runAsynchronously)(this.redirectToSignIn({ replace: true }));
1888
+ (0, import_react.suspend)();
1889
+ throw new import_errors.StackAssertionError("suspend should never return");
1890
+ }
1891
+ case "throw": {
1892
+ throw new Error("User is not signed in but useUser was called with { or: 'throw' }");
1893
+ }
1894
+ case void 0:
1895
+ case "return-null": {
1896
+ }
1897
+ }
1898
+ }
1899
+ return (0, import_react2.useMemo)(() => {
1900
+ return crud && this._currentUserFromCrud(crud, session);
1901
+ }, [crud, session, options?.or]);
1902
+ }
1903
+ }
1904
+ useUserById(userId) {
1905
+ const crud = useAsyncCache(this._serverUserCache, [userId], "useUserById()");
1906
+ return (0, import_react2.useMemo)(() => {
1907
+ return crud && this._serverUserFromCrud(crud);
1908
+ }, [crud]);
1909
+ }
1910
+ async listUsers(options) {
1911
+ const crud = import_results.Result.orThrow(await this._serverUsersCache.getOrWait([options?.cursor, options?.limit, options?.orderBy, options?.desc, options?.query], "write-only"));
1912
+ const result = crud.items.map((j) => this._serverUserFromCrud(j));
1913
+ result.nextCursor = crud.pagination?.next_cursor ?? null;
1914
+ return result;
1915
+ }
1916
+ useUsers(options) {
1917
+ const crud = useAsyncCache(this._serverUsersCache, [options?.cursor, options?.limit, options?.orderBy, options?.desc, options?.query], "useServerUsers()");
1918
+ const result = crud.items.map((j) => this._serverUserFromCrud(j));
1919
+ result.nextCursor = crud.pagination?.next_cursor ?? null;
1920
+ return result;
1921
+ }
1922
+ _serverPermissionFromCrud(crud) {
1923
+ return {
1924
+ id: crud.id
1925
+ };
1926
+ }
1927
+ _serverTeamPermissionDefinitionFromCrud(crud) {
1928
+ return {
1929
+ id: crud.id,
1930
+ description: crud.description,
1931
+ containedPermissionIds: crud.contained_permission_ids
1932
+ };
1933
+ }
1934
+ async listTeams() {
1935
+ const teams = import_results.Result.orThrow(await this._serverTeamsCache.getOrWait([void 0], "write-only"));
1936
+ return teams.map((t) => this._serverTeamFromCrud(t));
1937
+ }
1938
+ async createTeam(data) {
1939
+ const team = await this._interface.createServerTeam(serverTeamCreateOptionsToCrud(data));
1940
+ await this._serverTeamsCache.refresh([void 0]);
1941
+ return this._serverTeamFromCrud(team);
1942
+ }
1943
+ useTeams() {
1944
+ const teams = useAsyncCache(this._serverTeamsCache, [void 0], "useServerTeams()");
1945
+ return (0, import_react2.useMemo)(() => {
1946
+ return teams.map((t) => this._serverTeamFromCrud(t));
1947
+ }, [teams]);
1948
+ }
1949
+ async getTeam(teamId) {
1950
+ const teams = await this.listTeams();
1951
+ return teams.find((t) => t.id === teamId) ?? null;
1952
+ }
1953
+ useTeam(teamId) {
1954
+ const teams = this.useTeams();
1955
+ return (0, import_react2.useMemo)(() => {
1956
+ return teams.find((t) => t.id === teamId) ?? null;
1957
+ }, [teams, teamId]);
1958
+ }
1959
+ async _refreshSession(session) {
1960
+ await Promise.all([
1961
+ super._refreshUser(session),
1962
+ this._currentServerUserCache.refresh([session])
1963
+ ]);
1964
+ }
1965
+ async _refreshUsers() {
1966
+ await Promise.all([
1967
+ super._refreshUsers(),
1968
+ this._serverUserCache.refreshWhere(() => true),
1969
+ this._serverUsersCache.refreshWhere(() => true),
1970
+ this._serverContactChannelsCache.refreshWhere(() => true)
1971
+ ]);
1972
+ }
1973
+ };
1974
+ var _StackAdminAppImpl = class extends _StackServerAppImpl {
1975
+ constructor(options) {
1976
+ super({
1977
+ interface: new import_stack_shared.StackAdminInterface({
1978
+ getBaseUrl: () => getBaseUrl(options.baseUrl),
1979
+ projectId: options.projectId ?? getDefaultProjectId(),
1980
+ clientVersion,
1981
+ ..."projectOwnerSession" in options ? {
1982
+ projectOwnerSession: options.projectOwnerSession
1983
+ } : {
1984
+ publishableClientKey: options.publishableClientKey ?? getDefaultPublishableClientKey(),
1985
+ secretServerKey: options.secretServerKey ?? getDefaultSecretServerKey(),
1986
+ superSecretAdminKey: options.superSecretAdminKey ?? getDefaultSuperSecretAdminKey()
1987
+ }
1988
+ }),
1989
+ baseUrl: options.baseUrl,
1990
+ projectId: options.projectId,
1991
+ tokenStore: options.tokenStore,
1992
+ urls: options.urls,
1993
+ oauthScopesOnSignIn: options.oauthScopesOnSignIn,
1994
+ redirectMethod: options.redirectMethod
1995
+ });
1996
+ this._adminProjectCache = createCache(async () => {
1997
+ return await this._interface.getProject();
1998
+ });
1999
+ this._apiKeysCache = createCache(async () => {
2000
+ return await this._interface.listApiKeys();
2001
+ });
2002
+ this._adminEmailTemplatesCache = createCache(async () => {
2003
+ return await this._interface.listEmailTemplates();
2004
+ });
2005
+ this._adminTeamPermissionDefinitionsCache = createCache(async () => {
2006
+ return await this._interface.listPermissionDefinitions();
2007
+ });
2008
+ this._svixTokenCache = createCache(async () => {
2009
+ return await this._interface.getSvixToken();
2010
+ });
2011
+ this._metricsCache = createCache(async () => {
2012
+ return await this._interface.getMetrics();
2013
+ });
2014
+ }
2015
+ _adminOwnedProjectFromCrud(data, onRefresh) {
2016
+ if (this._tokenStoreInit !== null) {
2017
+ throw new import_errors.StackAssertionError("Owned apps must always have tokenStore === null \u2014 did you not create this project with app._createOwnedApp()?");
2018
+ ;
2019
+ }
2020
+ return {
2021
+ ...this._adminProjectFromCrud(data, onRefresh),
2022
+ app: this
2023
+ };
2024
+ }
2025
+ _adminProjectFromCrud(data, onRefresh) {
2026
+ if (data.id !== this.projectId) {
2027
+ throw new import_errors.StackAssertionError(`The project ID of the provided project JSON (${data.id}) does not match the project ID of the app (${this.projectId})!`);
2028
+ }
2029
+ const app = this;
2030
+ return {
2031
+ id: data.id,
2032
+ displayName: data.display_name,
2033
+ description: data.description,
2034
+ createdAt: new Date(data.created_at_millis),
2035
+ userCount: data.user_count,
2036
+ isProductionMode: data.is_production_mode,
2037
+ config: {
2038
+ id: data.config.id,
2039
+ signUpEnabled: data.config.sign_up_enabled,
2040
+ credentialEnabled: data.config.credential_enabled,
2041
+ magicLinkEnabled: data.config.magic_link_enabled,
2042
+ passkeyEnabled: data.config.passkey_enabled,
2043
+ clientTeamCreationEnabled: data.config.client_team_creation_enabled,
2044
+ clientUserDeletionEnabled: data.config.client_user_deletion_enabled,
2045
+ allowLocalhost: data.config.allow_localhost,
2046
+ oauthProviders: data.config.oauth_providers.map((p) => p.type === "shared" ? {
2047
+ id: p.id,
2048
+ enabled: p.enabled,
2049
+ type: "shared"
2050
+ } : {
2051
+ id: p.id,
2052
+ enabled: p.enabled,
2053
+ type: "standard",
2054
+ clientId: p.client_id ?? (0, import_errors.throwErr)("Client ID is missing"),
2055
+ clientSecret: p.client_secret ?? (0, import_errors.throwErr)("Client secret is missing"),
2056
+ facebookConfigId: p.facebook_config_id,
2057
+ microsoftTenantId: p.microsoft_tenant_id
2058
+ }),
2059
+ emailConfig: data.config.email_config.type === "shared" ? {
2060
+ type: "shared"
2061
+ } : {
2062
+ type: "standard",
2063
+ host: data.config.email_config.host ?? (0, import_errors.throwErr)("Email host is missing"),
2064
+ port: data.config.email_config.port ?? (0, import_errors.throwErr)("Email port is missing"),
2065
+ username: data.config.email_config.username ?? (0, import_errors.throwErr)("Email username is missing"),
2066
+ password: data.config.email_config.password ?? (0, import_errors.throwErr)("Email password is missing"),
2067
+ senderName: data.config.email_config.sender_name ?? (0, import_errors.throwErr)("Email sender name is missing"),
2068
+ senderEmail: data.config.email_config.sender_email ?? (0, import_errors.throwErr)("Email sender email is missing")
2069
+ },
2070
+ domains: data.config.domains.map((d) => ({
2071
+ domain: d.domain,
2072
+ handlerPath: d.handler_path
2073
+ })),
2074
+ createTeamOnSignUp: data.config.create_team_on_sign_up,
2075
+ teamCreatorDefaultPermissions: data.config.team_creator_default_permissions,
2076
+ teamMemberDefaultPermissions: data.config.team_member_default_permissions
2077
+ },
2078
+ async update(update) {
2079
+ await app._interface.updateProject(adminProjectUpdateOptionsToCrud(update));
2080
+ await onRefresh();
2081
+ },
2082
+ async delete() {
2083
+ await app._interface.deleteProject();
2084
+ },
2085
+ async getProductionModeErrors() {
2086
+ return (0, import_production_mode.getProductionModeErrors)(data);
2087
+ },
2088
+ useProductionModeErrors() {
2089
+ return (0, import_production_mode.getProductionModeErrors)(data);
2090
+ }
2091
+ };
2092
+ }
2093
+ _adminEmailTemplateFromCrud(data) {
2094
+ return {
2095
+ type: data.type,
2096
+ subject: data.subject,
2097
+ content: data.content,
2098
+ isDefault: data.is_default
2099
+ };
2100
+ }
2101
+ async getProject() {
2102
+ return this._adminProjectFromCrud(
2103
+ import_results.Result.orThrow(await this._adminProjectCache.getOrWait([], "write-only")),
2104
+ () => this._refreshProject()
2105
+ );
2106
+ }
2107
+ useProject() {
2108
+ const crud = useAsyncCache(this._adminProjectCache, [], "useProjectAdmin()");
2109
+ return (0, import_react2.useMemo)(() => this._adminProjectFromCrud(
2110
+ crud,
2111
+ () => this._refreshProject()
2112
+ ), [crud]);
2113
+ }
2114
+ _createApiKeyBaseFromCrud(data) {
2115
+ const app = this;
2116
+ return {
2117
+ id: data.id,
2118
+ description: data.description,
2119
+ expiresAt: new Date(data.expires_at_millis),
2120
+ manuallyRevokedAt: data.manually_revoked_at_millis ? new Date(data.manually_revoked_at_millis) : null,
2121
+ createdAt: new Date(data.created_at_millis),
2122
+ isValid() {
2123
+ return this.whyInvalid() === null;
2124
+ },
2125
+ whyInvalid() {
2126
+ if (this.expiresAt.getTime() < Date.now()) return "expired";
2127
+ if (this.manuallyRevokedAt) return "manually-revoked";
2128
+ return null;
2129
+ },
2130
+ async revoke() {
2131
+ const res = await app._interface.revokeApiKeyById(data.id);
2132
+ await app._refreshApiKeys();
2133
+ return res;
2134
+ }
2135
+ };
2136
+ }
2137
+ _createApiKeyFromCrud(data) {
2138
+ return {
2139
+ ...this._createApiKeyBaseFromCrud(data),
2140
+ publishableClientKey: data.publishable_client_key ? { lastFour: data.publishable_client_key.last_four } : null,
2141
+ secretServerKey: data.secret_server_key ? { lastFour: data.secret_server_key.last_four } : null,
2142
+ superSecretAdminKey: data.super_secret_admin_key ? { lastFour: data.super_secret_admin_key.last_four } : null
2143
+ };
2144
+ }
2145
+ _createApiKeyFirstViewFromCrud(data) {
2146
+ return {
2147
+ ...this._createApiKeyBaseFromCrud(data),
2148
+ publishableClientKey: data.publishable_client_key,
2149
+ secretServerKey: data.secret_server_key,
2150
+ superSecretAdminKey: data.super_secret_admin_key
2151
+ };
2152
+ }
2153
+ async listApiKeys() {
2154
+ const crud = import_results.Result.orThrow(await this._apiKeysCache.getOrWait([], "write-only"));
2155
+ return crud.map((j) => this._createApiKeyFromCrud(j));
2156
+ }
2157
+ useApiKeys() {
2158
+ const crud = useAsyncCache(this._apiKeysCache, [], "useApiKeys()");
2159
+ return (0, import_react2.useMemo)(() => {
2160
+ return crud.map((j) => this._createApiKeyFromCrud(j));
2161
+ }, [crud]);
2162
+ }
2163
+ async createApiKey(options) {
2164
+ const crud = await this._interface.createApiKey(apiKeyCreateOptionsToCrud(options));
2165
+ await this._refreshApiKeys();
2166
+ return this._createApiKeyFirstViewFromCrud(crud);
2167
+ }
2168
+ useEmailTemplates() {
2169
+ const crud = useAsyncCache(this._adminEmailTemplatesCache, [], "useEmailTemplates()");
2170
+ return (0, import_react2.useMemo)(() => {
2171
+ return crud.map((j) => this._adminEmailTemplateFromCrud(j));
2172
+ }, [crud]);
2173
+ }
2174
+ async listEmailTemplates() {
2175
+ const crud = import_results.Result.orThrow(await this._adminEmailTemplatesCache.getOrWait([], "write-only"));
2176
+ return crud.map((j) => this._adminEmailTemplateFromCrud(j));
2177
+ }
2178
+ async updateEmailTemplate(type, data) {
2179
+ await this._interface.updateEmailTemplate(type, adminEmailTemplateUpdateOptionsToCrud(data));
2180
+ await this._adminEmailTemplatesCache.refresh([]);
2181
+ }
2182
+ async resetEmailTemplate(type) {
2183
+ await this._interface.resetEmailTemplate(type);
2184
+ await this._adminEmailTemplatesCache.refresh([]);
2185
+ }
2186
+ async createTeamPermissionDefinition(data) {
2187
+ const crud = await this._interface.createPermissionDefinition(serverTeamPermissionDefinitionCreateOptionsToCrud(data));
2188
+ await this._adminTeamPermissionDefinitionsCache.refresh([]);
2189
+ return this._serverTeamPermissionDefinitionFromCrud(crud);
2190
+ }
2191
+ async updateTeamPermissionDefinition(permissionId, data) {
2192
+ await this._interface.updatePermissionDefinition(permissionId, serverTeamPermissionDefinitionUpdateOptionsToCrud(data));
2193
+ await this._adminTeamPermissionDefinitionsCache.refresh([]);
2194
+ }
2195
+ async deleteTeamPermissionDefinition(permissionId) {
2196
+ await this._interface.deletePermissionDefinition(permissionId);
2197
+ await this._adminTeamPermissionDefinitionsCache.refresh([]);
2198
+ }
2199
+ async listTeamPermissionDefinitions() {
2200
+ const crud = import_results.Result.orThrow(await this._adminTeamPermissionDefinitionsCache.getOrWait([], "write-only"));
2201
+ return crud.map((p) => this._serverTeamPermissionDefinitionFromCrud(p));
2202
+ }
2203
+ useTeamPermissionDefinitions() {
2204
+ const crud = useAsyncCache(this._adminTeamPermissionDefinitionsCache, [], "usePermissions()");
2205
+ return (0, import_react2.useMemo)(() => {
2206
+ return crud.map((p) => this._serverTeamPermissionDefinitionFromCrud(p));
2207
+ }, [crud]);
2208
+ }
2209
+ useSvixToken() {
2210
+ const crud = useAsyncCache(this._svixTokenCache, [], "useSvixToken()");
2211
+ return crud.token;
2212
+ }
2213
+ async _refreshProject() {
2214
+ await Promise.all([
2215
+ super._refreshProject(),
2216
+ this._adminProjectCache.refresh([])
2217
+ ]);
2218
+ }
2219
+ async _refreshApiKeys() {
2220
+ await this._apiKeysCache.refresh([]);
2221
+ }
2222
+ get [stackAppInternalsSymbol]() {
2223
+ return {
2224
+ ...super[stackAppInternalsSymbol],
2225
+ useMetrics: () => {
2226
+ return useAsyncCache(this._metricsCache, [], "useMetrics()");
2227
+ }
2228
+ };
2229
+ }
2230
+ async sendTestEmail(options) {
2231
+ const response = await this._interface.sendTestEmail({
2232
+ recipient_email: options.recipientEmail,
2233
+ email_config: {
2234
+ ...(0, import_objects.pick)(options.emailConfig, ["host", "port", "username", "password"]),
2235
+ sender_email: options.emailConfig.senderEmail,
2236
+ sender_name: options.emailConfig.senderName
2237
+ }
2238
+ });
2239
+ if (response.success) {
2240
+ return import_results.Result.ok(void 0);
2241
+ } else {
2242
+ return import_results.Result.error({ errorMessage: response.error_message ?? (0, import_errors.throwErr)("Email test error not specified") });
2243
+ }
2244
+ }
2245
+ };
2246
+ function contactChannelCreateOptionsToCrud(userId, options) {
2247
+ return {
2248
+ value: options.value,
2249
+ type: options.type,
2250
+ used_for_auth: options.usedForAuth,
2251
+ user_id: userId
2252
+ };
2253
+ }
2254
+ function contactChannelUpdateOptionsToCrud(options) {
2255
+ return {
2256
+ value: options.value,
2257
+ used_for_auth: options.usedForAuth,
2258
+ is_primary: options.isPrimary
2259
+ };
2260
+ }
2261
+ function serverContactChannelUpdateOptionsToCrud(options) {
2262
+ return {
2263
+ value: options.value,
2264
+ is_verified: options.isVerified,
2265
+ used_for_auth: options.usedForAuth
2266
+ };
2267
+ }
2268
+ function serverContactChannelCreateOptionsToCrud(userId, options) {
2269
+ return {
2270
+ type: options.type,
2271
+ value: options.value,
2272
+ is_verified: options.isVerified,
2273
+ user_id: userId,
2274
+ used_for_auth: options.usedForAuth
2275
+ };
2276
+ }
2277
+ function userUpdateOptionsToCrud(options) {
2278
+ return {
2279
+ display_name: options.displayName,
2280
+ client_metadata: options.clientMetadata,
2281
+ selected_team_id: options.selectedTeamId,
2282
+ totp_secret_base64: options.totpMultiFactorSecret != null ? (0, import_bytes.encodeBase64)(options.totpMultiFactorSecret) : options.totpMultiFactorSecret,
2283
+ profile_image_url: options.profileImageUrl,
2284
+ otp_auth_enabled: options.otpAuthEnabled,
2285
+ passkey_auth_enabled: options.passkeyAuthEnabled
2286
+ };
2287
+ }
2288
+ function serverUserUpdateOptionsToCrud(options) {
2289
+ return {
2290
+ display_name: options.displayName,
2291
+ primary_email: options.primaryEmail,
2292
+ client_metadata: options.clientMetadata,
2293
+ client_read_only_metadata: options.clientReadOnlyMetadata,
2294
+ server_metadata: options.serverMetadata,
2295
+ selected_team_id: options.selectedTeamId,
2296
+ primary_email_auth_enabled: options.primaryEmailAuthEnabled,
2297
+ primary_email_verified: options.primaryEmailVerified,
2298
+ password: options.password,
2299
+ profile_image_url: options.profileImageUrl,
2300
+ totp_secret_base64: options.totpMultiFactorSecret != null ? (0, import_bytes.encodeBase64)(options.totpMultiFactorSecret) : options.totpMultiFactorSecret
2301
+ };
2302
+ }
2303
+ function serverUserCreateOptionsToCrud(options) {
2304
+ return {
2305
+ primary_email: options.primaryEmail,
2306
+ password: options.password,
2307
+ otp_auth_enabled: options.otpAuthEnabled,
2308
+ primary_email_auth_enabled: options.primaryEmailAuthEnabled,
2309
+ display_name: options.displayName,
2310
+ primary_email_verified: options.primaryEmailVerified,
2311
+ client_metadata: options.clientMetadata,
2312
+ client_read_only_metadata: options.clientReadOnlyMetadata,
2313
+ server_metadata: options.serverMetadata
2314
+ };
2315
+ }
2316
+ function adminProjectUpdateOptionsToCrud(options) {
2317
+ return {
2318
+ display_name: options.displayName,
2319
+ description: options.description,
2320
+ is_production_mode: options.isProductionMode,
2321
+ config: {
2322
+ domains: options.config?.domains?.map((d) => ({
2323
+ domain: d.domain,
2324
+ handler_path: d.handlerPath
2325
+ })),
2326
+ oauth_providers: options.config?.oauthProviders?.map((p) => ({
2327
+ id: p.id,
2328
+ enabled: p.enabled,
2329
+ type: p.type,
2330
+ ...p.type === "standard" && {
2331
+ client_id: p.clientId,
2332
+ client_secret: p.clientSecret,
2333
+ facebook_config_id: p.facebookConfigId,
2334
+ microsoft_tenant_id: p.microsoftTenantId
2335
+ }
2336
+ })),
2337
+ email_config: options.config?.emailConfig && (options.config.emailConfig.type === "shared" ? {
2338
+ type: "shared"
2339
+ } : {
2340
+ type: "standard",
2341
+ host: options.config.emailConfig.host,
2342
+ port: options.config.emailConfig.port,
2343
+ username: options.config.emailConfig.username,
2344
+ password: options.config.emailConfig.password,
2345
+ sender_name: options.config.emailConfig.senderName,
2346
+ sender_email: options.config.emailConfig.senderEmail
2347
+ }),
2348
+ sign_up_enabled: options.config?.signUpEnabled,
2349
+ credential_enabled: options.config?.credentialEnabled,
2350
+ magic_link_enabled: options.config?.magicLinkEnabled,
2351
+ passkey_enabled: options.config?.passkeyEnabled,
2352
+ allow_localhost: options.config?.allowLocalhost,
2353
+ create_team_on_sign_up: options.config?.createTeamOnSignUp,
2354
+ client_team_creation_enabled: options.config?.clientTeamCreationEnabled,
2355
+ client_user_deletion_enabled: options.config?.clientUserDeletionEnabled,
2356
+ team_creator_default_permissions: options.config?.teamCreatorDefaultPermissions,
2357
+ team_member_default_permissions: options.config?.teamMemberDefaultPermissions
2358
+ }
2359
+ };
2360
+ }
2361
+ function adminProjectCreateOptionsToCrud(options) {
2362
+ return {
2363
+ ...adminProjectUpdateOptionsToCrud(options),
2364
+ display_name: options.displayName
2365
+ };
2366
+ }
2367
+ function apiKeyCreateOptionsToCrud(options) {
2368
+ return {
2369
+ description: options.description,
2370
+ expires_at_millis: options.expiresAt.getTime(),
2371
+ has_publishable_client_key: options.hasPublishableClientKey,
2372
+ has_secret_server_key: options.hasSecretServerKey,
2373
+ has_super_secret_admin_key: options.hasSuperSecretAdminKey
2374
+ };
2375
+ }
2376
+ function teamUpdateOptionsToCrud(options) {
2377
+ return {
2378
+ display_name: options.displayName,
2379
+ profile_image_url: options.profileImageUrl,
2380
+ client_metadata: options.clientMetadata
2381
+ };
2382
+ }
2383
+ function teamCreateOptionsToCrud(options, creatorUserId) {
2384
+ return {
2385
+ display_name: options.displayName,
2386
+ profile_image_url: options.profileImageUrl,
2387
+ creator_user_id: creatorUserId
2388
+ };
2389
+ }
2390
+ function serverTeamCreateOptionsToCrud(options) {
2391
+ return {
2392
+ display_name: options.displayName,
2393
+ profile_image_url: options.profileImageUrl,
2394
+ creator_user_id: options.creatorUserId
2395
+ };
2396
+ }
2397
+ function serverTeamUpdateOptionsToCrud(options) {
2398
+ return {
2399
+ display_name: options.displayName,
2400
+ profile_image_url: options.profileImageUrl,
2401
+ client_metadata: options.clientMetadata,
2402
+ client_read_only_metadata: options.clientReadOnlyMetadata,
2403
+ server_metadata: options.serverMetadata
2404
+ };
2405
+ }
2406
+ function serverTeamPermissionDefinitionCreateOptionsToCrud(options) {
2407
+ return {
2408
+ id: options.id,
2409
+ description: options.description,
2410
+ contained_permission_ids: options.containedPermissionIds
2411
+ };
2412
+ }
2413
+ function serverTeamPermissionDefinitionUpdateOptionsToCrud(options) {
2414
+ return {
2415
+ id: options.id,
2416
+ description: options.description,
2417
+ contained_permission_ids: options.containedPermissionIds
2418
+ };
2419
+ }
2420
+ var StackClientApp = _StackClientAppImpl;
2421
+ var StackServerApp = _StackServerAppImpl;
2422
+ var StackAdminApp = _StackAdminAppImpl;
2423
+ function adminEmailTemplateUpdateOptionsToCrud(options) {
2424
+ return {
2425
+ subject: options.subject,
2426
+ content: options.content
2427
+ };
2428
+ }
2429
+ // Annotate the CommonJS export names for ESM import in node:
2430
+ 0 && (module.exports = {
2431
+ StackAdminApp,
2432
+ StackClientApp,
2433
+ StackServerApp,
2434
+ serverTeamPermissionDefinitionCreateOptionsToCrud,
2435
+ serverTeamPermissionDefinitionUpdateOptionsToCrud,
2436
+ stackAppInternalsSymbol
2437
+ });
2438
+ //# sourceMappingURL=stack-app.js.map