@sanity/client 8.0.0 → 8.2.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/README.md +265 -0
- package/dist/{browserUpload-CQgx9YYo.js → browserUpload-2tz6Sdqp.js} +4 -3
- package/dist/browserUpload-2tz6Sdqp.js.map +1 -0
- package/dist/{browserUpload-icWlVP15.js → browserUpload-CwpNx7Vl.js} +4 -3
- package/dist/browserUpload-CwpNx7Vl.js.map +1 -0
- package/dist/{config-a8VajuEY.js → config-3wiPP-sZ.js} +2 -2
- package/dist/config-3wiPP-sZ.js.map +1 -0
- package/dist/csm.js +2 -2
- package/dist/csm.js.map +1 -1
- package/dist/index.d.ts +17 -11
- package/dist/index.js +610 -136
- package/dist/index.js.map +1 -1
- package/dist/index.node.d.ts +918 -26
- package/dist/index.node.js +559 -66
- package/dist/index.node.js.map +1 -1
- package/dist/media-library.d.ts +1 -1
- package/dist/{request-CJxcN16k.js → request-BhMuKj0D.js} +10 -9
- package/dist/request-BhMuKj0D.js.map +1 -0
- package/dist/{request-k7VS_NnC.js → request-SnMg7nUX.js} +10 -9
- package/dist/request-SnMg7nUX.js.map +1 -0
- package/dist/{resolveEditInfo-sq7yF78q.js → resolveEditInfo-Cz-smq3a.js} +17 -3
- package/dist/resolveEditInfo-Cz-smq3a.js.map +1 -0
- package/dist/stega.js +1 -1
- package/dist/{stegaEncodeSourceMap-DkoIlutY.js → stegaEncodeSourceMap-DbM2fTN4.js} +8 -2
- package/dist/stegaEncodeSourceMap-DbM2fTN4.js.map +1 -0
- package/dist/{stegaEncodeSourceMap-B2fGArSf.js → stegaEncodeSourceMap-YR3NQ3iz.js} +2 -2
- package/dist/{stegaEncodeSourceMap-B2fGArSf.js.map → stegaEncodeSourceMap-YR3NQ3iz.js.map} +1 -1
- package/dist/{types-CUxZSgB2.d.ts → types-nJhm5Nyq.d.ts} +910 -24
- package/package.json +26 -11
- package/src/SanityClient.ts +39 -20
- package/src/assets/AssetsClient.ts +54 -5
- package/src/collaboration/CollaborationCommentsClient.ts +387 -0
- package/src/collaboration/comments.ts +313 -0
- package/src/collaboration/types.ts +252 -0
- package/src/csm/applySourceDocuments.ts +2 -4
- package/src/csm/draftUtils.ts +23 -4
- package/src/data/dataMethods.ts +9 -20
- package/src/data/eventsource.ts +71 -41
- package/src/data/listen.ts +20 -5
- package/src/data/live.ts +17 -9
- package/src/data/resolveEventSourceFetch.ts +9 -1
- package/src/defineCreateClient.ts +5 -1
- package/src/functions/FunctionsClient.ts +66 -0
- package/src/functions/invoke.ts +176 -0
- package/src/http/browserUpload.ts +1 -0
- package/src/http/errors.ts +2 -1
- package/src/http/request.ts +8 -14
- package/src/mediaLibrary/MediaLibraryVideoClient.ts +1 -1
- package/src/types.ts +420 -4
- package/src/validators.ts +1 -1
- package/src/warnings.ts +7 -1
- package/dist/browserUpload-CQgx9YYo.js.map +0 -1
- package/dist/browserUpload-icWlVP15.js.map +0 -1
- package/dist/config-a8VajuEY.js.map +0 -1
- package/dist/request-CJxcN16k.js.map +0 -1
- package/dist/request-k7VS_NnC.js.map +0 -1
- package/dist/resolveEditInfo-sq7yF78q.js.map +0 -1
- package/dist/stegaEncodeSourceMap-DkoIlutY.js.map +0 -1
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
import {lastValueFrom, type Observable} from 'rxjs'
|
|
2
|
+
|
|
3
|
+
import type {ListenEventFromOptions} from '../data/listen'
|
|
4
|
+
import type {ObservableSanityClient, SanityClient} from '../SanityClient'
|
|
5
|
+
import type {
|
|
6
|
+
HttpRequest,
|
|
7
|
+
ListenEvent,
|
|
8
|
+
MultipleMutationResult,
|
|
9
|
+
MutationEvent,
|
|
10
|
+
QueryParams,
|
|
11
|
+
} from '../types'
|
|
12
|
+
import {
|
|
13
|
+
_addReaction,
|
|
14
|
+
_create,
|
|
15
|
+
_delete,
|
|
16
|
+
_fetch,
|
|
17
|
+
_getTargetDocumentRef,
|
|
18
|
+
_listen,
|
|
19
|
+
_removeReaction,
|
|
20
|
+
_update,
|
|
21
|
+
} from './comments'
|
|
22
|
+
import type {
|
|
23
|
+
CollaborationCommentCreate,
|
|
24
|
+
CollaborationCommentDocument,
|
|
25
|
+
CollaborationCommentReactionShortName,
|
|
26
|
+
CollaborationCommentsListenOptions,
|
|
27
|
+
CollaborationCommentsRequestOptions,
|
|
28
|
+
CollaborationCommentsWriteOptions,
|
|
29
|
+
CollaborationCommentUpdate,
|
|
30
|
+
} from './types'
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Comments on the configured organization resource.
|
|
34
|
+
*
|
|
35
|
+
* Requires `collaboration.organizationId`, plus either `resource` or `projectId` and `dataset`.
|
|
36
|
+
*
|
|
37
|
+
* @alpha
|
|
38
|
+
*/
|
|
39
|
+
export class ObservableCollaborationCommentsClient {
|
|
40
|
+
#client: ObservableSanityClient
|
|
41
|
+
#httpRequest: HttpRequest
|
|
42
|
+
constructor(client: ObservableSanityClient, httpRequest: HttpRequest) {
|
|
43
|
+
this.#client = client
|
|
44
|
+
this.#httpRequest = httpRequest
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Create a comment or reply on the configured resource.
|
|
49
|
+
*
|
|
50
|
+
* A top-level comment requires `target`; a reply requires `parentCommentId` (never both).
|
|
51
|
+
* Replies inherit `target`, `status`, and `threadId` from the parent comment.
|
|
52
|
+
*
|
|
53
|
+
* @param body - Comment to create
|
|
54
|
+
* @param options - Optional request options
|
|
55
|
+
* @returns The created comment
|
|
56
|
+
*/
|
|
57
|
+
create(
|
|
58
|
+
body: CollaborationCommentCreate,
|
|
59
|
+
options?: CollaborationCommentsWriteOptions,
|
|
60
|
+
): Observable<CollaborationCommentDocument> {
|
|
61
|
+
return _create(this.#client, this.#httpRequest, body, options)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Update an existing comment.
|
|
66
|
+
*
|
|
67
|
+
* Updating `status` cascades to the comment's replies.
|
|
68
|
+
*
|
|
69
|
+
* @param id - Comment document ID
|
|
70
|
+
* @param body - Fields to update
|
|
71
|
+
* @param options - Optional request options
|
|
72
|
+
* @returns The updated comment
|
|
73
|
+
*/
|
|
74
|
+
update(
|
|
75
|
+
id: string,
|
|
76
|
+
body: CollaborationCommentUpdate,
|
|
77
|
+
options?: CollaborationCommentsWriteOptions,
|
|
78
|
+
): Observable<CollaborationCommentDocument> {
|
|
79
|
+
return _update(this.#client, this.#httpRequest, id, body, options)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Delete a comment and its replies.
|
|
84
|
+
*
|
|
85
|
+
* @param id - Comment document ID
|
|
86
|
+
* @param options - Optional request options
|
|
87
|
+
* @returns Mutation result, where `documentIds` covers the comment and every deleted reply
|
|
88
|
+
*/
|
|
89
|
+
delete(
|
|
90
|
+
id: string,
|
|
91
|
+
options?: CollaborationCommentsWriteOptions,
|
|
92
|
+
): Observable<MultipleMutationResult> {
|
|
93
|
+
return _delete(this.#client, this.#httpRequest, id, options)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Add the current user's reaction to a comment.
|
|
98
|
+
*
|
|
99
|
+
* @param id - Comment document ID
|
|
100
|
+
* @param shortName - Emoji short name, for example `:+1:`
|
|
101
|
+
* @param options - Optional request options
|
|
102
|
+
* @returns The comment, with the reaction applied
|
|
103
|
+
*/
|
|
104
|
+
addReaction(
|
|
105
|
+
id: string,
|
|
106
|
+
shortName: CollaborationCommentReactionShortName,
|
|
107
|
+
options?: CollaborationCommentsWriteOptions,
|
|
108
|
+
): Observable<CollaborationCommentDocument> {
|
|
109
|
+
return _addReaction(this.#client, this.#httpRequest, id, shortName, options)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Remove the current user's reaction from a comment.
|
|
114
|
+
*
|
|
115
|
+
* @param id - Comment document ID
|
|
116
|
+
* @param shortName - Emoji short name, for example `:+1:`
|
|
117
|
+
* @param options - Optional request options
|
|
118
|
+
* @returns The comment, with the reaction removed
|
|
119
|
+
*/
|
|
120
|
+
removeReaction(
|
|
121
|
+
id: string,
|
|
122
|
+
shortName: CollaborationCommentReactionShortName,
|
|
123
|
+
options?: CollaborationCommentsWriteOptions,
|
|
124
|
+
): Observable<CollaborationCommentDocument> {
|
|
125
|
+
return _removeReaction(this.#client, this.#httpRequest, id, shortName, options)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Build the global document reference used by `target.document._ref`, for use in
|
|
130
|
+
* queries and listeners.
|
|
131
|
+
*
|
|
132
|
+
* The reference is built from the configured `resource` and the published ID of
|
|
133
|
+
* the given document ID, since comment references always use published IDs.
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* ```ts
|
|
137
|
+
* client.collaboration.comments.listen(
|
|
138
|
+
* '*[_type == "sanity.comment" && target.document._ref == $ref]',
|
|
139
|
+
* {ref: client.collaboration.comments.getTargetDocumentRef('doc-1')},
|
|
140
|
+
* )
|
|
141
|
+
* ```
|
|
142
|
+
*
|
|
143
|
+
* @param documentId - Document ID, in published, draft or version form
|
|
144
|
+
* @returns Global document reference, of the form `resourceType:resourceId:documentId`
|
|
145
|
+
*/
|
|
146
|
+
getTargetDocumentRef(
|
|
147
|
+
documentId: string,
|
|
148
|
+
): CollaborationCommentDocument['target']['document']['_ref'] {
|
|
149
|
+
return _getTargetDocumentRef(this.#client, documentId)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Fetch comments on the configured resource.
|
|
154
|
+
*
|
|
155
|
+
* Takes the same `query` and `params` as `client.fetch`, and switches from a
|
|
156
|
+
* GET to a POST for queries too large for the request URL in the same way,
|
|
157
|
+
* but queries the comments endpoint, which accepts none of the query options
|
|
158
|
+
* `client.fetch` does (`perspective`, `useCdn`, `filterResponse`,
|
|
159
|
+
* `resultSourceMap`, stega).
|
|
160
|
+
*
|
|
161
|
+
* The query runs against the organization store, which is not scoped to
|
|
162
|
+
* comments, so filter on `_type == "sanity.comment"`.
|
|
163
|
+
*
|
|
164
|
+
* @param query - GROQ-query to perform
|
|
165
|
+
* @param params - Optional query parameters
|
|
166
|
+
* @param options - Optional request options
|
|
167
|
+
*/
|
|
168
|
+
fetch<R = unknown>(
|
|
169
|
+
query: string,
|
|
170
|
+
params?: QueryParams,
|
|
171
|
+
options?: CollaborationCommentsRequestOptions,
|
|
172
|
+
): Observable<R> {
|
|
173
|
+
return _fetch<R>(this.#client, this.#httpRequest, query, params, options)
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Listen for changes to comments on the configured resource.
|
|
178
|
+
*
|
|
179
|
+
* Mirrors `client.listen(query, params)`, and emits mutation events.
|
|
180
|
+
*
|
|
181
|
+
* @param query - GROQ-filter to listen to changes for
|
|
182
|
+
* @param params - Optional query parameters
|
|
183
|
+
*/
|
|
184
|
+
listen(
|
|
185
|
+
query: string,
|
|
186
|
+
params?: QueryParams,
|
|
187
|
+
): Observable<MutationEvent<CollaborationCommentDocument>>
|
|
188
|
+
/**
|
|
189
|
+
* Listen for changes to comments on the configured resource.
|
|
190
|
+
*
|
|
191
|
+
* Mirrors `client.listen(query, params, options)`.
|
|
192
|
+
*
|
|
193
|
+
* @param query - GROQ-filter to listen to changes for
|
|
194
|
+
* @param params - Optional query parameters
|
|
195
|
+
* @param options - The same listener options `client.listen` takes, forwarded
|
|
196
|
+
* to the organization store's listener
|
|
197
|
+
*/
|
|
198
|
+
listen<Opts extends CollaborationCommentsListenOptions>(
|
|
199
|
+
query: string,
|
|
200
|
+
params: QueryParams | undefined,
|
|
201
|
+
options: Opts,
|
|
202
|
+
): Observable<ListenEventFromOptions<CollaborationCommentDocument, Opts>>
|
|
203
|
+
listen(
|
|
204
|
+
query: string,
|
|
205
|
+
params?: QueryParams,
|
|
206
|
+
options?: CollaborationCommentsListenOptions,
|
|
207
|
+
): Observable<ListenEvent<CollaborationCommentDocument>> {
|
|
208
|
+
return _listen(this.#client, query, params, options)
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Comments on the configured organization resource.
|
|
214
|
+
*
|
|
215
|
+
* Requires `collaboration.organizationId`, plus either `resource` or `projectId` and `dataset`.
|
|
216
|
+
*
|
|
217
|
+
* @alpha
|
|
218
|
+
*/
|
|
219
|
+
export class CollaborationCommentsClient {
|
|
220
|
+
#client: SanityClient
|
|
221
|
+
#httpRequest: HttpRequest
|
|
222
|
+
constructor(client: SanityClient, httpRequest: HttpRequest) {
|
|
223
|
+
this.#client = client
|
|
224
|
+
this.#httpRequest = httpRequest
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Create a comment or reply on the configured resource.
|
|
229
|
+
*
|
|
230
|
+
* A top-level comment requires `target`; a reply requires `parentCommentId` (never both).
|
|
231
|
+
* Replies inherit `target`, `status`, and `threadId` from the parent comment.
|
|
232
|
+
*
|
|
233
|
+
* @param body - Comment to create
|
|
234
|
+
* @param options - Optional request options
|
|
235
|
+
* @returns The created comment
|
|
236
|
+
*/
|
|
237
|
+
create(
|
|
238
|
+
body: CollaborationCommentCreate,
|
|
239
|
+
options?: CollaborationCommentsWriteOptions,
|
|
240
|
+
): Promise<CollaborationCommentDocument> {
|
|
241
|
+
return lastValueFrom(_create(this.#client, this.#httpRequest, body, options))
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Update an existing comment.
|
|
246
|
+
*
|
|
247
|
+
* Updating `status` cascades to the comment's replies.
|
|
248
|
+
*
|
|
249
|
+
* @param id - Comment document ID
|
|
250
|
+
* @param body - Fields to update
|
|
251
|
+
* @param options - Optional request options
|
|
252
|
+
* @returns The updated comment
|
|
253
|
+
*/
|
|
254
|
+
update(
|
|
255
|
+
id: string,
|
|
256
|
+
body: CollaborationCommentUpdate,
|
|
257
|
+
options?: CollaborationCommentsWriteOptions,
|
|
258
|
+
): Promise<CollaborationCommentDocument> {
|
|
259
|
+
return lastValueFrom(_update(this.#client, this.#httpRequest, id, body, options))
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Delete a comment and its replies.
|
|
264
|
+
*
|
|
265
|
+
* @param id - Comment document ID
|
|
266
|
+
* @param options - Optional request options
|
|
267
|
+
* @returns Mutation result, where `documentIds` covers the comment and every deleted reply
|
|
268
|
+
*/
|
|
269
|
+
delete(id: string, options?: CollaborationCommentsWriteOptions): Promise<MultipleMutationResult> {
|
|
270
|
+
return lastValueFrom(_delete(this.#client, this.#httpRequest, id, options))
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Add the current user's reaction to a comment.
|
|
275
|
+
*
|
|
276
|
+
* @param id - Comment document ID
|
|
277
|
+
* @param shortName - Emoji short name, for example `:+1:`
|
|
278
|
+
* @param options - Optional request options
|
|
279
|
+
* @returns The comment, with the reaction applied
|
|
280
|
+
*/
|
|
281
|
+
addReaction(
|
|
282
|
+
id: string,
|
|
283
|
+
shortName: CollaborationCommentReactionShortName,
|
|
284
|
+
options?: CollaborationCommentsWriteOptions,
|
|
285
|
+
): Promise<CollaborationCommentDocument> {
|
|
286
|
+
return lastValueFrom(_addReaction(this.#client, this.#httpRequest, id, shortName, options))
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Remove the current user's reaction from a comment.
|
|
291
|
+
*
|
|
292
|
+
* @param id - Comment document ID
|
|
293
|
+
* @param shortName - Emoji short name, for example `:+1:`
|
|
294
|
+
* @param options - Optional request options
|
|
295
|
+
* @returns The comment, with the reaction removed
|
|
296
|
+
*/
|
|
297
|
+
removeReaction(
|
|
298
|
+
id: string,
|
|
299
|
+
shortName: CollaborationCommentReactionShortName,
|
|
300
|
+
options?: CollaborationCommentsWriteOptions,
|
|
301
|
+
): Promise<CollaborationCommentDocument> {
|
|
302
|
+
return lastValueFrom(_removeReaction(this.#client, this.#httpRequest, id, shortName, options))
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Build the global document reference used by `target.document._ref`, for use in
|
|
307
|
+
* queries and listeners.
|
|
308
|
+
*
|
|
309
|
+
* The reference is built from the configured `resource` and the published ID of
|
|
310
|
+
* the given document ID, since comment references always use published IDs.
|
|
311
|
+
*
|
|
312
|
+
* @example
|
|
313
|
+
* ```ts
|
|
314
|
+
* const comments = await client.collaboration.comments.fetch(
|
|
315
|
+
* '*[_type == "sanity.comment" && target.document._ref == $ref]',
|
|
316
|
+
* {ref: client.collaboration.comments.getTargetDocumentRef('doc-1')},
|
|
317
|
+
* )
|
|
318
|
+
* ```
|
|
319
|
+
*
|
|
320
|
+
* @param documentId - Document ID, in published, draft or version form
|
|
321
|
+
* @returns Global document reference, of the form `resourceType:resourceId:documentId`
|
|
322
|
+
*/
|
|
323
|
+
getTargetDocumentRef(
|
|
324
|
+
documentId: string,
|
|
325
|
+
): CollaborationCommentDocument['target']['document']['_ref'] {
|
|
326
|
+
return _getTargetDocumentRef(this.#client, documentId)
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Fetch comments on the configured resource.
|
|
331
|
+
*
|
|
332
|
+
* Takes the same `query` and `params` as `client.fetch`, and switches from a
|
|
333
|
+
* GET to a POST for queries too large for the request URL in the same way,
|
|
334
|
+
* but queries the comments endpoint, which accepts none of the query options
|
|
335
|
+
* `client.fetch` does (`perspective`, `useCdn`, `filterResponse`,
|
|
336
|
+
* `resultSourceMap`, stega).
|
|
337
|
+
*
|
|
338
|
+
* The query runs against the organization store, which is not scoped to
|
|
339
|
+
* comments, so filter on `_type == "sanity.comment"`.
|
|
340
|
+
*
|
|
341
|
+
* @param query - GROQ-query to perform
|
|
342
|
+
* @param params - Optional query parameters
|
|
343
|
+
* @param options - Optional request options
|
|
344
|
+
*/
|
|
345
|
+
fetch<R = unknown>(
|
|
346
|
+
query: string,
|
|
347
|
+
params?: QueryParams,
|
|
348
|
+
options?: CollaborationCommentsRequestOptions,
|
|
349
|
+
): Promise<R> {
|
|
350
|
+
return lastValueFrom(_fetch<R>(this.#client, this.#httpRequest, query, params, options))
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Listen for changes to comments on the configured resource.
|
|
355
|
+
*
|
|
356
|
+
* Mirrors `client.listen(query, params)`, and emits mutation events.
|
|
357
|
+
*
|
|
358
|
+
* @param query - GROQ-filter to listen to changes for
|
|
359
|
+
* @param params - Optional query parameters
|
|
360
|
+
*/
|
|
361
|
+
listen(
|
|
362
|
+
query: string,
|
|
363
|
+
params?: QueryParams,
|
|
364
|
+
): Observable<MutationEvent<CollaborationCommentDocument>>
|
|
365
|
+
/**
|
|
366
|
+
* Listen for changes to comments on the configured resource.
|
|
367
|
+
*
|
|
368
|
+
* Mirrors `client.listen(query, params, options)`.
|
|
369
|
+
*
|
|
370
|
+
* @param query - GROQ-filter to listen to changes for
|
|
371
|
+
* @param params - Optional query parameters
|
|
372
|
+
* @param options - The same listener options `client.listen` takes, forwarded
|
|
373
|
+
* to the organization store's listener
|
|
374
|
+
*/
|
|
375
|
+
listen<Opts extends CollaborationCommentsListenOptions>(
|
|
376
|
+
query: string,
|
|
377
|
+
params: QueryParams | undefined,
|
|
378
|
+
options: Opts,
|
|
379
|
+
): Observable<ListenEventFromOptions<CollaborationCommentDocument, Opts>>
|
|
380
|
+
listen(
|
|
381
|
+
query: string,
|
|
382
|
+
params?: QueryParams,
|
|
383
|
+
options?: CollaborationCommentsListenOptions,
|
|
384
|
+
): Observable<ListenEvent<CollaborationCommentDocument>> {
|
|
385
|
+
return _listen(this.#client, query, params, options)
|
|
386
|
+
}
|
|
387
|
+
}
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
import {getPublishedId} from '@sanity/client/csm'
|
|
2
|
+
import {type Observable, throwError} from 'rxjs'
|
|
3
|
+
import {map} from 'rxjs/operators'
|
|
4
|
+
|
|
5
|
+
import {_requestObservable, getQuerySizeLimit} from '../data/dataMethods'
|
|
6
|
+
import {encodeQueryString} from '../data/encodeQueryString'
|
|
7
|
+
import {
|
|
8
|
+
_connectListenEventSource,
|
|
9
|
+
defaultOptions as defaultListenOptions,
|
|
10
|
+
type ListenEventFromOptions,
|
|
11
|
+
MAX_URL_LENGTH,
|
|
12
|
+
possibleOptions as possibleListenOptions,
|
|
13
|
+
} from '../data/listen'
|
|
14
|
+
import type {ObservableSanityClient, SanityClient} from '../SanityClient'
|
|
15
|
+
import type {
|
|
16
|
+
HttpRequest,
|
|
17
|
+
MultipleMutationResult,
|
|
18
|
+
MutationOperation,
|
|
19
|
+
QueryParams,
|
|
20
|
+
ResumableListenEventNames,
|
|
21
|
+
} from '../types'
|
|
22
|
+
import defaults from '../util/defaults'
|
|
23
|
+
import {pick} from '../util/pick'
|
|
24
|
+
import {
|
|
25
|
+
type CollaborationCommentCreate,
|
|
26
|
+
type CollaborationCommentDocument,
|
|
27
|
+
type CollaborationCommentReactionShortName,
|
|
28
|
+
type CollaborationCommentsListenOptions,
|
|
29
|
+
type CollaborationCommentsRequestOptions,
|
|
30
|
+
type CollaborationCommentsWriteOptions,
|
|
31
|
+
type CollaborationCommentUpdate,
|
|
32
|
+
possibleRequestOptions,
|
|
33
|
+
} from './types'
|
|
34
|
+
|
|
35
|
+
type Client = SanityClient | ObservableSanityClient
|
|
36
|
+
|
|
37
|
+
function commentUrl(id: string): string {
|
|
38
|
+
if (!id) {
|
|
39
|
+
throw new Error('Comment ID must be provided')
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return `/collaboration/comments/${encodeURIComponent(id)}`
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function resolveCommentResource(client: Client): {type: string; id: string} {
|
|
46
|
+
const {resource, projectId, dataset} = client.config()
|
|
47
|
+
|
|
48
|
+
if (resource) {
|
|
49
|
+
return resource
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (projectId && dataset) {
|
|
53
|
+
return {type: 'dataset', id: `${projectId}.${dataset}`}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
throw new Error(
|
|
57
|
+
'`resource` or `projectId` and `dataset` must be configured to use collaboration comments',
|
|
58
|
+
)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function resourceQuery(client: Client): Record<string, string> {
|
|
62
|
+
const {collaboration} = client.config()
|
|
63
|
+
const organizationId = collaboration?.organizationId
|
|
64
|
+
|
|
65
|
+
if (!organizationId) {
|
|
66
|
+
throw new Error(
|
|
67
|
+
'`collaboration.organizationId` must be configured to use collaboration comments',
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const resource = resolveCommentResource(client)
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
organizationId,
|
|
75
|
+
resourceId: resource.id,
|
|
76
|
+
resourceType: resource.type,
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** @internal */
|
|
81
|
+
export function _getTargetDocumentRef(
|
|
82
|
+
client: Client,
|
|
83
|
+
documentId: string,
|
|
84
|
+
): CollaborationCommentDocument['target']['document']['_ref'] {
|
|
85
|
+
if (!documentId) {
|
|
86
|
+
throw new Error('Document ID must be provided')
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const resource = resolveCommentResource(client)
|
|
90
|
+
|
|
91
|
+
return `${resource.type}:${resource.id}:${getPublishedId(documentId)}`
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
type WriteArgs = [
|
|
95
|
+
client: Client,
|
|
96
|
+
httpRequest: HttpRequest,
|
|
97
|
+
method: 'POST' | 'PATCH' | 'DELETE',
|
|
98
|
+
url: string,
|
|
99
|
+
body: unknown,
|
|
100
|
+
options?: CollaborationCommentsWriteOptions,
|
|
101
|
+
]
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* The write endpoints pass the mutation response through as-is, mirroring
|
|
105
|
+
* `client.mutate`.
|
|
106
|
+
*/
|
|
107
|
+
interface CommentMutationResponse {
|
|
108
|
+
transactionId: string
|
|
109
|
+
results: {id: string; operation: MutationOperation}[]
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Writes that return a comment come back with the document, since the API
|
|
114
|
+
* requests documents from the org store and 404s when nothing matched. A
|
|
115
|
+
* status update carries one result per cascaded reply on top of the comment
|
|
116
|
+
* itself.
|
|
117
|
+
*/
|
|
118
|
+
interface CommentDocumentMutationResponse extends CommentMutationResponse {
|
|
119
|
+
results: {id: string; operation: MutationOperation; document: CollaborationCommentDocument}[]
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function write<T>(
|
|
123
|
+
client: Client,
|
|
124
|
+
httpRequest: HttpRequest,
|
|
125
|
+
method: 'POST' | 'PATCH' | 'DELETE',
|
|
126
|
+
url: string,
|
|
127
|
+
body: unknown,
|
|
128
|
+
options: CollaborationCommentsWriteOptions = {},
|
|
129
|
+
): Observable<T> {
|
|
130
|
+
return _requestObservable<T>(client, httpRequest, {
|
|
131
|
+
method,
|
|
132
|
+
url,
|
|
133
|
+
body,
|
|
134
|
+
query: {
|
|
135
|
+
...resourceQuery(client),
|
|
136
|
+
...(options.transactionId ? {transactionId: options.transactionId} : {}),
|
|
137
|
+
},
|
|
138
|
+
...pick(options, possibleRequestOptions),
|
|
139
|
+
})
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* `commentId` picks the written comment out of the results: a status update
|
|
144
|
+
* cascades to the comment's replies, and the API leaves the results unordered.
|
|
145
|
+
* Creates pass the requested `_id`, which is undefined when the API assigns
|
|
146
|
+
* one, and always come back with a single result.
|
|
147
|
+
*/
|
|
148
|
+
function writeDocument(
|
|
149
|
+
commentId: string | undefined,
|
|
150
|
+
...args: WriteArgs
|
|
151
|
+
): Observable<CollaborationCommentDocument> {
|
|
152
|
+
return write<CommentDocumentMutationResponse>(...args).pipe(
|
|
153
|
+
map(({results}) => {
|
|
154
|
+
const result = commentId ? results.find(({id}) => id === commentId) : results[0]
|
|
155
|
+
if (!result?.document) {
|
|
156
|
+
throw new Error('Comment write did not return a comment document')
|
|
157
|
+
}
|
|
158
|
+
return result.document
|
|
159
|
+
}),
|
|
160
|
+
)
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function writeMutationResult(...args: WriteArgs): Observable<MultipleMutationResult> {
|
|
164
|
+
return write<CommentMutationResponse>(...args).pipe(
|
|
165
|
+
map(({transactionId, results}) => ({
|
|
166
|
+
transactionId,
|
|
167
|
+
documentIds: results.map((result) => result.id),
|
|
168
|
+
results,
|
|
169
|
+
})),
|
|
170
|
+
)
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/** @internal */
|
|
174
|
+
export function _create(
|
|
175
|
+
client: Client,
|
|
176
|
+
httpRequest: HttpRequest,
|
|
177
|
+
body: CollaborationCommentCreate,
|
|
178
|
+
options?: CollaborationCommentsWriteOptions,
|
|
179
|
+
): Observable<CollaborationCommentDocument> {
|
|
180
|
+
return writeDocument(
|
|
181
|
+
body._id,
|
|
182
|
+
client,
|
|
183
|
+
httpRequest,
|
|
184
|
+
'POST',
|
|
185
|
+
'/collaboration/comments',
|
|
186
|
+
body,
|
|
187
|
+
options,
|
|
188
|
+
)
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/** @internal */
|
|
192
|
+
export function _update(
|
|
193
|
+
client: Client,
|
|
194
|
+
httpRequest: HttpRequest,
|
|
195
|
+
id: string,
|
|
196
|
+
body: CollaborationCommentUpdate,
|
|
197
|
+
options?: CollaborationCommentsWriteOptions,
|
|
198
|
+
): Observable<CollaborationCommentDocument> {
|
|
199
|
+
return writeDocument(id, client, httpRequest, 'PATCH', commentUrl(id), body, options)
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/** @internal */
|
|
203
|
+
export function _delete(
|
|
204
|
+
client: Client,
|
|
205
|
+
httpRequest: HttpRequest,
|
|
206
|
+
id: string,
|
|
207
|
+
options?: CollaborationCommentsWriteOptions,
|
|
208
|
+
): Observable<MultipleMutationResult> {
|
|
209
|
+
return writeMutationResult(client, httpRequest, 'DELETE', commentUrl(id), undefined, options)
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/** @internal */
|
|
213
|
+
export function _addReaction(
|
|
214
|
+
client: Client,
|
|
215
|
+
httpRequest: HttpRequest,
|
|
216
|
+
id: string,
|
|
217
|
+
shortName: CollaborationCommentReactionShortName,
|
|
218
|
+
options?: CollaborationCommentsWriteOptions,
|
|
219
|
+
): Observable<CollaborationCommentDocument> {
|
|
220
|
+
return writeDocument(
|
|
221
|
+
id,
|
|
222
|
+
client,
|
|
223
|
+
httpRequest,
|
|
224
|
+
'POST',
|
|
225
|
+
`${commentUrl(id)}/reactions`,
|
|
226
|
+
{shortName},
|
|
227
|
+
options,
|
|
228
|
+
)
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/** @internal */
|
|
232
|
+
export function _removeReaction(
|
|
233
|
+
client: Client,
|
|
234
|
+
httpRequest: HttpRequest,
|
|
235
|
+
id: string,
|
|
236
|
+
shortName: CollaborationCommentReactionShortName,
|
|
237
|
+
options?: CollaborationCommentsWriteOptions,
|
|
238
|
+
): Observable<CollaborationCommentDocument> {
|
|
239
|
+
return writeDocument(
|
|
240
|
+
id,
|
|
241
|
+
client,
|
|
242
|
+
httpRequest,
|
|
243
|
+
'DELETE',
|
|
244
|
+
`${commentUrl(id)}/reactions/${encodeURIComponent(shortName)}`,
|
|
245
|
+
undefined,
|
|
246
|
+
options,
|
|
247
|
+
)
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/** @internal */
|
|
251
|
+
export function _fetch<R>(
|
|
252
|
+
client: Client,
|
|
253
|
+
httpRequest: HttpRequest,
|
|
254
|
+
query: string,
|
|
255
|
+
params?: QueryParams,
|
|
256
|
+
options?: CollaborationCommentsRequestOptions,
|
|
257
|
+
): Observable<R> {
|
|
258
|
+
const search = resourceQuery(client)
|
|
259
|
+
|
|
260
|
+
// Mirrors `client.fetch`: GET while the query fits in the URL, POST beyond that.
|
|
261
|
+
const useGet = encodeQueryString({query, params}).length < getQuerySizeLimit
|
|
262
|
+
const request = useGet
|
|
263
|
+
? {
|
|
264
|
+
method: 'GET',
|
|
265
|
+
url: `/collaboration/comments/query${encodeQueryString({query, params, options: search})}`,
|
|
266
|
+
}
|
|
267
|
+
: {
|
|
268
|
+
method: 'POST',
|
|
269
|
+
url: '/collaboration/comments/query',
|
|
270
|
+
query: search,
|
|
271
|
+
body: {query, params: params ?? {}},
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
return _requestObservable<{result: R}>(client, httpRequest, {
|
|
275
|
+
...request,
|
|
276
|
+
...pick(options || {}, possibleRequestOptions),
|
|
277
|
+
}).pipe(map((response) => response.result))
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/** @internal */
|
|
281
|
+
export function _listen<
|
|
282
|
+
Opts extends CollaborationCommentsListenOptions = CollaborationCommentsListenOptions,
|
|
283
|
+
>(
|
|
284
|
+
client: Client,
|
|
285
|
+
query: string,
|
|
286
|
+
params?: QueryParams,
|
|
287
|
+
options?: Opts,
|
|
288
|
+
): Observable<ListenEventFromOptions<CollaborationCommentDocument, Opts>> {
|
|
289
|
+
const opts: CollaborationCommentsListenOptions = options ?? {}
|
|
290
|
+
|
|
291
|
+
// Mirrors `_listen` in data/listen.ts, but against the comments listen endpoint
|
|
292
|
+
const {requestTagPrefix} = client.config()
|
|
293
|
+
const tag = opts.tag && requestTagPrefix ? [requestTagPrefix, opts.tag].join('.') : opts.tag
|
|
294
|
+
const listenOpts = pick({...defaults(opts, defaultListenOptions), tag}, possibleListenOptions)
|
|
295
|
+
const qs = encodeQueryString({
|
|
296
|
+
query,
|
|
297
|
+
params,
|
|
298
|
+
options: {...listenOpts, ...resourceQuery(client)},
|
|
299
|
+
})
|
|
300
|
+
|
|
301
|
+
const uri = `${client.getUrl('/collaboration/comments/listen')}${qs}`
|
|
302
|
+
if (uri.length > MAX_URL_LENGTH) {
|
|
303
|
+
return throwError(() => new Error('Query too large for listener'))
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
const events: ResumableListenEventNames[] = opts.events ? opts.events : ['mutation']
|
|
307
|
+
|
|
308
|
+
return _connectListenEventSource<ListenEventFromOptions<CollaborationCommentDocument, Opts>>(
|
|
309
|
+
client,
|
|
310
|
+
uri,
|
|
311
|
+
events,
|
|
312
|
+
)
|
|
313
|
+
}
|