@stackframe/stack 2.5.12 → 2.5.15

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.
@@ -23,7 +23,7 @@ import { constructRedirectUrl } from "../utils/url";
23
23
  import { addNewOAuthProviderOrScope, callOAuthCallback, signInWithOAuth } from "./auth";
24
24
  import { deleteCookie, getCookie, setOrDeleteCookie } from "./cookie";
25
25
  var NextNavigation = scrambleDuringCompileTime(NextNavigationUnscrambled);
26
- var clientVersion = "js @stackframe/stack@2.5.12";
26
+ var clientVersion = "js @stackframe/stack@2.5.15";
27
27
  function getUrls(partial) {
28
28
  const handler = partial.handler ?? "/handler";
29
29
  const home = partial.home ?? "/";
@@ -150,12 +150,10 @@ var _StackClientAppImpl = class __StackClientAppImpl {
150
150
  return await this._interface.listCurrentUserTeams(session);
151
151
  });
152
152
  this._currentUserOAuthConnectionAccessTokensCache = createCacheBySession(
153
- async (session, [accountId, scope]) => {
153
+ async (session, [providerId, scope]) => {
154
154
  try {
155
- const result = await this._interface.createProviderAccessToken(accountId, scope || "", session);
156
- return {
157
- accessToken: result.access_token
158
- };
155
+ const result = await this._interface.createProviderAccessToken(providerId, scope || "", session);
156
+ return { accessToken: result.access_token };
159
157
  } catch (err) {
160
158
  if (!(err instanceof KnownErrors.OAuthConnectionDoesNotHaveRequiredScope || err instanceof KnownErrors.OAuthConnectionNotConnectedToUser)) {
161
159
  throw err;
@@ -165,49 +163,16 @@ var _StackClientAppImpl = class __StackClientAppImpl {
165
163
  }
166
164
  );
167
165
  this._currentUserOAuthConnectionCache = createCacheBySession(
168
- async (session, [connectionId, scope, redirect]) => {
169
- const user = await this._currentUserCache.getOrWait([session], "write-only");
170
- let hasConnection = true;
171
- if (!user || !user.oauth_providers.find((p) => p.id === connectionId)) {
172
- hasConnection = false;
173
- }
174
- const token = await this._currentUserOAuthConnectionAccessTokensCache.getOrWait([session, connectionId, scope || ""], "write-only");
175
- if (!token) {
176
- hasConnection = false;
177
- }
178
- if (!hasConnection && redirect) {
179
- await addNewOAuthProviderOrScope(
180
- this._interface,
181
- {
182
- provider: connectionId,
183
- redirectUrl: this.urls.oauthCallback,
184
- errorRedirectUrl: this.urls.error,
185
- providerScope: mergeScopeStrings(scope || "", (this._oauthScopesOnSignIn[connectionId] ?? []).join(" "))
186
- },
187
- session
188
- );
189
- return await neverResolve();
190
- } else if (!hasConnection) {
191
- return null;
192
- }
193
- const app = this;
194
- return {
195
- id: connectionId,
196
- async getAccessToken() {
197
- const result = await app._currentUserOAuthConnectionAccessTokensCache.getOrWait([session, connectionId, scope || ""], "write-only");
198
- if (!result) {
199
- throw new StackAssertionError("No access token available");
200
- }
201
- return result;
202
- },
203
- useAccessToken() {
204
- const result = useAsyncCache(app._currentUserOAuthConnectionAccessTokensCache, [session, connectionId, scope || ""], "oauthAccount.useAccessToken()");
205
- if (!result) {
206
- throw new StackAssertionError("No access token available");
207
- }
208
- return result;
209
- }
210
- };
166
+ async (session, [providerId, scope, redirect]) => {
167
+ return await this._getUserOAuthConnectionCacheFn({
168
+ getUser: async () => await this._currentUserCache.getOrWait([session], "write-only"),
169
+ getOrWaitOAuthToken: async () => await this._currentUserOAuthConnectionAccessTokensCache.getOrWait([session, providerId, scope || ""], "write-only"),
170
+ useOAuthToken: () => useAsyncCache(this._currentUserOAuthConnectionAccessTokensCache, [session, providerId, scope || ""], "useOAuthToken"),
171
+ providerId,
172
+ scope,
173
+ redirect,
174
+ session
175
+ });
211
176
  }
212
177
  );
213
178
  this._memoryTokenStore = createEmptyTokenStore();
@@ -246,6 +211,53 @@ var _StackClientAppImpl = class __StackClientAppImpl {
246
211
  }
247
212
  }
248
213
  }
214
+ async _getUserOAuthConnectionCacheFn(options) {
215
+ const user = await options.getUser();
216
+ let hasConnection = true;
217
+ if (!user || !user.oauth_providers.find((p) => p.id === options.providerId)) {
218
+ hasConnection = false;
219
+ }
220
+ const token = await options.getOrWaitOAuthToken();
221
+ if (!token) {
222
+ hasConnection = false;
223
+ }
224
+ if (!hasConnection && options.redirect) {
225
+ if (!options.session) {
226
+ throw new Error("No session found. You might be calling getConnectedAccount with redirect without having a user session.");
227
+ }
228
+ await addNewOAuthProviderOrScope(
229
+ this._interface,
230
+ {
231
+ provider: options.providerId,
232
+ redirectUrl: this.urls.oauthCallback,
233
+ errorRedirectUrl: this.urls.error,
234
+ providerScope: mergeScopeStrings(options.scope || "", (this._oauthScopesOnSignIn[options.providerId] ?? []).join(" "))
235
+ },
236
+ options.session
237
+ );
238
+ return await neverResolve();
239
+ } else if (!hasConnection) {
240
+ return null;
241
+ }
242
+ const app = this;
243
+ return {
244
+ id: options.providerId,
245
+ async getAccessToken() {
246
+ const result = await options.getOrWaitOAuthToken();
247
+ if (!result) {
248
+ throw new StackAssertionError("No access token available");
249
+ }
250
+ return result;
251
+ },
252
+ useAccessToken() {
253
+ const result = options.useOAuthToken();
254
+ if (!result) {
255
+ throw new StackAssertionError("No access token available");
256
+ }
257
+ return result;
258
+ }
259
+ };
260
+ }
249
261
  _initUniqueIdentifier() {
250
262
  if (!this._uniqueIdentifier) {
251
263
  throw new StackAssertionError("Unique identifier not initialized");
@@ -1021,11 +1033,8 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1021
1033
  const user = await this._interface.getServerUserById(userId);
1022
1034
  return Result.or(user, null);
1023
1035
  });
1024
- this._serverTeamsCache = createCache(async () => {
1025
- return await this._interface.listServerTeams();
1026
- });
1027
- this._serverCurrentUserTeamsCache = createCacheBySession(async (session) => {
1028
- return await this._interface.listServerCurrentUserTeams(session);
1036
+ this._serverTeamsCache = createCache(async ([userId]) => {
1037
+ return await this._interface.listServerTeams({ userId });
1029
1038
  });
1030
1039
  this._serverTeamUsersCache = createCache(async ([teamId]) => {
1031
1040
  return await this._interface.listServerTeamUsers(teamId);
@@ -1033,6 +1042,32 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1033
1042
  this._serverTeamUserPermissionsCache = createCache(async ([teamId, userId, recursive]) => {
1034
1043
  return await this._interface.listServerTeamMemberPermissions({ teamId, userId, recursive });
1035
1044
  });
1045
+ this._serverUserOAuthConnectionAccessTokensCache = createCache(
1046
+ async ([userId, providerId, scope]) => {
1047
+ try {
1048
+ const result = await this._interface.createServerProviderAccessToken(userId, providerId, scope || "");
1049
+ return { accessToken: result.access_token };
1050
+ } catch (err) {
1051
+ if (!(err instanceof KnownErrors.OAuthConnectionDoesNotHaveRequiredScope || err instanceof KnownErrors.OAuthConnectionNotConnectedToUser)) {
1052
+ throw err;
1053
+ }
1054
+ }
1055
+ return null;
1056
+ }
1057
+ );
1058
+ this._serverUserOAuthConnectionCache = createCache(
1059
+ async ([userId, providerId, scope, redirect]) => {
1060
+ return await this._getUserOAuthConnectionCacheFn({
1061
+ getUser: async () => await this._serverUserCache.getOrWait([userId], "write-only"),
1062
+ getOrWaitOAuthToken: async () => await this._serverUserOAuthConnectionAccessTokensCache.getOrWait([userId, providerId, scope || ""], "write-only"),
1063
+ useOAuthToken: () => useAsyncCache(this._serverUserOAuthConnectionAccessTokensCache, [userId, providerId, scope || ""], "user.useConnectedAccount()"),
1064
+ providerId,
1065
+ scope,
1066
+ redirect,
1067
+ session: null
1068
+ });
1069
+ }
1070
+ );
1036
1071
  }
1037
1072
  async _updateServerUser(userId, update) {
1038
1073
  const result = await this._interface.updateServerUser(userId, serverUserUpdateOptionsToCrud(update));
@@ -1041,6 +1076,14 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1041
1076
  }
1042
1077
  _serverUserFromCrud(crud) {
1043
1078
  const app = this;
1079
+ async function getConnectedAccount(id, options) {
1080
+ const scopeString = options?.scopes?.join(" ");
1081
+ return await app._serverUserOAuthConnectionCache.getOrWait([crud.id, id, scopeString || "", options?.or === "redirect"], "write-only");
1082
+ }
1083
+ function useConnectedAccount(id, options) {
1084
+ const scopeString = options?.scopes?.join(" ");
1085
+ return useAsyncCache(app._serverUserOAuthConnectionCache, [crud.id, id, scopeString || "", options?.or === "redirect"], "user.useConnectedAccount()");
1086
+ }
1044
1087
  return {
1045
1088
  ...super._createBaseUser(crud),
1046
1089
  serverMetadata: crud.server_metadata,
@@ -1084,29 +1127,29 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1084
1127
  async setSelectedTeam(team) {
1085
1128
  return await this.update({ selectedTeamId: team?.id ?? null });
1086
1129
  },
1087
- getConnectedAccount: async () => {
1088
- return await app._checkFeatureSupport("getConnectedAccount() on ServerUser", {});
1089
- },
1090
- useConnectedAccount: () => {
1091
- return app._useCheckFeatureSupport("useConnectedAccount() on ServerUser", {});
1092
- },
1130
+ getConnectedAccount,
1131
+ useConnectedAccount,
1093
1132
  async getTeam(teamId) {
1094
1133
  const teams = await this.listTeams();
1095
1134
  return teams.find((t) => t.id === teamId) ?? null;
1096
1135
  },
1097
1136
  useTeam(teamId) {
1098
- return app._useCheckFeatureSupport("useTeam() on ServerUser", {});
1137
+ const teams = this.useTeams();
1138
+ return useMemo(() => {
1139
+ return teams.find((t) => t.id === teamId) ?? null;
1140
+ }, [teams, teamId]);
1099
1141
  },
1100
1142
  async listTeams() {
1101
- const crud2 = await app._serverCurrentUserTeamsCache.getOrWait([app._getSession()], "write-only");
1102
- return crud2.map((t) => app._serverTeamFromCrud(t));
1143
+ const teams = await app._serverTeamsCache.getOrWait([crud.id], "write-only");
1144
+ return teams.map((t) => app._serverTeamFromCrud(t));
1103
1145
  },
1104
1146
  useTeams() {
1105
- return app._useCheckFeatureSupport("useTeams() on ServerUser", {});
1147
+ const teams = useAsyncCache(app._serverTeamsCache, [crud.id], "user.useTeams()");
1148
+ return useMemo(() => teams.map((t) => app._serverTeamFromCrud(t)), [teams]);
1106
1149
  },
1107
1150
  createTeam: async (data) => {
1108
1151
  const team = await app._interface.createServerTeam(serverTeamCreateOptionsToCrud(data), app._getSession());
1109
- await app._serverTeamsCache.refresh([]);
1152
+ await app._serverTeamsCache.refresh([void 0]);
1110
1153
  return app._serverTeamFromCrud(team);
1111
1154
  },
1112
1155
  async listPermissions(scope, options) {
@@ -1163,11 +1206,11 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1163
1206
  },
1164
1207
  async update(update) {
1165
1208
  await app._interface.updateServerTeam(crud.id, serverTeamUpdateOptionsToCrud(update));
1166
- await app._serverTeamsCache.refresh([]);
1209
+ await app._serverTeamsCache.refresh([void 0]);
1167
1210
  },
1168
1211
  async delete() {
1169
1212
  await app._interface.deleteServerTeam(crud.id);
1170
- await app._serverTeamsCache.refresh([]);
1213
+ await app._serverTeamsCache.refresh([void 0]);
1171
1214
  },
1172
1215
  useUsers() {
1173
1216
  const result = useAsyncCache(app._serverTeamUsersCache, [crud.id], "team.useUsers()");
@@ -1270,16 +1313,16 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1270
1313
  };
1271
1314
  }
1272
1315
  async listTeams() {
1273
- const teams = await this._serverTeamsCache.getOrWait([], "write-only");
1316
+ const teams = await this._serverTeamsCache.getOrWait([void 0], "write-only");
1274
1317
  return teams.map((t) => this._serverTeamFromCrud(t));
1275
1318
  }
1276
1319
  async createTeam(data) {
1277
1320
  const team = await this._interface.createServerTeam(serverTeamCreateOptionsToCrud(data));
1278
- await this._serverTeamsCache.refresh([]);
1321
+ await this._serverTeamsCache.refresh([void 0]);
1279
1322
  return this._serverTeamFromCrud(team);
1280
1323
  }
1281
1324
  useTeams() {
1282
- const teams = useAsyncCache(this._serverTeamsCache, [], "useServerTeams()");
1325
+ const teams = useAsyncCache(this._serverTeamsCache, [void 0], "useServerTeams()");
1283
1326
  return useMemo(() => {
1284
1327
  return teams.map((t) => this._serverTeamFromCrud(t));
1285
1328
  }, [teams]);
@@ -1338,6 +1381,9 @@ var _StackAdminAppImpl = class extends _StackServerAppImpl {
1338
1381
  this._adminTeamPermissionDefinitionsCache = createCache(async () => {
1339
1382
  return await this._interface.listPermissionDefinitions();
1340
1383
  });
1384
+ this._svixTokenCache = createCache(async () => {
1385
+ return await this._interface.getSvixToken();
1386
+ });
1341
1387
  }
1342
1388
  _adminOwnedProjectFromCrud(data, onRefresh) {
1343
1389
  if (this._tokenStoreInit !== null) {
@@ -1525,6 +1571,10 @@ var _StackAdminAppImpl = class extends _StackServerAppImpl {
1525
1571
  return crud.map((p) => this._serverTeamPermissionDefinitionFromCrud(p));
1526
1572
  }, [crud]);
1527
1573
  }
1574
+ useSvixToken() {
1575
+ const crud = useAsyncCache(this._svixTokenCache, [], "useSvixToken()");
1576
+ return crud.token;
1577
+ }
1528
1578
  async _refreshProject() {
1529
1579
  await Promise.all([
1530
1580
  super._refreshProject(),