@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.
- package/dist/{browserUpload-2tz6Sdqp.js → browserUpload-C7PwCs-C.js} +6 -9
- package/dist/browserUpload-C7PwCs-C.js.map +1 -0
- package/dist/{browserUpload-CwpNx7Vl.js → browserUpload-D-2Rmfjo.js} +6 -9
- package/dist/browserUpload-D-2Rmfjo.js.map +1 -0
- package/dist/{config-3wiPP-sZ.js → config-CgJ16jET.js} +4 -2
- package/dist/config-CgJ16jET.js.map +1 -0
- package/dist/csm.js +1 -1
- package/dist/{dist-C9ExSk2R.js → dist-C5K_YcEU.js} +3 -2
- package/dist/{dist-C9ExSk2R.js.map → dist-C5K_YcEU.js.map} +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +912 -75
- package/dist/index.js.map +1 -1
- package/dist/index.node.d.ts +3255 -2
- package/dist/index.node.js +835 -19
- package/dist/index.node.js.map +1 -1
- package/dist/media-library.d.ts +1 -1
- package/dist/rolldown-runtime-4YWMqDIC.js +9 -0
- package/dist/{stegaEncodeSourceMap-DbM2fTN4.js → stegaEncodeSourceMap-CO1HKnm2.js} +2 -2
- package/dist/{stegaEncodeSourceMap-DbM2fTN4.js.map → stegaEncodeSourceMap-CO1HKnm2.js.map} +1 -1
- package/dist/{types-0x2hPfhJ.d.ts → types-DiPF0ENT.d.ts} +3256 -3
- package/package.json +3 -2
- package/src/SanityClient.ts +7 -0
- package/src/assets/AssetsClient.ts +5 -0
- package/src/config.ts +1 -0
- package/src/context/ContextClient.ts +1006 -0
- package/src/context/openapi.json +5345 -0
- package/src/context/reads.ts +206 -0
- package/src/context/store.ts +100 -0
- package/src/context/types.gen.ts +2428 -0
- package/src/context/types.ts +228 -0
- package/src/data/dataMethods.ts +4 -1
- package/src/defineCreateClient.ts +1 -0
- package/src/http/browserUpload.ts +0 -12
- package/src/types.ts +23 -2
- package/src/validators.ts +1 -0
- package/dist/browserUpload-2tz6Sdqp.js.map +0 -1
- package/dist/browserUpload-CwpNx7Vl.js.map +0 -1
- 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
|
+
}
|