@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
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import {createDebug} from 'obug'
|
|
2
|
+
import {Observable} from 'rxjs'
|
|
3
|
+
|
|
4
|
+
import type {UploadEvent} from '../types'
|
|
5
|
+
import {ClientError, httpResponseFromFetch, ServerError} from './errors'
|
|
6
|
+
import {parseJsonText} from './request'
|
|
7
|
+
|
|
8
|
+
const log = createDebug('sanity:client')
|
|
9
|
+
|
|
10
|
+
let nextRequestId = 1
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Options for a browser-side asset upload that needs progress events.
|
|
14
|
+
*
|
|
15
|
+
* @internal
|
|
16
|
+
*/
|
|
17
|
+
export interface BrowserUploadOptions {
|
|
18
|
+
url: string
|
|
19
|
+
method: string
|
|
20
|
+
headers: Record<string, string>
|
|
21
|
+
body: unknown
|
|
22
|
+
withCredentials: boolean
|
|
23
|
+
/** Milliseconds before the upload is aborted; `false` and `0` both disable the timeout. */
|
|
24
|
+
timeout?: number | false
|
|
25
|
+
signal?: AbortSignal
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Run an asset upload through `XMLHttpRequest` so we can surface per-chunk
|
|
30
|
+
* upload progress events. get-it v9 / fetch has no equivalent hook in the
|
|
31
|
+
* browser, so the observable asset-upload API falls back to this path when
|
|
32
|
+
* `XMLHttpRequest` is available.
|
|
33
|
+
*
|
|
34
|
+
* @internal
|
|
35
|
+
*/
|
|
36
|
+
export function uploadWithProgress<T>(options: BrowserUploadOptions): Observable<UploadEvent<T>> {
|
|
37
|
+
return new Observable<UploadEvent<T>>((subscriber) => {
|
|
38
|
+
const xhr = new XMLHttpRequest()
|
|
39
|
+
const requestId = nextRequestId++
|
|
40
|
+
const {url, method, headers, body, withCredentials, timeout, signal} = options
|
|
41
|
+
|
|
42
|
+
log('[%d] %s %s (XHR upload with progress)', requestId, method, url)
|
|
43
|
+
|
|
44
|
+
xhr.open(method, url)
|
|
45
|
+
xhr.withCredentials = withCredentials
|
|
46
|
+
if (typeof timeout === 'number' && timeout > 0) {
|
|
47
|
+
xhr.timeout = timeout
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
51
|
+
xhr.setRequestHeader(key, value)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
xhr.upload.onprogress = (e) => {
|
|
55
|
+
subscriber.next({
|
|
56
|
+
type: 'progress',
|
|
57
|
+
stage: 'upload',
|
|
58
|
+
percent: e.lengthComputable ? Math.round((e.loaded / e.total) * 100) : 0,
|
|
59
|
+
total: e.total || undefined,
|
|
60
|
+
loaded: e.loaded,
|
|
61
|
+
lengthComputable: e.lengthComputable,
|
|
62
|
+
})
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
xhr.onload = () => {
|
|
66
|
+
log('[%d] %s %s — %d', requestId, method, url, xhr.status)
|
|
67
|
+
|
|
68
|
+
if (xhr.status >= 400) {
|
|
69
|
+
// Same typed errors as the fetch transport, so consumers can keep
|
|
70
|
+
// detecting `ClientError`/`ServerError` and reading `statusCode`,
|
|
71
|
+
// `responseBody` and the structured API `details` on failed uploads.
|
|
72
|
+
const errorHeaders = parseXhrResponseHeaders(xhr.getAllResponseHeaders())
|
|
73
|
+
const canonical = httpResponseFromFetch(
|
|
74
|
+
{
|
|
75
|
+
status: xhr.status,
|
|
76
|
+
statusText: xhr.statusText,
|
|
77
|
+
headers: errorHeaders,
|
|
78
|
+
body: parseJsonText(xhr.responseText, errorHeaders),
|
|
79
|
+
},
|
|
80
|
+
url,
|
|
81
|
+
method,
|
|
82
|
+
)
|
|
83
|
+
subscriber.error(
|
|
84
|
+
xhr.status >= 500 ? new ServerError(canonical) : new ClientError(canonical),
|
|
85
|
+
)
|
|
86
|
+
return
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
let responseBody: T
|
|
90
|
+
try {
|
|
91
|
+
responseBody = JSON.parse(xhr.responseText) as T
|
|
92
|
+
} catch {
|
|
93
|
+
subscriber.error(new Error('Failed to parse upload response as JSON'))
|
|
94
|
+
return
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
subscriber.next({type: 'response', body: responseBody})
|
|
98
|
+
subscriber.complete()
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
xhr.onerror = () => {
|
|
102
|
+
log('[%d] %s %s — network error', requestId, method, url)
|
|
103
|
+
subscriber.error(new Error('XHR upload network error'))
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
xhr.ontimeout = () => {
|
|
107
|
+
log('[%d] %s %s — timed out after %dms', requestId, method, url, timeout)
|
|
108
|
+
// Same error shape as the fetch transport's timeout rejection.
|
|
109
|
+
subscriber.error(
|
|
110
|
+
new DOMException(
|
|
111
|
+
`The operation timed out after ${timeout}ms while attempting to reach ${url}`,
|
|
112
|
+
'TimeoutError',
|
|
113
|
+
),
|
|
114
|
+
)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
xhr.onabort = () => {
|
|
118
|
+
subscriber.error(new DOMException('Upload aborted', 'AbortError'))
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const onSignalAbort = () => xhr.abort()
|
|
122
|
+
if (signal) {
|
|
123
|
+
if (signal.aborted) {
|
|
124
|
+
// `xhr.abort()` before `send()` fires no `abort` event per spec, so
|
|
125
|
+
// error out directly instead of relying on `onabort`.
|
|
126
|
+
subscriber.error(new DOMException('Upload aborted', 'AbortError'))
|
|
127
|
+
return undefined
|
|
128
|
+
}
|
|
129
|
+
signal.addEventListener('abort', onSignalAbort, {once: true})
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
xhr.send(body as XMLHttpRequestBodyInit)
|
|
133
|
+
|
|
134
|
+
// Unsubscribing cancels the in-flight upload, mirroring how the fetch
|
|
135
|
+
// path aborts its request (`_observe`). After settle this is a no-op —
|
|
136
|
+
// except for detaching from the caller's signal, which may be long-lived
|
|
137
|
+
// and must not accumulate a listener per upload.
|
|
138
|
+
return () => {
|
|
139
|
+
signal?.removeEventListener('abort', onSignalAbort)
|
|
140
|
+
xhr.abort()
|
|
141
|
+
}
|
|
142
|
+
})
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Parse `XMLHttpRequest.getAllResponseHeaders()` output (CRLF-separated
|
|
147
|
+
* `name: value` lines) into a `Headers` instance.
|
|
148
|
+
*/
|
|
149
|
+
function parseXhrResponseHeaders(raw: string): Headers {
|
|
150
|
+
const headers = new Headers()
|
|
151
|
+
for (const line of raw.split('\r\n')) {
|
|
152
|
+
const separator = line.indexOf(':')
|
|
153
|
+
if (separator <= 0) continue
|
|
154
|
+
try {
|
|
155
|
+
headers.append(line.slice(0, separator).trim(), line.slice(separator + 1).trim())
|
|
156
|
+
} catch {
|
|
157
|
+
// Skip header lines the Headers constructor rejects — better a partial
|
|
158
|
+
// header record on the error than no error details at all.
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return headers
|
|
162
|
+
}
|
package/src/http/errors.ts
CHANGED
|
@@ -1,11 +1,66 @@
|
|
|
1
|
-
import type {HttpContext} from 'get-it'
|
|
2
|
-
|
|
3
1
|
import type {ActionError, Any, ErrorProps, MutationError, QueryParseError} from '../types'
|
|
4
2
|
import {codeFrame} from '../util/codeFrame'
|
|
5
3
|
import {isRecord} from '../util/isRecord'
|
|
6
4
|
|
|
7
5
|
const MAX_ITEMS_IN_ERROR_MESSAGE = 5
|
|
8
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Canonical HTTP response shape used internally to build {@link ClientError}
|
|
9
|
+
* and {@link ServerError}. Decouples the error layer from any particular
|
|
10
|
+
* transport library — adapters in the HTTP layer (e.g. `httpResponseFromGetIt`)
|
|
11
|
+
* project transport-specific response shapes into this stable form before
|
|
12
|
+
* constructing errors.
|
|
13
|
+
*
|
|
14
|
+
* Matches the public {@link HttpError.response} shape so consumers see no
|
|
15
|
+
* difference in error properties when the underlying transport changes.
|
|
16
|
+
*
|
|
17
|
+
* @internal
|
|
18
|
+
*/
|
|
19
|
+
export interface CanonicalHttpResponse {
|
|
20
|
+
statusCode: number
|
|
21
|
+
statusMessage: string | null
|
|
22
|
+
headers: Record<string, string>
|
|
23
|
+
body: unknown
|
|
24
|
+
url: string
|
|
25
|
+
method: string
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Adapter for buffered responses from get-it v9 (`BufferedResponse`-shaped).
|
|
30
|
+
*
|
|
31
|
+
* The URL and method aren't on the response itself in v9, so the request
|
|
32
|
+
* options must be passed alongside.
|
|
33
|
+
*
|
|
34
|
+
* @internal
|
|
35
|
+
*/
|
|
36
|
+
export function httpResponseFromFetch(
|
|
37
|
+
res: {
|
|
38
|
+
status: number
|
|
39
|
+
statusText: string
|
|
40
|
+
headers: Headers
|
|
41
|
+
body: unknown
|
|
42
|
+
},
|
|
43
|
+
reqUrl: string,
|
|
44
|
+
reqMethod: string,
|
|
45
|
+
): CanonicalHttpResponse {
|
|
46
|
+
return {
|
|
47
|
+
statusCode: res.status,
|
|
48
|
+
statusMessage: res.statusText || null,
|
|
49
|
+
headers: headersToRecord(res.headers),
|
|
50
|
+
body: res.body,
|
|
51
|
+
url: reqUrl,
|
|
52
|
+
method: reqMethod,
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function headersToRecord(headers: Headers): Record<string, string> {
|
|
57
|
+
const out: Record<string, string> = {}
|
|
58
|
+
headers.forEach((value, key) => {
|
|
59
|
+
out[key] = value
|
|
60
|
+
})
|
|
61
|
+
return out
|
|
62
|
+
}
|
|
63
|
+
|
|
9
64
|
/**
|
|
10
65
|
* Shared properties for HTTP errors (eg both ClientError and ServerError)
|
|
11
66
|
* Use `isHttpError` for type narrowing and accessing response properties.
|
|
@@ -67,8 +122,8 @@ export class ClientError extends Error {
|
|
|
67
122
|
traceId: ErrorProps['traceId']
|
|
68
123
|
details: ErrorProps['details']
|
|
69
124
|
|
|
70
|
-
constructor(res: Any,
|
|
71
|
-
const props = extractErrorProps(res,
|
|
125
|
+
constructor(res: Any, tag?: string) {
|
|
126
|
+
const props = extractErrorProps(res, tag)
|
|
72
127
|
super(props.message)
|
|
73
128
|
Object.assign(this, props)
|
|
74
129
|
}
|
|
@@ -89,7 +144,7 @@ export class ServerError extends Error {
|
|
|
89
144
|
}
|
|
90
145
|
}
|
|
91
146
|
|
|
92
|
-
function extractErrorProps(res: Any,
|
|
147
|
+
function extractErrorProps(res: Any, tag?: string): ErrorProps {
|
|
93
148
|
const body = res.body
|
|
94
149
|
const props = {
|
|
95
150
|
response: res,
|
|
@@ -144,7 +199,6 @@ function extractErrorProps(res: Any, context?: HttpContext): ErrorProps {
|
|
|
144
199
|
|
|
145
200
|
// Query parse errors
|
|
146
201
|
if (isQueryParseError(error)) {
|
|
147
|
-
const tag = context?.options?.query?.tag
|
|
148
202
|
props.message = formatQueryParseError(error, tag, props.traceId)
|
|
149
203
|
props.details = body.error
|
|
150
204
|
return props
|
|
@@ -1,41 +1,105 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import {Readable} from 'node:stream'
|
|
2
|
+
|
|
3
|
+
import type {FetchFunction} from 'get-it'
|
|
4
|
+
import {debug} from 'get-it/middleware'
|
|
5
|
+
import {createNodeFetch} from 'get-it/node'
|
|
6
|
+
import {createDebug} from 'obug'
|
|
3
7
|
|
|
4
8
|
import {name, version} from '../../package.json'
|
|
9
|
+
import type {EnvironmentOptions, LegacyMiddleware} from './request'
|
|
10
|
+
|
|
11
|
+
const log = createDebug('sanity:client')
|
|
12
|
+
|
|
13
|
+
function isNodeReadableStream(value: unknown): value is Readable {
|
|
14
|
+
if (typeof value !== 'object' || value === null) return false
|
|
15
|
+
if (!('pipe' in value)) return false
|
|
16
|
+
return typeof value.pipe === 'function'
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// One undici-backed fetch per (proxy URL) so callers don't pay the cost of
|
|
20
|
+
// rebuilding a dispatcher on every request when they use the same proxy.
|
|
21
|
+
const proxyFetchCache = new Map<string, ReturnType<typeof createNodeFetch>>()
|
|
22
|
+
|
|
23
|
+
function getProxyFetch(proxyUrl: string): ReturnType<typeof createNodeFetch> {
|
|
24
|
+
const cached = proxyFetchCache.get(proxyUrl)
|
|
25
|
+
if (cached) return cached
|
|
26
|
+
const fetch = createNodeFetch({proxy: proxyUrl, connections: 30})
|
|
27
|
+
proxyFetchCache.set(proxyUrl, fetch)
|
|
28
|
+
return fetch
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// The environment's default fetch, shared by all SSE connections that have no
|
|
32
|
+
// explicit proxy configured. Built lazily so clients that never use
|
|
33
|
+
// `listen()`/`live.events()` don't pay for the dispatcher.
|
|
34
|
+
let envDefaultFetch: ReturnType<typeof createNodeFetch> | undefined
|
|
5
35
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
36
|
+
/**
|
|
37
|
+
* Exposed via `EnvironmentOptions.resolveFetch` so EventSource connections
|
|
38
|
+
* use the same transport as regular requests instead of falling back to
|
|
39
|
+
* `globalThis.fetch`. Everything get-it's Node fetch provides then applies
|
|
40
|
+
* to SSE too: the undici dispatcher configuration, an explicit `proxy`
|
|
41
|
+
* config (pass the URL), and env-proxy support
|
|
42
|
+
* (`HTTP_PROXY`/`HTTPS_PROXY`/`NO_PROXY`, which Node's own global fetch does
|
|
43
|
+
* not read — that is opt-in via `NODE_USE_ENV_PROXY`, and not on our 22.12
|
|
44
|
+
* floor). Reached via the env rather than a direct import so `get-it/node`
|
|
45
|
+
* (and with it `undici`) stays out of the browser bundle.
|
|
46
|
+
*
|
|
47
|
+
* @internal
|
|
48
|
+
*/
|
|
49
|
+
function resolveFetch(proxyUrl?: string): FetchFunction {
|
|
50
|
+
if (typeof proxyUrl === 'string') {
|
|
51
|
+
return getProxyFetch(proxyUrl)
|
|
52
|
+
}
|
|
53
|
+
envDefaultFetch ??= createNodeFetch()
|
|
54
|
+
return envDefaultFetch
|
|
55
|
+
}
|
|
9
56
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
57
|
+
const middleware: LegacyMiddleware[] = [
|
|
58
|
+
debug({log: (message, ...args) => log(message, ...args), verbose: true}),
|
|
59
|
+
|
|
60
|
+
// Lineage is used for recursion control/tracing and can be passed either
|
|
61
|
+
// through the client config (arrives as `meta.lineage`, set by
|
|
62
|
+
// `requestOptions`) or through an environment variable. Not used in
|
|
63
|
+
// browser environments.
|
|
13
64
|
{
|
|
14
|
-
|
|
65
|
+
beforeRequest(opts) {
|
|
66
|
+
const configLineage = typeof opts.meta?.lineage === 'string' ? opts.meta.lineage : undefined
|
|
15
67
|
const lineage =
|
|
16
|
-
(typeof process !== 'undefined' && process.env.X_SANITY_LINEAGE) ||
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
return opts
|
|
68
|
+
(typeof process !== 'undefined' && process.env.X_SANITY_LINEAGE) || configLineage
|
|
69
|
+
if (!lineage) return opts
|
|
70
|
+
const headers = new Headers(opts.headers)
|
|
71
|
+
headers.set('x-sanity-lineage', lineage)
|
|
72
|
+
return {...opts, headers}
|
|
23
73
|
},
|
|
24
74
|
},
|
|
25
75
|
|
|
26
|
-
//
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
//
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
maxSockets: 30,
|
|
37
|
-
maxTotalSockets: 256,
|
|
38
|
-
}),
|
|
76
|
+
// Asset uploads can pass a Node.js Readable stream (from
|
|
77
|
+
// `fs.createReadStream(...)`) as the body. The HTTP transport's body type
|
|
78
|
+
// guard only accepts Web streams, so we project Node streams here —
|
|
79
|
+
// undici's fetch accepts Web streams natively.
|
|
80
|
+
{
|
|
81
|
+
beforeRequest(opts) {
|
|
82
|
+
if (!isNodeReadableStream(opts.body)) return opts
|
|
83
|
+
return {...opts, body: Readable.toWeb(opts.body)}
|
|
84
|
+
},
|
|
85
|
+
},
|
|
39
86
|
]
|
|
40
87
|
|
|
41
|
-
|
|
88
|
+
/**
|
|
89
|
+
* Node-specific environment options used to wire up `createRequester`.
|
|
90
|
+
*
|
|
91
|
+
* - `User-Agent` defaults to `@sanity/client <version>`.
|
|
92
|
+
* - Falls back to get-it/node's default undici-backed fetch (which honours
|
|
93
|
+
* `HTTP_PROXY` / `HTTPS_PROXY` / `NO_PROXY` env vars via undici's
|
|
94
|
+
* `EnvHttpProxyAgent`). Per-request proxy overrides are wired in via the
|
|
95
|
+
* wrapping middleware above.
|
|
96
|
+
*
|
|
97
|
+
* @internal
|
|
98
|
+
*/
|
|
99
|
+
const environment: EnvironmentOptions = {
|
|
100
|
+
headers: {'User-Agent': `${name} ${version}`},
|
|
101
|
+
middleware,
|
|
102
|
+
resolveFetch,
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export default environment
|