@sanity/client 8.3.0 → 8.4.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.
Files changed (38) hide show
  1. package/dist/{browserUpload-2tz6Sdqp.js → browserUpload-C7PwCs-C.js} +6 -9
  2. package/dist/browserUpload-C7PwCs-C.js.map +1 -0
  3. package/dist/{browserUpload-CwpNx7Vl.js → browserUpload-D-2Rmfjo.js} +6 -9
  4. package/dist/browserUpload-D-2Rmfjo.js.map +1 -0
  5. package/dist/{config-3wiPP-sZ.js → config-CgJ16jET.js} +4 -2
  6. package/dist/config-CgJ16jET.js.map +1 -0
  7. package/dist/csm.js +1 -1
  8. package/dist/{dist-C9ExSk2R.js → dist-C5K_YcEU.js} +3 -2
  9. package/dist/{dist-C9ExSk2R.js.map → dist-C5K_YcEU.js.map} +1 -1
  10. package/dist/index.d.ts +2 -2
  11. package/dist/index.js +912 -75
  12. package/dist/index.js.map +1 -1
  13. package/dist/index.node.d.ts +3255 -2
  14. package/dist/index.node.js +835 -19
  15. package/dist/index.node.js.map +1 -1
  16. package/dist/media-library.d.ts +1 -1
  17. package/dist/rolldown-runtime-4YWMqDIC.js +9 -0
  18. package/dist/{stegaEncodeSourceMap-DbM2fTN4.js → stegaEncodeSourceMap-CO1HKnm2.js} +2 -2
  19. package/dist/{stegaEncodeSourceMap-DbM2fTN4.js.map → stegaEncodeSourceMap-CO1HKnm2.js.map} +1 -1
  20. package/dist/{types-0x2hPfhJ.d.ts → types-DiPF0ENT.d.ts} +3256 -3
  21. package/package.json +3 -2
  22. package/src/SanityClient.ts +7 -0
  23. package/src/assets/AssetsClient.ts +5 -0
  24. package/src/config.ts +1 -0
  25. package/src/context/ContextClient.ts +1006 -0
  26. package/src/context/openapi.json +5345 -0
  27. package/src/context/reads.ts +206 -0
  28. package/src/context/store.ts +100 -0
  29. package/src/context/types.gen.ts +2428 -0
  30. package/src/context/types.ts +228 -0
  31. package/src/data/dataMethods.ts +4 -1
  32. package/src/defineCreateClient.ts +1 -0
  33. package/src/http/browserUpload.ts +0 -12
  34. package/src/types.ts +23 -2
  35. package/src/validators.ts +1 -0
  36. package/dist/browserUpload-2tz6Sdqp.js.map +0 -1
  37. package/dist/browserUpload-CwpNx7Vl.js.map +0 -1
  38. package/dist/config-3wiPP-sZ.js.map +0 -1
@@ -0,0 +1,206 @@
1
+ import {lastValueFrom} from 'rxjs'
2
+
3
+ import type {ObservableSanityClient, SanityClient} from '../SanityClient'
4
+ import type {HttpRequest, QueryParams} from '../types'
5
+ import {_fetch, _organizationId} from './store'
6
+ import type {
7
+ ContextRequestOptions,
8
+ ConversationDoc,
9
+ Entry,
10
+ EntryDoc,
11
+ InstructionDoc,
12
+ IssueDoc,
13
+ McpDoc,
14
+ } from './types'
15
+
16
+ type Client = SanityClient | ObservableSanityClient
17
+
18
+ const ENTRY_TYPE = 'sanity.context.entry'
19
+ const ISSUE_TYPE = 'sanity.context.issue'
20
+ const INSTRUCTION_TYPE = 'sanity.context.instruction'
21
+ const MCP_TYPE = 'sanity.context.mcp'
22
+ const CONVERSATION_TYPE = 'sanity.context.conversation'
23
+
24
+ /** Documents per page while a list read drains the store to completion. */
25
+ const PAGE_SIZE = 200
26
+
27
+ /** MCP endpoint configurations are few; one capped page covers them all. */
28
+ const MCP_LIST_LIMIT = 500
29
+
30
+ /** Keyset cursor over the `| order(_createdAt asc, _id asc)` total order. */
31
+ const CREATED_AT_KEYSET = '(_createdAt > $c || (_createdAt == $c && _id > $i))'
32
+
33
+ function _one<R>(
34
+ client: Client,
35
+ httpRequest: HttpRequest,
36
+ query: string,
37
+ params: QueryParams,
38
+ options?: ContextRequestOptions,
39
+ ): Promise<R | null> {
40
+ return lastValueFrom(_fetch<R | null>(client, httpRequest, query, params, options))
41
+ }
42
+
43
+ /**
44
+ * Drain every page of a `(_createdAt, _id)`-keyset read. Termination keys on
45
+ * the raw page length before anything looks at the rows: a short page means
46
+ * the store had nothing more to give, and filtering must never shorten a
47
+ * full page into a false stop.
48
+ */
49
+ async function _drainByCreatedAt<T extends {_createdAt: string; _id: string}>(
50
+ client: Client,
51
+ httpRequest: HttpRequest,
52
+ filter: string,
53
+ params: QueryParams,
54
+ options?: ContextRequestOptions,
55
+ ): Promise<T[]> {
56
+ const all: T[] = []
57
+ let cursor: {c: string; i: string} | undefined
58
+ for (;;) {
59
+ const pagedFilter = cursor ? `${filter} && ${CREATED_AT_KEYSET}` : filter
60
+ const query = `*[${pagedFilter}] | order(_createdAt asc, _id asc) [0...${PAGE_SIZE}]`
61
+ const page = await lastValueFrom(
62
+ _fetch<T[]>(client, httpRequest, query, cursor ? {...params, ...cursor} : params, options),
63
+ )
64
+ all.push(...page)
65
+ if (page.length < PAGE_SIZE) return all
66
+ const last = page[page.length - 1]
67
+ cursor = {c: last._createdAt, i: last._id}
68
+ }
69
+ }
70
+
71
+ /** @internal */
72
+ export function _readEntry(
73
+ client: Client,
74
+ httpRequest: HttpRequest,
75
+ knowledgeBaseId: string,
76
+ path: string,
77
+ options?: ContextRequestOptions,
78
+ ): Promise<EntryDoc | null> {
79
+ return _one<EntryDoc>(
80
+ client,
81
+ httpRequest,
82
+ `*[_type == "${ENTRY_TYPE}" && knowledgeBaseId == $kb && path == $path][0]`,
83
+ {kb: knowledgeBaseId, path},
84
+ options,
85
+ )
86
+ }
87
+
88
+ /** @internal */
89
+ export async function _listEntries(
90
+ client: Client,
91
+ httpRequest: HttpRequest,
92
+ knowledgeBaseId: string,
93
+ options?: ContextRequestOptions,
94
+ ): Promise<Entry[]> {
95
+ const all: Entry[] = []
96
+ let after = ''
97
+ for (;;) {
98
+ const query = `*[_type == "${ENTRY_TYPE}" && knowledgeBaseId == $kb && path > $after] | order(path asc) [0...${PAGE_SIZE}] {_id, path, title, tldr, status}`
99
+ const page = await lastValueFrom(
100
+ _fetch<Entry[]>(client, httpRequest, query, {kb: knowledgeBaseId, after}, options),
101
+ )
102
+ all.push(...page)
103
+ if (page.length < PAGE_SIZE) return all
104
+ after = page[page.length - 1].path
105
+ }
106
+ }
107
+
108
+ /** @internal */
109
+ export function _listIssues(
110
+ client: Client,
111
+ httpRequest: HttpRequest,
112
+ knowledgeBaseId: string,
113
+ status: 'open' | 'accepted' | 'rejected' | undefined,
114
+ options?: ContextRequestOptions,
115
+ ): Promise<IssueDoc[]> {
116
+ const statusFilter = status === undefined ? '' : ' && status == $status'
117
+ return _drainByCreatedAt<IssueDoc>(
118
+ client,
119
+ httpRequest,
120
+ `_type == "${ISSUE_TYPE}" && knowledgeBaseId == $kb${statusFilter}`,
121
+ status === undefined ? {kb: knowledgeBaseId} : {kb: knowledgeBaseId, status},
122
+ options,
123
+ )
124
+ }
125
+
126
+ /** @internal */
127
+ export function _readIssue(
128
+ client: Client,
129
+ httpRequest: HttpRequest,
130
+ knowledgeBaseId: string,
131
+ issueId: string,
132
+ options?: ContextRequestOptions,
133
+ ): Promise<IssueDoc | null> {
134
+ return _one<IssueDoc>(
135
+ client,
136
+ httpRequest,
137
+ `*[_type == "${ISSUE_TYPE}" && knowledgeBaseId == $kb && _id == $id][0]`,
138
+ {kb: knowledgeBaseId, id: issueId},
139
+ options,
140
+ )
141
+ }
142
+
143
+ /** @internal */
144
+ export function _listInstructions(
145
+ client: Client,
146
+ httpRequest: HttpRequest,
147
+ knowledgeBaseId: string,
148
+ options?: ContextRequestOptions,
149
+ ): Promise<InstructionDoc[]> {
150
+ return _drainByCreatedAt<InstructionDoc>(
151
+ client,
152
+ httpRequest,
153
+ `_type == "${INSTRUCTION_TYPE}" && knowledgeBaseId == $kb && schemaVersion == 1`,
154
+ {kb: knowledgeBaseId},
155
+ options,
156
+ )
157
+ }
158
+
159
+ /** @internal */
160
+ export function _listMcpEndpoints(
161
+ client: Client,
162
+ httpRequest: HttpRequest,
163
+ options?: ContextRequestOptions,
164
+ ): Promise<McpDoc[]> {
165
+ return lastValueFrom(
166
+ _fetch<McpDoc[]>(
167
+ client,
168
+ httpRequest,
169
+ `*[_type == "${MCP_TYPE}" && organizationId == $org] | order(_createdAt asc, _id asc) [0...${MCP_LIST_LIMIT}]`,
170
+ {org: _organizationId(client)},
171
+ options,
172
+ ),
173
+ )
174
+ }
175
+
176
+ /** @internal */
177
+ export function _readMcpEndpoint(
178
+ client: Client,
179
+ httpRequest: HttpRequest,
180
+ name: string,
181
+ options?: ContextRequestOptions,
182
+ ): Promise<McpDoc | null> {
183
+ return _one<McpDoc>(
184
+ client,
185
+ httpRequest,
186
+ `*[_type == "${MCP_TYPE}" && organizationId == $org && name == $name][0]`,
187
+ {org: _organizationId(client), name},
188
+ options,
189
+ )
190
+ }
191
+
192
+ /** @internal */
193
+ export function _readConversation(
194
+ client: Client,
195
+ httpRequest: HttpRequest,
196
+ threadId: string,
197
+ options?: ContextRequestOptions,
198
+ ): Promise<ConversationDoc | null> {
199
+ return _one<ConversationDoc>(
200
+ client,
201
+ httpRequest,
202
+ `*[_type == "${CONVERSATION_TYPE}" && organizationId == $org && threadId == $threadId][0]`,
203
+ {org: _organizationId(client), threadId},
204
+ options,
205
+ )
206
+ }
@@ -0,0 +1,100 @@
1
+ import {type Observable, throwError} from 'rxjs'
2
+ import {map} from 'rxjs/operators'
3
+
4
+ import {_requestObservable, getQuerySizeLimit} from '../data/dataMethods'
5
+ import {encodeQueryString} from '../data/encodeQueryString'
6
+ import {
7
+ _connectListenEventSource,
8
+ defaultOptions as defaultListenOptions,
9
+ type ListenEventFromOptions,
10
+ MAX_URL_LENGTH,
11
+ possibleOptions as possibleListenOptions,
12
+ } from '../data/listen'
13
+ import type {ObservableSanityClient, SanityClient} from '../SanityClient'
14
+ import type {HttpRequest, QueryParams, ResumableListenEventNames, SanityDocument} from '../types'
15
+ import defaults from '../util/defaults'
16
+ import {pick} from '../util/pick'
17
+ import {
18
+ type ContextListenOptions,
19
+ type ContextRequestOptions,
20
+ possibleStoreRequestOptions,
21
+ } from './types'
22
+
23
+ type Client = SanityClient | ObservableSanityClient
24
+
25
+ /** @internal */
26
+ export function _organizationId(client: Client): string {
27
+ const organizationId = client.config().context?.organizationId
28
+
29
+ if (!organizationId) {
30
+ throw new Error('`context.organizationId` must be configured to query Context documents')
31
+ }
32
+
33
+ return organizationId
34
+ }
35
+
36
+ function storeUrl(client: Client, suffix: 'query' | 'listen'): string {
37
+ return `/context/organizations/${encodeURIComponent(_organizationId(client))}/${suffix}`
38
+ }
39
+
40
+ /** @internal */
41
+ export function _fetch<R>(
42
+ client: Client,
43
+ httpRequest: HttpRequest,
44
+ query: string,
45
+ params?: QueryParams,
46
+ options?: ContextRequestOptions,
47
+ ): Observable<R> {
48
+ const url = storeUrl(client, 'query')
49
+
50
+ // Mirrors `client.fetch`: GET while the query fits in the URL, POST beyond that.
51
+ const useGet = encodeQueryString({query, params}).length < getQuerySizeLimit
52
+ const request = useGet
53
+ ? {
54
+ method: 'GET',
55
+ url: `${url}${encodeQueryString({query, params})}`,
56
+ }
57
+ : {
58
+ method: 'POST',
59
+ url,
60
+ body: {query, params: params ?? {}},
61
+ }
62
+
63
+ return _requestObservable<{result: R}>(client, httpRequest, {
64
+ ...request,
65
+ ...pick(options || {}, possibleStoreRequestOptions),
66
+ }).pipe(map((response) => response.result))
67
+ }
68
+
69
+ /** @internal */
70
+ export function _listen<Opts extends ContextListenOptions | undefined = undefined>(
71
+ client: Client,
72
+ query: string,
73
+ params?: QueryParams,
74
+ options?: Opts,
75
+ ): Observable<ListenEventFromOptions<SanityDocument, Opts>> {
76
+ const opts: ContextListenOptions = options ?? {}
77
+
78
+ // Mirrors `_listen` in data/listen.ts, but against the Context store's listen endpoint
79
+ const {requestTagPrefix} = client.config()
80
+ const tag = opts.tag && requestTagPrefix ? [requestTagPrefix, opts.tag].join('.') : opts.tag
81
+ const listenOpts = pick({...defaults(opts, defaultListenOptions), tag}, possibleListenOptions)
82
+ const qs = encodeQueryString({
83
+ query,
84
+ params,
85
+ options: listenOpts,
86
+ })
87
+
88
+ const uri = `${client.getUrl(storeUrl(client, 'listen'))}${qs}`
89
+ if (uri.length > MAX_URL_LENGTH) {
90
+ return throwError(() => new Error('Query too large for listener'))
91
+ }
92
+
93
+ const events: ResumableListenEventNames[] = opts.events ? opts.events : ['mutation']
94
+
95
+ return _connectListenEventSource<ListenEventFromOptions<SanityDocument, Opts>>(
96
+ client,
97
+ uri,
98
+ events,
99
+ )
100
+ }