@hexclave/js 1.0.0
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/LICENSE +7 -0
- package/README.md +26 -0
- package/dist/chunk-BE-pF4vm.js +34 -0
- package/dist/dev-tool/dev-tool-core.d.ts +7 -0
- package/dist/dev-tool/dev-tool-core.d.ts.map +1 -0
- package/dist/dev-tool/dev-tool-core.js +2116 -0
- package/dist/dev-tool/dev-tool-core.js.map +1 -0
- package/dist/dev-tool/dev-tool-styles.d.ts +5 -0
- package/dist/dev-tool/dev-tool-styles.d.ts.map +1 -0
- package/dist/dev-tool/dev-tool-styles.js +2757 -0
- package/dist/dev-tool/dev-tool-styles.js.map +1 -0
- package/dist/dev-tool/dev-tool-trigger-position.d.ts +36 -0
- package/dist/dev-tool/dev-tool-trigger-position.d.ts.map +1 -0
- package/dist/dev-tool/dev-tool-trigger-position.js +70 -0
- package/dist/dev-tool/dev-tool-trigger-position.js.map +1 -0
- package/dist/dev-tool/dev-tool-trigger-position.test.d.ts +1 -0
- package/dist/dev-tool/dev-tool-trigger-position.test.js +155 -0
- package/dist/dev-tool/dev-tool-trigger-position.test.js.map +1 -0
- package/dist/dev-tool/index.d.ts +19 -0
- package/dist/dev-tool/index.d.ts.map +1 -0
- package/dist/dev-tool/index.js +119 -0
- package/dist/dev-tool/index.js.map +1 -0
- package/dist/esm/dev-tool/dev-tool-core.d.ts +7 -0
- package/dist/esm/dev-tool/dev-tool-core.d.ts.map +1 -0
- package/dist/esm/dev-tool/dev-tool-core.js +2114 -0
- package/dist/esm/dev-tool/dev-tool-core.js.map +1 -0
- package/dist/esm/dev-tool/dev-tool-styles.d.ts +5 -0
- package/dist/esm/dev-tool/dev-tool-styles.d.ts.map +1 -0
- package/dist/esm/dev-tool/dev-tool-styles.js +2755 -0
- package/dist/esm/dev-tool/dev-tool-styles.js.map +1 -0
- package/dist/esm/dev-tool/dev-tool-trigger-position.d.ts +36 -0
- package/dist/esm/dev-tool/dev-tool-trigger-position.d.ts.map +1 -0
- package/dist/esm/dev-tool/dev-tool-trigger-position.js +65 -0
- package/dist/esm/dev-tool/dev-tool-trigger-position.js.map +1 -0
- package/dist/esm/dev-tool/dev-tool-trigger-position.test.d.ts +1 -0
- package/dist/esm/dev-tool/dev-tool-trigger-position.test.js +155 -0
- package/dist/esm/dev-tool/dev-tool-trigger-position.test.js.map +1 -0
- package/dist/esm/dev-tool/index.d.ts +19 -0
- package/dist/esm/dev-tool/index.d.ts.map +1 -0
- package/dist/esm/dev-tool/index.js +117 -0
- package/dist/esm/dev-tool/index.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/integrations/convex/component/convex.config.d.ts +7 -0
- package/dist/esm/integrations/convex/component/convex.config.d.ts.map +1 -0
- package/dist/esm/integrations/convex/component/convex.config.js +8 -0
- package/dist/esm/integrations/convex/component/convex.config.js.map +1 -0
- package/dist/esm/integrations/convex.d.ts +13 -0
- package/dist/esm/integrations/convex.d.ts.map +1 -0
- package/dist/esm/integrations/convex.js +23 -0
- package/dist/esm/integrations/convex.js.map +1 -0
- package/dist/esm/internal/deprecation-warning.d.ts +1 -0
- package/dist/esm/internal/deprecation-warning.js +24 -0
- package/dist/esm/internal/deprecation-warning.js.map +1 -0
- package/dist/esm/lib/auth.d.ts +31 -0
- package/dist/esm/lib/auth.d.ts.map +1 -0
- package/dist/esm/lib/auth.js +108 -0
- package/dist/esm/lib/auth.js.map +1 -0
- package/dist/esm/lib/auth.test.d.ts +1 -0
- package/dist/esm/lib/auth.test.js +60 -0
- package/dist/esm/lib/auth.test.js.map +1 -0
- package/dist/esm/lib/cookie.d.ts +42 -0
- package/dist/esm/lib/cookie.d.ts.map +1 -0
- package/dist/esm/lib/cookie.js +287 -0
- package/dist/esm/lib/cookie.js.map +1 -0
- package/dist/esm/lib/env.d.ts +42 -0
- package/dist/esm/lib/env.d.ts.map +1 -0
- package/dist/esm/lib/env.js +93 -0
- package/dist/esm/lib/env.js.map +1 -0
- package/dist/esm/lib/stack-app/api-keys/index.d.ts +53 -0
- package/dist/esm/lib/stack-app/api-keys/index.d.ts.map +1 -0
- package/dist/esm/lib/stack-app/api-keys/index.js +22 -0
- package/dist/esm/lib/stack-app/api-keys/index.js.map +1 -0
- package/dist/esm/lib/stack-app/apps/implementations/admin-app-impl.d.ts +364 -0
- package/dist/esm/lib/stack-app/apps/implementations/admin-app-impl.d.ts.map +1 -0
- package/dist/esm/lib/stack-app/apps/implementations/admin-app-impl.js +924 -0
- package/dist/esm/lib/stack-app/apps/implementations/admin-app-impl.js.map +1 -0
- package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.cross-domain.test.d.ts +1 -0
- package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.cross-domain.test.js +55 -0
- package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.cross-domain.test.js.map +1 -0
- package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.d.ts +542 -0
- package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.d.ts.map +1 -0
- package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.js +2504 -0
- package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.js.map +1 -0
- package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.oauth-prefetch.test.d.ts +1 -0
- package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.oauth-prefetch.test.js +32 -0
- package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.oauth-prefetch.test.js.map +1 -0
- package/dist/esm/lib/stack-app/apps/implementations/common.d.ts +65 -0
- package/dist/esm/lib/stack-app/apps/implementations/common.d.ts.map +1 -0
- package/dist/esm/lib/stack-app/apps/implementations/common.js +127 -0
- package/dist/esm/lib/stack-app/apps/implementations/common.js.map +1 -0
- package/dist/esm/lib/stack-app/apps/implementations/event-tracker.d.ts +42 -0
- package/dist/esm/lib/stack-app/apps/implementations/event-tracker.d.ts.map +1 -0
- package/dist/esm/lib/stack-app/apps/implementations/event-tracker.js +211 -0
- package/dist/esm/lib/stack-app/apps/implementations/event-tracker.js.map +1 -0
- package/dist/esm/lib/stack-app/apps/implementations/event-tracker.test.d.ts +1 -0
- package/dist/esm/lib/stack-app/apps/implementations/event-tracker.test.js +87 -0
- package/dist/esm/lib/stack-app/apps/implementations/event-tracker.test.js.map +1 -0
- package/dist/esm/lib/stack-app/apps/implementations/index.d.ts +9 -0
- package/dist/esm/lib/stack-app/apps/implementations/index.d.ts.map +1 -0
- package/dist/esm/lib/stack-app/apps/implementations/index.js +27 -0
- package/dist/esm/lib/stack-app/apps/implementations/index.js.map +1 -0
- package/dist/esm/lib/stack-app/apps/implementations/redirect-page-urls.d.ts +35 -0
- package/dist/esm/lib/stack-app/apps/implementations/redirect-page-urls.d.ts.map +1 -0
- package/dist/esm/lib/stack-app/apps/implementations/redirect-page-urls.js +197 -0
- package/dist/esm/lib/stack-app/apps/implementations/redirect-page-urls.js.map +1 -0
- package/dist/esm/lib/stack-app/apps/implementations/server-app-impl.d.ts +203 -0
- package/dist/esm/lib/stack-app/apps/implementations/server-app-impl.d.ts.map +1 -0
- package/dist/esm/lib/stack-app/apps/implementations/server-app-impl.js +1094 -0
- package/dist/esm/lib/stack-app/apps/implementations/server-app-impl.js.map +1 -0
- package/dist/esm/lib/stack-app/apps/implementations/session-refresh-subscription.d.ts +28 -0
- package/dist/esm/lib/stack-app/apps/implementations/session-refresh-subscription.d.ts.map +1 -0
- package/dist/esm/lib/stack-app/apps/implementations/session-refresh-subscription.js +31 -0
- package/dist/esm/lib/stack-app/apps/implementations/session-refresh-subscription.js.map +1 -0
- package/dist/esm/lib/stack-app/apps/implementations/session-refresh-subscription.test.d.ts +1 -0
- package/dist/esm/lib/stack-app/apps/implementations/session-refresh-subscription.test.js +82 -0
- package/dist/esm/lib/stack-app/apps/implementations/session-refresh-subscription.test.js.map +1 -0
- package/dist/esm/lib/stack-app/apps/implementations/session-replay.d.ts +111 -0
- package/dist/esm/lib/stack-app/apps/implementations/session-replay.d.ts.map +1 -0
- package/dist/esm/lib/stack-app/apps/implementations/session-replay.js +241 -0
- package/dist/esm/lib/stack-app/apps/implementations/session-replay.js.map +1 -0
- package/dist/esm/lib/stack-app/apps/implementations/session-replay.test.d.ts +1 -0
- package/dist/esm/lib/stack-app/apps/implementations/session-replay.test.js +29 -0
- package/dist/esm/lib/stack-app/apps/implementations/session-replay.test.js.map +1 -0
- package/dist/esm/lib/stack-app/apps/index.d.ts +4 -0
- package/dist/esm/lib/stack-app/apps/index.js +5 -0
- package/dist/esm/lib/stack-app/apps/interfaces/admin-app.d.ts +244 -0
- package/dist/esm/lib/stack-app/apps/interfaces/admin-app.d.ts.map +1 -0
- package/dist/esm/lib/stack-app/apps/interfaces/admin-app.js +9 -0
- package/dist/esm/lib/stack-app/apps/interfaces/admin-app.js.map +1 -0
- package/dist/esm/lib/stack-app/apps/interfaces/client-app.d.ts +208 -0
- package/dist/esm/lib/stack-app/apps/interfaces/client-app.d.ts.map +1 -0
- package/dist/esm/lib/stack-app/apps/interfaces/client-app.js +9 -0
- package/dist/esm/lib/stack-app/apps/interfaces/client-app.js.map +1 -0
- package/dist/esm/lib/stack-app/apps/interfaces/server-app.d.ts +116 -0
- package/dist/esm/lib/stack-app/apps/interfaces/server-app.d.ts.map +1 -0
- package/dist/esm/lib/stack-app/apps/interfaces/server-app.js +9 -0
- package/dist/esm/lib/stack-app/apps/interfaces/server-app.js.map +1 -0
- package/dist/esm/lib/stack-app/common.d.ts +174 -0
- package/dist/esm/lib/stack-app/common.d.ts.map +1 -0
- package/dist/esm/lib/stack-app/common.js +7 -0
- package/dist/esm/lib/stack-app/common.js.map +1 -0
- package/dist/esm/lib/stack-app/connected-accounts/index.d.ts +40 -0
- package/dist/esm/lib/stack-app/connected-accounts/index.d.ts.map +1 -0
- package/dist/esm/lib/stack-app/connected-accounts/index.js +1 -0
- package/dist/esm/lib/stack-app/contact-channels/index.d.ts +43 -0
- package/dist/esm/lib/stack-app/contact-channels/index.d.ts.map +1 -0
- package/dist/esm/lib/stack-app/contact-channels/index.js +39 -0
- package/dist/esm/lib/stack-app/contact-channels/index.js.map +1 -0
- package/dist/esm/lib/stack-app/customers/index.d.ts +129 -0
- package/dist/esm/lib/stack-app/customers/index.d.ts.map +1 -0
- package/dist/esm/lib/stack-app/customers/index.js +1 -0
- package/dist/esm/lib/stack-app/data-vault/index.d.ts +14 -0
- package/dist/esm/lib/stack-app/data-vault/index.d.ts.map +1 -0
- package/dist/esm/lib/stack-app/data-vault/index.js +1 -0
- package/dist/esm/lib/stack-app/email/index.d.ts +204 -0
- package/dist/esm/lib/stack-app/email/index.d.ts.map +1 -0
- package/dist/esm/lib/stack-app/email/index.js +1 -0
- package/dist/esm/lib/stack-app/email-templates/index.d.ts +17 -0
- package/dist/esm/lib/stack-app/email-templates/index.d.ts.map +1 -0
- package/dist/esm/lib/stack-app/email-templates/index.js +11 -0
- package/dist/esm/lib/stack-app/email-templates/index.js.map +1 -0
- package/dist/esm/lib/stack-app/index.d.ts +14 -0
- package/dist/esm/lib/stack-app/index.js +5 -0
- package/dist/esm/lib/stack-app/internal-api-keys/index.d.ts +42 -0
- package/dist/esm/lib/stack-app/internal-api-keys/index.d.ts.map +1 -0
- package/dist/esm/lib/stack-app/internal-api-keys/index.js +14 -0
- package/dist/esm/lib/stack-app/internal-api-keys/index.js.map +1 -0
- package/dist/esm/lib/stack-app/notification-categories/index.d.ts +11 -0
- package/dist/esm/lib/stack-app/notification-categories/index.d.ts.map +1 -0
- package/dist/esm/lib/stack-app/notification-categories/index.js +1 -0
- package/dist/esm/lib/stack-app/permissions/index.d.ts +43 -0
- package/dist/esm/lib/stack-app/permissions/index.d.ts.map +1 -0
- package/dist/esm/lib/stack-app/permissions/index.js +31 -0
- package/dist/esm/lib/stack-app/permissions/index.js.map +1 -0
- package/dist/esm/lib/stack-app/project-configs/index.d.ts +99 -0
- package/dist/esm/lib/stack-app/project-configs/index.d.ts.map +1 -0
- package/dist/esm/lib/stack-app/project-configs/index.js +1 -0
- package/dist/esm/lib/stack-app/projects/index.d.ts +145 -0
- package/dist/esm/lib/stack-app/projects/index.d.ts.map +1 -0
- package/dist/esm/lib/stack-app/projects/index.js +66 -0
- package/dist/esm/lib/stack-app/projects/index.js.map +1 -0
- package/dist/esm/lib/stack-app/session-replays/index.d.ts +66 -0
- package/dist/esm/lib/stack-app/session-replays/index.d.ts.map +1 -0
- package/dist/esm/lib/stack-app/session-replays/index.js +1 -0
- package/dist/esm/lib/stack-app/teams/index.d.ts +160 -0
- package/dist/esm/lib/stack-app/teams/index.d.ts.map +1 -0
- package/dist/esm/lib/stack-app/teams/index.js +35 -0
- package/dist/esm/lib/stack-app/teams/index.js.map +1 -0
- package/dist/esm/lib/stack-app/url-targets.d.ts +39 -0
- package/dist/esm/lib/stack-app/url-targets.d.ts.map +1 -0
- package/dist/esm/lib/stack-app/url-targets.js +266 -0
- package/dist/esm/lib/stack-app/url-targets.js.map +1 -0
- package/dist/esm/lib/stack-app/url-targets.test.d.ts +1 -0
- package/dist/esm/lib/stack-app/url-targets.test.js +213 -0
- package/dist/esm/lib/stack-app/url-targets.test.js.map +1 -0
- package/dist/esm/lib/stack-app/users/index.d.ts +357 -0
- package/dist/esm/lib/stack-app/users/index.d.ts.map +1 -0
- package/dist/esm/lib/stack-app/users/index.js +71 -0
- package/dist/esm/lib/stack-app/users/index.js.map +1 -0
- package/dist/esm/utils/url.d.ts +5 -0
- package/dist/esm/utils/url.d.ts.map +1 -0
- package/dist/esm/utils/url.js +16 -0
- package/dist/esm/utils/url.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +31 -0
- package/dist/integrations/convex/component/convex.config.d.ts +61 -0
- package/dist/integrations/convex/component/convex.config.d.ts.map +1 -0
- package/dist/integrations/convex/component/convex.config.js +9 -0
- package/dist/integrations/convex/component/convex.config.js.map +1 -0
- package/dist/integrations/convex.d.ts +13 -0
- package/dist/integrations/convex.d.ts.map +1 -0
- package/dist/integrations/convex.js +25 -0
- package/dist/integrations/convex.js.map +1 -0
- package/dist/internal/deprecation-warning.d.ts +1 -0
- package/dist/internal/deprecation-warning.js +24 -0
- package/dist/internal/deprecation-warning.js.map +1 -0
- package/dist/lib/auth.d.ts +31 -0
- package/dist/lib/auth.d.ts.map +1 -0
- package/dist/lib/auth.js +111 -0
- package/dist/lib/auth.js.map +1 -0
- package/dist/lib/auth.test.d.ts +1 -0
- package/dist/lib/auth.test.js +60 -0
- package/dist/lib/auth.test.js.map +1 -0
- package/dist/lib/cookie.d.ts +42 -0
- package/dist/lib/cookie.d.ts.map +1 -0
- package/dist/lib/cookie.js +305 -0
- package/dist/lib/cookie.js.map +1 -0
- package/dist/lib/env.d.ts +42 -0
- package/dist/lib/env.d.ts.map +1 -0
- package/dist/lib/env.js +95 -0
- package/dist/lib/env.js.map +1 -0
- package/dist/lib/stack-app/api-keys/index.d.ts +53 -0
- package/dist/lib/stack-app/api-keys/index.d.ts.map +1 -0
- package/dist/lib/stack-app/api-keys/index.js +25 -0
- package/dist/lib/stack-app/api-keys/index.js.map +1 -0
- package/dist/lib/stack-app/apps/implementations/admin-app-impl.d.ts +362 -0
- package/dist/lib/stack-app/apps/implementations/admin-app-impl.d.ts.map +1 -0
- package/dist/lib/stack-app/apps/implementations/admin-app-impl.js +926 -0
- package/dist/lib/stack-app/apps/implementations/admin-app-impl.js.map +1 -0
- package/dist/lib/stack-app/apps/implementations/client-app-impl.cross-domain.test.d.ts +1 -0
- package/dist/lib/stack-app/apps/implementations/client-app-impl.cross-domain.test.js +55 -0
- package/dist/lib/stack-app/apps/implementations/client-app-impl.cross-domain.test.js.map +1 -0
- package/dist/lib/stack-app/apps/implementations/client-app-impl.d.ts +541 -0
- package/dist/lib/stack-app/apps/implementations/client-app-impl.d.ts.map +1 -0
- package/dist/lib/stack-app/apps/implementations/client-app-impl.js +2507 -0
- package/dist/lib/stack-app/apps/implementations/client-app-impl.js.map +1 -0
- package/dist/lib/stack-app/apps/implementations/client-app-impl.oauth-prefetch.test.d.ts +1 -0
- package/dist/lib/stack-app/apps/implementations/client-app-impl.oauth-prefetch.test.js +32 -0
- package/dist/lib/stack-app/apps/implementations/client-app-impl.oauth-prefetch.test.js.map +1 -0
- package/dist/lib/stack-app/apps/implementations/common.d.ts +65 -0
- package/dist/lib/stack-app/apps/implementations/common.d.ts.map +1 -0
- package/dist/lib/stack-app/apps/implementations/common.js +144 -0
- package/dist/lib/stack-app/apps/implementations/common.js.map +1 -0
- package/dist/lib/stack-app/apps/implementations/event-tracker.d.ts +42 -0
- package/dist/lib/stack-app/apps/implementations/event-tracker.d.ts.map +1 -0
- package/dist/lib/stack-app/apps/implementations/event-tracker.js +213 -0
- package/dist/lib/stack-app/apps/implementations/event-tracker.js.map +1 -0
- package/dist/lib/stack-app/apps/implementations/event-tracker.test.d.ts +1 -0
- package/dist/lib/stack-app/apps/implementations/event-tracker.test.js +87 -0
- package/dist/lib/stack-app/apps/implementations/event-tracker.test.js.map +1 -0
- package/dist/lib/stack-app/apps/implementations/index.d.ts +9 -0
- package/dist/lib/stack-app/apps/implementations/index.d.ts.map +1 -0
- package/dist/lib/stack-app/apps/implementations/index.js +31 -0
- package/dist/lib/stack-app/apps/implementations/index.js.map +1 -0
- package/dist/lib/stack-app/apps/implementations/redirect-page-urls.d.ts +35 -0
- package/dist/lib/stack-app/apps/implementations/redirect-page-urls.d.ts.map +1 -0
- package/dist/lib/stack-app/apps/implementations/redirect-page-urls.js +201 -0
- package/dist/lib/stack-app/apps/implementations/redirect-page-urls.js.map +1 -0
- package/dist/lib/stack-app/apps/implementations/server-app-impl.d.ts +203 -0
- package/dist/lib/stack-app/apps/implementations/server-app-impl.d.ts.map +1 -0
- package/dist/lib/stack-app/apps/implementations/server-app-impl.js +1096 -0
- package/dist/lib/stack-app/apps/implementations/server-app-impl.js.map +1 -0
- package/dist/lib/stack-app/apps/implementations/session-refresh-subscription.d.ts +28 -0
- package/dist/lib/stack-app/apps/implementations/session-refresh-subscription.d.ts.map +1 -0
- package/dist/lib/stack-app/apps/implementations/session-refresh-subscription.js +33 -0
- package/dist/lib/stack-app/apps/implementations/session-refresh-subscription.js.map +1 -0
- package/dist/lib/stack-app/apps/implementations/session-refresh-subscription.test.d.ts +1 -0
- package/dist/lib/stack-app/apps/implementations/session-refresh-subscription.test.js +82 -0
- package/dist/lib/stack-app/apps/implementations/session-refresh-subscription.test.js.map +1 -0
- package/dist/lib/stack-app/apps/implementations/session-replay.d.ts +111 -0
- package/dist/lib/stack-app/apps/implementations/session-replay.d.ts.map +1 -0
- package/dist/lib/stack-app/apps/implementations/session-replay.js +250 -0
- package/dist/lib/stack-app/apps/implementations/session-replay.js.map +1 -0
- package/dist/lib/stack-app/apps/implementations/session-replay.test.d.ts +1 -0
- package/dist/lib/stack-app/apps/implementations/session-replay.test.js +29 -0
- package/dist/lib/stack-app/apps/implementations/session-replay.test.js.map +1 -0
- package/dist/lib/stack-app/apps/index.d.ts +4 -0
- package/dist/lib/stack-app/apps/index.js +42 -0
- package/dist/lib/stack-app/apps/interfaces/admin-app.d.ts +244 -0
- package/dist/lib/stack-app/apps/interfaces/admin-app.d.ts.map +1 -0
- package/dist/lib/stack-app/apps/interfaces/admin-app.js +12 -0
- package/dist/lib/stack-app/apps/interfaces/admin-app.js.map +1 -0
- package/dist/lib/stack-app/apps/interfaces/client-app.d.ts +208 -0
- package/dist/lib/stack-app/apps/interfaces/client-app.d.ts.map +1 -0
- package/dist/lib/stack-app/apps/interfaces/client-app.js +12 -0
- package/dist/lib/stack-app/apps/interfaces/client-app.js.map +1 -0
- package/dist/lib/stack-app/apps/interfaces/server-app.d.ts +116 -0
- package/dist/lib/stack-app/apps/interfaces/server-app.d.ts.map +1 -0
- package/dist/lib/stack-app/apps/interfaces/server-app.js +12 -0
- package/dist/lib/stack-app/apps/interfaces/server-app.js.map +1 -0
- package/dist/lib/stack-app/common.d.ts +174 -0
- package/dist/lib/stack-app/common.d.ts.map +1 -0
- package/dist/lib/stack-app/common.js +9 -0
- package/dist/lib/stack-app/common.js.map +1 -0
- package/dist/lib/stack-app/connected-accounts/index.d.ts +40 -0
- package/dist/lib/stack-app/connected-accounts/index.d.ts.map +1 -0
- package/dist/lib/stack-app/connected-accounts/index.js +0 -0
- package/dist/lib/stack-app/contact-channels/index.d.ts +43 -0
- package/dist/lib/stack-app/contact-channels/index.d.ts.map +1 -0
- package/dist/lib/stack-app/contact-channels/index.js +44 -0
- package/dist/lib/stack-app/contact-channels/index.js.map +1 -0
- package/dist/lib/stack-app/customers/index.d.ts +129 -0
- package/dist/lib/stack-app/customers/index.d.ts.map +1 -0
- package/dist/lib/stack-app/customers/index.js +0 -0
- package/dist/lib/stack-app/data-vault/index.d.ts +14 -0
- package/dist/lib/stack-app/data-vault/index.d.ts.map +1 -0
- package/dist/lib/stack-app/data-vault/index.js +0 -0
- package/dist/lib/stack-app/email/index.d.ts +204 -0
- package/dist/lib/stack-app/email/index.d.ts.map +1 -0
- package/dist/lib/stack-app/email/index.js +0 -0
- package/dist/lib/stack-app/email-templates/index.d.ts +17 -0
- package/dist/lib/stack-app/email-templates/index.d.ts.map +1 -0
- package/dist/lib/stack-app/email-templates/index.js +13 -0
- package/dist/lib/stack-app/email-templates/index.js.map +1 -0
- package/dist/lib/stack-app/index.d.ts +15 -0
- package/dist/lib/stack-app/index.js +54 -0
- package/dist/lib/stack-app/internal-api-keys/index.d.ts +42 -0
- package/dist/lib/stack-app/internal-api-keys/index.d.ts.map +1 -0
- package/dist/lib/stack-app/internal-api-keys/index.js +16 -0
- package/dist/lib/stack-app/internal-api-keys/index.js.map +1 -0
- package/dist/lib/stack-app/notification-categories/index.d.ts +11 -0
- package/dist/lib/stack-app/notification-categories/index.d.ts.map +1 -0
- package/dist/lib/stack-app/notification-categories/index.js +0 -0
- package/dist/lib/stack-app/permissions/index.d.ts +43 -0
- package/dist/lib/stack-app/permissions/index.d.ts.map +1 -0
- package/dist/lib/stack-app/permissions/index.js +36 -0
- package/dist/lib/stack-app/permissions/index.js.map +1 -0
- package/dist/lib/stack-app/project-configs/index.d.ts +99 -0
- package/dist/lib/stack-app/project-configs/index.d.ts.map +1 -0
- package/dist/lib/stack-app/project-configs/index.js +0 -0
- package/dist/lib/stack-app/projects/index.d.ts +145 -0
- package/dist/lib/stack-app/projects/index.d.ts.map +1 -0
- package/dist/lib/stack-app/projects/index.js +69 -0
- package/dist/lib/stack-app/projects/index.js.map +1 -0
- package/dist/lib/stack-app/session-replays/index.d.ts +66 -0
- package/dist/lib/stack-app/session-replays/index.d.ts.map +1 -0
- package/dist/lib/stack-app/session-replays/index.js +0 -0
- package/dist/lib/stack-app/teams/index.d.ts +160 -0
- package/dist/lib/stack-app/teams/index.d.ts.map +1 -0
- package/dist/lib/stack-app/teams/index.js +40 -0
- package/dist/lib/stack-app/teams/index.js.map +1 -0
- package/dist/lib/stack-app/url-targets.d.ts +39 -0
- package/dist/lib/stack-app/url-targets.d.ts.map +1 -0
- package/dist/lib/stack-app/url-targets.js +274 -0
- package/dist/lib/stack-app/url-targets.js.map +1 -0
- package/dist/lib/stack-app/url-targets.test.d.ts +1 -0
- package/dist/lib/stack-app/url-targets.test.js +213 -0
- package/dist/lib/stack-app/url-targets.test.js.map +1 -0
- package/dist/lib/stack-app/users/index.d.ts +357 -0
- package/dist/lib/stack-app/users/index.d.ts.map +1 -0
- package/dist/lib/stack-app/users/index.js +76 -0
- package/dist/lib/stack-app/users/index.js.map +1 -0
- package/dist/storage-CKsyME2q.d.ts +1912 -0
- package/dist/storage-CKsyME2q.d.ts.map +1 -0
- package/dist/utils/url.d.ts +5 -0
- package/dist/utils/url.d.ts.map +1 -0
- package/dist/utils/url.js +18 -0
- package/dist/utils/url.js.map +1 -0
- package/package.json +88 -0
|
@@ -0,0 +1,1094 @@
|
|
|
1
|
+
import { HexclaveAssertionError, captureError, throwErr } from "@hexclave/shared/dist/utils/errors";
|
|
2
|
+
import { HexclaveServerInterface, KnownErrors } from "@hexclave/shared";
|
|
3
|
+
import { Result } from "@hexclave/shared/dist/utils/results";
|
|
4
|
+
import { clientVersion, createCache, createCacheBySession, getDefaultExtraRequestHeaders, getDefaultProjectId, getDefaultPublishableClientKey, getDefaultSecretServerKey, resolveApiUrls, resolveConstructorOptions } from "./common.js";
|
|
5
|
+
import { WebAuthnError, startRegistration } from "@simplewebauthn/browser";
|
|
6
|
+
import { InternalSession } from "@hexclave/shared/dist/sessions";
|
|
7
|
+
import { constructRedirectUrl } from "../../../../utils/url.js";
|
|
8
|
+
import { apiKeyCreationOptionsToCrud, apiKeyUpdateOptionsToCrud } from "../../api-keys/index.js";
|
|
9
|
+
import { serverContactChannelCreateOptionsToCrud, serverContactChannelUpdateOptionsToCrud } from "../../contact-channels/index.js";
|
|
10
|
+
import { serverTeamCreateOptionsToCrud, serverTeamUpdateOptionsToCrud } from "../../teams/index.js";
|
|
11
|
+
import { serverUserCreateOptionsToCrud, serverUserUpdateOptionsToCrud, withUserDestructureGuard } from "../../users/index.js";
|
|
12
|
+
import { _StackClientAppImplIncomplete } from "./client-app-impl.js";
|
|
13
|
+
|
|
14
|
+
//#region src/lib/stack-app/apps/implementations/server-app-impl.ts
|
|
15
|
+
var _StackServerAppImplIncomplete = class extends _StackClientAppImplIncomplete {
|
|
16
|
+
async _refreshTeamMembership(teamId, userId) {
|
|
17
|
+
await Promise.all([
|
|
18
|
+
this._serverTeamMemberProfilesCache.refresh([teamId]),
|
|
19
|
+
this._serverTeamsCache.refreshWhere(([u]) => u === userId || u === void 0),
|
|
20
|
+
this._serverUsersCache.refreshWhere((key) => key[8] === teamId)
|
|
21
|
+
]);
|
|
22
|
+
}
|
|
23
|
+
_createServerCustomer(userIdOrTeamId, type) {
|
|
24
|
+
const app = this;
|
|
25
|
+
const productsCache = type === "user" ? app._serverUserProductsCache : app._serverTeamProductsCache;
|
|
26
|
+
const customerOptions = type === "user" ? { userId: userIdOrTeamId } : { teamId: userIdOrTeamId };
|
|
27
|
+
return {
|
|
28
|
+
...this._createCustomer(userIdOrTeamId, type, null),
|
|
29
|
+
async getItem(itemId) {
|
|
30
|
+
return await app.getItem({
|
|
31
|
+
itemId,
|
|
32
|
+
...customerOptions
|
|
33
|
+
});
|
|
34
|
+
},
|
|
35
|
+
async grantProduct(productOptions) {
|
|
36
|
+
if (type === "user") if ("productId" in productOptions) await app.grantProduct({
|
|
37
|
+
userId: userIdOrTeamId,
|
|
38
|
+
productId: productOptions.productId,
|
|
39
|
+
quantity: productOptions.quantity
|
|
40
|
+
});
|
|
41
|
+
else await app.grantProduct({
|
|
42
|
+
userId: userIdOrTeamId,
|
|
43
|
+
product: productOptions.product,
|
|
44
|
+
quantity: productOptions.quantity
|
|
45
|
+
});
|
|
46
|
+
else if ("productId" in productOptions) await app.grantProduct({
|
|
47
|
+
teamId: userIdOrTeamId,
|
|
48
|
+
productId: productOptions.productId,
|
|
49
|
+
quantity: productOptions.quantity
|
|
50
|
+
});
|
|
51
|
+
else await app.grantProduct({
|
|
52
|
+
teamId: userIdOrTeamId,
|
|
53
|
+
product: productOptions.product,
|
|
54
|
+
quantity: productOptions.quantity
|
|
55
|
+
});
|
|
56
|
+
await productsCache.refresh([
|
|
57
|
+
userIdOrTeamId,
|
|
58
|
+
null,
|
|
59
|
+
null
|
|
60
|
+
]);
|
|
61
|
+
},
|
|
62
|
+
async createCheckoutUrl(options) {
|
|
63
|
+
const productIdOrInline = "productId" in options ? options.productId : options.product;
|
|
64
|
+
return await app._interface.createCheckoutUrl(type, userIdOrTeamId, productIdOrInline, null, options.returnUrl, "server");
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
async _updateServerUser(userId, update) {
|
|
69
|
+
const result = await this._interface.updateServerUser(userId, serverUserUpdateOptionsToCrud(update));
|
|
70
|
+
await this._refreshUsers();
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
_serverEditableTeamProfileFromCrud(crud) {
|
|
74
|
+
const app = this;
|
|
75
|
+
return {
|
|
76
|
+
displayName: crud.display_name,
|
|
77
|
+
profileImageUrl: crud.profile_image_url,
|
|
78
|
+
async update(update) {
|
|
79
|
+
await app._interface.updateServerTeamMemberProfile({
|
|
80
|
+
teamId: crud.team_id,
|
|
81
|
+
userId: crud.user_id,
|
|
82
|
+
profile: {
|
|
83
|
+
display_name: update.displayName,
|
|
84
|
+
profile_image_url: update.profileImageUrl
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
await app._serverUserTeamProfileCache.refresh([crud.team_id, crud.user_id]);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
_serverContactChannelFromCrud(userId, crud) {
|
|
92
|
+
const app = this;
|
|
93
|
+
return {
|
|
94
|
+
id: crud.id,
|
|
95
|
+
value: crud.value,
|
|
96
|
+
type: crud.type,
|
|
97
|
+
isVerified: crud.is_verified,
|
|
98
|
+
isPrimary: crud.is_primary,
|
|
99
|
+
usedForAuth: crud.used_for_auth,
|
|
100
|
+
async sendVerificationEmail(options) {
|
|
101
|
+
await app._interface.sendServerContactChannelVerificationEmail(userId, crud.id, options?.callbackUrl ?? constructRedirectUrl(app.urls.emailVerification, "callbackUrl"));
|
|
102
|
+
},
|
|
103
|
+
async update(data) {
|
|
104
|
+
await app._interface.updateServerContactChannel(userId, crud.id, serverContactChannelUpdateOptionsToCrud(data));
|
|
105
|
+
await Promise.all([app._serverContactChannelsCache.refresh([userId]), app._serverUserCache.refresh([userId])]);
|
|
106
|
+
},
|
|
107
|
+
async delete() {
|
|
108
|
+
await app._interface.deleteServerContactChannel(userId, crud.id);
|
|
109
|
+
await Promise.all([app._serverContactChannelsCache.refresh([userId]), app._serverUserCache.refresh([userId])]);
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
_serverNotificationCategoryFromCrud(userId, crud) {
|
|
114
|
+
const app = this;
|
|
115
|
+
return {
|
|
116
|
+
id: crud.notification_category_id,
|
|
117
|
+
name: crud.notification_category_name,
|
|
118
|
+
enabled: crud.enabled,
|
|
119
|
+
canDisable: crud.can_disable,
|
|
120
|
+
async setEnabled(enabled) {
|
|
121
|
+
await app._interface.setServerNotificationsEnabled(userId, crud.notification_category_id, enabled);
|
|
122
|
+
await app._serverNotificationCategoriesCache.refresh([userId]);
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
_serverOAuthProviderFromCrud(crud) {
|
|
127
|
+
const app = this;
|
|
128
|
+
return {
|
|
129
|
+
id: crud.id,
|
|
130
|
+
type: crud.type,
|
|
131
|
+
userId: crud.user_id,
|
|
132
|
+
accountId: crud.account_id,
|
|
133
|
+
email: crud.email,
|
|
134
|
+
allowSignIn: crud.allow_sign_in,
|
|
135
|
+
allowConnectedAccounts: crud.allow_connected_accounts,
|
|
136
|
+
async update(data) {
|
|
137
|
+
try {
|
|
138
|
+
await app._interface.updateServerOAuthProvider(crud.user_id, crud.id, {
|
|
139
|
+
account_id: data.accountId,
|
|
140
|
+
email: data.email,
|
|
141
|
+
allow_sign_in: data.allowSignIn,
|
|
142
|
+
allow_connected_accounts: data.allowConnectedAccounts
|
|
143
|
+
});
|
|
144
|
+
await Promise.all([app._serverOAuthProvidersCache.refresh([crud.user_id]), app._serverUserConnectedAccountsCache.refresh([crud.user_id])]);
|
|
145
|
+
return Result.ok(void 0);
|
|
146
|
+
} catch (error) {
|
|
147
|
+
if (KnownErrors.OAuthProviderAccountIdAlreadyUsedForSignIn.isInstance(error)) return Result.error(error);
|
|
148
|
+
throw error;
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
async delete() {
|
|
152
|
+
await app._interface.deleteServerOAuthProvider(crud.user_id, crud.id);
|
|
153
|
+
await Promise.all([app._serverOAuthProvidersCache.refresh([crud.user_id]), app._serverUserConnectedAccountsCache.refresh([crud.user_id])]);
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
constructor(options, extraOptions) {
|
|
158
|
+
const resolvedOptions = resolveConstructorOptions(options);
|
|
159
|
+
const publishableClientKey = resolvedOptions.publishableClientKey ?? getDefaultPublishableClientKey();
|
|
160
|
+
super(resolvedOptions, {
|
|
161
|
+
...extraOptions,
|
|
162
|
+
interface: extraOptions?.interface ?? (() => {
|
|
163
|
+
const apiUrls = resolveApiUrls(resolvedOptions.baseUrl);
|
|
164
|
+
return new HexclaveServerInterface({
|
|
165
|
+
getBaseUrl: () => apiUrls()[0],
|
|
166
|
+
getApiUrls: apiUrls,
|
|
167
|
+
projectId: resolvedOptions.projectId ?? getDefaultProjectId(),
|
|
168
|
+
extraRequestHeaders: resolvedOptions.extraRequestHeaders ?? getDefaultExtraRequestHeaders(),
|
|
169
|
+
clientVersion,
|
|
170
|
+
...publishableClientKey != null ? { publishableClientKey } : {},
|
|
171
|
+
secretServerKey: resolvedOptions.secretServerKey ?? getDefaultSecretServerKey()
|
|
172
|
+
});
|
|
173
|
+
})()
|
|
174
|
+
});
|
|
175
|
+
this._currentServerUserCache = createCacheBySession(async (session) => {
|
|
176
|
+
if (session.isKnownToBeInvalid()) return null;
|
|
177
|
+
return await this._interface.getServerUserByToken(session);
|
|
178
|
+
});
|
|
179
|
+
this._serverUsersCache = createCache(async ([cursor, limit, orderBy, desc, query, includeRestricted, includeAnonymous, onlyAnonymous, teamId]) => {
|
|
180
|
+
if (onlyAnonymous && !includeAnonymous) throw new HexclaveAssertionError("onlyAnonymous=true requires includeAnonymous=true");
|
|
181
|
+
if (onlyAnonymous) return await this._interface.listServerUsers({
|
|
182
|
+
cursor,
|
|
183
|
+
limit,
|
|
184
|
+
orderBy,
|
|
185
|
+
desc,
|
|
186
|
+
query,
|
|
187
|
+
includeRestricted,
|
|
188
|
+
includeAnonymous: true,
|
|
189
|
+
onlyAnonymous: true,
|
|
190
|
+
teamId
|
|
191
|
+
});
|
|
192
|
+
return await this._interface.listServerUsers({
|
|
193
|
+
cursor,
|
|
194
|
+
limit,
|
|
195
|
+
orderBy,
|
|
196
|
+
desc,
|
|
197
|
+
query,
|
|
198
|
+
includeRestricted,
|
|
199
|
+
includeAnonymous,
|
|
200
|
+
teamId
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
this._serverUserCache = createCache(async ([userId]) => {
|
|
204
|
+
const user = await this._interface.getServerUserById(userId);
|
|
205
|
+
return Result.or(user, null);
|
|
206
|
+
});
|
|
207
|
+
this._serverTeamsCache = createCache(async ([userId, orderBy, desc, cursor, limit, query]) => {
|
|
208
|
+
return await this._interface.listServerTeamsPaginated({
|
|
209
|
+
userId,
|
|
210
|
+
orderBy,
|
|
211
|
+
desc,
|
|
212
|
+
cursor,
|
|
213
|
+
limit,
|
|
214
|
+
query
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
this._serverUserTeamInvitationsCache = createCache(async ([userId]) => {
|
|
218
|
+
return await this._interface.listServerUserTeamInvitations(userId);
|
|
219
|
+
});
|
|
220
|
+
this._serverTeamUserPermissionsCache = createCache(async ([teamId, userId, recursive]) => {
|
|
221
|
+
return await this._interface.listServerTeamPermissions({
|
|
222
|
+
teamId,
|
|
223
|
+
userId,
|
|
224
|
+
recursive
|
|
225
|
+
}, null);
|
|
226
|
+
});
|
|
227
|
+
this._serverAllTeamMemberPermissionsCache = createCache(async ([teamId, recursive]) => {
|
|
228
|
+
return await this._interface.listServerTeamPermissions({
|
|
229
|
+
teamId,
|
|
230
|
+
recursive
|
|
231
|
+
}, null);
|
|
232
|
+
});
|
|
233
|
+
this._serverUserProjectPermissionsCache = createCache(async ([userId, recursive]) => {
|
|
234
|
+
return await this._interface.listServerProjectPermissions({
|
|
235
|
+
userId,
|
|
236
|
+
recursive
|
|
237
|
+
}, null);
|
|
238
|
+
});
|
|
239
|
+
this._serverUserOAuthConnectionAccessTokensCache = createCache(async ([userId, providerId, scope]) => {
|
|
240
|
+
try {
|
|
241
|
+
return { accessToken: (await this._interface.createServerProviderAccessToken(userId, providerId, scope || "")).access_token };
|
|
242
|
+
} catch (err) {
|
|
243
|
+
if (!(KnownErrors.OAuthAccessTokenNotAvailable.isInstance(err) || KnownErrors.OAuthConnectionDoesNotHaveRequiredScope.isInstance(err) || KnownErrors.OAuthConnectionNotConnectedToUser.isInstance(err))) throw err;
|
|
244
|
+
}
|
|
245
|
+
return null;
|
|
246
|
+
});
|
|
247
|
+
this._serverUserOAuthConnectionCache = createCache(async ([userId, providerId, scope, redirect]) => {
|
|
248
|
+
return await this._getUserOAuthConnectionCacheFn({
|
|
249
|
+
getUser: async () => Result.orThrow(await this._serverUserCache.getOrWait([userId], "write-only")),
|
|
250
|
+
getOrWaitOAuthToken: async () => Result.orThrow(await this._serverUserOAuthConnectionAccessTokensCache.getOrWait([
|
|
251
|
+
userId,
|
|
252
|
+
providerId,
|
|
253
|
+
scope || ""
|
|
254
|
+
], "write-only")),
|
|
255
|
+
providerId,
|
|
256
|
+
scope,
|
|
257
|
+
redirect,
|
|
258
|
+
session: null
|
|
259
|
+
});
|
|
260
|
+
});
|
|
261
|
+
this._serverUserConnectedAccountsCache = createCache(async ([userId]) => {
|
|
262
|
+
return (await this._interface.listServerConnectedAccounts(userId)).items.map((item) => this._createServerOAuthConnectionFromCrudItem(userId, item));
|
|
263
|
+
});
|
|
264
|
+
this._serverUserOAuthConnectionAccessTokensByAccountCache = createCache(async ([userId, providerId, providerAccountId, scope]) => {
|
|
265
|
+
try {
|
|
266
|
+
return { accessToken: (await this._interface.createServerProviderAccessTokenByAccount(userId, providerId, providerAccountId, scope || "")).access_token };
|
|
267
|
+
} catch (err) {
|
|
268
|
+
if (!(KnownErrors.OAuthAccessTokenNotAvailable.isInstance(err) || KnownErrors.OAuthConnectionDoesNotHaveRequiredScope.isInstance(err) || KnownErrors.OAuthConnectionNotConnectedToUser.isInstance(err))) throw err;
|
|
269
|
+
}
|
|
270
|
+
return null;
|
|
271
|
+
});
|
|
272
|
+
this._serverTeamMemberProfilesCache = createCache(async ([teamId]) => {
|
|
273
|
+
return await this._interface.listServerTeamMemberProfiles({ teamId });
|
|
274
|
+
});
|
|
275
|
+
this._serverTeamInvitationsCache = createCache(async ([teamId]) => {
|
|
276
|
+
return await this._interface.listServerTeamInvitations({ teamId });
|
|
277
|
+
});
|
|
278
|
+
this._serverUserTeamProfileCache = createCache(async ([teamId, userId]) => {
|
|
279
|
+
return await this._interface.getServerTeamMemberProfile({
|
|
280
|
+
teamId,
|
|
281
|
+
userId
|
|
282
|
+
});
|
|
283
|
+
});
|
|
284
|
+
this._serverContactChannelsCache = createCache(async ([userId]) => {
|
|
285
|
+
return await this._interface.listServerContactChannels(userId);
|
|
286
|
+
});
|
|
287
|
+
this._serverNotificationCategoriesCache = createCache(async ([userId]) => {
|
|
288
|
+
return await this._interface.listServerNotificationCategories(userId);
|
|
289
|
+
});
|
|
290
|
+
this._serverDataVaultStoreValueCache = createCache(async ([storeId, key, secret]) => {
|
|
291
|
+
return await this._interface.getDataVaultStoreValue(secret, storeId, key);
|
|
292
|
+
});
|
|
293
|
+
this._emailDeliveryInfoCache = createCache(async () => {
|
|
294
|
+
return await this._interface.getEmailDeliveryInfo();
|
|
295
|
+
});
|
|
296
|
+
this._serverUserApiKeysCache = createCache(async ([userId]) => {
|
|
297
|
+
return await this._interface.listProjectApiKeys({ user_id: userId }, null, "server");
|
|
298
|
+
});
|
|
299
|
+
this._serverTeamApiKeysCache = createCache(async ([teamId]) => {
|
|
300
|
+
return await this._interface.listProjectApiKeys({ team_id: teamId }, null, "server");
|
|
301
|
+
});
|
|
302
|
+
this._convexIdentitySubjectCache = createCache(async ([ctx]) => {
|
|
303
|
+
const identity = await ctx.auth.getUserIdentity();
|
|
304
|
+
return identity ? identity.subject : null;
|
|
305
|
+
});
|
|
306
|
+
this._serverCheckApiKeyCache = createCache(async ([type, apiKey]) => {
|
|
307
|
+
return await this._interface.checkProjectApiKey(type, apiKey, null, "server");
|
|
308
|
+
});
|
|
309
|
+
this._serverOAuthProvidersCache = createCache(async ([userId]) => {
|
|
310
|
+
return await this._interface.listServerOAuthProviders({ user_id: userId });
|
|
311
|
+
});
|
|
312
|
+
this._serverTeamItemsCache = createCache(async ([teamId, itemId]) => {
|
|
313
|
+
return await this._interface.getItem({
|
|
314
|
+
teamId,
|
|
315
|
+
itemId
|
|
316
|
+
}, null, "server");
|
|
317
|
+
});
|
|
318
|
+
this._serverUserItemsCache = createCache(async ([userId, itemId]) => {
|
|
319
|
+
return await this._interface.getItem({
|
|
320
|
+
userId,
|
|
321
|
+
itemId
|
|
322
|
+
}, null, "server");
|
|
323
|
+
});
|
|
324
|
+
this._serverCustomItemsCache = createCache(async ([customCustomerId, itemId]) => {
|
|
325
|
+
return await this._interface.getItem({
|
|
326
|
+
customCustomerId,
|
|
327
|
+
itemId
|
|
328
|
+
}, null, "server");
|
|
329
|
+
});
|
|
330
|
+
this._serverUserProductsCache = createCache(async ([userId, cursor, limit]) => {
|
|
331
|
+
return await this._interface.listProducts({
|
|
332
|
+
customer_type: "user",
|
|
333
|
+
customer_id: userId,
|
|
334
|
+
cursor: cursor ?? void 0,
|
|
335
|
+
limit: limit ?? void 0
|
|
336
|
+
}, null, "server");
|
|
337
|
+
});
|
|
338
|
+
this._serverTeamProductsCache = createCache(async ([teamId, cursor, limit]) => {
|
|
339
|
+
return await this._interface.listProducts({
|
|
340
|
+
customer_type: "team",
|
|
341
|
+
customer_id: teamId,
|
|
342
|
+
cursor: cursor ?? void 0,
|
|
343
|
+
limit: limit ?? void 0
|
|
344
|
+
}, null, "server");
|
|
345
|
+
});
|
|
346
|
+
this._serverCustomProductsCache = createCache(async ([customCustomerId, cursor, limit]) => {
|
|
347
|
+
return await this._interface.listProducts({
|
|
348
|
+
customer_type: "custom",
|
|
349
|
+
customer_id: customCustomerId,
|
|
350
|
+
cursor: cursor ?? void 0,
|
|
351
|
+
limit: limit ?? void 0
|
|
352
|
+
}, null, "server");
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
_serverApiKeyFromCrud(crud) {
|
|
356
|
+
return {
|
|
357
|
+
...this._baseApiKeyFromCrud(crud),
|
|
358
|
+
async revoke() {
|
|
359
|
+
await this.update({ revoked: true });
|
|
360
|
+
},
|
|
361
|
+
update: async (options) => {
|
|
362
|
+
await this._interface.updateProjectApiKey(crud.type === "team" ? { team_id: crud.team_id } : { user_id: crud.user_id }, crud.id, await apiKeyUpdateOptionsToCrud(crud.type, options), null, "server");
|
|
363
|
+
if (crud.type === "team") await this._serverTeamApiKeysCache.refresh([crud.team_id]);
|
|
364
|
+
else await this._serverUserApiKeysCache.refresh([crud.user_id]);
|
|
365
|
+
}
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
_createServerOAuthConnectionFromCrudItem(userId, item) {
|
|
369
|
+
const app = this;
|
|
370
|
+
const providerId = item.provider;
|
|
371
|
+
const providerAccountId = item.provider_account_id;
|
|
372
|
+
return {
|
|
373
|
+
id: providerId,
|
|
374
|
+
provider: providerId,
|
|
375
|
+
providerAccountId,
|
|
376
|
+
async getAccessToken(options) {
|
|
377
|
+
const scopeString = options?.scopes?.join(" ") ?? "";
|
|
378
|
+
const result = Result.orThrow(await app._serverUserOAuthConnectionAccessTokensByAccountCache.getOrWait([
|
|
379
|
+
userId,
|
|
380
|
+
providerId,
|
|
381
|
+
providerAccountId,
|
|
382
|
+
scopeString
|
|
383
|
+
], "write-only"));
|
|
384
|
+
if (!result) {
|
|
385
|
+
const scopeDetail = scopeString ? `The requested scopes [${scopeString}] are not available on the existing token.` : "The OAuth refresh token has likely been revoked or expired.";
|
|
386
|
+
return Result.error(new KnownErrors.OAuthAccessTokenNotAvailable(providerId, `${scopeDetail} The user needs to re-authorize by calling \`linkConnectedAccount\` or using \`getOrLinkConnectedAccount\`.`));
|
|
387
|
+
}
|
|
388
|
+
return Result.ok(result);
|
|
389
|
+
}
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
_serverUserFromCrud(crud) {
|
|
393
|
+
const app = this;
|
|
394
|
+
async function getConnectedAccount(idOrAccount, options) {
|
|
395
|
+
const scopeString = options?.scopes?.join(" ") ?? "";
|
|
396
|
+
if (typeof idOrAccount === "object" && "provider" in idOrAccount && "providerAccountId" in idOrAccount) {
|
|
397
|
+
const { provider, providerAccountId } = idOrAccount;
|
|
398
|
+
const found = Result.orThrow(await app._serverUserConnectedAccountsCache.getOrWait([crud.id], "write-only")).find((a) => a.provider === provider && a.providerAccountId === providerAccountId);
|
|
399
|
+
if (!found) return null;
|
|
400
|
+
return found;
|
|
401
|
+
}
|
|
402
|
+
return Result.orThrow(await app._serverUserOAuthConnectionCache.getOrWait([
|
|
403
|
+
crud.id,
|
|
404
|
+
idOrAccount,
|
|
405
|
+
scopeString,
|
|
406
|
+
options?.or === "redirect"
|
|
407
|
+
], "write-only"));
|
|
408
|
+
}
|
|
409
|
+
const crudWithAdminRestriction = crud;
|
|
410
|
+
return withUserDestructureGuard({
|
|
411
|
+
...super._createBaseUser(crud),
|
|
412
|
+
lastActiveAt: new Date(crud.last_active_at_millis),
|
|
413
|
+
serverMetadata: crud.server_metadata,
|
|
414
|
+
restrictedByAdmin: crudWithAdminRestriction.restricted_by_admin,
|
|
415
|
+
restrictedByAdminReason: crudWithAdminRestriction.restricted_by_admin_reason,
|
|
416
|
+
restrictedByAdminPrivateDetails: crudWithAdminRestriction.restricted_by_admin_private_details,
|
|
417
|
+
countryCode: crud.country_code,
|
|
418
|
+
riskScores: { signUp: {
|
|
419
|
+
bot: crud.risk_scores.sign_up.bot,
|
|
420
|
+
freeTrialAbuse: crud.risk_scores.sign_up.free_trial_abuse
|
|
421
|
+
} },
|
|
422
|
+
async setPrimaryEmail(email, options) {
|
|
423
|
+
await app._updateServerUser(crud.id, {
|
|
424
|
+
primaryEmail: email,
|
|
425
|
+
primaryEmailVerified: options?.verified
|
|
426
|
+
});
|
|
427
|
+
},
|
|
428
|
+
async grantPermission(scopeOrPermissionId, permissionId) {
|
|
429
|
+
if (scopeOrPermissionId && typeof scopeOrPermissionId !== "string" && permissionId) {
|
|
430
|
+
const scope = scopeOrPermissionId;
|
|
431
|
+
await app._interface.grantServerTeamUserPermission(scope.id, crud.id, permissionId);
|
|
432
|
+
for (const recursive of [true, false]) {
|
|
433
|
+
await app._serverTeamUserPermissionsCache.refresh([
|
|
434
|
+
scope.id,
|
|
435
|
+
crud.id,
|
|
436
|
+
recursive
|
|
437
|
+
]);
|
|
438
|
+
await app._serverAllTeamMemberPermissionsCache.refresh([scope.id, recursive]);
|
|
439
|
+
}
|
|
440
|
+
} else {
|
|
441
|
+
const pId = scopeOrPermissionId;
|
|
442
|
+
await app._interface.grantServerProjectPermission(crud.id, pId);
|
|
443
|
+
for (const recursive of [true, false]) await app._serverUserProjectPermissionsCache.refresh([crud.id, recursive]);
|
|
444
|
+
}
|
|
445
|
+
},
|
|
446
|
+
async revokePermission(scopeOrPermissionId, permissionId) {
|
|
447
|
+
if (scopeOrPermissionId && typeof scopeOrPermissionId !== "string" && permissionId) {
|
|
448
|
+
const scope = scopeOrPermissionId;
|
|
449
|
+
await app._interface.revokeServerTeamUserPermission(scope.id, crud.id, permissionId);
|
|
450
|
+
for (const recursive of [true, false]) {
|
|
451
|
+
await app._serverTeamUserPermissionsCache.refresh([
|
|
452
|
+
scope.id,
|
|
453
|
+
crud.id,
|
|
454
|
+
recursive
|
|
455
|
+
]);
|
|
456
|
+
await app._serverAllTeamMemberPermissionsCache.refresh([scope.id, recursive]);
|
|
457
|
+
}
|
|
458
|
+
} else {
|
|
459
|
+
const pId = scopeOrPermissionId;
|
|
460
|
+
await app._interface.revokeServerProjectPermission(crud.id, pId);
|
|
461
|
+
for (const recursive of [true, false]) await app._serverUserProjectPermissionsCache.refresh([crud.id, recursive]);
|
|
462
|
+
}
|
|
463
|
+
},
|
|
464
|
+
async delete() {
|
|
465
|
+
const res = await app._interface.deleteServerUser(crud.id);
|
|
466
|
+
await app._refreshUsers();
|
|
467
|
+
return res;
|
|
468
|
+
},
|
|
469
|
+
async createSession(options) {
|
|
470
|
+
const tokens = await app._interface.createServerUserSession(crud.id, options.expiresInMillis ?? 1e3 * 60 * 60 * 24 * 365, options.isImpersonation ?? false);
|
|
471
|
+
return { async getTokens() {
|
|
472
|
+
return tokens;
|
|
473
|
+
} };
|
|
474
|
+
},
|
|
475
|
+
async getActiveSessions() {
|
|
476
|
+
return (await app._interface.listServerSessions(crud.id)).items.map((session) => app._clientSessionFromCrud(session));
|
|
477
|
+
},
|
|
478
|
+
async revokeSession(sessionId) {
|
|
479
|
+
await app._interface.deleteServerSession(sessionId);
|
|
480
|
+
},
|
|
481
|
+
async setDisplayName(displayName) {
|
|
482
|
+
return await this.update({ displayName });
|
|
483
|
+
},
|
|
484
|
+
async setClientMetadata(metadata) {
|
|
485
|
+
return await this.update({ clientMetadata: metadata });
|
|
486
|
+
},
|
|
487
|
+
async setClientReadOnlyMetadata(metadata) {
|
|
488
|
+
return await this.update({ clientReadOnlyMetadata: metadata });
|
|
489
|
+
},
|
|
490
|
+
async setServerMetadata(metadata) {
|
|
491
|
+
return await this.update({ serverMetadata: metadata });
|
|
492
|
+
},
|
|
493
|
+
async setSelectedTeam(team) {
|
|
494
|
+
return await this.update({ selectedTeamId: typeof team === "string" ? team : team?.id ?? null });
|
|
495
|
+
},
|
|
496
|
+
getConnectedAccount,
|
|
497
|
+
async listConnectedAccounts() {
|
|
498
|
+
return Result.orThrow(await app._serverUserConnectedAccountsCache.getOrWait([crud.id], "write-only"));
|
|
499
|
+
},
|
|
500
|
+
async linkConnectedAccount() {
|
|
501
|
+
throw new HexclaveAssertionError("linkConnectedAccount is not available for server users. OAuth flows must be initiated on the client side.");
|
|
502
|
+
},
|
|
503
|
+
async getOrLinkConnectedAccount() {
|
|
504
|
+
throw new HexclaveAssertionError("getOrLinkConnectedAccount is not available for server users. OAuth flows must be initiated on the client side.");
|
|
505
|
+
},
|
|
506
|
+
selectedTeam: crud.selected_team ? app._serverTeamFromCrud(crud.selected_team) : null,
|
|
507
|
+
async getTeam(teamId) {
|
|
508
|
+
return (await this.listTeams()).find((t) => t.id === teamId) ?? null;
|
|
509
|
+
},
|
|
510
|
+
async listTeams(options) {
|
|
511
|
+
const result = Result.orThrow(await app._serverTeamsCache.getOrWait([
|
|
512
|
+
crud.id,
|
|
513
|
+
options?.orderBy,
|
|
514
|
+
options?.desc,
|
|
515
|
+
options?.cursor,
|
|
516
|
+
options?.limit,
|
|
517
|
+
options?.query
|
|
518
|
+
], "write-only"));
|
|
519
|
+
const teams = result.items.map((t) => app._serverTeamFromCrud(t));
|
|
520
|
+
teams.nextCursor = result.pagination?.next_cursor ?? null;
|
|
521
|
+
return teams;
|
|
522
|
+
},
|
|
523
|
+
createTeam: async (data) => {
|
|
524
|
+
const team = await app._interface.createServerTeam(serverTeamCreateOptionsToCrud({
|
|
525
|
+
creatorUserId: crud.id,
|
|
526
|
+
...data
|
|
527
|
+
}));
|
|
528
|
+
await app._serverTeamsCache.refreshWhere(() => true);
|
|
529
|
+
await app._updateServerUser(crud.id, { selectedTeamId: team.id });
|
|
530
|
+
return app._serverTeamFromCrud(team);
|
|
531
|
+
},
|
|
532
|
+
leaveTeam: async (team) => {
|
|
533
|
+
await app._interface.leaveServerTeam({
|
|
534
|
+
teamId: team.id,
|
|
535
|
+
userId: crud.id
|
|
536
|
+
});
|
|
537
|
+
await app._refreshTeamMembership(team.id, crud.id);
|
|
538
|
+
},
|
|
539
|
+
async listTeamInvitations() {
|
|
540
|
+
return Result.orThrow(await app._serverUserTeamInvitationsCache.getOrWait([crud.id], "write-only")).map((inv) => app._serverReceivedTeamInvitationFromCrud(crud.id, inv));
|
|
541
|
+
},
|
|
542
|
+
async listPermissions(scopeOrOptions, options) {
|
|
543
|
+
if (scopeOrOptions && "id" in scopeOrOptions) {
|
|
544
|
+
const scope = scopeOrOptions;
|
|
545
|
+
const recursive = options?.recursive ?? true;
|
|
546
|
+
return Result.orThrow(await app._serverTeamUserPermissionsCache.getOrWait([
|
|
547
|
+
scope.id,
|
|
548
|
+
crud.id,
|
|
549
|
+
recursive
|
|
550
|
+
], "write-only")).map((crud) => app._serverPermissionFromCrud(crud));
|
|
551
|
+
} else {
|
|
552
|
+
const recursive = scopeOrOptions?.recursive ?? true;
|
|
553
|
+
return Result.orThrow(await app._serverUserProjectPermissionsCache.getOrWait([crud.id, recursive], "write-only")).map((crud) => app._serverPermissionFromCrud(crud));
|
|
554
|
+
}
|
|
555
|
+
},
|
|
556
|
+
async getPermission(scopeOrPermissionId, permissionId) {
|
|
557
|
+
if (scopeOrPermissionId && typeof scopeOrPermissionId !== "string") {
|
|
558
|
+
const scope = scopeOrPermissionId;
|
|
559
|
+
return (await this.listPermissions(scope)).find((p) => p.id === permissionId) ?? null;
|
|
560
|
+
} else {
|
|
561
|
+
const pid = scopeOrPermissionId;
|
|
562
|
+
return (await this.listPermissions()).find((p) => p.id === pid) ?? null;
|
|
563
|
+
}
|
|
564
|
+
},
|
|
565
|
+
async hasPermission(scopeOrPermissionId, permissionId) {
|
|
566
|
+
if (scopeOrPermissionId && typeof scopeOrPermissionId !== "string") {
|
|
567
|
+
const scope = scopeOrPermissionId;
|
|
568
|
+
return await this.getPermission(scope, permissionId) !== null;
|
|
569
|
+
} else {
|
|
570
|
+
const pid = scopeOrPermissionId;
|
|
571
|
+
return await this.getPermission(pid) !== null;
|
|
572
|
+
}
|
|
573
|
+
},
|
|
574
|
+
async update(update) {
|
|
575
|
+
await app._updateServerUser(crud.id, update);
|
|
576
|
+
},
|
|
577
|
+
async sendVerificationEmail() {
|
|
578
|
+
return await app._checkFeatureSupport("sendVerificationEmail() on ServerUser", {});
|
|
579
|
+
},
|
|
580
|
+
async updatePassword(options) {
|
|
581
|
+
const result = await app._interface.updatePassword(options);
|
|
582
|
+
await app._serverUserCache.refresh([crud.id]);
|
|
583
|
+
return result;
|
|
584
|
+
},
|
|
585
|
+
async setPassword(options) {
|
|
586
|
+
const result = await this.update(options);
|
|
587
|
+
await app._serverUserCache.refresh([crud.id]);
|
|
588
|
+
return result;
|
|
589
|
+
},
|
|
590
|
+
async getTeamProfile(team) {
|
|
591
|
+
const result = Result.orThrow(await app._serverUserTeamProfileCache.getOrWait([team.id, crud.id], "write-only"));
|
|
592
|
+
return app._serverEditableTeamProfileFromCrud(result);
|
|
593
|
+
},
|
|
594
|
+
async listContactChannels() {
|
|
595
|
+
return Result.orThrow(await app._serverContactChannelsCache.getOrWait([crud.id], "write-only")).map((data) => app._serverContactChannelFromCrud(crud.id, data));
|
|
596
|
+
},
|
|
597
|
+
createContactChannel: async (data) => {
|
|
598
|
+
const contactChannel = await app._interface.createServerContactChannel(serverContactChannelCreateOptionsToCrud(crud.id, data));
|
|
599
|
+
await Promise.all([app._serverContactChannelsCache.refresh([crud.id]), app._serverUserCache.refresh([crud.id])]);
|
|
600
|
+
return app._serverContactChannelFromCrud(crud.id, contactChannel);
|
|
601
|
+
},
|
|
602
|
+
async listNotificationCategories() {
|
|
603
|
+
return Result.orThrow(await app._serverNotificationCategoriesCache.getOrWait([crud.id], "write-only")).map((category) => app._serverNotificationCategoryFromCrud(crud.id, category));
|
|
604
|
+
},
|
|
605
|
+
async listApiKeys() {
|
|
606
|
+
return Result.orThrow(await app._serverUserApiKeysCache.getOrWait([crud.id], "write-only")).map((apiKey) => app._serverApiKeyFromCrud(apiKey));
|
|
607
|
+
},
|
|
608
|
+
async createApiKey(options) {
|
|
609
|
+
const result = await app._interface.createProjectApiKey(await apiKeyCreationOptionsToCrud("user", crud.id, options), null, "server");
|
|
610
|
+
await app._serverUserApiKeysCache.refresh([crud.id]);
|
|
611
|
+
return app._serverApiKeyFromCrud(result);
|
|
612
|
+
},
|
|
613
|
+
async listOAuthProviders() {
|
|
614
|
+
return Result.orThrow(await app._serverOAuthProvidersCache.getOrWait([crud.id], "write-only")).map((oauthCrud) => app._serverOAuthProviderFromCrud(oauthCrud));
|
|
615
|
+
},
|
|
616
|
+
async getOAuthProvider(id) {
|
|
617
|
+
return (await this.listOAuthProviders()).find((p) => p.id === id) ?? null;
|
|
618
|
+
},
|
|
619
|
+
async registerPasskey(options) {
|
|
620
|
+
const hostname = options?.hostname || (await app._getCurrentUrl())?.hostname;
|
|
621
|
+
if (!hostname) throw new HexclaveAssertionError("hostname must be provided if the Stack App does not have a redirect method");
|
|
622
|
+
const initiationResult = await app._interface.initiateServerPasskeyRegistration(crud.id);
|
|
623
|
+
if (initiationResult.status !== "ok") return Result.error(new KnownErrors.PasskeyRegistrationFailed("Failed to get initiation options for passkey registration"));
|
|
624
|
+
const { options_json, code } = initiationResult.data;
|
|
625
|
+
if (options_json.rp.id !== "THIS_VALUE_WILL_BE_REPLACED.example.com") throw new HexclaveAssertionError(`Expected returned RP ID from server to equal sentinel, but found ${options_json.rp.id}`);
|
|
626
|
+
options_json.rp.id = hostname;
|
|
627
|
+
let attResp;
|
|
628
|
+
try {
|
|
629
|
+
attResp = await startRegistration({ optionsJSON: options_json });
|
|
630
|
+
} catch (error) {
|
|
631
|
+
if (error instanceof WebAuthnError) return Result.error(new KnownErrors.PasskeyWebAuthnError(error.message, error.name));
|
|
632
|
+
else {
|
|
633
|
+
captureError("passkey-registration-failed", error);
|
|
634
|
+
return Result.error(new KnownErrors.PasskeyRegistrationFailed("Failed to start passkey registration due to unknown error"));
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
const { accessToken, refreshToken } = await app._interface.createServerUserSession(crud.id, 6e4 * 2, false);
|
|
638
|
+
const tempSession = new InternalSession({
|
|
639
|
+
accessToken,
|
|
640
|
+
refreshToken,
|
|
641
|
+
refreshAccessTokenCallback: async () => null
|
|
642
|
+
});
|
|
643
|
+
const registrationResult = await app._interface.registerPasskey({
|
|
644
|
+
credential: attResp,
|
|
645
|
+
code
|
|
646
|
+
}, tempSession);
|
|
647
|
+
await app._serverUserCache.refresh([crud.id]);
|
|
648
|
+
return registrationResult;
|
|
649
|
+
},
|
|
650
|
+
...app._createServerCustomer(crud.id, "user")
|
|
651
|
+
});
|
|
652
|
+
}
|
|
653
|
+
_serverTeamUserFromCrud(crud) {
|
|
654
|
+
return withUserDestructureGuard({
|
|
655
|
+
...this._serverUserFromCrud(crud.user),
|
|
656
|
+
teamProfile: {
|
|
657
|
+
displayName: crud.display_name,
|
|
658
|
+
profileImageUrl: crud.profile_image_url
|
|
659
|
+
}
|
|
660
|
+
});
|
|
661
|
+
}
|
|
662
|
+
_serverSentTeamInvitationFromCrud(crud) {
|
|
663
|
+
return {
|
|
664
|
+
id: crud.id,
|
|
665
|
+
recipientEmail: crud.recipient_email,
|
|
666
|
+
expiresAt: new Date(crud.expires_at_millis),
|
|
667
|
+
revoke: async () => {
|
|
668
|
+
await this._interface.revokeServerTeamInvitation(crud.id, crud.team_id);
|
|
669
|
+
await this._serverTeamInvitationsCache.refresh([crud.team_id]);
|
|
670
|
+
}
|
|
671
|
+
};
|
|
672
|
+
}
|
|
673
|
+
_serverReceivedTeamInvitationFromCrud(userId, crud) {
|
|
674
|
+
const app = this;
|
|
675
|
+
return {
|
|
676
|
+
id: crud.id,
|
|
677
|
+
teamId: crud.team_id,
|
|
678
|
+
teamDisplayName: crud.team_display_name,
|
|
679
|
+
recipientEmail: crud.recipient_email,
|
|
680
|
+
expiresAt: new Date(crud.expires_at_millis),
|
|
681
|
+
accept: async () => {
|
|
682
|
+
await app._interface.acceptServerTeamInvitationById(crud.id, userId);
|
|
683
|
+
await Promise.all([
|
|
684
|
+
app._serverUserTeamInvitationsCache.refresh([userId]),
|
|
685
|
+
app._serverTeamInvitationsCache.refresh([crud.team_id]),
|
|
686
|
+
app._refreshTeamMembership(crud.team_id, userId)
|
|
687
|
+
]);
|
|
688
|
+
}
|
|
689
|
+
};
|
|
690
|
+
}
|
|
691
|
+
_currentUserFromCrud(crud, session) {
|
|
692
|
+
return withUserDestructureGuard({
|
|
693
|
+
...this._serverUserFromCrud(crud),
|
|
694
|
+
...this._createAuth(session),
|
|
695
|
+
...this._isInternalProject() ? this._createInternalUserExtra(session) : {}
|
|
696
|
+
});
|
|
697
|
+
}
|
|
698
|
+
_serverTeamFromCrud(crud) {
|
|
699
|
+
const app = this;
|
|
700
|
+
return {
|
|
701
|
+
id: crud.id,
|
|
702
|
+
displayName: crud.display_name,
|
|
703
|
+
profileImageUrl: crud.profile_image_url,
|
|
704
|
+
createdAt: new Date(crud.created_at_millis),
|
|
705
|
+
clientMetadata: crud.client_metadata,
|
|
706
|
+
clientReadOnlyMetadata: crud.client_read_only_metadata,
|
|
707
|
+
serverMetadata: crud.server_metadata,
|
|
708
|
+
async update(update) {
|
|
709
|
+
await app._interface.updateServerTeam(crud.id, serverTeamUpdateOptionsToCrud(update));
|
|
710
|
+
await Promise.all([app._serverTeamsCache.refreshWhere(() => true), app._serverUsersCache.refreshWhere(() => true)]);
|
|
711
|
+
},
|
|
712
|
+
async delete() {
|
|
713
|
+
await app._interface.deleteServerTeam(crud.id);
|
|
714
|
+
await Promise.all([app._serverTeamsCache.refreshWhere(() => true), app._serverUsersCache.refreshWhere(() => true)]);
|
|
715
|
+
},
|
|
716
|
+
async listUsers() {
|
|
717
|
+
return Result.orThrow(await app._serverTeamMemberProfilesCache.getOrWait([crud.id], "write-only")).map((u) => app._serverTeamUserFromCrud(u));
|
|
718
|
+
},
|
|
719
|
+
async addUser(userId) {
|
|
720
|
+
await app._interface.addServerUserToTeam({
|
|
721
|
+
teamId: crud.id,
|
|
722
|
+
userId
|
|
723
|
+
});
|
|
724
|
+
await app._refreshTeamMembership(crud.id, userId);
|
|
725
|
+
},
|
|
726
|
+
async removeUser(userId) {
|
|
727
|
+
await app._interface.removeServerUserFromTeam({
|
|
728
|
+
teamId: crud.id,
|
|
729
|
+
userId
|
|
730
|
+
});
|
|
731
|
+
await app._refreshTeamMembership(crud.id, userId);
|
|
732
|
+
},
|
|
733
|
+
async inviteUser(options) {
|
|
734
|
+
await app._interface.sendServerTeamInvitation({
|
|
735
|
+
teamId: crud.id,
|
|
736
|
+
email: options.email,
|
|
737
|
+
callbackUrl: options.callbackUrl ?? constructRedirectUrl(app.urls.teamInvitation, "callbackUrl")
|
|
738
|
+
});
|
|
739
|
+
await app._serverTeamInvitationsCache.refresh([crud.id]);
|
|
740
|
+
},
|
|
741
|
+
async listInvitations() {
|
|
742
|
+
return Result.orThrow(await app._serverTeamInvitationsCache.getOrWait([crud.id], "write-only")).map((crud) => app._serverSentTeamInvitationFromCrud(crud));
|
|
743
|
+
},
|
|
744
|
+
async listApiKeys() {
|
|
745
|
+
return Result.orThrow(await app._serverTeamApiKeysCache.getOrWait([crud.id], "write-only")).map((apiKey) => app._serverApiKeyFromCrud(apiKey));
|
|
746
|
+
},
|
|
747
|
+
async createApiKey(options) {
|
|
748
|
+
const result = await app._interface.createProjectApiKey(await apiKeyCreationOptionsToCrud("team", crud.id, options), null, "server");
|
|
749
|
+
await app._serverTeamApiKeysCache.refresh([crud.id]);
|
|
750
|
+
return app._serverApiKeyFromCrud(result);
|
|
751
|
+
},
|
|
752
|
+
...app._createServerCustomer(crud.id, "team")
|
|
753
|
+
};
|
|
754
|
+
}
|
|
755
|
+
_serverItemFromCrud(customer, crud) {
|
|
756
|
+
const app = this;
|
|
757
|
+
return {
|
|
758
|
+
displayName: crud.display_name,
|
|
759
|
+
quantity: crud.quantity,
|
|
760
|
+
nonNegativeQuantity: Math.max(0, crud.quantity),
|
|
761
|
+
increaseQuantity: async (delta) => {
|
|
762
|
+
const updateOptions = customer.type === "user" ? {
|
|
763
|
+
itemId: crud.id,
|
|
764
|
+
userId: customer.id
|
|
765
|
+
} : customer.type === "team" ? {
|
|
766
|
+
itemId: crud.id,
|
|
767
|
+
teamId: customer.id
|
|
768
|
+
} : {
|
|
769
|
+
itemId: crud.id,
|
|
770
|
+
customCustomerId: customer.id
|
|
771
|
+
};
|
|
772
|
+
await app._interface.updateItemQuantity(updateOptions, { delta });
|
|
773
|
+
if (customer.type === "user") await app._serverUserItemsCache.refresh([customer.id, crud.id]);
|
|
774
|
+
else if (customer.type === "team") await app._serverTeamItemsCache.refresh([customer.id, crud.id]);
|
|
775
|
+
else await app._serverCustomItemsCache.refresh([customer.id, crud.id]);
|
|
776
|
+
},
|
|
777
|
+
decreaseQuantity: async (delta) => {
|
|
778
|
+
const updateOptions = customer.type === "user" ? {
|
|
779
|
+
itemId: crud.id,
|
|
780
|
+
userId: customer.id
|
|
781
|
+
} : customer.type === "team" ? {
|
|
782
|
+
itemId: crud.id,
|
|
783
|
+
teamId: customer.id
|
|
784
|
+
} : {
|
|
785
|
+
itemId: crud.id,
|
|
786
|
+
customCustomerId: customer.id
|
|
787
|
+
};
|
|
788
|
+
await app._interface.updateItemQuantity(updateOptions, {
|
|
789
|
+
delta: -delta,
|
|
790
|
+
allow_negative: true
|
|
791
|
+
});
|
|
792
|
+
if (customer.type === "user") await app._serverUserItemsCache.refresh([customer.id, crud.id]);
|
|
793
|
+
else if (customer.type === "team") await app._serverTeamItemsCache.refresh([customer.id, crud.id]);
|
|
794
|
+
else await app._serverCustomItemsCache.refresh([customer.id, crud.id]);
|
|
795
|
+
},
|
|
796
|
+
tryDecreaseQuantity: async (delta) => {
|
|
797
|
+
try {
|
|
798
|
+
const updateOptions = customer.type === "user" ? {
|
|
799
|
+
itemId: crud.id,
|
|
800
|
+
userId: customer.id
|
|
801
|
+
} : customer.type === "team" ? {
|
|
802
|
+
itemId: crud.id,
|
|
803
|
+
teamId: customer.id
|
|
804
|
+
} : {
|
|
805
|
+
itemId: crud.id,
|
|
806
|
+
customCustomerId: customer.id
|
|
807
|
+
};
|
|
808
|
+
await app._interface.updateItemQuantity(updateOptions, { delta: -delta });
|
|
809
|
+
if (customer.type === "user") await app._serverUserItemsCache.refresh([customer.id, crud.id]);
|
|
810
|
+
else if (customer.type === "team") await app._serverTeamItemsCache.refresh([customer.id, crud.id]);
|
|
811
|
+
else await app._serverCustomItemsCache.refresh([customer.id, crud.id]);
|
|
812
|
+
return true;
|
|
813
|
+
} catch (error) {
|
|
814
|
+
if (error instanceof KnownErrors.ItemQuantityInsufficientAmount) return false;
|
|
815
|
+
throw error;
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
};
|
|
819
|
+
}
|
|
820
|
+
async _getUserApiKey(options) {
|
|
821
|
+
const crud = Result.orThrow(await this._serverCheckApiKeyCache.getOrWait(["user", options.apiKey], "write-only"));
|
|
822
|
+
return crud ? this._serverApiKeyFromCrud(crud) : null;
|
|
823
|
+
}
|
|
824
|
+
async _getTeamApiKey(options) {
|
|
825
|
+
const crud = Result.orThrow(await this._serverCheckApiKeyCache.getOrWait(["team", options.apiKey], "write-only"));
|
|
826
|
+
return crud ? this._serverApiKeyFromCrud(crud) : null;
|
|
827
|
+
}
|
|
828
|
+
async _getUserByApiKey(apiKey) {
|
|
829
|
+
const apiKeyObject = await this._getUserApiKey({ apiKey });
|
|
830
|
+
if (apiKeyObject === null) return null;
|
|
831
|
+
return await this.getServerUserById(apiKeyObject.userId);
|
|
832
|
+
}
|
|
833
|
+
async _getUserByConvex(ctx, includeAnonymous) {
|
|
834
|
+
const identity = await ctx.auth.getUserIdentity();
|
|
835
|
+
if (identity === null) return null;
|
|
836
|
+
const user = await this.getServerUserById(identity.subject);
|
|
837
|
+
if (user?.isAnonymous && !includeAnonymous) return null;
|
|
838
|
+
return user;
|
|
839
|
+
}
|
|
840
|
+
async _getTeamByApiKey(apiKey) {
|
|
841
|
+
const apiKeyObject = await this._getTeamApiKey({ apiKey });
|
|
842
|
+
if (apiKeyObject === null) return null;
|
|
843
|
+
return await this.getTeam(apiKeyObject.teamId);
|
|
844
|
+
}
|
|
845
|
+
async createUser(options) {
|
|
846
|
+
const crud = await this._interface.createServerUser(serverUserCreateOptionsToCrud(options));
|
|
847
|
+
await this._refreshUsers();
|
|
848
|
+
return this._serverUserFromCrud(crud);
|
|
849
|
+
}
|
|
850
|
+
async getUser(options) {
|
|
851
|
+
if (typeof options === "string") return await this.getServerUserById(options);
|
|
852
|
+
else if (typeof options === "object" && "apiKey" in options) return await this._getUserByApiKey(options.apiKey);
|
|
853
|
+
else if (typeof options === "object" && "from" in options && options.from === "convex") return await this._getUserByConvex(options.ctx, "or" in options && options.or === "anonymous");
|
|
854
|
+
else {
|
|
855
|
+
options = options;
|
|
856
|
+
if (options?.or === "anonymous" && options.includeRestricted === false) throw new Error("Cannot use { or: 'anonymous' } with { includeRestricted: false }. Anonymous users implicitly include restricted users.");
|
|
857
|
+
this._ensurePersistentTokenStore(options?.tokenStore);
|
|
858
|
+
const session = await this._getSession(options?.tokenStore);
|
|
859
|
+
let crud = Result.orThrow(await this._currentServerUserCache.getOrWait([session], "write-only"));
|
|
860
|
+
const includeAnonymous = options?.or === "anonymous" || options?.or === "anonymous-if-exists[deprecated]";
|
|
861
|
+
const includeRestricted = options?.includeRestricted === true || includeAnonymous;
|
|
862
|
+
if (crud === null || crud.is_anonymous && !includeAnonymous || crud.is_restricted && !includeRestricted) switch (options?.or) {
|
|
863
|
+
case "redirect":
|
|
864
|
+
if (!crud?.is_anonymous && crud?.is_restricted) await this.redirectToOnboarding({ replace: true });
|
|
865
|
+
else await this.redirectToSignIn({ replace: true });
|
|
866
|
+
break;
|
|
867
|
+
case "throw": throw new Error("User is not signed in but getUser was called with { or: 'throw' }");
|
|
868
|
+
case "anonymous": {
|
|
869
|
+
const tokens = await this._signUpAnonymously();
|
|
870
|
+
return await this.getUser({
|
|
871
|
+
tokenStore: tokens,
|
|
872
|
+
or: "anonymous-if-exists[deprecated]",
|
|
873
|
+
includeRestricted: true
|
|
874
|
+
}) ?? throwErr("Something went wrong while signing up anonymously");
|
|
875
|
+
}
|
|
876
|
+
case void 0:
|
|
877
|
+
case "anonymous-if-exists[deprecated]":
|
|
878
|
+
case "return-null": return null;
|
|
879
|
+
}
|
|
880
|
+
return crud && this._currentUserFromCrud(crud, session);
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
async getServerUser() {
|
|
884
|
+
console.warn("stackServerApp.getServerUser is deprecated; use stackServerApp.getUser instead");
|
|
885
|
+
return await this.getUser();
|
|
886
|
+
}
|
|
887
|
+
async getServerUserById(userId) {
|
|
888
|
+
const crud = Result.orThrow(await this._serverUserCache.getOrWait([userId], "write-only"));
|
|
889
|
+
return crud && this._serverUserFromCrud(crud);
|
|
890
|
+
}
|
|
891
|
+
async listUsers(options) {
|
|
892
|
+
const crud = Result.orThrow(await this._serverUsersCache.getOrWait([
|
|
893
|
+
options?.cursor,
|
|
894
|
+
options?.limit,
|
|
895
|
+
options?.orderBy,
|
|
896
|
+
options?.desc,
|
|
897
|
+
options?.query,
|
|
898
|
+
options?.includeRestricted,
|
|
899
|
+
options?.includeAnonymous,
|
|
900
|
+
options?.onlyAnonymous,
|
|
901
|
+
options?.teamId
|
|
902
|
+
], "write-only"));
|
|
903
|
+
const result = crud.items.map((j) => this._serverUserFromCrud(j));
|
|
904
|
+
result.nextCursor = crud.pagination?.next_cursor ?? null;
|
|
905
|
+
return result;
|
|
906
|
+
}
|
|
907
|
+
_serverPermissionFromCrud(crud) {
|
|
908
|
+
return { id: crud.id };
|
|
909
|
+
}
|
|
910
|
+
_serverTeamPermissionDefinitionFromCrud(crud) {
|
|
911
|
+
return {
|
|
912
|
+
id: crud.id,
|
|
913
|
+
description: crud.description,
|
|
914
|
+
containedPermissionIds: crud.contained_permission_ids
|
|
915
|
+
};
|
|
916
|
+
}
|
|
917
|
+
_serverProjectPermissionDefinitionFromCrud(crud) {
|
|
918
|
+
return {
|
|
919
|
+
id: crud.id,
|
|
920
|
+
description: crud.description,
|
|
921
|
+
containedPermissionIds: crud.contained_permission_ids
|
|
922
|
+
};
|
|
923
|
+
}
|
|
924
|
+
async getItem(options) {
|
|
925
|
+
if ("userId" in options) {
|
|
926
|
+
const result = Result.orThrow(await this._serverUserItemsCache.getOrWait([options.userId, options.itemId], "write-only"));
|
|
927
|
+
return this._serverItemFromCrud({
|
|
928
|
+
type: "user",
|
|
929
|
+
id: options.userId
|
|
930
|
+
}, result);
|
|
931
|
+
} else if ("teamId" in options) {
|
|
932
|
+
const result = Result.orThrow(await this._serverTeamItemsCache.getOrWait([options.teamId, options.itemId], "write-only"));
|
|
933
|
+
return this._serverItemFromCrud({
|
|
934
|
+
type: "team",
|
|
935
|
+
id: options.teamId
|
|
936
|
+
}, result);
|
|
937
|
+
} else {
|
|
938
|
+
const result = Result.orThrow(await this._serverCustomItemsCache.getOrWait([options.customCustomerId, options.itemId], "write-only"));
|
|
939
|
+
return this._serverItemFromCrud({
|
|
940
|
+
type: "custom",
|
|
941
|
+
id: options.customCustomerId
|
|
942
|
+
}, result);
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
async listProducts(options) {
|
|
946
|
+
if ("userId" in options) {
|
|
947
|
+
const response = Result.orThrow(await this._serverUserProductsCache.getOrWait([
|
|
948
|
+
options.userId,
|
|
949
|
+
options.cursor ?? null,
|
|
950
|
+
options.limit ?? null
|
|
951
|
+
], "write-only"));
|
|
952
|
+
return this._customerProductsFromResponse(response);
|
|
953
|
+
} else if ("teamId" in options) {
|
|
954
|
+
const response = Result.orThrow(await this._serverTeamProductsCache.getOrWait([
|
|
955
|
+
options.teamId,
|
|
956
|
+
options.cursor ?? null,
|
|
957
|
+
options.limit ?? null
|
|
958
|
+
], "write-only"));
|
|
959
|
+
return this._customerProductsFromResponse(response);
|
|
960
|
+
}
|
|
961
|
+
const response = Result.orThrow(await this._serverCustomProductsCache.getOrWait([
|
|
962
|
+
options.customCustomerId,
|
|
963
|
+
options.cursor ?? null,
|
|
964
|
+
options.limit ?? null
|
|
965
|
+
], "write-only"));
|
|
966
|
+
return this._customerProductsFromResponse(response);
|
|
967
|
+
}
|
|
968
|
+
async grantProduct(options) {
|
|
969
|
+
let customerType;
|
|
970
|
+
let customerId;
|
|
971
|
+
if ("userId" in options) {
|
|
972
|
+
customerType = "user";
|
|
973
|
+
customerId = options.userId;
|
|
974
|
+
} else if ("teamId" in options) {
|
|
975
|
+
customerType = "team";
|
|
976
|
+
customerId = options.teamId;
|
|
977
|
+
} else {
|
|
978
|
+
customerType = "custom";
|
|
979
|
+
customerId = options.customCustomerId;
|
|
980
|
+
}
|
|
981
|
+
await this._interface.grantProduct({
|
|
982
|
+
customerType,
|
|
983
|
+
customerId,
|
|
984
|
+
productId: "productId" in options ? options.productId : void 0,
|
|
985
|
+
product: "product" in options ? options.product : void 0,
|
|
986
|
+
quantity: options.quantity
|
|
987
|
+
});
|
|
988
|
+
await (customerType === "user" ? this._serverUserProductsCache : customerType === "team" ? this._serverTeamProductsCache : this._serverCustomProductsCache).refresh([
|
|
989
|
+
customerId,
|
|
990
|
+
null,
|
|
991
|
+
null
|
|
992
|
+
]);
|
|
993
|
+
}
|
|
994
|
+
async createTeam(data) {
|
|
995
|
+
const team = await this._interface.createServerTeam(serverTeamCreateOptionsToCrud(data));
|
|
996
|
+
await this._serverTeamsCache.refreshWhere(() => true);
|
|
997
|
+
return this._serverTeamFromCrud(team);
|
|
998
|
+
}
|
|
999
|
+
async listTeams(options) {
|
|
1000
|
+
const crud = Result.orThrow(await this._serverTeamsCache.getOrWait([
|
|
1001
|
+
void 0,
|
|
1002
|
+
options?.orderBy,
|
|
1003
|
+
options?.desc,
|
|
1004
|
+
options?.cursor,
|
|
1005
|
+
options?.limit,
|
|
1006
|
+
options?.query
|
|
1007
|
+
], "write-only"));
|
|
1008
|
+
const teams = crud.items.map((t) => this._serverTeamFromCrud(t));
|
|
1009
|
+
teams.nextCursor = crud.pagination?.next_cursor ?? null;
|
|
1010
|
+
return teams;
|
|
1011
|
+
}
|
|
1012
|
+
async listTeamMemberPermissions(teamId, options) {
|
|
1013
|
+
const recursive = options?.recursive ?? false;
|
|
1014
|
+
return Result.orThrow(await this._serverAllTeamMemberPermissionsCache.getOrWait([teamId, recursive], "write-only")).map((r) => ({
|
|
1015
|
+
userId: r.user_id,
|
|
1016
|
+
permissionId: r.id
|
|
1017
|
+
}));
|
|
1018
|
+
}
|
|
1019
|
+
async getTeam(options) {
|
|
1020
|
+
if (typeof options === "object" && "apiKey" in options) return await this._getTeamByApiKey(options.apiKey);
|
|
1021
|
+
else {
|
|
1022
|
+
const teamId = options;
|
|
1023
|
+
return (await this.listTeams()).find((t) => t.id === teamId) ?? null;
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
_createServerDataVaultStore(id) {
|
|
1027
|
+
const validateOptions = (options) => {
|
|
1028
|
+
if (typeof options.secret !== "string") throw new Error("secret must be a string, got " + typeof options.secret);
|
|
1029
|
+
};
|
|
1030
|
+
return {
|
|
1031
|
+
id,
|
|
1032
|
+
setValue: async (key, value, options) => {
|
|
1033
|
+
validateOptions(options);
|
|
1034
|
+
await this._interface.setDataVaultStoreValue(options.secret, id, key, value);
|
|
1035
|
+
},
|
|
1036
|
+
getValue: async (key, options) => {
|
|
1037
|
+
validateOptions(options);
|
|
1038
|
+
return Result.orThrow(await this._serverDataVaultStoreValueCache.getOrWait([
|
|
1039
|
+
id,
|
|
1040
|
+
key,
|
|
1041
|
+
options.secret
|
|
1042
|
+
], "write-only"));
|
|
1043
|
+
}
|
|
1044
|
+
};
|
|
1045
|
+
}
|
|
1046
|
+
async getDataVaultStore(id) {
|
|
1047
|
+
return this._createServerDataVaultStore(id);
|
|
1048
|
+
}
|
|
1049
|
+
async sendEmail(options) {
|
|
1050
|
+
await this._interface.sendEmail(options);
|
|
1051
|
+
await this._emailDeliveryInfoCache.refresh([]);
|
|
1052
|
+
}
|
|
1053
|
+
async getEmailDeliveryStats() {
|
|
1054
|
+
return Result.orThrow(await this._emailDeliveryInfoCache.getOrWait([], "write-only"));
|
|
1055
|
+
}
|
|
1056
|
+
async activateEmailCapacityBoost() {
|
|
1057
|
+
await this._interface.activateEmailCapacityBoost();
|
|
1058
|
+
await this._emailDeliveryInfoCache.refresh([]);
|
|
1059
|
+
}
|
|
1060
|
+
async _refreshSession(session) {
|
|
1061
|
+
await Promise.all([super._refreshUser(session), this._currentServerUserCache.refresh([session])]);
|
|
1062
|
+
}
|
|
1063
|
+
async _refreshUsers() {
|
|
1064
|
+
await Promise.all([
|
|
1065
|
+
super._refreshUsers(),
|
|
1066
|
+
this._serverUserCache.refreshWhere(() => true),
|
|
1067
|
+
this._serverUsersCache.refreshWhere(() => true),
|
|
1068
|
+
this._serverContactChannelsCache.refreshWhere(() => true),
|
|
1069
|
+
this._serverOAuthProvidersCache.refreshWhere(() => true),
|
|
1070
|
+
this._serverUserConnectedAccountsCache.refreshWhere(() => true)
|
|
1071
|
+
]);
|
|
1072
|
+
}
|
|
1073
|
+
async createOAuthProvider(options) {
|
|
1074
|
+
try {
|
|
1075
|
+
const crud = await this._interface.createServerOAuthProvider({
|
|
1076
|
+
user_id: options.userId,
|
|
1077
|
+
provider_config_id: options.providerConfigId,
|
|
1078
|
+
account_id: options.accountId,
|
|
1079
|
+
email: options.email,
|
|
1080
|
+
allow_sign_in: options.allowSignIn,
|
|
1081
|
+
allow_connected_accounts: options.allowConnectedAccounts
|
|
1082
|
+
});
|
|
1083
|
+
await Promise.all([this._serverOAuthProvidersCache.refresh([options.userId]), this._serverUserConnectedAccountsCache.refresh([options.userId])]);
|
|
1084
|
+
return Result.ok(this._serverOAuthProviderFromCrud(crud));
|
|
1085
|
+
} catch (error) {
|
|
1086
|
+
if (KnownErrors.OAuthProviderAccountIdAlreadyUsedForSignIn.isInstance(error)) return Result.error(error);
|
|
1087
|
+
throw error;
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
};
|
|
1091
|
+
|
|
1092
|
+
//#endregion
|
|
1093
|
+
export { _StackServerAppImplIncomplete };
|
|
1094
|
+
//# sourceMappingURL=server-app-impl.js.map
|