@sanity/client 7.26.2 → 8.0.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 +5 -377
- package/dist/browserUpload-CQgx9YYo.js +86 -0
- package/dist/browserUpload-CQgx9YYo.js.map +1 -0
- package/dist/browserUpload-icWlVP15.js +86 -0
- package/dist/browserUpload-icWlVP15.js.map +1 -0
- package/dist/config-a8VajuEY.js +126 -0
- package/dist/config-a8VajuEY.js.map +1 -0
- package/dist/csm.d.ts +122 -335
- package/dist/csm.js +79 -91
- package/dist/csm.js.map +1 -1
- package/dist/dist-C9ExSk2R.js +73 -0
- package/dist/dist-C9ExSk2R.js.map +1 -0
- package/dist/dist-Z8cIRxoB.js +69 -0
- package/dist/dist-Z8cIRxoB.js.map +1 -0
- package/dist/index.d.ts +107 -6723
- package/dist/index.js +2822 -2847
- package/dist/index.js.map +1 -1
- package/dist/{index.d.cts → index.node.d.ts} +4291 -5328
- package/dist/index.node.js +3131 -0
- package/dist/index.node.js.map +1 -0
- package/dist/isRecord-Kfmt-nk-.js +7 -0
- package/dist/isRecord-Kfmt-nk-.js.map +1 -0
- package/dist/media-library.d.ts +9 -100
- package/dist/media-library.js +36 -14
- package/dist/media-library.js.map +1 -1
- package/dist/request-CJxcN16k.js +372 -0
- package/dist/request-CJxcN16k.js.map +1 -0
- package/dist/request-k7VS_NnC.js +354 -0
- package/dist/request-k7VS_NnC.js.map +1 -0
- package/dist/resolveEditInfo-sq7yF78q.js +325 -0
- package/dist/resolveEditInfo-sq7yF78q.js.map +1 -0
- package/dist/rolldown-runtime-vyAXikos.js +9 -0
- package/dist/stega.d.ts +78 -7137
- package/dist/stega.js +27 -20
- package/dist/stega.js.map +1 -1
- package/dist/stegaClean-C18wLWau.js +21 -0
- package/dist/stegaClean-C18wLWau.js.map +1 -0
- package/dist/stegaEncodeSourceMap-B2fGArSf.js +163 -0
- package/dist/stegaEncodeSourceMap-B2fGArSf.js.map +1 -0
- package/dist/stegaEncodeSourceMap-DkoIlutY.js +367 -0
- package/dist/stegaEncodeSourceMap-DkoIlutY.js.map +1 -0
- package/dist/{index.browser.d.cts → types-CUxZSgB2.d.ts} +3956 -5256
- package/dist/types-CfGzbXrl.d.ts +108 -0
- package/package.json +64 -141
- package/src/SanityClient.ts +82 -117
- package/src/agent/actions/AgentActionsClient.ts +12 -12
- package/src/agent/actions/commonTypes.ts +2 -1
- package/src/agent/actions/generate.ts +26 -6
- package/src/agent/actions/patch.ts +27 -7
- package/src/agent/actions/prompt.ts +19 -5
- package/src/agent/actions/transform.ts +23 -5
- package/src/agent/actions/translate.ts +23 -5
- package/src/assets/AssetsClient.ts +71 -23
- package/src/csm/applySourceDocuments.ts +3 -1
- package/src/csm/createEditUrl.ts +1 -1
- package/src/csm/draftUtils.ts +0 -1
- package/src/csm/index.ts +2 -2
- package/src/csm/studioPath.ts +2 -1
- package/src/csm/types.ts +8 -2
- package/src/data/dataMethods.ts +801 -349
- package/src/data/eventsource.ts +13 -10
- package/src/data/listen.ts +18 -23
- package/src/data/live.ts +44 -27
- package/src/data/resolveEventSourceFetch.ts +96 -0
- package/src/datasets/DatasetsClient.ts +58 -41
- package/src/defineCreateClient.ts +35 -23
- package/src/http/browserMiddleware.ts +7 -1
- package/src/http/browserUpload.ts +162 -0
- package/src/http/errors.ts +60 -6
- package/src/http/nodeMiddleware.ts +94 -30
- package/src/http/request.ts +310 -87
- package/src/http/requestOptions.ts +131 -15
- package/src/{index.browser.ts → index.node.ts} +9 -4
- package/src/index.ts +4 -3
- package/src/mediaLibrary/MediaLibraryVideoClient.ts +26 -11
- package/src/projects/ProjectsClient.ts +18 -16
- package/src/releases/ReleasesClient.ts +38 -33
- package/src/stega/index.ts +1 -2
- package/src/stega/stegaEncodeSourceMap.ts +5 -0
- package/src/stega/types.ts +2 -2
- package/src/types.ts +148 -105
- package/src/users/UsersClient.ts +10 -14
- package/src/util/shareReplayLatest.ts +1 -1
- package/src/warnings.ts +6 -1
- package/dist/_chunks-cjs/config.cjs +0 -206
- package/dist/_chunks-cjs/config.cjs.map +0 -1
- package/dist/_chunks-cjs/isRecord.cjs +0 -6
- package/dist/_chunks-cjs/isRecord.cjs.map +0 -1
- package/dist/_chunks-cjs/resolveEditInfo.cjs +0 -334
- package/dist/_chunks-cjs/resolveEditInfo.cjs.map +0 -1
- package/dist/_chunks-cjs/stegaClean.cjs +0 -46
- package/dist/_chunks-cjs/stegaClean.cjs.map +0 -1
- package/dist/_chunks-cjs/stegaEncodeSourceMap.cjs +0 -388
- package/dist/_chunks-cjs/stegaEncodeSourceMap.cjs.map +0 -1
- package/dist/_chunks-es/config.js +0 -207
- package/dist/_chunks-es/config.js.map +0 -1
- package/dist/_chunks-es/isRecord.js +0 -7
- package/dist/_chunks-es/isRecord.js.map +0 -1
- package/dist/_chunks-es/resolveEditInfo.js +0 -335
- package/dist/_chunks-es/resolveEditInfo.js.map +0 -1
- package/dist/_chunks-es/stegaClean.js +0 -47
- package/dist/_chunks-es/stegaClean.js.map +0 -1
- package/dist/_chunks-es/stegaEncodeSourceMap.js +0 -389
- package/dist/_chunks-es/stegaEncodeSourceMap.js.map +0 -1
- package/dist/csm.cjs +0 -99
- package/dist/csm.cjs.map +0 -1
- package/dist/csm.d.cts +0 -391
- package/dist/index.browser.cjs +0 -3106
- package/dist/index.browser.cjs.map +0 -1
- package/dist/index.browser.d.ts +0 -6802
- package/dist/index.browser.js +0 -3082
- package/dist/index.browser.js.map +0 -1
- package/dist/index.cjs +0 -2946
- package/dist/index.cjs.map +0 -1
- package/dist/media-library.cjs +0 -20
- package/dist/media-library.cjs.map +0 -1
- package/dist/media-library.d.cts +0 -117
- package/dist/stega.browser.cjs +0 -29
- package/dist/stega.browser.cjs.map +0 -1
- package/dist/stega.browser.d.cts +0 -7200
- package/dist/stega.browser.d.ts +0 -7200
- package/dist/stega.browser.js +0 -24
- package/dist/stega.browser.js.map +0 -1
- package/dist/stega.cjs +0 -29
- package/dist/stega.cjs.map +0 -1
- package/dist/stega.d.cts +0 -7200
- package/src/data/eventsourcePolyfill.ts +0 -7
- package/umd/.gitkeep +0 -1
- package/umd/sanityClient.js +0 -6543
- package/umd/sanityClient.min.js +0 -6
package/src/data/eventsource.ts
CHANGED
|
@@ -14,8 +14,8 @@ export class ConnectionFailedError extends Error {
|
|
|
14
14
|
readonly name = 'ConnectionFailedError'
|
|
15
15
|
/**
|
|
16
16
|
* HTTP status code of the rejected connection attempt, if known.
|
|
17
|
-
* Only set when the EventSource implementation exposes it — the
|
|
18
|
-
*
|
|
17
|
+
* Only set when the EventSource implementation exposes it — the `eventsource`
|
|
18
|
+
* package used by the client does (as `code` on its error events), while
|
|
19
19
|
* native EventSource implementations (browser and Node.js) do not.
|
|
20
20
|
*/
|
|
21
21
|
readonly status?: number
|
|
@@ -151,8 +151,10 @@ function connectWithESInstance<EventTypeName extends string>(
|
|
|
151
151
|
const [parseError, event] = parseEvent(evt as MessageEvent)
|
|
152
152
|
observer.error(
|
|
153
153
|
parseError
|
|
154
|
-
? new MessageParseError('Unable to parse EventSource error message', {
|
|
155
|
-
|
|
154
|
+
? new MessageParseError('Unable to parse EventSource error message', {
|
|
155
|
+
cause: parseError,
|
|
156
|
+
})
|
|
157
|
+
: new MessageError((event.data as {message: string}).message, event),
|
|
156
158
|
)
|
|
157
159
|
return
|
|
158
160
|
}
|
|
@@ -161,12 +163,13 @@ function connectWithESInstance<EventTypeName extends string>(
|
|
|
161
163
|
// automatically, but in some cases (like when a laptop lid is closed), it will trigger onError
|
|
162
164
|
// if it can't reconnect.
|
|
163
165
|
// see https://html.spec.whatwg.org/multipage/server-sent-events.html#sse-processing-model
|
|
164
|
-
// The
|
|
165
|
-
// (native EventSource implementations
|
|
166
|
-
//
|
|
167
|
-
//
|
|
168
|
-
//
|
|
169
|
-
|
|
166
|
+
// The `eventsource` package exposes the HTTP status of a rejected connection as
|
|
167
|
+
// `code` on the error event (native EventSource implementations expose nothing).
|
|
168
|
+
// A status means the server rejected the connection attempt, so error out
|
|
169
|
+
// regardless of readyState — implementations disagree on whether the connection
|
|
170
|
+
// closes before or after the error event is dispatched — and let
|
|
171
|
+
// `reconnectOnConnectionFailure` classify it (4xx fatal, otherwise retried).
|
|
172
|
+
const rawStatus = (evt as {code?: unknown}).code
|
|
170
173
|
const status = typeof rawStatus === 'number' ? rawStatus : undefined
|
|
171
174
|
if (status !== undefined) {
|
|
172
175
|
observer.error(new ConnectionFailedError('EventSource connection failed', {status}))
|
package/src/data/listen.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {EventSource} from 'eventsource'
|
|
2
|
+
import {Observable, throwError} from 'rxjs'
|
|
2
3
|
import {filter, map} from 'rxjs/operators'
|
|
3
4
|
|
|
4
5
|
import type {ObservableSanityClient, SanityClient} from '../SanityClient'
|
|
@@ -22,8 +23,8 @@ import {pick} from '../util/pick'
|
|
|
22
23
|
import {_getDataUrl} from './dataMethods'
|
|
23
24
|
import {encodeQueryString} from './encodeQueryString'
|
|
24
25
|
import {connectEventSource} from './eventsource'
|
|
25
|
-
import {eventSourcePolyfill} from './eventsourcePolyfill'
|
|
26
26
|
import {reconnectOnConnectionFailure} from './reconnectOnConnectionFailure'
|
|
27
|
+
import {resolveEventSourceFetch} from './resolveEventSourceFetch'
|
|
27
28
|
|
|
28
29
|
// Limit is 16K for a _request_, eg including headers. Have to account for an
|
|
29
30
|
// unknown range of headers, but an average EventSource request from Chrome seems
|
|
@@ -57,7 +58,8 @@ const defaultOptions = {
|
|
|
57
58
|
export type MapListenEventNamesToListenEvents<
|
|
58
59
|
R extends Record<string, Any> = Record<string, Any>,
|
|
59
60
|
Events extends (ResumableListenEventNames | ListenEventName)[] = (
|
|
60
|
-
|
|
61
|
+
| ResumableListenEventNames
|
|
62
|
+
| ListenEventName
|
|
61
63
|
)[],
|
|
62
64
|
> = Events extends (infer E)[]
|
|
63
65
|
? E extends 'welcome'
|
|
@@ -134,7 +136,8 @@ export function _listen<
|
|
|
134
136
|
params?: ListenParams,
|
|
135
137
|
opts: Opts = {} as Opts,
|
|
136
138
|
): Observable<ListenEventFromOptions<R, Opts>> {
|
|
137
|
-
const
|
|
139
|
+
const config = this.config()
|
|
140
|
+
const {url, token, withCredentials, requestTagPrefix, headers: configHeaders} = config
|
|
138
141
|
const tag = opts.tag && requestTagPrefix ? [requestTagPrefix, opts.tag].join('.') : opts.tag
|
|
139
142
|
const options = {...defaults(opts, defaultOptions), tag}
|
|
140
143
|
const listenOpts = pick(options, possibleOptions)
|
|
@@ -147,29 +150,21 @@ export function _listen<
|
|
|
147
150
|
|
|
148
151
|
const listenFor = (options.events ? options.events : ['mutation']) satisfies Opts['events']
|
|
149
152
|
|
|
150
|
-
const
|
|
151
|
-
if (
|
|
152
|
-
|
|
153
|
+
const headers: Record<string, string> = {}
|
|
154
|
+
if (token) {
|
|
155
|
+
headers.Authorization = `Bearer ${token}`
|
|
153
156
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
esOptions.headers = {}
|
|
157
|
-
|
|
158
|
-
if (token) {
|
|
159
|
-
esOptions.headers.Authorization = `Bearer ${token}`
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
if (configHeaders) {
|
|
163
|
-
Object.assign(esOptions.headers, configHeaders)
|
|
164
|
-
}
|
|
157
|
+
if (configHeaders) {
|
|
158
|
+
Object.assign(headers, configHeaders)
|
|
165
159
|
}
|
|
166
160
|
|
|
167
161
|
const initEventSource = () =>
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
162
|
+
new EventSource(uri, {
|
|
163
|
+
fetch: resolveEventSourceFetch(config, {
|
|
164
|
+
headers: Object.keys(headers).length ? headers : undefined,
|
|
165
|
+
withCredentials,
|
|
166
|
+
}),
|
|
167
|
+
})
|
|
173
168
|
|
|
174
169
|
return connectEventSource(initEventSource, listenFor).pipe(
|
|
175
170
|
reconnectOnConnectionFailure(),
|
package/src/data/live.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import {EventSource} from 'eventsource'
|
|
1
2
|
import {catchError, mergeMap, Observable, of, throwError} from 'rxjs'
|
|
2
3
|
import {finalize, map} from 'rxjs/operators'
|
|
3
4
|
|
|
4
5
|
import {CorsOriginError} from '../http/errors'
|
|
5
6
|
import type {ObservableSanityClient, SanityClient} from '../SanityClient'
|
|
6
7
|
import type {
|
|
8
|
+
InitializedClientConfig,
|
|
7
9
|
LiveEvent,
|
|
8
10
|
LiveEventGoAway,
|
|
9
11
|
LiveEventMessage,
|
|
@@ -15,8 +17,8 @@ import type {
|
|
|
15
17
|
import {shareReplayLatest} from '../util/shareReplayLatest'
|
|
16
18
|
import {_getDataUrl} from './dataMethods'
|
|
17
19
|
import {connectEventSource} from './eventsource'
|
|
18
|
-
import {eventSourcePolyfill} from './eventsourcePolyfill'
|
|
19
20
|
import {reconnectOnConnectionFailure} from './reconnectOnConnectionFailure'
|
|
21
|
+
import {resolveEventSourceFetch} from './resolveEventSourceFetch'
|
|
20
22
|
|
|
21
23
|
const requiredApiVersion = '2021-03-25'
|
|
22
24
|
|
|
@@ -50,6 +52,7 @@ export class LiveClient {
|
|
|
50
52
|
*/
|
|
51
53
|
waitFor?: 'function'
|
|
52
54
|
} = {}): Observable<LiveEvent> {
|
|
55
|
+
const config = this.#client.config()
|
|
53
56
|
const {
|
|
54
57
|
projectId,
|
|
55
58
|
apiVersion: _apiVersion,
|
|
@@ -57,7 +60,7 @@ export class LiveClient {
|
|
|
57
60
|
withCredentials,
|
|
58
61
|
requestTagPrefix,
|
|
59
62
|
headers: configHeaders,
|
|
60
|
-
} =
|
|
63
|
+
} = config
|
|
61
64
|
const apiVersion = _apiVersion.replace(/^v/, '')
|
|
62
65
|
if (apiVersion !== 'X' && apiVersion < requiredApiVersion) {
|
|
63
66
|
throw new Error(
|
|
@@ -83,36 +86,39 @@ export class LiveClient {
|
|
|
83
86
|
if (waitFor) {
|
|
84
87
|
url.searchParams.set('waitFor', waitFor)
|
|
85
88
|
}
|
|
86
|
-
const
|
|
87
|
-
if (includeDrafts &&
|
|
88
|
-
|
|
89
|
+
const eventSourceHeaders: Record<string, string> = {}
|
|
90
|
+
if (includeDrafts && token) {
|
|
91
|
+
eventSourceHeaders.Authorization = `Bearer ${token}`
|
|
89
92
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
esOptions.headers = {}
|
|
93
|
-
|
|
94
|
-
if (includeDrafts && token) {
|
|
95
|
-
esOptions.headers.Authorization = `Bearer ${token}`
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if (configHeaders) {
|
|
99
|
-
Object.assign(esOptions.headers, configHeaders)
|
|
100
|
-
}
|
|
93
|
+
if (configHeaders) {
|
|
94
|
+
Object.assign(eventSourceHeaders, configHeaders)
|
|
101
95
|
}
|
|
96
|
+
const eventSourceWithCredentials = Boolean(includeDrafts && withCredentials)
|
|
102
97
|
|
|
103
|
-
|
|
104
|
-
|
|
98
|
+
let transportCache = eventsCache.get(config.resolveFetch)
|
|
99
|
+
if (!transportCache) {
|
|
100
|
+
transportCache = new Map()
|
|
101
|
+
eventsCache.set(config.resolveFetch, transportCache)
|
|
102
|
+
}
|
|
103
|
+
const cacheKey = JSON.stringify([
|
|
104
|
+
url.href,
|
|
105
|
+
typeof config.proxy === 'string' ? config.proxy : null,
|
|
106
|
+
eventSourceHeaders,
|
|
107
|
+
eventSourceWithCredentials,
|
|
108
|
+
])
|
|
109
|
+
const existing = transportCache.get(cacheKey)
|
|
105
110
|
|
|
106
111
|
if (existing) {
|
|
107
112
|
return existing
|
|
108
113
|
}
|
|
109
114
|
|
|
110
115
|
const initEventSource = () =>
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
+
new EventSource(url.href, {
|
|
117
|
+
fetch: resolveEventSourceFetch(config, {
|
|
118
|
+
headers: Object.keys(eventSourceHeaders).length ? eventSourceHeaders : undefined,
|
|
119
|
+
withCredentials: eventSourceWithCredentials,
|
|
120
|
+
}),
|
|
121
|
+
})
|
|
116
122
|
|
|
117
123
|
const events = connectEventSource(initEventSource, [
|
|
118
124
|
'message',
|
|
@@ -125,7 +131,7 @@ export class LiveClient {
|
|
|
125
131
|
const checkCors = checkCorsObservable(
|
|
126
132
|
new URL(this.#client.getUrl('/check/cors', false)),
|
|
127
133
|
projectId,
|
|
128
|
-
|
|
134
|
+
eventSourceWithCredentials,
|
|
129
135
|
)
|
|
130
136
|
|
|
131
137
|
const observable = events
|
|
@@ -162,12 +168,15 @@ export class LiveClient {
|
|
|
162
168
|
}),
|
|
163
169
|
)
|
|
164
170
|
.pipe(
|
|
165
|
-
finalize(() =>
|
|
171
|
+
finalize(() => {
|
|
172
|
+
transportCache.delete(cacheKey)
|
|
173
|
+
if (transportCache.size === 0) eventsCache.delete(config.resolveFetch)
|
|
174
|
+
}),
|
|
166
175
|
shareReplayLatest({
|
|
167
176
|
predicate: (event) => event.type === 'welcome',
|
|
168
177
|
}),
|
|
169
178
|
)
|
|
170
|
-
|
|
179
|
+
transportCache.set(cacheKey, observable)
|
|
171
180
|
return observable
|
|
172
181
|
}
|
|
173
182
|
}
|
|
@@ -262,4 +271,12 @@ function checkCorsObservable(
|
|
|
262
271
|
})
|
|
263
272
|
}
|
|
264
273
|
|
|
265
|
-
|
|
274
|
+
/**
|
|
275
|
+
* Cached observables capture their transport (`initEventSource` closes over
|
|
276
|
+
* `config.resolveFetch` and `config.proxy`), so the cache is scoped per
|
|
277
|
+
* resolver — `undefined` covers the `globalThis.fetch` fallback.
|
|
278
|
+
*/
|
|
279
|
+
const eventsCache = new Map<
|
|
280
|
+
InitializedClientConfig['resolveFetch'],
|
|
281
|
+
Map<string, Observable<LiveEvent>>
|
|
282
|
+
>()
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type {EventSourceFetchInit, FetchLikeResponse} from 'eventsource'
|
|
2
|
+
import type {FetchFunction, FetchInit} from 'get-it'
|
|
3
|
+
|
|
4
|
+
import type {InitializedClientConfig} from '../types'
|
|
5
|
+
|
|
6
|
+
/** @internal */
|
|
7
|
+
export interface EventSourceFetchOptions {
|
|
8
|
+
/**
|
|
9
|
+
* Headers that must be merged into every EventSource request. Used for
|
|
10
|
+
* the `Authorization` token, custom `headers` from the client config,
|
|
11
|
+
* etc. — things the native EventSource API has no equivalent for.
|
|
12
|
+
*/
|
|
13
|
+
headers?: Record<string, string>
|
|
14
|
+
/**
|
|
15
|
+
* If the client was configured with `withCredentials: true`, the
|
|
16
|
+
* resolved fetch forwards `credentials: 'include'` so the browser
|
|
17
|
+
* attaches cookies to the SSE request.
|
|
18
|
+
*/
|
|
19
|
+
withCredentials?: boolean
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Build a `fetch` implementation suitable for the `eventsource` package's
|
|
24
|
+
* `fetch` option. Routes the EventSource connection through the same
|
|
25
|
+
* transport layer the rest of the client uses, so things like the
|
|
26
|
+
* test-fetch override, the per-request `proxy` config, and `HTTPS_PROXY`
|
|
27
|
+
* env-var support apply to SSE too.
|
|
28
|
+
*
|
|
29
|
+
* Resolution order on each request:
|
|
30
|
+
*
|
|
31
|
+
* 1. `config.resolveFetch(config.proxy)` if set — the client's fetch
|
|
32
|
+
* resolver, so SSE uses the same transport as regular requests:
|
|
33
|
+
* custom fetch variants (incl. the test suite's injected mock),
|
|
34
|
+
* undici configuration, an explicit `proxy` config, and env-proxy
|
|
35
|
+
* support all apply to SSE too. The Node entry supplies get-it's
|
|
36
|
+
* undici-backed fetch (threading the resolver through the env
|
|
37
|
+
* instead of importing `get-it/node` directly keeps `undici` out of
|
|
38
|
+
* the browser bundle); the browser entry leaves it unset.
|
|
39
|
+
* 2. `globalThis.fetch`. Note that Node's global fetch does NOT read
|
|
40
|
+
* proxy env vars (that is opt-in via `NODE_USE_ENV_PROXY`), which
|
|
41
|
+
* is one of the reasons step 1 exists.
|
|
42
|
+
*
|
|
43
|
+
* The returned fetch always merges `options.headers` into the outgoing
|
|
44
|
+
* request, regardless of which underlying fetch was picked.
|
|
45
|
+
*
|
|
46
|
+
* @internal
|
|
47
|
+
*/
|
|
48
|
+
export function resolveEventSourceFetch(
|
|
49
|
+
config: InitializedClientConfig,
|
|
50
|
+
options: EventSourceFetchOptions = {},
|
|
51
|
+
): EventSourceFetch {
|
|
52
|
+
const extraHeaders = options.headers
|
|
53
|
+
const credentials: FetchInit['credentials'] = options.withCredentials ? 'include' : undefined
|
|
54
|
+
|
|
55
|
+
return function eventSourceFetch(url, init) {
|
|
56
|
+
const baseFetch = pickBaseFetch(config)
|
|
57
|
+
|
|
58
|
+
// Extra `EventSourceFetchInit` fields get-it's `FetchInit` doesn't
|
|
59
|
+
// declare (`mode`, `cache`) survive the spread and reach whichever
|
|
60
|
+
// fetch implementation is effective.
|
|
61
|
+
const mergedInit: FetchInit = {...init}
|
|
62
|
+
if (extraHeaders) {
|
|
63
|
+
const headers = new Headers(init?.headers)
|
|
64
|
+
for (const [key, value] of Object.entries(extraHeaders)) {
|
|
65
|
+
headers.set(key, value)
|
|
66
|
+
}
|
|
67
|
+
mergedInit.headers = headers
|
|
68
|
+
}
|
|
69
|
+
if (credentials !== undefined) {
|
|
70
|
+
mergedInit.credentials = credentials
|
|
71
|
+
}
|
|
72
|
+
// get-it's `FetchResponse` is a structural superset of the package's
|
|
73
|
+
// `FetchLikeResponse`, so it can be handed over as-is.
|
|
74
|
+
return baseFetch(typeof url === 'string' ? url : url.href, mergedInit)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* The fetch shape handed to the `eventsource` package: accepts what its
|
|
80
|
+
* `FetchLike` passes in, requires only what get-it's `FetchFunction`
|
|
81
|
+
* guarantees back — the full `typeof fetch` contract is not needed anywhere
|
|
82
|
+
* in this chain.
|
|
83
|
+
*
|
|
84
|
+
* @internal
|
|
85
|
+
*/
|
|
86
|
+
export type EventSourceFetch = (
|
|
87
|
+
url: string | URL,
|
|
88
|
+
init?: EventSourceFetchInit,
|
|
89
|
+
) => Promise<FetchLikeResponse>
|
|
90
|
+
|
|
91
|
+
function pickBaseFetch(config: InitializedClientConfig): FetchFunction {
|
|
92
|
+
if (config.resolveFetch) {
|
|
93
|
+
return config.resolveFetch(typeof config.proxy === 'string' ? config.proxy : undefined)
|
|
94
|
+
}
|
|
95
|
+
return globalThis.fetch.bind(globalThis)
|
|
96
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {type Observable} from 'rxjs'
|
|
2
2
|
|
|
3
|
-
import {_request} from '../data/dataMethods'
|
|
3
|
+
import {_request, _requestObservable} from '../data/dataMethods'
|
|
4
4
|
import type {ObservableSanityClient, SanityClient} from '../SanityClient'
|
|
5
5
|
import type {
|
|
6
6
|
DatasetCreateOptions,
|
|
@@ -29,7 +29,7 @@ export class ObservableDatasetsClient {
|
|
|
29
29
|
* @param options - Options for the dataset, including optional embeddings configuration
|
|
30
30
|
*/
|
|
31
31
|
create(name: string, options?: DatasetCreateOptions): Observable<DatasetResponse> {
|
|
32
|
-
return
|
|
32
|
+
return _modifyObservable<DatasetResponse>(this.#client, this.#httpRequest, 'PUT', name, options)
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
/**
|
|
@@ -39,7 +39,13 @@ export class ObservableDatasetsClient {
|
|
|
39
39
|
* @param options - New options for the dataset
|
|
40
40
|
*/
|
|
41
41
|
edit(name: string, options?: DatasetEditOptions): Observable<DatasetResponse> {
|
|
42
|
-
return
|
|
42
|
+
return _modifyObservable<DatasetResponse>(
|
|
43
|
+
this.#client,
|
|
44
|
+
this.#httpRequest,
|
|
45
|
+
'PATCH',
|
|
46
|
+
name,
|
|
47
|
+
options,
|
|
48
|
+
)
|
|
43
49
|
}
|
|
44
50
|
|
|
45
51
|
/**
|
|
@@ -48,7 +54,7 @@ export class ObservableDatasetsClient {
|
|
|
48
54
|
* @param name - Name of the dataset to delete
|
|
49
55
|
*/
|
|
50
56
|
delete(name: string): Observable<{deleted: true}> {
|
|
51
|
-
return
|
|
57
|
+
return _modifyObservable<{deleted: true}>(this.#client, this.#httpRequest, 'DELETE', name)
|
|
52
58
|
}
|
|
53
59
|
|
|
54
60
|
/**
|
|
@@ -58,13 +64,13 @@ export class ObservableDatasetsClient {
|
|
|
58
64
|
validate.resourceGuard('dataset', this.#client.config())
|
|
59
65
|
const config = this.#client.config()
|
|
60
66
|
const projectId = config.projectId
|
|
61
|
-
let
|
|
67
|
+
let url = '/datasets'
|
|
62
68
|
if (config.useProjectHostname === false) {
|
|
63
|
-
|
|
69
|
+
url = `/projects/${projectId}/datasets`
|
|
64
70
|
}
|
|
65
71
|
|
|
66
|
-
return
|
|
67
|
-
|
|
72
|
+
return _requestObservable<DatasetsResponse>(this.#client, this.#httpRequest, {
|
|
73
|
+
url,
|
|
68
74
|
tag: null,
|
|
69
75
|
})
|
|
70
76
|
}
|
|
@@ -77,8 +83,8 @@ export class ObservableDatasetsClient {
|
|
|
77
83
|
getEmbeddingsSettings(name: string): Observable<EmbeddingsSettings> {
|
|
78
84
|
validate.resourceGuard('dataset', this.#client.config())
|
|
79
85
|
validate.dataset(name)
|
|
80
|
-
return
|
|
81
|
-
|
|
86
|
+
return _requestObservable<EmbeddingsSettings>(this.#client, this.#httpRequest, {
|
|
87
|
+
url: _embeddingsSettingsUri(this.#client, name),
|
|
82
88
|
tag: null,
|
|
83
89
|
})
|
|
84
90
|
}
|
|
@@ -92,9 +98,9 @@ export class ObservableDatasetsClient {
|
|
|
92
98
|
editEmbeddingsSettings(name: string, settings: EmbeddingsSettingsBody): Observable<void> {
|
|
93
99
|
validate.resourceGuard('dataset', this.#client.config())
|
|
94
100
|
validate.dataset(name)
|
|
95
|
-
return
|
|
101
|
+
return _requestObservable<void>(this.#client, this.#httpRequest, {
|
|
96
102
|
method: 'PUT',
|
|
97
|
-
|
|
103
|
+
url: _embeddingsSettingsUri(this.#client, name),
|
|
98
104
|
body: settings,
|
|
99
105
|
tag: null,
|
|
100
106
|
})
|
|
@@ -118,9 +124,7 @@ export class DatasetsClient {
|
|
|
118
124
|
*/
|
|
119
125
|
create(name: string, options?: DatasetCreateOptions): Promise<DatasetResponse> {
|
|
120
126
|
validate.resourceGuard('dataset', this.#client.config())
|
|
121
|
-
return
|
|
122
|
-
_modify<DatasetResponse>(this.#client, this.#httpRequest, 'PUT', name, options),
|
|
123
|
-
)
|
|
127
|
+
return _modify<DatasetResponse>(this.#client, this.#httpRequest, 'PUT', name, options)
|
|
124
128
|
}
|
|
125
129
|
|
|
126
130
|
/**
|
|
@@ -131,9 +135,7 @@ export class DatasetsClient {
|
|
|
131
135
|
*/
|
|
132
136
|
edit(name: string, options?: DatasetEditOptions): Promise<DatasetResponse> {
|
|
133
137
|
validate.resourceGuard('dataset', this.#client.config())
|
|
134
|
-
return
|
|
135
|
-
_modify<DatasetResponse>(this.#client, this.#httpRequest, 'PATCH', name, options),
|
|
136
|
-
)
|
|
138
|
+
return _modify<DatasetResponse>(this.#client, this.#httpRequest, 'PATCH', name, options)
|
|
137
139
|
}
|
|
138
140
|
|
|
139
141
|
/**
|
|
@@ -143,7 +145,7 @@ export class DatasetsClient {
|
|
|
143
145
|
*/
|
|
144
146
|
delete(name: string): Promise<{deleted: true}> {
|
|
145
147
|
validate.resourceGuard('dataset', this.#client.config())
|
|
146
|
-
return
|
|
148
|
+
return _modify<{deleted: true}>(this.#client, this.#httpRequest, 'DELETE', name)
|
|
147
149
|
}
|
|
148
150
|
|
|
149
151
|
/**
|
|
@@ -153,14 +155,15 @@ export class DatasetsClient {
|
|
|
153
155
|
validate.resourceGuard('dataset', this.#client.config())
|
|
154
156
|
const config = this.#client.config()
|
|
155
157
|
const projectId = config.projectId
|
|
156
|
-
let
|
|
158
|
+
let url = '/datasets'
|
|
157
159
|
if (config.useProjectHostname === false) {
|
|
158
|
-
|
|
160
|
+
url = `/projects/${projectId}/datasets`
|
|
159
161
|
}
|
|
160
162
|
|
|
161
|
-
return
|
|
162
|
-
|
|
163
|
-
|
|
163
|
+
return _request<DatasetsResponse>(this.#client, this.#httpRequest, {
|
|
164
|
+
url,
|
|
165
|
+
tag: null,
|
|
166
|
+
})
|
|
164
167
|
}
|
|
165
168
|
|
|
166
169
|
/**
|
|
@@ -171,12 +174,10 @@ export class DatasetsClient {
|
|
|
171
174
|
getEmbeddingsSettings(name: string): Promise<EmbeddingsSettings> {
|
|
172
175
|
validate.resourceGuard('dataset', this.#client.config())
|
|
173
176
|
validate.dataset(name)
|
|
174
|
-
return
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
}),
|
|
179
|
-
)
|
|
177
|
+
return _request<EmbeddingsSettings>(this.#client, this.#httpRequest, {
|
|
178
|
+
url: _embeddingsSettingsUri(this.#client, name),
|
|
179
|
+
tag: null,
|
|
180
|
+
})
|
|
180
181
|
}
|
|
181
182
|
|
|
182
183
|
/**
|
|
@@ -188,14 +189,12 @@ export class DatasetsClient {
|
|
|
188
189
|
editEmbeddingsSettings(name: string, settings: EmbeddingsSettingsBody): Promise<void> {
|
|
189
190
|
validate.resourceGuard('dataset', this.#client.config())
|
|
190
191
|
validate.dataset(name)
|
|
191
|
-
return
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
}),
|
|
198
|
-
)
|
|
192
|
+
return _request<void>(this.#client, this.#httpRequest, {
|
|
193
|
+
method: 'PUT',
|
|
194
|
+
url: _embeddingsSettingsUri(this.#client, name),
|
|
195
|
+
body: settings,
|
|
196
|
+
tag: null,
|
|
197
|
+
})
|
|
199
198
|
}
|
|
200
199
|
}
|
|
201
200
|
|
|
@@ -210,7 +209,7 @@ function _embeddingsSettingsUri(
|
|
|
210
209
|
return `/datasets/${name}/settings/embeddings`
|
|
211
210
|
}
|
|
212
211
|
|
|
213
|
-
function
|
|
212
|
+
function _modifyObservable<R = unknown>(
|
|
214
213
|
client: SanityClient | ObservableSanityClient,
|
|
215
214
|
httpRequest: HttpRequest,
|
|
216
215
|
method: 'DELETE' | 'PATCH' | 'PUT',
|
|
@@ -220,9 +219,27 @@ function _modify<R = unknown>(
|
|
|
220
219
|
validate.resourceGuard('dataset', client.config())
|
|
221
220
|
validate.dataset(name)
|
|
222
221
|
|
|
222
|
+
return _requestObservable<R>(client, httpRequest, {
|
|
223
|
+
method,
|
|
224
|
+
url: `/datasets/${name}`,
|
|
225
|
+
body: options,
|
|
226
|
+
tag: null,
|
|
227
|
+
})
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function _modify<R = unknown>(
|
|
231
|
+
client: SanityClient | ObservableSanityClient,
|
|
232
|
+
httpRequest: HttpRequest,
|
|
233
|
+
method: 'DELETE' | 'PATCH' | 'PUT',
|
|
234
|
+
name: string,
|
|
235
|
+
options?: DatasetCreateOptions | DatasetEditOptions,
|
|
236
|
+
): Promise<R> {
|
|
237
|
+
validate.resourceGuard('dataset', client.config())
|
|
238
|
+
validate.dataset(name)
|
|
239
|
+
|
|
223
240
|
return _request<R>(client, httpRequest, {
|
|
224
241
|
method,
|
|
225
|
-
|
|
242
|
+
url: `/datasets/${name}`,
|
|
226
243
|
body: options,
|
|
227
244
|
tag: null,
|
|
228
245
|
})
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import type
|
|
2
|
-
|
|
3
|
-
import {defineHttpRequest} from './http/request'
|
|
4
|
-
import type {Any, ClientConfig, HttpRequest} from './types'
|
|
1
|
+
import {defineRequester, type EnvironmentOptions} from './http/request'
|
|
2
|
+
import type {ClientConfig, HttpRequest} from './types'
|
|
5
3
|
|
|
6
4
|
export {validateApiPerspective} from './config'
|
|
7
5
|
export {
|
|
@@ -29,9 +27,6 @@ export {
|
|
|
29
27
|
export * from './SanityClient'
|
|
30
28
|
export * from './types'
|
|
31
29
|
|
|
32
|
-
/** @alpha */
|
|
33
|
-
export {adapter as unstable__adapter, environment as unstable__environment} from 'get-it'
|
|
34
|
-
|
|
35
30
|
/**
|
|
36
31
|
* Create the `requester` and `createClient` exports, that have environment specific middleware for node and browsers
|
|
37
32
|
* @internal
|
|
@@ -40,27 +35,44 @@ export default function defineCreateClientExports<
|
|
|
40
35
|
SanityClientType,
|
|
41
36
|
ClientConfigType extends ClientConfig,
|
|
42
37
|
>(
|
|
43
|
-
|
|
38
|
+
envOptions: EnvironmentOptions,
|
|
44
39
|
ClassConstructor: new (httpRequest: HttpRequest, config: ClientConfigType) => SanityClientType,
|
|
45
40
|
) {
|
|
46
|
-
// Set the http client to use for requests, and its environment specific
|
|
47
|
-
const defaultRequester =
|
|
41
|
+
// Set the http client to use for requests, and its environment specific options
|
|
42
|
+
const defaultRequester = defineRequester(envOptions).observable
|
|
48
43
|
|
|
49
44
|
const createClient = (config: ClientConfigType) => {
|
|
50
|
-
const clientRequester =
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
maxRetries: config.maxRetries,
|
|
58
|
-
retryDelay: config.retryDelay,
|
|
59
|
-
lineage: config.lineage,
|
|
60
|
-
...options,
|
|
61
|
-
} as Any),
|
|
62
|
-
config,
|
|
45
|
+
const {observable: clientRequester, promise: clientRequesterPromise} = defineRequester(
|
|
46
|
+
envOptions,
|
|
47
|
+
{
|
|
48
|
+
ignoreWarnings: config.ignoreWarnings,
|
|
49
|
+
maxRetries: config.maxRetries,
|
|
50
|
+
retryDelay: config.retryDelay,
|
|
51
|
+
},
|
|
63
52
|
)
|
|
53
|
+
// The single transport for the whole client. Resolves a request to its
|
|
54
|
+
// parsed response body as a Promise; the observable client surface wraps
|
|
55
|
+
// this in `new Observable(...)` (see `_observe` in dataMethods).
|
|
56
|
+
// Redirects are surfaced rather than followed unless a request opts in
|
|
57
|
+
// (via the public `maxRedirects` option, translated in `requestOptions`).
|
|
58
|
+
const httpRequest: HttpRequest = async (options) => {
|
|
59
|
+
const event = await clientRequesterPromise({redirect: 'manual', ...options})
|
|
60
|
+
return event.body
|
|
61
|
+
}
|
|
62
|
+
// Populate `requester` on the initialized config so internal paths
|
|
63
|
+
// (e.g. the asset upload event stream) can reach the underlying transport.
|
|
64
|
+
// `resolveFetch` is threaded onto the config so request building and
|
|
65
|
+
// EventSource fetches can reach the environment's fetch without importing
|
|
66
|
+
// `get-it/node` from a browser-shared module (would leak `undici` into
|
|
67
|
+
// the browser bundle). A caller-supplied `resolveFetch` wins over the
|
|
68
|
+
// environment's — that is the supported way to swap the transport (the
|
|
69
|
+
// test suite injects its mock fetch through it).
|
|
70
|
+
const resolvedConfig = {
|
|
71
|
+
...config,
|
|
72
|
+
requester: clientRequester,
|
|
73
|
+
resolveFetch: config.resolveFetch ?? envOptions.resolveFetch,
|
|
74
|
+
}
|
|
75
|
+
return new ClassConstructor(httpRequest, resolvedConfig)
|
|
64
76
|
}
|
|
65
77
|
|
|
66
78
|
return {requester: defaultRequester, createClient}
|