@stytch/react 14.0.1 → 15.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/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # @stytch/react
2
2
 
3
+ ## 15.0.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 223e30e: Add `useStytchOrganization` hook for B2B
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [223e30e]
12
+ - @stytch/vanilla-js@4.2.0
13
+
3
14
  ## 14.0.1
4
15
 
5
16
  ### Patch Changes
@@ -1,7 +1,7 @@
1
1
  /// <reference types="react" />
2
2
  import React from "react";
3
3
  import { ReactNode } from "react";
4
- import { Member, MemberSession, StytchB2BUIClient } from "@stytch/vanilla-js/b2b";
4
+ import { Member, MemberSession, Organization, StytchB2BUIClient } from "@stytch/vanilla-js/b2b";
5
5
  import { StytchB2BHeadlessClient } from "@stytch/vanilla-js/b2b/headless";
6
6
  import { PermissionsMap } from "@stytch/core/public";
7
7
  import { Callbacks, StyleConfig, StytchB2BUIConfig } from "@stytch/vanilla-js";
@@ -29,6 +29,16 @@ type SWRMemberSession = {
29
29
  */
30
30
  fromCache: boolean;
31
31
  };
32
+ type SWROrganization = {
33
+ /**
34
+ * Either the active {@link Organization} object, or null if the user is not logged in.
35
+ */
36
+ organization: Organization | null;
37
+ /**
38
+ * If true, indicates that the value returned is from the application cache and a state refresh is in progress.
39
+ */
40
+ fromCache: boolean;
41
+ };
32
42
  /**
33
43
  * Returns the active Member.
34
44
  * Check the fromCache property to determine if the member data is from persistent storage.
@@ -50,6 +60,14 @@ declare const useStytchMember: () => SWRMember;
50
60
  * @returns A {@link SWRMemberSession}
51
61
  */
52
62
  declare const useStytchMemberSession: () => SWRMemberSession;
63
+ /**
64
+ * Returns the active Stytch organization.
65
+ * @example
66
+ * const { organization } = useStytchOrganization();
67
+ * return organization ? <p>Welcome to {organization.organization_name}</p> : <p>Log in to continue!</p>;
68
+ * @returns A {@link SWROrganization}
69
+ */
70
+ declare const useStytchOrganization: () => SWROrganization;
53
71
  type SWRIsAuthorized = {
54
72
  /**
55
73
  * Whether the logged-in member is allowed to perform the specified action on the specified resource.
@@ -94,6 +112,10 @@ declare const withStytchMemberSession: <T extends object>(Component: React.Compo
94
112
  stytchMemberSession: MemberSession | null;
95
113
  stytchMemberSessionIsFromCache: boolean;
96
114
  }>) => React.ComponentType<T>;
115
+ declare const withStytchOrganization: <T extends object>(Component: React.ComponentType<T & {
116
+ stytchOrganization: Organization | null;
117
+ stytchOrganizationIsFromCache: boolean;
118
+ }>) => React.ComponentType<T>;
97
119
  /**
98
120
  * Wrap your component with this HOC in order to receive the permissions for the logged-in member.
99
121
  * Evaluates all permissions granted to the logged-in member.
@@ -241,5 +263,5 @@ interface StytchB2BProps {
241
263
  * @param props {@link StytchB2BProps}
242
264
  */
243
265
  declare const StytchB2B: ({ styles, callbacks, config }: StytchB2BProps) => React.JSX.Element;
244
- export { StytchB2BProvider, useStytchB2BClient, useStytchMemberSession, useStytchMember, useStytchIsAuthorized, withStytchB2BClient, withStytchMemberSession, withStytchMember, withStytchPermissions, StytchB2B };
266
+ export { StytchB2BProvider, useStytchB2BClient, useStytchMemberSession, useStytchMember, useStytchIsAuthorized, useStytchOrganization, withStytchB2BClient, withStytchMemberSession, withStytchMember, withStytchOrganization, withStytchPermissions, StytchB2B };
245
267
  export type { StytchB2BProviderProps };
@@ -1,7 +1,7 @@
1
1
  /// <reference types="react" />
2
2
  import React from "react";
3
3
  import { ReactNode } from "react";
4
- import { Member, MemberSession, StytchB2BUIClient } from "@stytch/vanilla-js/b2b";
4
+ import { Member, MemberSession, Organization, StytchB2BUIClient } from "@stytch/vanilla-js/b2b";
5
5
  import { StytchB2BHeadlessClient } from "@stytch/vanilla-js/b2b/headless";
6
6
  import { PermissionsMap } from "@stytch/core/public";
7
7
  import { Callbacks, StyleConfig, StytchB2BUIConfig } from "@stytch/vanilla-js";
@@ -29,6 +29,16 @@ type SWRMemberSession = {
29
29
  */
30
30
  fromCache: boolean;
31
31
  };
32
+ type SWROrganization = {
33
+ /**
34
+ * Either the active {@link Organization} object, or null if the user is not logged in.
35
+ */
36
+ organization: Organization | null;
37
+ /**
38
+ * If true, indicates that the value returned is from the application cache and a state refresh is in progress.
39
+ */
40
+ fromCache: boolean;
41
+ };
32
42
  /**
33
43
  * Returns the active Member.
34
44
  * Check the fromCache property to determine if the member data is from persistent storage.
@@ -50,6 +60,14 @@ declare const useStytchMember: () => SWRMember;
50
60
  * @returns A {@link SWRMemberSession}
51
61
  */
52
62
  declare const useStytchMemberSession: () => SWRMemberSession;
63
+ /**
64
+ * Returns the active Stytch organization.
65
+ * @example
66
+ * const { organization } = useStytchOrganization();
67
+ * return organization ? <p>Welcome to {organization.organization_name}</p> : <p>Log in to continue!</p>;
68
+ * @returns A {@link SWROrganization}
69
+ */
70
+ declare const useStytchOrganization: () => SWROrganization;
53
71
  type SWRIsAuthorized = {
54
72
  /**
55
73
  * Whether the logged-in member is allowed to perform the specified action on the specified resource.
@@ -94,6 +112,10 @@ declare const withStytchMemberSession: <T extends object>(Component: React.Compo
94
112
  stytchMemberSession: MemberSession | null;
95
113
  stytchMemberSessionIsFromCache: boolean;
96
114
  }>) => React.ComponentType<T>;
115
+ declare const withStytchOrganization: <T extends object>(Component: React.ComponentType<T & {
116
+ stytchOrganization: Organization | null;
117
+ stytchOrganizationIsFromCache: boolean;
118
+ }>) => React.ComponentType<T>;
97
119
  /**
98
120
  * Wrap your component with this HOC in order to receive the permissions for the logged-in member.
99
121
  * Evaluates all permissions granted to the logged-in member.
@@ -241,5 +263,5 @@ interface StytchB2BProps {
241
263
  * @param props {@link StytchB2BProps}
242
264
  */
243
265
  declare const StytchB2B: ({ styles, callbacks, config }: StytchB2BProps) => React.JSX.Element;
244
- export { StytchB2BProvider, useStytchB2BClient, useStytchMemberSession, useStytchMember, useStytchIsAuthorized, withStytchB2BClient, withStytchMemberSession, withStytchMember, withStytchPermissions, StytchB2B };
266
+ export { StytchB2BProvider, useStytchB2BClient, useStytchMemberSession, useStytchMember, useStytchIsAuthorized, useStytchOrganization, withStytchB2BClient, withStytchMemberSession, withStytchMember, withStytchOrganization, withStytchPermissions, StytchB2B };
245
267
  export type { StytchB2BProviderProps };
@@ -41,9 +41,14 @@ const initialMemberSession = {
41
41
  session: null,
42
42
  fromCache: false,
43
43
  };
44
+ const initialOrganization = {
45
+ organization: null,
46
+ fromCache: false,
47
+ };
44
48
  const StytchB2BContext = createContext({ isMounted: false });
45
49
  const StytchMemberContext = createContext(initialMember);
46
50
  const StytchMemberSessionContext = createContext(initialMemberSession);
51
+ const StytchOrganizationContext = createContext(initialOrganization);
47
52
  const useIsMounted__INTERNAL = () => useContext(StytchB2BContext).isMounted;
48
53
  const isUIClient = (client) => {
49
54
  return client.mount !== undefined;
@@ -75,6 +80,17 @@ const useStytchMemberSession = () => {
75
80
  invariant(useIsMounted__INTERNAL(), noProviderError('useStytchMemberSession', 'StytchB2BProvider'));
76
81
  return useContext(StytchMemberSessionContext);
77
82
  };
83
+ /**
84
+ * Returns the active Stytch organization.
85
+ * @example
86
+ * const { organization } = useStytchOrganization();
87
+ * return organization ? <p>Welcome to {organization.organization_name}</p> : <p>Log in to continue!</p>;
88
+ * @returns A {@link SWROrganization}
89
+ */
90
+ const useStytchOrganization = () => {
91
+ invariant(useIsMounted__INTERNAL(), noProviderError('useStytchOrganization', 'StytchB2BProvider'));
92
+ return useContext(StytchOrganizationContext);
93
+ };
78
94
  /**
79
95
  * Determines whether the logged-in member is allowed to perform the specified action on the specified resource.
80
96
  * Returns `true` if the member can perform the action, `false` otherwise.
@@ -143,6 +159,15 @@ const withStytchMemberSession = (Component) => {
143
159
  WithStytchSession.displayName = `withStytchSession(${Component.displayName || Component.name || 'Component'})`;
144
160
  return WithStytchSession;
145
161
  };
162
+ const withStytchOrganization = (Component) => {
163
+ const WithStytchOrganization = (props) => {
164
+ invariant(useIsMounted__INTERNAL(), noProviderError('withStytchOrganization', 'StytchB2BProvider'));
165
+ const { organization, fromCache } = useStytchOrganization();
166
+ return React.createElement(Component, Object.assign({}, props, { stytchOrganization: organization, stytchOrganizationIsFromCache: fromCache }));
167
+ };
168
+ WithStytchOrganization.displayName = `withStytchOrganization(${Component.displayName || Component.name || 'Component'})`;
169
+ return WithStytchOrganization;
170
+ };
146
171
  /**
147
172
  * Wrap your component with this HOC in order to receive the permissions for the logged-in member.
148
173
  * Evaluates all permissions granted to the logged-in member.
@@ -208,6 +233,10 @@ const StytchB2BProvider = ({ stytch, children }) => {
208
233
  session: stytch.session.getSync(),
209
234
  fromCache: true,
210
235
  });
236
+ const [organization, setOrganization] = useAsyncState({
237
+ organization: stytch.organization.getSync(),
238
+ fromCache: true,
239
+ });
211
240
  useEffect(() => {
212
241
  const unsubscribeMember = stytch.self.onChange((member) => setMember({
213
242
  member,
@@ -217,17 +246,25 @@ const StytchB2BProvider = ({ stytch, children }) => {
217
246
  session,
218
247
  fromCache: false,
219
248
  }));
249
+ const unsubscribeOrganization = stytch.organization.onChange((organization) => setOrganization({
250
+ organization,
251
+ fromCache: false,
252
+ }));
220
253
  return () => {
221
254
  unsubscribeMember();
222
255
  unsubscribeSession();
256
+ unsubscribeOrganization();
223
257
  };
224
- }, [stytch, setMember, setMemberSession]);
258
+ }, [stytch, setMember, setMemberSession, setOrganization]);
225
259
  // TODO (SDK-813): Remove this when we have a single top-level onChange handler
226
- const finalMemberSession = !!session.session === !!member.member ? session : initialMemberSession;
227
- const finalMember = !!session.session === !!member.member ? member : initialMember;
260
+ const allValuesReady = !!member.member === !!session.session && !!session.session === !!organization.organization;
261
+ const finalValues = allValuesReady
262
+ ? { member, session, organization }
263
+ : { member: initialMember, session: initialMemberSession, organization: initialOrganization };
228
264
  return (React.createElement(StytchB2BContext.Provider, { value: ctx },
229
- React.createElement(StytchMemberContext.Provider, { value: finalMember },
230
- React.createElement(StytchMemberSessionContext.Provider, { value: finalMemberSession }, children))));
265
+ React.createElement(StytchOrganizationContext.Provider, { value: finalValues.organization },
266
+ React.createElement(StytchMemberContext.Provider, { value: finalValues.member },
267
+ React.createElement(StytchMemberSessionContext.Provider, { value: finalValues.session }, children)))));
231
268
  };
232
269
 
233
270
  /**
@@ -289,4 +326,4 @@ const StytchB2B = ({ styles, callbacks, config }) => {
289
326
  return React.createElement("div", { ref: containerEl });
290
327
  };
291
328
 
292
- export { StytchB2B, StytchB2BProvider, useStytchB2BClient, useStytchIsAuthorized, useStytchMember, useStytchMemberSession, withStytchB2BClient, withStytchMember, withStytchMemberSession, withStytchPermissions };
329
+ export { StytchB2B, StytchB2BProvider, useStytchB2BClient, useStytchIsAuthorized, useStytchMember, useStytchMemberSession, useStytchOrganization, withStytchB2BClient, withStytchMember, withStytchMemberSession, withStytchOrganization, withStytchPermissions };
package/dist/b2b/index.js CHANGED
@@ -49,9 +49,14 @@ const initialMemberSession = {
49
49
  session: null,
50
50
  fromCache: false,
51
51
  };
52
+ const initialOrganization = {
53
+ organization: null,
54
+ fromCache: false,
55
+ };
52
56
  const StytchB2BContext = React.createContext({ isMounted: false });
53
57
  const StytchMemberContext = React.createContext(initialMember);
54
58
  const StytchMemberSessionContext = React.createContext(initialMemberSession);
59
+ const StytchOrganizationContext = React.createContext(initialOrganization);
55
60
  const useIsMounted__INTERNAL = () => React.useContext(StytchB2BContext).isMounted;
56
61
  const isUIClient = (client) => {
57
62
  return client.mount !== undefined;
@@ -83,6 +88,17 @@ const useStytchMemberSession = () => {
83
88
  invariant(useIsMounted__INTERNAL(), noProviderError('useStytchMemberSession', 'StytchB2BProvider'));
84
89
  return React.useContext(StytchMemberSessionContext);
85
90
  };
91
+ /**
92
+ * Returns the active Stytch organization.
93
+ * @example
94
+ * const { organization } = useStytchOrganization();
95
+ * return organization ? <p>Welcome to {organization.organization_name}</p> : <p>Log in to continue!</p>;
96
+ * @returns A {@link SWROrganization}
97
+ */
98
+ const useStytchOrganization = () => {
99
+ invariant(useIsMounted__INTERNAL(), noProviderError('useStytchOrganization', 'StytchB2BProvider'));
100
+ return React.useContext(StytchOrganizationContext);
101
+ };
86
102
  /**
87
103
  * Determines whether the logged-in member is allowed to perform the specified action on the specified resource.
88
104
  * Returns `true` if the member can perform the action, `false` otherwise.
@@ -151,6 +167,15 @@ const withStytchMemberSession = (Component) => {
151
167
  WithStytchSession.displayName = `withStytchSession(${Component.displayName || Component.name || 'Component'})`;
152
168
  return WithStytchSession;
153
169
  };
170
+ const withStytchOrganization = (Component) => {
171
+ const WithStytchOrganization = (props) => {
172
+ invariant(useIsMounted__INTERNAL(), noProviderError('withStytchOrganization', 'StytchB2BProvider'));
173
+ const { organization, fromCache } = useStytchOrganization();
174
+ return React__default['default'].createElement(Component, Object.assign({}, props, { stytchOrganization: organization, stytchOrganizationIsFromCache: fromCache }));
175
+ };
176
+ WithStytchOrganization.displayName = `withStytchOrganization(${Component.displayName || Component.name || 'Component'})`;
177
+ return WithStytchOrganization;
178
+ };
154
179
  /**
155
180
  * Wrap your component with this HOC in order to receive the permissions for the logged-in member.
156
181
  * Evaluates all permissions granted to the logged-in member.
@@ -216,6 +241,10 @@ const StytchB2BProvider = ({ stytch, children }) => {
216
241
  session: stytch.session.getSync(),
217
242
  fromCache: true,
218
243
  });
244
+ const [organization, setOrganization] = useAsyncState({
245
+ organization: stytch.organization.getSync(),
246
+ fromCache: true,
247
+ });
219
248
  React.useEffect(() => {
220
249
  const unsubscribeMember = stytch.self.onChange((member) => setMember({
221
250
  member,
@@ -225,17 +254,25 @@ const StytchB2BProvider = ({ stytch, children }) => {
225
254
  session,
226
255
  fromCache: false,
227
256
  }));
257
+ const unsubscribeOrganization = stytch.organization.onChange((organization) => setOrganization({
258
+ organization,
259
+ fromCache: false,
260
+ }));
228
261
  return () => {
229
262
  unsubscribeMember();
230
263
  unsubscribeSession();
264
+ unsubscribeOrganization();
231
265
  };
232
- }, [stytch, setMember, setMemberSession]);
266
+ }, [stytch, setMember, setMemberSession, setOrganization]);
233
267
  // TODO (SDK-813): Remove this when we have a single top-level onChange handler
234
- const finalMemberSession = !!session.session === !!member.member ? session : initialMemberSession;
235
- const finalMember = !!session.session === !!member.member ? member : initialMember;
268
+ const allValuesReady = !!member.member === !!session.session && !!session.session === !!organization.organization;
269
+ const finalValues = allValuesReady
270
+ ? { member, session, organization }
271
+ : { member: initialMember, session: initialMemberSession, organization: initialOrganization };
236
272
  return (React__default['default'].createElement(StytchB2BContext.Provider, { value: ctx },
237
- React__default['default'].createElement(StytchMemberContext.Provider, { value: finalMember },
238
- React__default['default'].createElement(StytchMemberSessionContext.Provider, { value: finalMemberSession }, children))));
273
+ React__default['default'].createElement(StytchOrganizationContext.Provider, { value: finalValues.organization },
274
+ React__default['default'].createElement(StytchMemberContext.Provider, { value: finalValues.member },
275
+ React__default['default'].createElement(StytchMemberSessionContext.Provider, { value: finalValues.session }, children)))));
239
276
  };
240
277
 
241
278
  /**
@@ -303,7 +340,9 @@ exports.useStytchB2BClient = useStytchB2BClient;
303
340
  exports.useStytchIsAuthorized = useStytchIsAuthorized;
304
341
  exports.useStytchMember = useStytchMember;
305
342
  exports.useStytchMemberSession = useStytchMemberSession;
343
+ exports.useStytchOrganization = useStytchOrganization;
306
344
  exports.withStytchB2BClient = withStytchB2BClient;
307
345
  exports.withStytchMember = withStytchMember;
308
346
  exports.withStytchMemberSession = withStytchMemberSession;
347
+ exports.withStytchOrganization = withStytchOrganization;
309
348
  exports.withStytchPermissions = withStytchPermissions;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stytch/react",
3
- "version": "14.0.1",
3
+ "version": "15.0.0",
4
4
  "description": "Stytch's official React Library",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.esm.js",
@@ -33,7 +33,7 @@
33
33
  ],
34
34
  "devDependencies": {
35
35
  "@babel/runtime": "7.18.6",
36
- "@stytch/vanilla-js": "4.1.1",
36
+ "@stytch/vanilla-js": "4.2.0",
37
37
  "@testing-library/react": "14.0.0",
38
38
  "eslint-config-custom": "0.0.1",
39
39
  "react-test-renderer": "18.0.0",
@@ -41,7 +41,7 @@
41
41
  "typescript": "4.7.4"
42
42
  },
43
43
  "peerDependencies": {
44
- "@stytch/vanilla-js": "^4.1.1",
44
+ "@stytch/vanilla-js": "^4.2.0",
45
45
  "react": ">= 17.0.2",
46
46
  "react-dom": ">= 17.0.2"
47
47
  }