@stytch/react 19.4.3 → 19.5.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.
Files changed (52) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +7 -7
  3. package/b2b/headless/package.json +6 -0
  4. package/b2b/ui/package.json +6 -0
  5. package/dist/StytchB2BContext-9c062712.d.ts +272 -0
  6. package/dist/{StytchB2BContext-081081ee.js → StytchB2BContext-9c062712.js} +94 -49
  7. package/dist/StytchB2BContext-c5062f9b.d.ts +272 -0
  8. package/dist/StytchB2BContext-c5062f9b.js +280 -0
  9. package/dist/StytchSSRProxy-34c789b5.d.ts +3 -0
  10. package/dist/StytchSSRProxy-34c789b5.js +48 -0
  11. package/dist/StytchSSRProxy-86bc42b3.d.ts +3 -0
  12. package/dist/StytchSSRProxy-86bc42b3.js +54 -0
  13. package/dist/adminPortal/index.d.ts +1 -1
  14. package/dist/adminPortal/index.esm.d.ts +1 -1
  15. package/dist/adminPortal/index.esm.js +5 -4
  16. package/dist/adminPortal/index.js +5 -4
  17. package/dist/b2b/index.d.ts +180 -19
  18. package/dist/b2b/index.esm.d.ts +180 -19
  19. package/dist/b2b/index.esm.js +91 -18
  20. package/dist/b2b/index.headless.d.ts +16 -0
  21. package/dist/b2b/index.headless.esm.d.ts +16 -0
  22. package/dist/b2b/index.headless.esm.js +24 -0
  23. package/dist/b2b/index.headless.js +28 -0
  24. package/dist/b2b/index.js +99 -26
  25. package/dist/b2b/index.ui.d.ts +17 -0
  26. package/dist/b2b/index.ui.esm.d.ts +17 -0
  27. package/dist/b2b/index.ui.esm.js +25 -0
  28. package/dist/b2b/index.ui.js +29 -0
  29. package/dist/errors-d9d5fbc8.d.ts +5 -0
  30. package/dist/index-b14d4efe.d.ts +1 -1
  31. package/dist/index.d.ts +134 -77
  32. package/dist/index.esm.d.ts +134 -77
  33. package/dist/index.esm.js +153 -94
  34. package/dist/index.headless.d.ts +16 -0
  35. package/dist/index.headless.esm.d.ts +16 -0
  36. package/dist/index.headless.esm.js +24 -0
  37. package/dist/index.headless.js +28 -0
  38. package/dist/index.js +167 -108
  39. package/dist/index.ui.d.ts +17 -0
  40. package/dist/index.ui.esm.d.ts +17 -0
  41. package/dist/index.ui.esm.js +25 -0
  42. package/dist/index.ui.js +29 -0
  43. package/dist/useIsomorphicLayoutEffect-1babb81e.d.ts +24 -0
  44. package/dist/{invariant-568a7633.js → useIsomorphicLayoutEffect-1babb81e.js} +5 -13
  45. package/dist/useIsomorphicLayoutEffect-65746ef3.d.ts +24 -0
  46. package/dist/{invariant-ae5a5bce.js → useIsomorphicLayoutEffect-65746ef3.js} +4 -16
  47. package/package.json +5 -3
  48. package/dist/StytchB2BContext-081081ee.d.ts +0 -165
  49. package/dist/StytchB2BContext-865b6947.d.ts +0 -165
  50. package/dist/StytchB2BContext-865b6947.js +0 -235
  51. package/dist/invariant-568a7633.d.ts +0 -27
  52. package/dist/invariant-ae5a5bce.d.ts +0 -27
@@ -0,0 +1,272 @@
1
+ /// <reference types="react" />
2
+ import React from 'react';
3
+ import { ReactNode } from "react";
4
+ import { PermissionsMap } from '@stytch/core/public';
5
+ import { Member, MemberSession, Organization, StytchB2BUIClient } from '@stytch/vanilla-js/b2b';
6
+ import { StytchB2BHeadlessClient, StytchProjectConfigurationInput } from '@stytch/vanilla-js/b2b/headless';
7
+ /**
8
+ * The Stytch Client object passed in to <StytchB2BProvider /> in your application root.
9
+ * Either a StytchB2BUIClient or StytchB2BHeadlessClient.
10
+ */
11
+ type StytchB2BClient<TProjectConfiguration extends StytchProjectConfigurationInput> = StytchB2BHeadlessClient<TProjectConfiguration> | StytchB2BUIClient<TProjectConfiguration>;
12
+ type SWRMemberUninitialized = {
13
+ /**
14
+ * Either the active {@link Member} object, or null if the member is not logged in.
15
+ */
16
+ member: null;
17
+ /**
18
+ * If true, indicates that the value returned is from the application cache and a state refresh is in progress.
19
+ */
20
+ fromCache: false;
21
+ /**
22
+ * If true, indicates that the SDK has completed initialization.
23
+ */
24
+ isInitialized: false;
25
+ };
26
+ type SWRMemberInitialized = {
27
+ /**
28
+ * Either the active {@link Member} object, or null if the member is not logged in.
29
+ */
30
+ member: Member | null;
31
+ /**
32
+ * If true, indicates that the value returned is from the application cache and a state refresh is in progress.
33
+ */
34
+ fromCache: boolean;
35
+ /**
36
+ * If true, indicates that the SDK has completed initialization.
37
+ */
38
+ isInitialized: true;
39
+ };
40
+ type SWRMember<TAlwaysInitialized extends boolean = boolean> = TAlwaysInitialized extends true ? SWRMemberInitialized : SWRMemberInitialized | SWRMemberUninitialized;
41
+ type SWRMemberSessionUninitialized = {
42
+ /**
43
+ * Either the active {@link MemberSession} object, or null if the member is not logged in.
44
+ */
45
+ session: null;
46
+ /**
47
+ * If true, indicates that the value returned is from the application cache and a state refresh is in progress.
48
+ */
49
+ fromCache: false;
50
+ /**
51
+ * If true, indicates that the SDK has completed initialization.
52
+ */
53
+ isInitialized: false;
54
+ };
55
+ type SWRMemberSessionInitialized = {
56
+ /**
57
+ * Either the active {@link MemberSession} object, or null if the member is not logged in.
58
+ */
59
+ session: MemberSession | null;
60
+ /**
61
+ * If true, indicates that the value returned is from the application cache and a state refresh is in progress.
62
+ */
63
+ fromCache: boolean;
64
+ /**
65
+ * If true, indicates that the SDK has completed initialization.
66
+ */
67
+ isInitialized: true;
68
+ };
69
+ type SWRMemberSession<TAlwaysInitialized extends boolean = boolean> = TAlwaysInitialized extends true ? SWRMemberSessionInitialized : SWRMemberSessionInitialized | SWRMemberSessionUninitialized;
70
+ type SWROrganizationUninitialized = {
71
+ /**
72
+ * Either the active {@link Organization} object, or null if the member is not logged in.
73
+ */
74
+ organization: null;
75
+ /**
76
+ * If true, indicates that the value returned is from the application cache and a state refresh is in progress.
77
+ */
78
+ fromCache: false;
79
+ /**
80
+ * If true, indicates that the SDK has completed initialization.
81
+ */
82
+ isInitialized: false;
83
+ };
84
+ type SWROrganizationInitialized = {
85
+ /**
86
+ * Either the active {@link Organization} object, or null if the member is not logged in.
87
+ */
88
+ organization: Organization | null;
89
+ /**
90
+ * If true, indicates that the value returned is from the application cache and a state refresh is in progress.
91
+ */
92
+ fromCache: boolean;
93
+ /**
94
+ * If true, indicates that the SDK has completed initialization.
95
+ */
96
+ isInitialized: true;
97
+ };
98
+ type SWROrganization<TAlwaysInitialized extends boolean = boolean> = TAlwaysInitialized extends true ? SWROrganizationInitialized : SWROrganizationInitialized | SWROrganizationUninitialized;
99
+ declare const useIsMounted__INTERNAL: () => boolean;
100
+ declare const isUIClient: <TProjectConfiguration extends Partial<import("@stytch/core/public").StytchProjectConfiguration>>(client: StytchB2BClient<TProjectConfiguration>) => client is StytchB2BUIClient<TProjectConfiguration>;
101
+ /**
102
+ * Returns the active Member.
103
+ * The Stytch SDKs are used for client-side authentication and session management.
104
+ * Check the isInitialized property to determine if the SDK has completed initialization.
105
+ * Check the fromCache property to determine if the member data is from persistent storage.
106
+ * @example
107
+ * const {member, isInitialized, fromCache} = useStytchMember();
108
+ * if (!isInitialized) {
109
+ * return <p>Loading...</p>;
110
+ * }
111
+ * return (<h1>Welcome, {member.name}</h1>);
112
+ */
113
+ declare const useStytchMember: <TAssumeHydrated extends boolean = false>() => SWRMember<TAssumeHydrated>;
114
+ /**
115
+ * Returns the active member's Stytch member session.
116
+ * The Stytch SDKs are used for client-side authentication and session management.
117
+ * Check the isInitialized property to determine if the SDK has completed initialization.
118
+ * Check the fromCache property to determine if the session data is from persistent storage.
119
+ * @example
120
+ * const {session, isInitialized, fromCache} = useStytchMemberSession();
121
+ * useEffect(() => {
122
+ * if (!isInitialized) {
123
+ * return;
124
+ * }
125
+ * if (!session) {
126
+ * router.replace('/login')
127
+ * }
128
+ * }, [session, isInitialized]);
129
+ */
130
+ declare const useStytchMemberSession: <TAssumeHydrated extends boolean = false>() => SWRMemberSession<TAssumeHydrated>;
131
+ /**
132
+ * Returns the active Stytch organization.
133
+ * The Stytch SDKs are used for client-side authentication and session management.
134
+ * Check the isInitialized property to determine if the SDK has completed initialization.
135
+ * Check the fromCache property to determine if the organization data is from persistent storage.
136
+ * @example
137
+ * const {organization, isInitialized, fromCache} = useStytchOrganization();
138
+ * if (!isInitialized) {
139
+ * return <p>Loading...</p>;
140
+ * }
141
+ * return (<p>Welcome to {organization.organization_name}</p>);
142
+ */
143
+ declare const useStytchOrganization: <TAssumeHydrated extends boolean = false>() => SWROrganization<TAssumeHydrated>;
144
+ type SWRIsAuthorizedUninitialized = {
145
+ /**
146
+ * Whether the logged-in member is allowed to perform the specified action on the specified resource.
147
+ */
148
+ isAuthorized: false;
149
+ /**
150
+ * If true, indicates that the value returned is from the application cache and a state refresh is in progress.
151
+ */
152
+ fromCache: false;
153
+ /**
154
+ * If true, indicates that the SDK has completed initialization.
155
+ */
156
+ isInitialized: false;
157
+ };
158
+ type SWRIsAuthorizedInitialized = {
159
+ /**
160
+ * Whether the logged-in member is allowed to perform the specified action on the specified resource.
161
+ */
162
+ isAuthorized: boolean;
163
+ /**
164
+ * If true, indicates that the value returned is from the application cache and a state refresh is in progress.
165
+ */
166
+ fromCache: boolean;
167
+ /**
168
+ * If true, indicates that the SDK has completed initialization.
169
+ */
170
+ isInitialized: boolean;
171
+ };
172
+ type SWRIsAuthorized<TAlwaysInitialized extends boolean> = TAlwaysInitialized extends true ? SWRIsAuthorizedInitialized : SWRIsAuthorizedInitialized | SWRIsAuthorizedUninitialized;
173
+ /**
174
+ * Determines whether the logged-in member is allowed to perform the specified action on the specified resource.
175
+ * Returns `true` if the member can perform the action, `false` otherwise.
176
+ *
177
+ * If the member is not logged in, this method will always return false.
178
+ * If the resource or action provided are not valid for the configured RBAC policy, this method will return false.
179
+ *
180
+ * Remember - authorization checks for sensitive actions should always occur on the backend as well.
181
+ * @example
182
+ * const { isAuthorized } = useStytchIsAuthorized<Permissions>('documents', 'edit');
183
+ * return <button disabled={!isAuthorized}>Edit</button>
184
+ */
185
+ declare const useStytchIsAuthorized: <TAssumeHydrated extends boolean = false>(resourceId: string, action: string) => SWRIsAuthorized<TAssumeHydrated>;
186
+ /**
187
+ * Returns the Stytch B2B client stored in the Stytch context.
188
+ *
189
+ * @example
190
+ * const stytch = useStytchB2BClient();
191
+ * useEffect(() => {
192
+ * stytch.magicLinks.authenticate('...')
193
+ * }, [stytch]);
194
+ */
195
+ declare const useStytchB2BClient: <TProjectConfiguration extends Partial<import("@stytch/core/public").StytchProjectConfiguration> = Stytch.DefaultProjectConfiguration>() => StytchB2BHeadlessClient<TProjectConfiguration>;
196
+ declare const withStytchB2BClient: <T extends object, TProjectConfiguration extends Partial<import("@stytch/core/public").StytchProjectConfiguration>>(Component: React.ComponentType<T & {
197
+ stytch: StytchB2BHeadlessClient<TProjectConfiguration>;
198
+ }>) => React.ComponentType<T>;
199
+ declare const withStytchMember: <T extends object, TAssumeHydrated extends boolean = false>(Component: React.ComponentType<T & {
200
+ stytchMember: Member | null;
201
+ stytchMemberIsInitialized: boolean;
202
+ stytchMemberIsFromCache: boolean;
203
+ }>) => React.ComponentType<T>;
204
+ declare const withStytchMemberSession: <T extends object, TAssumeHydrated extends boolean = false>(Component: React.ComponentType<T & {
205
+ stytchMemberSession: MemberSession | null;
206
+ stytchMemberSessionIsInitialized: boolean;
207
+ stytchMemberSessionIsFromCache: boolean;
208
+ }>) => React.ComponentType<T>;
209
+ declare const withStytchOrganization: <T extends object, TAssumeHydrated extends boolean = false>(Component: React.ComponentType<T & {
210
+ stytchOrganization: Organization | null;
211
+ stytchOrganizationIsInitialized: boolean;
212
+ stytchOrganizationIsFromCache: boolean;
213
+ }>) => React.ComponentType<T>;
214
+ /**
215
+ * Wrap your component with this HOC in order to receive the permissions for the logged-in member.
216
+ * Evaluates all permissions granted to the logged-in member.
217
+ * Returns a Record<RoleId, Record<Action, boolean>> response indicating the member's permissions.
218
+ * Each boolean will be `true` if the member can perform the action, `false` otherwise.
219
+ *
220
+ * If the member is not logged in, all values will be false.
221
+ *
222
+ * Remember - authorization checks for sensitive actions should always occur on the backend as well.
223
+ * @example
224
+ * type Permissions = {
225
+ * document: 'create' | 'read' | 'write
226
+ * image: 'create' | 'read'
227
+ * }
228
+ *
229
+ * const MyComponent = (props) => {
230
+ * const canEditDocuments = props.stytchPermissions.document.edit;
231
+ * const canReadImages = props.stytchPermissions.image.read;
232
+ * }
233
+ * return withStytchPermissions<Permissions>(MyComponent)
234
+ */
235
+ declare const withStytchPermissions: <Permissions_1 extends Record<string, string>, T extends object>(Component: React.ComponentType<T & {
236
+ stytchPermissions: PermissionsMap<Permissions_1>;
237
+ }>) => React.ComponentType<T>;
238
+ interface StytchB2BProviderProps<TProjectConfiguration extends StytchProjectConfigurationInput = Stytch.DefaultProjectConfiguration> {
239
+ /**
240
+ * A Stytch client instance, created using either {@link createStytchHeadlessClient} or {@link createStytchUIClient}
241
+ */
242
+ stytch: StytchB2BClient<TProjectConfiguration>;
243
+ /**
244
+ * When true, the provider will assume that the component will only be
245
+ * rendered in a browser environment, either in a single-page application or
246
+ * after completing hydration of a server-rendered application. This allows
247
+ * cached values to be retrieved from the browser on the first render, meaning
248
+ * that the `isInitialized` value returned from Stytch hooks will be `true`
249
+ * starting from the first render.
250
+ *
251
+ * When `false`, the provider will defer initialization until after the first
252
+ * render, and `isInitialized` will initially be `false`.
253
+ *
254
+ * This value defaults to `false` in `@stytch/nextjs`.
255
+ */
256
+ assumeHydrated?: boolean;
257
+ children?: ReactNode;
258
+ }
259
+ /**
260
+ * The Stytch Context Provider.
261
+ * Wrap your application with this component in order to use Stytch everywhere in your app.
262
+ * @example
263
+ * const stytch = createStytchB2BHeadlessClient('public-token-<find yours in the stytch dashboard>')
264
+ *
265
+ * return (
266
+ * <StytchB2BProvider stytch={stytch}>
267
+ * <App />
268
+ * </StytchB2BProvider>
269
+ * )
270
+ */
271
+ declare const StytchB2BProvider: <TProjectConfiguration extends Partial<import("@stytch/core/public").StytchProjectConfiguration> = Stytch.DefaultProjectConfiguration>({ stytch, children, assumeHydrated, }: StytchB2BProviderProps<TProjectConfiguration>) => JSX.Element;
272
+ export { useIsMounted__INTERNAL, isUIClient, useStytchMember, useStytchMemberSession, useStytchOrganization, useStytchIsAuthorized, useStytchB2BClient, withStytchB2BClient, withStytchMember, withStytchMemberSession, withStytchOrganization, withStytchPermissions, StytchB2BProviderProps, StytchB2BProvider };
@@ -0,0 +1,280 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+ var useIsomorphicLayoutEffect = require('./useIsomorphicLayoutEffect-65746ef3.js');
5
+ var StytchSSRProxy = require('./StytchSSRProxy-86bc42b3.js');
6
+
7
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
8
+
9
+ var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
10
+
11
+ const initialMember = {
12
+ member: null,
13
+ fromCache: false,
14
+ isInitialized: false,
15
+ };
16
+ const initialMemberSession = {
17
+ session: null,
18
+ fromCache: false,
19
+ isInitialized: false,
20
+ };
21
+ const initialOrganization = {
22
+ organization: null,
23
+ fromCache: false,
24
+ isInitialized: false,
25
+ };
26
+ const StytchB2BContext = React.createContext({ isMounted: false });
27
+ const StytchMemberContext = React.createContext(initialMember);
28
+ const StytchMemberSessionContext = React.createContext(initialMemberSession);
29
+ const StytchOrganizationContext = React.createContext(initialOrganization);
30
+ const useIsMounted__INTERNAL = () => React.useContext(StytchB2BContext).isMounted;
31
+ const isUIClient = (client) => {
32
+ return client.mount !== undefined;
33
+ };
34
+ /**
35
+ * Returns the active Member.
36
+ * The Stytch SDKs are used for client-side authentication and session management.
37
+ * Check the isInitialized property to determine if the SDK has completed initialization.
38
+ * Check the fromCache property to determine if the member data is from persistent storage.
39
+ * @example
40
+ * const {member, isInitialized, fromCache} = useStytchMember();
41
+ * if (!isInitialized) {
42
+ * return <p>Loading...</p>;
43
+ * }
44
+ * return (<h1>Welcome, {member.name}</h1>);
45
+ */
46
+ const useStytchMember = () => {
47
+ useIsomorphicLayoutEffect.invariant(useIsMounted__INTERNAL(), StytchSSRProxy.noProviderError('useStytchMember', 'StytchB2BProvider'));
48
+ return React.useContext(StytchMemberContext);
49
+ };
50
+ /**
51
+ * Returns the active member's Stytch member session.
52
+ * The Stytch SDKs are used for client-side authentication and session management.
53
+ * Check the isInitialized property to determine if the SDK has completed initialization.
54
+ * Check the fromCache property to determine if the session data is from persistent storage.
55
+ * @example
56
+ * const {session, isInitialized, fromCache} = useStytchMemberSession();
57
+ * useEffect(() => {
58
+ * if (!isInitialized) {
59
+ * return;
60
+ * }
61
+ * if (!session) {
62
+ * router.replace('/login')
63
+ * }
64
+ * }, [session, isInitialized]);
65
+ */
66
+ const useStytchMemberSession = () => {
67
+ useIsomorphicLayoutEffect.invariant(useIsMounted__INTERNAL(), StytchSSRProxy.noProviderError('useStytchMemberSession', 'StytchB2BProvider'));
68
+ return React.useContext(StytchMemberSessionContext);
69
+ };
70
+ /**
71
+ * Returns the active Stytch organization.
72
+ * The Stytch SDKs are used for client-side authentication and session management.
73
+ * Check the isInitialized property to determine if the SDK has completed initialization.
74
+ * Check the fromCache property to determine if the organization data is from persistent storage.
75
+ * @example
76
+ * const {organization, isInitialized, fromCache} = useStytchOrganization();
77
+ * if (!isInitialized) {
78
+ * return <p>Loading...</p>;
79
+ * }
80
+ * return (<p>Welcome to {organization.organization_name}</p>);
81
+ */
82
+ const useStytchOrganization = () => {
83
+ useIsomorphicLayoutEffect.invariant(useIsMounted__INTERNAL(), StytchSSRProxy.noProviderError('useStytchOrganization', 'StytchB2BProvider'));
84
+ return React.useContext(StytchOrganizationContext);
85
+ };
86
+ /**
87
+ * Determines whether the logged-in member is allowed to perform the specified action on the specified resource.
88
+ * Returns `true` if the member can perform the action, `false` otherwise.
89
+ *
90
+ * If the member is not logged in, this method will always return false.
91
+ * If the resource or action provided are not valid for the configured RBAC policy, this method will return false.
92
+ *
93
+ * Remember - authorization checks for sensitive actions should always occur on the backend as well.
94
+ * @example
95
+ * const { isAuthorized } = useStytchIsAuthorized<Permissions>('documents', 'edit');
96
+ * return <button disabled={!isAuthorized}>Edit</button>
97
+ */
98
+ const useStytchIsAuthorized = (resourceId, action) => {
99
+ useIsomorphicLayoutEffect.invariant(useIsMounted__INTERNAL(), StytchSSRProxy.noProviderError('useStytchIsAuthorized', 'StytchB2BProvider'));
100
+ const client = useStytchB2BClient();
101
+ const { session } = useStytchMemberSession();
102
+ const [isAuthorized, setIsAuthorized] = useIsomorphicLayoutEffect.useAsyncState({
103
+ isInitialized: false,
104
+ fromCache: false,
105
+ isAuthorized: false,
106
+ });
107
+ React.useEffect(() => {
108
+ if (StytchSSRProxy.isStytchSSRProxy(client)) {
109
+ return;
110
+ }
111
+ setIsAuthorized({
112
+ isInitialized: true,
113
+ fromCache: true,
114
+ isAuthorized: client.rbac.isAuthorizedSync(resourceId, action),
115
+ });
116
+ }, [action, client, resourceId, setIsAuthorized]);
117
+ React.useEffect(() => {
118
+ if (StytchSSRProxy.isStytchSSRProxy(client)) {
119
+ return;
120
+ }
121
+ client.rbac.isAuthorized(resourceId, action).then((isAuthorized) => {
122
+ setIsAuthorized({ isAuthorized, fromCache: false, isInitialized: true });
123
+ });
124
+ }, [client, session === null || session === void 0 ? void 0 : session.roles, resourceId, action, setIsAuthorized]);
125
+ return isAuthorized;
126
+ };
127
+ /**
128
+ * Returns the Stytch B2B client stored in the Stytch context.
129
+ *
130
+ * @example
131
+ * const stytch = useStytchB2BClient();
132
+ * useEffect(() => {
133
+ * stytch.magicLinks.authenticate('...')
134
+ * }, [stytch]);
135
+ */
136
+ const useStytchB2BClient = () => {
137
+ const ctx = React.useContext(StytchB2BContext);
138
+ useIsomorphicLayoutEffect.invariant(ctx.isMounted, StytchSSRProxy.noProviderError('useStytchB2BClient', 'StytchB2BProvider'));
139
+ return ctx.client;
140
+ };
141
+ const withStytchB2BClient = (Component) => {
142
+ const WithStytch = (props) => {
143
+ useIsomorphicLayoutEffect.invariant(useIsMounted__INTERNAL(), StytchSSRProxy.noProviderError('withStytchB2BClient', 'StytchB2BProvider'));
144
+ return React__default["default"].createElement(Component, Object.assign({}, props, { stytch: useStytchB2BClient() }));
145
+ };
146
+ WithStytch.displayName = `withStytch(${Component.displayName || Component.name || 'Component'})`;
147
+ return WithStytch;
148
+ };
149
+ const withStytchMember = (Component) => {
150
+ const WithStytchUser = (props) => {
151
+ useIsomorphicLayoutEffect.invariant(useIsMounted__INTERNAL(), StytchSSRProxy.noProviderError('withStytchMember', 'StytchB2BProvider'));
152
+ const { member, isInitialized, fromCache } = useStytchMember();
153
+ return (React__default["default"].createElement(Component, Object.assign({}, props, { stytchMember: member, stytchMemberIsInitialized: isInitialized, stytchMemberIsFromCache: fromCache })));
154
+ };
155
+ WithStytchUser.displayName = `withStytchMember(${Component.displayName || Component.name || 'Component'})`;
156
+ return WithStytchUser;
157
+ };
158
+ const withStytchMemberSession = (Component) => {
159
+ const WithStytchSession = (props) => {
160
+ useIsomorphicLayoutEffect.invariant(useIsMounted__INTERNAL(), StytchSSRProxy.noProviderError('withStytchMemberSession', 'StytchB2BProvider'));
161
+ const { session, isInitialized, fromCache } = useStytchMemberSession();
162
+ return (React__default["default"].createElement(Component, Object.assign({}, props, { stytchMemberSession: session, stytchMemberSessionIsInitialized: isInitialized, stytchMemberSessionIsFromCache: fromCache })));
163
+ };
164
+ WithStytchSession.displayName = `withStytchMemberSession(${Component.displayName || Component.name || 'Component'})`;
165
+ return WithStytchSession;
166
+ };
167
+ const withStytchOrganization = (Component) => {
168
+ const WithStytchOrganization = (props) => {
169
+ useIsomorphicLayoutEffect.invariant(useIsMounted__INTERNAL(), StytchSSRProxy.noProviderError('withStytchOrganization', 'StytchB2BProvider'));
170
+ const { organization, isInitialized, fromCache } = useStytchOrganization();
171
+ return (React__default["default"].createElement(Component, Object.assign({}, props, { stytchOrganization: organization, stytchOrganizationIsInitialized: isInitialized, stytchOrganizationIsFromCache: fromCache })));
172
+ };
173
+ WithStytchOrganization.displayName = `withStytchOrganization(${Component.displayName || Component.name || 'Component'})`;
174
+ return WithStytchOrganization;
175
+ };
176
+ /**
177
+ * Wrap your component with this HOC in order to receive the permissions for the logged-in member.
178
+ * Evaluates all permissions granted to the logged-in member.
179
+ * Returns a Record<RoleId, Record<Action, boolean>> response indicating the member's permissions.
180
+ * Each boolean will be `true` if the member can perform the action, `false` otherwise.
181
+ *
182
+ * If the member is not logged in, all values will be false.
183
+ *
184
+ * Remember - authorization checks for sensitive actions should always occur on the backend as well.
185
+ * @example
186
+ * type Permissions = {
187
+ * document: 'create' | 'read' | 'write
188
+ * image: 'create' | 'read'
189
+ * }
190
+ *
191
+ * const MyComponent = (props) => {
192
+ * const canEditDocuments = props.stytchPermissions.document.edit;
193
+ * const canReadImages = props.stytchPermissions.image.read;
194
+ * }
195
+ * return withStytchPermissions<Permissions>(MyComponent)
196
+ */
197
+ const withStytchPermissions = (Component) => {
198
+ const WithStytchPermissions = (props) => {
199
+ useIsomorphicLayoutEffect.invariant(useIsMounted__INTERNAL(), StytchSSRProxy.noProviderError('useRBACPermissions', 'StytchB2BProvider'));
200
+ const client = useStytchB2BClient();
201
+ const { session } = useStytchMemberSession();
202
+ const [permissions, setPermissions] = useIsomorphicLayoutEffect.useAsyncState({ loaded: false, value: null });
203
+ React.useEffect(() => {
204
+ client.rbac
205
+ .allPermissions()
206
+ .then((permissions) => setPermissions({ loaded: true, value: permissions }));
207
+ }, [client, session === null || session === void 0 ? void 0 : session.roles, setPermissions]);
208
+ if (!permissions.loaded) {
209
+ return null;
210
+ }
211
+ return React__default["default"].createElement(Component, Object.assign({}, props, { stytchPermissions: permissions.value }));
212
+ };
213
+ WithStytchPermissions.displayName = `withStytchPermissions(${Component.displayName || Component.name || 'Component'})`;
214
+ return WithStytchPermissions;
215
+ };
216
+ /**
217
+ * The Stytch Context Provider.
218
+ * Wrap your application with this component in order to use Stytch everywhere in your app.
219
+ * @example
220
+ * const stytch = createStytchB2BHeadlessClient('public-token-<find yours in the stytch dashboard>')
221
+ *
222
+ * return (
223
+ * <StytchB2BProvider stytch={stytch}>
224
+ * <App />
225
+ * </StytchB2BProvider>
226
+ * )
227
+ */
228
+ const StytchB2BProvider = ({ stytch, children, assumeHydrated = false, }) => {
229
+ useIsomorphicLayoutEffect.invariant(!useIsMounted__INTERNAL(), 'You cannot render a <StytchB2BProvider> inside another <StytchB2BProvider>.');
230
+ useIsomorphicLayoutEffect.invariant(!assumeHydrated || typeof window !== 'undefined', 'The `assumeHydrated` prop must be set to `false` when using StytchB2BProvider in a server environment.');
231
+ const ctx = React.useMemo(() => ({ client: stytch, isMounted: true }), [stytch]);
232
+ const getHydratedState = React.useCallback(() => {
233
+ return {
234
+ member: Object.assign(Object.assign({}, stytch.self.getInfo()), { isInitialized: true }),
235
+ session: Object.assign(Object.assign({}, stytch.session.getInfo()), { isInitialized: true }),
236
+ organization: Object.assign(Object.assign({}, stytch.organization.getInfo()), { isInitialized: true }),
237
+ };
238
+ }, [stytch]);
239
+ const getInitialState = () => {
240
+ return {
241
+ member: initialMember,
242
+ session: initialMemberSession,
243
+ organization: initialOrganization,
244
+ };
245
+ };
246
+ const [{ member, session, organization }, setClientState] = useIsomorphicLayoutEffect.useAsyncState(() => assumeHydrated ? getHydratedState() : getInitialState());
247
+ // Store the initial value of `assumeHydrated` in a ref, because it is
248
+ // logically only relevant for the first render
249
+ const assumeHydratedRef = React.useRef(assumeHydrated);
250
+ React.useEffect(() => {
251
+ if (StytchSSRProxy.isStytchSSRProxy(stytch)) {
252
+ return;
253
+ }
254
+ const updateState = () => {
255
+ setClientState((oldState) => useIsomorphicLayoutEffect.mergeWithStableProps(oldState, getHydratedState()));
256
+ };
257
+ if (!assumeHydratedRef.current) {
258
+ updateState();
259
+ }
260
+ return stytch.onStateChange(updateState);
261
+ }, [getHydratedState, setClientState, stytch]);
262
+ return (React__default["default"].createElement(StytchB2BContext.Provider, { value: ctx },
263
+ React__default["default"].createElement(StytchOrganizationContext.Provider, { value: organization },
264
+ React__default["default"].createElement(StytchMemberContext.Provider, { value: member },
265
+ React__default["default"].createElement(StytchMemberSessionContext.Provider, { value: session }, children)))));
266
+ };
267
+
268
+ exports.StytchB2BProvider = StytchB2BProvider;
269
+ exports.isUIClient = isUIClient;
270
+ exports.useIsMounted__INTERNAL = useIsMounted__INTERNAL;
271
+ exports.useStytchB2BClient = useStytchB2BClient;
272
+ exports.useStytchIsAuthorized = useStytchIsAuthorized;
273
+ exports.useStytchMember = useStytchMember;
274
+ exports.useStytchMemberSession = useStytchMemberSession;
275
+ exports.useStytchOrganization = useStytchOrganization;
276
+ exports.withStytchB2BClient = withStytchB2BClient;
277
+ exports.withStytchMember = withStytchMember;
278
+ exports.withStytchMemberSession = withStytchMemberSession;
279
+ exports.withStytchOrganization = withStytchOrganization;
280
+ exports.withStytchPermissions = withStytchPermissions;
@@ -0,0 +1,3 @@
1
+ declare const isStytchSSRProxy: (proxy: any) => boolean;
2
+ declare const createStytchSSRProxy: () => any;
3
+ export { isStytchSSRProxy, createStytchSSRProxy };
@@ -0,0 +1,48 @@
1
+ const noProviderError = (item, provider = 'StytchProvider') => `${item} can only be used inside <${provider}>.`;
2
+ const providerMustBeUniqueError = 'You cannot render a <StytchProvider> inside another <StytchProvider>.';
3
+ const noHeadlessClientError = `Tried to create a Stytch Login UI element using the Stytch Headless SDK.
4
+ You must use the UI SDK to use UI elements.
5
+ Please make sure you are using a Stytch UI client, not a Stytch Headless client.`;
6
+ const cannotInvokeMethodOnServerError = (path) => `[Stytch] Invalid serverside function call to ${path}.
7
+ The Stytch Javascript SDK is intended to ony be used on the client side.
8
+ Make sure to wrap your API calls in a hook to ensure they are executed on the client.
9
+ \`\`\`
10
+ const myComponent = () => {
11
+ const stytch = useStytch();
12
+ // This will error out on the server.
13
+ stytch.magicLinks.authenticate(...);
14
+ useEffect(() => {
15
+ // This will work well
16
+ stytch.magicLinks.authenticate(...);
17
+ }, []);
18
+ }
19
+ \`\`\`
20
+
21
+ If you want to make API calls from server environments, please use the Stytch Node Library
22
+ https://www.npmjs.com/package/stytch.
23
+ `;
24
+
25
+ const SSRStubKey = Symbol('__stytch_SSRStubKey');
26
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
27
+ const isStytchSSRProxy = (proxy) => {
28
+ return !!proxy[SSRStubKey];
29
+ };
30
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
31
+ const createProxy = (path) => {
32
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
33
+ const noop = () => { };
34
+ return new Proxy(noop, {
35
+ get(target, p) {
36
+ if (p === SSRStubKey) {
37
+ return true;
38
+ }
39
+ return createProxy(path + '.' + String(p));
40
+ },
41
+ apply() {
42
+ throw new Error(cannotInvokeMethodOnServerError(path));
43
+ },
44
+ });
45
+ };
46
+ const createStytchSSRProxy = () => createProxy('stytch');
47
+
48
+ export { noHeadlessClientError as a, createStytchSSRProxy as c, isStytchSSRProxy as i, noProviderError as n, providerMustBeUniqueError as p };
@@ -0,0 +1,3 @@
1
+ declare const isStytchSSRProxy: (proxy: any) => boolean;
2
+ declare const createStytchSSRProxy: () => any;
3
+ export { isStytchSSRProxy, createStytchSSRProxy };
@@ -0,0 +1,54 @@
1
+ 'use strict';
2
+
3
+ const noProviderError = (item, provider = 'StytchProvider') => `${item} can only be used inside <${provider}>.`;
4
+ const providerMustBeUniqueError = 'You cannot render a <StytchProvider> inside another <StytchProvider>.';
5
+ const noHeadlessClientError = `Tried to create a Stytch Login UI element using the Stytch Headless SDK.
6
+ You must use the UI SDK to use UI elements.
7
+ Please make sure you are using a Stytch UI client, not a Stytch Headless client.`;
8
+ const cannotInvokeMethodOnServerError = (path) => `[Stytch] Invalid serverside function call to ${path}.
9
+ The Stytch Javascript SDK is intended to ony be used on the client side.
10
+ Make sure to wrap your API calls in a hook to ensure they are executed on the client.
11
+ \`\`\`
12
+ const myComponent = () => {
13
+ const stytch = useStytch();
14
+ // This will error out on the server.
15
+ stytch.magicLinks.authenticate(...);
16
+ useEffect(() => {
17
+ // This will work well
18
+ stytch.magicLinks.authenticate(...);
19
+ }, []);
20
+ }
21
+ \`\`\`
22
+
23
+ If you want to make API calls from server environments, please use the Stytch Node Library
24
+ https://www.npmjs.com/package/stytch.
25
+ `;
26
+
27
+ const SSRStubKey = Symbol('__stytch_SSRStubKey');
28
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
29
+ const isStytchSSRProxy = (proxy) => {
30
+ return !!proxy[SSRStubKey];
31
+ };
32
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
33
+ const createProxy = (path) => {
34
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
35
+ const noop = () => { };
36
+ return new Proxy(noop, {
37
+ get(target, p) {
38
+ if (p === SSRStubKey) {
39
+ return true;
40
+ }
41
+ return createProxy(path + '.' + String(p));
42
+ },
43
+ apply() {
44
+ throw new Error(cannotInvokeMethodOnServerError(path));
45
+ },
46
+ });
47
+ };
48
+ const createStytchSSRProxy = () => createProxy('stytch');
49
+
50
+ exports.createStytchSSRProxy = createStytchSSRProxy;
51
+ exports.isStytchSSRProxy = isStytchSSRProxy;
52
+ exports.noHeadlessClientError = noHeadlessClientError;
53
+ exports.noProviderError = noProviderError;
54
+ exports.providerMustBeUniqueError = providerMustBeUniqueError;
@@ -39,6 +39,6 @@ type AdminPortalSCIMProps<TProjectConfiguration extends StytchProjectConfigurati
39
39
  * See the {@link https://stytch.com/docs/b2b/sdks/javascript-sdk online reference}
40
40
  */
41
41
  declare const AdminPortalSCIM: <TProjectConfiguration extends Partial<import("@stytch/core/public").StytchProjectConfiguration> = Stytch.DefaultProjectConfiguration>(props: ExcludeInjectedOptions<AdminPortalSCIMMountOptions<Partial<import("@stytch/core/public").StytchProjectConfiguration>>>) => JSX.Element;
42
- export { AdminPortalSSO, AdminPortalOrgSettings, AdminPortalMemberManagement, AdminPortalSCIM };
43
42
  export { AdminPortalB2BProducts } from "@stytch/vanilla-js/b2b/adminPortal";
43
+ export { AdminPortalMemberManagement, AdminPortalOrgSettings, AdminPortalSCIM, AdminPortalSSO };
44
44
  export type { AdminPortalSSOProps, AdminPortalOrgSettingsProps, AdminPortalMemberManagementProps, AdminPortalSCIMProps };