@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.
@@ -62,7 +62,7 @@ var import_url = require("../utils/url");
62
62
  var import_auth = require("./auth");
63
63
  var import_cookie = require("./cookie");
64
64
  var NextNavigation = (0, import_compile_time.scrambleDuringCompileTime)(NextNavigationUnscrambled);
65
- var clientVersion = "js @stackframe/stack@2.5.12";
65
+ var clientVersion = "js @stackframe/stack@2.5.15";
66
66
  function getUrls(partial) {
67
67
  const handler = partial.handler ?? "/handler";
68
68
  const home = partial.home ?? "/";
@@ -189,12 +189,10 @@ var _StackClientAppImpl = class __StackClientAppImpl {
189
189
  return await this._interface.listCurrentUserTeams(session);
190
190
  });
191
191
  this._currentUserOAuthConnectionAccessTokensCache = createCacheBySession(
192
- async (session, [accountId, scope]) => {
192
+ async (session, [providerId, scope]) => {
193
193
  try {
194
- const result = await this._interface.createProviderAccessToken(accountId, scope || "", session);
195
- return {
196
- accessToken: result.access_token
197
- };
194
+ const result = await this._interface.createProviderAccessToken(providerId, scope || "", session);
195
+ return { accessToken: result.access_token };
198
196
  } catch (err) {
199
197
  if (!(err instanceof import_stack_shared.KnownErrors.OAuthConnectionDoesNotHaveRequiredScope || err instanceof import_stack_shared.KnownErrors.OAuthConnectionNotConnectedToUser)) {
200
198
  throw err;
@@ -204,49 +202,16 @@ var _StackClientAppImpl = class __StackClientAppImpl {
204
202
  }
205
203
  );
206
204
  this._currentUserOAuthConnectionCache = createCacheBySession(
207
- async (session, [connectionId, scope, redirect]) => {
208
- const user = await this._currentUserCache.getOrWait([session], "write-only");
209
- let hasConnection = true;
210
- if (!user || !user.oauth_providers.find((p) => p.id === connectionId)) {
211
- hasConnection = false;
212
- }
213
- const token = await this._currentUserOAuthConnectionAccessTokensCache.getOrWait([session, connectionId, scope || ""], "write-only");
214
- if (!token) {
215
- hasConnection = false;
216
- }
217
- if (!hasConnection && redirect) {
218
- await (0, import_auth.addNewOAuthProviderOrScope)(
219
- this._interface,
220
- {
221
- provider: connectionId,
222
- redirectUrl: this.urls.oauthCallback,
223
- errorRedirectUrl: this.urls.error,
224
- providerScope: (0, import_strings.mergeScopeStrings)(scope || "", (this._oauthScopesOnSignIn[connectionId] ?? []).join(" "))
225
- },
226
- session
227
- );
228
- return await (0, import_promises.neverResolve)();
229
- } else if (!hasConnection) {
230
- return null;
231
- }
232
- const app = this;
233
- return {
234
- id: connectionId,
235
- async getAccessToken() {
236
- const result = await app._currentUserOAuthConnectionAccessTokensCache.getOrWait([session, connectionId, scope || ""], "write-only");
237
- if (!result) {
238
- throw new import_errors.StackAssertionError("No access token available");
239
- }
240
- return result;
241
- },
242
- useAccessToken() {
243
- const result = useAsyncCache(app._currentUserOAuthConnectionAccessTokensCache, [session, connectionId, scope || ""], "oauthAccount.useAccessToken()");
244
- if (!result) {
245
- throw new import_errors.StackAssertionError("No access token available");
246
- }
247
- return result;
248
- }
249
- };
205
+ async (session, [providerId, scope, redirect]) => {
206
+ return await this._getUserOAuthConnectionCacheFn({
207
+ getUser: async () => await this._currentUserCache.getOrWait([session], "write-only"),
208
+ getOrWaitOAuthToken: async () => await this._currentUserOAuthConnectionAccessTokensCache.getOrWait([session, providerId, scope || ""], "write-only"),
209
+ useOAuthToken: () => useAsyncCache(this._currentUserOAuthConnectionAccessTokensCache, [session, providerId, scope || ""], "useOAuthToken"),
210
+ providerId,
211
+ scope,
212
+ redirect,
213
+ session
214
+ });
250
215
  }
251
216
  );
252
217
  this._memoryTokenStore = createEmptyTokenStore();
@@ -285,6 +250,53 @@ var _StackClientAppImpl = class __StackClientAppImpl {
285
250
  }
286
251
  }
287
252
  }
253
+ async _getUserOAuthConnectionCacheFn(options) {
254
+ const user = await options.getUser();
255
+ let hasConnection = true;
256
+ if (!user || !user.oauth_providers.find((p) => p.id === options.providerId)) {
257
+ hasConnection = false;
258
+ }
259
+ const token = await options.getOrWaitOAuthToken();
260
+ if (!token) {
261
+ hasConnection = false;
262
+ }
263
+ if (!hasConnection && options.redirect) {
264
+ if (!options.session) {
265
+ throw new Error("No session found. You might be calling getConnectedAccount with redirect without having a user session.");
266
+ }
267
+ await (0, import_auth.addNewOAuthProviderOrScope)(
268
+ this._interface,
269
+ {
270
+ provider: options.providerId,
271
+ redirectUrl: this.urls.oauthCallback,
272
+ errorRedirectUrl: this.urls.error,
273
+ providerScope: (0, import_strings.mergeScopeStrings)(options.scope || "", (this._oauthScopesOnSignIn[options.providerId] ?? []).join(" "))
274
+ },
275
+ options.session
276
+ );
277
+ return await (0, import_promises.neverResolve)();
278
+ } else if (!hasConnection) {
279
+ return null;
280
+ }
281
+ const app = this;
282
+ return {
283
+ id: options.providerId,
284
+ async getAccessToken() {
285
+ const result = await options.getOrWaitOAuthToken();
286
+ if (!result) {
287
+ throw new import_errors.StackAssertionError("No access token available");
288
+ }
289
+ return result;
290
+ },
291
+ useAccessToken() {
292
+ const result = options.useOAuthToken();
293
+ if (!result) {
294
+ throw new import_errors.StackAssertionError("No access token available");
295
+ }
296
+ return result;
297
+ }
298
+ };
299
+ }
288
300
  _initUniqueIdentifier() {
289
301
  if (!this._uniqueIdentifier) {
290
302
  throw new import_errors.StackAssertionError("Unique identifier not initialized");
@@ -1060,11 +1072,8 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1060
1072
  const user = await this._interface.getServerUserById(userId);
1061
1073
  return import_results.Result.or(user, null);
1062
1074
  });
1063
- this._serverTeamsCache = createCache(async () => {
1064
- return await this._interface.listServerTeams();
1065
- });
1066
- this._serverCurrentUserTeamsCache = createCacheBySession(async (session) => {
1067
- return await this._interface.listServerCurrentUserTeams(session);
1075
+ this._serverTeamsCache = createCache(async ([userId]) => {
1076
+ return await this._interface.listServerTeams({ userId });
1068
1077
  });
1069
1078
  this._serverTeamUsersCache = createCache(async ([teamId]) => {
1070
1079
  return await this._interface.listServerTeamUsers(teamId);
@@ -1072,6 +1081,32 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1072
1081
  this._serverTeamUserPermissionsCache = createCache(async ([teamId, userId, recursive]) => {
1073
1082
  return await this._interface.listServerTeamMemberPermissions({ teamId, userId, recursive });
1074
1083
  });
1084
+ this._serverUserOAuthConnectionAccessTokensCache = createCache(
1085
+ async ([userId, providerId, scope]) => {
1086
+ try {
1087
+ const result = await this._interface.createServerProviderAccessToken(userId, providerId, scope || "");
1088
+ return { accessToken: result.access_token };
1089
+ } catch (err) {
1090
+ if (!(err instanceof import_stack_shared.KnownErrors.OAuthConnectionDoesNotHaveRequiredScope || err instanceof import_stack_shared.KnownErrors.OAuthConnectionNotConnectedToUser)) {
1091
+ throw err;
1092
+ }
1093
+ }
1094
+ return null;
1095
+ }
1096
+ );
1097
+ this._serverUserOAuthConnectionCache = createCache(
1098
+ async ([userId, providerId, scope, redirect]) => {
1099
+ return await this._getUserOAuthConnectionCacheFn({
1100
+ getUser: async () => await this._serverUserCache.getOrWait([userId], "write-only"),
1101
+ getOrWaitOAuthToken: async () => await this._serverUserOAuthConnectionAccessTokensCache.getOrWait([userId, providerId, scope || ""], "write-only"),
1102
+ useOAuthToken: () => useAsyncCache(this._serverUserOAuthConnectionAccessTokensCache, [userId, providerId, scope || ""], "user.useConnectedAccount()"),
1103
+ providerId,
1104
+ scope,
1105
+ redirect,
1106
+ session: null
1107
+ });
1108
+ }
1109
+ );
1075
1110
  }
1076
1111
  async _updateServerUser(userId, update) {
1077
1112
  const result = await this._interface.updateServerUser(userId, serverUserUpdateOptionsToCrud(update));
@@ -1080,6 +1115,14 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1080
1115
  }
1081
1116
  _serverUserFromCrud(crud) {
1082
1117
  const app = this;
1118
+ async function getConnectedAccount(id, options) {
1119
+ const scopeString = options?.scopes?.join(" ");
1120
+ return await app._serverUserOAuthConnectionCache.getOrWait([crud.id, id, scopeString || "", options?.or === "redirect"], "write-only");
1121
+ }
1122
+ function useConnectedAccount(id, options) {
1123
+ const scopeString = options?.scopes?.join(" ");
1124
+ return useAsyncCache(app._serverUserOAuthConnectionCache, [crud.id, id, scopeString || "", options?.or === "redirect"], "user.useConnectedAccount()");
1125
+ }
1083
1126
  return {
1084
1127
  ...super._createBaseUser(crud),
1085
1128
  serverMetadata: crud.server_metadata,
@@ -1123,29 +1166,29 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1123
1166
  async setSelectedTeam(team) {
1124
1167
  return await this.update({ selectedTeamId: team?.id ?? null });
1125
1168
  },
1126
- getConnectedAccount: async () => {
1127
- return await app._checkFeatureSupport("getConnectedAccount() on ServerUser", {});
1128
- },
1129
- useConnectedAccount: () => {
1130
- return app._useCheckFeatureSupport("useConnectedAccount() on ServerUser", {});
1131
- },
1169
+ getConnectedAccount,
1170
+ useConnectedAccount,
1132
1171
  async getTeam(teamId) {
1133
1172
  const teams = await this.listTeams();
1134
1173
  return teams.find((t) => t.id === teamId) ?? null;
1135
1174
  },
1136
1175
  useTeam(teamId) {
1137
- return app._useCheckFeatureSupport("useTeam() on ServerUser", {});
1176
+ const teams = this.useTeams();
1177
+ return (0, import_react2.useMemo)(() => {
1178
+ return teams.find((t) => t.id === teamId) ?? null;
1179
+ }, [teams, teamId]);
1138
1180
  },
1139
1181
  async listTeams() {
1140
- const crud2 = await app._serverCurrentUserTeamsCache.getOrWait([app._getSession()], "write-only");
1141
- return crud2.map((t) => app._serverTeamFromCrud(t));
1182
+ const teams = await app._serverTeamsCache.getOrWait([crud.id], "write-only");
1183
+ return teams.map((t) => app._serverTeamFromCrud(t));
1142
1184
  },
1143
1185
  useTeams() {
1144
- return app._useCheckFeatureSupport("useTeams() on ServerUser", {});
1186
+ const teams = useAsyncCache(app._serverTeamsCache, [crud.id], "user.useTeams()");
1187
+ return (0, import_react2.useMemo)(() => teams.map((t) => app._serverTeamFromCrud(t)), [teams]);
1145
1188
  },
1146
1189
  createTeam: async (data) => {
1147
1190
  const team = await app._interface.createServerTeam(serverTeamCreateOptionsToCrud(data), app._getSession());
1148
- await app._serverTeamsCache.refresh([]);
1191
+ await app._serverTeamsCache.refresh([void 0]);
1149
1192
  return app._serverTeamFromCrud(team);
1150
1193
  },
1151
1194
  async listPermissions(scope, options) {
@@ -1202,11 +1245,11 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1202
1245
  },
1203
1246
  async update(update) {
1204
1247
  await app._interface.updateServerTeam(crud.id, serverTeamUpdateOptionsToCrud(update));
1205
- await app._serverTeamsCache.refresh([]);
1248
+ await app._serverTeamsCache.refresh([void 0]);
1206
1249
  },
1207
1250
  async delete() {
1208
1251
  await app._interface.deleteServerTeam(crud.id);
1209
- await app._serverTeamsCache.refresh([]);
1252
+ await app._serverTeamsCache.refresh([void 0]);
1210
1253
  },
1211
1254
  useUsers() {
1212
1255
  const result = useAsyncCache(app._serverTeamUsersCache, [crud.id], "team.useUsers()");
@@ -1309,16 +1352,16 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1309
1352
  };
1310
1353
  }
1311
1354
  async listTeams() {
1312
- const teams = await this._serverTeamsCache.getOrWait([], "write-only");
1355
+ const teams = await this._serverTeamsCache.getOrWait([void 0], "write-only");
1313
1356
  return teams.map((t) => this._serverTeamFromCrud(t));
1314
1357
  }
1315
1358
  async createTeam(data) {
1316
1359
  const team = await this._interface.createServerTeam(serverTeamCreateOptionsToCrud(data));
1317
- await this._serverTeamsCache.refresh([]);
1360
+ await this._serverTeamsCache.refresh([void 0]);
1318
1361
  return this._serverTeamFromCrud(team);
1319
1362
  }
1320
1363
  useTeams() {
1321
- const teams = useAsyncCache(this._serverTeamsCache, [], "useServerTeams()");
1364
+ const teams = useAsyncCache(this._serverTeamsCache, [void 0], "useServerTeams()");
1322
1365
  return (0, import_react2.useMemo)(() => {
1323
1366
  return teams.map((t) => this._serverTeamFromCrud(t));
1324
1367
  }, [teams]);
@@ -1377,6 +1420,9 @@ var _StackAdminAppImpl = class extends _StackServerAppImpl {
1377
1420
  this._adminTeamPermissionDefinitionsCache = createCache(async () => {
1378
1421
  return await this._interface.listPermissionDefinitions();
1379
1422
  });
1423
+ this._svixTokenCache = createCache(async () => {
1424
+ return await this._interface.getSvixToken();
1425
+ });
1380
1426
  }
1381
1427
  _adminOwnedProjectFromCrud(data, onRefresh) {
1382
1428
  if (this._tokenStoreInit !== null) {
@@ -1564,6 +1610,10 @@ var _StackAdminAppImpl = class extends _StackServerAppImpl {
1564
1610
  return crud.map((p) => this._serverTeamPermissionDefinitionFromCrud(p));
1565
1611
  }, [crud]);
1566
1612
  }
1613
+ useSvixToken() {
1614
+ const crud = useAsyncCache(this._svixTokenCache, [], "useSvixToken()");
1615
+ return crud.token;
1616
+ }
1567
1617
  async _refreshProject() {
1568
1618
  await Promise.all([
1569
1619
  super._refreshProject(),