@sanity/sdk 0.0.0-chore-react-18-compat.1 → 0.0.0-chore-react-18-compat.3
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/dist/index.d.ts +441 -322
- package/dist/index.js +1685 -1481
- package/dist/index.js.map +1 -1
- package/package.json +13 -15
- package/src/_exports/index.ts +32 -30
- package/src/auth/authStore.test.ts +149 -104
- package/src/auth/authStore.ts +51 -100
- package/src/auth/handleAuthCallback.test.ts +67 -34
- package/src/auth/handleAuthCallback.ts +8 -7
- package/src/auth/logout.test.ts +61 -29
- package/src/auth/logout.ts +26 -28
- package/src/auth/refreshStampedToken.test.ts +197 -91
- package/src/auth/refreshStampedToken.ts +170 -59
- package/src/auth/subscribeToStateAndFetchCurrentUser.test.ts +5 -5
- package/src/auth/subscribeToStateAndFetchCurrentUser.ts +45 -47
- package/src/auth/subscribeToStorageEventsAndSetToken.test.ts +4 -5
- package/src/auth/subscribeToStorageEventsAndSetToken.ts +22 -24
- package/src/client/clientStore.test.ts +131 -67
- package/src/client/clientStore.ts +117 -116
- package/src/comlink/controller/actions/destroyController.test.ts +38 -13
- package/src/comlink/controller/actions/destroyController.ts +11 -15
- package/src/comlink/controller/actions/getOrCreateChannel.test.ts +56 -27
- package/src/comlink/controller/actions/getOrCreateChannel.ts +37 -35
- package/src/comlink/controller/actions/getOrCreateController.test.ts +27 -16
- package/src/comlink/controller/actions/getOrCreateController.ts +23 -22
- package/src/comlink/controller/actions/releaseChannel.test.ts +37 -13
- package/src/comlink/controller/actions/releaseChannel.ts +22 -21
- package/src/comlink/controller/comlinkControllerStore.test.ts +65 -36
- package/src/comlink/controller/comlinkControllerStore.ts +44 -5
- package/src/comlink/node/actions/getOrCreateNode.test.ts +31 -15
- package/src/comlink/node/actions/getOrCreateNode.ts +30 -29
- package/src/comlink/node/actions/releaseNode.test.ts +75 -55
- package/src/comlink/node/actions/releaseNode.ts +19 -21
- package/src/comlink/node/comlinkNodeStore.test.ts +6 -11
- package/src/comlink/node/comlinkNodeStore.ts +22 -5
- package/src/config/authConfig.ts +79 -0
- package/src/config/sanityConfig.ts +48 -0
- package/src/datasets/datasets.test.ts +2 -2
- package/src/datasets/datasets.ts +18 -5
- package/src/document/actions.test.ts +22 -10
- package/src/document/actions.ts +44 -56
- package/src/document/applyDocumentActions.test.ts +96 -36
- package/src/document/applyDocumentActions.ts +140 -99
- package/src/document/documentStore.test.ts +103 -155
- package/src/document/documentStore.ts +247 -238
- package/src/document/listen.ts +56 -55
- package/src/document/patchOperations.ts +0 -43
- package/src/document/permissions.test.ts +25 -12
- package/src/document/permissions.ts +11 -4
- package/src/document/processActions.test.ts +41 -8
- package/src/document/reducers.test.ts +87 -16
- package/src/document/reducers.ts +2 -2
- package/src/document/sharedListener.test.ts +34 -16
- package/src/document/sharedListener.ts +33 -11
- package/src/preview/getPreviewState.test.ts +40 -39
- package/src/preview/getPreviewState.ts +68 -56
- package/src/preview/previewConstants.ts +43 -0
- package/src/preview/previewQuery.test.ts +1 -1
- package/src/preview/previewQuery.ts +4 -5
- package/src/preview/previewStore.test.ts +13 -58
- package/src/preview/previewStore.ts +7 -21
- package/src/preview/resolvePreview.test.ts +33 -104
- package/src/preview/resolvePreview.ts +11 -21
- package/src/preview/subscribeToStateAndFetchBatches.test.ts +96 -97
- package/src/preview/subscribeToStateAndFetchBatches.ts +85 -81
- package/src/preview/util.ts +1 -0
- package/src/project/project.test.ts +3 -3
- package/src/project/project.ts +28 -5
- package/src/projection/getProjectionState.test.ts +188 -72
- package/src/projection/getProjectionState.ts +92 -62
- package/src/projection/projectionQuery.test.ts +114 -12
- package/src/projection/projectionQuery.ts +75 -32
- package/src/projection/projectionStore.test.ts +13 -51
- package/src/projection/projectionStore.ts +6 -43
- package/src/projection/resolveProjection.test.ts +32 -127
- package/src/projection/resolveProjection.ts +16 -28
- package/src/projection/subscribeToStateAndFetchBatches.test.ts +203 -116
- package/src/projection/subscribeToStateAndFetchBatches.ts +140 -85
- package/src/projection/types.ts +50 -0
- package/src/projection/util.ts +3 -1
- package/src/projects/projects.test.ts +13 -4
- package/src/projects/projects.ts +6 -1
- package/src/query/queryStore.test.ts +10 -47
- package/src/query/queryStore.ts +151 -133
- package/src/query/queryStoreConstants.ts +2 -0
- package/src/store/createActionBinder.test.ts +153 -0
- package/src/store/createActionBinder.ts +176 -0
- package/src/store/createSanityInstance.test.ts +84 -0
- package/src/store/createSanityInstance.ts +124 -0
- package/src/store/createStateSourceAction.test.ts +196 -0
- package/src/store/createStateSourceAction.ts +260 -0
- package/src/store/createStoreInstance.test.ts +81 -0
- package/src/store/createStoreInstance.ts +80 -0
- package/src/store/createStoreState.test.ts +85 -0
- package/src/store/createStoreState.ts +92 -0
- package/src/store/defineStore.test.ts +18 -0
- package/src/store/defineStore.ts +81 -0
- package/src/users/reducers.test.ts +318 -0
- package/src/users/reducers.ts +88 -0
- package/src/users/types.ts +46 -4
- package/src/users/usersConstants.ts +4 -0
- package/src/users/usersStore.test.ts +350 -223
- package/src/users/usersStore.ts +285 -149
- package/src/utils/createFetcherStore.test.ts +6 -7
- package/src/utils/createFetcherStore.ts +150 -153
- package/src/utils/createGroqSearchFilter.test.ts +75 -0
- package/src/utils/createGroqSearchFilter.ts +85 -0
- package/src/{common/util.test.ts → utils/hashString.test.ts} +1 -1
- package/dist/index.cjs +0 -4888
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -2121
- package/src/auth/fetchLoginUrls.test.ts +0 -163
- package/src/auth/fetchLoginUrls.ts +0 -74
- package/src/common/createLiveEventSubscriber.test.ts +0 -121
- package/src/common/createLiveEventSubscriber.ts +0 -55
- package/src/common/types.ts +0 -4
- package/src/instance/identity.test.ts +0 -46
- package/src/instance/identity.ts +0 -29
- package/src/instance/sanityInstance.test.ts +0 -77
- package/src/instance/sanityInstance.ts +0 -57
- package/src/instance/types.ts +0 -37
- package/src/preview/getPreviewProjection.ts +0 -45
- package/src/resources/README.md +0 -370
- package/src/resources/createAction.test.ts +0 -101
- package/src/resources/createAction.ts +0 -44
- package/src/resources/createResource.test.ts +0 -112
- package/src/resources/createResource.ts +0 -102
- package/src/resources/createStateSourceAction.test.ts +0 -114
- package/src/resources/createStateSourceAction.ts +0 -83
- package/src/resources/createStore.test.ts +0 -67
- package/src/resources/createStore.ts +0 -46
- package/src/store/createStore.test.ts +0 -108
- package/src/store/createStore.ts +0 -106
- /package/src/{common/util.ts → utils/hashString.ts} +0 -0
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
import {describe, expect, it} from 'vitest'
|
|
2
|
+
|
|
3
|
+
import {type SanityInstance} from '../store/createSanityInstance'
|
|
4
|
+
import {
|
|
5
|
+
addSubscription,
|
|
6
|
+
cancelRequest,
|
|
7
|
+
getUsersKey,
|
|
8
|
+
initializeRequest,
|
|
9
|
+
parseUsersKey,
|
|
10
|
+
removeSubscription,
|
|
11
|
+
setUsersData,
|
|
12
|
+
setUsersError,
|
|
13
|
+
updateLastLoadMoreRequest,
|
|
14
|
+
} from './reducers'
|
|
15
|
+
import {type GetUsersOptions, type SanityUserResponse, type UsersStoreState} from './types'
|
|
16
|
+
import {DEFAULT_USERS_BATCH_SIZE} from './usersConstants'
|
|
17
|
+
|
|
18
|
+
describe('Users Reducers', () => {
|
|
19
|
+
// Mock SanityInstance for testing
|
|
20
|
+
const mockInstance: SanityInstance = {
|
|
21
|
+
instanceId: 'test-instance-id',
|
|
22
|
+
config: {
|
|
23
|
+
projectId: 'test-project-id',
|
|
24
|
+
},
|
|
25
|
+
isDisposed: () => false,
|
|
26
|
+
dispose: () => {},
|
|
27
|
+
onDispose: () => () => {},
|
|
28
|
+
getParent: () => undefined,
|
|
29
|
+
createChild: (_config) => mockInstance,
|
|
30
|
+
match: () => undefined,
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const sampleOptions: GetUsersOptions = {
|
|
34
|
+
resourceType: 'project',
|
|
35
|
+
projectId: 'proj123',
|
|
36
|
+
batchSize: 50,
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const sampleOptionsWithDefaultBatchSize: GetUsersOptions = {
|
|
40
|
+
resourceType: 'project',
|
|
41
|
+
projectId: 'proj123',
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
describe('getUsersKey', () => {
|
|
45
|
+
it('should generate a key based on resourceType, resourceId and batchSize', () => {
|
|
46
|
+
const key = getUsersKey(mockInstance, sampleOptions)
|
|
47
|
+
expect(JSON.parse(key)).toEqual({
|
|
48
|
+
resourceType: 'project',
|
|
49
|
+
projectId: 'proj123',
|
|
50
|
+
batchSize: 50,
|
|
51
|
+
})
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
it('should use DEFAULT_USERS_BATCH_SIZE when batchSize is not provided', () => {
|
|
55
|
+
const key = getUsersKey(mockInstance, sampleOptionsWithDefaultBatchSize)
|
|
56
|
+
expect(JSON.parse(key)).toEqual({
|
|
57
|
+
resourceType: 'project',
|
|
58
|
+
projectId: 'proj123',
|
|
59
|
+
batchSize: DEFAULT_USERS_BATCH_SIZE,
|
|
60
|
+
})
|
|
61
|
+
})
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
describe('parseUsersKey', () => {
|
|
65
|
+
it('should parse a key back into its components', () => {
|
|
66
|
+
const key = JSON.stringify({
|
|
67
|
+
resourceType: 'organization',
|
|
68
|
+
resourceId: 'org456',
|
|
69
|
+
batchSize: 25,
|
|
70
|
+
})
|
|
71
|
+
const parsed = parseUsersKey(key)
|
|
72
|
+
expect(parsed).toEqual({
|
|
73
|
+
resourceType: 'organization',
|
|
74
|
+
resourceId: 'org456',
|
|
75
|
+
batchSize: 25,
|
|
76
|
+
})
|
|
77
|
+
})
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
describe('addSubscription', () => {
|
|
81
|
+
it('should add a subscription when key does not exist', () => {
|
|
82
|
+
const state: UsersStoreState = {users: {}}
|
|
83
|
+
const key = getUsersKey(mockInstance, sampleOptions)
|
|
84
|
+
const reducer = addSubscription('sub1', key)
|
|
85
|
+
const newState = reducer(state)
|
|
86
|
+
expect(newState.users[key]).toEqual({subscriptions: ['sub1']})
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
it('should append subscription when key exists', () => {
|
|
90
|
+
const key = getUsersKey(mockInstance, sampleOptions)
|
|
91
|
+
const state: UsersStoreState = {users: {[key]: {subscriptions: ['subA']}}}
|
|
92
|
+
const reducer = addSubscription('subB', key)
|
|
93
|
+
const newState = reducer(state)
|
|
94
|
+
expect(newState.users[key]).toEqual({subscriptions: ['subA', 'subB']})
|
|
95
|
+
})
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
describe('removeSubscription', () => {
|
|
99
|
+
it('should return state unchanged if key does not exist', () => {
|
|
100
|
+
const state: UsersStoreState = {users: {}}
|
|
101
|
+
const key = getUsersKey(mockInstance, sampleOptions)
|
|
102
|
+
const reducer = removeSubscription('subX', key)
|
|
103
|
+
const newState = reducer(state)
|
|
104
|
+
expect(newState).toBe(state)
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
it('should remove subscription and keep the group if other subscriptions remain', () => {
|
|
108
|
+
const key = getUsersKey(mockInstance, sampleOptions)
|
|
109
|
+
const state: UsersStoreState = {users: {[key]: {subscriptions: ['sub1', 'sub2']}}}
|
|
110
|
+
const reducer = removeSubscription('sub1', key)
|
|
111
|
+
const newState = reducer(state)
|
|
112
|
+
expect(newState.users[key]).toEqual({subscriptions: ['sub2']})
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
it('should remove the group if no subscriptions remain after removal', () => {
|
|
116
|
+
const key = getUsersKey(mockInstance, sampleOptions)
|
|
117
|
+
const state: UsersStoreState = {users: {[key]: {subscriptions: ['onlySub']}}}
|
|
118
|
+
const reducer = removeSubscription('onlySub', key)
|
|
119
|
+
const newState = reducer(state)
|
|
120
|
+
expect(newState.users).not.toHaveProperty(key)
|
|
121
|
+
})
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
describe('setUsersData', () => {
|
|
125
|
+
it('should return state unchanged if key does not exist', () => {
|
|
126
|
+
const state: UsersStoreState = {users: {}}
|
|
127
|
+
const key = getUsersKey(mockInstance, sampleOptions)
|
|
128
|
+
const userResponse: SanityUserResponse = {
|
|
129
|
+
data: [
|
|
130
|
+
{
|
|
131
|
+
sanityUserId: 'user1',
|
|
132
|
+
profile: {
|
|
133
|
+
id: 'profile1',
|
|
134
|
+
displayName: 'User One',
|
|
135
|
+
email: 'user1@example.com',
|
|
136
|
+
provider: 'google',
|
|
137
|
+
createdAt: '2023-01-01',
|
|
138
|
+
},
|
|
139
|
+
memberships: [],
|
|
140
|
+
},
|
|
141
|
+
],
|
|
142
|
+
totalCount: 1,
|
|
143
|
+
nextCursor: null,
|
|
144
|
+
}
|
|
145
|
+
const reducer = setUsersData(key, userResponse)
|
|
146
|
+
const newState = reducer(state)
|
|
147
|
+
expect(newState).toBe(state)
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
it('should set users data if key exists', () => {
|
|
151
|
+
const key = getUsersKey(mockInstance, sampleOptions)
|
|
152
|
+
const state: UsersStoreState = {users: {[key]: {subscriptions: ['sub1']}}}
|
|
153
|
+
const userResponse: SanityUserResponse = {
|
|
154
|
+
data: [
|
|
155
|
+
{
|
|
156
|
+
sanityUserId: 'user1',
|
|
157
|
+
profile: {
|
|
158
|
+
id: 'profile1',
|
|
159
|
+
displayName: 'User One',
|
|
160
|
+
email: 'user1@example.com',
|
|
161
|
+
provider: 'google',
|
|
162
|
+
createdAt: '2023-01-01',
|
|
163
|
+
},
|
|
164
|
+
memberships: [],
|
|
165
|
+
},
|
|
166
|
+
],
|
|
167
|
+
totalCount: 1,
|
|
168
|
+
nextCursor: null,
|
|
169
|
+
}
|
|
170
|
+
const reducer = setUsersData(key, userResponse)
|
|
171
|
+
const newState = reducer(state)
|
|
172
|
+
expect(newState.users[key]).toEqual({
|
|
173
|
+
subscriptions: ['sub1'],
|
|
174
|
+
users: userResponse.data,
|
|
175
|
+
totalCount: 1,
|
|
176
|
+
nextCursor: null,
|
|
177
|
+
})
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
it('should append new users to existing users', () => {
|
|
181
|
+
const key = getUsersKey(mockInstance, sampleOptions)
|
|
182
|
+
const existingUser = {
|
|
183
|
+
sanityUserId: 'user1',
|
|
184
|
+
profile: {
|
|
185
|
+
id: 'profile1',
|
|
186
|
+
displayName: 'User One',
|
|
187
|
+
email: 'user1@example.com',
|
|
188
|
+
provider: 'google',
|
|
189
|
+
createdAt: '2023-01-01',
|
|
190
|
+
},
|
|
191
|
+
memberships: [],
|
|
192
|
+
}
|
|
193
|
+
const newUser = {
|
|
194
|
+
sanityUserId: 'user2',
|
|
195
|
+
profile: {
|
|
196
|
+
id: 'profile2',
|
|
197
|
+
displayName: 'User Two',
|
|
198
|
+
email: 'user2@example.com',
|
|
199
|
+
provider: 'google',
|
|
200
|
+
createdAt: '2023-01-02',
|
|
201
|
+
},
|
|
202
|
+
memberships: [],
|
|
203
|
+
}
|
|
204
|
+
const state: UsersStoreState = {
|
|
205
|
+
users: {
|
|
206
|
+
[key]: {
|
|
207
|
+
subscriptions: ['sub1'],
|
|
208
|
+
users: [existingUser],
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
}
|
|
212
|
+
const userResponse: SanityUserResponse = {
|
|
213
|
+
data: [newUser],
|
|
214
|
+
totalCount: 2,
|
|
215
|
+
nextCursor: null,
|
|
216
|
+
}
|
|
217
|
+
const reducer = setUsersData(key, userResponse)
|
|
218
|
+
const newState = reducer(state)
|
|
219
|
+
expect(newState.users[key]).toEqual({
|
|
220
|
+
subscriptions: ['sub1'],
|
|
221
|
+
users: [existingUser, newUser],
|
|
222
|
+
totalCount: 2,
|
|
223
|
+
nextCursor: null,
|
|
224
|
+
})
|
|
225
|
+
})
|
|
226
|
+
})
|
|
227
|
+
|
|
228
|
+
describe('updateLastLoadMoreRequest', () => {
|
|
229
|
+
it('should return state unchanged if key does not exist', () => {
|
|
230
|
+
const state: UsersStoreState = {users: {}}
|
|
231
|
+
const key = getUsersKey(mockInstance, sampleOptions)
|
|
232
|
+
const timestamp = '2023-05-15T12:00:00Z'
|
|
233
|
+
const reducer = updateLastLoadMoreRequest(timestamp, key)
|
|
234
|
+
const newState = reducer(state)
|
|
235
|
+
expect(newState).toBe(state)
|
|
236
|
+
})
|
|
237
|
+
|
|
238
|
+
it('should update lastLoadMoreRequest if key exists', () => {
|
|
239
|
+
const key = getUsersKey(mockInstance, sampleOptions)
|
|
240
|
+
const state: UsersStoreState = {users: {[key]: {subscriptions: ['sub1']}}}
|
|
241
|
+
const timestamp = '2023-05-15T12:00:00Z'
|
|
242
|
+
const reducer = updateLastLoadMoreRequest(timestamp, key)
|
|
243
|
+
const newState = reducer(state)
|
|
244
|
+
expect(newState.users[key]).toEqual({
|
|
245
|
+
subscriptions: ['sub1'],
|
|
246
|
+
lastLoadMoreRequest: timestamp,
|
|
247
|
+
})
|
|
248
|
+
})
|
|
249
|
+
})
|
|
250
|
+
|
|
251
|
+
describe('setUsersError', () => {
|
|
252
|
+
it('should return state unchanged if key does not exist', () => {
|
|
253
|
+
const state: UsersStoreState = {users: {}}
|
|
254
|
+
const key = getUsersKey(mockInstance, sampleOptions)
|
|
255
|
+
const error = new Error('Failed to fetch users')
|
|
256
|
+
const reducer = setUsersError(key, error)
|
|
257
|
+
const newState = reducer(state)
|
|
258
|
+
expect(newState).toBe(state)
|
|
259
|
+
})
|
|
260
|
+
|
|
261
|
+
it('should set error if key exists', () => {
|
|
262
|
+
const key = getUsersKey(mockInstance, sampleOptions)
|
|
263
|
+
const state: UsersStoreState = {users: {[key]: {subscriptions: ['sub1']}}}
|
|
264
|
+
const error = new Error('Failed to fetch users')
|
|
265
|
+
const reducer = setUsersError(key, error)
|
|
266
|
+
const newState = reducer(state)
|
|
267
|
+
expect(newState.users[key]).toEqual({
|
|
268
|
+
subscriptions: ['sub1'],
|
|
269
|
+
error,
|
|
270
|
+
})
|
|
271
|
+
})
|
|
272
|
+
})
|
|
273
|
+
|
|
274
|
+
describe('cancelRequest', () => {
|
|
275
|
+
it('should return state unchanged if key does not exist', () => {
|
|
276
|
+
const state: UsersStoreState = {users: {}}
|
|
277
|
+
const key = getUsersKey(mockInstance, sampleOptions)
|
|
278
|
+
const reducer = cancelRequest(key)
|
|
279
|
+
const newState = reducer(state)
|
|
280
|
+
expect(newState).toBe(state)
|
|
281
|
+
})
|
|
282
|
+
|
|
283
|
+
it('should return state unchanged if group has subscriptions', () => {
|
|
284
|
+
const key = getUsersKey(mockInstance, sampleOptions)
|
|
285
|
+
const state: UsersStoreState = {users: {[key]: {subscriptions: ['sub1']}}}
|
|
286
|
+
const reducer = cancelRequest(key)
|
|
287
|
+
const newState = reducer(state)
|
|
288
|
+
expect(newState).toBe(state)
|
|
289
|
+
})
|
|
290
|
+
|
|
291
|
+
it('should remove the group if no subscriptions exist', () => {
|
|
292
|
+
const key = getUsersKey(mockInstance, sampleOptions)
|
|
293
|
+
const state: UsersStoreState = {users: {[key]: {subscriptions: []}}}
|
|
294
|
+
const reducer = cancelRequest(key)
|
|
295
|
+
const newState = reducer(state)
|
|
296
|
+
expect(newState.users).not.toHaveProperty(key)
|
|
297
|
+
})
|
|
298
|
+
})
|
|
299
|
+
|
|
300
|
+
describe('initializeRequest', () => {
|
|
301
|
+
it('should return state unchanged if group already exists', () => {
|
|
302
|
+
const key = getUsersKey(mockInstance, sampleOptions)
|
|
303
|
+
const existing = {subscriptions: ['sub1']}
|
|
304
|
+
const state: UsersStoreState = {users: {[key]: existing}}
|
|
305
|
+
const reducer = initializeRequest(key)
|
|
306
|
+
const newState = reducer(state)
|
|
307
|
+
expect(newState).toBe(state)
|
|
308
|
+
})
|
|
309
|
+
|
|
310
|
+
it('should add the group with empty subscriptions if it does not exist', () => {
|
|
311
|
+
const state: UsersStoreState = {users: {}}
|
|
312
|
+
const key = getUsersKey(mockInstance, sampleOptions)
|
|
313
|
+
const reducer = initializeRequest(key)
|
|
314
|
+
const newState = reducer(state)
|
|
315
|
+
expect(newState.users[key]).toEqual({subscriptions: []})
|
|
316
|
+
})
|
|
317
|
+
})
|
|
318
|
+
})
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import {omit} from 'lodash-es'
|
|
2
|
+
|
|
3
|
+
import {type SanityInstance} from '../store/createSanityInstance'
|
|
4
|
+
import {type GetUsersOptions, type SanityUserResponse, type UsersStoreState} from './types'
|
|
5
|
+
import {DEFAULT_USERS_BATCH_SIZE} from './usersConstants'
|
|
6
|
+
|
|
7
|
+
/** @internal */
|
|
8
|
+
export const getUsersKey = (
|
|
9
|
+
instance: SanityInstance,
|
|
10
|
+
{
|
|
11
|
+
resourceType,
|
|
12
|
+
organizationId,
|
|
13
|
+
batchSize = DEFAULT_USERS_BATCH_SIZE,
|
|
14
|
+
projectId = instance.config.projectId,
|
|
15
|
+
}: GetUsersOptions = {},
|
|
16
|
+
): string =>
|
|
17
|
+
JSON.stringify({resourceType, organizationId, batchSize, projectId} satisfies ReturnType<
|
|
18
|
+
typeof parseUsersKey
|
|
19
|
+
>)
|
|
20
|
+
|
|
21
|
+
/** @internal */
|
|
22
|
+
export const parseUsersKey = (
|
|
23
|
+
key: string,
|
|
24
|
+
): {
|
|
25
|
+
batchSize: number
|
|
26
|
+
resourceType?: 'organization' | 'project'
|
|
27
|
+
projectId?: string
|
|
28
|
+
organizationId?: string
|
|
29
|
+
} => JSON.parse(key)
|
|
30
|
+
|
|
31
|
+
export const addSubscription =
|
|
32
|
+
(subscriptionId: string, key: string) =>
|
|
33
|
+
(prev: UsersStoreState): UsersStoreState => {
|
|
34
|
+
const group = prev.users[key]
|
|
35
|
+
const subscriptions = [...(group?.subscriptions ?? []), subscriptionId]
|
|
36
|
+
return {...prev, users: {...prev.users, [key]: {...group, subscriptions}}}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export const removeSubscription =
|
|
40
|
+
(subscriptionId: string, key: string) =>
|
|
41
|
+
(prev: UsersStoreState): UsersStoreState => {
|
|
42
|
+
const group = prev.users[key]
|
|
43
|
+
if (!group) return prev
|
|
44
|
+
const subscriptions = group.subscriptions.filter((id) => id !== subscriptionId)
|
|
45
|
+
if (!subscriptions.length) return {...prev, users: omit(prev.users, key)}
|
|
46
|
+
return {...prev, users: {...prev.users, [key]: {...group, subscriptions}}}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export const setUsersData =
|
|
50
|
+
(key: string, {data, nextCursor, totalCount}: SanityUserResponse) =>
|
|
51
|
+
(prev: UsersStoreState): UsersStoreState => {
|
|
52
|
+
const group = prev.users[key]
|
|
53
|
+
if (!group) return prev
|
|
54
|
+
const users = [...(group.users ?? []), ...data]
|
|
55
|
+
return {...prev, users: {...prev.users, [key]: {...group, users, totalCount, nextCursor}}}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export const updateLastLoadMoreRequest =
|
|
59
|
+
(timestamp: string, key: string) =>
|
|
60
|
+
(prev: UsersStoreState): UsersStoreState => {
|
|
61
|
+
const group = prev.users[key]
|
|
62
|
+
if (!group) return prev
|
|
63
|
+
return {...prev, users: {...prev.users, [key]: {...group, lastLoadMoreRequest: timestamp}}}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export const setUsersError =
|
|
67
|
+
(key: string, error: unknown) =>
|
|
68
|
+
(prev: UsersStoreState): UsersStoreState => {
|
|
69
|
+
const group = prev.users[key]
|
|
70
|
+
if (!group) return prev
|
|
71
|
+
return {...prev, users: {...prev.users, [key]: {...group, error}}}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export const cancelRequest =
|
|
75
|
+
(key: string) =>
|
|
76
|
+
(prev: UsersStoreState): UsersStoreState => {
|
|
77
|
+
const group = prev.users[key]
|
|
78
|
+
if (!group) return prev
|
|
79
|
+
if (group.subscriptions.length) return prev
|
|
80
|
+
return {...prev, users: omit(prev.users, key)}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export const initializeRequest =
|
|
84
|
+
(key: string) =>
|
|
85
|
+
(prev: UsersStoreState): UsersStoreState => {
|
|
86
|
+
if (prev.users[key]) return prev
|
|
87
|
+
return {...prev, users: {...prev.users, [key]: {subscriptions: []}}}
|
|
88
|
+
}
|
package/src/users/types.ts
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
* @public
|
|
3
|
-
*/
|
|
4
|
-
export type ResourceType = 'organization' | 'project'
|
|
1
|
+
import {type ProjectHandle} from '../config/sanityConfig'
|
|
5
2
|
|
|
6
3
|
/**
|
|
7
4
|
* @public
|
|
@@ -41,3 +38,48 @@ export interface UserProfile {
|
|
|
41
38
|
isCurrentUser?: boolean
|
|
42
39
|
providerId?: string
|
|
43
40
|
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @public
|
|
44
|
+
*/
|
|
45
|
+
export interface GetUsersOptions extends ProjectHandle {
|
|
46
|
+
resourceType?: 'organization' | 'project'
|
|
47
|
+
batchSize?: number
|
|
48
|
+
organizationId?: string
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @public
|
|
53
|
+
*/
|
|
54
|
+
export interface UsersGroupState {
|
|
55
|
+
subscriptions: string[]
|
|
56
|
+
totalCount?: number
|
|
57
|
+
nextCursor?: string | null
|
|
58
|
+
lastLoadMoreRequest?: string
|
|
59
|
+
users?: SanityUser[]
|
|
60
|
+
error?: unknown
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* @public
|
|
65
|
+
*/
|
|
66
|
+
export interface SanityUserResponse {
|
|
67
|
+
data: SanityUser[]
|
|
68
|
+
totalCount: number
|
|
69
|
+
nextCursor: string | null
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @public
|
|
74
|
+
*/
|
|
75
|
+
export interface UsersStoreState {
|
|
76
|
+
users: {[TUsersKey in string]?: UsersGroupState}
|
|
77
|
+
error?: unknown
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* @public
|
|
82
|
+
*/
|
|
83
|
+
export interface ResolveUsersOptions extends GetUsersOptions {
|
|
84
|
+
signal?: AbortSignal
|
|
85
|
+
}
|