@stackframe/stack 2.8.41 → 2.8.44

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.
Files changed (51) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/esm/integrations/convex/component/convex.config.js +8 -0
  3. package/dist/esm/integrations/convex/component/convex.config.js.map +1 -0
  4. package/dist/esm/integrations/convex.js +5 -4
  5. package/dist/esm/integrations/convex.js.map +1 -1
  6. package/dist/esm/lib/hooks.js +3 -0
  7. package/dist/esm/lib/hooks.js.map +1 -1
  8. package/dist/esm/lib/stack-app/apps/implementations/admin-app-impl.js +31 -42
  9. package/dist/esm/lib/stack-app/apps/implementations/admin-app-impl.js.map +1 -1
  10. package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.js +107 -32
  11. package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.js.map +1 -1
  12. package/dist/esm/lib/stack-app/apps/implementations/common.js +16 -2
  13. package/dist/esm/lib/stack-app/apps/implementations/common.js.map +1 -1
  14. package/dist/esm/lib/stack-app/apps/implementations/server-app-impl.js +119 -60
  15. package/dist/esm/lib/stack-app/apps/implementations/server-app-impl.js.map +1 -1
  16. package/dist/esm/lib/stack-app/apps/interfaces/admin-app.js.map +1 -1
  17. package/dist/esm/lib/stack-app/apps/interfaces/client-app.js.map +1 -1
  18. package/dist/esm/lib/stack-app/apps/interfaces/server-app.js.map +1 -1
  19. package/dist/esm/lib/stack-app/projects/index.js.map +1 -1
  20. package/dist/esm/lib/stack-app/users/index.js +16 -0
  21. package/dist/esm/lib/stack-app/users/index.js.map +1 -1
  22. package/dist/esm/providers/stack-provider.js +2 -6
  23. package/dist/esm/providers/stack-provider.js.map +1 -1
  24. package/dist/index.d.mts +86 -23
  25. package/dist/index.d.ts +86 -23
  26. package/dist/integrations/convex/component/convex.config.d.mts +5 -0
  27. package/dist/integrations/convex/component/convex.config.d.ts +5 -0
  28. package/dist/integrations/convex/component/convex.config.js +29 -0
  29. package/dist/integrations/convex/component/convex.config.js.map +1 -0
  30. package/dist/integrations/convex.js +4 -3
  31. package/dist/integrations/convex.js.map +1 -1
  32. package/dist/lib/hooks.js +3 -0
  33. package/dist/lib/hooks.js.map +1 -1
  34. package/dist/lib/stack-app/apps/implementations/admin-app-impl.js +30 -41
  35. package/dist/lib/stack-app/apps/implementations/admin-app-impl.js.map +1 -1
  36. package/dist/lib/stack-app/apps/implementations/client-app-impl.js +105 -30
  37. package/dist/lib/stack-app/apps/implementations/client-app-impl.js.map +1 -1
  38. package/dist/lib/stack-app/apps/implementations/common.js +17 -1
  39. package/dist/lib/stack-app/apps/implementations/common.js.map +1 -1
  40. package/dist/lib/stack-app/apps/implementations/server-app-impl.js +117 -58
  41. package/dist/lib/stack-app/apps/implementations/server-app-impl.js.map +1 -1
  42. package/dist/lib/stack-app/apps/interfaces/admin-app.js.map +1 -1
  43. package/dist/lib/stack-app/apps/interfaces/client-app.js.map +1 -1
  44. package/dist/lib/stack-app/apps/interfaces/server-app.js.map +1 -1
  45. package/dist/lib/stack-app/customers/index.js.map +1 -1
  46. package/dist/lib/stack-app/projects/index.js.map +1 -1
  47. package/dist/lib/stack-app/users/index.js +17 -0
  48. package/dist/lib/stack-app/users/index.js.map +1 -1
  49. package/dist/providers/stack-provider.js +1 -5
  50. package/dist/providers/stack-provider.js.map +1 -1
  51. package/package.json +19 -10
@@ -34,6 +34,7 @@ __export(common_exports, {
34
34
  createCache: () => createCache,
35
35
  createCacheBySession: () => createCacheBySession,
36
36
  createEmptyTokenStore: () => createEmptyTokenStore,
37
+ defaultBaseUrl: () => defaultBaseUrl,
37
38
  getBaseUrl: () => getBaseUrl,
38
39
  getDefaultExtraRequestHeaders: () => getDefaultExtraRequestHeaders,
39
40
  getDefaultProjectId: () => getDefaultProjectId,
@@ -41,18 +42,21 @@ __export(common_exports, {
41
42
  getDefaultSecretServerKey: () => getDefaultSecretServerKey,
42
43
  getDefaultSuperSecretAdminKey: () => getDefaultSuperSecretAdminKey,
43
44
  getUrls: () => getUrls,
45
+ resolveConstructorOptions: () => resolveConstructorOptions,
44
46
  useAsyncCache: () => useAsyncCache
45
47
  });
46
48
  module.exports = __toCommonJS(common_exports);
47
49
  var import_caches = require("@stackframe/stack-shared/dist/utils/caches");
48
50
  var import_env = require("@stackframe/stack-shared/dist/utils/env");
49
51
  var import_errors = require("@stackframe/stack-shared/dist/utils/errors");
52
+ var import_globals = require("@stackframe/stack-shared/dist/utils/globals");
50
53
  var import_objects = require("@stackframe/stack-shared/dist/utils/objects");
51
54
  var import_react = require("@stackframe/stack-shared/dist/utils/react");
52
55
  var import_results = require("@stackframe/stack-shared/dist/utils/results");
53
56
  var import_stores = require("@stackframe/stack-shared/dist/utils/stores");
54
57
  var import_react2 = __toESM(require("react"));
55
- var clientVersion = "js @stackframe/stack@2.8.41";
58
+ var import_common = require("../../common.js");
59
+ var clientVersion = "js @stackframe/stack@2.8.44";
56
60
  if (clientVersion.startsWith("STACK_COMPILE_TIME")) {
57
61
  throw new import_errors.StackAssertionError("Client version was not replaced. Something went wrong during build!");
58
62
  }
@@ -73,6 +77,12 @@ var createCacheBySession = (fetcher) => {
73
77
  }
74
78
  );
75
79
  };
80
+ function resolveConstructorOptions(options) {
81
+ return {
82
+ ...options.inheritsFrom?.[import_common.stackAppInternalsSymbol].getConstructorOptions() ?? {},
83
+ ...(0, import_objects.filterUndefined)((0, import_objects.omit)(options, ["inheritsFrom"]))
84
+ };
85
+ }
76
86
  function getUrls(partial) {
77
87
  const handler = partial.handler ?? "/handler";
78
88
  const home = partial.home ?? "/";
@@ -145,6 +155,10 @@ function createEmptyTokenStore() {
145
155
  var cachePromiseByHookId = /* @__PURE__ */ new Map();
146
156
  function useAsyncCache(cache, dependencies, caller) {
147
157
  (0, import_react.suspendIfSsr)(caller);
158
+ const asyncCacheHooks = (0, import_globals.getGlobal)("use-async-cache-execution-hooks") ?? [];
159
+ for (const hook of asyncCacheHooks) {
160
+ hook({ cache, caller, dependencies });
161
+ }
148
162
  const id = import_react2.default.useId();
149
163
  import_react2.default.useEffect(() => {
150
164
  cachePromiseByHookId.delete(id);
@@ -184,6 +198,7 @@ function useAsyncCache(cache, dependencies, caller) {
184
198
  createCache,
185
199
  createCacheBySession,
186
200
  createEmptyTokenStore,
201
+ defaultBaseUrl,
187
202
  getBaseUrl,
188
203
  getDefaultExtraRequestHeaders,
189
204
  getDefaultProjectId,
@@ -191,6 +206,7 @@ function useAsyncCache(cache, dependencies, caller) {
191
206
  getDefaultSecretServerKey,
192
207
  getDefaultSuperSecretAdminKey,
193
208
  getUrls,
209
+ resolveConstructorOptions,
194
210
  useAsyncCache
195
211
  });
196
212
  //# sourceMappingURL=common.js.map
@@ -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.41\";\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":"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","names":["import_react","React"]}
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 { getGlobal } from \"@stackframe/stack-shared/dist/utils/globals\";\nimport { filterUndefined, omit } 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, stackAppInternalsSymbol } from \"../../common\";\n\n// hack to make sure process is defined in non-node environments\n\nexport const clientVersion = \"js @stackframe/stack@2.8.44\";\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\n\ntype AppLike = { [stackAppInternalsSymbol]: { getConstructorOptions: () => any } };\nexport function resolveConstructorOptions<T extends { inheritsFrom?: AppLike }>(options: T): T & { inheritsFrom?: undefined } {\n return {\n ...options.inheritsFrom?.[stackAppInternalsSymbol].getConstructorOptions() ?? {},\n ...filterUndefined(omit(options, [\"inheritsFrom\"])),\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}\nexport const 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 // on the dashboard, we do some perf monitoring for pre-fetching which should hook right in here\n const asyncCacheHooks: any[] = getGlobal(\"use-async-cache-execution-hooks\") ?? [];\n for (const hook of asyncCacheHooks) {\n hook({ cache, caller, dependencies });\n }\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":["import_react","React"]}
@@ -38,29 +38,18 @@ var import_client_app_impl = require("./client-app-impl.js");
38
38
  var import_common = require("./common.js");
39
39
  var import_common2 = require("./common.js");
40
40
  var _StackServerAppImplIncomplete = class extends import_client_app_impl._StackClientAppImplIncomplete {
41
- constructor(options) {
42
- super("interface" in options ? {
43
- interface: options.interface,
44
- tokenStore: options.tokenStore,
45
- urls: options.urls,
46
- oauthScopesOnSignIn: options.oauthScopesOnSignIn
47
- } : {
48
- interface: new import_stack_shared.StackServerInterface({
49
- getBaseUrl: () => (0, import_common.getBaseUrl)(options.baseUrl),
50
- projectId: options.projectId ?? (0, import_common.getDefaultProjectId)(),
51
- extraRequestHeaders: options.extraRequestHeaders ?? (0, import_common.getDefaultExtraRequestHeaders)(),
41
+ constructor(options, extraOptions) {
42
+ const resolvedOptions = (0, import_common.resolveConstructorOptions)(options);
43
+ super(resolvedOptions, {
44
+ ...extraOptions,
45
+ interface: extraOptions?.interface ?? new import_stack_shared.StackServerInterface({
46
+ getBaseUrl: () => (0, import_common.getBaseUrl)(resolvedOptions.baseUrl),
47
+ projectId: resolvedOptions.projectId ?? (0, import_common.getDefaultProjectId)(),
48
+ extraRequestHeaders: resolvedOptions.extraRequestHeaders ?? (0, import_common.getDefaultExtraRequestHeaders)(),
52
49
  clientVersion: import_common.clientVersion,
53
- publishableClientKey: options.publishableClientKey ?? (0, import_common.getDefaultPublishableClientKey)(),
54
- secretServerKey: options.secretServerKey ?? (0, import_common.getDefaultSecretServerKey)()
55
- }),
56
- baseUrl: options.baseUrl,
57
- extraRequestHeaders: options.extraRequestHeaders,
58
- projectId: options.projectId,
59
- publishableClientKey: options.publishableClientKey,
60
- tokenStore: options.tokenStore,
61
- urls: options.urls,
62
- oauthScopesOnSignIn: options.oauthScopesOnSignIn,
63
- redirectMethod: options.redirectMethod
50
+ publishableClientKey: resolvedOptions.publishableClientKey ?? (0, import_common.getDefaultPublishableClientKey)(),
51
+ secretServerKey: resolvedOptions.secretServerKey ?? (0, import_common.getDefaultSecretServerKey)()
52
+ })
64
53
  });
65
54
  // TODO override the client user cache to use the server user cache, so we save some requests
66
55
  this._currentServerUserCache = (0, import_common.createCacheBySession)(async (session) => {
@@ -190,6 +179,70 @@ var _StackServerAppImplIncomplete = class extends import_client_app_impl._StackC
190
179
  return await this._interface.getItem({ customCustomerId, itemId }, null);
191
180
  }
192
181
  );
182
+ this._serverUserProductsCache = (0, import_common.createCache)(
183
+ async ([userId, cursor, limit]) => {
184
+ return await this._interface.listProducts({
185
+ customer_type: "user",
186
+ customer_id: userId,
187
+ cursor: cursor ?? void 0,
188
+ limit: limit ?? void 0
189
+ }, null);
190
+ }
191
+ );
192
+ this._serverTeamProductsCache = (0, import_common.createCache)(
193
+ async ([teamId, cursor, limit]) => {
194
+ return await this._interface.listProducts({
195
+ customer_type: "team",
196
+ customer_id: teamId,
197
+ cursor: cursor ?? void 0,
198
+ limit: limit ?? void 0
199
+ }, null);
200
+ }
201
+ );
202
+ this._serverCustomProductsCache = (0, import_common.createCache)(
203
+ async ([customCustomerId, cursor, limit]) => {
204
+ return await this._interface.listProducts({
205
+ customer_type: "custom",
206
+ customer_id: customCustomerId,
207
+ cursor: cursor ?? void 0,
208
+ limit: limit ?? void 0
209
+ }, null);
210
+ }
211
+ );
212
+ }
213
+ _createServerCustomer(userIdOrTeamId, type) {
214
+ const app = this;
215
+ const productsCache = type === "user" ? app._serverUserProductsCache : app._serverTeamProductsCache;
216
+ const customerOptions = type === "user" ? { userId: userIdOrTeamId } : { teamId: userIdOrTeamId };
217
+ return {
218
+ ...this._createCustomer(userIdOrTeamId, type, null),
219
+ async getItem(itemId) {
220
+ return await app.getItem({ itemId, ...customerOptions });
221
+ },
222
+ useItem(itemId) {
223
+ return app.useItem({ itemId, ...customerOptions });
224
+ },
225
+ async grantProduct(productOptions) {
226
+ if (type === "user") {
227
+ if ("productId" in productOptions) {
228
+ await app.grantProduct({ userId: userIdOrTeamId, productId: productOptions.productId, quantity: productOptions.quantity });
229
+ } else {
230
+ await app.grantProduct({ userId: userIdOrTeamId, product: productOptions.product, quantity: productOptions.quantity });
231
+ }
232
+ } else {
233
+ if ("productId" in productOptions) {
234
+ await app.grantProduct({ teamId: userIdOrTeamId, productId: productOptions.productId, quantity: productOptions.quantity });
235
+ } else {
236
+ await app.grantProduct({ teamId: userIdOrTeamId, product: productOptions.product, quantity: productOptions.quantity });
237
+ }
238
+ }
239
+ await productsCache.refresh([userIdOrTeamId, null, null]);
240
+ },
241
+ async createCheckoutUrl(options) {
242
+ const productIdOrInline = "productId" in options ? options.productId : options.product;
243
+ return await app._interface.createCheckoutUrl(type, userIdOrTeamId, productIdOrInline, null, options.returnUrl);
244
+ }
245
+ };
193
246
  }
194
247
  async _updateServerUser(userId, update) {
195
248
  const result = await this._interface.updateServerUser(userId, (0, import_users.serverUserUpdateOptionsToCrud)(update));
@@ -320,7 +373,7 @@ var _StackServerAppImplIncomplete = class extends import_client_app_impl._StackC
320
373
  const scopeString = options?.scopes?.join(" ");
321
374
  return (0, import_common2.useAsyncCache)(app._serverUserOAuthConnectionCache, [crud.id, id, scopeString || "", options?.or === "redirect"], "user.useConnectedAccount()");
322
375
  }
323
- return {
376
+ const serverUser = {
324
377
  ...super._createBaseUser(crud),
325
378
  lastActiveAt: new Date(crud.last_active_at_millis),
326
379
  serverMetadata: crud.server_metadata,
@@ -564,28 +617,21 @@ var _StackServerAppImplIncomplete = class extends import_client_app_impl._StackC
564
617
  const providers = await this.listOAuthProviders();
565
618
  return providers.find((p) => p.id === id) ?? null;
566
619
  },
567
- async createCheckoutUrl(options) {
568
- const offerIdOrInline = "offerId" in options ? options.offerId : options.offer;
569
- return await app._interface.createCheckoutUrl("user", crud.id, offerIdOrInline, null);
570
- },
571
- async getItem(itemId) {
572
- const result = import_results.Result.orThrow(await app._serverUserItemsCache.getOrWait([crud.id, itemId], "write-only"));
573
- return app._serverItemFromCrud({ type: "user", id: crud.id }, result);
574
- },
575
- useItem(itemId) {
576
- const result = (0, import_common2.useAsyncCache)(app._serverUserItemsCache, [crud.id, itemId], "user.useItem()");
577
- return (0, import_react2.useMemo)(() => app._serverItemFromCrud({ type: "user", id: crud.id }, result), [result]);
578
- }
620
+ ...app._createServerCustomer(crud.id, "user")
579
621
  };
622
+ (0, import_users.attachUserDestructureGuard)(serverUser);
623
+ return serverUser;
580
624
  }
581
625
  _serverTeamUserFromCrud(crud) {
582
- return {
626
+ const teamUser = {
583
627
  ...this._serverUserFromCrud(crud.user),
584
628
  teamProfile: {
585
629
  displayName: crud.display_name,
586
630
  profileImageUrl: crud.profile_image_url
587
631
  }
588
632
  };
633
+ (0, import_users.attachUserDestructureGuard)(teamUser);
634
+ return teamUser;
589
635
  }
590
636
  _serverTeamInvitationFromCrud(crud) {
591
637
  return {
@@ -594,16 +640,17 @@ var _StackServerAppImplIncomplete = class extends import_client_app_impl._StackC
594
640
  expiresAt: new Date(crud.expires_at_millis),
595
641
  revoke: async () => {
596
642
  await this._interface.revokeServerTeamInvitation(crud.id, crud.team_id);
643
+ await this._serverTeamInvitationsCache.refresh([crud.team_id]);
597
644
  }
598
645
  };
599
646
  }
600
647
  _currentUserFromCrud(crud, session) {
601
- const app = this;
602
648
  const currentUser = {
603
649
  ...this._serverUserFromCrud(crud),
604
650
  ...this._createAuth(session),
605
651
  ...this._isInternalProject() ? this._createInternalUserExtra(session) : {}
606
652
  };
653
+ (0, import_users.attachUserDestructureGuard)(currentUser);
607
654
  Object.freeze(currentUser);
608
655
  return currentUser;
609
656
  }
@@ -680,18 +727,7 @@ var _StackServerAppImplIncomplete = class extends import_client_app_impl._StackC
680
727
  await app._serverTeamApiKeysCache.refresh([crud.id]);
681
728
  return app._serverApiKeyFromCrud(result);
682
729
  },
683
- async getItem(itemId) {
684
- const result = import_results.Result.orThrow(await app._serverTeamItemsCache.getOrWait([crud.id, itemId], "write-only"));
685
- return app._serverItemFromCrud({ type: "team", id: crud.id }, result);
686
- },
687
- useItem(itemId) {
688
- const result = (0, import_common2.useAsyncCache)(app._serverTeamItemsCache, [crud.id, itemId], "team.useItem()");
689
- return (0, import_react2.useMemo)(() => app._serverItemFromCrud({ type: "team", id: crud.id }, result), [result]);
690
- },
691
- async createCheckoutUrl(options) {
692
- const offerIdOrInline = "offerId" in options ? options.offerId : options.offer;
693
- return await app._interface.createCheckoutUrl("team", crud.id, offerIdOrInline, null);
694
- }
730
+ ...app._createServerCustomer(crud.id, "team")
695
731
  };
696
732
  }
697
733
  _serverItemFromCrud(customer, crud) {
@@ -740,11 +776,11 @@ var _StackServerAppImplIncomplete = class extends import_client_app_impl._StackC
740
776
  return crud ? this._serverApiKeyFromCrud(crud) : null;
741
777
  }
742
778
  _useUserApiKey(options) {
743
- const crud = (0, import_common2.useAsyncCache)(this._serverCheckApiKeyCache, ["user", options.apiKey], "useUserApiKey()");
779
+ const crud = (0, import_common2.useAsyncCache)(this._serverCheckApiKeyCache, ["user", options.apiKey], "serverApp.useUserApiKey()");
744
780
  return (0, import_react2.useMemo)(() => crud ? this._serverApiKeyFromCrud(crud) : null, [crud]);
745
781
  }
746
782
  _useTeamApiKey(options) {
747
- const crud = (0, import_common2.useAsyncCache)(this._serverCheckApiKeyCache, ["team", options.apiKey], "useTeamApiKey()");
783
+ const crud = (0, import_common2.useAsyncCache)(this._serverCheckApiKeyCache, ["team", options.apiKey], "serverApp.useTeamApiKey()");
748
784
  return (0, import_react2.useMemo)(() => crud ? this._serverApiKeyFromCrud(crud) : null, [crud]);
749
785
  }
750
786
  async _getUserByApiKey(apiKey) {
@@ -766,7 +802,7 @@ var _StackServerAppImplIncomplete = class extends import_client_app_impl._StackC
766
802
  return user;
767
803
  }
768
804
  _useUserByConvex(ctx, includeAnonymous) {
769
- const subject = (0, import_common2.useAsyncCache)(this._convexIdentitySubjectCache, [ctx], "useUserByConvex()");
805
+ const subject = (0, import_common2.useAsyncCache)(this._convexIdentitySubjectCache, [ctx], "serverApp.useUserByConvex()");
770
806
  if (subject === null) {
771
807
  return null;
772
808
  }
@@ -859,7 +895,7 @@ var _StackServerAppImplIncomplete = class extends import_client_app_impl._StackC
859
895
  options = options;
860
896
  this._ensurePersistentTokenStore(options?.tokenStore);
861
897
  const session = this._useSession(options?.tokenStore);
862
- let crud = (0, import_common2.useAsyncCache)(this._currentServerUserCache, [session], "useUser()");
898
+ let crud = (0, import_common2.useAsyncCache)(this._currentServerUserCache, [session], "serverApp.useUser()");
863
899
  if (crud?.is_anonymous && options?.or !== "anonymous" && options?.or !== "anonymous-if-exists[deprecated]") {
864
900
  crud = null;
865
901
  }
@@ -895,7 +931,7 @@ var _StackServerAppImplIncomplete = class extends import_client_app_impl._StackC
895
931
  }
896
932
  }
897
933
  useUserById(userId) {
898
- const crud = (0, import_common2.useAsyncCache)(this._serverUserCache, [userId], "useUserById()");
934
+ const crud = (0, import_common2.useAsyncCache)(this._serverUserCache, [userId], "serverApp.useUserById()");
899
935
  return (0, import_react2.useMemo)(() => {
900
936
  return crud && this._serverUserFromCrud(crud);
901
937
  }, [crud]);
@@ -907,7 +943,7 @@ var _StackServerAppImplIncomplete = class extends import_client_app_impl._StackC
907
943
  return result;
908
944
  }
909
945
  useUsers(options) {
910
- const crud = (0, import_common2.useAsyncCache)(this._serverUsersCache, [options?.cursor, options?.limit, options?.orderBy, options?.desc, options?.query], "useServerUsers()");
946
+ const crud = (0, import_common2.useAsyncCache)(this._serverUsersCache, [options?.cursor, options?.limit, options?.orderBy, options?.desc, options?.query], "serverApp.useUsers()");
911
947
  const result = crud.items.map((j) => this._serverUserFromCrud(j));
912
948
  result.nextCursor = crud.pagination?.next_cursor ?? null;
913
949
  return result;
@@ -965,17 +1001,40 @@ var _StackServerAppImplIncomplete = class extends import_client_app_impl._StackC
965
1001
  cache = this._serverCustomItemsCache;
966
1002
  }
967
1003
  const cacheKey = [id, options.itemId];
968
- const debugLabel = `app.useItem(${type})`;
1004
+ const debugLabel = "serverApp.useItem()";
969
1005
  const result = (0, import_common2.useAsyncCache)(cache, cacheKey, debugLabel);
970
1006
  return (0, import_react2.useMemo)(() => this._serverItemFromCrud({ type, id }, result), [result]);
971
1007
  }
1008
+ async grantProduct(options) {
1009
+ let customerType;
1010
+ let customerId;
1011
+ if ("userId" in options) {
1012
+ customerType = "user";
1013
+ customerId = options.userId;
1014
+ } else if ("teamId" in options) {
1015
+ customerType = "team";
1016
+ customerId = options.teamId;
1017
+ } else {
1018
+ customerType = "custom";
1019
+ customerId = options.customCustomerId;
1020
+ }
1021
+ await this._interface.grantProduct({
1022
+ customerType,
1023
+ customerId,
1024
+ productId: "productId" in options ? options.productId : void 0,
1025
+ product: "product" in options ? options.product : void 0,
1026
+ quantity: options.quantity
1027
+ });
1028
+ const cache = customerType === "user" ? this._serverUserProductsCache : customerType === "team" ? this._serverTeamProductsCache : this._serverCustomProductsCache;
1029
+ await cache.refresh([customerId, null, null]);
1030
+ }
972
1031
  async createTeam(data) {
973
1032
  const team = await this._interface.createServerTeam((0, import_teams.serverTeamCreateOptionsToCrud)(data));
974
1033
  await this._serverTeamsCache.refresh([void 0]);
975
1034
  return this._serverTeamFromCrud(team);
976
1035
  }
977
1036
  useTeams() {
978
- const teams = (0, import_common2.useAsyncCache)(this._serverTeamsCache, [void 0], "useServerTeams()");
1037
+ const teams = (0, import_common2.useAsyncCache)(this._serverTeamsCache, [void 0], "serverApp.useTeams()");
979
1038
  return (0, import_react2.useMemo)(() => {
980
1039
  return teams.map((t) => this._serverTeamFromCrud(t));
981
1040
  }, [teams]);
@@ -1016,7 +1075,7 @@ var _StackServerAppImplIncomplete = class extends import_client_app_impl._StackC
1016
1075
  },
1017
1076
  useValue: (key, options) => {
1018
1077
  validateOptions(options);
1019
- return (0, import_common2.useAsyncCache)(this._serverDataVaultStoreValueCache, [id, key, options.secret], `app.useDataVaultStoreValue()`);
1078
+ return (0, import_common2.useAsyncCache)(this._serverDataVaultStoreValueCache, [id, key, options.secret], "store.useValue()");
1020
1079
  }
1021
1080
  };
1022
1081
  }