@sanity/sdk 2.13.0 → 2.14.1

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.
@@ -14,6 +14,7 @@ import {
14
14
 
15
15
  import {type StoreContext} from '../store/defineStore'
16
16
  import {DEFAULT_API_VERSION, REQUEST_TAG_PREFIX} from './authConstants'
17
+ import {getAuthLogger} from './authLogger'
17
18
  import {AuthStateType} from './authStateType'
18
19
  import {type AuthState, type AuthStoreState} from './authStore'
19
20
 
@@ -141,7 +142,12 @@ function shouldRefreshToken(lastRefresh: number | undefined): boolean {
141
142
  /**
142
143
  * @internal
143
144
  */
144
- export const refreshStampedToken = ({state}: StoreContext<AuthStoreState>): Subscription => {
145
+ export const refreshStampedToken = ({
146
+ state,
147
+ instance,
148
+ }: StoreContext<AuthStoreState>): Subscription => {
149
+ const logger = getAuthLogger(instance)
150
+
145
151
  const {clientFactory, apiHost, storageArea, storageKey} = state.get().options
146
152
 
147
153
  const refreshToken$ = state.observable.pipe(
@@ -171,14 +177,17 @@ export const refreshStampedToken = ({state}: StoreContext<AuthStoreState>): Subs
171
177
  // Read the latest token directly from state inside refresh
172
178
  const currentState = state.get()
173
179
  if (currentState.authState.type !== AuthStateType.LOGGED_IN) {
180
+ logger.debug('Token refresh aborted - user logged out')
174
181
  throw new Error('User logged out before refresh could complete') // Abort refresh
175
182
  }
176
183
  const currentToken = currentState.authState.token
177
184
 
185
+ logger.debug('Refreshing stamped token')
178
186
  const response = await firstValueFrom(
179
187
  createTokenRefreshStream(currentToken, clientFactory, apiHost),
180
188
  )
181
189
 
190
+ logger.info('Token refreshed successfully')
182
191
  state.set('setRefreshStampedToken', (prev) => ({
183
192
  authState:
184
193
  prev.authState.type === AuthStateType.LOGGED_IN
@@ -276,6 +285,7 @@ export const refreshStampedToken = ({state}: StoreContext<AuthStoreState>): Subs
276
285
 
277
286
  return refreshToken$.subscribe({
278
287
  next: (response: {token: string}) => {
288
+ logger.debug('Token refresh completed, updating state')
279
289
  state.set('setRefreshStampedToken', (prev) => ({
280
290
  authState:
281
291
  prev.authState.type === AuthStateType.LOGGED_IN
@@ -289,6 +299,7 @@ export const refreshStampedToken = ({state}: StoreContext<AuthStoreState>): Subs
289
299
  storageArea?.setItem(storageKey, JSON.stringify({token: response.token}))
290
300
  },
291
301
  error: (error) => {
302
+ logger.error('Token refresh failed', {error})
292
303
  state.set('setRefreshStampedTokenError', {authState: {type: AuthStateType.ERROR, error}})
293
304
  },
294
305
  })
@@ -1,6 +1,6 @@
1
1
  import {type CurrentUser} from '@sanity/types'
2
2
  import {delay, of, throwError} from 'rxjs'
3
- import {beforeEach, describe, it} from 'vitest'
3
+ import {beforeEach, describe, expect, it, vi} from 'vitest'
4
4
 
5
5
  import {createSanityInstance} from '../store/createSanityInstance'
6
6
  import {createStoreState} from '../store/createStoreState'
@@ -8,13 +8,28 @@ import {AuthStateType} from './authStateType'
8
8
  import {authStore} from './authStore'
9
9
  import {subscribeToStateAndFetchCurrentUser} from './subscribeToStateAndFetchCurrentUser'
10
10
 
11
+ // Mock logger to prevent actual logging during tests
12
+ vi.mock('../utils/logger', async (importOriginal) => {
13
+ const original = await importOriginal<typeof import('../utils/logger')>()
14
+ return {
15
+ ...original,
16
+ createLogger: vi.fn(() => ({
17
+ info: vi.fn(),
18
+ debug: vi.fn(),
19
+ warn: vi.fn(),
20
+ error: vi.fn(),
21
+ trace: vi.fn(),
22
+ })),
23
+ }
24
+ })
25
+
11
26
  describe('subscribeToStateAndFetchCurrentUser', () => {
12
27
  beforeEach(() => {
13
28
  vi.clearAllMocks()
14
29
  })
15
30
 
16
31
  it('fetches the current user if the is logged in without a current user present', () => {
17
- const mockUser = {id: 'example-user'} as CurrentUser
32
+ const mockUser = {id: 'example-user', email: 'user@example.com'} as CurrentUser
18
33
  const mockRequest = vi.fn().mockReturnValue(of(mockUser))
19
34
  const mockClient = {observable: {request: mockRequest}}
20
35
  const clientFactory = vi.fn().mockReturnValue(mockClient)
@@ -11,6 +11,7 @@ import {
11
11
 
12
12
  import {type StoreContext} from '../store/defineStore'
13
13
  import {DEFAULT_API_VERSION, REQUEST_TAG_PREFIX} from './authConstants'
14
+ import {getAuthLogger} from './authLogger'
14
15
  import {isStudioConfig} from './authMode'
15
16
  import {AuthStateType} from './authStateType'
16
17
  import {type AuthMethodOptions, type AuthState, type AuthStoreState} from './authStore'
@@ -30,6 +31,8 @@ export const subscribeToStateAndFetchCurrentUser = (
30
31
  {state, instance}: StoreContext<AuthStoreState>,
31
32
  fetchOptions?: {useProjectHostname?: boolean},
32
33
  ): Subscription => {
34
+ const logger = getAuthLogger(instance)
35
+
33
36
  const {clientFactory, apiHost} = state.get().options
34
37
  const useProjectHostname = fetchOptions?.useProjectHostname ?? isStudioConfig(instance.config)
35
38
  const projectId = instance.config.projectId
@@ -82,6 +85,7 @@ export const subscribeToStateAndFetchCurrentUser = (
82
85
  * @see SDK-1409
83
86
  */
84
87
  catchError((error) => {
88
+ logger.error('Failed to fetch current user', {error})
85
89
  state.set('setError', {authState: {type: AuthStateType.ERROR, error}})
86
90
  return EMPTY
87
91
  }),
@@ -91,6 +95,11 @@ export const subscribeToStateAndFetchCurrentUser = (
91
95
 
92
96
  return currentUser$.subscribe({
93
97
  next: (currentUser) => {
98
+ logger.info('Current user fetched successfully', {
99
+ hasEmail: !!currentUser.email,
100
+ })
101
+ // userId is PII, so only surface it at debug level
102
+ logger.debug('Current user details', {userId: currentUser.id})
94
103
  state.set('setCurrentUser', (prev) => ({
95
104
  authState:
96
105
  prev.authState.type === AuthStateType.LOGGED_IN