@sanity/sdk 2.8.0 → 3.0.0-rc.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/dist/index.d.ts +228 -239
- package/dist/index.js +287 -454
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/src/_exports/index.ts +16 -17
- package/src/agent/agentActions.test.ts +60 -16
- package/src/agent/agentActions.ts +29 -20
- package/src/auth/authMode.test.ts +0 -25
- package/src/auth/authMode.ts +3 -6
- package/src/auth/authStore.test.ts +129 -66
- package/src/auth/authStore.ts +9 -11
- package/src/auth/dashboardAuth.ts +2 -2
- package/src/auth/getOrganizationVerificationState.test.ts +10 -11
- package/src/auth/handleAuthCallback.test.ts +0 -12
- package/src/auth/handleAuthCallback.ts +9 -3
- package/src/auth/logout.test.ts +0 -6
- package/src/auth/refreshStampedToken.test.ts +121 -17
- package/src/auth/standaloneAuth.ts +9 -3
- package/src/auth/studioAuth.ts +35 -8
- package/src/auth/subscribeToStateAndFetchCurrentUser.test.ts +9 -3
- package/src/auth/subscribeToStateAndFetchCurrentUser.ts +1 -1
- package/src/auth/subscribeToStorageEventsAndSetToken.test.ts +0 -2
- package/src/auth/subscribeToStorageEventsAndSetToken.ts +2 -2
- package/src/auth/utils.ts +33 -0
- package/src/client/clientStore.test.ts +14 -61
- package/src/client/clientStore.ts +52 -28
- package/src/comlink/controller/actions/destroyController.test.ts +1 -4
- package/src/comlink/controller/actions/getOrCreateChannel.test.ts +1 -4
- package/src/comlink/controller/actions/getOrCreateController.test.ts +1 -4
- package/src/comlink/controller/actions/releaseChannel.test.ts +1 -1
- package/src/comlink/controller/comlinkControllerStore.test.ts +1 -4
- package/src/comlink/node/actions/getOrCreateNode.test.ts +1 -4
- package/src/comlink/node/actions/releaseNode.test.ts +1 -4
- package/src/comlink/node/comlinkNodeStore.test.ts +2 -2
- package/src/comlink/node/getNodeState.test.ts +1 -1
- package/src/config/__tests__/handles.test.ts +12 -18
- package/src/config/handles.ts +7 -25
- package/src/config/sanityConfig.ts +99 -52
- package/src/datasets/datasets.test.ts +2 -2
- package/src/datasets/datasets.ts +4 -10
- package/src/document/actions.test.ts +33 -4
- package/src/document/actions.ts +3 -10
- package/src/document/applyDocumentActions.test.ts +17 -18
- package/src/document/applyDocumentActions.ts +9 -12
- package/src/document/documentStore.test.ts +303 -133
- package/src/document/documentStore.ts +70 -61
- package/src/document/permissions.test.ts +44 -8
- package/src/document/processActions.test.ts +77 -7
- package/src/document/reducers.test.ts +35 -3
- package/src/document/sharedListener.test.ts +13 -13
- package/src/document/sharedListener.ts +8 -3
- package/src/favorites/favorites.test.ts +10 -2
- package/src/presence/presenceStore.test.ts +34 -9
- package/src/presence/presenceStore.ts +29 -13
- package/src/preview/previewProjectionUtils.test.ts +192 -0
- package/src/preview/previewProjectionUtils.ts +88 -0
- package/src/preview/{previewStore.ts → types.ts} +6 -25
- package/src/project/project.test.ts +1 -1
- package/src/project/project.ts +14 -20
- package/src/projection/getProjectionState.test.ts +4 -2
- package/src/projection/getProjectionState.ts +2 -21
- package/src/projection/projectionQuery.ts +2 -3
- package/src/projection/projectionStore.test.ts +3 -3
- package/src/projection/resolveProjection.test.ts +2 -1
- package/src/projection/resolveProjection.ts +2 -18
- package/src/projection/subscribeToStateAndFetchBatches.test.ts +2 -2
- package/src/projection/subscribeToStateAndFetchBatches.ts +23 -36
- package/src/projection/types.ts +1 -9
- package/src/projects/projects.test.ts +1 -1
- package/src/query/queryStore.test.ts +86 -28
- package/src/query/queryStore.ts +23 -38
- package/src/releases/getPerspectiveState.test.ts +14 -13
- package/src/releases/getPerspectiveState.ts +6 -6
- package/src/releases/releasesStore.test.ts +21 -6
- package/src/releases/releasesStore.ts +18 -8
- package/src/store/createActionBinder.test.ts +114 -111
- package/src/store/createActionBinder.ts +52 -101
- package/src/store/createSanityInstance.test.ts +13 -83
- package/src/store/createSanityInstance.ts +2 -78
- package/src/store/createStateSourceAction.test.ts +2 -2
- package/src/store/createStateSourceAction.ts +5 -5
- package/src/store/createStoreInstance.test.ts +2 -4
- package/src/users/reducers.test.ts +1 -6
- package/src/users/reducers.ts +2 -2
- package/src/users/types.ts +4 -4
- package/src/users/usersStore.test.ts +12 -15
- package/src/utils/createFetcherStore.test.ts +1 -1
- package/src/utils/logger.test.ts +0 -12
- package/src/utils/logger.ts +3 -8
- package/src/preview/getPreviewState.test.ts +0 -120
- package/src/preview/getPreviewState.ts +0 -91
- package/src/preview/previewQuery.test.ts +0 -236
- package/src/preview/previewQuery.ts +0 -153
- package/src/preview/previewStore.test.ts +0 -36
- package/src/preview/resolvePreview.test.ts +0 -47
- package/src/preview/resolvePreview.ts +0 -20
- package/src/preview/subscribeToStateAndFetchBatches.test.ts +0 -221
- package/src/preview/subscribeToStateAndFetchBatches.ts +0 -112
- package/src/preview/util.ts +0 -13
|
@@ -5,14 +5,14 @@ import {createSanityInstance} from './createSanityInstance'
|
|
|
5
5
|
|
|
6
6
|
describe('createSanityInstance', () => {
|
|
7
7
|
it('should create an instance with a unique instanceId and given config', () => {
|
|
8
|
-
const instance = createSanityInstance(
|
|
8
|
+
const instance = createSanityInstance()
|
|
9
9
|
expect(typeof instance.instanceId).toBe('string')
|
|
10
|
-
expect(instance.config).toEqual({
|
|
10
|
+
expect(instance.config).toEqual({})
|
|
11
11
|
expect(instance.isDisposed()).toBe(false)
|
|
12
12
|
})
|
|
13
13
|
|
|
14
14
|
it('should dispose an instance and call onDispose callbacks', () => {
|
|
15
|
-
const instance = createSanityInstance(
|
|
15
|
+
const instance = createSanityInstance()
|
|
16
16
|
const callback = vi.fn()
|
|
17
17
|
instance.onDispose(callback)
|
|
18
18
|
instance.dispose()
|
|
@@ -21,7 +21,7 @@ describe('createSanityInstance', () => {
|
|
|
21
21
|
})
|
|
22
22
|
|
|
23
23
|
it('should not call onDispose callbacks more than once when disposed multiple times', () => {
|
|
24
|
-
const instance = createSanityInstance(
|
|
24
|
+
const instance = createSanityInstance()
|
|
25
25
|
const callback = vi.fn()
|
|
26
26
|
instance.onDispose(callback)
|
|
27
27
|
instance.dispose()
|
|
@@ -29,60 +29,6 @@ describe('createSanityInstance', () => {
|
|
|
29
29
|
expect(callback).toHaveBeenCalledTimes(1)
|
|
30
30
|
})
|
|
31
31
|
|
|
32
|
-
it('should create a child instance with merged config and correct parent', () => {
|
|
33
|
-
const parent = createSanityInstance({projectId: 'proj1', dataset: 'ds1'})
|
|
34
|
-
const child = parent.createChild({dataset: 'ds2'})
|
|
35
|
-
expect(child.config).toEqual({projectId: 'proj1', dataset: 'ds2'})
|
|
36
|
-
expect(child.getParent()).toBe(parent)
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
it('should match an instance in the hierarchy using match', () => {
|
|
40
|
-
// three-level hierarchy
|
|
41
|
-
const grandparent = createSanityInstance({projectId: 'proj1', dataset: 'ds1'})
|
|
42
|
-
const parent = grandparent.createChild({projectId: 'proj2'})
|
|
43
|
-
const child = parent.createChild({dataset: 'ds2'})
|
|
44
|
-
|
|
45
|
-
expect(child.config).toEqual({projectId: 'proj2', dataset: 'ds2'})
|
|
46
|
-
expect(parent.config).toEqual({projectId: 'proj2', dataset: 'ds1'})
|
|
47
|
-
|
|
48
|
-
expect(child.match({dataset: 'ds2'})).toBe(child)
|
|
49
|
-
expect(child.match({projectId: 'proj2'})).toBe(child)
|
|
50
|
-
expect(child.match({projectId: 'proj1'})).toBe(grandparent)
|
|
51
|
-
expect(parent.match({projectId: 'proj1'})).toBe(grandparent)
|
|
52
|
-
expect(grandparent.match({projectId: 'proj1'})).toBe(grandparent)
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
it('should match `undefined` when the desired resource ID should not be set on an instance', () => {
|
|
56
|
-
const noProjectOrDataset = createSanityInstance()
|
|
57
|
-
const noDataset = noProjectOrDataset.createChild({projectId: 'proj1'})
|
|
58
|
-
const leaf = noDataset.createChild({dataset: 'ds1'})
|
|
59
|
-
|
|
60
|
-
// no keys means anything (in this case, self) will match
|
|
61
|
-
expect(leaf.match({})).toBe(leaf)
|
|
62
|
-
|
|
63
|
-
// `[resourceId]: undefined` means match an instance with no dataset set
|
|
64
|
-
expect(leaf.match({dataset: undefined})).toBe(noDataset)
|
|
65
|
-
expect(noDataset.match({dataset: undefined})).toBe(noDataset)
|
|
66
|
-
expect(leaf.match({projectId: undefined})).toBe(noProjectOrDataset)
|
|
67
|
-
expect(noDataset.match({projectId: undefined})).toBe(noProjectOrDataset)
|
|
68
|
-
expect(noProjectOrDataset.match({projectId: undefined})).toBe(noProjectOrDataset)
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
it('should return undefined when no match is found', () => {
|
|
72
|
-
const instance = createSanityInstance({projectId: 'proj1', dataset: 'ds1'})
|
|
73
|
-
expect(instance.match({dataset: 'non-existent'})).toBeUndefined()
|
|
74
|
-
})
|
|
75
|
-
|
|
76
|
-
it('should inherit and merge auth config', () => {
|
|
77
|
-
const parent = createSanityInstance({
|
|
78
|
-
projectId: 'proj1',
|
|
79
|
-
dataset: 'ds1',
|
|
80
|
-
auth: {apiHost: 'api.sanity.work'},
|
|
81
|
-
})
|
|
82
|
-
const child = parent.createChild({auth: {token: 'my-token'}})
|
|
83
|
-
expect(child.config.auth).toEqual({apiHost: 'api.sanity.work', token: 'my-token'})
|
|
84
|
-
})
|
|
85
|
-
|
|
86
32
|
describe('logging', () => {
|
|
87
33
|
const mockHandler: LogHandler = {
|
|
88
34
|
error: vi.fn(),
|
|
@@ -106,31 +52,30 @@ describe('createSanityInstance', () => {
|
|
|
106
52
|
})
|
|
107
53
|
|
|
108
54
|
it('should log instance creation at info level', () => {
|
|
109
|
-
createSanityInstance(
|
|
55
|
+
createSanityInstance()
|
|
110
56
|
|
|
111
57
|
expect(mockHandler.info).toHaveBeenCalledWith(
|
|
112
58
|
expect.stringContaining('[INFO] [sdk]'),
|
|
113
59
|
expect.objectContaining({
|
|
114
|
-
|
|
115
|
-
|
|
60
|
+
hasAuth: false,
|
|
61
|
+
hasPerspective: false,
|
|
116
62
|
}),
|
|
117
63
|
)
|
|
118
64
|
})
|
|
119
65
|
|
|
120
66
|
it('should log configuration details at debug level', () => {
|
|
121
|
-
createSanityInstance({projectId: 'test-proj', dataset: 'test-
|
|
67
|
+
createSanityInstance({defaultResource: {projectId: 'test-proj', dataset: 'test-dataset'}})
|
|
122
68
|
|
|
123
69
|
expect(mockHandler.debug).toHaveBeenCalledWith(
|
|
124
70
|
expect.stringContaining('[DEBUG] [sdk]'),
|
|
125
71
|
expect.objectContaining({
|
|
126
|
-
|
|
127
|
-
dataset: 'test-ds',
|
|
72
|
+
hasStudioConfig: false,
|
|
128
73
|
}),
|
|
129
74
|
)
|
|
130
75
|
})
|
|
131
76
|
|
|
132
77
|
it('should log instance disposal', () => {
|
|
133
|
-
const instance = createSanityInstance(
|
|
78
|
+
const instance = createSanityInstance()
|
|
134
79
|
vi.clearAllMocks() // Clear creation logs
|
|
135
80
|
|
|
136
81
|
instance.dispose()
|
|
@@ -141,26 +86,11 @@ describe('createSanityInstance', () => {
|
|
|
141
86
|
)
|
|
142
87
|
})
|
|
143
88
|
|
|
144
|
-
it('should
|
|
145
|
-
|
|
146
|
-
vi.clearAllMocks() // Clear parent creation logs
|
|
147
|
-
|
|
148
|
-
parent.createChild({dataset: 'child-ds'})
|
|
149
|
-
|
|
150
|
-
expect(mockHandler.debug).toHaveBeenCalledWith(
|
|
151
|
-
expect.stringContaining('Creating child instance'),
|
|
152
|
-
expect.objectContaining({
|
|
153
|
-
overridingDataset: true,
|
|
154
|
-
}),
|
|
155
|
-
)
|
|
156
|
-
})
|
|
157
|
-
|
|
158
|
-
it('should include instance context in logs', () => {
|
|
159
|
-
createSanityInstance({projectId: 'my-project', dataset: 'my-dataset'})
|
|
89
|
+
it('should include instance id in logs', () => {
|
|
90
|
+
createSanityInstance()
|
|
160
91
|
|
|
161
|
-
// Check that logs include the instance context (project and dataset)
|
|
162
92
|
expect(mockHandler.info).toHaveBeenCalledWith(
|
|
163
|
-
expect.stringMatching(/\[
|
|
93
|
+
expect.stringMatching(/\[instance:/),
|
|
164
94
|
expect.anything(),
|
|
165
95
|
)
|
|
166
96
|
})
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
import {pick} from 'lodash-es'
|
|
2
|
-
|
|
3
1
|
import {type SanityConfig} from '../config/sanityConfig'
|
|
4
2
|
import {insecureRandomId} from '../utils/ids'
|
|
5
3
|
import {createLogger, type InstanceContext} from '../utils/logger'
|
|
6
4
|
|
|
7
5
|
/**
|
|
8
|
-
* Represents a Sanity.io resource instance with its own configuration and lifecycle
|
|
9
|
-
* @remarks Instances form a hierarchy through parent/child relationships
|
|
6
|
+
* Represents a Sanity.io resource instance with its own configuration and lifecycle.
|
|
10
7
|
*
|
|
11
8
|
* @public
|
|
12
9
|
*/
|
|
@@ -17,10 +14,7 @@ export interface SanityInstance {
|
|
|
17
14
|
*/
|
|
18
15
|
readonly instanceId: string
|
|
19
16
|
|
|
20
|
-
/**
|
|
21
|
-
* Resolved configuration for this instance
|
|
22
|
-
* @remarks Merges values from parent instances where appropriate
|
|
23
|
-
*/
|
|
17
|
+
/** Resolved configuration for this instance */
|
|
24
18
|
readonly config: SanityConfig
|
|
25
19
|
|
|
26
20
|
/**
|
|
@@ -41,34 +35,12 @@ export interface SanityInstance {
|
|
|
41
35
|
* @returns Function to unsubscribe the callback
|
|
42
36
|
*/
|
|
43
37
|
onDispose(cb: () => void): () => void
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Gets the parent instance in the hierarchy
|
|
47
|
-
* @returns Parent instance or undefined if this is the root
|
|
48
|
-
*/
|
|
49
|
-
getParent(): SanityInstance | undefined
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Creates a child instance with merged configuration
|
|
53
|
-
* @param config - Configuration to merge with parent values
|
|
54
|
-
* @remarks Child instances inherit parent configuration but can override values
|
|
55
|
-
*/
|
|
56
|
-
createChild(config: SanityConfig): SanityInstance
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Traverses the instance hierarchy to find the first instance whose configuration
|
|
60
|
-
* matches the given target config using a shallow comparison.
|
|
61
|
-
* @param targetConfig - A partial configuration object containing key-value pairs to match.
|
|
62
|
-
* @returns The first matching instance or undefined if no match is found.
|
|
63
|
-
*/
|
|
64
|
-
match(targetConfig: Partial<SanityConfig>): SanityInstance | undefined
|
|
65
38
|
}
|
|
66
39
|
|
|
67
40
|
/**
|
|
68
41
|
* Creates a new Sanity resource instance
|
|
69
42
|
* @param config - Configuration for the instance (optional)
|
|
70
43
|
* @returns A configured SanityInstance
|
|
71
|
-
* @remarks When creating child instances, configurations are merged with parent values
|
|
72
44
|
*
|
|
73
45
|
* @public
|
|
74
46
|
*/
|
|
@@ -77,32 +49,21 @@ export function createSanityInstance(config: SanityConfig = {}): SanityInstance
|
|
|
77
49
|
const disposeListeners = new Map<string, () => void>()
|
|
78
50
|
const disposed = {current: false}
|
|
79
51
|
|
|
80
|
-
// Create instance context for logging
|
|
81
52
|
const instanceContext: InstanceContext = {
|
|
82
53
|
instanceId,
|
|
83
|
-
projectId: config.projectId,
|
|
84
|
-
dataset: config.dataset,
|
|
85
54
|
}
|
|
86
55
|
|
|
87
|
-
// Create logger with instance context
|
|
88
56
|
const logger = createLogger('sdk', {instanceContext})
|
|
89
57
|
|
|
90
|
-
// Log instance creation
|
|
91
58
|
logger.info('Sanity instance created', {
|
|
92
|
-
hasProjectId: !!config.projectId,
|
|
93
|
-
hasDataset: !!config.dataset,
|
|
94
59
|
hasAuth: !!config.auth,
|
|
95
60
|
hasPerspective: !!config.perspective,
|
|
96
61
|
})
|
|
97
62
|
|
|
98
|
-
// Log configuration details at debug level
|
|
99
63
|
logger.debug('Instance configuration', {
|
|
100
|
-
projectId: config.projectId,
|
|
101
|
-
dataset: config.dataset,
|
|
102
64
|
perspective: config.perspective,
|
|
103
65
|
hasStudioConfig: !!config.studio,
|
|
104
66
|
hasStudioTokenSource: !!config.studio?.auth?.token,
|
|
105
|
-
legacyStudioMode: config.studioMode?.enabled,
|
|
106
67
|
hasAuthProviders: !!config.auth?.providers,
|
|
107
68
|
hasAuthToken: !!config.auth?.token,
|
|
108
69
|
})
|
|
@@ -132,43 +93,6 @@ export function createSanityInstance(config: SanityConfig = {}): SanityInstance
|
|
|
132
93
|
disposeListeners.delete(listenerId)
|
|
133
94
|
}
|
|
134
95
|
},
|
|
135
|
-
getParent: () => undefined,
|
|
136
|
-
createChild: (next) => {
|
|
137
|
-
logger.debug('Creating child instance', {
|
|
138
|
-
parentInstanceId: instanceId.slice(0, 8),
|
|
139
|
-
overridingProjectId: !!next.projectId,
|
|
140
|
-
overridingDataset: !!next.dataset,
|
|
141
|
-
overridingAuth: !!next.auth,
|
|
142
|
-
})
|
|
143
|
-
const child = Object.assign(
|
|
144
|
-
createSanityInstance({
|
|
145
|
-
...config,
|
|
146
|
-
...next,
|
|
147
|
-
...(config.auth === next.auth
|
|
148
|
-
? config.auth
|
|
149
|
-
: config.auth && next.auth && {auth: {...config.auth, ...next.auth}}),
|
|
150
|
-
}),
|
|
151
|
-
{getParent: () => instance},
|
|
152
|
-
)
|
|
153
|
-
logger.trace('Child instance created', {
|
|
154
|
-
internal: true,
|
|
155
|
-
childInstanceId: child.instanceId.slice(0, 8),
|
|
156
|
-
})
|
|
157
|
-
return child
|
|
158
|
-
},
|
|
159
|
-
match: (targetConfig) => {
|
|
160
|
-
if (
|
|
161
|
-
Object.entries(pick(targetConfig, 'auth', 'projectId', 'dataset')).every(
|
|
162
|
-
([key, value]) => config[key as keyof SanityConfig] === value,
|
|
163
|
-
)
|
|
164
|
-
) {
|
|
165
|
-
return instance
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
const parent = instance.getParent()
|
|
169
|
-
if (parent) return parent.match(targetConfig)
|
|
170
|
-
return undefined
|
|
171
|
-
},
|
|
172
96
|
}
|
|
173
97
|
|
|
174
98
|
return instance
|
|
@@ -14,7 +14,7 @@ describe('createStateSourceAction', () => {
|
|
|
14
14
|
let instance: SanityInstance
|
|
15
15
|
|
|
16
16
|
beforeEach(() => {
|
|
17
|
-
instance = createSanityInstance(
|
|
17
|
+
instance = createSanityInstance()
|
|
18
18
|
state = createStoreState({count: 0, items: [] as string[]}, {name: 'test-store'})
|
|
19
19
|
})
|
|
20
20
|
|
|
@@ -179,7 +179,7 @@ describe('createStateSourceAction', () => {
|
|
|
179
179
|
|
|
180
180
|
// New test: distinct contexts for same state with different instance
|
|
181
181
|
it('should create distinct contexts for same state with different instance', () => {
|
|
182
|
-
const secondInstance = createSanityInstance(
|
|
182
|
+
const secondInstance = createSanityInstance()
|
|
183
183
|
const selector = vi.fn(({state: s}: SelectorContext<CountStoreState>) => s.count)
|
|
184
184
|
|
|
185
185
|
const source1 = createStateSourceAction(selector)({state, instance, key: null})
|
|
@@ -57,9 +57,9 @@ export interface StateSource<T> {
|
|
|
57
57
|
* ```ts
|
|
58
58
|
* // Using both state and instance in a selector (psuedo example)
|
|
59
59
|
* const getUserByProjectId = createStateSourceAction(
|
|
60
|
-
* ({ state, instance }: SelectorContext<UsersState>, options?:
|
|
60
|
+
* ({ state, instance }: SelectorContext<UsersState>, options?: ResourceHandle) => {
|
|
61
61
|
* const allUsers = state.users
|
|
62
|
-
* const projectId = options?.projectId ?? instance.config.projectId
|
|
62
|
+
* const projectId = options?.projectId ?? instance.config.defaultResource?.projectId
|
|
63
63
|
* return allUsers.filter(user => user.projectId === projectId)
|
|
64
64
|
* }
|
|
65
65
|
* )
|
|
@@ -155,13 +155,13 @@ interface StateSourceOptions<TState, TParams extends unknown[], TReturn, TKey> {
|
|
|
155
155
|
* // ...
|
|
156
156
|
* })
|
|
157
157
|
*
|
|
158
|
-
* const getDocument =
|
|
158
|
+
* const getDocument = bindActionByResource(
|
|
159
159
|
* documentStore,
|
|
160
|
-
* createStateSourceAction(({state}, documentId: string) => state.documents[documentId])
|
|
160
|
+
* createStateSourceAction(({state}, _options, documentId: string) => state.documents[documentId])
|
|
161
161
|
* )
|
|
162
162
|
*
|
|
163
163
|
* // Usage
|
|
164
|
-
* const documentSource = getDocument(sanityInstance, 'doc123')
|
|
164
|
+
* const documentSource = getDocument(sanityInstance, {}, 'doc123')
|
|
165
165
|
* const doc = documentSource.getCurrent()
|
|
166
166
|
* const subscription = documentSource.observable.subscribe(updatedDoc => {
|
|
167
167
|
* console.log('Document changed:', updatedDoc)
|
|
@@ -13,14 +13,12 @@ describe('createStoreInstance', () => {
|
|
|
13
13
|
randomUUID: () => 'test-uuid-1234',
|
|
14
14
|
})
|
|
15
15
|
|
|
16
|
-
instance = createSanityInstance(
|
|
16
|
+
instance = createSanityInstance()
|
|
17
17
|
})
|
|
18
18
|
|
|
19
19
|
const storeDef: StoreDefinition<{count: number}> = {
|
|
20
20
|
name: 'TestStore',
|
|
21
|
-
getInitialState: (
|
|
22
|
-
count: inst.config.projectId === 'test' ? 0 : -1,
|
|
23
|
-
}),
|
|
21
|
+
getInitialState: () => ({count: 0}),
|
|
24
22
|
}
|
|
25
23
|
|
|
26
24
|
it('should create store instance with initial state', () => {
|
|
@@ -19,15 +19,10 @@ describe('Users Reducers', () => {
|
|
|
19
19
|
// Mock SanityInstance for testing
|
|
20
20
|
const mockInstance: SanityInstance = {
|
|
21
21
|
instanceId: 'test-instance-id',
|
|
22
|
-
config: {
|
|
23
|
-
projectId: 'test-project-id',
|
|
24
|
-
},
|
|
22
|
+
config: {},
|
|
25
23
|
isDisposed: () => false,
|
|
26
24
|
dispose: () => {},
|
|
27
25
|
onDispose: () => () => {},
|
|
28
|
-
getParent: () => undefined,
|
|
29
|
-
createChild: (_config) => mockInstance,
|
|
30
|
-
match: () => undefined,
|
|
31
26
|
}
|
|
32
27
|
|
|
33
28
|
const sampleOptions: GetUsersOptions = {
|
package/src/users/reducers.ts
CHANGED
|
@@ -6,12 +6,12 @@ import {DEFAULT_USERS_BATCH_SIZE} from './usersConstants'
|
|
|
6
6
|
|
|
7
7
|
/** @internal */
|
|
8
8
|
export const getUsersKey = (
|
|
9
|
-
|
|
9
|
+
_instance: SanityInstance,
|
|
10
10
|
{
|
|
11
11
|
resourceType,
|
|
12
12
|
organizationId,
|
|
13
13
|
batchSize = DEFAULT_USERS_BATCH_SIZE,
|
|
14
|
-
projectId
|
|
14
|
+
projectId,
|
|
15
15
|
userId,
|
|
16
16
|
}: GetUsersOptions = {},
|
|
17
17
|
): string =>
|
package/src/users/types.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import {type ProjectHandle} from '../config/sanityConfig'
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
* @public
|
|
5
3
|
*/
|
|
@@ -42,7 +40,8 @@ export interface UserProfile {
|
|
|
42
40
|
/**
|
|
43
41
|
* @public
|
|
44
42
|
*/
|
|
45
|
-
export interface GetUsersOptions
|
|
43
|
+
export interface GetUsersOptions {
|
|
44
|
+
projectId?: string
|
|
46
45
|
resourceType?: 'organization' | 'project'
|
|
47
46
|
batchSize?: number
|
|
48
47
|
organizationId?: string
|
|
@@ -88,7 +87,8 @@ export interface ResolveUsersOptions extends GetUsersOptions {
|
|
|
88
87
|
/**
|
|
89
88
|
* @public
|
|
90
89
|
*/
|
|
91
|
-
export interface GetUserOptions
|
|
90
|
+
export interface GetUserOptions {
|
|
91
|
+
projectId?: string
|
|
92
92
|
userId: string
|
|
93
93
|
resourceType?: 'organization' | 'project'
|
|
94
94
|
organizationId?: string
|
|
@@ -87,7 +87,7 @@ describe('usersStore', () => {
|
|
|
87
87
|
})
|
|
88
88
|
|
|
89
89
|
it('initializes users state and cleans up after unsubscribe', async () => {
|
|
90
|
-
const instance = createSanityInstance(
|
|
90
|
+
const instance = createSanityInstance()
|
|
91
91
|
const state = getUsersState(instance, {
|
|
92
92
|
resourceType: 'project',
|
|
93
93
|
projectId: 'project1',
|
|
@@ -122,7 +122,7 @@ describe('usersStore', () => {
|
|
|
122
122
|
})
|
|
123
123
|
|
|
124
124
|
it('maintains state when multiple subscribers exist', async () => {
|
|
125
|
-
const instance = createSanityInstance(
|
|
125
|
+
const instance = createSanityInstance()
|
|
126
126
|
const state = getUsersState(instance, {
|
|
127
127
|
resourceType: 'project',
|
|
128
128
|
projectId: 'project1',
|
|
@@ -165,7 +165,7 @@ describe('usersStore', () => {
|
|
|
165
165
|
})
|
|
166
166
|
|
|
167
167
|
it('resolveUsers works without affecting subscriber cleanup', async () => {
|
|
168
|
-
const instance = createSanityInstance(
|
|
168
|
+
const instance = createSanityInstance()
|
|
169
169
|
const options: GetUsersOptions = {resourceType: 'project', projectId: 'project1'}
|
|
170
170
|
|
|
171
171
|
const state = getUsersState(instance, options)
|
|
@@ -198,7 +198,7 @@ describe('usersStore', () => {
|
|
|
198
198
|
})
|
|
199
199
|
|
|
200
200
|
it('handles abort signal in resolveUsers', async () => {
|
|
201
|
-
const instance = createSanityInstance(
|
|
201
|
+
const instance = createSanityInstance()
|
|
202
202
|
const options: GetUsersOptions = {resourceType: 'project', projectId: 'project1'}
|
|
203
203
|
const abortController = new AbortController()
|
|
204
204
|
|
|
@@ -221,7 +221,7 @@ describe('usersStore', () => {
|
|
|
221
221
|
})
|
|
222
222
|
|
|
223
223
|
it('loads more users when loadMoreUsers is called', async () => {
|
|
224
|
-
const instance = createSanityInstance(
|
|
224
|
+
const instance = createSanityInstance()
|
|
225
225
|
const options: GetUsersOptions = {resourceType: 'project', projectId: 'project1'}
|
|
226
226
|
|
|
227
227
|
// First response has nextCursor
|
|
@@ -291,7 +291,7 @@ describe('usersStore', () => {
|
|
|
291
291
|
})
|
|
292
292
|
|
|
293
293
|
it('throws error when loadMoreUsers is called without initial data', async () => {
|
|
294
|
-
const instance = createSanityInstance(
|
|
294
|
+
const instance = createSanityInstance()
|
|
295
295
|
|
|
296
296
|
// Expect loadMoreUsers to throw when no data is loaded
|
|
297
297
|
await expect(
|
|
@@ -302,7 +302,7 @@ describe('usersStore', () => {
|
|
|
302
302
|
})
|
|
303
303
|
|
|
304
304
|
it('throws error when loadMoreUsers is called with no more data available', async () => {
|
|
305
|
-
const instance = createSanityInstance(
|
|
305
|
+
const instance = createSanityInstance()
|
|
306
306
|
const options: GetUsersOptions = {resourceType: 'project', projectId: 'project1'}
|
|
307
307
|
|
|
308
308
|
// Response with no nextCursor
|
|
@@ -325,7 +325,7 @@ describe('usersStore', () => {
|
|
|
325
325
|
})
|
|
326
326
|
|
|
327
327
|
it('handles errors in users fetching', async () => {
|
|
328
|
-
const instance = createSanityInstance(
|
|
328
|
+
const instance = createSanityInstance()
|
|
329
329
|
const errorMessage = 'Failed to fetch users'
|
|
330
330
|
|
|
331
331
|
// Override request to simulate error
|
|
@@ -351,7 +351,7 @@ describe('usersStore', () => {
|
|
|
351
351
|
})
|
|
352
352
|
|
|
353
353
|
it('delays users state removal after unsubscribe', async () => {
|
|
354
|
-
const instance = createSanityInstance(
|
|
354
|
+
const instance = createSanityInstance()
|
|
355
355
|
const options: GetUsersOptions = {resourceType: 'project', projectId: 'project1'}
|
|
356
356
|
const state = getUsersState(instance, options)
|
|
357
357
|
const unsubscribe = state.subscribe()
|
|
@@ -370,7 +370,7 @@ describe('usersStore', () => {
|
|
|
370
370
|
})
|
|
371
371
|
|
|
372
372
|
it('preserves users state if a new subscriber subscribes before cleanup delay', async () => {
|
|
373
|
-
const instance = createSanityInstance(
|
|
373
|
+
const instance = createSanityInstance()
|
|
374
374
|
const state = getUsersState(instance, {
|
|
375
375
|
resourceType: 'project',
|
|
376
376
|
projectId: 'project1',
|
|
@@ -412,7 +412,7 @@ describe('usersStore', () => {
|
|
|
412
412
|
})
|
|
413
413
|
|
|
414
414
|
it('fetches a single user with a project-scoped ID', async () => {
|
|
415
|
-
const instance = createSanityInstance(
|
|
415
|
+
const instance = createSanityInstance()
|
|
416
416
|
const projectUserId = 'p12345'
|
|
417
417
|
const mockProjectUser: PatchedSanityUserFromClient = {
|
|
418
418
|
id: projectUserId,
|
|
@@ -476,10 +476,7 @@ describe('usersStore', () => {
|
|
|
476
476
|
})
|
|
477
477
|
|
|
478
478
|
it('fetches a single user with a global-scoped ID', async () => {
|
|
479
|
-
const instance = createSanityInstance(
|
|
480
|
-
projectId: 'test',
|
|
481
|
-
dataset: 'test',
|
|
482
|
-
})
|
|
479
|
+
const instance = createSanityInstance()
|
|
483
480
|
const globalUserId = 'g12345'
|
|
484
481
|
const mockGlobalUser: SanityUser = {
|
|
485
482
|
sanityUserId: globalUserId,
|
package/src/utils/logger.test.ts
CHANGED
|
@@ -644,7 +644,6 @@ describe('logger', () => {
|
|
|
644
644
|
instanceContext: {
|
|
645
645
|
instanceId: 'abc123def456',
|
|
646
646
|
projectId: 'my-project',
|
|
647
|
-
dataset: 'production',
|
|
648
647
|
},
|
|
649
648
|
})
|
|
650
649
|
|
|
@@ -654,10 +653,6 @@ describe('logger', () => {
|
|
|
654
653
|
expect.stringContaining('[project:my-project]'),
|
|
655
654
|
expect.any(Object),
|
|
656
655
|
)
|
|
657
|
-
expect(mockHandler.info).toHaveBeenCalledWith(
|
|
658
|
-
expect.stringContaining('[dataset:production]'),
|
|
659
|
-
expect.any(Object),
|
|
660
|
-
)
|
|
661
656
|
expect(mockHandler.info).toHaveBeenCalledWith(
|
|
662
657
|
expect.stringContaining('[instance:abc123de]'), // Truncated to 8 chars
|
|
663
658
|
expect.any(Object),
|
|
@@ -694,7 +689,6 @@ describe('logger', () => {
|
|
|
694
689
|
const logger = createLogger('query', {
|
|
695
690
|
instanceContext: {
|
|
696
691
|
projectId: 'my-project',
|
|
697
|
-
// No dataset or instanceId
|
|
698
692
|
},
|
|
699
693
|
})
|
|
700
694
|
|
|
@@ -704,17 +698,12 @@ describe('logger', () => {
|
|
|
704
698
|
expect.stringContaining('[project:my-project]'),
|
|
705
699
|
expect.any(Object),
|
|
706
700
|
)
|
|
707
|
-
expect(mockHandler.info).not.toHaveBeenCalledWith(
|
|
708
|
-
expect.stringContaining('[dataset:'),
|
|
709
|
-
expect.any(Object),
|
|
710
|
-
)
|
|
711
701
|
})
|
|
712
702
|
|
|
713
703
|
it('should return instance context', () => {
|
|
714
704
|
const instanceContext = {
|
|
715
705
|
instanceId: 'test-instance',
|
|
716
706
|
projectId: 'test-project',
|
|
717
|
-
dataset: 'test-dataset',
|
|
718
707
|
}
|
|
719
708
|
|
|
720
709
|
const logger = createLogger('auth', {instanceContext})
|
|
@@ -738,7 +727,6 @@ describe('logger', () => {
|
|
|
738
727
|
const logger = createLogger('document', {
|
|
739
728
|
instanceContext: {
|
|
740
729
|
projectId: 'my-project',
|
|
741
|
-
dataset: 'production',
|
|
742
730
|
},
|
|
743
731
|
})
|
|
744
732
|
|
package/src/utils/logger.ts
CHANGED
|
@@ -153,9 +153,9 @@ export interface LogContext {
|
|
|
153
153
|
export interface InstanceContext {
|
|
154
154
|
/** Unique instance ID */
|
|
155
155
|
instanceId?: string
|
|
156
|
-
/** Project ID */
|
|
156
|
+
/** Project ID (derived from default resource) */
|
|
157
157
|
projectId?: string
|
|
158
|
-
/** Dataset name */
|
|
158
|
+
/** Dataset name (derived from default resource) */
|
|
159
159
|
dataset?: string
|
|
160
160
|
}
|
|
161
161
|
|
|
@@ -520,14 +520,9 @@ function logRxJSOperator(namespace: string, operator: string, context?: LogConte
|
|
|
520
520
|
* @internal
|
|
521
521
|
*/
|
|
522
522
|
/* c8 ignore next 7 */
|
|
523
|
-
function getInstanceContext(instance: {
|
|
524
|
-
instanceId?: string
|
|
525
|
-
config?: {projectId?: string; dataset?: string}
|
|
526
|
-
}): InstanceContext {
|
|
523
|
+
function getInstanceContext(instance: {instanceId?: string}): InstanceContext {
|
|
527
524
|
return {
|
|
528
525
|
instanceId: instance.instanceId,
|
|
529
|
-
projectId: instance.config?.projectId,
|
|
530
|
-
dataset: instance.config?.dataset,
|
|
531
526
|
}
|
|
532
527
|
}
|
|
533
528
|
|