@stackframe/stack 2.5.2 → 2.5.4
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.
- package/CHANGELOG.md +20 -0
- package/dist/components/credential-sign-in-form.js +4 -14
- package/dist/components/credential-sign-in-form.js.map +1 -1
- package/dist/components/credential-sign-up-form.js +18 -20
- package/dist/components/credential-sign-up-form.js.map +1 -1
- package/dist/components/elements/maybe-full-page.js.map +1 -1
- package/dist/components/elements/ssr-layout-effect.d.mts +1 -0
- package/dist/components/elements/ssr-layout-effect.d.ts +1 -0
- package/dist/components/elements/ssr-layout-effect.js +8 -1
- package/dist/components/elements/ssr-layout-effect.js.map +1 -1
- package/dist/components/elements/user-avatar.d.mts +5 -3
- package/dist/components/elements/user-avatar.d.ts +5 -3
- package/dist/components/elements/user-avatar.js.map +1 -1
- package/dist/components/forgot-password-form.js +3 -13
- package/dist/components/forgot-password-form.js.map +1 -1
- package/dist/components/magic-link-sign-in-form.js +3 -13
- package/dist/components/magic-link-sign-in-form.js.map +1 -1
- package/dist/components/message-cards/known-error-message-card.js.map +1 -1
- package/dist/components/message-cards/message-card.js.map +1 -1
- package/dist/components/message-cards/predefined-message-card.js.map +1 -1
- package/dist/components/oauth-button-group.d.mts +7 -2
- package/dist/components/oauth-button-group.d.ts +7 -2
- package/dist/components/oauth-button-group.js +1 -1
- package/dist/components/oauth-button-group.js.map +1 -1
- package/dist/components/oauth-button.js +28 -26
- package/dist/components/oauth-button.js.map +1 -1
- package/dist/components/password-reset-form.js +4 -3
- package/dist/components/password-reset-form.js.map +1 -1
- package/dist/components/selected-team-switcher.d.mts +5 -3
- package/dist/components/selected-team-switcher.d.ts +5 -3
- package/dist/components/selected-team-switcher.js +12 -1
- package/dist/components/selected-team-switcher.js.map +1 -1
- package/dist/components/user-button.js.map +1 -1
- package/dist/components-page/account-settings.js +42 -7
- package/dist/components-page/account-settings.js.map +1 -1
- package/dist/components-page/auth-page.d.mts +9 -2
- package/dist/components-page/auth-page.d.ts +9 -2
- package/dist/components-page/auth-page.js +3 -3
- package/dist/components-page/auth-page.js.map +1 -1
- package/dist/components-page/email-verification.js +12 -2
- package/dist/components-page/email-verification.js.map +1 -1
- package/dist/components-page/error-page.js.map +1 -1
- package/dist/components-page/magic-link-callback.js +13 -3
- package/dist/components-page/magic-link-callback.js.map +1 -1
- package/dist/components-page/password-reset.js +2 -2
- package/dist/components-page/password-reset.js.map +1 -1
- package/dist/components-page/sign-out.js +12 -2
- package/dist/components-page/sign-out.js.map +1 -1
- package/dist/components-page/stack-handler.d.mts +5 -3
- package/dist/components-page/stack-handler.d.ts +5 -3
- package/dist/components-page/stack-handler.js +27 -10
- package/dist/components-page/stack-handler.js.map +1 -1
- package/dist/esm/components/credential-sign-in-form.js +4 -4
- package/dist/esm/components/credential-sign-in-form.js.map +1 -1
- package/dist/esm/components/credential-sign-up-form.js +18 -20
- package/dist/esm/components/credential-sign-up-form.js.map +1 -1
- package/dist/esm/components/elements/maybe-full-page.js.map +1 -1
- package/dist/esm/components/elements/ssr-layout-effect.js +8 -1
- package/dist/esm/components/elements/ssr-layout-effect.js.map +1 -1
- package/dist/esm/components/elements/user-avatar.js.map +1 -1
- package/dist/esm/components/forgot-password-form.js +3 -3
- package/dist/esm/components/forgot-password-form.js.map +1 -1
- package/dist/esm/components/magic-link-sign-in-form.js +3 -3
- package/dist/esm/components/magic-link-sign-in-form.js.map +1 -1
- package/dist/esm/components/message-cards/known-error-message-card.js.map +1 -1
- package/dist/esm/components/message-cards/message-card.js.map +1 -1
- package/dist/esm/components/message-cards/predefined-message-card.js.map +1 -1
- package/dist/esm/components/oauth-button-group.js +1 -1
- package/dist/esm/components/oauth-button-group.js.map +1 -1
- package/dist/esm/components/oauth-button.js +29 -27
- package/dist/esm/components/oauth-button.js.map +1 -1
- package/dist/esm/components/password-reset-form.js +4 -3
- package/dist/esm/components/password-reset-form.js.map +1 -1
- package/dist/esm/components/selected-team-switcher.js +2 -1
- package/dist/esm/components/selected-team-switcher.js.map +1 -1
- package/dist/esm/components/user-button.js.map +1 -1
- package/dist/esm/components-page/account-settings.js +42 -7
- package/dist/esm/components-page/account-settings.js.map +1 -1
- package/dist/esm/components-page/auth-page.js +3 -3
- package/dist/esm/components-page/auth-page.js.map +1 -1
- package/dist/esm/components-page/email-verification.js +2 -2
- package/dist/esm/components-page/email-verification.js.map +1 -1
- package/dist/esm/components-page/error-page.js.map +1 -1
- package/dist/esm/components-page/magic-link-callback.js +3 -3
- package/dist/esm/components-page/magic-link-callback.js.map +1 -1
- package/dist/esm/components-page/password-reset.js +2 -2
- package/dist/esm/components-page/password-reset.js.map +1 -1
- package/dist/esm/components-page/sign-out.js +2 -2
- package/dist/esm/components-page/sign-out.js.map +1 -1
- package/dist/esm/components-page/stack-handler.js +27 -10
- package/dist/esm/components-page/stack-handler.js.map +1 -1
- package/dist/esm/index.js +1 -4
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/auth.js.map +1 -1
- package/dist/esm/lib/cookie.js +6 -1
- package/dist/esm/lib/cookie.js.map +1 -1
- package/dist/esm/lib/hooks.js.map +1 -1
- package/dist/esm/lib/stack-app.js +581 -456
- package/dist/esm/lib/stack-app.js.map +1 -1
- package/dist/esm/providers/stack-provider-client.js +3 -4
- package/dist/esm/providers/stack-provider-client.js.map +1 -1
- package/dist/esm/providers/theme-provider.js +16 -7
- package/dist/esm/providers/theme-provider.js.map +1 -1
- package/dist/esm/utils/browser-script.js +2 -2
- package/dist/esm/utils/browser-script.js.map +1 -1
- package/dist/esm/utils/email.js +2 -2
- package/dist/esm/utils/email.js.map +1 -1
- package/dist/index.d.mts +6 -4
- package/dist/index.d.ts +6 -4
- package/dist/index.js +4 -8
- package/dist/index.js.map +1 -1
- package/dist/lib/auth.js.map +1 -1
- package/dist/lib/cookie.js +6 -1
- package/dist/lib/cookie.js.map +1 -1
- package/dist/lib/hooks.d.mts +5 -3
- package/dist/lib/hooks.d.ts +5 -3
- package/dist/lib/hooks.js.map +1 -1
- package/dist/lib/stack-app.d.mts +219 -114
- package/dist/lib/stack-app.d.ts +219 -114
- package/dist/lib/stack-app.js +603 -476
- package/dist/lib/stack-app.js.map +1 -1
- package/dist/providers/stack-provider-client.d.mts +8 -6
- package/dist/providers/stack-provider-client.d.ts +8 -6
- package/dist/providers/stack-provider-client.js +4 -5
- package/dist/providers/stack-provider-client.js.map +1 -1
- package/dist/providers/stack-provider.d.mts +5 -3
- package/dist/providers/stack-provider.d.ts +5 -3
- package/dist/providers/theme-provider.d.mts +2 -1
- package/dist/providers/theme-provider.d.ts +2 -1
- package/dist/providers/theme-provider.js +15 -6
- package/dist/providers/theme-provider.js.map +1 -1
- package/dist/utils/browser-script.d.mts +3 -1
- package/dist/utils/browser-script.d.ts +3 -1
- package/dist/utils/browser-script.js +2 -2
- package/dist/utils/browser-script.js.map +1 -1
- package/dist/utils/email.js +2 -12
- package/dist/utils/email.js.map +1 -1
- package/package.json +4 -5
- package/dist/esm/providers/styled-components-registry.js +0 -25
- package/dist/esm/providers/styled-components-registry.js.map +0 -1
- package/dist/providers/styled-components-registry.d.mts +0 -8
- package/dist/providers/styled-components-registry.d.ts +0 -8
- package/dist/providers/styled-components-registry.js +0 -45
- package/dist/providers/styled-components-registry.js.map +0 -1
package/dist/lib/stack-app.js
CHANGED
|
@@ -33,36 +33,35 @@ __export(stack_app_exports, {
|
|
|
33
33
|
StackAdminApp: () => StackAdminApp,
|
|
34
34
|
StackClientApp: () => StackClientApp,
|
|
35
35
|
StackServerApp: () => StackServerApp,
|
|
36
|
+
serverTeamPermissionDefinitionCreateOptionsToCrud: () => serverTeamPermissionDefinitionCreateOptionsToCrud,
|
|
37
|
+
serverTeamPermissionDefinitionUpdateOptionsToCrud: () => serverTeamPermissionDefinitionUpdateOptionsToCrud,
|
|
36
38
|
stackAppInternalsSymbol: () => stackAppInternalsSymbol
|
|
37
39
|
});
|
|
38
40
|
module.exports = __toCommonJS(stack_app_exports);
|
|
39
|
-
var
|
|
41
|
+
var import_stack_sc = require("@stackframe/stack-sc");
|
|
40
42
|
var import_stack_shared = require("@stackframe/stack-shared");
|
|
41
|
-
var
|
|
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_caches = require("@stackframe/stack-shared/dist/utils/caches");
|
|
46
|
+
var import_compile_time = require("@stackframe/stack-shared/dist/utils/compile-time");
|
|
47
|
+
var import_env = require("@stackframe/stack-shared/dist/utils/env");
|
|
42
48
|
var import_errors = require("@stackframe/stack-shared/dist/utils/errors");
|
|
43
|
-
var
|
|
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");
|
|
44
53
|
var import_results = require("@stackframe/stack-shared/dist/utils/results");
|
|
45
|
-
var import_react2 = require("@stackframe/stack-shared/dist/utils/react");
|
|
46
54
|
var import_stores = require("@stackframe/stack-shared/dist/utils/stores");
|
|
47
|
-
var
|
|
48
|
-
var
|
|
49
|
-
var
|
|
55
|
+
var import_strings = require("@stackframe/stack-shared/dist/utils/strings");
|
|
56
|
+
var import_uuids = require("@stackframe/stack-shared/dist/utils/uuids");
|
|
57
|
+
var cookie = __toESM(require("cookie"));
|
|
50
58
|
var NextNavigationUnscrambled = __toESM(require("next/navigation"));
|
|
59
|
+
var import_react2 = __toESM(require("react"));
|
|
51
60
|
var import_url = require("../utils/url");
|
|
52
|
-
var
|
|
53
|
-
var
|
|
54
|
-
var import_caches = require("@stackframe/stack-shared/dist/utils/caches");
|
|
55
|
-
var import_react3 = require("@stackframe/stack-shared/dist/utils/react");
|
|
56
|
-
var import_compile_time = require("@stackframe/stack-shared/dist/utils/compile-time");
|
|
57
|
-
var import_stack_sc = require("@stackframe/stack-sc");
|
|
58
|
-
var cookie = __toESM(require("cookie"));
|
|
59
|
-
var import_sessions = require("@stackframe/stack-shared/dist/sessions");
|
|
60
|
-
var import_strings = require("@stackframe/stack-shared/dist/utils/strings");
|
|
61
|
+
var import_auth = require("./auth");
|
|
62
|
+
var import_cookie = require("./cookie");
|
|
61
63
|
var NextNavigation = (0, import_compile_time.scrambleDuringCompileTime)(NextNavigationUnscrambled);
|
|
62
|
-
var clientVersion = "js @stackframe/stack@2.5.
|
|
63
|
-
function permissionDefinitionScopeToType(scope) {
|
|
64
|
-
return { "any-team": "team", "specific-team": "team", "global": "global" }[scope.type];
|
|
65
|
-
}
|
|
64
|
+
var clientVersion = "js @stackframe/stack@2.5.4";
|
|
66
65
|
function getUrls(partial) {
|
|
67
66
|
const handler = partial.handler ?? "/handler";
|
|
68
67
|
return {
|
|
@@ -111,7 +110,7 @@ function getDefaultSuperSecretAdminKey() {
|
|
|
111
110
|
function getDefaultBaseUrl() {
|
|
112
111
|
return process.env.NEXT_PUBLIC_STACK_URL || defaultBaseUrl;
|
|
113
112
|
}
|
|
114
|
-
var defaultBaseUrl = "https://
|
|
113
|
+
var defaultBaseUrl = "https://api.stack-auth.com";
|
|
115
114
|
function createEmptyTokenStore() {
|
|
116
115
|
return new import_stores.Store({
|
|
117
116
|
refreshToken: null,
|
|
@@ -120,27 +119,27 @@ function createEmptyTokenStore() {
|
|
|
120
119
|
}
|
|
121
120
|
var cachePromiseByComponentId = /* @__PURE__ */ new Map();
|
|
122
121
|
function useAsyncCache(cache, dependencies, caller) {
|
|
123
|
-
(0,
|
|
124
|
-
const id =
|
|
125
|
-
const subscribe = (0,
|
|
122
|
+
(0, import_react.suspendIfSsr)(caller);
|
|
123
|
+
const id = import_react2.default.useId();
|
|
124
|
+
const subscribe = (0, import_react2.useCallback)((cb) => {
|
|
126
125
|
const { unsubscribe } = cache.onStateChange(dependencies, () => {
|
|
127
126
|
cachePromiseByComponentId.delete(id);
|
|
128
127
|
cb();
|
|
129
128
|
});
|
|
130
129
|
return unsubscribe;
|
|
131
130
|
}, [cache, ...dependencies]);
|
|
132
|
-
const getSnapshot = (0,
|
|
131
|
+
const getSnapshot = (0, import_react2.useCallback)(() => {
|
|
133
132
|
if (!cachePromiseByComponentId.has(id)) {
|
|
134
133
|
cachePromiseByComponentId.set(id, cache.getOrWait(dependencies, "read-write"));
|
|
135
134
|
}
|
|
136
135
|
return cachePromiseByComponentId.get(id);
|
|
137
136
|
}, [cache, ...dependencies]);
|
|
138
|
-
const promise =
|
|
137
|
+
const promise = import_react2.default.useSyncExternalStore(
|
|
139
138
|
subscribe,
|
|
140
139
|
getSnapshot,
|
|
141
140
|
() => (0, import_errors.throwErr)(new Error("getServerSnapshot should never be called in useAsyncCache because we restrict to CSR earlier"))
|
|
142
141
|
);
|
|
143
|
-
return
|
|
142
|
+
return import_react2.default.use(promise);
|
|
144
143
|
}
|
|
145
144
|
var stackAppInternalsSymbol = Symbol.for("StackAppInternals");
|
|
146
145
|
var allClientApps = /* @__PURE__ */ new Map();
|
|
@@ -165,6 +164,97 @@ var numberOfAppsCreated = 0;
|
|
|
165
164
|
var _StackClientAppImpl = class __StackClientAppImpl {
|
|
166
165
|
constructor(_options) {
|
|
167
166
|
this._options = _options;
|
|
167
|
+
this._uniqueIdentifier = void 0;
|
|
168
|
+
this.__DEMO_ENABLE_SLIGHT_FETCH_DELAY = false;
|
|
169
|
+
this._ownedAdminApps = new import_maps.DependenciesMap();
|
|
170
|
+
this._currentUserCache = createCacheBySession(async (session) => {
|
|
171
|
+
if (this.__DEMO_ENABLE_SLIGHT_FETCH_DELAY) {
|
|
172
|
+
await (0, import_promises.wait)(2e3);
|
|
173
|
+
}
|
|
174
|
+
return await this._interface.getClientUserByToken(session);
|
|
175
|
+
});
|
|
176
|
+
this._currentProjectCache = createCache(async () => {
|
|
177
|
+
return import_results.Result.orThrow(await this._interface.getClientProject());
|
|
178
|
+
});
|
|
179
|
+
this._ownedProjectsCache = createCacheBySession(async (session) => {
|
|
180
|
+
return await this._interface.listProjects(session);
|
|
181
|
+
});
|
|
182
|
+
this._currentUserPermissionsCache = createCacheBySession(async (session, [teamId, recursive]) => {
|
|
183
|
+
return await this._interface.listCurrentUserTeamPermissions({ teamId, recursive }, session);
|
|
184
|
+
});
|
|
185
|
+
this._currentUserTeamsCache = createCacheBySession(async (session) => {
|
|
186
|
+
return await this._interface.listCurrentUserTeams(session);
|
|
187
|
+
});
|
|
188
|
+
this._currentUserOAuthConnectionAccessTokensCache = createCacheBySession(
|
|
189
|
+
async (session, [accountId, scope]) => {
|
|
190
|
+
try {
|
|
191
|
+
return await this._interface.getAccessToken(accountId, scope || "", session);
|
|
192
|
+
} catch (err) {
|
|
193
|
+
if (!(err instanceof import_stack_shared.KnownErrors.OAuthConnectionDoesNotHaveRequiredScope || err instanceof import_stack_shared.KnownErrors.OAuthConnectionNotConnectedToUser)) {
|
|
194
|
+
throw err;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
);
|
|
200
|
+
this._currentUserOAuthConnectionCache = createCacheBySession(
|
|
201
|
+
async (session, [connectionId, scope, redirect]) => {
|
|
202
|
+
const user = await this._currentUserCache.getOrWait([session], "write-only");
|
|
203
|
+
let hasConnection = true;
|
|
204
|
+
if (!user || !user.oauth_providers.find((p) => p.id === connectionId)) {
|
|
205
|
+
hasConnection = false;
|
|
206
|
+
}
|
|
207
|
+
const token = await this._currentUserOAuthConnectionAccessTokensCache.getOrWait([session, connectionId, scope || ""], "write-only");
|
|
208
|
+
if (!token) {
|
|
209
|
+
hasConnection = false;
|
|
210
|
+
}
|
|
211
|
+
if (!hasConnection && redirect) {
|
|
212
|
+
await (0, import_auth.addNewOAuthProviderOrScope)(
|
|
213
|
+
this._interface,
|
|
214
|
+
{
|
|
215
|
+
provider: connectionId,
|
|
216
|
+
redirectUrl: this.urls.oauthCallback,
|
|
217
|
+
errorRedirectUrl: this.urls.error,
|
|
218
|
+
providerScope: (0, import_strings.mergeScopeStrings)(scope || "", (this._oauthScopesOnSignIn[connectionId] ?? []).join(" "))
|
|
219
|
+
},
|
|
220
|
+
session
|
|
221
|
+
);
|
|
222
|
+
return await (0, import_promises.neverResolve)();
|
|
223
|
+
} else if (!hasConnection) {
|
|
224
|
+
return null;
|
|
225
|
+
}
|
|
226
|
+
const app = this;
|
|
227
|
+
return {
|
|
228
|
+
id: connectionId,
|
|
229
|
+
async getAccessToken() {
|
|
230
|
+
const result = await app._currentUserOAuthConnectionAccessTokensCache.getOrWait([session, connectionId, scope || ""], "write-only");
|
|
231
|
+
if (!result) {
|
|
232
|
+
throw new import_errors.StackAssertionError("No access token available");
|
|
233
|
+
}
|
|
234
|
+
return result;
|
|
235
|
+
},
|
|
236
|
+
useAccessToken() {
|
|
237
|
+
const result = useAsyncCache(app._currentUserOAuthConnectionAccessTokensCache, [session, connectionId, scope || ""], "oauthAccount.useAccessToken()");
|
|
238
|
+
if (!result) {
|
|
239
|
+
throw new import_errors.StackAssertionError("No access token available");
|
|
240
|
+
}
|
|
241
|
+
return result;
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
);
|
|
246
|
+
this._memoryTokenStore = createEmptyTokenStore();
|
|
247
|
+
this._requestTokenStores = /* @__PURE__ */ new WeakMap();
|
|
248
|
+
this._storedCookieTokenStore = null;
|
|
249
|
+
/**
|
|
250
|
+
* A map from token stores and session keys to sessions.
|
|
251
|
+
*
|
|
252
|
+
* This isn't just a map from session keys to sessions for two reasons:
|
|
253
|
+
*
|
|
254
|
+
* - So we can garbage-collect Session objects when the token store is garbage-collected
|
|
255
|
+
* - 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
|
|
256
|
+
*/
|
|
257
|
+
this._sessionsByTokenStoreAndSessionKey = /* @__PURE__ */ new WeakMap();
|
|
168
258
|
if ("interface" in _options) {
|
|
169
259
|
this._interface = _options.interface;
|
|
170
260
|
} else {
|
|
@@ -182,94 +272,13 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
182
272
|
this._uniqueIdentifier = _options.uniqueIdentifier;
|
|
183
273
|
this._initUniqueIdentifier();
|
|
184
274
|
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
}
|
|
190
|
-
_uniqueIdentifier = void 0;
|
|
191
|
-
_interface;
|
|
192
|
-
_tokenStoreInit;
|
|
193
|
-
_urlOptions;
|
|
194
|
-
_oauthScopesOnSignIn;
|
|
195
|
-
__DEMO_ENABLE_SLIGHT_FETCH_DELAY = false;
|
|
196
|
-
_currentUserCache = createCacheBySession(async (session) => {
|
|
197
|
-
if (this.__DEMO_ENABLE_SLIGHT_FETCH_DELAY) {
|
|
198
|
-
await (0, import_promises.wait)(2e3);
|
|
199
|
-
}
|
|
200
|
-
const user = await this._interface.getClientUserByToken(session);
|
|
201
|
-
return import_results.Result.or(user, null);
|
|
202
|
-
});
|
|
203
|
-
_currentProjectCache = createCache(async () => {
|
|
204
|
-
return import_results.Result.orThrow(await this._interface.getClientProject());
|
|
205
|
-
});
|
|
206
|
-
_ownedProjectsCache = createCacheBySession(async (session) => {
|
|
207
|
-
return await this._interface.listProjects(session);
|
|
208
|
-
});
|
|
209
|
-
_currentUserPermissionsCache = createCacheBySession(async (session, [teamId, type, direct]) => {
|
|
210
|
-
return await this._interface.listClientUserTeamPermissions({ teamId, type, direct }, session);
|
|
211
|
-
});
|
|
212
|
-
_currentUserTeamsCache = createCacheBySession(async (session) => {
|
|
213
|
-
return await this._interface.listClientUserTeams(session);
|
|
214
|
-
});
|
|
215
|
-
_currentUserOAuthConnectionAccessTokensCache = createCacheBySession(
|
|
216
|
-
async (session, [accountId, scope]) => {
|
|
217
|
-
try {
|
|
218
|
-
return await this._interface.getAccessToken(accountId, scope || "", session);
|
|
219
|
-
} catch (err) {
|
|
220
|
-
if (!(err instanceof import_stack_shared.KnownErrors.OAuthConnectionDoesNotHaveRequiredScope || err instanceof import_stack_shared.KnownErrors.OAuthConnectionNotConnectedToUser)) {
|
|
221
|
-
throw err;
|
|
222
|
-
}
|
|
275
|
+
if (!_options.noAutomaticPrefetch) {
|
|
276
|
+
numberOfAppsCreated++;
|
|
277
|
+
if (numberOfAppsCreated > 10) {
|
|
278
|
+
(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.)`);
|
|
223
279
|
}
|
|
224
|
-
return null;
|
|
225
280
|
}
|
|
226
|
-
|
|
227
|
-
_currentUserOAuthConnectionCache = createCacheBySession(
|
|
228
|
-
async (session, [connectionId, scope, redirect]) => {
|
|
229
|
-
const user = await this._currentUserCache.getOrWait([session], "write-only");
|
|
230
|
-
let hasConnection = true;
|
|
231
|
-
if (!user || !user.oauthProviders.find((p) => p === connectionId)) {
|
|
232
|
-
hasConnection = false;
|
|
233
|
-
}
|
|
234
|
-
const token = await this._currentUserOAuthConnectionAccessTokensCache.getOrWait([session, connectionId, scope || ""], "write-only");
|
|
235
|
-
if (!token) {
|
|
236
|
-
hasConnection = false;
|
|
237
|
-
}
|
|
238
|
-
if (!hasConnection && redirect) {
|
|
239
|
-
await (0, import_auth.addNewOAuthProviderOrScope)(
|
|
240
|
-
this._interface,
|
|
241
|
-
{
|
|
242
|
-
provider: connectionId,
|
|
243
|
-
redirectUrl: this.urls.oauthCallback,
|
|
244
|
-
errorRedirectUrl: this.urls.error,
|
|
245
|
-
providerScope: (0, import_strings.mergeScopeStrings)(scope || "", (this._oauthScopesOnSignIn[connectionId] ?? []).join(" "))
|
|
246
|
-
},
|
|
247
|
-
session
|
|
248
|
-
);
|
|
249
|
-
return await (0, import_promises.neverResolve)();
|
|
250
|
-
} else if (!hasConnection) {
|
|
251
|
-
return null;
|
|
252
|
-
}
|
|
253
|
-
const app = this;
|
|
254
|
-
return {
|
|
255
|
-
id: connectionId,
|
|
256
|
-
async getAccessToken() {
|
|
257
|
-
const result = await app._currentUserOAuthConnectionAccessTokensCache.getOrWait([session, connectionId, scope || ""], "write-only");
|
|
258
|
-
if (!result) {
|
|
259
|
-
throw new import_errors.StackAssertionError("No access token available");
|
|
260
|
-
}
|
|
261
|
-
return result;
|
|
262
|
-
},
|
|
263
|
-
useAccessToken() {
|
|
264
|
-
const result = useAsyncCache(app._currentUserOAuthConnectionAccessTokensCache, [session, connectionId, scope || ""], "oauthAccount.useAccessToken()");
|
|
265
|
-
if (!result) {
|
|
266
|
-
throw new import_errors.StackAssertionError("No access token available");
|
|
267
|
-
}
|
|
268
|
-
return result;
|
|
269
|
-
}
|
|
270
|
-
};
|
|
271
|
-
}
|
|
272
|
-
);
|
|
281
|
+
}
|
|
273
282
|
_initUniqueIdentifier() {
|
|
274
283
|
if (!this._uniqueIdentifier) {
|
|
275
284
|
throw new import_errors.StackAssertionError("Unique identifier not initialized");
|
|
@@ -281,7 +290,8 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
281
290
|
}
|
|
282
291
|
/**
|
|
283
292
|
* Cloudflare workers does not allow use of randomness on the global scope (on which the Stack app is probably
|
|
284
|
-
* initialized). For that reason, we generate the unique identifier lazily when it is first needed
|
|
293
|
+
* initialized). For that reason, we generate the unique identifier lazily when it is first needed instead of in the
|
|
294
|
+
* constructor.
|
|
285
295
|
*/
|
|
286
296
|
_getUniqueIdentifier() {
|
|
287
297
|
if (!this._uniqueIdentifier) {
|
|
@@ -297,9 +307,6 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
297
307
|
(0, import_promises.runAsynchronously)(this._checkFeatureSupport(featureName, options));
|
|
298
308
|
throw new import_errors.StackAssertionError(`${featureName} is not currently supported. Please reach out to Stack support for more information.`);
|
|
299
309
|
}
|
|
300
|
-
_memoryTokenStore = createEmptyTokenStore();
|
|
301
|
-
_requestTokenStores = /* @__PURE__ */ new WeakMap();
|
|
302
|
-
_storedCookieTokenStore = null;
|
|
303
310
|
get _refreshTokenCookieName() {
|
|
304
311
|
return `stack-refresh-${this.projectId}`;
|
|
305
312
|
}
|
|
@@ -427,15 +434,6 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
427
434
|
}
|
|
428
435
|
}
|
|
429
436
|
}
|
|
430
|
-
/**
|
|
431
|
-
* A map from token stores and session keys to sessions.
|
|
432
|
-
*
|
|
433
|
-
* This isn't just a map from session keys to sessions for two reasons:
|
|
434
|
-
*
|
|
435
|
-
* - So we can garbage-collect Session objects when the token store is garbage-collected
|
|
436
|
-
* - 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
|
|
437
|
-
*/
|
|
438
|
-
_sessionsByTokenStoreAndSessionKey = /* @__PURE__ */ new WeakMap();
|
|
439
437
|
_getSessionFromTokenStore(tokenStore) {
|
|
440
438
|
const tokenObj = tokenStore.get();
|
|
441
439
|
const sessionKey = import_sessions.InternalSession.calculateSessionKey(tokenObj);
|
|
@@ -469,14 +467,14 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
469
467
|
}
|
|
470
468
|
_useSession(overrideTokenStoreInit) {
|
|
471
469
|
const tokenStore = this._getOrCreateTokenStore(overrideTokenStoreInit);
|
|
472
|
-
const subscribe = (0,
|
|
470
|
+
const subscribe = (0, import_react2.useCallback)((cb) => {
|
|
473
471
|
const { unsubscribe } = tokenStore.onChange(() => {
|
|
474
472
|
cb();
|
|
475
473
|
});
|
|
476
474
|
return unsubscribe;
|
|
477
475
|
}, [tokenStore]);
|
|
478
|
-
const getSnapshot = (0,
|
|
479
|
-
return
|
|
476
|
+
const getSnapshot = (0, import_react2.useCallback)(() => this._getSessionFromTokenStore(tokenStore), [tokenStore]);
|
|
477
|
+
return import_react2.default.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
480
478
|
}
|
|
481
479
|
async _signInToAccountWithTokens(tokens) {
|
|
482
480
|
const tokenStore = this._getOrCreateTokenStore();
|
|
@@ -498,38 +496,28 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
498
496
|
throw new Error("Cannot call this function on a Stack app with a project ID other than 'internal'.");
|
|
499
497
|
}
|
|
500
498
|
}
|
|
501
|
-
|
|
502
|
-
const type = permissionDefinitionScopeToType(json.scope);
|
|
503
|
-
if (type === "team") {
|
|
504
|
-
return {
|
|
505
|
-
id: json.id,
|
|
506
|
-
type,
|
|
507
|
-
teamId: json.scope.teamId
|
|
508
|
-
};
|
|
509
|
-
} else {
|
|
510
|
-
return {
|
|
511
|
-
id: json.id,
|
|
512
|
-
type
|
|
513
|
-
};
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
|
-
_teamFromJson(json) {
|
|
499
|
+
_clientProjectFromCrud(crud) {
|
|
517
500
|
return {
|
|
518
|
-
id:
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
501
|
+
id: crud.id,
|
|
502
|
+
config: {
|
|
503
|
+
credentialEnabled: crud.config.credential_enabled,
|
|
504
|
+
magicLinkEnabled: crud.config.magic_link_enabled,
|
|
505
|
+
oauthProviders: crud.config.oauth_providers.map((p) => ({
|
|
506
|
+
id: p.id
|
|
507
|
+
}))
|
|
524
508
|
}
|
|
525
509
|
};
|
|
526
510
|
}
|
|
527
|
-
|
|
528
|
-
|
|
511
|
+
_clientTeamPermissionFromCrud(crud) {
|
|
512
|
+
return {
|
|
513
|
+
id: crud.id
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
_clientTeamFromCrud(crud) {
|
|
529
517
|
return {
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
518
|
+
id: crud.id,
|
|
519
|
+
displayName: crud.display_name,
|
|
520
|
+
profileImageUrl: crud.profile_image_url
|
|
533
521
|
};
|
|
534
522
|
}
|
|
535
523
|
_createAuth(session) {
|
|
@@ -559,41 +547,29 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
559
547
|
}
|
|
560
548
|
};
|
|
561
549
|
}
|
|
562
|
-
_createBaseUser(
|
|
550
|
+
_createBaseUser(crud) {
|
|
551
|
+
if (!crud) {
|
|
552
|
+
throw new import_errors.StackAssertionError("User not found");
|
|
553
|
+
}
|
|
563
554
|
return {
|
|
564
|
-
projectId:
|
|
565
|
-
id:
|
|
566
|
-
displayName:
|
|
567
|
-
primaryEmail:
|
|
568
|
-
primaryEmailVerified:
|
|
569
|
-
profileImageUrl:
|
|
570
|
-
signedUpAt: new Date(
|
|
571
|
-
clientMetadata:
|
|
572
|
-
hasPassword:
|
|
573
|
-
|
|
574
|
-
oauthProviders:
|
|
575
|
-
selectedTeam:
|
|
555
|
+
projectId: crud.project_id,
|
|
556
|
+
id: crud.id,
|
|
557
|
+
displayName: crud.display_name,
|
|
558
|
+
primaryEmail: crud.primary_email,
|
|
559
|
+
primaryEmailVerified: crud.primary_email_verified,
|
|
560
|
+
profileImageUrl: crud.profile_image_url,
|
|
561
|
+
signedUpAt: new Date(crud.signed_up_at_millis),
|
|
562
|
+
clientMetadata: crud.client_metadata,
|
|
563
|
+
hasPassword: crud.has_password,
|
|
564
|
+
emailAuthEnabled: crud.auth_with_email,
|
|
565
|
+
oauthProviders: crud.oauth_providers,
|
|
566
|
+
selectedTeam: crud.selected_team && this._clientTeamFromCrud(crud.selected_team),
|
|
576
567
|
toClientJson() {
|
|
577
|
-
return
|
|
578
|
-
"projectId",
|
|
579
|
-
"id",
|
|
580
|
-
"displayName",
|
|
581
|
-
"primaryEmail",
|
|
582
|
-
"primaryEmailVerified",
|
|
583
|
-
"profileImageUrl",
|
|
584
|
-
"signedUpAtMillis",
|
|
585
|
-
"clientMetadata",
|
|
586
|
-
"hasPassword",
|
|
587
|
-
"authMethod",
|
|
588
|
-
"authWithEmail",
|
|
589
|
-
"selectedTeamId",
|
|
590
|
-
"selectedTeam",
|
|
591
|
-
"oauthProviders"
|
|
592
|
-
]);
|
|
568
|
+
return crud;
|
|
593
569
|
}
|
|
594
570
|
};
|
|
595
571
|
}
|
|
596
|
-
|
|
572
|
+
_createCurrentUserExtra(crud, session) {
|
|
597
573
|
const app = this;
|
|
598
574
|
async function getConnectedAccount(id, options) {
|
|
599
575
|
const scopeString = options?.scopes?.join(" ");
|
|
@@ -621,34 +597,36 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
621
597
|
},
|
|
622
598
|
useTeam(teamId) {
|
|
623
599
|
const teams = this.useTeams();
|
|
624
|
-
return (0,
|
|
600
|
+
return (0, import_react2.useMemo)(() => {
|
|
625
601
|
return teams.find((t) => t.id === teamId) ?? null;
|
|
626
602
|
}, [teams, teamId]);
|
|
627
603
|
},
|
|
628
604
|
async listTeams() {
|
|
629
605
|
const teams = await app._currentUserTeamsCache.getOrWait([session], "write-only");
|
|
630
|
-
return teams.map((
|
|
606
|
+
return teams.map((crud2) => app._clientTeamFromCrud(crud2));
|
|
631
607
|
},
|
|
632
608
|
useTeams() {
|
|
633
609
|
const teams = useAsyncCache(app._currentUserTeamsCache, [session], "user.useTeams()");
|
|
634
|
-
return (0,
|
|
610
|
+
return (0, import_react2.useMemo)(() => teams.map((crud2) => app._clientTeamFromCrud(crud2)), [teams]);
|
|
635
611
|
},
|
|
636
612
|
async createTeam(data) {
|
|
637
|
-
const
|
|
613
|
+
const crud2 = await app._interface.createTeamForCurrentUser(teamCreateOptionsToCrud(data), session);
|
|
638
614
|
await app._currentUserTeamsCache.refresh([session]);
|
|
639
|
-
return app.
|
|
615
|
+
return app._clientTeamFromCrud(crud2);
|
|
640
616
|
},
|
|
641
617
|
async listPermissions(scope, options) {
|
|
642
|
-
const
|
|
643
|
-
|
|
618
|
+
const recursive = options?.recursive ?? true;
|
|
619
|
+
const permissions = await app._currentUserPermissionsCache.getOrWait([session, scope.id, recursive], "write-only");
|
|
620
|
+
return permissions.map((crud2) => app._clientTeamPermissionFromCrud(crud2));
|
|
644
621
|
},
|
|
645
622
|
usePermissions(scope, options) {
|
|
646
|
-
const
|
|
647
|
-
|
|
623
|
+
const recursive = options?.recursive ?? true;
|
|
624
|
+
const permissions = useAsyncCache(app._currentUserPermissionsCache, [session, scope.id, recursive], "user.usePermissions()");
|
|
625
|
+
return (0, import_react2.useMemo)(() => permissions.map((crud2) => app._clientTeamPermissionFromCrud(crud2)), [permissions]);
|
|
648
626
|
},
|
|
649
627
|
usePermission(scope, permissionId) {
|
|
650
628
|
const permissions = this.usePermissions(scope);
|
|
651
|
-
return (0,
|
|
629
|
+
return (0, import_react2.useMemo)(() => permissions.find((p) => p.id === permissionId) ?? null, [permissions, permissionId]);
|
|
652
630
|
},
|
|
653
631
|
async getPermission(scope, permissionId) {
|
|
654
632
|
const permissions = await this.listPermissions(scope);
|
|
@@ -658,7 +636,7 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
658
636
|
return await this.getPermission(scope, permissionId) !== null;
|
|
659
637
|
},
|
|
660
638
|
update(update) {
|
|
661
|
-
return app.
|
|
639
|
+
return app._updateClientUser(update, session);
|
|
662
640
|
},
|
|
663
641
|
sendVerificationEmail() {
|
|
664
642
|
return app._sendVerificationEmail(session);
|
|
@@ -683,58 +661,27 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
683
661
|
}
|
|
684
662
|
};
|
|
685
663
|
}
|
|
686
|
-
|
|
664
|
+
_currentUserFromCrud(crud, session) {
|
|
687
665
|
const currentUser = {
|
|
688
|
-
...this._createBaseUser(
|
|
666
|
+
...this._createBaseUser(crud),
|
|
689
667
|
...this._createAuth(session),
|
|
690
|
-
...this.
|
|
668
|
+
...this._createCurrentUserExtra(crud, session),
|
|
691
669
|
...this._isInternalProject() ? this._createInternalUserExtra(session) : {}
|
|
692
670
|
};
|
|
693
671
|
Object.freeze(currentUser);
|
|
694
672
|
return currentUser;
|
|
695
673
|
}
|
|
696
|
-
|
|
697
|
-
if (
|
|
698
|
-
|
|
674
|
+
_getOwnedAdminApp(forProjectId, session) {
|
|
675
|
+
if (!this._ownedAdminApps.has([session, forProjectId])) {
|
|
676
|
+
this._ownedAdminApps.set([session, forProjectId], new _StackAdminAppImpl({
|
|
677
|
+
baseUrl: this._interface.options.baseUrl,
|
|
678
|
+
projectId: forProjectId,
|
|
679
|
+
tokenStore: null,
|
|
680
|
+
projectOwnerSession: session,
|
|
681
|
+
noAutomaticPrefetch: true
|
|
682
|
+
}));
|
|
699
683
|
}
|
|
700
|
-
return
|
|
701
|
-
id: data.id,
|
|
702
|
-
displayName: data.displayName,
|
|
703
|
-
description: data.description,
|
|
704
|
-
createdAt: new Date(data.createdAtMillis),
|
|
705
|
-
userCount: data.userCount,
|
|
706
|
-
isProductionMode: data.isProductionMode,
|
|
707
|
-
evaluatedConfig: {
|
|
708
|
-
id: data.evaluatedConfig.id,
|
|
709
|
-
credentialEnabled: data.evaluatedConfig.credentialEnabled,
|
|
710
|
-
magicLinkEnabled: data.evaluatedConfig.magicLinkEnabled,
|
|
711
|
-
allowLocalhost: data.evaluatedConfig.allowLocalhost,
|
|
712
|
-
oauthProviders: data.evaluatedConfig.oauthProviders,
|
|
713
|
-
emailConfig: data.evaluatedConfig.emailConfig,
|
|
714
|
-
domains: data.evaluatedConfig.domains,
|
|
715
|
-
createTeamOnSignUp: data.evaluatedConfig.createTeamOnSignUp,
|
|
716
|
-
teamCreatorDefaultPermissions: data.evaluatedConfig.teamCreatorDefaultPermissions,
|
|
717
|
-
teamMemberDefaultPermissions: data.evaluatedConfig.teamMemberDefaultPermissions
|
|
718
|
-
},
|
|
719
|
-
async update(update) {
|
|
720
|
-
await adminInterface.updateProject(update);
|
|
721
|
-
await onRefresh();
|
|
722
|
-
},
|
|
723
|
-
toJson() {
|
|
724
|
-
return data;
|
|
725
|
-
},
|
|
726
|
-
getProductionModeErrors() {
|
|
727
|
-
return (0, import_clientInterface.getProductionModeErrors)(this.toJson());
|
|
728
|
-
}
|
|
729
|
-
};
|
|
730
|
-
}
|
|
731
|
-
_createAdminInterface(forProjectId, session) {
|
|
732
|
-
return new import_stack_shared.StackAdminInterface({
|
|
733
|
-
baseUrl: this._interface.options.baseUrl,
|
|
734
|
-
projectId: forProjectId,
|
|
735
|
-
clientVersion,
|
|
736
|
-
projectOwnerSession: session
|
|
737
|
-
});
|
|
684
|
+
return this._ownedAdminApps.get([session, forProjectId]);
|
|
738
685
|
}
|
|
739
686
|
get projectId() {
|
|
740
687
|
return this._interface.projectId;
|
|
@@ -814,8 +761,8 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
814
761
|
async getUser(options) {
|
|
815
762
|
this._ensurePersistentTokenStore(options?.tokenStore);
|
|
816
763
|
const session = this._getSession(options?.tokenStore);
|
|
817
|
-
const
|
|
818
|
-
if (
|
|
764
|
+
const crud = await this._currentUserCache.getOrWait([session], "write-only");
|
|
765
|
+
if (crud === null) {
|
|
819
766
|
switch (options?.or) {
|
|
820
767
|
case "redirect": {
|
|
821
768
|
await this.redirectToSignIn();
|
|
@@ -829,18 +776,18 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
829
776
|
}
|
|
830
777
|
}
|
|
831
778
|
}
|
|
832
|
-
return
|
|
779
|
+
return crud && this._currentUserFromCrud(crud, session);
|
|
833
780
|
}
|
|
834
781
|
useUser(options) {
|
|
835
782
|
this._ensurePersistentTokenStore(options?.tokenStore);
|
|
836
783
|
const router = NextNavigation.useRouter();
|
|
837
784
|
const session = this._useSession(options?.tokenStore);
|
|
838
|
-
const
|
|
839
|
-
if (
|
|
785
|
+
const crud = useAsyncCache(this._currentUserCache, [session], "useUser()");
|
|
786
|
+
if (crud === null) {
|
|
840
787
|
switch (options?.or) {
|
|
841
788
|
case "redirect": {
|
|
842
789
|
setTimeout(() => router.replace(this.urls.signIn), 0);
|
|
843
|
-
(0,
|
|
790
|
+
(0, import_react.suspend)();
|
|
844
791
|
throw new import_errors.StackAssertionError("suspend should never return");
|
|
845
792
|
}
|
|
846
793
|
case "throw": {
|
|
@@ -851,12 +798,12 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
851
798
|
}
|
|
852
799
|
}
|
|
853
800
|
}
|
|
854
|
-
return (0,
|
|
855
|
-
return
|
|
856
|
-
}, [
|
|
801
|
+
return (0, import_react2.useMemo)(() => {
|
|
802
|
+
return crud && this._currentUserFromCrud(crud, session);
|
|
803
|
+
}, [crud, session, options?.or]);
|
|
857
804
|
}
|
|
858
|
-
async
|
|
859
|
-
const res = await this._interface.
|
|
805
|
+
async _updateClientUser(update, session) {
|
|
806
|
+
const res = await this._interface.updateClientUser(userUpdateOptionsToCrud(update), session);
|
|
860
807
|
await this._refreshUser(session);
|
|
861
808
|
return res;
|
|
862
809
|
}
|
|
@@ -900,8 +847,7 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
900
847
|
}
|
|
901
848
|
async signInWithMagicLink(code) {
|
|
902
849
|
this._ensurePersistentTokenStore();
|
|
903
|
-
const
|
|
904
|
-
const result = await this._interface.signInWithMagicLink(code, session);
|
|
850
|
+
const result = await this._interface.signInWithMagicLink(code);
|
|
905
851
|
if (result instanceof import_stack_shared.KnownError) {
|
|
906
852
|
return result;
|
|
907
853
|
}
|
|
@@ -948,35 +894,34 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
948
894
|
}
|
|
949
895
|
}
|
|
950
896
|
async getProject() {
|
|
951
|
-
|
|
897
|
+
const crud = await this._currentProjectCache.getOrWait([], "write-only");
|
|
898
|
+
return this._clientProjectFromCrud(crud);
|
|
952
899
|
}
|
|
953
900
|
useProject() {
|
|
954
|
-
|
|
901
|
+
const crud = useAsyncCache(this._currentProjectCache, [], "useProject()");
|
|
902
|
+
return (0, import_react2.useMemo)(() => this._clientProjectFromCrud(crud), [crud]);
|
|
955
903
|
}
|
|
956
904
|
async _listOwnedProjects(session) {
|
|
957
905
|
this._ensureInternalProject();
|
|
958
|
-
const
|
|
959
|
-
return
|
|
906
|
+
const crud = await this._ownedProjectsCache.getOrWait([session], "write-only");
|
|
907
|
+
return crud.map((j) => this._getOwnedAdminApp(j.id, session)._adminOwnedProjectFromCrud(
|
|
960
908
|
j,
|
|
961
|
-
this._createAdminInterface(j.id, session),
|
|
962
909
|
() => this._refreshOwnedProjects(session)
|
|
963
910
|
));
|
|
964
911
|
}
|
|
965
912
|
_useOwnedProjects(session) {
|
|
966
913
|
this._ensureInternalProject();
|
|
967
|
-
const
|
|
968
|
-
return (0,
|
|
914
|
+
const projects = useAsyncCache(this._ownedProjectsCache, [session], "useOwnedProjects()");
|
|
915
|
+
return (0, import_react2.useMemo)(() => projects.map((j) => this._getOwnedAdminApp(j.id, session)._adminOwnedProjectFromCrud(
|
|
969
916
|
j,
|
|
970
|
-
this._createAdminInterface(j.id, session),
|
|
971
917
|
() => this._refreshOwnedProjects(session)
|
|
972
|
-
)), [
|
|
918
|
+
)), [projects]);
|
|
973
919
|
}
|
|
974
920
|
async _createProject(session, newProject) {
|
|
975
921
|
this._ensureInternalProject();
|
|
976
|
-
const
|
|
977
|
-
const res = this.
|
|
978
|
-
|
|
979
|
-
this._createAdminInterface(json.id, session),
|
|
922
|
+
const crud = await this._interface.createProject(adminProjectCreateOptionsToCrud(newProject), session);
|
|
923
|
+
const res = this._getOwnedAdminApp(crud.id, session)._adminOwnedProjectFromCrud(
|
|
924
|
+
crud,
|
|
980
925
|
() => this._refreshOwnedProjects(session)
|
|
981
926
|
);
|
|
982
927
|
await this._refreshOwnedProjects(session);
|
|
@@ -1040,33 +985,6 @@ var _StackClientAppImpl = class __StackClientAppImpl {
|
|
|
1040
985
|
}
|
|
1041
986
|
};
|
|
1042
987
|
var _StackServerAppImpl = class extends _StackClientAppImpl {
|
|
1043
|
-
// TODO override the client user cache to use the server user cache, so we save some requests
|
|
1044
|
-
_currentServerUserCache = createCacheBySession(async (session) => {
|
|
1045
|
-
const user = await this._interface.getServerUserByToken(session);
|
|
1046
|
-
return import_results.Result.or(user, null);
|
|
1047
|
-
});
|
|
1048
|
-
_serverUsersCache = createCache(async () => {
|
|
1049
|
-
return await this._interface.listServerUsers();
|
|
1050
|
-
});
|
|
1051
|
-
_serverUserCache = createCache(async ([userId]) => {
|
|
1052
|
-
const user = await this._interface.getServerUserById(userId);
|
|
1053
|
-
return import_results.Result.or(user, null);
|
|
1054
|
-
});
|
|
1055
|
-
_serverTeamsCache = createCache(async () => {
|
|
1056
|
-
return await this._interface.listServerTeams();
|
|
1057
|
-
});
|
|
1058
|
-
_serverTeamMembersCache = createCache(async ([teamId]) => {
|
|
1059
|
-
return await this._interface.listServerTeamMembers(teamId);
|
|
1060
|
-
});
|
|
1061
|
-
_serverTeamPermissionDefinitionsCache = createCache(async () => {
|
|
1062
|
-
return await this._interface.listPermissionDefinitions();
|
|
1063
|
-
});
|
|
1064
|
-
_serverTeamUserPermissionsCache = createCache(async ([teamId, userId, type, direct]) => {
|
|
1065
|
-
return await this._interface.listServerTeamMemberPermissions({ teamId, userId, type, direct });
|
|
1066
|
-
});
|
|
1067
|
-
_serverEmailTemplatesCache = createCache(async () => {
|
|
1068
|
-
return await this._interface.listEmailTemplates();
|
|
1069
|
-
});
|
|
1070
988
|
constructor(options) {
|
|
1071
989
|
super("interface" in options ? {
|
|
1072
990
|
interface: options.interface,
|
|
@@ -1085,24 +1003,46 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
|
|
|
1085
1003
|
urls: options.urls ?? {},
|
|
1086
1004
|
oauthScopesOnSignIn: options.oauthScopesOnSignIn ?? {}
|
|
1087
1005
|
});
|
|
1006
|
+
// TODO override the client user cache to use the server user cache, so we save some requests
|
|
1007
|
+
this._currentServerUserCache = createCacheBySession(async (session) => {
|
|
1008
|
+
return await this._interface.getServerUserByToken(session);
|
|
1009
|
+
});
|
|
1010
|
+
this._serverUsersCache = createCache(async () => {
|
|
1011
|
+
return await this._interface.listServerUsers();
|
|
1012
|
+
});
|
|
1013
|
+
this._serverUserCache = createCache(async ([userId]) => {
|
|
1014
|
+
const user = await this._interface.getServerUserById(userId);
|
|
1015
|
+
return import_results.Result.or(user, null);
|
|
1016
|
+
});
|
|
1017
|
+
this._serverTeamsCache = createCache(async () => {
|
|
1018
|
+
return await this._interface.listServerTeams();
|
|
1019
|
+
});
|
|
1020
|
+
this._serverCurrentUserTeamsCache = createCacheBySession(async (session) => {
|
|
1021
|
+
return await this._interface.listServerCurrentUserTeams(session);
|
|
1022
|
+
});
|
|
1023
|
+
this._serverTeamUsersCache = createCache(async ([teamId]) => {
|
|
1024
|
+
return await this._interface.listServerTeamUsers(teamId);
|
|
1025
|
+
});
|
|
1026
|
+
this._serverTeamUserPermissionsCache = createCache(async ([teamId, userId, recursive]) => {
|
|
1027
|
+
return await this._interface.listServerTeamMemberPermissions({ teamId, userId, recursive });
|
|
1028
|
+
});
|
|
1088
1029
|
}
|
|
1089
|
-
_createBaseUser(
|
|
1030
|
+
_createBaseUser(crud) {
|
|
1031
|
+
if (!crud) {
|
|
1032
|
+
throw new import_errors.StackAssertionError("User not found");
|
|
1033
|
+
}
|
|
1090
1034
|
return {
|
|
1091
|
-
...super._createBaseUser(
|
|
1092
|
-
..."
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
return {
|
|
1096
|
-
...this.toClientJson(),
|
|
1097
|
-
...(0, import_objects.pick)(json, [
|
|
1098
|
-
"serverMetadata"
|
|
1099
|
-
])
|
|
1100
|
-
};
|
|
1101
|
-
}
|
|
1035
|
+
...super._createBaseUser(crud),
|
|
1036
|
+
..."server_metadata" in crud ? {
|
|
1037
|
+
// server user
|
|
1038
|
+
serverMetadata: crud.server_metadata
|
|
1102
1039
|
} : {}
|
|
1103
1040
|
};
|
|
1104
1041
|
}
|
|
1105
|
-
|
|
1042
|
+
_createCurrentUserExtra(crud) {
|
|
1043
|
+
if (!crud) {
|
|
1044
|
+
throw new import_errors.StackAssertionError("User not found");
|
|
1045
|
+
}
|
|
1106
1046
|
const app = this;
|
|
1107
1047
|
return {
|
|
1108
1048
|
async setDisplayName(displayName) {
|
|
@@ -1118,7 +1058,7 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
|
|
|
1118
1058
|
return await this.update({ selectedTeamId: team?.id ?? null });
|
|
1119
1059
|
},
|
|
1120
1060
|
async setPrimaryEmail(email, options) {
|
|
1121
|
-
return await this.update({ primaryEmail: email });
|
|
1061
|
+
return await this.update({ primaryEmail: email, primaryEmailVerified: options?.verified });
|
|
1122
1062
|
},
|
|
1123
1063
|
getConnectedAccount: async () => {
|
|
1124
1064
|
return await app._checkFeatureSupport("getConnectedAccount() on ServerUser", {});
|
|
@@ -1131,31 +1071,29 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
|
|
|
1131
1071
|
return teams.find((t) => t.id === teamId) ?? null;
|
|
1132
1072
|
},
|
|
1133
1073
|
useTeam(teamId) {
|
|
1134
|
-
|
|
1135
|
-
return (0, import_react.useMemo)(() => {
|
|
1136
|
-
return teams.find((t) => t.id === teamId) ?? null;
|
|
1137
|
-
}, [teams, teamId]);
|
|
1074
|
+
return app._useCheckFeatureSupport("useTeam() on ServerUser", {});
|
|
1138
1075
|
},
|
|
1139
1076
|
async listTeams() {
|
|
1140
|
-
const
|
|
1141
|
-
|
|
1142
|
-
return withMembers.filter(([_, members]) => members.find((m) => m.userId === json.id)).map(([t]) => t);
|
|
1077
|
+
const crud2 = await app._serverCurrentUserTeamsCache.getOrWait([app._getSession()], "write-only");
|
|
1078
|
+
return crud2.map((t) => app._serverTeamFromCrud(t));
|
|
1143
1079
|
},
|
|
1144
1080
|
useTeams() {
|
|
1145
1081
|
return app._useCheckFeatureSupport("useTeams() on ServerUser", {});
|
|
1146
1082
|
},
|
|
1147
1083
|
createTeam: async (data) => {
|
|
1148
|
-
const team = await app._interface.
|
|
1084
|
+
const team = await app._interface.createServerTeam(serverTeamCreateOptionsToCrud(data), app._getSession());
|
|
1149
1085
|
await app._serverTeamsCache.refresh([]);
|
|
1150
|
-
return app.
|
|
1086
|
+
return app._serverTeamFromCrud(team);
|
|
1151
1087
|
},
|
|
1152
1088
|
async listPermissions(scope, options) {
|
|
1153
|
-
const
|
|
1154
|
-
|
|
1089
|
+
const recursive = options?.recursive ?? true;
|
|
1090
|
+
const permissions = await app._serverTeamUserPermissionsCache.getOrWait([scope.id, crud.id, recursive], "write-only");
|
|
1091
|
+
return permissions.map((crud2) => app._serverPermissionFromCrud(crud2));
|
|
1155
1092
|
},
|
|
1156
1093
|
usePermissions(scope, options) {
|
|
1157
|
-
const
|
|
1158
|
-
|
|
1094
|
+
const recursive = options?.recursive ?? true;
|
|
1095
|
+
const permissions = useAsyncCache(app._serverTeamUserPermissionsCache, [scope.id, crud.id, recursive], "user.usePermissions()");
|
|
1096
|
+
return (0, import_react2.useMemo)(() => permissions.map((crud2) => app._serverPermissionFromCrud(crud2)), [permissions]);
|
|
1159
1097
|
},
|
|
1160
1098
|
async getPermission(scope, permissionId) {
|
|
1161
1099
|
const permissions = await this.listPermissions(scope);
|
|
@@ -1163,32 +1101,31 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
|
|
|
1163
1101
|
},
|
|
1164
1102
|
usePermission(scope, permissionId) {
|
|
1165
1103
|
const permissions = this.usePermissions(scope);
|
|
1166
|
-
return (0,
|
|
1104
|
+
return (0, import_react2.useMemo)(() => permissions.find((p) => p.id === permissionId) ?? null, [permissions, permissionId]);
|
|
1167
1105
|
},
|
|
1168
1106
|
async hasPermission(scope, permissionId) {
|
|
1169
1107
|
return await this.getPermission(scope, permissionId) !== null;
|
|
1170
1108
|
},
|
|
1171
1109
|
async grantPermission(scope, permissionId) {
|
|
1172
|
-
await app._interface.grantServerTeamUserPermission(scope.id,
|
|
1173
|
-
for (const
|
|
1174
|
-
await app._serverTeamUserPermissionsCache.refresh([scope.id,
|
|
1110
|
+
await app._interface.grantServerTeamUserPermission(scope.id, crud.id, permissionId);
|
|
1111
|
+
for (const recursive of [true, false]) {
|
|
1112
|
+
await app._serverTeamUserPermissionsCache.refresh([scope.id, crud.id, recursive]);
|
|
1175
1113
|
}
|
|
1176
1114
|
},
|
|
1177
1115
|
async revokePermission(scope, permissionId) {
|
|
1178
|
-
await app._interface.revokeServerTeamUserPermission(scope.id,
|
|
1179
|
-
for (const
|
|
1180
|
-
await app._serverTeamUserPermissionsCache.refresh([scope.id,
|
|
1116
|
+
await app._interface.revokeServerTeamUserPermission(scope.id, crud.id, permissionId);
|
|
1117
|
+
for (const recursive of [true, false]) {
|
|
1118
|
+
await app._serverTeamUserPermissionsCache.refresh([scope.id, crud.id, recursive]);
|
|
1181
1119
|
}
|
|
1182
1120
|
},
|
|
1183
1121
|
async delete() {
|
|
1184
|
-
const res = await app._interface.deleteServerServerUser(
|
|
1122
|
+
const res = await app._interface.deleteServerServerUser(crud.id);
|
|
1185
1123
|
await app._refreshUsers();
|
|
1186
1124
|
return res;
|
|
1187
1125
|
},
|
|
1188
1126
|
async update(update) {
|
|
1189
|
-
const res = await app._interface.
|
|
1127
|
+
const res = await app._interface.updateServerUser(crud.id, serverUserUpdateOptionsToCrud(update));
|
|
1190
1128
|
await app._refreshUsers();
|
|
1191
|
-
return res;
|
|
1192
1129
|
},
|
|
1193
1130
|
async sendVerificationEmail() {
|
|
1194
1131
|
return await app._checkFeatureSupport("sendVerificationEmail() on ServerUser", {});
|
|
@@ -1198,76 +1135,65 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
|
|
|
1198
1135
|
}
|
|
1199
1136
|
};
|
|
1200
1137
|
}
|
|
1201
|
-
|
|
1138
|
+
_serverUserFromCrud(crud) {
|
|
1202
1139
|
return {
|
|
1203
|
-
...this._createBaseUser(
|
|
1204
|
-
...this.
|
|
1140
|
+
...this._createBaseUser(crud),
|
|
1141
|
+
...this._createCurrentUserExtra(crud)
|
|
1205
1142
|
};
|
|
1206
1143
|
}
|
|
1207
|
-
|
|
1144
|
+
_currentUserFromCrud(crud, session) {
|
|
1208
1145
|
const app = this;
|
|
1209
1146
|
const currentUser = {
|
|
1210
|
-
...this.
|
|
1147
|
+
...this._serverUserFromCrud(crud),
|
|
1211
1148
|
...this._createAuth(session),
|
|
1212
1149
|
...this._isInternalProject() ? this._createInternalUserExtra(session) : {}
|
|
1213
1150
|
};
|
|
1214
1151
|
Object.freeze(currentUser);
|
|
1215
1152
|
return currentUser;
|
|
1216
1153
|
}
|
|
1217
|
-
|
|
1218
|
-
if (json === null) return null;
|
|
1219
|
-
const app = this;
|
|
1220
|
-
return {
|
|
1221
|
-
...app._teamMemberFromJson(json),
|
|
1222
|
-
user: app._createUser(json.user)
|
|
1223
|
-
};
|
|
1224
|
-
}
|
|
1225
|
-
_serverTeamFromJson(json) {
|
|
1154
|
+
_serverTeamFromCrud(crud) {
|
|
1226
1155
|
const app = this;
|
|
1227
1156
|
return {
|
|
1228
|
-
id:
|
|
1229
|
-
displayName:
|
|
1230
|
-
profileImageUrl:
|
|
1231
|
-
createdAt: new Date(
|
|
1232
|
-
async
|
|
1233
|
-
return (await app._interface.
|
|
1157
|
+
id: crud.id,
|
|
1158
|
+
displayName: crud.display_name,
|
|
1159
|
+
profileImageUrl: crud.profile_image_url,
|
|
1160
|
+
createdAt: new Date(crud.created_at_millis),
|
|
1161
|
+
async listUsers() {
|
|
1162
|
+
return (await app._interface.listServerTeamUsers(crud.id)).map((u) => app._serverUserFromCrud(u));
|
|
1234
1163
|
},
|
|
1235
1164
|
async update(update) {
|
|
1236
|
-
await app._interface.updateServerTeam(
|
|
1165
|
+
await app._interface.updateServerTeam(crud.id, serverTeamUpdateOptionsToCrud(update));
|
|
1237
1166
|
await app._serverTeamsCache.refresh([]);
|
|
1238
1167
|
},
|
|
1239
1168
|
async delete() {
|
|
1240
|
-
await app._interface.deleteServerTeam(
|
|
1169
|
+
await app._interface.deleteServerTeam(crud.id);
|
|
1241
1170
|
await app._serverTeamsCache.refresh([]);
|
|
1242
1171
|
},
|
|
1243
|
-
|
|
1244
|
-
const result = useAsyncCache(app.
|
|
1245
|
-
return (0,
|
|
1172
|
+
useUsers() {
|
|
1173
|
+
const result = useAsyncCache(app._serverTeamUsersCache, [crud.id], "team.useUsers()");
|
|
1174
|
+
return (0, import_react2.useMemo)(() => result.map((u) => app._serverUserFromCrud(u)), [result]);
|
|
1246
1175
|
},
|
|
1247
1176
|
async addUser(userId) {
|
|
1248
1177
|
await app._interface.addServerUserToTeam({
|
|
1249
|
-
teamId:
|
|
1178
|
+
teamId: crud.id,
|
|
1250
1179
|
userId
|
|
1251
1180
|
});
|
|
1252
|
-
await app.
|
|
1181
|
+
await app._serverTeamUsersCache.refresh([crud.id]);
|
|
1253
1182
|
},
|
|
1254
1183
|
async removeUser(userId) {
|
|
1255
1184
|
await app._interface.removeServerUserFromTeam({
|
|
1256
|
-
teamId:
|
|
1185
|
+
teamId: crud.id,
|
|
1257
1186
|
userId
|
|
1258
1187
|
});
|
|
1259
|
-
await app.
|
|
1260
|
-
},
|
|
1261
|
-
toJson() {
|
|
1262
|
-
return json;
|
|
1188
|
+
await app._serverTeamUsersCache.refresh([crud.id]);
|
|
1263
1189
|
}
|
|
1264
1190
|
};
|
|
1265
1191
|
}
|
|
1266
1192
|
async getUser(options) {
|
|
1267
1193
|
this._ensurePersistentTokenStore(options?.tokenStore);
|
|
1268
1194
|
const session = this._getSession(options?.tokenStore);
|
|
1269
|
-
const
|
|
1270
|
-
if (
|
|
1195
|
+
const crud = await this._currentServerUserCache.getOrWait([session], "write-only");
|
|
1196
|
+
if (crud === null) {
|
|
1271
1197
|
switch (options?.or) {
|
|
1272
1198
|
case "redirect": {
|
|
1273
1199
|
await this.redirectToSignIn();
|
|
@@ -1281,26 +1207,26 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
|
|
|
1281
1207
|
}
|
|
1282
1208
|
}
|
|
1283
1209
|
}
|
|
1284
|
-
return
|
|
1210
|
+
return crud && this._currentUserFromCrud(crud, session);
|
|
1285
1211
|
}
|
|
1286
1212
|
async getServerUser() {
|
|
1287
1213
|
console.warn("stackServerApp.getServerUser is deprecated; use stackServerApp.getUser instead");
|
|
1288
1214
|
return await this.getUser();
|
|
1289
1215
|
}
|
|
1290
1216
|
async getServerUserById(userId) {
|
|
1291
|
-
const
|
|
1292
|
-
return
|
|
1217
|
+
const crud = await this._serverUserCache.getOrWait([userId], "write-only");
|
|
1218
|
+
return crud && this._serverUserFromCrud(crud);
|
|
1293
1219
|
}
|
|
1294
1220
|
useUser(options) {
|
|
1295
1221
|
this._ensurePersistentTokenStore(options?.tokenStore);
|
|
1296
1222
|
const router = NextNavigation.useRouter();
|
|
1297
1223
|
const session = this._getSession(options?.tokenStore);
|
|
1298
|
-
const
|
|
1299
|
-
if (
|
|
1224
|
+
const crud = useAsyncCache(this._currentServerUserCache, [session], "useUser()");
|
|
1225
|
+
if (crud === null) {
|
|
1300
1226
|
switch (options?.or) {
|
|
1301
1227
|
case "redirect": {
|
|
1302
1228
|
setTimeout(() => router.replace(this.urls.signIn), 0);
|
|
1303
|
-
(0,
|
|
1229
|
+
(0, import_react.suspend)();
|
|
1304
1230
|
throw new import_errors.StackAssertionError("suspend should never return");
|
|
1305
1231
|
}
|
|
1306
1232
|
case "throw": {
|
|
@@ -1311,66 +1237,51 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
|
|
|
1311
1237
|
}
|
|
1312
1238
|
}
|
|
1313
1239
|
}
|
|
1314
|
-
return (0,
|
|
1315
|
-
return
|
|
1316
|
-
}, [
|
|
1240
|
+
return (0, import_react2.useMemo)(() => {
|
|
1241
|
+
return crud && this._currentUserFromCrud(crud, session);
|
|
1242
|
+
}, [crud, session, options?.or]);
|
|
1317
1243
|
}
|
|
1318
1244
|
useUserById(userId) {
|
|
1319
|
-
const
|
|
1320
|
-
return (0,
|
|
1321
|
-
return
|
|
1322
|
-
}, [
|
|
1245
|
+
const crud = useAsyncCache(this._serverUserCache, [userId], "useUserById()");
|
|
1246
|
+
return (0, import_react2.useMemo)(() => {
|
|
1247
|
+
return crud && this._serverUserFromCrud(crud);
|
|
1248
|
+
}, [crud]);
|
|
1323
1249
|
}
|
|
1324
1250
|
async listUsers() {
|
|
1325
|
-
const
|
|
1326
|
-
return
|
|
1251
|
+
const crud = await this._serverUsersCache.getOrWait([], "write-only");
|
|
1252
|
+
return crud.map((j) => this._serverUserFromCrud(j));
|
|
1327
1253
|
}
|
|
1328
1254
|
useUsers() {
|
|
1329
|
-
const
|
|
1330
|
-
return (0,
|
|
1331
|
-
return
|
|
1332
|
-
}, [
|
|
1333
|
-
}
|
|
1334
|
-
async listPermissionDefinitions() {
|
|
1335
|
-
return await this._serverTeamPermissionDefinitionsCache.getOrWait([], "write-only");
|
|
1255
|
+
const crud = useAsyncCache(this._serverUsersCache, [], "useServerUsers()");
|
|
1256
|
+
return (0, import_react2.useMemo)(() => {
|
|
1257
|
+
return crud.map((j) => this._serverUserFromCrud(j));
|
|
1258
|
+
}, [crud]);
|
|
1336
1259
|
}
|
|
1337
|
-
|
|
1338
|
-
return useAsyncCache(this._serverTeamPermissionDefinitionsCache, [], "usePermissions()");
|
|
1339
|
-
}
|
|
1340
|
-
_serverPermissionFromJson(json) {
|
|
1260
|
+
_serverPermissionFromCrud(crud) {
|
|
1341
1261
|
return {
|
|
1342
|
-
|
|
1343
|
-
__databaseUniqueId: json.__databaseUniqueId,
|
|
1344
|
-
description: json.description,
|
|
1345
|
-
containPermissionIds: json.containPermissionIds
|
|
1262
|
+
id: crud.id
|
|
1346
1263
|
};
|
|
1347
1264
|
}
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
await this._interface.updatePermissionDefinition(permissionId, data);
|
|
1355
|
-
await this._serverTeamPermissionDefinitionsCache.refresh([]);
|
|
1356
|
-
}
|
|
1357
|
-
async deletePermissionDefinition(permissionId) {
|
|
1358
|
-
await this._interface.deletePermissionDefinition(permissionId);
|
|
1359
|
-
await this._serverTeamPermissionDefinitionsCache.refresh([]);
|
|
1265
|
+
_serverTeamPermissionDefinitionFromCrud(crud) {
|
|
1266
|
+
return {
|
|
1267
|
+
id: crud.id,
|
|
1268
|
+
description: crud.description,
|
|
1269
|
+
containedPermissionIds: crud.contained_permission_ids
|
|
1270
|
+
};
|
|
1360
1271
|
}
|
|
1361
1272
|
async listTeams() {
|
|
1362
1273
|
const teams = await this._serverTeamsCache.getOrWait([], "write-only");
|
|
1363
|
-
return teams.map((t) => this.
|
|
1274
|
+
return teams.map((t) => this._serverTeamFromCrud(t));
|
|
1364
1275
|
}
|
|
1365
1276
|
async createTeam(data) {
|
|
1366
|
-
const team = await this._interface.createServerTeam(data);
|
|
1277
|
+
const team = await this._interface.createServerTeam(serverTeamCreateOptionsToCrud(data));
|
|
1367
1278
|
await this._serverTeamsCache.refresh([]);
|
|
1368
|
-
return this.
|
|
1279
|
+
return this._serverTeamFromCrud(team);
|
|
1369
1280
|
}
|
|
1370
1281
|
useTeams() {
|
|
1371
1282
|
const teams = useAsyncCache(this._serverTeamsCache, [], "useServerTeams()");
|
|
1372
|
-
return (0,
|
|
1373
|
-
return teams.map((t) => this.
|
|
1283
|
+
return (0, import_react2.useMemo)(() => {
|
|
1284
|
+
return teams.map((t) => this._serverTeamFromCrud(t));
|
|
1374
1285
|
}, [teams]);
|
|
1375
1286
|
}
|
|
1376
1287
|
async getTeam(teamId) {
|
|
@@ -1379,7 +1290,7 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
|
|
|
1379
1290
|
}
|
|
1380
1291
|
useTeam(teamId) {
|
|
1381
1292
|
const teams = this.useTeams();
|
|
1382
|
-
return (0,
|
|
1293
|
+
return (0, import_react2.useMemo)(() => {
|
|
1383
1294
|
return teams.find((t) => t.id === teamId) ?? null;
|
|
1384
1295
|
}, [teams, teamId]);
|
|
1385
1296
|
}
|
|
@@ -1395,28 +1306,8 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
|
|
|
1395
1306
|
this._serverUsersCache.refresh([])
|
|
1396
1307
|
]);
|
|
1397
1308
|
}
|
|
1398
|
-
useEmailTemplates() {
|
|
1399
|
-
return useAsyncCache(this._serverEmailTemplatesCache, [], "useEmailTemplates()");
|
|
1400
|
-
}
|
|
1401
|
-
async listEmailTemplates() {
|
|
1402
|
-
return await this._serverEmailTemplatesCache.getOrWait([], "write-only");
|
|
1403
|
-
}
|
|
1404
|
-
async updateEmailTemplate(type, data) {
|
|
1405
|
-
await this._interface.updateEmailTemplate(type, data);
|
|
1406
|
-
await this._serverEmailTemplatesCache.refresh([]);
|
|
1407
|
-
}
|
|
1408
|
-
async resetEmailTemplate(type) {
|
|
1409
|
-
await this._interface.resetEmailTemplate(type);
|
|
1410
|
-
await this._serverEmailTemplatesCache.refresh([]);
|
|
1411
|
-
}
|
|
1412
1309
|
};
|
|
1413
1310
|
var _StackAdminAppImpl = class extends _StackServerAppImpl {
|
|
1414
|
-
_adminProjectCache = createCache(async () => {
|
|
1415
|
-
return await this._interface.getProject();
|
|
1416
|
-
});
|
|
1417
|
-
_apiKeySetsCache = createCache(async () => {
|
|
1418
|
-
return await this._interface.listApiKeySets();
|
|
1419
|
-
});
|
|
1420
1311
|
constructor(options) {
|
|
1421
1312
|
super({
|
|
1422
1313
|
interface: new import_stack_shared.StackAdminInterface({
|
|
@@ -1435,15 +1326,117 @@ var _StackAdminAppImpl = class extends _StackServerAppImpl {
|
|
|
1435
1326
|
urls: options.urls,
|
|
1436
1327
|
oauthScopesOnSignIn: options.oauthScopesOnSignIn
|
|
1437
1328
|
});
|
|
1329
|
+
this._adminProjectCache = createCache(async () => {
|
|
1330
|
+
return await this._interface.getProject();
|
|
1331
|
+
});
|
|
1332
|
+
this._apiKeysCache = createCache(async () => {
|
|
1333
|
+
return await this._interface.listApiKeys();
|
|
1334
|
+
});
|
|
1335
|
+
this._adminEmailTemplatesCache = createCache(async () => {
|
|
1336
|
+
return await this._interface.listEmailTemplates();
|
|
1337
|
+
});
|
|
1338
|
+
this._adminTeamPermissionDefinitionsCache = createCache(async () => {
|
|
1339
|
+
return await this._interface.listPermissionDefinitions();
|
|
1340
|
+
});
|
|
1341
|
+
}
|
|
1342
|
+
_adminOwnedProjectFromCrud(data, onRefresh) {
|
|
1343
|
+
if (this._tokenStoreInit !== null) {
|
|
1344
|
+
throw new import_errors.StackAssertionError("Owned apps must always have tokenStore === null \u2014 did you not create this project with app._createOwnedApp()?");
|
|
1345
|
+
;
|
|
1346
|
+
}
|
|
1347
|
+
return {
|
|
1348
|
+
...this._adminProjectFromCrud(data, onRefresh),
|
|
1349
|
+
app: this
|
|
1350
|
+
};
|
|
1438
1351
|
}
|
|
1439
|
-
|
|
1352
|
+
_adminProjectFromCrud(data, onRefresh) {
|
|
1353
|
+
if (data.id !== this.projectId) {
|
|
1354
|
+
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})!`);
|
|
1355
|
+
}
|
|
1440
1356
|
const app = this;
|
|
1441
1357
|
return {
|
|
1442
1358
|
id: data.id,
|
|
1359
|
+
displayName: data.display_name,
|
|
1443
1360
|
description: data.description,
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1361
|
+
createdAt: new Date(data.created_at_millis),
|
|
1362
|
+
userCount: data.user_count,
|
|
1363
|
+
isProductionMode: data.is_production_mode,
|
|
1364
|
+
config: {
|
|
1365
|
+
id: data.config.id,
|
|
1366
|
+
credentialEnabled: data.config.credential_enabled,
|
|
1367
|
+
magicLinkEnabled: data.config.magic_link_enabled,
|
|
1368
|
+
allowLocalhost: data.config.allow_localhost,
|
|
1369
|
+
oauthProviders: data.config.oauth_providers.map((p) => p.type === "shared" ? {
|
|
1370
|
+
id: p.id,
|
|
1371
|
+
enabled: p.enabled,
|
|
1372
|
+
type: "shared"
|
|
1373
|
+
} : {
|
|
1374
|
+
id: p.id,
|
|
1375
|
+
enabled: p.enabled,
|
|
1376
|
+
type: "standard",
|
|
1377
|
+
clientId: p.client_id ?? (0, import_errors.throwErr)("Client ID is missing"),
|
|
1378
|
+
clientSecret: p.client_secret ?? (0, import_errors.throwErr)("Client secret is missing")
|
|
1379
|
+
}),
|
|
1380
|
+
emailConfig: data.config.email_config.type === "shared" ? {
|
|
1381
|
+
type: "shared"
|
|
1382
|
+
} : {
|
|
1383
|
+
type: "standard",
|
|
1384
|
+
host: data.config.email_config.host ?? (0, import_errors.throwErr)("Email host is missing"),
|
|
1385
|
+
port: data.config.email_config.port ?? (0, import_errors.throwErr)("Email port is missing"),
|
|
1386
|
+
username: data.config.email_config.username ?? (0, import_errors.throwErr)("Email username is missing"),
|
|
1387
|
+
password: data.config.email_config.password ?? (0, import_errors.throwErr)("Email password is missing"),
|
|
1388
|
+
senderName: data.config.email_config.sender_name ?? (0, import_errors.throwErr)("Email sender name is missing"),
|
|
1389
|
+
senderEmail: data.config.email_config.sender_email ?? (0, import_errors.throwErr)("Email sender email is missing")
|
|
1390
|
+
},
|
|
1391
|
+
domains: data.config.domains.map((d) => ({
|
|
1392
|
+
domain: d.domain,
|
|
1393
|
+
handlerPath: d.handler_path
|
|
1394
|
+
})),
|
|
1395
|
+
createTeamOnSignUp: data.config.create_team_on_sign_up,
|
|
1396
|
+
teamCreatorDefaultPermissions: data.config.team_creator_default_permissions,
|
|
1397
|
+
teamMemberDefaultPermissions: data.config.team_member_default_permissions
|
|
1398
|
+
},
|
|
1399
|
+
async update(update) {
|
|
1400
|
+
await app._interface.updateProject(adminProjectUpdateOptionsToCrud(update));
|
|
1401
|
+
await onRefresh();
|
|
1402
|
+
},
|
|
1403
|
+
async getProductionModeErrors() {
|
|
1404
|
+
return (0, import_production_mode.getProductionModeErrors)(data);
|
|
1405
|
+
},
|
|
1406
|
+
useProductionModeErrors() {
|
|
1407
|
+
return (0, import_production_mode.getProductionModeErrors)(data);
|
|
1408
|
+
}
|
|
1409
|
+
};
|
|
1410
|
+
}
|
|
1411
|
+
_adminEmailTemplateFromCrud(data) {
|
|
1412
|
+
return {
|
|
1413
|
+
type: data.type,
|
|
1414
|
+
subject: data.subject,
|
|
1415
|
+
content: data.content,
|
|
1416
|
+
isDefault: data.is_default
|
|
1417
|
+
};
|
|
1418
|
+
}
|
|
1419
|
+
async getProject() {
|
|
1420
|
+
return this._adminProjectFromCrud(
|
|
1421
|
+
await this._adminProjectCache.getOrWait([], "write-only"),
|
|
1422
|
+
() => this._refreshProject()
|
|
1423
|
+
);
|
|
1424
|
+
}
|
|
1425
|
+
useProject() {
|
|
1426
|
+
const crud = useAsyncCache(this._adminProjectCache, [], "useProjectAdmin()");
|
|
1427
|
+
return (0, import_react2.useMemo)(() => this._adminProjectFromCrud(
|
|
1428
|
+
crud,
|
|
1429
|
+
() => this._refreshProject()
|
|
1430
|
+
), [crud]);
|
|
1431
|
+
}
|
|
1432
|
+
_createApiKeyBaseFromCrud(data) {
|
|
1433
|
+
const app = this;
|
|
1434
|
+
return {
|
|
1435
|
+
id: data.id,
|
|
1436
|
+
description: data.description,
|
|
1437
|
+
expiresAt: new Date(data.expires_at_millis),
|
|
1438
|
+
manuallyRevokedAt: data.manually_revoked_at_millis ? new Date(data.manually_revoked_at_millis) : null,
|
|
1439
|
+
createdAt: new Date(data.created_at_millis),
|
|
1447
1440
|
isValid() {
|
|
1448
1441
|
return this.whyInvalid() === null;
|
|
1449
1442
|
},
|
|
@@ -1453,57 +1446,83 @@ var _StackAdminAppImpl = class extends _StackServerAppImpl {
|
|
|
1453
1446
|
return null;
|
|
1454
1447
|
},
|
|
1455
1448
|
async revoke() {
|
|
1456
|
-
const res = await app._interface.
|
|
1457
|
-
await app.
|
|
1449
|
+
const res = await app._interface.revokeApiKeyById(data.id);
|
|
1450
|
+
await app._refreshApiKeys();
|
|
1458
1451
|
return res;
|
|
1459
1452
|
}
|
|
1460
1453
|
};
|
|
1461
1454
|
}
|
|
1462
|
-
|
|
1455
|
+
_createApiKeyFromCrud(data) {
|
|
1463
1456
|
return {
|
|
1464
|
-
...this.
|
|
1465
|
-
publishableClientKey: data.
|
|
1466
|
-
secretServerKey: data.
|
|
1467
|
-
superSecretAdminKey: data.
|
|
1457
|
+
...this._createApiKeyBaseFromCrud(data),
|
|
1458
|
+
publishableClientKey: data.publishable_client_key ? { lastFour: data.publishable_client_key.last_four } : null,
|
|
1459
|
+
secretServerKey: data.secret_server_key ? { lastFour: data.secret_server_key.last_four } : null,
|
|
1460
|
+
superSecretAdminKey: data.super_secret_admin_key ? { lastFour: data.super_secret_admin_key.last_four } : null
|
|
1468
1461
|
};
|
|
1469
1462
|
}
|
|
1470
|
-
|
|
1463
|
+
_createApiKeyFirstViewFromCrud(data) {
|
|
1471
1464
|
return {
|
|
1472
|
-
...this.
|
|
1473
|
-
publishableClientKey: data.
|
|
1474
|
-
secretServerKey: data.
|
|
1475
|
-
superSecretAdminKey: data.
|
|
1465
|
+
...this._createApiKeyBaseFromCrud(data),
|
|
1466
|
+
publishableClientKey: data.publishable_client_key,
|
|
1467
|
+
secretServerKey: data.secret_server_key,
|
|
1468
|
+
superSecretAdminKey: data.super_secret_admin_key
|
|
1476
1469
|
};
|
|
1477
1470
|
}
|
|
1478
|
-
async
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
this._interface,
|
|
1482
|
-
() => this._refreshProject()
|
|
1483
|
-
);
|
|
1471
|
+
async listApiKeys() {
|
|
1472
|
+
const crud = await this._apiKeysCache.getOrWait([], "write-only");
|
|
1473
|
+
return crud.map((j) => this._createApiKeyFromCrud(j));
|
|
1484
1474
|
}
|
|
1485
|
-
|
|
1486
|
-
const
|
|
1487
|
-
return (0,
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
() => this._refreshProject()
|
|
1491
|
-
), [json]);
|
|
1475
|
+
useApiKeys() {
|
|
1476
|
+
const crud = useAsyncCache(this._apiKeysCache, [], "useApiKeys()");
|
|
1477
|
+
return (0, import_react2.useMemo)(() => {
|
|
1478
|
+
return crud.map((j) => this._createApiKeyFromCrud(j));
|
|
1479
|
+
}, [crud]);
|
|
1492
1480
|
}
|
|
1493
|
-
async
|
|
1494
|
-
const
|
|
1495
|
-
|
|
1481
|
+
async createApiKey(options) {
|
|
1482
|
+
const crud = await this._interface.createApiKey(apiKeyCreateOptionsToCrud(options));
|
|
1483
|
+
await this._refreshApiKeys();
|
|
1484
|
+
return this._createApiKeyFirstViewFromCrud(crud);
|
|
1496
1485
|
}
|
|
1497
|
-
|
|
1498
|
-
const
|
|
1499
|
-
return (0,
|
|
1500
|
-
return
|
|
1501
|
-
}, [
|
|
1486
|
+
useEmailTemplates() {
|
|
1487
|
+
const crud = useAsyncCache(this._adminEmailTemplatesCache, [], "useEmailTemplates()");
|
|
1488
|
+
return (0, import_react2.useMemo)(() => {
|
|
1489
|
+
return crud.map((j) => this._adminEmailTemplateFromCrud(j));
|
|
1490
|
+
}, [crud]);
|
|
1502
1491
|
}
|
|
1503
|
-
async
|
|
1504
|
-
const
|
|
1505
|
-
|
|
1506
|
-
|
|
1492
|
+
async listEmailTemplates() {
|
|
1493
|
+
const crud = await this._adminEmailTemplatesCache.getOrWait([], "write-only");
|
|
1494
|
+
return crud.map((j) => this._adminEmailTemplateFromCrud(j));
|
|
1495
|
+
}
|
|
1496
|
+
async updateEmailTemplate(type, data) {
|
|
1497
|
+
await this._interface.updateEmailTemplate(type, adminEmailTemplateUpdateOptionsToCrud(data));
|
|
1498
|
+
await this._adminEmailTemplatesCache.refresh([]);
|
|
1499
|
+
}
|
|
1500
|
+
async resetEmailTemplate(type) {
|
|
1501
|
+
await this._interface.resetEmailTemplate(type);
|
|
1502
|
+
await this._adminEmailTemplatesCache.refresh([]);
|
|
1503
|
+
}
|
|
1504
|
+
async createTeamPermissionDefinition(data) {
|
|
1505
|
+
const crud = await this._interface.createPermissionDefinition(serverTeamPermissionDefinitionCreateOptionsToCrud(data));
|
|
1506
|
+
await this._adminTeamPermissionDefinitionsCache.refresh([]);
|
|
1507
|
+
return this._serverTeamPermissionDefinitionFromCrud(crud);
|
|
1508
|
+
}
|
|
1509
|
+
async updateTeamPermissionDefinition(permissionId, data) {
|
|
1510
|
+
await this._interface.updatePermissionDefinition(permissionId, data);
|
|
1511
|
+
await this._adminTeamPermissionDefinitionsCache.refresh([]);
|
|
1512
|
+
}
|
|
1513
|
+
async deleteTeamPermissionDefinition(permissionId) {
|
|
1514
|
+
await this._interface.deletePermissionDefinition(permissionId);
|
|
1515
|
+
await this._adminTeamPermissionDefinitionsCache.refresh([]);
|
|
1516
|
+
}
|
|
1517
|
+
async listTeamPermissionDefinitions() {
|
|
1518
|
+
const crud = await this._adminTeamPermissionDefinitionsCache.getOrWait([], "write-only");
|
|
1519
|
+
return crud.map((p) => this._serverTeamPermissionDefinitionFromCrud(p));
|
|
1520
|
+
}
|
|
1521
|
+
useTeamPermissionDefinitions() {
|
|
1522
|
+
const crud = useAsyncCache(this._adminTeamPermissionDefinitionsCache, [], "usePermissions()");
|
|
1523
|
+
return (0, import_react2.useMemo)(() => {
|
|
1524
|
+
return crud.map((p) => this._serverTeamPermissionDefinitionFromCrud(p));
|
|
1525
|
+
}, [crud]);
|
|
1507
1526
|
}
|
|
1508
1527
|
async _refreshProject() {
|
|
1509
1528
|
await Promise.all([
|
|
@@ -1511,18 +1530,126 @@ var _StackAdminAppImpl = class extends _StackServerAppImpl {
|
|
|
1511
1530
|
this._adminProjectCache.refresh([])
|
|
1512
1531
|
]);
|
|
1513
1532
|
}
|
|
1514
|
-
async
|
|
1515
|
-
await this.
|
|
1533
|
+
async _refreshApiKeys() {
|
|
1534
|
+
await this._apiKeysCache.refresh([]);
|
|
1516
1535
|
}
|
|
1517
1536
|
};
|
|
1537
|
+
function userUpdateOptionsToCrud(options) {
|
|
1538
|
+
return {
|
|
1539
|
+
display_name: options.displayName,
|
|
1540
|
+
client_metadata: options.clientMetadata,
|
|
1541
|
+
selected_team_id: options.selectedTeamId
|
|
1542
|
+
};
|
|
1543
|
+
}
|
|
1544
|
+
function serverUserUpdateOptionsToCrud(options) {
|
|
1545
|
+
return {
|
|
1546
|
+
display_name: options.displayName,
|
|
1547
|
+
client_metadata: options.clientMetadata,
|
|
1548
|
+
selected_team_id: options.selectedTeamId,
|
|
1549
|
+
primary_email: options.primaryEmail,
|
|
1550
|
+
primary_email_verified: options.primaryEmailVerified,
|
|
1551
|
+
server_metadata: options.serverMetadata
|
|
1552
|
+
};
|
|
1553
|
+
}
|
|
1554
|
+
function adminProjectUpdateOptionsToCrud(options) {
|
|
1555
|
+
return {
|
|
1556
|
+
display_name: options.displayName,
|
|
1557
|
+
description: options.description,
|
|
1558
|
+
is_production_mode: options.isProductionMode,
|
|
1559
|
+
config: {
|
|
1560
|
+
domains: options.config?.domains?.map((d) => ({
|
|
1561
|
+
domain: d.domain,
|
|
1562
|
+
handler_path: d.handlerPath
|
|
1563
|
+
})),
|
|
1564
|
+
oauth_providers: options.config?.oauthProviders?.map((p) => ({
|
|
1565
|
+
id: p.id,
|
|
1566
|
+
enabled: p.enabled,
|
|
1567
|
+
type: p.type,
|
|
1568
|
+
...p.type === "standard" && {
|
|
1569
|
+
client_id: p.clientId,
|
|
1570
|
+
client_secret: p.clientSecret
|
|
1571
|
+
}
|
|
1572
|
+
})),
|
|
1573
|
+
email_config: options.config?.emailConfig && (options.config.emailConfig.type === "shared" ? {
|
|
1574
|
+
type: "shared"
|
|
1575
|
+
} : {
|
|
1576
|
+
type: "standard",
|
|
1577
|
+
host: options.config.emailConfig.host,
|
|
1578
|
+
port: options.config.emailConfig.port,
|
|
1579
|
+
username: options.config.emailConfig.username,
|
|
1580
|
+
password: options.config.emailConfig.password,
|
|
1581
|
+
sender_name: options.config.emailConfig.senderName,
|
|
1582
|
+
sender_email: options.config.emailConfig.senderEmail
|
|
1583
|
+
}),
|
|
1584
|
+
credential_enabled: options.config?.credentialEnabled,
|
|
1585
|
+
magic_link_enabled: options.config?.magicLinkEnabled,
|
|
1586
|
+
allow_localhost: options.config?.allowLocalhost,
|
|
1587
|
+
create_team_on_sign_up: options.config?.createTeamOnSignUp,
|
|
1588
|
+
team_creator_default_permissions: options.config?.teamCreatorDefaultPermissions,
|
|
1589
|
+
team_member_default_permissions: options.config?.teamMemberDefaultPermissions
|
|
1590
|
+
}
|
|
1591
|
+
};
|
|
1592
|
+
}
|
|
1593
|
+
function adminProjectCreateOptionsToCrud(options) {
|
|
1594
|
+
return {
|
|
1595
|
+
...adminProjectUpdateOptionsToCrud(options),
|
|
1596
|
+
display_name: options.displayName
|
|
1597
|
+
};
|
|
1598
|
+
}
|
|
1599
|
+
function apiKeyCreateOptionsToCrud(options) {
|
|
1600
|
+
return {
|
|
1601
|
+
description: options.description,
|
|
1602
|
+
expires_at_millis: options.expiresAt.getTime(),
|
|
1603
|
+
has_publishable_client_key: options.hasPublishableClientKey,
|
|
1604
|
+
has_secret_server_key: options.hasSecretServerKey,
|
|
1605
|
+
has_super_secret_admin_key: options.hasSuperSecretAdminKey
|
|
1606
|
+
};
|
|
1607
|
+
}
|
|
1608
|
+
function teamCreateOptionsToCrud(options) {
|
|
1609
|
+
return {
|
|
1610
|
+
display_name: options.displayName,
|
|
1611
|
+
profile_image_url: options.profileImageUrl
|
|
1612
|
+
};
|
|
1613
|
+
}
|
|
1614
|
+
function serverTeamCreateOptionsToCrud(options) {
|
|
1615
|
+
return teamCreateOptionsToCrud(options);
|
|
1616
|
+
}
|
|
1617
|
+
function serverTeamUpdateOptionsToCrud(options) {
|
|
1618
|
+
return {
|
|
1619
|
+
display_name: options.displayName,
|
|
1620
|
+
profile_image_url: options.profileImageUrl
|
|
1621
|
+
};
|
|
1622
|
+
}
|
|
1623
|
+
function serverTeamPermissionDefinitionCreateOptionsToCrud(options) {
|
|
1624
|
+
return {
|
|
1625
|
+
id: options.id,
|
|
1626
|
+
description: options.description,
|
|
1627
|
+
contained_permission_ids: options.containedPermissionIds
|
|
1628
|
+
};
|
|
1629
|
+
}
|
|
1630
|
+
function serverTeamPermissionDefinitionUpdateOptionsToCrud(options) {
|
|
1631
|
+
return {
|
|
1632
|
+
id: options.id,
|
|
1633
|
+
description: options.description,
|
|
1634
|
+
contained_permission_ids: options.containedPermissionIds
|
|
1635
|
+
};
|
|
1636
|
+
}
|
|
1518
1637
|
var StackClientApp = _StackClientAppImpl;
|
|
1519
1638
|
var StackServerApp = _StackServerAppImpl;
|
|
1520
1639
|
var StackAdminApp = _StackAdminAppImpl;
|
|
1640
|
+
function adminEmailTemplateUpdateOptionsToCrud(options) {
|
|
1641
|
+
return {
|
|
1642
|
+
subject: options.subject,
|
|
1643
|
+
content: options.content
|
|
1644
|
+
};
|
|
1645
|
+
}
|
|
1521
1646
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1522
1647
|
0 && (module.exports = {
|
|
1523
1648
|
StackAdminApp,
|
|
1524
1649
|
StackClientApp,
|
|
1525
1650
|
StackServerApp,
|
|
1651
|
+
serverTeamPermissionDefinitionCreateOptionsToCrud,
|
|
1652
|
+
serverTeamPermissionDefinitionUpdateOptionsToCrud,
|
|
1526
1653
|
stackAppInternalsSymbol
|
|
1527
1654
|
});
|
|
1528
1655
|
//# sourceMappingURL=stack-app.js.map
|