@stackframe/stack 2.3.8 → 2.4.1

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 (281) hide show
  1. package/dist/components/card-frame.js +1 -0
  2. package/dist/components/card-frame.js.map +1 -0
  3. package/dist/components/credential-sign-in.js +1 -0
  4. package/dist/components/credential-sign-in.js.map +1 -0
  5. package/dist/components/credential-sign-up.js +1 -0
  6. package/dist/components/credential-sign-up.js.map +1 -0
  7. package/dist/components/forgot-password.js +1 -0
  8. package/dist/components/forgot-password.js.map +1 -0
  9. package/dist/components/form-warning.js +1 -0
  10. package/dist/components/form-warning.js.map +1 -0
  11. package/dist/components/magic-link-sign-in.js +1 -0
  12. package/dist/components/magic-link-sign-in.js.map +1 -0
  13. package/dist/components/message-card.js +1 -0
  14. package/dist/components/message-card.js.map +1 -0
  15. package/dist/components/oauth-button.js +1 -0
  16. package/dist/components/oauth-button.js.map +1 -0
  17. package/dist/components/oauth-group.js +1 -0
  18. package/dist/components/oauth-group.js.map +1 -0
  19. package/dist/components/password-field.js +1 -0
  20. package/dist/components/password-field.js.map +1 -0
  21. package/dist/components/password-reset-inner.js +1 -0
  22. package/dist/components/password-reset-inner.js.map +1 -0
  23. package/dist/components/redirect-message-card.js +9 -14
  24. package/dist/components/redirect-message-card.js.map +1 -0
  25. package/dist/components/separator-with-text.js +1 -0
  26. package/dist/components/separator-with-text.js.map +1 -0
  27. package/dist/components/user-avatar.d.mts +1 -0
  28. package/dist/components/user-avatar.d.ts +1 -0
  29. package/dist/components/user-avatar.js +1 -0
  30. package/dist/components/user-avatar.js.map +1 -0
  31. package/dist/components/user-button.js +1 -0
  32. package/dist/components/user-button.js.map +1 -0
  33. package/dist/components-core/avatar.js +1 -0
  34. package/dist/components-core/avatar.js.map +1 -0
  35. package/dist/components-core/button.js +1 -0
  36. package/dist/components-core/button.js.map +1 -0
  37. package/dist/components-core/card.js +1 -0
  38. package/dist/components-core/card.js.map +1 -0
  39. package/dist/components-core/collapsible.js +1 -0
  40. package/dist/components-core/collapsible.js.map +1 -0
  41. package/dist/components-core/container.js +1 -0
  42. package/dist/components-core/container.js.map +1 -0
  43. package/dist/components-core/dropdown.js +1 -0
  44. package/dist/components-core/dropdown.js.map +1 -0
  45. package/dist/components-core/index.d.mts +4 -4
  46. package/dist/components-core/index.d.ts +4 -4
  47. package/dist/components-core/index.js +1 -0
  48. package/dist/components-core/index.js.map +1 -0
  49. package/dist/components-core/input.js +1 -0
  50. package/dist/components-core/input.js.map +1 -0
  51. package/dist/components-core/label.js +1 -0
  52. package/dist/components-core/label.js.map +1 -0
  53. package/dist/components-core/link.js +1 -0
  54. package/dist/components-core/link.js.map +1 -0
  55. package/dist/components-core/loading-indicator.js +1 -0
  56. package/dist/components-core/loading-indicator.js.map +1 -0
  57. package/dist/components-core/popover.js +1 -0
  58. package/dist/components-core/popover.js.map +1 -0
  59. package/dist/components-core/separator.js +1 -0
  60. package/dist/components-core/separator.js.map +1 -0
  61. package/dist/components-core/skeleton.js +1 -0
  62. package/dist/components-core/skeleton.js.map +1 -0
  63. package/dist/components-core/tabs.js +4 -2
  64. package/dist/components-core/tabs.js.map +1 -0
  65. package/dist/components-core/text.js +1 -0
  66. package/dist/components-core/text.js.map +1 -0
  67. package/dist/components-core-joy/button.js +1 -0
  68. package/dist/components-core-joy/button.js.map +1 -0
  69. package/dist/components-core-joy/input.js +1 -0
  70. package/dist/components-core-joy/input.js.map +1 -0
  71. package/dist/components-core-joy/separator.js +1 -0
  72. package/dist/components-core-joy/separator.js.map +1 -0
  73. package/dist/components-core-joy/tabs.js +1 -0
  74. package/dist/components-core-joy/tabs.js.map +1 -0
  75. package/dist/components-core-joy/text.js +1 -0
  76. package/dist/components-core-joy/text.js.map +1 -0
  77. package/dist/components-page/account-settings.js +1 -0
  78. package/dist/components-page/account-settings.js.map +1 -0
  79. package/dist/components-page/auth-page.js +1 -0
  80. package/dist/components-page/auth-page.js.map +1 -0
  81. package/dist/components-page/email-verification.js +1 -0
  82. package/dist/components-page/email-verification.js.map +1 -0
  83. package/dist/components-page/forgot-password.js +1 -0
  84. package/dist/components-page/forgot-password.js.map +1 -0
  85. package/dist/components-page/magic-link-callback.js +3 -2
  86. package/dist/components-page/magic-link-callback.js.map +1 -0
  87. package/dist/components-page/oauth-callback.js +12 -2
  88. package/dist/components-page/oauth-callback.js.map +1 -0
  89. package/dist/components-page/password-reset.js +1 -0
  90. package/dist/components-page/password-reset.js.map +1 -0
  91. package/dist/components-page/sign-in.js +1 -0
  92. package/dist/components-page/sign-in.js.map +1 -0
  93. package/dist/components-page/sign-out.js +1 -0
  94. package/dist/components-page/sign-out.js.map +1 -0
  95. package/dist/components-page/sign-up.js +1 -0
  96. package/dist/components-page/sign-up.js.map +1 -0
  97. package/dist/components-page/stack-handler.d.mts +1 -0
  98. package/dist/components-page/stack-handler.d.ts +1 -0
  99. package/dist/components-page/stack-handler.js +1 -0
  100. package/dist/components-page/stack-handler.js.map +1 -0
  101. package/dist/esm/components/card-frame.js +1 -0
  102. package/dist/esm/components/card-frame.js.map +1 -0
  103. package/dist/esm/components/credential-sign-in.js +1 -0
  104. package/dist/esm/components/credential-sign-in.js.map +1 -0
  105. package/dist/esm/components/credential-sign-up.js +1 -0
  106. package/dist/esm/components/credential-sign-up.js.map +1 -0
  107. package/dist/esm/components/forgot-password.js +1 -0
  108. package/dist/esm/components/forgot-password.js.map +1 -0
  109. package/dist/esm/components/form-warning.js +1 -0
  110. package/dist/esm/components/form-warning.js.map +1 -0
  111. package/dist/esm/components/magic-link-sign-in.js +1 -0
  112. package/dist/esm/components/magic-link-sign-in.js.map +1 -0
  113. package/dist/esm/components/message-card.js +1 -0
  114. package/dist/esm/components/message-card.js.map +1 -0
  115. package/dist/esm/components/oauth-button.js +1 -0
  116. package/dist/esm/components/oauth-button.js.map +1 -0
  117. package/dist/esm/components/oauth-group.js +1 -0
  118. package/dist/esm/components/oauth-group.js.map +1 -0
  119. package/dist/esm/components/password-field.js +1 -0
  120. package/dist/esm/components/password-field.js.map +1 -0
  121. package/dist/esm/components/password-reset-inner.js +1 -0
  122. package/dist/esm/components/password-reset-inner.js.map +1 -0
  123. package/dist/esm/components/redirect-message-card.js +9 -14
  124. package/dist/esm/components/redirect-message-card.js.map +1 -0
  125. package/dist/esm/components/separator-with-text.js +1 -0
  126. package/dist/esm/components/separator-with-text.js.map +1 -0
  127. package/dist/esm/components/user-avatar.js +1 -0
  128. package/dist/esm/components/user-avatar.js.map +1 -0
  129. package/dist/esm/components/user-button.js +1 -0
  130. package/dist/esm/components/user-button.js.map +1 -0
  131. package/dist/esm/components-core/avatar.js +1 -0
  132. package/dist/esm/components-core/avatar.js.map +1 -0
  133. package/dist/esm/components-core/button.js +1 -0
  134. package/dist/esm/components-core/button.js.map +1 -0
  135. package/dist/esm/components-core/card.js +1 -0
  136. package/dist/esm/components-core/card.js.map +1 -0
  137. package/dist/esm/components-core/collapsible.js +1 -0
  138. package/dist/esm/components-core/collapsible.js.map +1 -0
  139. package/dist/esm/components-core/container.js +1 -0
  140. package/dist/esm/components-core/container.js.map +1 -0
  141. package/dist/esm/components-core/dropdown.js +1 -0
  142. package/dist/esm/components-core/dropdown.js.map +1 -0
  143. package/dist/esm/components-core/index.js +1 -0
  144. package/dist/esm/components-core/index.js.map +1 -0
  145. package/dist/esm/components-core/input.js +1 -0
  146. package/dist/esm/components-core/input.js.map +1 -0
  147. package/dist/esm/components-core/label.js +1 -0
  148. package/dist/esm/components-core/label.js.map +1 -0
  149. package/dist/esm/components-core/link.js +1 -0
  150. package/dist/esm/components-core/link.js.map +1 -0
  151. package/dist/esm/components-core/loading-indicator.js +1 -0
  152. package/dist/esm/components-core/loading-indicator.js.map +1 -0
  153. package/dist/esm/components-core/popover.js +1 -0
  154. package/dist/esm/components-core/popover.js.map +1 -0
  155. package/dist/esm/components-core/separator.js +1 -0
  156. package/dist/esm/components-core/separator.js.map +1 -0
  157. package/dist/esm/components-core/skeleton.js +1 -0
  158. package/dist/esm/components-core/skeleton.js.map +1 -0
  159. package/dist/esm/components-core/tabs.js +4 -2
  160. package/dist/esm/components-core/tabs.js.map +1 -0
  161. package/dist/esm/components-core/text.js +1 -0
  162. package/dist/esm/components-core/text.js.map +1 -0
  163. package/dist/esm/components-core-joy/button.js +1 -0
  164. package/dist/esm/components-core-joy/button.js.map +1 -0
  165. package/dist/esm/components-core-joy/input.js +1 -0
  166. package/dist/esm/components-core-joy/input.js.map +1 -0
  167. package/dist/esm/components-core-joy/separator.js +1 -0
  168. package/dist/esm/components-core-joy/separator.js.map +1 -0
  169. package/dist/esm/components-core-joy/tabs.js +1 -0
  170. package/dist/esm/components-core-joy/tabs.js.map +1 -0
  171. package/dist/esm/components-core-joy/text.js +1 -0
  172. package/dist/esm/components-core-joy/text.js.map +1 -0
  173. package/dist/esm/components-page/account-settings.js +1 -0
  174. package/dist/esm/components-page/account-settings.js.map +1 -0
  175. package/dist/esm/components-page/auth-page.js +1 -0
  176. package/dist/esm/components-page/auth-page.js.map +1 -0
  177. package/dist/esm/components-page/email-verification.js +1 -0
  178. package/dist/esm/components-page/email-verification.js.map +1 -0
  179. package/dist/esm/components-page/forgot-password.js +1 -0
  180. package/dist/esm/components-page/forgot-password.js.map +1 -0
  181. package/dist/esm/components-page/magic-link-callback.js +3 -2
  182. package/dist/esm/components-page/magic-link-callback.js.map +1 -0
  183. package/dist/esm/components-page/oauth-callback.js +14 -4
  184. package/dist/esm/components-page/oauth-callback.js.map +1 -0
  185. package/dist/esm/components-page/password-reset.js +1 -0
  186. package/dist/esm/components-page/password-reset.js.map +1 -0
  187. package/dist/esm/components-page/sign-in.js +1 -0
  188. package/dist/esm/components-page/sign-in.js.map +1 -0
  189. package/dist/esm/components-page/sign-out.js +1 -0
  190. package/dist/esm/components-page/sign-out.js.map +1 -0
  191. package/dist/esm/components-page/sign-up.js +1 -0
  192. package/dist/esm/components-page/sign-up.js.map +1 -0
  193. package/dist/esm/components-page/stack-handler.js +1 -0
  194. package/dist/esm/components-page/stack-handler.js.map +1 -0
  195. package/dist/esm/index.js +1 -0
  196. package/dist/esm/index.js.map +1 -0
  197. package/dist/esm/joy.js +1 -0
  198. package/dist/esm/joy.js.map +1 -0
  199. package/dist/esm/lib/auth.js +1 -0
  200. package/dist/esm/lib/auth.js.map +1 -0
  201. package/dist/esm/lib/cookie.js +38 -16
  202. package/dist/esm/lib/cookie.js.map +1 -0
  203. package/dist/esm/lib/hooks.js +1 -0
  204. package/dist/esm/lib/hooks.js.map +1 -0
  205. package/dist/esm/lib/stack-app.js +297 -13
  206. package/dist/esm/lib/stack-app.js.map +1 -0
  207. package/dist/esm/providers/component-provider.js +1 -0
  208. package/dist/esm/providers/component-provider.js.map +1 -0
  209. package/dist/esm/providers/design-provider.js +1 -0
  210. package/dist/esm/providers/design-provider.js.map +1 -0
  211. package/dist/esm/providers/joy-provider.js +1 -0
  212. package/dist/esm/providers/joy-provider.js.map +1 -0
  213. package/dist/esm/providers/stack-provider-client.js +1 -0
  214. package/dist/esm/providers/stack-provider-client.js.map +1 -0
  215. package/dist/esm/providers/stack-provider.js +1 -0
  216. package/dist/esm/providers/stack-provider.js.map +1 -0
  217. package/dist/esm/providers/styled-components-registry.js +1 -0
  218. package/dist/esm/providers/styled-components-registry.js.map +1 -0
  219. package/dist/esm/providers/theme-provider.js +1 -0
  220. package/dist/esm/providers/theme-provider.js.map +1 -0
  221. package/dist/esm/utils/browser-script.js +1 -0
  222. package/dist/esm/utils/browser-script.js.map +1 -0
  223. package/dist/esm/utils/constants.js +1 -0
  224. package/dist/esm/utils/constants.js.map +1 -0
  225. package/dist/esm/utils/email.js +1 -0
  226. package/dist/esm/utils/email.js.map +1 -0
  227. package/dist/esm/utils/next.js +1 -0
  228. package/dist/esm/utils/next.js.map +1 -0
  229. package/dist/esm/utils/url.js +1 -0
  230. package/dist/esm/utils/url.js.map +1 -0
  231. package/dist/index.d.mts +2 -1
  232. package/dist/index.d.ts +2 -1
  233. package/dist/index.js +1 -0
  234. package/dist/index.js.map +1 -0
  235. package/dist/joy.js +1 -0
  236. package/dist/joy.js.map +1 -0
  237. package/dist/lib/auth.js +1 -0
  238. package/dist/lib/auth.js.map +1 -0
  239. package/dist/lib/cookie.d.mts +5 -2
  240. package/dist/lib/cookie.d.ts +5 -2
  241. package/dist/lib/cookie.js +40 -18
  242. package/dist/lib/cookie.js.map +1 -0
  243. package/dist/lib/hooks.d.mts +1 -0
  244. package/dist/lib/hooks.d.ts +1 -0
  245. package/dist/lib/hooks.js +1 -0
  246. package/dist/lib/hooks.js.map +1 -0
  247. package/dist/lib/stack-app.d.mts +78 -22
  248. package/dist/lib/stack-app.d.ts +78 -22
  249. package/dist/lib/stack-app.js +297 -13
  250. package/dist/lib/stack-app.js.map +1 -0
  251. package/dist/providers/component-provider.d.mts +6 -6
  252. package/dist/providers/component-provider.d.ts +6 -6
  253. package/dist/providers/component-provider.js +1 -0
  254. package/dist/providers/component-provider.js.map +1 -0
  255. package/dist/providers/design-provider.js +1 -0
  256. package/dist/providers/design-provider.js.map +1 -0
  257. package/dist/providers/joy-provider.js +1 -0
  258. package/dist/providers/joy-provider.js.map +1 -0
  259. package/dist/providers/stack-provider-client.d.mts +1 -0
  260. package/dist/providers/stack-provider-client.d.ts +1 -0
  261. package/dist/providers/stack-provider-client.js +1 -0
  262. package/dist/providers/stack-provider-client.js.map +1 -0
  263. package/dist/providers/stack-provider.d.mts +1 -0
  264. package/dist/providers/stack-provider.d.ts +1 -0
  265. package/dist/providers/stack-provider.js +1 -0
  266. package/dist/providers/stack-provider.js.map +1 -0
  267. package/dist/providers/styled-components-registry.js +1 -0
  268. package/dist/providers/styled-components-registry.js.map +1 -0
  269. package/dist/providers/theme-provider.js +1 -0
  270. package/dist/providers/theme-provider.js.map +1 -0
  271. package/dist/utils/browser-script.js +1 -0
  272. package/dist/utils/browser-script.js.map +1 -0
  273. package/dist/utils/constants.js +1 -0
  274. package/dist/utils/constants.js.map +1 -0
  275. package/dist/utils/email.js +1 -0
  276. package/dist/utils/email.js.map +1 -0
  277. package/dist/utils/next.js +1 -0
  278. package/dist/utils/next.js.map +1 -0
  279. package/dist/utils/url.js +1 -0
  280. package/dist/utils/url.js.map +1 -0
  281. package/package.json +3 -3
@@ -16,6 +16,9 @@ import { filterUndefined, omit } from "@stackframe/stack-shared/dist/utils/objec
16
16
  import { neverResolve, resolved, runAsynchronously, wait } from "@stackframe/stack-shared/dist/utils/promises";
17
17
  import { AsyncCache } from "@stackframe/stack-shared/dist/utils/caches";
18
18
  import { suspend } from "@stackframe/stack-shared/dist/utils/react";
19
+ function permissionDefinitionScopeToType(scope) {
20
+ return { "any-team": "team", "specific-team": "team", "global": "global" }[scope.type];
21
+ }
19
22
  function getUrls(partial) {
20
23
  const handler = partial.handler ?? "/handler";
21
24
  return {
@@ -43,10 +46,10 @@ function getDefaultPublishableClientKey() {
43
46
  return process.env.NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY || throwErr("Welcome to Stack! 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.");
44
47
  }
45
48
  function getDefaultSecretServerKey() {
46
- return process.env.STACK_SECRET_SERVER_KEY || throwErr("No secret server key provided. Please copy your publishable client key from the Stack dashboard and put your it in the STACK_SECRET_SERVER_KEY environment variable.");
49
+ return process.env.STACK_SECRET_SERVER_KEY || throwErr("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.");
47
50
  }
48
51
  function getDefaultSuperSecretAdminKey() {
49
- return process.env.STACK_SUPER_SECRET_ADMIN_KEY || throwErr("No super secret admin key provided. Please copy your publishable client key from the Stack dashboard and put it in the STACK_SUPER_SECRET_ADMIN_KEY environment variable.");
52
+ return process.env.STACK_SUPER_SECRET_ADMIN_KEY || throwErr("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.");
50
53
  }
51
54
  function getDefaultBaseUrl() {
52
55
  return process.env.NEXT_PUBLIC_STACK_URL || defaultBaseUrl;
@@ -83,8 +86,8 @@ var cookieTokenStoreInitializer = () => {
83
86
  }, 10);
84
87
  cookieTokenStore.onChange((value) => {
85
88
  try {
86
- setOrDeleteCookie("stack-refresh", value.refreshToken);
87
- setOrDeleteCookie("stack-access", value.accessToken);
89
+ setOrDeleteCookie("stack-refresh", value.refreshToken, { maxAge: 60 * 60 * 24 * 365 });
90
+ setOrDeleteCookie("stack-access", value.accessToken, { maxAge: 60 * 60 * 24 });
88
91
  hasSucceededInWriting = true;
89
92
  } catch (e) {
90
93
  hasSucceededInWriting = false;
@@ -106,8 +109,8 @@ var tokenStoreInitializers = /* @__PURE__ */ new Map([
106
109
  });
107
110
  store.onChange((value) => {
108
111
  try {
109
- setOrDeleteCookie("stack-refresh", value.refreshToken);
110
- setOrDeleteCookie("stack-access", value.accessToken);
112
+ setOrDeleteCookie("stack-refresh", value.refreshToken, { maxAge: 60 * 60 * 24 * 365 });
113
+ setOrDeleteCookie("stack-access", value.accessToken, { maxAge: 60 * 60 * 24 });
111
114
  } catch (e) {
112
115
  }
113
116
  });
@@ -179,6 +182,12 @@ var _StackClientAppImpl = class __StackClientAppImpl {
179
182
  _ownedProjectsCache = createCacheByTokenStore(async (tokenStore) => {
180
183
  return await this._interface.listProjects(tokenStore);
181
184
  });
185
+ _currentUserPermissionsCache = createCacheByTokenStore(async (tokenStore, [teamId, type, direct]) => {
186
+ return await this._interface.listClientUserTeamPermissions({ teamId, type, direct }, tokenStore);
187
+ });
188
+ _currentUserTeamsCache = createCacheByTokenStore(async (tokenStore) => {
189
+ return await this._interface.listClientUserTeams(tokenStore);
190
+ });
182
191
  constructor(options) {
183
192
  if ("interface" in options) {
184
193
  this._interface = options.interface;
@@ -213,7 +222,33 @@ var _StackClientAppImpl = class __StackClientAppImpl {
213
222
  throw new Error("Cannot call this function on a Stack app with a project ID other than 'internal'.");
214
223
  }
215
224
  }
225
+ _permissionFromJson(json) {
226
+ const type = permissionDefinitionScopeToType(json.scope);
227
+ if (type === "team") {
228
+ return {
229
+ id: json.id,
230
+ type,
231
+ teamId: json.scope.teamId
232
+ };
233
+ } else {
234
+ return {
235
+ id: json.id,
236
+ type
237
+ };
238
+ }
239
+ }
240
+ _teamFromJson(json) {
241
+ return {
242
+ id: json.id,
243
+ displayName: json.displayName,
244
+ createdAt: new Date(json.createdAtMillis),
245
+ toJson() {
246
+ return json;
247
+ }
248
+ };
249
+ }
216
250
  _userFromJson(json) {
251
+ const app = this;
217
252
  return {
218
253
  projectId: json.projectId,
219
254
  id: json.id,
@@ -227,11 +262,69 @@ var _StackClientAppImpl = class __StackClientAppImpl {
227
262
  hasPassword: json.hasPassword,
228
263
  authWithEmail: json.authWithEmail,
229
264
  oauthProviders: json.oauthProviders,
265
+ async getTeam(teamId) {
266
+ const teams = await this.listTeams();
267
+ return teams.find((t) => t.id === teamId) ?? null;
268
+ },
269
+ useTeam(teamId) {
270
+ const teams = this.useTeams();
271
+ return useMemo(() => {
272
+ return teams.find((t) => t.id === teamId) ?? null;
273
+ }, [teams, teamId]);
274
+ },
275
+ onTeamChange(teamId, callback) {
276
+ return this.onTeamsChange((teams) => {
277
+ const team = teams.find((t) => t.id === teamId) ?? null;
278
+ callback(team);
279
+ });
280
+ },
281
+ async listTeams() {
282
+ const teams = await app._currentUserTeamsCache.getOrWait([getTokenStore(app._tokenStoreOptions)], "write-only");
283
+ return teams.map((json2) => app._teamFromJson(json2));
284
+ },
285
+ useTeams() {
286
+ const teams = useCache(app._currentUserTeamsCache, [getTokenStore(app._tokenStoreOptions)], "user.useTeams()");
287
+ return useMemo(() => teams.map((json2) => app._teamFromJson(json2)), [teams]);
288
+ },
289
+ onTeamsChange(callback) {
290
+ return app._currentUserTeamsCache.onChange([getTokenStore(app._tokenStoreOptions)], (value, oldValue) => {
291
+ callback(value.map((json2) => app._teamFromJson(json2)), oldValue?.map((json2) => app._teamFromJson(json2)));
292
+ });
293
+ },
294
+ async listPermissions(scope, options) {
295
+ const permissions = await app._currentUserPermissionsCache.getOrWait([getTokenStore(app._tokenStoreOptions), scope.id, "team", !!options?.direct], "write-only");
296
+ return permissions.map((json2) => app._permissionFromJson(json2));
297
+ },
298
+ usePermissions(scope, options) {
299
+ const permissions = useCache(app._currentUserPermissionsCache, [getTokenStore(app._tokenStoreOptions), scope.id, "team", !!options?.direct], "user.usePermissions()");
300
+ return useMemo(() => permissions.map((json2) => app._permissionFromJson(json2)), [permissions]);
301
+ },
302
+ usePermission(scope, permissionId) {
303
+ const permissions = this.usePermissions(scope);
304
+ return useMemo(() => permissions.find((p) => p.id === permissionId) ?? null, [permissions, permissionId]);
305
+ },
306
+ async getPermission(scope, permissionId) {
307
+ const permissions = await this.listPermissions(scope);
308
+ return permissions.find((p) => p.id === permissionId) ?? null;
309
+ },
310
+ async hasPermission(scope, permissionId) {
311
+ const permissions = await this.listPermissions(scope);
312
+ return permissions.some((p) => p.id === permissionId);
313
+ },
230
314
  toJson() {
231
315
  return json;
232
316
  }
233
317
  };
234
318
  }
319
+ _teamMemberFromJson(json) {
320
+ if (json === null)
321
+ return null;
322
+ return {
323
+ teamId: json.teamId,
324
+ userId: json.userId,
325
+ displayName: json.displayName
326
+ };
327
+ }
235
328
  _currentUserFromJson(json, tokenStore) {
236
329
  if (json === null)
237
330
  return null;
@@ -309,7 +402,8 @@ var _StackClientAppImpl = class __StackClientAppImpl {
309
402
  allowLocalhost: data.evaluatedConfig.allowLocalhost,
310
403
  oauthProviders: data.evaluatedConfig.oauthProviders,
311
404
  emailConfig: data.evaluatedConfig.emailConfig,
312
- domains: data.evaluatedConfig.domains
405
+ domains: data.evaluatedConfig.domains,
406
+ createTeamOnSignUp: data.evaluatedConfig.createTeamOnSignUp
313
407
  },
314
408
  async update(update) {
315
409
  await adminInterface.updateProject(update);
@@ -341,7 +435,7 @@ var _StackClientAppImpl = class __StackClientAppImpl {
341
435
  throw new Error(`No URL for handler name ${handlerName}`);
342
436
  }
343
437
  window.location.href = this.urls[handlerName];
344
- return neverResolve();
438
+ return wait(2e3);
345
439
  }
346
440
  async redirectToSignIn() {
347
441
  return await this._redirectTo("signIn");
@@ -432,7 +526,7 @@ var _StackClientAppImpl = class __StackClientAppImpl {
432
526
  case "redirect": {
433
527
  router.replace(this.urls.signIn);
434
528
  suspend();
435
- throw new Error("suspend should never return! This is a bug in Stack.");
529
+ throw new StackAssertionError("suspend should never return");
436
530
  }
437
531
  case "throw": {
438
532
  throw new Error("User is not signed in but useUser was called with { or: 'throw' }");
@@ -504,10 +598,12 @@ var _StackClientAppImpl = class __StackClientAppImpl {
504
598
  this._ensurePersistentTokenStore();
505
599
  const tokenStore = getTokenStore(this._tokenStoreOptions);
506
600
  const result = await callOAuthCallback(this._interface, tokenStore, this.urls.oauthCallback);
507
- if (result?.newUser) {
508
- window.location.replace(this.urls.afterSignUp);
509
- } else {
510
- window.location.replace(this.urls.afterSignIn);
601
+ if (result) {
602
+ if (result.newUser) {
603
+ window.location.replace(this.urls.afterSignUp);
604
+ } else {
605
+ window.location.replace(this.urls.afterSignIn);
606
+ }
511
607
  }
512
608
  await neverResolve();
513
609
  }
@@ -642,6 +738,22 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
642
738
  _serverUsersCache = createCache(async () => {
643
739
  return await this._interface.listUsers();
644
740
  });
741
+ _serverUserCache = createCache(async ([userId]) => {
742
+ const user = await this._interface.getServerUserById(userId);
743
+ return Result.or(user, null);
744
+ });
745
+ _serverTeamsCache = createCache(async () => {
746
+ return await this._interface.listTeams();
747
+ });
748
+ _serverTeamMembersCache = createCache(async ([teamId]) => {
749
+ return await this._interface.listTeamMembers(teamId);
750
+ });
751
+ _serverTeamPermissionDefinitionsCache = createCache(async () => {
752
+ return await this._interface.listPermissionDefinitions();
753
+ });
754
+ _serverTeamUserPermissionsCache = createCache(async ([teamId, userId, type, direct]) => {
755
+ return await this._interface.listTeamMemberPermissions({ teamId, userId, type, direct });
756
+ });
645
757
  constructor(options) {
646
758
  if ("interface" in options) {
647
759
  super({
@@ -682,6 +794,67 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
682
794
  getClientUser() {
683
795
  return app._userFromJson(json);
684
796
  },
797
+ async grantPermission(scope, permissionId) {
798
+ await app._interface.grantTeamUserPermission(scope.id, json.id, permissionId, "team");
799
+ for (const direct of [true, false]) {
800
+ await app._serverTeamUserPermissionsCache.refresh([scope.id, json.id, "team", direct]);
801
+ }
802
+ },
803
+ async revokePermission(scope, permissionId) {
804
+ await app._interface.revokeTeamUserPermission(scope.id, json.id, permissionId, "team");
805
+ for (const direct of [true, false]) {
806
+ await app._serverTeamUserPermissionsCache.refresh([scope.id, json.id, "team", direct]);
807
+ }
808
+ },
809
+ async getTeam(teamId) {
810
+ const teams = await this.listTeams();
811
+ return teams.find((t) => t.id === teamId) ?? null;
812
+ },
813
+ useTeam(teamId) {
814
+ const teams = this.useTeams();
815
+ return useMemo(() => {
816
+ return teams.find((t) => t.id === teamId) ?? null;
817
+ }, [teams, teamId]);
818
+ },
819
+ onTeamChange(teamId, callback) {
820
+ return this.onTeamsChange((teams) => {
821
+ const team = teams.find((t) => t.id === teamId) ?? null;
822
+ callback(team);
823
+ });
824
+ },
825
+ async listTeams() {
826
+ const teams = await app._serverTeamsCache.getOrWait([getTokenStore(app._tokenStoreOptions)], "write-only");
827
+ return teams.map((json2) => app._serverTeamFromJson(json2));
828
+ },
829
+ useTeams() {
830
+ const teams = useCache(app._serverTeamsCache, [getTokenStore(app._tokenStoreOptions)], "user.useTeams()");
831
+ return useMemo(() => teams.map((json2) => app._serverTeamFromJson(json2)), [teams]);
832
+ },
833
+ onTeamsChange(callback) {
834
+ return app._serverTeamsCache.onChange([getTokenStore(app._tokenStoreOptions)], (value, oldValue) => {
835
+ callback(value.map((json2) => app._serverTeamFromJson(json2)), oldValue?.map((json2) => app._serverTeamFromJson(json2)));
836
+ });
837
+ },
838
+ async listPermissions(scope, options) {
839
+ const permissions = await app._serverTeamUserPermissionsCache.getOrWait([scope.id, json.id, "team", !!options?.direct], "write-only");
840
+ return permissions.map((json2) => app._serverPermissionFromJson(json2));
841
+ },
842
+ usePermissions(scope, options) {
843
+ const permissions = useCache(app._serverTeamUserPermissionsCache, [scope.id, json.id, "team", !!options?.direct], "user.usePermissions()");
844
+ return useMemo(() => permissions.map((json2) => app._serverPermissionFromJson(json2)), [permissions]);
845
+ },
846
+ usePermission(scope, permissionId) {
847
+ const permissions = this.usePermissions(scope);
848
+ return useMemo(() => permissions.find((p) => p.id === permissionId) ?? null, [permissions, permissionId]);
849
+ },
850
+ async getPermission(scope, permissionId) {
851
+ const permissions = await this.listPermissions(scope);
852
+ return permissions.find((p) => p.id === permissionId) ?? null;
853
+ },
854
+ async hasPermission(scope, permissionId) {
855
+ const permissions = await this.listPermissions(scope);
856
+ return permissions.some((p) => p.id === permissionId);
857
+ },
685
858
  toJson() {
686
859
  return app._serverUserToJson(this);
687
860
  }
@@ -741,6 +914,20 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
741
914
  return currentUser;
742
915
  }
743
916
  }
917
+ _serverTeamMemberFromJson(json) {
918
+ if (json === null)
919
+ return null;
920
+ const app = this;
921
+ return {
922
+ ...app._teamMemberFromJson(json),
923
+ async getUser() {
924
+ const user = app._serverUserFromJson(await app._serverUserCache.getOrWait([json.userId], "write-only"));
925
+ if (!user)
926
+ throw new Error(`User ${json.userId} not found`);
927
+ return user;
928
+ }
929
+ };
930
+ }
744
931
  _serverUserToJson(user) {
745
932
  return {
746
933
  projectId: user.projectId,
@@ -758,12 +945,56 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
758
945
  oauthProviders: user.oauthProviders
759
946
  };
760
947
  }
948
+ _serverTeamFromJson(json) {
949
+ const app = this;
950
+ return {
951
+ id: json.id,
952
+ displayName: json.displayName,
953
+ createdAt: new Date(json.createdAtMillis),
954
+ async listMembers() {
955
+ return (await app._interface.listTeamMembers(json.id)).map((u) => app._serverTeamMemberFromJson(u));
956
+ },
957
+ async update(update) {
958
+ await app._interface.updateTeam(json.id, update);
959
+ await app._serverTeamsCache.refresh([]);
960
+ },
961
+ async delete() {
962
+ await app._interface.deleteTeam(json.id);
963
+ await app._serverTeamsCache.refresh([]);
964
+ },
965
+ useMembers() {
966
+ const result = useCache(app._serverTeamMembersCache, [json.id], "team.useUsers()");
967
+ return useMemo(() => result.map((u) => app._serverTeamMemberFromJson(u)), [result]);
968
+ },
969
+ async addUser(userId) {
970
+ await app._interface.addUserToTeam({
971
+ teamId: json.id,
972
+ userId
973
+ });
974
+ await app._serverTeamMembersCache.refresh([json.id]);
975
+ },
976
+ async removeUser(userId) {
977
+ await app._interface.removeUserFromTeam({
978
+ teamId: json.id,
979
+ userId
980
+ });
981
+ await app._serverTeamMembersCache.refresh([json.id]);
982
+ },
983
+ toJson() {
984
+ return json;
985
+ }
986
+ };
987
+ }
761
988
  async getServerUser() {
762
989
  this._ensurePersistentTokenStore();
763
990
  const tokenStore = getTokenStore(this._tokenStoreOptions);
764
991
  const userJson = await this._currentServerUserCache.getOrWait([tokenStore], "write-only");
765
992
  return this._currentServerUserFromJson(userJson, tokenStore);
766
993
  }
994
+ async getServerUserById(userId) {
995
+ const json = await this._serverUserCache.getOrWait([userId], "write-only");
996
+ return this._serverUserFromJson(json);
997
+ }
767
998
  useServerUser(options) {
768
999
  this._ensurePersistentTokenStore();
769
1000
  const tokenStore = getTokenStore(this._tokenStoreOptions);
@@ -797,6 +1028,58 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
797
1028
  callback(users.map((j) => this._serverUserFromJson(j)));
798
1029
  });
799
1030
  }
1031
+ async listPermissionDefinitions() {
1032
+ return await this._serverTeamPermissionDefinitionsCache.getOrWait([], "write-only");
1033
+ }
1034
+ usePermissionDefinitions() {
1035
+ return useCache(this._serverTeamPermissionDefinitionsCache, [], "usePermissions()");
1036
+ }
1037
+ _serverPermissionFromJson(json) {
1038
+ return {
1039
+ ...this._permissionFromJson(json),
1040
+ __databaseUniqueId: json.__databaseUniqueId,
1041
+ description: json.description,
1042
+ containPermissionIds: json.containPermissionIds
1043
+ };
1044
+ }
1045
+ async createPermissionDefinition(data) {
1046
+ const permission = await this._serverPermissionFromJson(await this._interface.createPermissionDefinition(data));
1047
+ await this._serverTeamPermissionDefinitionsCache.refresh([]);
1048
+ return permission;
1049
+ }
1050
+ async updatePermissionDefinition(permissionId, data) {
1051
+ await this._interface.updatePermissionDefinition(permissionId, data);
1052
+ await this._serverTeamPermissionDefinitionsCache.refresh([]);
1053
+ }
1054
+ async deletePermissionDefinition(permissionId) {
1055
+ await this._interface.deletePermissionDefinition(permissionId);
1056
+ await this._serverTeamPermissionDefinitionsCache.refresh([]);
1057
+ }
1058
+ async listTeams() {
1059
+ const teams = await this._serverTeamsCache.getOrWait([], "write-only");
1060
+ return teams.map((t) => this._serverTeamFromJson(t));
1061
+ }
1062
+ async createTeam(data) {
1063
+ const team = await this._interface.createTeam(data);
1064
+ await this._serverTeamsCache.refresh([]);
1065
+ return this._serverTeamFromJson(team);
1066
+ }
1067
+ useTeams() {
1068
+ const teams = useCache(this._serverTeamsCache, [], "useServerTeams()");
1069
+ return useMemo(() => {
1070
+ return teams.map((t) => this._serverTeamFromJson(t));
1071
+ }, [teams]);
1072
+ }
1073
+ async getTeam(teamId) {
1074
+ const teams = await this.listTeams();
1075
+ return teams.find((t) => t.id === teamId) ?? null;
1076
+ }
1077
+ useTeam(teamId) {
1078
+ const teams = this.useTeams();
1079
+ return useMemo(() => {
1080
+ return teams.find((t) => t.id === teamId) ?? null;
1081
+ }, [teams, teamId]);
1082
+ }
800
1083
  async _refreshUser(tokenStore) {
801
1084
  await Promise.all([
802
1085
  super._refreshUser(tokenStore),
@@ -938,3 +1221,4 @@ export {
938
1221
  StackServerApp,
939
1222
  stackAppInternalsSymbol
940
1223
  };
1224
+ //# sourceMappingURL=stack-app.js.map