@stackframe/stack 2.8.36 → 2.8.40
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 +40 -0
- package/dist/components/user-button.js +2 -2
- package/dist/components/user-button.js.map +1 -1
- package/dist/esm/components/user-button.js +2 -2
- package/dist/esm/components/user-button.js.map +1 -1
- package/dist/esm/index.js +3 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/integrations/convex.js +18 -0
- package/dist/esm/integrations/convex.js.map +1 -0
- package/dist/esm/lib/stack-app/apps/implementations/admin-app-impl.js +59 -6
- package/dist/esm/lib/stack-app/apps/implementations/admin-app-impl.js.map +1 -1
- package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.js +140 -3
- package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.js.map +1 -1
- package/dist/esm/lib/stack-app/apps/implementations/common.js +7 -7
- package/dist/esm/lib/stack-app/apps/implementations/common.js.map +1 -1
- package/dist/esm/lib/stack-app/apps/implementations/server-app-impl.js +112 -4
- package/dist/esm/lib/stack-app/apps/implementations/server-app-impl.js.map +1 -1
- package/dist/esm/lib/stack-app/apps/interfaces/admin-app.js.map +1 -1
- package/dist/esm/lib/stack-app/apps/interfaces/client-app.js.map +1 -1
- package/dist/esm/lib/stack-app/apps/interfaces/server-app.js.map +1 -1
- package/dist/esm/lib/stack-app/common.js.map +1 -1
- package/dist/esm/lib/stack-app/index.js.map +1 -1
- package/dist/esm/lib/stack-app/users/index.js.map +1 -1
- package/dist/esm/providers/stack-provider-client.js.map +1 -1
- package/dist/index.d.mts +200 -43
- package/dist/index.d.ts +200 -43
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/integrations/convex.js +43 -0
- package/dist/integrations/convex.js.map +1 -0
- package/dist/lib/stack-app/apps/implementations/admin-app-impl.js +58 -5
- package/dist/lib/stack-app/apps/implementations/admin-app-impl.js.map +1 -1
- package/dist/lib/stack-app/apps/implementations/client-app-impl.js +140 -3
- package/dist/lib/stack-app/apps/implementations/client-app-impl.js.map +1 -1
- package/dist/lib/stack-app/apps/implementations/common.js +7 -7
- package/dist/lib/stack-app/apps/implementations/common.js.map +1 -1
- package/dist/lib/stack-app/apps/implementations/server-app-impl.js +111 -3
- package/dist/lib/stack-app/apps/implementations/server-app-impl.js.map +1 -1
- package/dist/lib/stack-app/apps/interfaces/admin-app.js.map +1 -1
- package/dist/lib/stack-app/apps/interfaces/client-app.js.map +1 -1
- package/dist/lib/stack-app/apps/interfaces/server-app.js.map +1 -1
- package/dist/lib/stack-app/common.js.map +1 -1
- package/dist/lib/stack-app/email/index.js.map +1 -1
- package/dist/lib/stack-app/index.js.map +1 -1
- package/dist/lib/stack-app/project-configs/index.js.map +1 -1
- package/dist/lib/stack-app/users/index.js.map +1 -1
- package/dist/providers/stack-provider-client.js.map +1 -1
- package/package.json +6 -5
|
@@ -7,7 +7,7 @@ import { suspendIfSsr } from "@stackframe/stack-shared/dist/utils/react";
|
|
|
7
7
|
import { Result } from "@stackframe/stack-shared/dist/utils/results";
|
|
8
8
|
import { Store } from "@stackframe/stack-shared/dist/utils/stores";
|
|
9
9
|
import React, { useCallback } from "react";
|
|
10
|
-
var clientVersion = "js @stackframe/stack@2.8.
|
|
10
|
+
var clientVersion = "js @stackframe/stack@2.8.40";
|
|
11
11
|
if (clientVersion.startsWith("STACK_COMPILE_TIME")) {
|
|
12
12
|
throw new StackAssertionError("Client version was not replaced. Something went wrong during build!");
|
|
13
13
|
}
|
|
@@ -54,10 +54,10 @@ function getUrls(partial) {
|
|
|
54
54
|
};
|
|
55
55
|
}
|
|
56
56
|
function getDefaultProjectId() {
|
|
57
|
-
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."));
|
|
57
|
+
return process.env.NEXT_PUBLIC_STACK_PROJECT_ID || process.env.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."));
|
|
58
58
|
}
|
|
59
59
|
function getDefaultPublishableClientKey() {
|
|
60
|
-
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."));
|
|
60
|
+
return process.env.NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY || process.env.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."));
|
|
61
61
|
}
|
|
62
62
|
function getDefaultSecretServerKey() {
|
|
63
63
|
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."));
|
|
@@ -66,7 +66,7 @@ function getDefaultSuperSecretAdminKey() {
|
|
|
66
66
|
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."));
|
|
67
67
|
}
|
|
68
68
|
function getDefaultExtraRequestHeaders() {
|
|
69
|
-
return JSON.parse(process.env.NEXT_PUBLIC_STACK_EXTRA_REQUEST_HEADERS || "{}");
|
|
69
|
+
return JSON.parse(process.env.NEXT_PUBLIC_STACK_EXTRA_REQUEST_HEADERS || process.env.STACK_EXTRA_REQUEST_HEADERS || "{}");
|
|
70
70
|
}
|
|
71
71
|
function getBaseUrl(userSpecifiedBaseUrl) {
|
|
72
72
|
let url;
|
|
@@ -82,11 +82,11 @@ function getBaseUrl(userSpecifiedBaseUrl) {
|
|
|
82
82
|
}
|
|
83
83
|
} else {
|
|
84
84
|
if (isBrowserLike()) {
|
|
85
|
-
url = process.env.NEXT_PUBLIC_BROWSER_STACK_API_URL;
|
|
85
|
+
url = process.env.NEXT_PUBLIC_BROWSER_STACK_API_URL || process.env.NEXT_PUBLIC_STACK_API_URL_BROWSER || process.env.STACK_API_URL_BROWSER;
|
|
86
86
|
} else {
|
|
87
|
-
url = process.env.NEXT_PUBLIC_SERVER_STACK_API_URL;
|
|
87
|
+
url = process.env.NEXT_PUBLIC_SERVER_STACK_API_URL || process.env.NEXT_PUBLIC_STACK_API_URL_SERVER || process.env.STACK_API_URL_SERVER;
|
|
88
88
|
}
|
|
89
|
-
url = url || process.env.NEXT_PUBLIC_STACK_API_URL || process.env.NEXT_PUBLIC_STACK_URL || defaultBaseUrl;
|
|
89
|
+
url = url || process.env.NEXT_PUBLIC_STACK_API_URL || process.env.STACK_API_URL || process.env.NEXT_PUBLIC_STACK_URL || defaultBaseUrl;
|
|
90
90
|
}
|
|
91
91
|
return url.endsWith("/") ? url.slice(0, -1) : url;
|
|
92
92
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../src/lib/stack-app/apps/implementations/common.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\nimport { InternalSession } from \"@stackframe/stack-shared/dist/sessions\";\nimport { AsyncCache } from \"@stackframe/stack-shared/dist/utils/caches\";\nimport { isBrowserLike } from \"@stackframe/stack-shared/dist/utils/env\";\nimport { StackAssertionError, concatStacktraces, throwErr } from \"@stackframe/stack-shared/dist/utils/errors\";\nimport { filterUndefined } from \"@stackframe/stack-shared/dist/utils/objects\";\nimport { ReactPromise } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { suspendIfSsr } from \"@stackframe/stack-shared/dist/utils/react\";\nimport { Result } from \"@stackframe/stack-shared/dist/utils/results\";\nimport { Store } from \"@stackframe/stack-shared/dist/utils/stores\";\nimport React, { useCallback } from \"react\"; // THIS_LINE_PLATFORM react-like\nimport { HandlerUrls } from \"../../common\";\n\n// hack to make sure process is defined in non-node environments\n\nexport const clientVersion = \"js @stackframe/stack@2.8.36\";\nif (clientVersion.startsWith(\"STACK_COMPILE_TIME\")) {\n throw new StackAssertionError(\"Client version was not replaced. Something went wrong during build!\");\n}\n\n\nexport const createCache = <D extends any[], T>(fetcher: (dependencies: D) => Promise<T>) => {\n return new AsyncCache<D, Result<T>>(\n async (dependencies) => await Result.fromThrowingAsync(async () => await fetcher(dependencies)),\n {},\n );\n};\n\nexport const createCacheBySession = <D extends any[], T>(fetcher: (session: InternalSession, extraDependencies: D) => Promise<T> ) => {\n return new AsyncCache<[InternalSession, ...D], Result<T>>(\n async ([session, ...extraDependencies]) => await Result.fromThrowingAsync(async () => await fetcher(session, extraDependencies)),\n {\n onSubscribe: ([session], refresh) => {\n const handler = session.onInvalidate(() => refresh());\n return () => handler.unsubscribe();\n },\n },\n );\n};\n\nexport function getUrls(partial: Partial<HandlerUrls>): HandlerUrls {\n const handler = partial.handler ?? \"/handler\";\n const home = partial.home ?? \"/\";\n const afterSignIn = partial.afterSignIn ?? home;\n return {\n handler,\n signIn: `${handler}/sign-in`,\n afterSignIn: home,\n signUp: `${handler}/sign-up`,\n afterSignUp: afterSignIn,\n signOut: `${handler}/sign-out`,\n afterSignOut: home,\n emailVerification: `${handler}/email-verification`,\n passwordReset: `${handler}/password-reset`,\n forgotPassword: `${handler}/forgot-password`,\n oauthCallback: `${handler}/oauth-callback`,\n magicLinkCallback: `${handler}/magic-link-callback`,\n home: home,\n accountSettings: `${handler}/account-settings`,\n error: `${handler}/error`,\n teamInvitation: `${handler}/team-invitation`,\n mfa: `${handler}/mfa`,\n ...filterUndefined(partial),\n };\n}\n\nexport function getDefaultProjectId() {\n 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.\"));\n}\n\nexport function getDefaultPublishableClientKey() {\n 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.\"));\n}\n\nexport function getDefaultSecretServerKey() {\n 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.\"));\n}\n\nexport function getDefaultSuperSecretAdminKey() {\n 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.\"));\n}\n\nexport function getDefaultExtraRequestHeaders() {\n return JSON.parse(process.env.NEXT_PUBLIC_STACK_EXTRA_REQUEST_HEADERS || '{}');\n}\n\n/**\n * Returns the base URL for the Stack API.\n *\n * The URL can be specified in several ways, in order of precedence:\n * 1. Directly through userSpecifiedBaseUrl parameter as string or browser/server object\n * 2. Through environment variables:\n * - Browser: NEXT_PUBLIC_BROWSER_STACK_API_URL\n * - Server: NEXT_PUBLIC_SERVER_STACK_API_URL\n * - Fallback: NEXT_PUBLIC_STACK_API_URL or NEXT_PUBLIC_STACK_URL\n * 3. Default base URL if none of the above are specified\n *\n * The function also ensures the URL doesn't end with a trailing slash\n * by removing it if present.\n *\n * @param userSpecifiedBaseUrl - Optional URL override as string or {browser, server} object\n * @returns The configured base URL without trailing slash\n\n */\nexport function getBaseUrl(userSpecifiedBaseUrl: string | { browser: string, server: string } | undefined) {\n let url;\n if (userSpecifiedBaseUrl) {\n if (typeof userSpecifiedBaseUrl === \"string\") {\n url = userSpecifiedBaseUrl;\n } else {\n if (isBrowserLike()) {\n url = userSpecifiedBaseUrl.browser;\n } else {\n url = userSpecifiedBaseUrl.server;\n }\n }\n } else {\n if (isBrowserLike()) {\n url = process.env.NEXT_PUBLIC_BROWSER_STACK_API_URL;\n } else {\n url = process.env.NEXT_PUBLIC_SERVER_STACK_API_URL;\n }\n url = url || process.env.NEXT_PUBLIC_STACK_API_URL || process.env.NEXT_PUBLIC_STACK_URL || defaultBaseUrl;\n }\n\n return url.endsWith('/') ? url.slice(0, -1) : url;\n}\nconst defaultBaseUrl = \"https://api.stack-auth.com\";\n\nexport type TokenObject = {\n accessToken: string | null,\n refreshToken: string | null,\n};\n\nexport function createEmptyTokenStore() {\n return new Store<TokenObject>({\n refreshToken: null,\n accessToken: null,\n });\n}\n\n\nconst cachePromiseByHookId = new Map<string, ReactPromise<Result<unknown>>>();\nexport function useAsyncCache<D extends any[], T>(cache: AsyncCache<D, Result<T>>, dependencies: D, caller: string): T {\n // we explicitly don't want to run this hook in SSR\n suspendIfSsr(caller);\n\n const id = React.useId();\n\n // whenever the dependencies change, we need to refresh the promise cache\n React.useEffect(() => {\n cachePromiseByHookId.delete(id);\n }, [...dependencies, id]);\n\n const subscribe = useCallback((cb: () => void) => {\n const { unsubscribe } = cache.onStateChange(dependencies, () => {\n cachePromiseByHookId.delete(id);\n cb();\n });\n return unsubscribe;\n }, [cache, ...dependencies]);\n const getSnapshot = useCallback(() => {\n // React checks whether a promise passed to `use` is still the same as the previous one by comparing the reference.\n // If we didn't cache here, this wouldn't work because the promise would be recreated every time the value changes.\n if (!cachePromiseByHookId.has(id)) {\n cachePromiseByHookId.set(id, cache.getOrWait(dependencies, \"read-write\"));\n }\n return cachePromiseByHookId.get(id) as ReactPromise<Result<T>>;\n }, [cache, ...dependencies]);\n\n // note: we must use React.useSyncExternalStore instead of importing the function directly, as it will otherwise\n // throw an error on Next.js (\"can't import useSyncExternalStore from the server\")\n const promise = React.useSyncExternalStore(\n subscribe,\n getSnapshot,\n () => throwErr(new Error(\"getServerSnapshot should never be called in useAsyncCache because we restrict to CSR earlier\"))\n );\n\n const result = React.use(promise);\n if (result.status === \"error\") {\n const error = result.error;\n if (error instanceof Error && !(error as any).__stackHasConcatenatedStacktraces) {\n concatStacktraces(error, new Error());\n (error as any).__stackHasConcatenatedStacktraces = true;\n }\n throw error;\n }\n return result.data;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../../../src/lib/stack-app/apps/implementations/common.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\nimport { InternalSession } from \"@stackframe/stack-shared/dist/sessions\";\nimport { AsyncCache } from \"@stackframe/stack-shared/dist/utils/caches\";\nimport { isBrowserLike } from \"@stackframe/stack-shared/dist/utils/env\";\nimport { StackAssertionError, concatStacktraces, throwErr } from \"@stackframe/stack-shared/dist/utils/errors\";\nimport { filterUndefined } from \"@stackframe/stack-shared/dist/utils/objects\";\nimport { ReactPromise } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { suspendIfSsr } from \"@stackframe/stack-shared/dist/utils/react\";\nimport { Result } from \"@stackframe/stack-shared/dist/utils/results\";\nimport { Store } from \"@stackframe/stack-shared/dist/utils/stores\";\nimport React, { useCallback } from \"react\"; // THIS_LINE_PLATFORM react-like\nimport { HandlerUrls } from \"../../common\";\n\n// hack to make sure process is defined in non-node environments\n\nexport const clientVersion = \"js @stackframe/stack@2.8.40\";\nif (clientVersion.startsWith(\"STACK_COMPILE_TIME\")) {\n throw new StackAssertionError(\"Client version was not replaced. Something went wrong during build!\");\n}\n\n\nexport const createCache = <D extends any[], T>(fetcher: (dependencies: D) => Promise<T>) => {\n return new AsyncCache<D, Result<T>>(\n async (dependencies) => await Result.fromThrowingAsync(async () => await fetcher(dependencies)),\n {},\n );\n};\n\nexport const createCacheBySession = <D extends any[], T>(fetcher: (session: InternalSession, extraDependencies: D) => Promise<T> ) => {\n return new AsyncCache<[InternalSession, ...D], Result<T>>(\n async ([session, ...extraDependencies]) => await Result.fromThrowingAsync(async () => await fetcher(session, extraDependencies)),\n {\n onSubscribe: ([session], refresh) => {\n const handler = session.onInvalidate(() => refresh());\n return () => handler.unsubscribe();\n },\n },\n );\n};\n\nexport function getUrls(partial: Partial<HandlerUrls>): HandlerUrls {\n const handler = partial.handler ?? \"/handler\";\n const home = partial.home ?? \"/\";\n const afterSignIn = partial.afterSignIn ?? home;\n return {\n handler,\n signIn: `${handler}/sign-in`,\n afterSignIn: home,\n signUp: `${handler}/sign-up`,\n afterSignUp: afterSignIn,\n signOut: `${handler}/sign-out`,\n afterSignOut: home,\n emailVerification: `${handler}/email-verification`,\n passwordReset: `${handler}/password-reset`,\n forgotPassword: `${handler}/forgot-password`,\n oauthCallback: `${handler}/oauth-callback`,\n magicLinkCallback: `${handler}/magic-link-callback`,\n home: home,\n accountSettings: `${handler}/account-settings`,\n error: `${handler}/error`,\n teamInvitation: `${handler}/team-invitation`,\n mfa: `${handler}/mfa`,\n ...filterUndefined(partial),\n };\n}\n\nexport function getDefaultProjectId() {\n return process.env.NEXT_PUBLIC_STACK_PROJECT_ID || process.env.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.\"));\n}\n\nexport function getDefaultPublishableClientKey() {\n return process.env.NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY || process.env.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.\"));\n}\n\nexport function getDefaultSecretServerKey() {\n 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.\"));\n}\n\nexport function getDefaultSuperSecretAdminKey() {\n 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.\"));\n}\n\nexport function getDefaultExtraRequestHeaders() {\n return JSON.parse(process.env.NEXT_PUBLIC_STACK_EXTRA_REQUEST_HEADERS || process.env.STACK_EXTRA_REQUEST_HEADERS || '{}');\n}\n\n/**\n * Returns the base URL for the Stack API.\n *\n * The URL can be specified in several ways, in order of precedence:\n * 1. Directly through userSpecifiedBaseUrl parameter as string or browser/server object\n * 2. Through environment variables:\n * - Browser: NEXT_PUBLIC_BROWSER_STACK_API_URL\n * - Server: NEXT_PUBLIC_SERVER_STACK_API_URL\n * - Fallback: NEXT_PUBLIC_STACK_API_URL or NEXT_PUBLIC_STACK_URL\n * 3. Default base URL if none of the above are specified\n *\n * The function also ensures the URL doesn't end with a trailing slash\n * by removing it if present.\n *\n * @param userSpecifiedBaseUrl - Optional URL override as string or {browser, server} object\n * @returns The configured base URL without trailing slash\n\n */\nexport function getBaseUrl(userSpecifiedBaseUrl: string | { browser: string, server: string } | undefined) {\n let url;\n if (userSpecifiedBaseUrl) {\n if (typeof userSpecifiedBaseUrl === \"string\") {\n url = userSpecifiedBaseUrl;\n } else {\n if (isBrowserLike()) {\n url = userSpecifiedBaseUrl.browser;\n } else {\n url = userSpecifiedBaseUrl.server;\n }\n }\n } else {\n // note: NEXT_PUBLIC_BROWSER_STACK_API_URL was renamed to NEXT_PUBLIC_STACK_API_URL_BROWSER, and NEXT_PUBLIC_STACK_URL to NEXT_PUBLIC_STACK_API_URL\n if (isBrowserLike()) {\n url = process.env.NEXT_PUBLIC_BROWSER_STACK_API_URL || process.env.NEXT_PUBLIC_STACK_API_URL_BROWSER || process.env.STACK_API_URL_BROWSER;\n } else {\n url = process.env.NEXT_PUBLIC_SERVER_STACK_API_URL || process.env.NEXT_PUBLIC_STACK_API_URL_SERVER || process.env.STACK_API_URL_SERVER;\n }\n url = url || process.env.NEXT_PUBLIC_STACK_API_URL || process.env.STACK_API_URL || process.env.NEXT_PUBLIC_STACK_URL || defaultBaseUrl;\n }\n\n return url.endsWith('/') ? url.slice(0, -1) : url;\n}\nconst defaultBaseUrl = \"https://api.stack-auth.com\";\n\nexport type TokenObject = {\n accessToken: string | null,\n refreshToken: string | null,\n};\n\nexport function createEmptyTokenStore() {\n return new Store<TokenObject>({\n refreshToken: null,\n accessToken: null,\n });\n}\n\n\nconst cachePromiseByHookId = new Map<string, ReactPromise<Result<unknown>>>();\nexport function useAsyncCache<D extends any[], T>(cache: AsyncCache<D, Result<T>>, dependencies: D, caller: string): T {\n // we explicitly don't want to run this hook in SSR\n suspendIfSsr(caller);\n\n const id = React.useId();\n\n // whenever the dependencies change, we need to refresh the promise cache\n React.useEffect(() => {\n cachePromiseByHookId.delete(id);\n }, [...dependencies, id]);\n\n const subscribe = useCallback((cb: () => void) => {\n const { unsubscribe } = cache.onStateChange(dependencies, () => {\n cachePromiseByHookId.delete(id);\n cb();\n });\n return unsubscribe;\n }, [cache, ...dependencies]);\n const getSnapshot = useCallback(() => {\n // React checks whether a promise passed to `use` is still the same as the previous one by comparing the reference.\n // If we didn't cache here, this wouldn't work because the promise would be recreated every time the value changes.\n if (!cachePromiseByHookId.has(id)) {\n cachePromiseByHookId.set(id, cache.getOrWait(dependencies, \"read-write\"));\n }\n return cachePromiseByHookId.get(id) as ReactPromise<Result<T>>;\n }, [cache, ...dependencies]);\n\n // note: we must use React.useSyncExternalStore instead of importing the function directly, as it will otherwise\n // throw an error on Next.js (\"can't import useSyncExternalStore from the server\")\n const promise = React.useSyncExternalStore(\n subscribe,\n getSnapshot,\n () => throwErr(new Error(\"getServerSnapshot should never be called in useAsyncCache because we restrict to CSR earlier\"))\n );\n\n const result = React.use(promise);\n if (result.status === \"error\") {\n const error = result.error;\n if (error instanceof Error && !(error as any).__stackHasConcatenatedStacktraces) {\n concatStacktraces(error, new Error());\n (error as any).__stackHasConcatenatedStacktraces = true;\n }\n throw error;\n }\n return result.data;\n}\n"],"mappings":";AAKA,SAAS,kBAAkB;AAC3B,SAAS,qBAAqB;AAC9B,SAAS,qBAAqB,mBAAmB,gBAAgB;AACjE,SAAS,uBAAuB;AAEhC,SAAS,oBAAoB;AAC7B,SAAS,cAAc;AACvB,SAAS,aAAa;AACtB,OAAO,SAAS,mBAAmB;AAK5B,IAAM,gBAAgB;AAC7B,IAAI,cAAc,WAAW,oBAAoB,GAAG;AAClD,QAAM,IAAI,oBAAoB,qEAAqE;AACrG;AAGO,IAAM,cAAc,CAAqB,YAA6C;AAC3F,SAAO,IAAI;AAAA,IACT,OAAO,iBAAiB,MAAM,OAAO,kBAAkB,YAAY,MAAM,QAAQ,YAAY,CAAC;AAAA,IAC9F,CAAC;AAAA,EACH;AACF;AAEO,IAAM,uBAAuB,CAAqB,YAA6E;AACpI,SAAO,IAAI;AAAA,IACT,OAAO,CAAC,SAAY,oBAAiB,MAAM,MAAM,OAAO,kBAAkB,YAAY,MAAM,QAAQ,SAAS,iBAAiB,CAAC;AAAA,IAC/H;AAAA,MACE,aAAa,CAAC,CAAC,OAAO,GAAG,YAAY;AACnC,cAAM,UAAU,QAAQ,aAAa,MAAM,QAAQ,CAAC;AACpD,eAAO,MAAM,QAAQ,YAAY;AAAA,MACnC;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,QAAQ,SAA4C;AAClE,QAAM,UAAU,QAAQ,WAAW;AACnC,QAAM,OAAO,QAAQ,QAAQ;AAC7B,QAAM,cAAc,QAAQ,eAAe;AAC3C,SAAO;AAAA,IACL;AAAA,IACA,QAAQ,GAAG,OAAO;AAAA,IAClB,aAAa;AAAA,IACb,QAAQ,GAAG,OAAO;AAAA,IAClB,aAAa;AAAA,IACb,SAAS,GAAG,OAAO;AAAA,IACnB,cAAc;AAAA,IACd,mBAAmB,GAAG,OAAO;AAAA,IAC7B,eAAe,GAAG,OAAO;AAAA,IACzB,gBAAgB,GAAG,OAAO;AAAA,IAC1B,eAAe,GAAG,OAAO;AAAA,IACzB,mBAAmB,GAAG,OAAO;AAAA,IAC7B;AAAA,IACA,iBAAiB,GAAG,OAAO;AAAA,IAC3B,OAAO,GAAG,OAAO;AAAA,IACjB,gBAAgB,GAAG,OAAO;AAAA,IAC1B,KAAK,GAAG,OAAO;AAAA,IACf,GAAG,gBAAgB,OAAO;AAAA,EAC5B;AACF;AAEO,SAAS,sBAAsB;AACpC,SAAO,QAAQ,IAAI,gCAAgC,QAAQ,IAAI,oBAAoB,SAAS,IAAI,MAAM,2NAA2N,CAAC;AACpU;AAEO,SAAS,iCAAiC;AAC/C,SAAO,QAAQ,IAAI,4CAA4C,QAAQ,IAAI,gCAAgC,SAAS,IAAI,MAAM,iSAAiS,CAAC;AACla;AAEO,SAAS,4BAA4B;AAC1C,SAAO,QAAQ,IAAI,2BAA2B,SAAS,IAAI,MAAM,8IAA8I,CAAC;AAClN;AAEO,SAAS,gCAAgC;AAC9C,SAAO,QAAQ,IAAI,gCAAgC,SAAS,IAAI,MAAM,wJAAwJ,CAAC;AACjO;AAEO,SAAS,gCAAgC;AAC9C,SAAO,KAAK,MAAM,QAAQ,IAAI,2CAA2C,QAAQ,IAAI,+BAA+B,IAAI;AAC1H;AAoBO,SAAS,WAAW,sBAAgF;AACzG,MAAI;AACJ,MAAI,sBAAsB;AACxB,QAAI,OAAO,yBAAyB,UAAU;AAC5C,YAAM;AAAA,IACR,OAAO;AACL,UAAI,cAAc,GAAG;AACnB,cAAM,qBAAqB;AAAA,MAC7B,OAAO;AACL,cAAM,qBAAqB;AAAA,MAC7B;AAAA,IACF;AAAA,EACF,OAAO;AAEL,QAAI,cAAc,GAAG;AACnB,YAAM,QAAQ,IAAI,qCAAqC,QAAQ,IAAI,qCAAqC,QAAQ,IAAI;AAAA,IACtH,OAAO;AACL,YAAM,QAAQ,IAAI,oCAAoC,QAAQ,IAAI,oCAAoC,QAAQ,IAAI;AAAA,IACpH;AACA,UAAM,OAAO,QAAQ,IAAI,6BAA6B,QAAQ,IAAI,iBAAiB,QAAQ,IAAI,yBAAyB;AAAA,EAC1H;AAEA,SAAO,IAAI,SAAS,GAAG,IAAI,IAAI,MAAM,GAAG,EAAE,IAAI;AAChD;AACA,IAAM,iBAAiB;AAOhB,SAAS,wBAAwB;AACtC,SAAO,IAAI,MAAmB;AAAA,IAC5B,cAAc;AAAA,IACd,aAAa;AAAA,EACf,CAAC;AACH;AAGA,IAAM,uBAAuB,oBAAI,IAA2C;AACrE,SAAS,cAAkC,OAAiC,cAAiB,QAAmB;AAErH,eAAa,MAAM;AAEnB,QAAM,KAAK,MAAM,MAAM;AAGvB,QAAM,UAAU,MAAM;AACpB,yBAAqB,OAAO,EAAE;AAAA,EAChC,GAAG,CAAC,GAAG,cAAc,EAAE,CAAC;AAExB,QAAM,YAAY,YAAY,CAAC,OAAmB;AAChD,UAAM,EAAE,YAAY,IAAI,MAAM,cAAc,cAAc,MAAM;AAC9D,2BAAqB,OAAO,EAAE;AAC9B,SAAG;AAAA,IACL,CAAC;AACD,WAAO;AAAA,EACT,GAAG,CAAC,OAAO,GAAG,YAAY,CAAC;AAC3B,QAAM,cAAc,YAAY,MAAM;AAGpC,QAAI,CAAC,qBAAqB,IAAI,EAAE,GAAG;AACjC,2BAAqB,IAAI,IAAI,MAAM,UAAU,cAAc,YAAY,CAAC;AAAA,IAC1E;AACA,WAAO,qBAAqB,IAAI,EAAE;AAAA,EACpC,GAAG,CAAC,OAAO,GAAG,YAAY,CAAC;AAI3B,QAAM,UAAU,MAAM;AAAA,IACpB;AAAA,IACA;AAAA,IACA,MAAM,SAAS,IAAI,MAAM,8FAA8F,CAAC;AAAA,EAC1H;AAEA,QAAM,SAAS,MAAM,IAAI,OAAO;AAChC,MAAI,OAAO,WAAW,SAAS;AAC7B,UAAM,QAAQ,OAAO;AACrB,QAAI,iBAAiB,SAAS,CAAE,MAAc,mCAAmC;AAC/E,wBAAkB,OAAO,IAAI,MAAM,CAAC;AACpC,MAAC,MAAc,oCAAoC;AAAA,IACrD;AACA,UAAM;AAAA,EACR;AACA,SAAO,OAAO;AAChB;","names":[]}
|
|
@@ -11,7 +11,7 @@ import { serverContactChannelCreateOptionsToCrud, serverContactChannelUpdateOpti
|
|
|
11
11
|
import { serverTeamCreateOptionsToCrud, serverTeamUpdateOptionsToCrud } from "../../teams/index.js";
|
|
12
12
|
import { serverUserCreateOptionsToCrud, serverUserUpdateOptionsToCrud } from "../../users/index.js";
|
|
13
13
|
import { _StackClientAppImplIncomplete } from "./client-app-impl.js";
|
|
14
|
-
import { clientVersion, createCache, createCacheBySession, getBaseUrl, getDefaultProjectId, getDefaultPublishableClientKey, getDefaultSecretServerKey } from "./common.js";
|
|
14
|
+
import { clientVersion, createCache, createCacheBySession, getBaseUrl, getDefaultExtraRequestHeaders, getDefaultProjectId, getDefaultPublishableClientKey, getDefaultSecretServerKey } from "./common.js";
|
|
15
15
|
import { useAsyncCache } from "./common.js";
|
|
16
16
|
var _StackServerAppImplIncomplete = class extends _StackClientAppImplIncomplete {
|
|
17
17
|
constructor(options) {
|
|
@@ -24,7 +24,7 @@ var _StackServerAppImplIncomplete = class extends _StackClientAppImplIncomplete
|
|
|
24
24
|
interface: new StackServerInterface({
|
|
25
25
|
getBaseUrl: () => getBaseUrl(options.baseUrl),
|
|
26
26
|
projectId: options.projectId ?? getDefaultProjectId(),
|
|
27
|
-
extraRequestHeaders: options.extraRequestHeaders ??
|
|
27
|
+
extraRequestHeaders: options.extraRequestHeaders ?? getDefaultExtraRequestHeaders(),
|
|
28
28
|
clientVersion,
|
|
29
29
|
publishableClientKey: options.publishableClientKey ?? getDefaultPublishableClientKey(),
|
|
30
30
|
secretServerKey: options.secretServerKey ?? getDefaultSecretServerKey()
|
|
@@ -131,6 +131,12 @@ var _StackServerAppImplIncomplete = class extends _StackClientAppImplIncomplete
|
|
|
131
131
|
return result;
|
|
132
132
|
}
|
|
133
133
|
);
|
|
134
|
+
this._convexIdentitySubjectCache = createCache(
|
|
135
|
+
async ([ctx]) => {
|
|
136
|
+
const identity = await ctx.auth.getUserIdentity();
|
|
137
|
+
return identity ? identity.subject : null;
|
|
138
|
+
}
|
|
139
|
+
);
|
|
134
140
|
this._serverCheckApiKeyCache = createCache(async ([type, apiKey]) => {
|
|
135
141
|
const result = await this._interface.checkProjectApiKey(
|
|
136
142
|
type,
|
|
@@ -140,6 +146,11 @@ var _StackServerAppImplIncomplete = class extends _StackClientAppImplIncomplete
|
|
|
140
146
|
);
|
|
141
147
|
return result;
|
|
142
148
|
});
|
|
149
|
+
this._serverOAuthProvidersCache = createCache(
|
|
150
|
+
async ([userId]) => {
|
|
151
|
+
return await this._interface.listServerOAuthProviders({ user_id: userId });
|
|
152
|
+
}
|
|
153
|
+
);
|
|
143
154
|
this._serverTeamItemsCache = createCache(
|
|
144
155
|
async ([teamId, itemId]) => {
|
|
145
156
|
return await this._interface.getItem({ teamId, itemId }, null);
|
|
@@ -220,6 +231,39 @@ var _StackServerAppImplIncomplete = class extends _StackClientAppImplIncomplete
|
|
|
220
231
|
}
|
|
221
232
|
};
|
|
222
233
|
}
|
|
234
|
+
_serverOAuthProviderFromCrud(crud) {
|
|
235
|
+
const app = this;
|
|
236
|
+
return {
|
|
237
|
+
id: crud.id,
|
|
238
|
+
type: crud.type,
|
|
239
|
+
userId: crud.user_id,
|
|
240
|
+
accountId: crud.account_id,
|
|
241
|
+
email: crud.email,
|
|
242
|
+
allowSignIn: crud.allow_sign_in,
|
|
243
|
+
allowConnectedAccounts: crud.allow_connected_accounts,
|
|
244
|
+
async update(data) {
|
|
245
|
+
try {
|
|
246
|
+
await app._interface.updateServerOAuthProvider(crud.user_id, crud.id, {
|
|
247
|
+
account_id: data.accountId,
|
|
248
|
+
email: data.email,
|
|
249
|
+
allow_sign_in: data.allowSignIn,
|
|
250
|
+
allow_connected_accounts: data.allowConnectedAccounts
|
|
251
|
+
});
|
|
252
|
+
await app._serverOAuthProvidersCache.refresh([crud.user_id]);
|
|
253
|
+
return Result.ok(void 0);
|
|
254
|
+
} catch (error) {
|
|
255
|
+
if (KnownErrors.OAuthProviderAccountIdAlreadyUsedForSignIn.isInstance(error)) {
|
|
256
|
+
return Result.error(error);
|
|
257
|
+
}
|
|
258
|
+
throw error;
|
|
259
|
+
}
|
|
260
|
+
},
|
|
261
|
+
async delete() {
|
|
262
|
+
await app._interface.deleteServerOAuthProvider(crud.user_id, crud.id);
|
|
263
|
+
await app._serverOAuthProvidersCache.refresh([crud.user_id]);
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
}
|
|
223
267
|
_serverApiKeyFromCrud(crud) {
|
|
224
268
|
return {
|
|
225
269
|
...this._baseApiKeyFromCrud(crud),
|
|
@@ -480,6 +524,22 @@ var _StackServerAppImplIncomplete = class extends _StackClientAppImplIncomplete
|
|
|
480
524
|
await app._serverUserApiKeysCache.refresh([crud.id]);
|
|
481
525
|
return app._serverApiKeyFromCrud(result);
|
|
482
526
|
},
|
|
527
|
+
useOAuthProviders() {
|
|
528
|
+
const results = useAsyncCache(app._serverOAuthProvidersCache, [crud.id], "user.useOAuthProviders()");
|
|
529
|
+
return useMemo(() => results.map((oauthCrud) => app._serverOAuthProviderFromCrud(oauthCrud)), [results]);
|
|
530
|
+
},
|
|
531
|
+
async listOAuthProviders() {
|
|
532
|
+
const results = Result.orThrow(await app._serverOAuthProvidersCache.getOrWait([crud.id], "write-only"));
|
|
533
|
+
return results.map((oauthCrud) => app._serverOAuthProviderFromCrud(oauthCrud));
|
|
534
|
+
},
|
|
535
|
+
useOAuthProvider(id) {
|
|
536
|
+
const providers = this.useOAuthProviders();
|
|
537
|
+
return useMemo(() => providers.find((p) => p.id === id) ?? null, [providers, id]);
|
|
538
|
+
},
|
|
539
|
+
async getOAuthProvider(id) {
|
|
540
|
+
const providers = await this.listOAuthProviders();
|
|
541
|
+
return providers.find((p) => p.id === id) ?? null;
|
|
542
|
+
},
|
|
483
543
|
async createCheckoutUrl(options) {
|
|
484
544
|
const offerIdOrInline = "offerId" in options ? options.offerId : options.offer;
|
|
485
545
|
return await app._interface.createCheckoutUrl("user", crud.id, offerIdOrInline, null);
|
|
@@ -670,6 +730,28 @@ var _StackServerAppImplIncomplete = class extends _StackClientAppImplIncomplete
|
|
|
670
730
|
}
|
|
671
731
|
return await this.getServerUserById(apiKeyObject.userId);
|
|
672
732
|
}
|
|
733
|
+
async _getUserByConvex(ctx, includeAnonymous) {
|
|
734
|
+
const identity = await ctx.auth.getUserIdentity();
|
|
735
|
+
if (identity === null) {
|
|
736
|
+
return null;
|
|
737
|
+
}
|
|
738
|
+
const user = await this.getServerUserById(identity.subject);
|
|
739
|
+
if (user?.isAnonymous && !includeAnonymous) {
|
|
740
|
+
return null;
|
|
741
|
+
}
|
|
742
|
+
return user;
|
|
743
|
+
}
|
|
744
|
+
_useUserByConvex(ctx, includeAnonymous) {
|
|
745
|
+
const subject = useAsyncCache(this._convexIdentitySubjectCache, [ctx], "useUserByConvex()");
|
|
746
|
+
if (subject === null) {
|
|
747
|
+
return null;
|
|
748
|
+
}
|
|
749
|
+
const user = this.useUserById(subject);
|
|
750
|
+
if (user?.isAnonymous && !includeAnonymous) {
|
|
751
|
+
return null;
|
|
752
|
+
}
|
|
753
|
+
return user;
|
|
754
|
+
}
|
|
673
755
|
_useUserByApiKey(apiKey) {
|
|
674
756
|
const apiKeyObject = this._useUserApiKey({ apiKey });
|
|
675
757
|
if (apiKeyObject === null) {
|
|
@@ -701,7 +783,10 @@ var _StackServerAppImplIncomplete = class extends _StackClientAppImplIncomplete
|
|
|
701
783
|
return await this.getServerUserById(options);
|
|
702
784
|
} else if (typeof options === "object" && "apiKey" in options) {
|
|
703
785
|
return await this._getUserByApiKey(options.apiKey);
|
|
786
|
+
} else if (typeof options === "object" && "from" in options && options.from === "convex") {
|
|
787
|
+
return await this._getUserByConvex(options.ctx, "or" in options && options.or === "anonymous");
|
|
704
788
|
} else {
|
|
789
|
+
options = options;
|
|
705
790
|
this._ensurePersistentTokenStore(options?.tokenStore);
|
|
706
791
|
const session = await this._getSession(options?.tokenStore);
|
|
707
792
|
let crud = Result.orThrow(await this._currentServerUserCache.getOrWait([session], "write-only"));
|
|
@@ -744,7 +829,10 @@ var _StackServerAppImplIncomplete = class extends _StackClientAppImplIncomplete
|
|
|
744
829
|
return this.useUserById(options);
|
|
745
830
|
} else if (typeof options === "object" && "apiKey" in options) {
|
|
746
831
|
return this._useUserByApiKey(options.apiKey);
|
|
832
|
+
} else if (typeof options === "object" && "from" in options && options.from === "convex") {
|
|
833
|
+
return this._useUserByConvex(options.ctx, "or" in options && options.or === "anonymous");
|
|
747
834
|
} else {
|
|
835
|
+
options = options;
|
|
748
836
|
this._ensurePersistentTokenStore(options?.tokenStore);
|
|
749
837
|
const session = this._useSession(options?.tokenStore);
|
|
750
838
|
let crud = useAsyncCache(this._currentServerUserCache, [session], "useUser()");
|
|
@@ -915,7 +1003,7 @@ var _StackServerAppImplIncomplete = class extends _StackClientAppImplIncomplete
|
|
|
915
1003
|
return useMemo(() => this._createServerDataVaultStore(id), [id]);
|
|
916
1004
|
}
|
|
917
1005
|
async sendEmail(options) {
|
|
918
|
-
|
|
1006
|
+
await this._interface.sendEmail(options);
|
|
919
1007
|
}
|
|
920
1008
|
async _refreshSession(session) {
|
|
921
1009
|
await Promise.all([
|
|
@@ -928,9 +1016,29 @@ var _StackServerAppImplIncomplete = class extends _StackClientAppImplIncomplete
|
|
|
928
1016
|
super._refreshUsers(),
|
|
929
1017
|
this._serverUserCache.refreshWhere(() => true),
|
|
930
1018
|
this._serverUsersCache.refreshWhere(() => true),
|
|
931
|
-
this._serverContactChannelsCache.refreshWhere(() => true)
|
|
1019
|
+
this._serverContactChannelsCache.refreshWhere(() => true),
|
|
1020
|
+
this._serverOAuthProvidersCache.refreshWhere(() => true)
|
|
932
1021
|
]);
|
|
933
1022
|
}
|
|
1023
|
+
async createOAuthProvider(options) {
|
|
1024
|
+
try {
|
|
1025
|
+
const crud = await this._interface.createServerOAuthProvider({
|
|
1026
|
+
user_id: options.userId,
|
|
1027
|
+
provider_config_id: options.providerConfigId,
|
|
1028
|
+
account_id: options.accountId,
|
|
1029
|
+
email: options.email,
|
|
1030
|
+
allow_sign_in: options.allowSignIn,
|
|
1031
|
+
allow_connected_accounts: options.allowConnectedAccounts
|
|
1032
|
+
});
|
|
1033
|
+
await this._serverOAuthProvidersCache.refresh([options.userId]);
|
|
1034
|
+
return Result.ok(this._serverOAuthProviderFromCrud(crud));
|
|
1035
|
+
} catch (error) {
|
|
1036
|
+
if (KnownErrors.OAuthProviderAccountIdAlreadyUsedForSignIn.isInstance(error)) {
|
|
1037
|
+
return Result.error(error);
|
|
1038
|
+
}
|
|
1039
|
+
throw error;
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
934
1042
|
};
|
|
935
1043
|
export {
|
|
936
1044
|
_StackServerAppImplIncomplete
|