mirror of
https://github.com/eigent-ai/eigent.git
synced 2026-04-29 20:20:16 +00:00
Initial commit of eigent-main
This commit is contained in:
commit
723df5a03e
1144 changed files with 103478 additions and 0 deletions
331
package/@stackframe/react/dist/esm/lib/stack-app/apps/implementations/admin-app-impl.js
vendored
Normal file
331
package/@stackframe/react/dist/esm/lib/stack-app/apps/implementations/admin-app-impl.js
vendored
Normal file
|
|
@ -0,0 +1,331 @@
|
|||
// src/lib/stack-app/apps/implementations/admin-app-impl.ts
|
||||
import { StackAdminInterface } from "@stackframe/stack-shared";
|
||||
import { getProductionModeErrors } from "@stackframe/stack-shared/dist/helpers/production-mode";
|
||||
import { StackAssertionError, throwErr } from "@stackframe/stack-shared/dist/utils/errors";
|
||||
import { pick } from "@stackframe/stack-shared/dist/utils/objects";
|
||||
import { Result } from "@stackframe/stack-shared/dist/utils/results";
|
||||
import { useMemo } from "react";
|
||||
import { stackAppInternalsSymbol } from "../../common";
|
||||
import { adminEmailTemplateUpdateOptionsToCrud } from "../../email-templates";
|
||||
import { internalApiKeyCreateOptionsToCrud } from "../../internal-api-keys";
|
||||
import { adminProjectPermissionDefinitionCreateOptionsToCrud, adminProjectPermissionDefinitionUpdateOptionsToCrud, adminTeamPermissionDefinitionCreateOptionsToCrud, adminTeamPermissionDefinitionUpdateOptionsToCrud } from "../../permissions";
|
||||
import { adminProjectUpdateOptionsToCrud } from "../../projects";
|
||||
import { clientVersion, createCache, getBaseUrl, getDefaultProjectId, getDefaultPublishableClientKey, getDefaultSecretServerKey, getDefaultSuperSecretAdminKey } from "./common";
|
||||
import { _StackServerAppImplIncomplete } from "./server-app-impl";
|
||||
import { useAsyncCache } from "./common";
|
||||
var _StackAdminAppImplIncomplete = class extends _StackServerAppImplIncomplete {
|
||||
constructor(options) {
|
||||
super({
|
||||
interface: new StackAdminInterface({
|
||||
getBaseUrl: () => getBaseUrl(options.baseUrl),
|
||||
projectId: options.projectId ?? getDefaultProjectId(),
|
||||
extraRequestHeaders: options.extraRequestHeaders ?? {},
|
||||
clientVersion,
|
||||
..."projectOwnerSession" in options ? {
|
||||
projectOwnerSession: options.projectOwnerSession
|
||||
} : {
|
||||
publishableClientKey: options.publishableClientKey ?? getDefaultPublishableClientKey(),
|
||||
secretServerKey: options.secretServerKey ?? getDefaultSecretServerKey(),
|
||||
superSecretAdminKey: options.superSecretAdminKey ?? getDefaultSuperSecretAdminKey()
|
||||
}
|
||||
}),
|
||||
baseUrl: options.baseUrl,
|
||||
extraRequestHeaders: options.extraRequestHeaders,
|
||||
projectId: options.projectId,
|
||||
tokenStore: options.tokenStore,
|
||||
urls: options.urls,
|
||||
oauthScopesOnSignIn: options.oauthScopesOnSignIn,
|
||||
redirectMethod: options.redirectMethod
|
||||
});
|
||||
this._adminProjectCache = createCache(async () => {
|
||||
return await this._interface.getProject();
|
||||
});
|
||||
this._internalApiKeysCache = createCache(async () => {
|
||||
const res = await this._interface.listInternalApiKeys();
|
||||
return res;
|
||||
});
|
||||
this._adminEmailTemplatesCache = createCache(async () => {
|
||||
return await this._interface.listEmailTemplates();
|
||||
});
|
||||
this._adminTeamPermissionDefinitionsCache = createCache(async () => {
|
||||
return await this._interface.listTeamPermissionDefinitions();
|
||||
});
|
||||
this._adminProjectPermissionDefinitionsCache = createCache(async () => {
|
||||
return await this._interface.listProjectPermissionDefinitions();
|
||||
});
|
||||
this._svixTokenCache = createCache(async () => {
|
||||
return await this._interface.getSvixToken();
|
||||
});
|
||||
this._metricsCache = createCache(async () => {
|
||||
return await this._interface.getMetrics();
|
||||
});
|
||||
}
|
||||
_adminOwnedProjectFromCrud(data, onRefresh) {
|
||||
if (this._tokenStoreInit !== null) {
|
||||
throw new StackAssertionError("Owned apps must always have tokenStore === null \u2014 did you not create this project with app._createOwnedApp()?");
|
||||
}
|
||||
return {
|
||||
...this._adminProjectFromCrud(data, onRefresh),
|
||||
app: this
|
||||
};
|
||||
}
|
||||
_adminProjectFromCrud(data, onRefresh) {
|
||||
if (data.id !== this.projectId) {
|
||||
throw new StackAssertionError(`The project ID of the provided project JSON (${data.id}) does not match the project ID of the app (${this.projectId})!`);
|
||||
}
|
||||
const app = this;
|
||||
return {
|
||||
id: data.id,
|
||||
displayName: data.display_name,
|
||||
description: data.description,
|
||||
createdAt: new Date(data.created_at_millis),
|
||||
userCount: data.user_count,
|
||||
isProductionMode: data.is_production_mode,
|
||||
config: {
|
||||
signUpEnabled: data.config.sign_up_enabled,
|
||||
credentialEnabled: data.config.credential_enabled,
|
||||
magicLinkEnabled: data.config.magic_link_enabled,
|
||||
passkeyEnabled: data.config.passkey_enabled,
|
||||
clientTeamCreationEnabled: data.config.client_team_creation_enabled,
|
||||
clientUserDeletionEnabled: data.config.client_user_deletion_enabled,
|
||||
allowLocalhost: data.config.allow_localhost,
|
||||
oauthAccountMergeStrategy: data.config.oauth_account_merge_strategy,
|
||||
allowUserApiKeys: data.config.allow_user_api_keys,
|
||||
allowTeamApiKeys: data.config.allow_team_api_keys,
|
||||
oauthProviders: data.config.oauth_providers.map((p) => p.type === "shared" ? {
|
||||
id: p.id,
|
||||
type: "shared"
|
||||
} : {
|
||||
id: p.id,
|
||||
type: "standard",
|
||||
clientId: p.client_id ?? throwErr("Client ID is missing"),
|
||||
clientSecret: p.client_secret ?? throwErr("Client secret is missing"),
|
||||
facebookConfigId: p.facebook_config_id,
|
||||
microsoftTenantId: p.microsoft_tenant_id
|
||||
}),
|
||||
emailConfig: data.config.email_config.type === "shared" ? {
|
||||
type: "shared"
|
||||
} : {
|
||||
type: "standard",
|
||||
host: data.config.email_config.host ?? throwErr("Email host is missing"),
|
||||
port: data.config.email_config.port ?? throwErr("Email port is missing"),
|
||||
username: data.config.email_config.username ?? throwErr("Email username is missing"),
|
||||
password: data.config.email_config.password ?? throwErr("Email password is missing"),
|
||||
senderName: data.config.email_config.sender_name ?? throwErr("Email sender name is missing"),
|
||||
senderEmail: data.config.email_config.sender_email ?? throwErr("Email sender email is missing")
|
||||
},
|
||||
domains: data.config.domains.map((d) => ({
|
||||
domain: d.domain,
|
||||
handlerPath: d.handler_path
|
||||
})),
|
||||
createTeamOnSignUp: data.config.create_team_on_sign_up,
|
||||
teamCreatorDefaultPermissions: data.config.team_creator_default_permissions,
|
||||
teamMemberDefaultPermissions: data.config.team_member_default_permissions,
|
||||
userDefaultPermissions: data.config.user_default_permissions
|
||||
},
|
||||
async update(update) {
|
||||
await app._interface.updateProject(adminProjectUpdateOptionsToCrud(update));
|
||||
await onRefresh();
|
||||
},
|
||||
async delete() {
|
||||
await app._interface.deleteProject();
|
||||
},
|
||||
async getProductionModeErrors() {
|
||||
return getProductionModeErrors(data);
|
||||
},
|
||||
useProductionModeErrors() {
|
||||
return getProductionModeErrors(data);
|
||||
}
|
||||
};
|
||||
}
|
||||
_adminEmailTemplateFromCrud(data) {
|
||||
return {
|
||||
type: data.type,
|
||||
subject: data.subject,
|
||||
content: data.content,
|
||||
isDefault: data.is_default
|
||||
};
|
||||
}
|
||||
async getProject() {
|
||||
return this._adminProjectFromCrud(
|
||||
Result.orThrow(await this._adminProjectCache.getOrWait([], "write-only")),
|
||||
() => this._refreshProject()
|
||||
);
|
||||
}
|
||||
useProject() {
|
||||
const crud = useAsyncCache(this._adminProjectCache, [], "useProjectAdmin()");
|
||||
return useMemo(() => this._adminProjectFromCrud(
|
||||
crud,
|
||||
() => this._refreshProject()
|
||||
), [crud]);
|
||||
}
|
||||
_createInternalApiKeyBaseFromCrud(data) {
|
||||
const app = this;
|
||||
return {
|
||||
id: data.id,
|
||||
description: data.description,
|
||||
expiresAt: new Date(data.expires_at_millis),
|
||||
manuallyRevokedAt: data.manually_revoked_at_millis ? new Date(data.manually_revoked_at_millis) : null,
|
||||
createdAt: new Date(data.created_at_millis),
|
||||
isValid() {
|
||||
return this.whyInvalid() === null;
|
||||
},
|
||||
whyInvalid() {
|
||||
if (this.expiresAt.getTime() < Date.now()) return "expired";
|
||||
if (this.manuallyRevokedAt) return "manually-revoked";
|
||||
return null;
|
||||
},
|
||||
async revoke() {
|
||||
const res = await app._interface.revokeInternalApiKeyById(data.id);
|
||||
await app._refreshInternalApiKeys();
|
||||
return res;
|
||||
}
|
||||
};
|
||||
}
|
||||
_createInternalApiKeyFromCrud(data) {
|
||||
return {
|
||||
...this._createInternalApiKeyBaseFromCrud(data),
|
||||
publishableClientKey: data.publishable_client_key ? { lastFour: data.publishable_client_key.last_four } : null,
|
||||
secretServerKey: data.secret_server_key ? { lastFour: data.secret_server_key.last_four } : null,
|
||||
superSecretAdminKey: data.super_secret_admin_key ? { lastFour: data.super_secret_admin_key.last_four } : null
|
||||
};
|
||||
}
|
||||
_createInternalApiKeyFirstViewFromCrud(data) {
|
||||
return {
|
||||
...this._createInternalApiKeyBaseFromCrud(data),
|
||||
publishableClientKey: data.publishable_client_key,
|
||||
secretServerKey: data.secret_server_key,
|
||||
superSecretAdminKey: data.super_secret_admin_key
|
||||
};
|
||||
}
|
||||
async listInternalApiKeys() {
|
||||
const crud = Result.orThrow(await this._internalApiKeysCache.getOrWait([], "write-only"));
|
||||
return crud.map((j) => this._createInternalApiKeyFromCrud(j));
|
||||
}
|
||||
useInternalApiKeys() {
|
||||
const crud = useAsyncCache(this._internalApiKeysCache, [], "useInternalApiKeys()");
|
||||
return useMemo(() => {
|
||||
return crud.map((j) => this._createInternalApiKeyFromCrud(j));
|
||||
}, [crud]);
|
||||
}
|
||||
async createInternalApiKey(options) {
|
||||
const crud = await this._interface.createInternalApiKey(internalApiKeyCreateOptionsToCrud(options));
|
||||
await this._refreshInternalApiKeys();
|
||||
return this._createInternalApiKeyFirstViewFromCrud(crud);
|
||||
}
|
||||
useEmailTemplates() {
|
||||
const crud = useAsyncCache(this._adminEmailTemplatesCache, [], "useEmailTemplates()");
|
||||
return useMemo(() => {
|
||||
return crud.map((j) => this._adminEmailTemplateFromCrud(j));
|
||||
}, [crud]);
|
||||
}
|
||||
async listEmailTemplates() {
|
||||
const crud = Result.orThrow(await this._adminEmailTemplatesCache.getOrWait([], "write-only"));
|
||||
return crud.map((j) => this._adminEmailTemplateFromCrud(j));
|
||||
}
|
||||
async updateEmailTemplate(type, data) {
|
||||
await this._interface.updateEmailTemplate(type, adminEmailTemplateUpdateOptionsToCrud(data));
|
||||
await this._adminEmailTemplatesCache.refresh([]);
|
||||
}
|
||||
async resetEmailTemplate(type) {
|
||||
await this._interface.resetEmailTemplate(type);
|
||||
await this._adminEmailTemplatesCache.refresh([]);
|
||||
}
|
||||
async createTeamPermissionDefinition(data) {
|
||||
const crud = await this._interface.createTeamPermissionDefinition(adminTeamPermissionDefinitionCreateOptionsToCrud(data));
|
||||
await this._adminTeamPermissionDefinitionsCache.refresh([]);
|
||||
return this._serverTeamPermissionDefinitionFromCrud(crud);
|
||||
}
|
||||
async updateTeamPermissionDefinition(permissionId, data) {
|
||||
await this._interface.updateTeamPermissionDefinition(permissionId, adminTeamPermissionDefinitionUpdateOptionsToCrud(data));
|
||||
await this._adminTeamPermissionDefinitionsCache.refresh([]);
|
||||
}
|
||||
async deleteTeamPermissionDefinition(permissionId) {
|
||||
await this._interface.deleteTeamPermissionDefinition(permissionId);
|
||||
await this._adminTeamPermissionDefinitionsCache.refresh([]);
|
||||
}
|
||||
async listTeamPermissionDefinitions() {
|
||||
const crud = Result.orThrow(await this._adminTeamPermissionDefinitionsCache.getOrWait([], "write-only"));
|
||||
return crud.map((p) => this._serverTeamPermissionDefinitionFromCrud(p));
|
||||
}
|
||||
useTeamPermissionDefinitions() {
|
||||
const crud = useAsyncCache(this._adminTeamPermissionDefinitionsCache, [], "usePermissions()");
|
||||
return useMemo(() => {
|
||||
return crud.map((p) => this._serverTeamPermissionDefinitionFromCrud(p));
|
||||
}, [crud]);
|
||||
}
|
||||
async createProjectPermissionDefinition(data) {
|
||||
const crud = await this._interface.createProjectPermissionDefinition(adminProjectPermissionDefinitionCreateOptionsToCrud(data));
|
||||
await this._adminProjectPermissionDefinitionsCache.refresh([]);
|
||||
return this._serverProjectPermissionDefinitionFromCrud(crud);
|
||||
}
|
||||
async updateProjectPermissionDefinition(permissionId, data) {
|
||||
await this._interface.updateProjectPermissionDefinition(permissionId, adminProjectPermissionDefinitionUpdateOptionsToCrud(data));
|
||||
await this._adminProjectPermissionDefinitionsCache.refresh([]);
|
||||
}
|
||||
async deleteProjectPermissionDefinition(permissionId) {
|
||||
await this._interface.deleteProjectPermissionDefinition(permissionId);
|
||||
await this._adminProjectPermissionDefinitionsCache.refresh([]);
|
||||
}
|
||||
async listProjectPermissionDefinitions() {
|
||||
const crud = Result.orThrow(await this._adminProjectPermissionDefinitionsCache.getOrWait([], "write-only"));
|
||||
return crud.map((p) => this._serverProjectPermissionDefinitionFromCrud(p));
|
||||
}
|
||||
useProjectPermissionDefinitions() {
|
||||
const crud = useAsyncCache(this._adminProjectPermissionDefinitionsCache, [], "useProjectPermissions()");
|
||||
return useMemo(() => {
|
||||
return crud.map((p) => this._serverProjectPermissionDefinitionFromCrud(p));
|
||||
}, [crud]);
|
||||
}
|
||||
useSvixToken() {
|
||||
const crud = useAsyncCache(this._svixTokenCache, [], "useSvixToken()");
|
||||
return crud.token;
|
||||
}
|
||||
async _refreshProject() {
|
||||
await Promise.all([
|
||||
super._refreshProject(),
|
||||
this._adminProjectCache.refresh([])
|
||||
]);
|
||||
}
|
||||
async _refreshInternalApiKeys() {
|
||||
await this._internalApiKeysCache.refresh([]);
|
||||
}
|
||||
get [stackAppInternalsSymbol]() {
|
||||
return {
|
||||
...super[stackAppInternalsSymbol],
|
||||
useMetrics: () => {
|
||||
return useAsyncCache(this._metricsCache, [], "useMetrics()");
|
||||
}
|
||||
};
|
||||
}
|
||||
async sendTestEmail(options) {
|
||||
const response = await this._interface.sendTestEmail({
|
||||
recipient_email: options.recipientEmail,
|
||||
email_config: {
|
||||
...pick(options.emailConfig, ["host", "port", "username", "password"]),
|
||||
sender_email: options.emailConfig.senderEmail,
|
||||
sender_name: options.emailConfig.senderName
|
||||
}
|
||||
});
|
||||
if (response.success) {
|
||||
return Result.ok(void 0);
|
||||
} else {
|
||||
return Result.error({ errorMessage: response.error_message ?? throwErr("Email test error not specified") });
|
||||
}
|
||||
}
|
||||
async listSentEmails() {
|
||||
const response = await this._interface.listSentEmails();
|
||||
return response.items.map((email) => ({
|
||||
id: email.id,
|
||||
to: email.to ?? [],
|
||||
subject: email.subject,
|
||||
recipient: email.to?.[0] ?? "",
|
||||
sentAt: new Date(email.sent_at_millis),
|
||||
error: email.error
|
||||
}));
|
||||
}
|
||||
};
|
||||
export {
|
||||
_StackAdminAppImplIncomplete
|
||||
};
|
||||
//# sourceMappingURL=admin-app-impl.js.map
|
||||
1
package/@stackframe/react/dist/esm/lib/stack-app/apps/implementations/admin-app-impl.js.map
vendored
Normal file
1
package/@stackframe/react/dist/esm/lib/stack-app/apps/implementations/admin-app-impl.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
1585
package/@stackframe/react/dist/esm/lib/stack-app/apps/implementations/client-app-impl.js
vendored
Normal file
1585
package/@stackframe/react/dist/esm/lib/stack-app/apps/implementations/client-app-impl.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
1
package/@stackframe/react/dist/esm/lib/stack-app/apps/implementations/client-app-impl.js.map
vendored
Normal file
1
package/@stackframe/react/dist/esm/lib/stack-app/apps/implementations/client-app-impl.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
147
package/@stackframe/react/dist/esm/lib/stack-app/apps/implementations/common.js
vendored
Normal file
147
package/@stackframe/react/dist/esm/lib/stack-app/apps/implementations/common.js
vendored
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
// src/lib/stack-app/apps/implementations/common.ts
|
||||
import { AsyncCache } from "@stackframe/stack-shared/dist/utils/caches";
|
||||
import { isBrowserLike } from "@stackframe/stack-shared/dist/utils/env";
|
||||
import { StackAssertionError, concatStacktraces, throwErr } from "@stackframe/stack-shared/dist/utils/errors";
|
||||
import { filterUndefined } from "@stackframe/stack-shared/dist/utils/objects";
|
||||
import { suspendIfSsr } from "@stackframe/stack-shared/dist/utils/react";
|
||||
import { Result } from "@stackframe/stack-shared/dist/utils/results";
|
||||
import { Store } from "@stackframe/stack-shared/dist/utils/stores";
|
||||
import React, { useCallback } from "react";
|
||||
var process = globalThis.process ?? { env: {} };
|
||||
var clientVersion = "js @stackframe/react@2.8.12";
|
||||
if (clientVersion.startsWith("STACK_COMPILE_TIME")) {
|
||||
throw new StackAssertionError("Client version was not replaced. Something went wrong during build!");
|
||||
}
|
||||
var createCache = (fetcher) => {
|
||||
return new AsyncCache(
|
||||
async (dependencies) => await Result.fromThrowingAsync(async () => await fetcher(dependencies)),
|
||||
{}
|
||||
);
|
||||
};
|
||||
var createCacheBySession = (fetcher) => {
|
||||
return new AsyncCache(
|
||||
async ([session, ...extraDependencies]) => await Result.fromThrowingAsync(async () => await fetcher(session, extraDependencies)),
|
||||
{
|
||||
onSubscribe: ([session], refresh) => {
|
||||
const handler = session.onInvalidate(() => refresh());
|
||||
return () => handler.unsubscribe();
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
function getUrls(partial) {
|
||||
const handler = partial.handler ?? "/handler";
|
||||
const home = partial.home ?? "/";
|
||||
const afterSignIn = partial.afterSignIn ?? home;
|
||||
return {
|
||||
handler,
|
||||
signIn: `${handler}/sign-in`,
|
||||
afterSignIn: home,
|
||||
signUp: `${handler}/sign-up`,
|
||||
afterSignUp: afterSignIn,
|
||||
signOut: `${handler}/sign-out`,
|
||||
afterSignOut: home,
|
||||
emailVerification: `${handler}/email-verification`,
|
||||
passwordReset: `${handler}/password-reset`,
|
||||
forgotPassword: `${handler}/forgot-password`,
|
||||
oauthCallback: `${handler}/oauth-callback`,
|
||||
magicLinkCallback: `${handler}/magic-link-callback`,
|
||||
home,
|
||||
accountSettings: `${handler}/account-settings`,
|
||||
error: `${handler}/error`,
|
||||
teamInvitation: `${handler}/team-invitation`,
|
||||
...filterUndefined(partial)
|
||||
};
|
||||
}
|
||||
function getDefaultProjectId() {
|
||||
return process.env.NEXT_PUBLIC_STACK_PROJECT_ID || throwErr(new Error("Welcome to Stack Auth! It seems that you haven't provided a project ID. Please create a project on the Stack dashboard at https://app.stack-auth.com and put it in the NEXT_PUBLIC_STACK_PROJECT_ID environment variable."));
|
||||
}
|
||||
function getDefaultPublishableClientKey() {
|
||||
return process.env.NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY || throwErr(new Error("Welcome to Stack Auth! It seems that you haven't provided a publishable client key. Please create an API key for your project on the Stack dashboard at https://app.stack-auth.com and copy your publishable client key into the NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY environment variable."));
|
||||
}
|
||||
function getDefaultSecretServerKey() {
|
||||
return process.env.STACK_SECRET_SERVER_KEY || throwErr(new Error("No secret server key provided. Please copy your key from the Stack dashboard and put it in the STACK_SECRET_SERVER_KEY environment variable."));
|
||||
}
|
||||
function getDefaultSuperSecretAdminKey() {
|
||||
return process.env.STACK_SUPER_SECRET_ADMIN_KEY || throwErr(new Error("No super secret admin key provided. Please copy your key from the Stack dashboard and put it in the STACK_SUPER_SECRET_ADMIN_KEY environment variable."));
|
||||
}
|
||||
function getDefaultExtraRequestHeaders() {
|
||||
return JSON.parse(process.env.NEXT_PUBLIC_STACK_EXTRA_REQUEST_HEADERS || "{}");
|
||||
}
|
||||
function getBaseUrl(userSpecifiedBaseUrl) {
|
||||
let url;
|
||||
if (userSpecifiedBaseUrl) {
|
||||
if (typeof userSpecifiedBaseUrl === "string") {
|
||||
url = userSpecifiedBaseUrl;
|
||||
} else {
|
||||
if (isBrowserLike()) {
|
||||
url = userSpecifiedBaseUrl.browser;
|
||||
} else {
|
||||
url = userSpecifiedBaseUrl.server;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (isBrowserLike()) {
|
||||
url = process.env.NEXT_PUBLIC_BROWSER_STACK_API_URL;
|
||||
} else {
|
||||
url = process.env.NEXT_PUBLIC_SERVER_STACK_API_URL;
|
||||
}
|
||||
url = url || process.env.NEXT_PUBLIC_STACK_API_URL || process.env.NEXT_PUBLIC_STACK_URL || defaultBaseUrl;
|
||||
}
|
||||
return url.endsWith("/") ? url.slice(0, -1) : url;
|
||||
}
|
||||
var defaultBaseUrl = "https://api.stack-auth.com";
|
||||
function createEmptyTokenStore() {
|
||||
return new Store({
|
||||
refreshToken: null,
|
||||
accessToken: null
|
||||
});
|
||||
}
|
||||
var cachePromiseByHookId = /* @__PURE__ */ new Map();
|
||||
function useAsyncCache(cache, dependencies, caller) {
|
||||
suspendIfSsr(caller);
|
||||
const id = React.useId();
|
||||
const subscribe = useCallback((cb) => {
|
||||
const { unsubscribe } = cache.onStateChange(dependencies, () => {
|
||||
cachePromiseByHookId.delete(id);
|
||||
cb();
|
||||
});
|
||||
return unsubscribe;
|
||||
}, [cache, ...dependencies]);
|
||||
const getSnapshot = useCallback(() => {
|
||||
if (!cachePromiseByHookId.has(id)) {
|
||||
cachePromiseByHookId.set(id, cache.getOrWait(dependencies, "read-write"));
|
||||
}
|
||||
return cachePromiseByHookId.get(id);
|
||||
}, [cache, ...dependencies]);
|
||||
const promise = React.useSyncExternalStore(
|
||||
subscribe,
|
||||
getSnapshot,
|
||||
() => throwErr(new Error("getServerSnapshot should never be called in useAsyncCache because we restrict to CSR earlier"))
|
||||
);
|
||||
const result = React.use(promise);
|
||||
if (result.status === "error") {
|
||||
const error = result.error;
|
||||
if (error instanceof Error && !error.__stackHasConcatenatedStacktraces) {
|
||||
concatStacktraces(error, new Error());
|
||||
error.__stackHasConcatenatedStacktraces = true;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
return result.data;
|
||||
}
|
||||
export {
|
||||
clientVersion,
|
||||
createCache,
|
||||
createCacheBySession,
|
||||
createEmptyTokenStore,
|
||||
getBaseUrl,
|
||||
getDefaultExtraRequestHeaders,
|
||||
getDefaultProjectId,
|
||||
getDefaultPublishableClientKey,
|
||||
getDefaultSecretServerKey,
|
||||
getDefaultSuperSecretAdminKey,
|
||||
getUrls,
|
||||
useAsyncCache
|
||||
};
|
||||
//# sourceMappingURL=common.js.map
|
||||
1
package/@stackframe/react/dist/esm/lib/stack-app/apps/implementations/common.js.map
vendored
Normal file
1
package/@stackframe/react/dist/esm/lib/stack-app/apps/implementations/common.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
24
package/@stackframe/react/dist/esm/lib/stack-app/apps/implementations/index.js
vendored
Normal file
24
package/@stackframe/react/dist/esm/lib/stack-app/apps/implementations/index.js
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
// src/lib/stack-app/apps/implementations/index.ts
|
||||
import { scrambleDuringCompileTime } from "@stackframe/stack-shared/dist/utils/compile-time";
|
||||
import { _StackAdminAppImplIncomplete } from "./admin-app-impl";
|
||||
import { _StackClientAppImplIncomplete } from "./client-app-impl";
|
||||
import { _StackServerAppImplIncomplete } from "./server-app-impl";
|
||||
function complete() {
|
||||
_StackClientAppImplIncomplete.LazyStackAdminAppImpl.value = _StackAdminAppImplIncomplete;
|
||||
return {
|
||||
_StackAdminAppImpl: scrambleDuringCompileTime(_StackAdminAppImplIncomplete),
|
||||
_StackClientAppImpl: scrambleDuringCompileTime(_StackClientAppImplIncomplete),
|
||||
_StackServerAppImpl: scrambleDuringCompileTime(_StackServerAppImplIncomplete)
|
||||
};
|
||||
}
|
||||
var {
|
||||
_StackAdminAppImpl,
|
||||
_StackClientAppImpl,
|
||||
_StackServerAppImpl
|
||||
} = complete();
|
||||
export {
|
||||
_StackAdminAppImpl,
|
||||
_StackClientAppImpl,
|
||||
_StackServerAppImpl
|
||||
};
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
package/@stackframe/react/dist/esm/lib/stack-app/apps/implementations/index.js.map
vendored
Normal file
1
package/@stackframe/react/dist/esm/lib/stack-app/apps/implementations/index.js.map
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"sources":["../../../../../../src/lib/stack-app/apps/implementations/index.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\n\nimport { scrambleDuringCompileTime } from \"@stackframe/stack-shared/dist/utils/compile-time\";\nimport { _StackAdminAppImplIncomplete } from \"./admin-app-impl\";\nimport { _StackClientAppImplIncomplete } from \"./client-app-impl\";\nimport { _StackServerAppImplIncomplete } from \"./server-app-impl\";\n\n\n/**\n * Prevents a circular dependency between the client and admin apps. For more information, see the documentation comment\n * of `_StackClientAppImplIncomplete.LazyStackAdminAppImpl`.\n *\n * Note: This is an explicitly defined function that returns the new values (and not a barrel file with top-level side\n * effects) because we have `sideEffects: false` in the package.json, and so it would be tree-shaken away if we just\n * exported the values directly.\n */\nfunction complete() {\n _StackClientAppImplIncomplete.LazyStackAdminAppImpl.value = _StackAdminAppImplIncomplete;\n\n return {\n _StackAdminAppImpl: scrambleDuringCompileTime(_StackAdminAppImplIncomplete),\n _StackClientAppImpl: scrambleDuringCompileTime(_StackClientAppImplIncomplete),\n _StackServerAppImpl: scrambleDuringCompileTime(_StackServerAppImplIncomplete),\n };\n}\n\nexport const {\n _StackAdminAppImpl,\n _StackClientAppImpl,\n _StackServerAppImpl\n} = complete();\n\n"],"mappings":";AAKA,SAAS,iCAAiC;AAC1C,SAAS,oCAAoC;AAC7C,SAAS,qCAAqC;AAC9C,SAAS,qCAAqC;AAW9C,SAAS,WAAW;AAClB,gCAA8B,sBAAsB,QAAQ;AAE5D,SAAO;AAAA,IACL,oBAAoB,0BAA0B,4BAA4B;AAAA,IAC1E,qBAAqB,0BAA0B,6BAA6B;AAAA,IAC5E,qBAAqB,0BAA0B,6BAA6B;AAAA,EAC9E;AACF;AAEO,IAAM;AAAA,EACX;AAAA,EACA;AAAA,EACA;AACF,IAAI,SAAS;","names":[]}
|
||||
770
package/@stackframe/react/dist/esm/lib/stack-app/apps/implementations/server-app-impl.js
vendored
Normal file
770
package/@stackframe/react/dist/esm/lib/stack-app/apps/implementations/server-app-impl.js
vendored
Normal file
|
|
@ -0,0 +1,770 @@
|
|||
// src/lib/stack-app/apps/implementations/server-app-impl.ts
|
||||
import { KnownErrors, StackServerInterface } from "@stackframe/stack-shared";
|
||||
import { StackAssertionError, throwErr } from "@stackframe/stack-shared/dist/utils/errors";
|
||||
import { runAsynchronously } from "@stackframe/stack-shared/dist/utils/promises";
|
||||
import { suspend } from "@stackframe/stack-shared/dist/utils/react";
|
||||
import { Result } from "@stackframe/stack-shared/dist/utils/results";
|
||||
import { useMemo } from "react";
|
||||
import { constructRedirectUrl } from "../../../../utils/url";
|
||||
import { apiKeyCreationOptionsToCrud, apiKeyUpdateOptionsToCrud } from "../../api-keys";
|
||||
import { serverContactChannelCreateOptionsToCrud, serverContactChannelUpdateOptionsToCrud } from "../../contact-channels";
|
||||
import { serverTeamCreateOptionsToCrud, serverTeamUpdateOptionsToCrud } from "../../teams";
|
||||
import { serverUserCreateOptionsToCrud, serverUserUpdateOptionsToCrud } from "../../users";
|
||||
import { _StackClientAppImplIncomplete } from "./client-app-impl";
|
||||
import { clientVersion, createCache, createCacheBySession, getBaseUrl, getDefaultProjectId, getDefaultPublishableClientKey, getDefaultSecretServerKey } from "./common";
|
||||
import { useAsyncCache } from "./common";
|
||||
var _StackServerAppImplIncomplete = class extends _StackClientAppImplIncomplete {
|
||||
constructor(options) {
|
||||
super("interface" in options ? {
|
||||
interface: options.interface,
|
||||
tokenStore: options.tokenStore,
|
||||
urls: options.urls,
|
||||
oauthScopesOnSignIn: options.oauthScopesOnSignIn
|
||||
} : {
|
||||
interface: new StackServerInterface({
|
||||
getBaseUrl: () => getBaseUrl(options.baseUrl),
|
||||
projectId: options.projectId ?? getDefaultProjectId(),
|
||||
extraRequestHeaders: options.extraRequestHeaders ?? {},
|
||||
clientVersion,
|
||||
publishableClientKey: options.publishableClientKey ?? getDefaultPublishableClientKey(),
|
||||
secretServerKey: options.secretServerKey ?? getDefaultSecretServerKey()
|
||||
}),
|
||||
baseUrl: options.baseUrl,
|
||||
extraRequestHeaders: options.extraRequestHeaders,
|
||||
projectId: options.projectId,
|
||||
publishableClientKey: options.publishableClientKey,
|
||||
tokenStore: options.tokenStore,
|
||||
urls: options.urls,
|
||||
oauthScopesOnSignIn: options.oauthScopesOnSignIn,
|
||||
redirectMethod: options.redirectMethod
|
||||
});
|
||||
// TODO override the client user cache to use the server user cache, so we save some requests
|
||||
this._currentServerUserCache = createCacheBySession(async (session) => {
|
||||
if (session.isKnownToBeInvalid()) {
|
||||
return null;
|
||||
}
|
||||
return await this._interface.getServerUserByToken(session);
|
||||
});
|
||||
this._serverUsersCache = createCache(async ([cursor, limit, orderBy, desc, query]) => {
|
||||
return await this._interface.listServerUsers({ cursor, limit, orderBy, desc, query });
|
||||
});
|
||||
this._serverUserCache = createCache(async ([userId]) => {
|
||||
const user = await this._interface.getServerUserById(userId);
|
||||
return Result.or(user, null);
|
||||
});
|
||||
this._serverTeamsCache = createCache(async ([userId]) => {
|
||||
return await this._interface.listServerTeams({ userId });
|
||||
});
|
||||
this._serverTeamUserPermissionsCache = createCache(async ([teamId, userId, recursive]) => {
|
||||
return await this._interface.listServerTeamPermissions({ teamId, userId, recursive }, null);
|
||||
});
|
||||
this._serverUserProjectPermissionsCache = createCache(async ([userId, recursive]) => {
|
||||
return await this._interface.listServerProjectPermissions({ userId, recursive }, null);
|
||||
});
|
||||
this._serverUserOAuthConnectionAccessTokensCache = createCache(
|
||||
async ([userId, providerId, scope]) => {
|
||||
try {
|
||||
const result = await this._interface.createServerProviderAccessToken(userId, providerId, scope || "");
|
||||
return { accessToken: result.access_token };
|
||||
} catch (err) {
|
||||
if (!(KnownErrors.OAuthConnectionDoesNotHaveRequiredScope.isInstance(err) || KnownErrors.OAuthConnectionNotConnectedToUser.isInstance(err))) {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
);
|
||||
this._serverUserOAuthConnectionCache = createCache(
|
||||
async ([userId, providerId, scope, redirect]) => {
|
||||
return await this._getUserOAuthConnectionCacheFn({
|
||||
getUser: async () => Result.orThrow(await this._serverUserCache.getOrWait([userId], "write-only")),
|
||||
getOrWaitOAuthToken: async () => Result.orThrow(await this._serverUserOAuthConnectionAccessTokensCache.getOrWait([userId, providerId, scope || ""], "write-only")),
|
||||
useOAuthToken: () => useAsyncCache(this._serverUserOAuthConnectionAccessTokensCache, [userId, providerId, scope || ""], "user.useConnectedAccount()"),
|
||||
providerId,
|
||||
scope,
|
||||
redirect,
|
||||
session: null
|
||||
});
|
||||
}
|
||||
);
|
||||
this._serverTeamMemberProfilesCache = createCache(
|
||||
async ([teamId]) => {
|
||||
return await this._interface.listServerTeamMemberProfiles({ teamId });
|
||||
}
|
||||
);
|
||||
this._serverTeamInvitationsCache = createCache(
|
||||
async ([teamId]) => {
|
||||
return await this._interface.listServerTeamInvitations({ teamId });
|
||||
}
|
||||
);
|
||||
this._serverUserTeamProfileCache = createCache(
|
||||
async ([teamId, userId]) => {
|
||||
return await this._interface.getServerTeamMemberProfile({ teamId, userId });
|
||||
}
|
||||
);
|
||||
this._serverContactChannelsCache = createCache(
|
||||
async ([userId]) => {
|
||||
return await this._interface.listServerContactChannels(userId);
|
||||
}
|
||||
);
|
||||
this._serverUserApiKeysCache = createCache(
|
||||
async ([userId]) => {
|
||||
const result = await this._interface.listProjectApiKeys({
|
||||
user_id: userId
|
||||
}, null, "server");
|
||||
return result;
|
||||
}
|
||||
);
|
||||
this._serverTeamApiKeysCache = createCache(
|
||||
async ([teamId]) => {
|
||||
const result = await this._interface.listProjectApiKeys({
|
||||
team_id: teamId
|
||||
}, null, "server");
|
||||
return result;
|
||||
}
|
||||
);
|
||||
this._serverCheckApiKeyCache = createCache(async ([type, apiKey]) => {
|
||||
const result = await this._interface.checkProjectApiKey(
|
||||
type,
|
||||
apiKey,
|
||||
null,
|
||||
"server"
|
||||
);
|
||||
return result;
|
||||
});
|
||||
}
|
||||
async _updateServerUser(userId, update) {
|
||||
const result = await this._interface.updateServerUser(userId, serverUserUpdateOptionsToCrud(update));
|
||||
await this._refreshUsers();
|
||||
return result;
|
||||
}
|
||||
_serverEditableTeamProfileFromCrud(crud) {
|
||||
const app = this;
|
||||
return {
|
||||
displayName: crud.display_name,
|
||||
profileImageUrl: crud.profile_image_url,
|
||||
async update(update) {
|
||||
await app._interface.updateServerTeamMemberProfile({
|
||||
teamId: crud.team_id,
|
||||
userId: crud.user_id,
|
||||
profile: {
|
||||
display_name: update.displayName,
|
||||
profile_image_url: update.profileImageUrl
|
||||
}
|
||||
});
|
||||
await app._serverUserTeamProfileCache.refresh([crud.team_id, crud.user_id]);
|
||||
}
|
||||
};
|
||||
}
|
||||
_serverContactChannelFromCrud(userId, crud) {
|
||||
const app = this;
|
||||
return {
|
||||
id: crud.id,
|
||||
value: crud.value,
|
||||
type: crud.type,
|
||||
isVerified: crud.is_verified,
|
||||
isPrimary: crud.is_primary,
|
||||
usedForAuth: crud.used_for_auth,
|
||||
async sendVerificationEmail(options) {
|
||||
await app._interface.sendServerContactChannelVerificationEmail(userId, crud.id, options?.callbackUrl ?? constructRedirectUrl(app.urls.emailVerification, "callbackUrl"));
|
||||
},
|
||||
async update(data) {
|
||||
await app._interface.updateServerContactChannel(userId, crud.id, serverContactChannelUpdateOptionsToCrud(data));
|
||||
await Promise.all([
|
||||
app._serverContactChannelsCache.refresh([userId]),
|
||||
app._serverUserCache.refresh([userId])
|
||||
]);
|
||||
},
|
||||
async delete() {
|
||||
await app._interface.deleteServerContactChannel(userId, crud.id);
|
||||
await Promise.all([
|
||||
app._serverContactChannelsCache.refresh([userId]),
|
||||
app._serverUserCache.refresh([userId])
|
||||
]);
|
||||
}
|
||||
};
|
||||
}
|
||||
_serverApiKeyFromCrud(crud) {
|
||||
return {
|
||||
...this._baseApiKeyFromCrud(crud),
|
||||
async revoke() {
|
||||
await this.update({ revoked: true });
|
||||
},
|
||||
update: async (options) => {
|
||||
await this._interface.updateProjectApiKey(
|
||||
crud.type === "team" ? { team_id: crud.team_id } : { user_id: crud.user_id },
|
||||
crud.id,
|
||||
await apiKeyUpdateOptionsToCrud(crud.type, options),
|
||||
null,
|
||||
"server"
|
||||
);
|
||||
if (crud.type === "team") {
|
||||
await this._serverTeamApiKeysCache.refresh([crud.team_id]);
|
||||
} else {
|
||||
await this._serverUserApiKeysCache.refresh([crud.user_id]);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
_serverUserFromCrud(crud) {
|
||||
const app = this;
|
||||
async function getConnectedAccount(id, options) {
|
||||
const scopeString = options?.scopes?.join(" ");
|
||||
return Result.orThrow(await app._serverUserOAuthConnectionCache.getOrWait([crud.id, id, scopeString || "", options?.or === "redirect"], "write-only"));
|
||||
}
|
||||
function useConnectedAccount(id, options) {
|
||||
const scopeString = options?.scopes?.join(" ");
|
||||
return useAsyncCache(app._serverUserOAuthConnectionCache, [crud.id, id, scopeString || "", options?.or === "redirect"], "user.useConnectedAccount()");
|
||||
}
|
||||
return {
|
||||
...super._createBaseUser(crud),
|
||||
lastActiveAt: new Date(crud.last_active_at_millis),
|
||||
serverMetadata: crud.server_metadata,
|
||||
async setPrimaryEmail(email, options) {
|
||||
await app._updateServerUser(crud.id, { primaryEmail: email, primaryEmailVerified: options?.verified });
|
||||
},
|
||||
async grantPermission(scopeOrPermissionId, permissionId) {
|
||||
if (scopeOrPermissionId && typeof scopeOrPermissionId !== "string" && permissionId) {
|
||||
const scope = scopeOrPermissionId;
|
||||
await app._interface.grantServerTeamUserPermission(scope.id, crud.id, permissionId);
|
||||
for (const recursive of [true, false]) {
|
||||
await app._serverTeamUserPermissionsCache.refresh([scope.id, crud.id, recursive]);
|
||||
}
|
||||
} else {
|
||||
const pId = scopeOrPermissionId;
|
||||
await app._interface.grantServerProjectPermission(crud.id, pId);
|
||||
for (const recursive of [true, false]) {
|
||||
await app._serverUserProjectPermissionsCache.refresh([crud.id, recursive]);
|
||||
}
|
||||
}
|
||||
},
|
||||
async revokePermission(scopeOrPermissionId, permissionId) {
|
||||
if (scopeOrPermissionId && typeof scopeOrPermissionId !== "string" && permissionId) {
|
||||
const scope = scopeOrPermissionId;
|
||||
await app._interface.revokeServerTeamUserPermission(scope.id, crud.id, permissionId);
|
||||
for (const recursive of [true, false]) {
|
||||
await app._serverTeamUserPermissionsCache.refresh([scope.id, crud.id, recursive]);
|
||||
}
|
||||
} else {
|
||||
const pId = scopeOrPermissionId;
|
||||
await app._interface.revokeServerProjectPermission(crud.id, pId);
|
||||
for (const recursive of [true, false]) {
|
||||
await app._serverUserProjectPermissionsCache.refresh([crud.id, recursive]);
|
||||
}
|
||||
}
|
||||
},
|
||||
async delete() {
|
||||
const res = await app._interface.deleteServerUser(crud.id);
|
||||
await app._refreshUsers();
|
||||
return res;
|
||||
},
|
||||
async createSession(options) {
|
||||
const tokens = await app._interface.createServerUserSession(crud.id, options.expiresInMillis ?? 1e3 * 60 * 60 * 24 * 365, options.isImpersonation ?? false);
|
||||
return {
|
||||
async getTokens() {
|
||||
return tokens;
|
||||
}
|
||||
};
|
||||
},
|
||||
async getActiveSessions() {
|
||||
const sessions = await app._interface.listServerSessions(crud.id);
|
||||
return sessions.map((session) => app._clientSessionFromCrud(session));
|
||||
},
|
||||
async revokeSession(sessionId) {
|
||||
await app._interface.deleteServerSession(sessionId);
|
||||
},
|
||||
async setDisplayName(displayName) {
|
||||
return await this.update({ displayName });
|
||||
},
|
||||
async setClientMetadata(metadata) {
|
||||
return await this.update({ clientMetadata: metadata });
|
||||
},
|
||||
async setClientReadOnlyMetadata(metadata) {
|
||||
return await this.update({ clientReadOnlyMetadata: metadata });
|
||||
},
|
||||
async setServerMetadata(metadata) {
|
||||
return await this.update({ serverMetadata: metadata });
|
||||
},
|
||||
async setSelectedTeam(team) {
|
||||
return await this.update({ selectedTeamId: team?.id ?? null });
|
||||
},
|
||||
getConnectedAccount,
|
||||
useConnectedAccount,
|
||||
// THIS_LINE_PLATFORM react-like
|
||||
selectedTeam: crud.selected_team ? app._serverTeamFromCrud(crud.selected_team) : null,
|
||||
async getTeam(teamId) {
|
||||
const teams = await this.listTeams();
|
||||
return teams.find((t) => t.id === teamId) ?? null;
|
||||
},
|
||||
useTeam(teamId) {
|
||||
const teams = this.useTeams();
|
||||
return useMemo(() => {
|
||||
return teams.find((t) => t.id === teamId) ?? null;
|
||||
}, [teams, teamId]);
|
||||
},
|
||||
async listTeams() {
|
||||
const teams = Result.orThrow(await app._serverTeamsCache.getOrWait([crud.id], "write-only"));
|
||||
return teams.map((t) => app._serverTeamFromCrud(t));
|
||||
},
|
||||
useTeams() {
|
||||
const teams = useAsyncCache(app._serverTeamsCache, [crud.id], "user.useTeams()");
|
||||
return useMemo(() => teams.map((t) => app._serverTeamFromCrud(t)), [teams]);
|
||||
},
|
||||
createTeam: async (data) => {
|
||||
const team = await app._interface.createServerTeam(serverTeamCreateOptionsToCrud({
|
||||
creatorUserId: crud.id,
|
||||
...data
|
||||
}));
|
||||
await app._serverTeamsCache.refresh([void 0]);
|
||||
await app._updateServerUser(crud.id, { selectedTeamId: team.id });
|
||||
return app._serverTeamFromCrud(team);
|
||||
},
|
||||
leaveTeam: async (team) => {
|
||||
await app._interface.leaveServerTeam({ teamId: team.id, userId: crud.id });
|
||||
},
|
||||
async listPermissions(scopeOrOptions, options) {
|
||||
if (scopeOrOptions && "id" in scopeOrOptions) {
|
||||
const scope = scopeOrOptions;
|
||||
const recursive = options?.recursive ?? true;
|
||||
const permissions = Result.orThrow(await app._serverTeamUserPermissionsCache.getOrWait([scope.id, crud.id, recursive], "write-only"));
|
||||
return permissions.map((crud2) => app._serverPermissionFromCrud(crud2));
|
||||
} else {
|
||||
const opts = scopeOrOptions;
|
||||
const recursive = opts?.recursive ?? true;
|
||||
const permissions = Result.orThrow(await app._serverUserProjectPermissionsCache.getOrWait([crud.id, recursive], "write-only"));
|
||||
return permissions.map((crud2) => app._serverPermissionFromCrud(crud2));
|
||||
}
|
||||
},
|
||||
usePermissions(scopeOrOptions, options) {
|
||||
if (scopeOrOptions && "id" in scopeOrOptions) {
|
||||
const scope = scopeOrOptions;
|
||||
const recursive = options?.recursive ?? true;
|
||||
const permissions = useAsyncCache(app._serverTeamUserPermissionsCache, [scope.id, crud.id, recursive], "user.usePermissions()");
|
||||
return useMemo(() => permissions.map((crud2) => app._serverPermissionFromCrud(crud2)), [permissions]);
|
||||
} else {
|
||||
const opts = scopeOrOptions;
|
||||
const recursive = opts?.recursive ?? true;
|
||||
const permissions = useAsyncCache(app._serverUserProjectPermissionsCache, [crud.id, recursive], "user.usePermissions()");
|
||||
return useMemo(() => permissions.map((crud2) => app._serverPermissionFromCrud(crud2)), [permissions]);
|
||||
}
|
||||
},
|
||||
async getPermission(scopeOrPermissionId, permissionId) {
|
||||
if (scopeOrPermissionId && typeof scopeOrPermissionId !== "string") {
|
||||
const scope = scopeOrPermissionId;
|
||||
const permissions = await this.listPermissions(scope);
|
||||
return permissions.find((p) => p.id === permissionId) ?? null;
|
||||
} else {
|
||||
const pid = scopeOrPermissionId;
|
||||
const permissions = await this.listPermissions();
|
||||
return permissions.find((p) => p.id === pid) ?? null;
|
||||
}
|
||||
},
|
||||
usePermission(scopeOrPermissionId, permissionId) {
|
||||
if (scopeOrPermissionId && typeof scopeOrPermissionId !== "string") {
|
||||
const scope = scopeOrPermissionId;
|
||||
const permissions = this.usePermissions(scope);
|
||||
return useMemo(() => permissions.find((p) => p.id === permissionId) ?? null, [permissions, permissionId]);
|
||||
} else {
|
||||
const pid = scopeOrPermissionId;
|
||||
const permissions = this.usePermissions();
|
||||
return useMemo(() => permissions.find((p) => p.id === pid) ?? null, [permissions, pid]);
|
||||
}
|
||||
},
|
||||
async hasPermission(scopeOrPermissionId, permissionId) {
|
||||
if (scopeOrPermissionId && typeof scopeOrPermissionId !== "string") {
|
||||
const scope = scopeOrPermissionId;
|
||||
return await this.getPermission(scope, permissionId) !== null;
|
||||
} else {
|
||||
const pid = scopeOrPermissionId;
|
||||
return await this.getPermission(pid) !== null;
|
||||
}
|
||||
},
|
||||
async update(update) {
|
||||
await app._updateServerUser(crud.id, update);
|
||||
},
|
||||
async sendVerificationEmail() {
|
||||
return await app._checkFeatureSupport("sendVerificationEmail() on ServerUser", {});
|
||||
},
|
||||
async updatePassword(options) {
|
||||
const result = await app._interface.updatePassword(options);
|
||||
await app._serverUserCache.refresh([crud.id]);
|
||||
return result;
|
||||
},
|
||||
async setPassword(options) {
|
||||
const result = await this.update(options);
|
||||
await app._serverUserCache.refresh([crud.id]);
|
||||
return result;
|
||||
},
|
||||
async getTeamProfile(team) {
|
||||
const result = Result.orThrow(await app._serverUserTeamProfileCache.getOrWait([team.id, crud.id], "write-only"));
|
||||
return app._serverEditableTeamProfileFromCrud(result);
|
||||
},
|
||||
useTeamProfile(team) {
|
||||
const result = useAsyncCache(app._serverUserTeamProfileCache, [team.id, crud.id], "user.useTeamProfile()");
|
||||
return useMemo(() => app._serverEditableTeamProfileFromCrud(result), [result]);
|
||||
},
|
||||
async listContactChannels() {
|
||||
const result = Result.orThrow(await app._serverContactChannelsCache.getOrWait([crud.id], "write-only"));
|
||||
return result.map((data) => app._serverContactChannelFromCrud(crud.id, data));
|
||||
},
|
||||
useContactChannels() {
|
||||
const result = useAsyncCache(app._serverContactChannelsCache, [crud.id], "user.useContactChannels()");
|
||||
return useMemo(() => result.map((data) => app._serverContactChannelFromCrud(crud.id, data)), [result]);
|
||||
},
|
||||
createContactChannel: async (data) => {
|
||||
const contactChannel = await app._interface.createServerContactChannel(serverContactChannelCreateOptionsToCrud(crud.id, data));
|
||||
await Promise.all([
|
||||
app._serverContactChannelsCache.refresh([crud.id]),
|
||||
app._serverUserCache.refresh([crud.id])
|
||||
]);
|
||||
return app._serverContactChannelFromCrud(crud.id, contactChannel);
|
||||
},
|
||||
useApiKeys() {
|
||||
const result = useAsyncCache(app._serverUserApiKeysCache, [crud.id], "user.useApiKeys()");
|
||||
return result.map((apiKey) => app._serverApiKeyFromCrud(apiKey));
|
||||
},
|
||||
async listApiKeys() {
|
||||
const result = Result.orThrow(await app._serverUserApiKeysCache.getOrWait([crud.id], "write-only"));
|
||||
return result.map((apiKey) => app._serverApiKeyFromCrud(apiKey));
|
||||
},
|
||||
async createApiKey(options) {
|
||||
const result = await app._interface.createProjectApiKey(
|
||||
await apiKeyCreationOptionsToCrud("user", crud.id, options),
|
||||
null,
|
||||
"server"
|
||||
);
|
||||
await app._serverUserApiKeysCache.refresh([crud.id]);
|
||||
return app._serverApiKeyFromCrud(result);
|
||||
}
|
||||
};
|
||||
}
|
||||
_serverTeamUserFromCrud(crud) {
|
||||
return {
|
||||
...this._serverUserFromCrud(crud.user),
|
||||
teamProfile: {
|
||||
displayName: crud.display_name,
|
||||
profileImageUrl: crud.profile_image_url
|
||||
}
|
||||
};
|
||||
}
|
||||
_serverTeamInvitationFromCrud(crud) {
|
||||
return {
|
||||
id: crud.id,
|
||||
recipientEmail: crud.recipient_email,
|
||||
expiresAt: new Date(crud.expires_at_millis),
|
||||
revoke: async () => {
|
||||
await this._interface.revokeServerTeamInvitation(crud.id, crud.team_id);
|
||||
}
|
||||
};
|
||||
}
|
||||
_currentUserFromCrud(crud, session) {
|
||||
const app = this;
|
||||
const currentUser = {
|
||||
...this._serverUserFromCrud(crud),
|
||||
...this._createAuth(session),
|
||||
...this._isInternalProject() ? this._createInternalUserExtra(session) : {}
|
||||
};
|
||||
Object.freeze(currentUser);
|
||||
return currentUser;
|
||||
}
|
||||
_serverTeamFromCrud(crud) {
|
||||
const app = this;
|
||||
return {
|
||||
id: crud.id,
|
||||
displayName: crud.display_name,
|
||||
profileImageUrl: crud.profile_image_url,
|
||||
createdAt: new Date(crud.created_at_millis),
|
||||
clientMetadata: crud.client_metadata,
|
||||
clientReadOnlyMetadata: crud.client_read_only_metadata,
|
||||
serverMetadata: crud.server_metadata,
|
||||
async update(update) {
|
||||
await app._interface.updateServerTeam(crud.id, serverTeamUpdateOptionsToCrud(update));
|
||||
await app._serverTeamsCache.refresh([void 0]);
|
||||
},
|
||||
async delete() {
|
||||
await app._interface.deleteServerTeam(crud.id);
|
||||
await app._serverTeamsCache.refresh([void 0]);
|
||||
},
|
||||
async listUsers() {
|
||||
const result = Result.orThrow(await app._serverTeamMemberProfilesCache.getOrWait([crud.id], "write-only"));
|
||||
return result.map((u) => app._serverTeamUserFromCrud(u));
|
||||
},
|
||||
useUsers() {
|
||||
const result = useAsyncCache(app._serverTeamMemberProfilesCache, [crud.id], "team.useUsers()");
|
||||
return useMemo(() => result.map((u) => app._serverTeamUserFromCrud(u)), [result]);
|
||||
},
|
||||
async addUser(userId) {
|
||||
await app._interface.addServerUserToTeam({
|
||||
teamId: crud.id,
|
||||
userId
|
||||
});
|
||||
await app._serverTeamMemberProfilesCache.refresh([crud.id]);
|
||||
},
|
||||
async removeUser(userId) {
|
||||
await app._interface.removeServerUserFromTeam({
|
||||
teamId: crud.id,
|
||||
userId
|
||||
});
|
||||
await app._serverTeamMemberProfilesCache.refresh([crud.id]);
|
||||
},
|
||||
async inviteUser(options) {
|
||||
await app._interface.sendServerTeamInvitation({
|
||||
teamId: crud.id,
|
||||
email: options.email,
|
||||
callbackUrl: options.callbackUrl ?? constructRedirectUrl(app.urls.teamInvitation, "callbackUrl")
|
||||
});
|
||||
await app._serverTeamInvitationsCache.refresh([crud.id]);
|
||||
},
|
||||
async listInvitations() {
|
||||
const result = Result.orThrow(await app._serverTeamInvitationsCache.getOrWait([crud.id], "write-only"));
|
||||
return result.map((crud2) => app._serverTeamInvitationFromCrud(crud2));
|
||||
},
|
||||
useInvitations() {
|
||||
const result = useAsyncCache(app._serverTeamInvitationsCache, [crud.id], "team.useInvitations()");
|
||||
return useMemo(() => result.map((crud2) => app._serverTeamInvitationFromCrud(crud2)), [result]);
|
||||
},
|
||||
useApiKeys() {
|
||||
const result = useAsyncCache(app._serverTeamApiKeysCache, [crud.id], "team.useApiKeys()");
|
||||
return result.map((apiKey) => app._serverApiKeyFromCrud(apiKey));
|
||||
},
|
||||
async listApiKeys() {
|
||||
const result = Result.orThrow(await app._serverTeamApiKeysCache.getOrWait([crud.id], "write-only"));
|
||||
return result.map((apiKey) => app._serverApiKeyFromCrud(apiKey));
|
||||
},
|
||||
async createApiKey(options) {
|
||||
const result = await app._interface.createProjectApiKey(
|
||||
await apiKeyCreationOptionsToCrud("team", crud.id, options),
|
||||
null,
|
||||
"server"
|
||||
);
|
||||
await app._serverTeamApiKeysCache.refresh([crud.id]);
|
||||
return app._serverApiKeyFromCrud(result);
|
||||
}
|
||||
};
|
||||
}
|
||||
async _getUserApiKey(options) {
|
||||
const crud = Result.orThrow(await this._serverCheckApiKeyCache.getOrWait(["user", options.apiKey], "write-only"));
|
||||
return crud ? this._serverApiKeyFromCrud(crud) : null;
|
||||
}
|
||||
async _getTeamApiKey(options) {
|
||||
const crud = Result.orThrow(await this._serverCheckApiKeyCache.getOrWait(["team", options.apiKey], "write-only"));
|
||||
return crud ? this._serverApiKeyFromCrud(crud) : null;
|
||||
}
|
||||
_useUserApiKey(options) {
|
||||
const crud = useAsyncCache(this._serverCheckApiKeyCache, ["user", options.apiKey], "useUserApiKey()");
|
||||
return useMemo(() => crud ? this._serverApiKeyFromCrud(crud) : null, [crud]);
|
||||
}
|
||||
_useTeamApiKey(options) {
|
||||
const crud = useAsyncCache(this._serverCheckApiKeyCache, ["team", options.apiKey], "useTeamApiKey()");
|
||||
return useMemo(() => crud ? this._serverApiKeyFromCrud(crud) : null, [crud]);
|
||||
}
|
||||
async _getUserByApiKey(apiKey) {
|
||||
const apiKeyObject = await this._getUserApiKey({ apiKey });
|
||||
if (apiKeyObject === null) {
|
||||
return null;
|
||||
}
|
||||
return await this.getServerUserById(apiKeyObject.userId);
|
||||
}
|
||||
_useUserByApiKey(apiKey) {
|
||||
const apiKeyObject = this._useUserApiKey({ apiKey });
|
||||
if (apiKeyObject === null) {
|
||||
return null;
|
||||
}
|
||||
return this.useUserById(apiKeyObject.userId);
|
||||
}
|
||||
async _getTeamByApiKey(apiKey) {
|
||||
const apiKeyObject = await this._getTeamApiKey({ apiKey });
|
||||
if (apiKeyObject === null) {
|
||||
return null;
|
||||
}
|
||||
return await this.getTeam(apiKeyObject.teamId);
|
||||
}
|
||||
_useTeamByApiKey(apiKey) {
|
||||
const apiKeyObject = this._useTeamApiKey({ apiKey });
|
||||
if (apiKeyObject === null) {
|
||||
return null;
|
||||
}
|
||||
return this.useTeam(apiKeyObject.teamId);
|
||||
}
|
||||
async createUser(options) {
|
||||
const crud = await this._interface.createServerUser(serverUserCreateOptionsToCrud(options));
|
||||
await this._refreshUsers();
|
||||
return this._serverUserFromCrud(crud);
|
||||
}
|
||||
async getUser(options) {
|
||||
if (typeof options === "string") {
|
||||
return await this.getServerUserById(options);
|
||||
} else if (typeof options === "object" && "apiKey" in options) {
|
||||
return await this._getUserByApiKey(options.apiKey);
|
||||
} else {
|
||||
this._ensurePersistentTokenStore(options?.tokenStore);
|
||||
const session = await this._getSession(options?.tokenStore);
|
||||
let crud = Result.orThrow(await this._currentServerUserCache.getOrWait([session], "write-only"));
|
||||
if (crud?.is_anonymous && options?.or !== "anonymous" && options?.or !== "anonymous-if-exists") {
|
||||
crud = null;
|
||||
}
|
||||
if (crud === null) {
|
||||
switch (options?.or) {
|
||||
case "redirect": {
|
||||
await this.redirectToSignIn({ replace: true });
|
||||
break;
|
||||
}
|
||||
case "throw": {
|
||||
throw new Error("User is not signed in but getUser was called with { or: 'throw' }");
|
||||
}
|
||||
case "anonymous": {
|
||||
const tokens = await this._signUpAnonymously();
|
||||
return await this.getUser({ tokenStore: tokens, or: "anonymous-if-exists" }) ?? throwErr("Something went wrong while signing up anonymously");
|
||||
}
|
||||
case void 0:
|
||||
case "anonymous-if-exists":
|
||||
case "return-null": {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return crud && this._currentUserFromCrud(crud, session);
|
||||
}
|
||||
}
|
||||
async getServerUser() {
|
||||
console.warn("stackServerApp.getServerUser is deprecated; use stackServerApp.getUser instead");
|
||||
return await this.getUser();
|
||||
}
|
||||
async getServerUserById(userId) {
|
||||
const crud = Result.orThrow(await this._serverUserCache.getOrWait([userId], "write-only"));
|
||||
return crud && this._serverUserFromCrud(crud);
|
||||
}
|
||||
useUser(options) {
|
||||
if (typeof options === "string") {
|
||||
return this.useUserById(options);
|
||||
} else if (typeof options === "object" && "apiKey" in options) {
|
||||
return this._useUserByApiKey(options.apiKey);
|
||||
} else {
|
||||
this._ensurePersistentTokenStore(options?.tokenStore);
|
||||
const session = this._useSession(options?.tokenStore);
|
||||
let crud = useAsyncCache(this._currentServerUserCache, [session], "useUser()");
|
||||
if (crud?.is_anonymous && options?.or !== "anonymous" && options?.or !== "anonymous-if-exists") {
|
||||
crud = null;
|
||||
}
|
||||
if (crud === null) {
|
||||
switch (options?.or) {
|
||||
case "redirect": {
|
||||
runAsynchronously(this.redirectToSignIn({ replace: true }));
|
||||
suspend();
|
||||
throw new StackAssertionError("suspend should never return");
|
||||
}
|
||||
case "throw": {
|
||||
throw new Error("User is not signed in but useUser was called with { or: 'throw' }");
|
||||
}
|
||||
case "anonymous": {
|
||||
runAsynchronously(async () => {
|
||||
await this._signUpAnonymously();
|
||||
if (typeof window !== "undefined") {
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
suspend();
|
||||
throw new StackAssertionError("suspend should never return");
|
||||
}
|
||||
case void 0:
|
||||
case "anonymous-if-exists":
|
||||
case "return-null": {
|
||||
}
|
||||
}
|
||||
}
|
||||
return useMemo(() => {
|
||||
return crud && this._currentUserFromCrud(crud, session);
|
||||
}, [crud, session, options?.or]);
|
||||
}
|
||||
}
|
||||
useUserById(userId) {
|
||||
const crud = useAsyncCache(this._serverUserCache, [userId], "useUserById()");
|
||||
return useMemo(() => {
|
||||
return crud && this._serverUserFromCrud(crud);
|
||||
}, [crud]);
|
||||
}
|
||||
async listUsers(options) {
|
||||
const crud = Result.orThrow(await this._serverUsersCache.getOrWait([options?.cursor, options?.limit, options?.orderBy, options?.desc, options?.query], "write-only"));
|
||||
const result = crud.items.map((j) => this._serverUserFromCrud(j));
|
||||
result.nextCursor = crud.pagination?.next_cursor ?? null;
|
||||
return result;
|
||||
}
|
||||
useUsers(options) {
|
||||
const crud = useAsyncCache(this._serverUsersCache, [options?.cursor, options?.limit, options?.orderBy, options?.desc, options?.query], "useServerUsers()");
|
||||
const result = crud.items.map((j) => this._serverUserFromCrud(j));
|
||||
result.nextCursor = crud.pagination?.next_cursor ?? null;
|
||||
return result;
|
||||
}
|
||||
_serverPermissionFromCrud(crud) {
|
||||
return {
|
||||
id: crud.id
|
||||
};
|
||||
}
|
||||
_serverTeamPermissionDefinitionFromCrud(crud) {
|
||||
return {
|
||||
id: crud.id,
|
||||
description: crud.description,
|
||||
containedPermissionIds: crud.contained_permission_ids
|
||||
};
|
||||
}
|
||||
_serverProjectPermissionDefinitionFromCrud(crud) {
|
||||
return {
|
||||
id: crud.id,
|
||||
description: crud.description,
|
||||
containedPermissionIds: crud.contained_permission_ids
|
||||
};
|
||||
}
|
||||
async listTeams() {
|
||||
const teams = Result.orThrow(await this._serverTeamsCache.getOrWait([void 0], "write-only"));
|
||||
return teams.map((t) => this._serverTeamFromCrud(t));
|
||||
}
|
||||
async createTeam(data) {
|
||||
const team = await this._interface.createServerTeam(serverTeamCreateOptionsToCrud(data));
|
||||
await this._serverTeamsCache.refresh([void 0]);
|
||||
return this._serverTeamFromCrud(team);
|
||||
}
|
||||
useTeams() {
|
||||
const teams = useAsyncCache(this._serverTeamsCache, [void 0], "useServerTeams()");
|
||||
return useMemo(() => {
|
||||
return teams.map((t) => this._serverTeamFromCrud(t));
|
||||
}, [teams]);
|
||||
}
|
||||
async getTeam(options) {
|
||||
if (typeof options === "object" && "apiKey" in options) {
|
||||
return await this._getTeamByApiKey(options.apiKey);
|
||||
} else {
|
||||
const teamId = options;
|
||||
const teams = await this.listTeams();
|
||||
return teams.find((t) => t.id === teamId) ?? null;
|
||||
}
|
||||
}
|
||||
useTeam(options) {
|
||||
if (typeof options === "object" && "apiKey" in options) {
|
||||
return this._useTeamByApiKey(options.apiKey);
|
||||
} else {
|
||||
const teamId = options;
|
||||
const teams = this.useTeams();
|
||||
return useMemo(() => {
|
||||
return teams.find((t) => t.id === teamId) ?? null;
|
||||
}, [teams, teamId]);
|
||||
}
|
||||
}
|
||||
async _refreshSession(session) {
|
||||
await Promise.all([
|
||||
super._refreshUser(session),
|
||||
this._currentServerUserCache.refresh([session])
|
||||
]);
|
||||
}
|
||||
async _refreshUsers() {
|
||||
await Promise.all([
|
||||
super._refreshUsers(),
|
||||
this._serverUserCache.refreshWhere(() => true),
|
||||
this._serverUsersCache.refreshWhere(() => true),
|
||||
this._serverContactChannelsCache.refreshWhere(() => true)
|
||||
]);
|
||||
}
|
||||
};
|
||||
export {
|
||||
_StackServerAppImplIncomplete
|
||||
};
|
||||
//# sourceMappingURL=server-app-impl.js.map
|
||||
1
package/@stackframe/react/dist/esm/lib/stack-app/apps/implementations/server-app-impl.js.map
vendored
Normal file
1
package/@stackframe/react/dist/esm/lib/stack-app/apps/implementations/server-app-impl.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue