@stackframe/js 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 (43) 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/stack-app/apps/implementations/admin-app-impl.js +17 -28
  7. package/dist/esm/lib/stack-app/apps/implementations/admin-app-impl.js.map +1 -1
  8. package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.js +89 -24
  9. package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.js.map +1 -1
  10. package/dist/esm/lib/stack-app/apps/implementations/common.js +12 -3
  11. package/dist/esm/lib/stack-app/apps/implementations/common.js.map +1 -1
  12. package/dist/esm/lib/stack-app/apps/implementations/server-app-impl.js +107 -43
  13. package/dist/esm/lib/stack-app/apps/implementations/server-app-impl.js.map +1 -1
  14. package/dist/esm/lib/stack-app/apps/interfaces/admin-app.js.map +1 -1
  15. package/dist/esm/lib/stack-app/apps/interfaces/client-app.js.map +1 -1
  16. package/dist/esm/lib/stack-app/apps/interfaces/server-app.js.map +1 -1
  17. package/dist/esm/lib/stack-app/projects/index.js.map +1 -1
  18. package/dist/esm/lib/stack-app/users/index.js +16 -0
  19. package/dist/esm/lib/stack-app/users/index.js.map +1 -1
  20. package/dist/index.d.mts +86 -23
  21. package/dist/index.d.ts +86 -23
  22. package/dist/integrations/convex/component/convex.config.d.mts +5 -0
  23. package/dist/integrations/convex/component/convex.config.d.ts +5 -0
  24. package/dist/integrations/convex/component/convex.config.js +29 -0
  25. package/dist/integrations/convex/component/convex.config.js.map +1 -0
  26. package/dist/integrations/convex.js +4 -3
  27. package/dist/integrations/convex.js.map +1 -1
  28. package/dist/lib/stack-app/apps/implementations/admin-app-impl.js +16 -27
  29. package/dist/lib/stack-app/apps/implementations/admin-app-impl.js.map +1 -1
  30. package/dist/lib/stack-app/apps/implementations/client-app-impl.js +87 -22
  31. package/dist/lib/stack-app/apps/implementations/client-app-impl.js.map +1 -1
  32. package/dist/lib/stack-app/apps/implementations/common.js +14 -3
  33. package/dist/lib/stack-app/apps/implementations/common.js.map +1 -1
  34. package/dist/lib/stack-app/apps/implementations/server-app-impl.js +105 -41
  35. package/dist/lib/stack-app/apps/implementations/server-app-impl.js.map +1 -1
  36. package/dist/lib/stack-app/apps/interfaces/admin-app.js.map +1 -1
  37. package/dist/lib/stack-app/apps/interfaces/client-app.js.map +1 -1
  38. package/dist/lib/stack-app/apps/interfaces/server-app.js.map +1 -1
  39. package/dist/lib/stack-app/customers/index.js.map +1 -1
  40. package/dist/lib/stack-app/projects/index.js.map +1 -1
  41. package/dist/lib/stack-app/users/index.js +17 -0
  42. package/dist/lib/stack-app/users/index.js.map +1 -1
  43. package/package.json +12 -3
@@ -2,11 +2,12 @@
2
2
  import { AsyncCache } from "@stackframe/stack-shared/dist/utils/caches";
3
3
  import { isBrowserLike } from "@stackframe/stack-shared/dist/utils/env";
4
4
  import { StackAssertionError, throwErr } from "@stackframe/stack-shared/dist/utils/errors";
5
- import { filterUndefined } from "@stackframe/stack-shared/dist/utils/objects";
5
+ import { filterUndefined, omit } from "@stackframe/stack-shared/dist/utils/objects";
6
6
  import { Result } from "@stackframe/stack-shared/dist/utils/results";
7
7
  import { Store } from "@stackframe/stack-shared/dist/utils/stores";
8
+ import { stackAppInternalsSymbol } from "../../common.js";
8
9
  var process = globalThis.process ?? { env: {} };
9
- var clientVersion = "js @stackframe/js@2.8.41";
10
+ var clientVersion = "js @stackframe/js@2.8.44";
10
11
  if (clientVersion.startsWith("STACK_COMPILE_TIME")) {
11
12
  throw new StackAssertionError("Client version was not replaced. Something went wrong during build!");
12
13
  }
@@ -27,6 +28,12 @@ var createCacheBySession = (fetcher) => {
27
28
  }
28
29
  );
29
30
  };
31
+ function resolveConstructorOptions(options) {
32
+ return {
33
+ ...options.inheritsFrom?.[stackAppInternalsSymbol].getConstructorOptions() ?? {},
34
+ ...filterUndefined(omit(options, ["inheritsFrom"]))
35
+ };
36
+ }
30
37
  function getUrls(partial) {
31
38
  const handler = partial.handler ?? "/handler";
32
39
  const home = partial.home ?? "/";
@@ -101,12 +108,14 @@ export {
101
108
  createCache,
102
109
  createCacheBySession,
103
110
  createEmptyTokenStore,
111
+ defaultBaseUrl,
104
112
  getBaseUrl,
105
113
  getDefaultExtraRequestHeaders,
106
114
  getDefaultProjectId,
107
115
  getDefaultPublishableClientKey,
108
116
  getDefaultSecretServerKey,
109
117
  getDefaultSuperSecretAdminKey,
110
- getUrls
118
+ getUrls,
119
+ resolveConstructorOptions
111
120
  };
112
121
  //# 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 { HandlerUrls } from \"../../common\";\n\n// hack to make sure process is defined in non-node environments\nconst process = (globalThis as any).process ?? { env: {} }; // THIS_LINE_PLATFORM js react\n\nexport const clientVersion = \"js @stackframe/js@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\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 { 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 { HandlerUrls, stackAppInternalsSymbol } from \"../../common\";\n\n// hack to make sure process is defined in non-node environments\nconst process = (globalThis as any).process ?? { env: {} }; // THIS_LINE_PLATFORM js react\n\nexport const clientVersion = \"js @stackframe/js@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\n"],"mappings":"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","names":[]}
@@ -6,33 +6,22 @@ import { constructRedirectUrl } from "../../../../utils/url.js";
6
6
  import { apiKeyCreationOptionsToCrud, apiKeyUpdateOptionsToCrud } from "../../api-keys/index.js";
7
7
  import { serverContactChannelCreateOptionsToCrud, serverContactChannelUpdateOptionsToCrud } from "../../contact-channels/index.js";
8
8
  import { serverTeamCreateOptionsToCrud, serverTeamUpdateOptionsToCrud } from "../../teams/index.js";
9
- import { serverUserCreateOptionsToCrud, serverUserUpdateOptionsToCrud } from "../../users/index.js";
9
+ import { attachUserDestructureGuard, serverUserCreateOptionsToCrud, serverUserUpdateOptionsToCrud } from "../../users/index.js";
10
10
  import { _StackClientAppImplIncomplete } from "./client-app-impl.js";
11
- import { clientVersion, createCache, createCacheBySession, getBaseUrl, getDefaultExtraRequestHeaders, getDefaultProjectId, getDefaultPublishableClientKey, getDefaultSecretServerKey } from "./common.js";
11
+ import { clientVersion, createCache, createCacheBySession, getBaseUrl, getDefaultExtraRequestHeaders, getDefaultProjectId, getDefaultPublishableClientKey, getDefaultSecretServerKey, resolveConstructorOptions } from "./common.js";
12
12
  var _StackServerAppImplIncomplete = class extends _StackClientAppImplIncomplete {
13
- constructor(options) {
14
- super("interface" in options ? {
15
- interface: options.interface,
16
- tokenStore: options.tokenStore,
17
- urls: options.urls,
18
- oauthScopesOnSignIn: options.oauthScopesOnSignIn
19
- } : {
20
- interface: new StackServerInterface({
21
- getBaseUrl: () => getBaseUrl(options.baseUrl),
22
- projectId: options.projectId ?? getDefaultProjectId(),
23
- extraRequestHeaders: options.extraRequestHeaders ?? getDefaultExtraRequestHeaders(),
13
+ constructor(options, extraOptions) {
14
+ const resolvedOptions = resolveConstructorOptions(options);
15
+ super(resolvedOptions, {
16
+ ...extraOptions,
17
+ interface: extraOptions?.interface ?? new StackServerInterface({
18
+ getBaseUrl: () => getBaseUrl(resolvedOptions.baseUrl),
19
+ projectId: resolvedOptions.projectId ?? getDefaultProjectId(),
20
+ extraRequestHeaders: resolvedOptions.extraRequestHeaders ?? getDefaultExtraRequestHeaders(),
24
21
  clientVersion,
25
- publishableClientKey: options.publishableClientKey ?? getDefaultPublishableClientKey(),
26
- secretServerKey: options.secretServerKey ?? getDefaultSecretServerKey()
27
- }),
28
- baseUrl: options.baseUrl,
29
- extraRequestHeaders: options.extraRequestHeaders,
30
- projectId: options.projectId,
31
- publishableClientKey: options.publishableClientKey,
32
- tokenStore: options.tokenStore,
33
- urls: options.urls,
34
- oauthScopesOnSignIn: options.oauthScopesOnSignIn,
35
- redirectMethod: options.redirectMethod
22
+ publishableClientKey: resolvedOptions.publishableClientKey ?? getDefaultPublishableClientKey(),
23
+ secretServerKey: resolvedOptions.secretServerKey ?? getDefaultSecretServerKey()
24
+ })
36
25
  });
37
26
  // TODO override the client user cache to use the server user cache, so we save some requests
38
27
  this._currentServerUserCache = createCacheBySession(async (session) => {
@@ -161,6 +150,67 @@ var _StackServerAppImplIncomplete = class extends _StackClientAppImplIncomplete
161
150
  return await this._interface.getItem({ customCustomerId, itemId }, null);
162
151
  }
163
152
  );
153
+ this._serverUserProductsCache = createCache(
154
+ async ([userId, cursor, limit]) => {
155
+ return await this._interface.listProducts({
156
+ customer_type: "user",
157
+ customer_id: userId,
158
+ cursor: cursor ?? void 0,
159
+ limit: limit ?? void 0
160
+ }, null);
161
+ }
162
+ );
163
+ this._serverTeamProductsCache = createCache(
164
+ async ([teamId, cursor, limit]) => {
165
+ return await this._interface.listProducts({
166
+ customer_type: "team",
167
+ customer_id: teamId,
168
+ cursor: cursor ?? void 0,
169
+ limit: limit ?? void 0
170
+ }, null);
171
+ }
172
+ );
173
+ this._serverCustomProductsCache = createCache(
174
+ async ([customCustomerId, cursor, limit]) => {
175
+ return await this._interface.listProducts({
176
+ customer_type: "custom",
177
+ customer_id: customCustomerId,
178
+ cursor: cursor ?? void 0,
179
+ limit: limit ?? void 0
180
+ }, null);
181
+ }
182
+ );
183
+ }
184
+ _createServerCustomer(userIdOrTeamId, type) {
185
+ const app = this;
186
+ const productsCache = type === "user" ? app._serverUserProductsCache : app._serverTeamProductsCache;
187
+ const customerOptions = type === "user" ? { userId: userIdOrTeamId } : { teamId: userIdOrTeamId };
188
+ return {
189
+ ...this._createCustomer(userIdOrTeamId, type, null),
190
+ async getItem(itemId) {
191
+ return await app.getItem({ itemId, ...customerOptions });
192
+ },
193
+ async grantProduct(productOptions) {
194
+ if (type === "user") {
195
+ if ("productId" in productOptions) {
196
+ await app.grantProduct({ userId: userIdOrTeamId, productId: productOptions.productId, quantity: productOptions.quantity });
197
+ } else {
198
+ await app.grantProduct({ userId: userIdOrTeamId, product: productOptions.product, quantity: productOptions.quantity });
199
+ }
200
+ } else {
201
+ if ("productId" in productOptions) {
202
+ await app.grantProduct({ teamId: userIdOrTeamId, productId: productOptions.productId, quantity: productOptions.quantity });
203
+ } else {
204
+ await app.grantProduct({ teamId: userIdOrTeamId, product: productOptions.product, quantity: productOptions.quantity });
205
+ }
206
+ }
207
+ await productsCache.refresh([userIdOrTeamId, null, null]);
208
+ },
209
+ async createCheckoutUrl(options) {
210
+ const productIdOrInline = "productId" in options ? options.productId : options.product;
211
+ return await app._interface.createCheckoutUrl(type, userIdOrTeamId, productIdOrInline, null, options.returnUrl);
212
+ }
213
+ };
164
214
  }
165
215
  async _updateServerUser(userId, update) {
166
216
  const result = await this._interface.updateServerUser(userId, serverUserUpdateOptionsToCrud(update));
@@ -287,7 +337,7 @@ var _StackServerAppImplIncomplete = class extends _StackClientAppImplIncomplete
287
337
  const scopeString = options?.scopes?.join(" ");
288
338
  return Result.orThrow(await app._serverUserOAuthConnectionCache.getOrWait([crud.id, id, scopeString || "", options?.or === "redirect"], "write-only"));
289
339
  }
290
- return {
340
+ const serverUser = {
291
341
  ...super._createBaseUser(crud),
292
342
  lastActiveAt: new Date(crud.last_active_at_millis),
293
343
  serverMetadata: crud.server_metadata,
@@ -471,24 +521,21 @@ var _StackServerAppImplIncomplete = class extends _StackClientAppImplIncomplete
471
521
  const providers = await this.listOAuthProviders();
472
522
  return providers.find((p) => p.id === id) ?? null;
473
523
  },
474
- async createCheckoutUrl(options) {
475
- const offerIdOrInline = "offerId" in options ? options.offerId : options.offer;
476
- return await app._interface.createCheckoutUrl("user", crud.id, offerIdOrInline, null);
477
- },
478
- async getItem(itemId) {
479
- const result = Result.orThrow(await app._serverUserItemsCache.getOrWait([crud.id, itemId], "write-only"));
480
- return app._serverItemFromCrud({ type: "user", id: crud.id }, result);
481
- }
524
+ ...app._createServerCustomer(crud.id, "user")
482
525
  };
526
+ attachUserDestructureGuard(serverUser);
527
+ return serverUser;
483
528
  }
484
529
  _serverTeamUserFromCrud(crud) {
485
- return {
530
+ const teamUser = {
486
531
  ...this._serverUserFromCrud(crud.user),
487
532
  teamProfile: {
488
533
  displayName: crud.display_name,
489
534
  profileImageUrl: crud.profile_image_url
490
535
  }
491
536
  };
537
+ attachUserDestructureGuard(teamUser);
538
+ return teamUser;
492
539
  }
493
540
  _serverTeamInvitationFromCrud(crud) {
494
541
  return {
@@ -497,16 +544,17 @@ var _StackServerAppImplIncomplete = class extends _StackClientAppImplIncomplete
497
544
  expiresAt: new Date(crud.expires_at_millis),
498
545
  revoke: async () => {
499
546
  await this._interface.revokeServerTeamInvitation(crud.id, crud.team_id);
547
+ await this._serverTeamInvitationsCache.refresh([crud.team_id]);
500
548
  }
501
549
  };
502
550
  }
503
551
  _currentUserFromCrud(crud, session) {
504
- const app = this;
505
552
  const currentUser = {
506
553
  ...this._serverUserFromCrud(crud),
507
554
  ...this._createAuth(session),
508
555
  ...this._isInternalProject() ? this._createInternalUserExtra(session) : {}
509
556
  };
557
+ attachUserDestructureGuard(currentUser);
510
558
  Object.freeze(currentUser);
511
559
  return currentUser;
512
560
  }
@@ -571,14 +619,7 @@ var _StackServerAppImplIncomplete = class extends _StackClientAppImplIncomplete
571
619
  await app._serverTeamApiKeysCache.refresh([crud.id]);
572
620
  return app._serverApiKeyFromCrud(result);
573
621
  },
574
- async getItem(itemId) {
575
- const result = Result.orThrow(await app._serverTeamItemsCache.getOrWait([crud.id, itemId], "write-only"));
576
- return app._serverItemFromCrud({ type: "team", id: crud.id }, result);
577
- },
578
- async createCheckoutUrl(options) {
579
- const offerIdOrInline = "offerId" in options ? options.offerId : options.offer;
580
- return await app._interface.createCheckoutUrl("team", crud.id, offerIdOrInline, null);
581
- }
622
+ ...app._createServerCustomer(crud.id, "team")
582
623
  };
583
624
  }
584
625
  _serverItemFromCrud(customer, crud) {
@@ -743,6 +784,29 @@ var _StackServerAppImplIncomplete = class extends _StackClientAppImplIncomplete
743
784
  return this._serverItemFromCrud({ type: "custom", id: options.customCustomerId }, result);
744
785
  }
745
786
  }
787
+ async grantProduct(options) {
788
+ let customerType;
789
+ let customerId;
790
+ if ("userId" in options) {
791
+ customerType = "user";
792
+ customerId = options.userId;
793
+ } else if ("teamId" in options) {
794
+ customerType = "team";
795
+ customerId = options.teamId;
796
+ } else {
797
+ customerType = "custom";
798
+ customerId = options.customCustomerId;
799
+ }
800
+ await this._interface.grantProduct({
801
+ customerType,
802
+ customerId,
803
+ productId: "productId" in options ? options.productId : void 0,
804
+ product: "product" in options ? options.product : void 0,
805
+ quantity: options.quantity
806
+ });
807
+ const cache = customerType === "user" ? this._serverUserProductsCache : customerType === "team" ? this._serverTeamProductsCache : this._serverCustomProductsCache;
808
+ await cache.refresh([customerId, null, null]);
809
+ }
746
810
  async createTeam(data) {
747
811
  const team = await this._interface.createServerTeam(serverTeamCreateOptionsToCrud(data));
748
812
  await this._serverTeamsCache.refresh([void 0]);