@sanity/vision 5.0.0-next.0-9b570ece82-202507150640 → 5.0.0-next.7

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.
@@ -1,1866 +0,0 @@
1
- "use strict";
2
- var jsxRuntime = require("react/jsx-runtime"), reactCompilerRuntime = require("react-compiler-runtime"), sanity = require("sanity"), ui = require("@sanity/ui"), react = require("react"), reactSplitPane = require("@rexxars/react-split-pane"), icons = require("@sanity/icons"), isHotkeyEsm = require("is-hotkey-esm"), useEffectEvent = require("use-effect-event"), CodeMirror = require("@uiw/react-codemirror"), autocomplete = require("@codemirror/autocomplete"), commands = require("@codemirror/commands"), langJavascript = require("@codemirror/lang-javascript"), language = require("@codemirror/language"), search = require("@codemirror/search"), view = require("@codemirror/view"), highlight = require("@lezer/highlight"), color = require("@sanity/color"), styledComponents = require("styled-components"), index = require("./index.js"), debounce = require("lodash/debounce.js"), JSON5 = require("json5"), isEqual = require("lodash/isEqual.js"), uuid = require("@sanity/uuid"), operators = require("rxjs/operators"), json2Csv = require("json-2-csv"), reactJsonInspector = require("@rexxars/react-json-inspector"), LRU = require("quick-lru"), router = require("sanity/router"), reactRx = require("react-rx"), rxjs = require("rxjs");
3
- function _interopDefaultCompat(e) {
4
- return e && typeof e == "object" && "default" in e ? e : { default: e };
5
- }
6
- var CodeMirror__default = /* @__PURE__ */ _interopDefaultCompat(CodeMirror), debounce__default = /* @__PURE__ */ _interopDefaultCompat(debounce), JSON5__default = /* @__PURE__ */ _interopDefaultCompat(JSON5), isEqual__default = /* @__PURE__ */ _interopDefaultCompat(isEqual), LRU__default = /* @__PURE__ */ _interopDefaultCompat(LRU);
7
- const API_VERSIONS = ["v1", "vX", "v2021-03-25", "v2021-10-21", "v2022-03-07", "v2025-02-19", `v${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}`], [DEFAULT_API_VERSION] = API_VERSIONS.slice(-1);
8
- function DelayedSpinner(props) {
9
- const $ = reactCompilerRuntime.c(5), [show, setShow] = react.useState(!1);
10
- let t0, t1;
11
- $[0] !== props.delay ? (t0 = () => {
12
- const timer = setTimeout(() => setShow(!0), props.delay || 500);
13
- return () => clearTimeout(timer);
14
- }, t1 = [props.delay], $[0] = props.delay, $[1] = t0, $[2] = t1) : (t0 = $[1], t1 = $[2]), react.useEffect(t0, t1);
15
- let t2;
16
- return $[3] !== show ? (t2 = show ? /* @__PURE__ */ jsxRuntime.jsx(ui.Spinner, { muted: !0, size: 4 }) : null, $[3] = show, $[4] = t2) : t2 = $[4], t2;
17
- }
18
- const codemirrorExtensions = [[langJavascript.javascriptLanguage], view.lineNumbers(), view.highlightActiveLine(), view.highlightActiveLineGutter(), search.highlightSelectionMatches(), view.highlightSpecialChars(), language.indentOnInput(), language.bracketMatching(), autocomplete.closeBrackets(), commands.history(), view.drawSelection(), language.syntaxHighlighting(language.defaultHighlightStyle, {
19
- fallback: !0
20
- }), view.keymap.of([
21
- // Override the default keymap for Mod-Enter to not insert a new line, we have a custom event handler for executing queries
22
- {
23
- key: "Mod-Enter",
24
- run: () => !0
25
- },
26
- // Add the default keymap and history keymap
27
- commands.defaultKeymap,
28
- commands.historyKeymap
29
- ].flat().filter(Boolean))];
30
- function useCodemirrorTheme(theme) {
31
- const $ = reactCompilerRuntime.c(7);
32
- let t0, t1;
33
- $[0] !== theme ? (t1 = createTheme(theme), $[0] = theme, $[1] = t1) : t1 = $[1], t0 = t1;
34
- const cmTheme = t0;
35
- let t2, t3;
36
- $[2] !== theme ? (t3 = language.syntaxHighlighting(createHighlight(theme)), $[2] = theme, $[3] = t3) : t3 = $[3], t2 = t3;
37
- const cmHighlight = t2;
38
- let t4;
39
- return $[4] !== cmHighlight || $[5] !== cmTheme ? (t4 = [cmTheme, cmHighlight], $[4] = cmHighlight, $[5] = cmTheme, $[6] = t4) : t4 = $[6], t4;
40
- }
41
- function createTheme(theme) {
42
- const {
43
- color: color$1,
44
- fonts
45
- } = theme.sanity, card = color$1.card.enabled, cursor = color.hues.blue[color$1.dark ? 400 : 500].hex, selection = color.hues.gray[theme.sanity.color.dark ? 900 : 100].hex;
46
- return view.EditorView.theme({
47
- "&": {
48
- color: card.fg,
49
- backgroundColor: card.bg
50
- },
51
- ".cm-content": {
52
- caretColor: cursor
53
- },
54
- ".cm-editor": {
55
- fontFamily: fonts.code.family,
56
- fontSize: ui.rem(fonts.code.sizes[1].fontSize),
57
- lineHeight: "inherit"
58
- },
59
- ".cm-cursor, .cm-dropCursor": {
60
- borderLeftColor: cursor
61
- },
62
- "&.cm-focused .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection": {
63
- backgroundColor: selection
64
- },
65
- ".cm-panels": {
66
- backgroundColor: card.bg,
67
- color: card.fg
68
- },
69
- ".cm-panels.cm-panels-top": {
70
- borderBottom: `2px solid ${card.border}`
71
- },
72
- ".cm-panels.cm-panels-bottom": {
73
- borderTop: `2px solid ${card.border}`
74
- }
75
- }, {
76
- dark: color$1.dark
77
- });
78
- }
79
- function createHighlight(theme) {
80
- const c = theme.sanity.color.base, s = theme.sanity.color.syntax;
81
- return language.HighlightStyle.define([{
82
- tag: highlight.tags.keyword,
83
- color: s.keyword
84
- }, {
85
- tag: [highlight.tags.propertyName, highlight.tags.name, highlight.tags.deleted, highlight.tags.character, highlight.tags.macroName],
86
- color: s.property
87
- }, {
88
- tag: [highlight.tags.function(highlight.tags.variableName), highlight.tags.labelName],
89
- color: s.function
90
- }, {
91
- tag: [highlight.tags.color, highlight.tags.constant(highlight.tags.name), highlight.tags.standard(highlight.tags.name)],
92
- color: s.variable
93
- }, {
94
- tag: [highlight.tags.definition(highlight.tags.name), highlight.tags.separator],
95
- color: s.constant
96
- }, {
97
- tag: [highlight.tags.typeName, highlight.tags.className, highlight.tags.number, highlight.tags.changed, highlight.tags.annotation, highlight.tags.modifier, highlight.tags.self, highlight.tags.namespace],
98
- color: s.number
99
- }, {
100
- tag: [highlight.tags.operator, highlight.tags.operatorKeyword, highlight.tags.url, highlight.tags.escape, highlight.tags.regexp, highlight.tags.link, highlight.tags.special(highlight.tags.string)],
101
- color: s.operator
102
- }, {
103
- tag: [highlight.tags.meta, highlight.tags.comment],
104
- color: s.comment
105
- }, {
106
- tag: highlight.tags.strong,
107
- fontWeight: "bold"
108
- }, {
109
- tag: highlight.tags.emphasis,
110
- fontStyle: "italic"
111
- }, {
112
- tag: highlight.tags.strikethrough,
113
- textDecoration: "line-through"
114
- }, {
115
- tag: highlight.tags.heading,
116
- fontWeight: "bold",
117
- color: s.property
118
- }, {
119
- tag: [highlight.tags.atom, highlight.tags.bool, highlight.tags.special(highlight.tags.variableName)],
120
- color: s.boolean
121
- }, {
122
- tag: [highlight.tags.processingInstruction, highlight.tags.string, highlight.tags.inserted],
123
- color: s.string
124
- }, {
125
- tag: highlight.tags.invalid,
126
- color: c.fg
127
- }]);
128
- }
129
- const EditorRoot = styledComponents.styled.div`
130
- width: 100%;
131
- box-sizing: border-box;
132
- height: 100%;
133
- overflow: hidden;
134
- overflow: clip;
135
- position: relative;
136
- display: flex;
137
-
138
- & .cm-theme {
139
- width: 100%;
140
- }
141
-
142
- & .cm-editor {
143
- height: 100%;
144
-
145
- font-size: 16px;
146
- line-height: 21px;
147
- }
148
-
149
- & .cm-line {
150
- padding-left: ${({
151
- theme
152
- }) => ui.rem(theme.sanity.space[3])};
153
- }
154
-
155
- & .cm-content {
156
- border-right-width: ${({
157
- theme
158
- }) => ui.rem(theme.sanity.space[4])} !important;
159
- padding-top: ${({
160
- theme
161
- }) => ui.rem(theme.sanity.space[5])};
162
- }
163
- `, VisionCodeMirror = react.forwardRef((props, ref) => {
164
- const $ = reactCompilerRuntime.c(7), [initialValue] = react.useState(props.initialValue), sanityTheme = ui.useTheme(), theme = useCodemirrorTheme(sanityTheme), codeMirrorRef = react.useRef(null);
165
- let t0;
166
- $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = (newContent) => {
167
- const editorView = codeMirrorRef.current?.view;
168
- if (!editorView)
169
- return;
170
- const currentDoc = editorView.state.doc.toString();
171
- newContent !== currentDoc && editorView.dispatch({
172
- changes: {
173
- from: 0,
174
- to: currentDoc.length,
175
- insert: newContent
176
- },
177
- selection: CodeMirror.EditorSelection.cursor(newContent.length)
178
- });
179
- }, $[0] = t0) : t0 = $[0];
180
- const resetEditorContent = t0;
181
- let t1, t2;
182
- $[1] === Symbol.for("react.memo_cache_sentinel") ? (t1 = () => ({
183
- resetEditorContent
184
- }), t2 = [resetEditorContent], $[1] = t1, $[2] = t2) : (t1 = $[1], t2 = $[2]), react.useImperativeHandle(ref, t1, t2);
185
- let t3;
186
- return $[3] !== initialValue || $[4] !== props.onChange || $[5] !== theme ? (t3 = /* @__PURE__ */ jsxRuntime.jsx(EditorRoot, { children: /* @__PURE__ */ jsxRuntime.jsx(CodeMirror__default.default, { ref: codeMirrorRef, basicSetup: !1, theme, extensions: codemirrorExtensions, value: initialValue, onChange: props.onChange }) }), $[3] = initialValue, $[4] = props.onChange, $[5] = theme, $[6] = t3) : t3 = $[6], t3;
187
- });
188
- VisionCodeMirror.displayName = "VisionCodeMirror";
189
- const SUPPORTED_PERSPECTIVES = ["pinnedRelease", "raw", "published", "drafts"], VIRTUAL_PERSPECTIVES = ["pinnedRelease"];
190
- function isSupportedPerspective(p) {
191
- return SUPPORTED_PERSPECTIVES.includes(p);
192
- }
193
- function isVirtualPerspective(maybeVirtualPerspective) {
194
- return typeof maybeVirtualPerspective == "string" && VIRTUAL_PERSPECTIVES.includes(maybeVirtualPerspective);
195
- }
196
- function hasPinnedPerspective({
197
- selectedPerspectiveName
198
- }) {
199
- return typeof selectedPerspectiveName < "u";
200
- }
201
- function getActivePerspective({
202
- visionPerspective,
203
- perspectiveStack
204
- }) {
205
- return visionPerspective !== "pinnedRelease" ? visionPerspective : perspectiveStack;
206
- }
207
- function encodeQueryString(query, params = {}, options = {}) {
208
- const searchParams = new URLSearchParams();
209
- searchParams.set("query", query);
210
- for (const [key, value] of Object.entries(params))
211
- searchParams.set(`$${key}`, JSON.stringify(value));
212
- for (const [key, value] of Object.entries(options))
213
- value && searchParams.set(key, `${value}`);
214
- return `?${searchParams}`;
215
- }
216
- function isPlainObject(obj) {
217
- return !!obj && typeof obj == "object" && Object.prototype.toString.call(obj) === "[object Object]";
218
- }
219
- const hasLocalStorage = supportsLocalStorage(), keyPrefix = "sanityVision:";
220
- function clearLocalStorage() {
221
- if (hasLocalStorage)
222
- for (let i = 0; i < localStorage.length; i++) {
223
- const key = localStorage.key(i);
224
- key?.startsWith(keyPrefix) && localStorage.removeItem(key);
225
- }
226
- }
227
- function getLocalStorage(namespace) {
228
- const storageKey = `${keyPrefix}${namespace}`;
229
- let loadedState = null;
230
- return {
231
- get,
232
- set,
233
- merge
234
- };
235
- function get(key, defaultVal) {
236
- const state = ensureState();
237
- return typeof state[key] > "u" ? defaultVal : state[key];
238
- }
239
- function set(key, value) {
240
- const state = ensureState();
241
- return state[key] = value, localStorage.setItem(storageKey, JSON.stringify(loadedState)), value;
242
- }
243
- function merge(props) {
244
- const state = {
245
- ...ensureState(),
246
- ...props
247
- };
248
- return localStorage.setItem(storageKey, JSON.stringify(state)), state;
249
- }
250
- function ensureState() {
251
- return loadedState === null && (loadedState = loadState()), loadedState;
252
- }
253
- function loadState() {
254
- if (!hasLocalStorage)
255
- return {};
256
- try {
257
- const stored = JSON.parse(localStorage.getItem(storageKey) || "{}");
258
- return isPlainObject(stored) ? stored : {};
259
- } catch {
260
- return {};
261
- }
262
- }
263
- }
264
- function supportsLocalStorage() {
265
- const mod = "lsCheck";
266
- try {
267
- return localStorage.setItem(mod, mod), localStorage.removeItem(mod), !0;
268
- } catch {
269
- return !1;
270
- }
271
- }
272
- function parseApiQueryString(qs) {
273
- const params = {}, options = {};
274
- for (const [key, value] of qs.entries()) {
275
- if (key[0] === "$") {
276
- params[key.slice(1)] = JSON.parse(value);
277
- continue;
278
- }
279
- if (key === "perspective") {
280
- options[key] = value;
281
- continue;
282
- }
283
- }
284
- return {
285
- query: qs.get("query") || "",
286
- params,
287
- options
288
- };
289
- }
290
- function prefixApiVersion(version) {
291
- return version[0] !== "v" && version !== "other" ? `v${version}` : version;
292
- }
293
- function validateApiVersion(apiVersion) {
294
- const parseableApiVersion = apiVersion.replace(/^v/, "").trim().toUpperCase();
295
- return parseableApiVersion.length > 0 && (parseableApiVersion === "X" || parseableApiVersion === "1" || /^\d{4}-\d{2}-\d{2}$/.test(parseableApiVersion) && !isNaN(Date.parse(parseableApiVersion)));
296
- }
297
- function tryParseParams(val, t) {
298
- try {
299
- const parsed = val ? JSON5__default.default.parse(val) : {};
300
- return typeof parsed == "object" && parsed && !Array.isArray(parsed) ? parsed : {};
301
- } catch (err) {
302
- return err.message = `${t("params.error.params-invalid-json")}:
303
-
304
- ${err.message.replace("JSON5:", "")}`, err;
305
- }
306
- }
307
- const Root = styledComponents.styled(ui.Flex)`
308
- .sidebarPanes .Pane {
309
- overflow-y: auto;
310
- overflow-x: hidden;
311
- }
312
-
313
- & .Resizer {
314
- background: var(--card-border-color);
315
- opacity: 1;
316
- z-index: 1;
317
- box-sizing: border-box;
318
- background-clip: padding-box;
319
- border: solid transparent;
320
- }
321
-
322
- & .Resizer:hover {
323
- border-color: var(--card-shadow-ambient-color);
324
- }
325
-
326
- & .Resizer.horizontal {
327
- height: 11px;
328
- margin: -5px 0;
329
- border-width: 5px 0;
330
- cursor: row-resize;
331
- width: 100%;
332
- z-index: 4;
333
- }
334
-
335
- & .Resizer.vertical {
336
- width: 11px;
337
- margin: 0 -5px;
338
- border-width: 0 5px;
339
- cursor: col-resize;
340
- z-index: 2; /* To prevent the resizer from being hidden behind CodeMirror scroll area */
341
- }
342
-
343
- .Resizer.disabled {
344
- cursor: not-allowed;
345
- }
346
-
347
- .Resizer.disabled:hover {
348
- border-color: transparent;
349
- }
350
- `;
351
- Root.displayName = "Root";
352
- const Header = styledComponents.styled(ui.Card)`
353
- border-bottom: 1px solid var(--card-border-color);
354
- `, StyledLabel = styledComponents.styled(ui.Label)`
355
- flex: 1;
356
- `, SplitpaneContainer = styledComponents.styled(ui.Box)`
357
- position: relative;
358
- `, QueryCopyLink = styledComponents.styled.a`
359
- cursor: pointer;
360
- margin-right: auto;
361
- `, InputBackgroundContainer = styledComponents.styled(ui.Box)`
362
- position: absolute;
363
- top: 1rem;
364
- left: 0;
365
- padding: 0;
366
- margin: 0;
367
- z-index: 10;
368
- right: 0;
369
-
370
- ${StyledLabel} {
371
- user-select: none;
372
- }
373
- `, InputBackgroundContainerLeft = styledComponents.styled(InputBackgroundContainer)`
374
- // This is so its aligned with the gutters of CodeMirror
375
- left: 33px;
376
- `, InputContainer = styledComponents.styled(ui.Card)`
377
- width: 100%;
378
- height: 100%;
379
- position: relative;
380
- flex-direction: column;
381
- `, ResultOuterContainer = styledComponents.styled(ui.Flex)`
382
- height: 100%;
383
- `, ResultInnerContainer = styledComponents.styled(ui.Box)`
384
- position: relative;
385
- `, ResultContainer = styledComponents.styled(ui.Card)`
386
- height: 100%;
387
- width: 100%;
388
- position: absolute;
389
- max-width: 100%;
390
-
391
- ${({
392
- $isInvalid
393
- }) => $isInvalid && styledComponents.css`
394
- &:after {
395
- background-color: var(--card-bg-color);
396
- content: '';
397
- position: absolute;
398
- top: 0;
399
- bottom: 0;
400
- left: 0;
401
- width: 100%;
402
- }
403
- `}
404
- `, Result = styledComponents.styled(ui.Box)`
405
- position: relative;
406
- width: 100%;
407
- height: 100%;
408
- z-index: 20;
409
- `, ResultFooter = styledComponents.styled(ui.Flex)`
410
- border-top: 1px solid var(--card-border-color);
411
- `, TimingsCard = styledComponents.styled(ui.Card)`
412
- position: relative;
413
- `;
414
- styledComponents.styled(ui.Box)`
415
- width: 100%;
416
- height: 100%;
417
- `;
418
- const TimingsTextContainer = styledComponents.styled(ui.Flex)`
419
- height: 100%;
420
- min-height: ${({
421
- theme
422
- }) => ui.rem(theme.sanity.space[3] * 2 + theme.sanity.fonts.text.sizes[2].lineHeight - theme.sanity.fonts.text.sizes[2].ascenderHeight - theme.sanity.fonts.text.sizes[2].descenderHeight)};
423
- `, DownloadsCard = styledComponents.styled(ui.Card)`
424
- position: relative;
425
- `, SaveResultLabel = styledComponents.styled(ui.Text)`
426
- transform: initial;
427
- &:before,
428
- &:after {
429
- content: none;
430
- }
431
- > span {
432
- display: flex !important;
433
- gap: ${({
434
- theme
435
- }) => ui.rem(theme.sanity.space[3])};
436
- align-items: center;
437
- }
438
- `, ControlsContainer = styledComponents.styled(ui.Box)`
439
- border-top: 1px solid var(--card-border-color);
440
- `, defaultValue$1 = `{
441
-
442
- }`;
443
- function ParamsEditor(props) {
444
- const $ = reactCompilerRuntime.c(33), {
445
- onChange,
446
- paramsError,
447
- hasValidParams,
448
- editorRef
449
- } = props, {
450
- t
451
- } = sanity.useTranslation(index.visionLocaleNamespace);
452
- let t0;
453
- $[0] !== props.value || $[1] !== t ? (t0 = parseParams(props.value, t), $[0] = props.value, $[1] = t, $[2] = t0) : t0 = $[2];
454
- const {
455
- raw: value,
456
- error,
457
- parsed,
458
- valid
459
- } = t0, [isValid, setValid] = react.useState(valid), [init, setInit] = react.useState(!1);
460
- let t1, t2;
461
- $[3] !== error || $[4] !== init || $[5] !== isValid || $[6] !== onChange || $[7] !== parsed || $[8] !== value ? (t1 = () => {
462
- init || (onChange({
463
- parsed,
464
- raw: value,
465
- valid: isValid,
466
- error
467
- }), setInit(!0));
468
- }, t2 = [error, init, isValid, onChange, parsed, value], $[3] = error, $[4] = init, $[5] = isValid, $[6] = onChange, $[7] = parsed, $[8] = value, $[9] = t1, $[10] = t2) : (t1 = $[9], t2 = $[10]), react.useEffect(t1, t2);
469
- let t3;
470
- $[11] !== onChange || $[12] !== t ? (t3 = (newValue) => {
471
- const event = parseParams(newValue, t);
472
- setValid(event.valid), onChange(event);
473
- }, $[11] = onChange, $[12] = t, $[13] = t3) : t3 = $[13];
474
- const handleChangeRaw = t3;
475
- let t4, t5;
476
- $[14] !== handleChangeRaw ? (t5 = debounce__default.default(handleChangeRaw, 333), $[14] = handleChangeRaw, $[15] = t5) : t5 = $[15], t4 = t5;
477
- const handleChange = t4, t6 = hasValidParams ? "default" : "critical";
478
- let t7;
479
- $[16] !== t ? (t7 = t("params.label"), $[16] = t, $[17] = t7) : t7 = $[17];
480
- let t8;
481
- $[18] !== t7 ? (t8 = /* @__PURE__ */ jsxRuntime.jsx(StyledLabel, { muted: !0, children: t7 }), $[18] = t7, $[19] = t8) : t8 = $[19];
482
- let t9;
483
- $[20] !== paramsError ? (t9 = paramsError && /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { animate: !0, placement: "top", portal: !0, content: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: 1, children: paramsError }), children: /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { padding: 1, marginX: 2, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: /* @__PURE__ */ jsxRuntime.jsx(icons.ErrorOutlineIcon, {}) }) }) }), $[20] = paramsError, $[21] = t9) : t9 = $[21];
484
- let t10;
485
- $[22] !== t8 || $[23] !== t9 ? (t10 = /* @__PURE__ */ jsxRuntime.jsx(InputBackgroundContainerLeft, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { children: [
486
- t8,
487
- t9
488
- ] }) }), $[22] = t8, $[23] = t9, $[24] = t10) : t10 = $[24];
489
- const t11 = props.value || defaultValue$1;
490
- let t12;
491
- $[25] !== editorRef || $[26] !== handleChange || $[27] !== t11 ? (t12 = /* @__PURE__ */ jsxRuntime.jsx(VisionCodeMirror, { ref: editorRef, initialValue: t11, onChange: handleChange }), $[25] = editorRef, $[26] = handleChange, $[27] = t11, $[28] = t12) : t12 = $[28];
492
- let t13;
493
- return $[29] !== t10 || $[30] !== t12 || $[31] !== t6 ? (t13 = /* @__PURE__ */ jsxRuntime.jsxs(ui.Card, { flex: 1, tone: t6, "data-testid": "params-editor", children: [
494
- t10,
495
- t12
496
- ] }), $[29] = t10, $[30] = t12, $[31] = t6, $[32] = t13) : t13 = $[32], t13;
497
- }
498
- function parseParams(value, t) {
499
- const parsedParams = tryParseParams(value, t), params = parsedParams instanceof Error ? {} : parsedParams, validationError = parsedParams instanceof Error ? parsedParams.message : void 0;
500
- return {
501
- parsed: params,
502
- raw: value,
503
- valid: !validationError,
504
- error: validationError
505
- };
506
- }
507
- const STORED_QUERIES_NAMESPACE = "studio.vision-tool.saved-queries", defaultValue = {
508
- queries: []
509
- }, keyValueStoreKey = STORED_QUERIES_NAMESPACE;
510
- function useSavedQueries() {
511
- const keyValueStore = sanity.useKeyValueStore(), [value, setValue] = react.useState(defaultValue), [saving, setSaving] = react.useState(!1), [deleting, setDeleting] = react.useState([]), [saveQueryError, setSaveQueryError] = react.useState(), [deleteQueryError, setDeleteQueryError] = react.useState(), [error, setError] = react.useState(), queries = react.useMemo(() => keyValueStore.getKey(keyValueStoreKey), [keyValueStore]);
512
- react.useEffect(() => {
513
- const sub = queries.pipe(operators.startWith(defaultValue), operators.map((data) => data || defaultValue)).subscribe({
514
- next: setValue,
515
- error: (err) => setError(err)
516
- });
517
- return () => sub?.unsubscribe();
518
- }, [queries, keyValueStore]);
519
- const saveQuery = react.useCallback((query) => {
520
- setSaving(!0), setSaveQueryError(void 0);
521
- try {
522
- const newQueries = [{
523
- ...query,
524
- _key: uuid.uuid()
525
- }, ...value.queries];
526
- setValue({
527
- queries: newQueries
528
- }), keyValueStore.setKey(keyValueStoreKey, {
529
- queries: newQueries
530
- });
531
- } catch (err_0) {
532
- setSaveQueryError(err_0);
533
- } finally {
534
- setSaving(!1);
535
- }
536
- }, [keyValueStore, value.queries]), updateQuery = react.useCallback((query_0) => {
537
- setSaving(!0), setSaveQueryError(void 0);
538
- try {
539
- const updatedQueries = value.queries.map((q) => q._key === query_0._key ? {
540
- ...q,
541
- ...query_0
542
- } : q);
543
- setValue({
544
- queries: updatedQueries
545
- }), keyValueStore.setKey(keyValueStoreKey, {
546
- queries: updatedQueries
547
- });
548
- } catch (err_1) {
549
- setSaveQueryError(err_1);
550
- } finally {
551
- setSaving(!1);
552
- }
553
- }, [keyValueStore, value.queries]), deleteQuery = react.useCallback((key) => {
554
- setDeleting((prev) => [...prev, key]), setDeleteQueryError(void 0);
555
- try {
556
- const filteredQueries = value.queries.filter((q_0) => q_0._key !== key);
557
- setValue({
558
- queries: filteredQueries
559
- }), keyValueStore.setKey(keyValueStoreKey, {
560
- queries: filteredQueries
561
- });
562
- } catch (err_2) {
563
- setDeleteQueryError(err_2);
564
- } finally {
565
- setDeleting((prev) => prev.filter((k) => k !== key));
566
- }
567
- }, [keyValueStore, value.queries]);
568
- return {
569
- queries: value.queries,
570
- saveQuery,
571
- updateQuery,
572
- deleteQuery,
573
- saving,
574
- deleting,
575
- saveQueryError,
576
- deleteQueryError,
577
- error
578
- };
579
- }
580
- const FixedHeader = styledComponents.styled(ui.Stack)`
581
- position: sticky;
582
- top: 0;
583
- background: ${({
584
- theme
585
- }) => theme.sanity.color.base.bg};
586
- z-index: 1;
587
- `, ScrollContainer = styledComponents.styled(ui.Box)`
588
- height: 100%;
589
- overflow-y: auto;
590
- overflow-x: hidden;
591
-
592
- &::-webkit-scrollbar {
593
- width: 8px;
594
- }
595
-
596
- &::-webkit-scrollbar-track {
597
- background: transparent;
598
- }
599
-
600
- &::-webkit-scrollbar-thumb {
601
- background: ${({
602
- theme
603
- }) => theme.sanity.color.base.border};
604
- border-radius: 4px;
605
- }
606
- `;
607
- function QueryRecall(t0) {
608
- const $ = reactCompilerRuntime.c(80), {
609
- url,
610
- getStateFromUrl,
611
- setStateFromParsedUrl,
612
- currentQuery,
613
- currentParams,
614
- generateUrl
615
- } = t0, toast = ui.useToast(), {
616
- saveQuery,
617
- updateQuery,
618
- queries,
619
- deleteQuery,
620
- saving,
621
- saveQueryError
622
- } = useSavedQueries(), {
623
- t
624
- } = sanity.useTranslation(index.visionLocaleNamespace);
625
- let t1;
626
- $[0] === Symbol.for("react.memo_cache_sentinel") ? (t1 = {
627
- month: "short",
628
- day: "numeric",
629
- year: "numeric",
630
- hour: "numeric",
631
- minute: "2-digit",
632
- hour12: !0
633
- }, $[0] = t1) : t1 = $[0];
634
- const formatDate = sanity.useDateTimeFormat(t1), [editingKey, setEditingKey] = react.useState(null), [editingTitle, setEditingTitle] = react.useState("");
635
- let t2;
636
- $[1] === Symbol.for("react.memo_cache_sentinel") ? (t2 = {}, $[1] = t2) : t2 = $[1];
637
- const [optimisticTitles, setOptimisticTitles] = react.useState(t2), [searchQuery, setSearchQuery] = react.useState(""), [selectedUrl, setSelectedUrl] = react.useState(url);
638
- let t3;
639
- $[2] !== currentParams || $[3] !== currentQuery || $[4] !== formatDate || $[5] !== generateUrl || $[6] !== getStateFromUrl || $[7] !== queries || $[8] !== saveQuery || $[9] !== saveQueryError || $[10] !== t || $[11] !== toast ? (t3 = async () => {
640
- const newUrl = generateUrl(currentQuery, currentParams);
641
- if (queries?.some((q) => {
642
- const savedQueryObj = getStateFromUrl(q.url);
643
- return savedQueryObj && savedQueryObj.query === currentQuery && isEqual__default.default(savedQueryObj.params, currentParams);
644
- })) {
645
- const duplicateQuery = queries?.find((q_0) => {
646
- const savedQueryObj_0 = getStateFromUrl(q_0.url);
647
- return savedQueryObj_0 && savedQueryObj_0.query === currentQuery && isEqual__default.default(savedQueryObj_0.params, currentParams);
648
- });
649
- toast.push({
650
- closable: !0,
651
- status: "warning",
652
- title: t("save-query.already-saved"),
653
- description: `${duplicateQuery?.title} - ${formatDate.format(new Date(duplicateQuery?.savedAt || ""))}`
654
- });
655
- return;
656
- }
657
- newUrl && (await saveQuery({
658
- url: newUrl,
659
- savedAt: (/* @__PURE__ */ new Date()).toISOString(),
660
- title: "Untitled"
661
- }), setSelectedUrl(newUrl)), saveQueryError ? toast.push({
662
- closable: !0,
663
- status: "error",
664
- title: t("save-query.error"),
665
- description: saveQueryError.message
666
- }) : toast.push({
667
- closable: !0,
668
- status: "success",
669
- title: t("save-query.success")
670
- });
671
- }, $[2] = currentParams, $[3] = currentQuery, $[4] = formatDate, $[5] = generateUrl, $[6] = getStateFromUrl, $[7] = queries, $[8] = saveQuery, $[9] = saveQueryError, $[10] = t, $[11] = toast, $[12] = t3) : t3 = $[12];
672
- const handleSave = t3;
673
- let t4;
674
- $[13] !== t || $[14] !== toast || $[15] !== updateQuery ? (t4 = async (query, newTitle) => {
675
- setEditingKey(null), setOptimisticTitles((prev) => ({
676
- ...prev,
677
- [query._key]: newTitle
678
- }));
679
- try {
680
- await updateQuery({
681
- ...query,
682
- title: newTitle
683
- }), setOptimisticTitles((prev_1) => {
684
- const next_0 = {
685
- ...prev_1
686
- };
687
- return delete next_0[query._key], next_0;
688
- });
689
- } catch (t52) {
690
- const err = t52;
691
- setOptimisticTitles((prev_0) => {
692
- const next = {
693
- ...prev_0
694
- };
695
- return delete next[query._key], next;
696
- }), toast.push({
697
- closable: !0,
698
- status: "error",
699
- title: t("save-query.error"),
700
- description: err.message
701
- });
702
- }
703
- }, $[13] = t, $[14] = toast, $[15] = updateQuery, $[16] = t4) : t4 = $[16];
704
- const handleTitleSave = t4;
705
- let t5;
706
- $[17] !== currentParams || $[18] !== currentQuery || $[19] !== formatDate || $[20] !== generateUrl || $[21] !== getStateFromUrl || $[22] !== queries || $[23] !== t || $[24] !== toast || $[25] !== updateQuery ? (t5 = async (query_0) => {
707
- const newUrl_0 = generateUrl(currentQuery, currentParams);
708
- if (queries?.some((q_1) => {
709
- if (q_1._key === query_0._key)
710
- return !1;
711
- const savedQueryObj_1 = getStateFromUrl(q_1.url);
712
- return savedQueryObj_1 && savedQueryObj_1.query === currentQuery && isEqual__default.default(savedQueryObj_1.params, currentParams);
713
- })) {
714
- const duplicateQuery_0 = queries?.find((q_2) => {
715
- if (q_2._key === query_0._key)
716
- return !1;
717
- const savedQueryObj_2 = getStateFromUrl(q_2.url);
718
- return savedQueryObj_2 && savedQueryObj_2.query === currentQuery && isEqual__default.default(savedQueryObj_2.params, currentParams);
719
- });
720
- toast.push({
721
- closable: !0,
722
- status: "warning",
723
- title: t("save-query.already-saved"),
724
- description: `${duplicateQuery_0?.title} - ${formatDate.format(new Date(duplicateQuery_0?.savedAt || ""))}`
725
- });
726
- return;
727
- }
728
- try {
729
- await updateQuery({
730
- ...query_0,
731
- url: newUrl_0,
732
- savedAt: (/* @__PURE__ */ new Date()).toISOString()
733
- }), setSelectedUrl(newUrl_0), toast.push({
734
- closable: !0,
735
- status: "success",
736
- title: t("save-query.success")
737
- });
738
- } catch (t62) {
739
- const err_0 = t62;
740
- toast.push({
741
- closable: !0,
742
- status: "error",
743
- title: t("save-query.error"),
744
- description: err_0.message
745
- });
746
- }
747
- }, $[17] = currentParams, $[18] = currentQuery, $[19] = formatDate, $[20] = generateUrl, $[21] = getStateFromUrl, $[22] = queries, $[23] = t, $[24] = toast, $[25] = updateQuery, $[26] = t5) : t5 = $[26];
748
- const handleUpdate = t5;
749
- let T0, T1, t6, t7, t8;
750
- if ($[27] !== currentParams || $[28] !== currentQuery || $[29] !== deleteQuery || $[30] !== editingKey || $[31] !== editingTitle || $[32] !== formatDate || $[33] !== getStateFromUrl || $[34] !== handleSave || $[35] !== handleTitleSave || $[36] !== handleUpdate || $[37] !== optimisticTitles || $[38] !== queries || $[39] !== saving || $[40] !== searchQuery || $[41] !== selectedUrl || $[42] !== setStateFromParsedUrl || $[43] !== t) {
751
- const filteredQueries = queries?.filter((q_3) => q_3?.title?.toLowerCase().includes(searchQuery.toLowerCase()));
752
- T1 = ScrollContainer;
753
- let t92;
754
- $[49] === Symbol.for("react.memo_cache_sentinel") ? (t92 = {
755
- textTransform: "capitalize"
756
- }, $[49] = t92) : t92 = $[49];
757
- let t102;
758
- $[50] !== t ? (t102 = t("label.saved-queries"), $[50] = t, $[51] = t102) : t102 = $[51];
759
- let t11;
760
- $[52] !== t102 ? (t11 = /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "semibold", style: t92, size: 4, children: t102 }), $[52] = t102, $[53] = t11) : t11 = $[53];
761
- let t12;
762
- $[54] !== t ? (t12 = t("action.save-query"), $[54] = t, $[55] = t12) : t12 = $[55];
763
- let t13;
764
- $[56] !== handleSave || $[57] !== saving || $[58] !== t12 ? (t13 = /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { label: t12, icon: icons.AddIcon, disabled: saving, onClick: handleSave, mode: "bleed" }), $[56] = handleSave, $[57] = saving, $[58] = t12, $[59] = t13) : t13 = $[59];
765
- let t14;
766
- $[60] !== t11 || $[61] !== t13 ? (t14 = /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { padding: 3, paddingTop: 4, paddingBottom: 0, justify: "space-between", align: "center", children: [
767
- t11,
768
- t13
769
- ] }), $[60] = t11, $[61] = t13, $[62] = t14) : t14 = $[62];
770
- let t15;
771
- $[63] !== t ? (t15 = t("label.search-queries"), $[63] = t, $[64] = t15) : t15 = $[64];
772
- let t16;
773
- $[65] === Symbol.for("react.memo_cache_sentinel") ? (t16 = (event) => setSearchQuery(event.currentTarget.value), $[65] = t16) : t16 = $[65];
774
- let t17;
775
- $[66] !== searchQuery || $[67] !== t15 ? (t17 = /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { padding: 3, paddingTop: 0, children: /* @__PURE__ */ jsxRuntime.jsx(ui.TextInput, { placeholder: t15, icon: icons.SearchIcon, value: searchQuery, onChange: t16 }) }), $[66] = searchQuery, $[67] = t15, $[68] = t17) : t17 = $[68], $[69] !== t14 || $[70] !== t17 ? (t8 = /* @__PURE__ */ jsxRuntime.jsxs(FixedHeader, { space: 3, children: [
776
- t14,
777
- t17
778
- ] }), $[69] = t14, $[70] = t17, $[71] = t8) : t8 = $[71], T0 = ui.Stack, t6 = 3, t7 = filteredQueries?.map((q_4) => {
779
- const queryObj = getStateFromUrl(q_4.url), isSelected = selectedUrl === q_4.url, areQueriesEqual = queryObj && currentQuery === queryObj.query && isEqual__default.default(currentParams, queryObj.params), isEdited = isSelected && !areQueriesEqual;
780
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { width: "fill", padding: 4, border: !0, tone: isSelected ? "positive" : "default", onClick: () => {
781
- setSelectedUrl(q_4.url);
782
- const parsedUrl = getStateFromUrl(q_4.url);
783
- parsedUrl && setStateFromParsedUrl(parsedUrl);
784
- }, style: {
785
- position: "relative"
786
- }, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
787
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "space-between", align: "center", children: [
788
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { align: "center", gap: 2, paddingRight: 1, children: [
789
- editingKey === q_4._key ? /* @__PURE__ */ jsxRuntime.jsx(ui.TextInput, { value: editingTitle, onChange: (event_0) => setEditingTitle(event_0.currentTarget.value), onKeyDown: (event_1) => {
790
- event_1.key === "Enter" ? handleTitleSave(q_4, editingTitle) : event_1.key === "Escape" && setEditingKey(null);
791
- }, onBlur: () => handleTitleSave(q_4, editingTitle), autoFocus: !0, style: {
792
- maxWidth: "170px",
793
- height: "24px"
794
- } }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", size: 3, textOverflow: "ellipsis", style: {
795
- maxWidth: "170px",
796
- cursor: "pointer",
797
- padding: "4px 0"
798
- }, title: optimisticTitles[q_4._key] || q_4.title || q_4._key.slice(q_4._key.length - 5, q_4._key.length), onClick: () => {
799
- setEditingKey(q_4._key), setEditingTitle(q_4.title || q_4._key.slice(0, 5));
800
- }, children: optimisticTitles[q_4._key] || q_4.title || q_4._key.slice(q_4._key.length - 5, q_4._key.length) }),
801
- isEdited && /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { style: {
802
- width: "6px",
803
- height: "6px",
804
- borderRadius: "50%",
805
- backgroundColor: "var(--card-focus-ring-color)"
806
- } })
807
- ] }),
808
- /* @__PURE__ */ jsxRuntime.jsx(ui.MenuButton, { button: /* @__PURE__ */ jsxRuntime.jsx(sanity.ContextMenuButton, {}), id: `${q_4._key}-menu`, menu: /* @__PURE__ */ jsxRuntime.jsx(ui.Menu, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.MenuItem, { tone: "critical", padding: 3, icon: icons.TrashIcon, text: t("action.delete"), onClick: (event_2) => {
809
- event_2.stopPropagation(), deleteQuery(q_4._key);
810
- } }) }), popover: {
811
- portal: !0,
812
- placement: "bottom-end",
813
- tone: "default"
814
- } })
815
- ] }),
816
- /* @__PURE__ */ jsxRuntime.jsx(ui.Code, { muted: !0, children: queryObj?.query.split("{")[0] }),
817
- /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, { align: "center", gap: 1, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: 1, muted: !0, children: formatDate.format(new Date(q_4.savedAt || "")) }) }),
818
- isEdited && /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { mode: "ghost", tone: "default", size: 1, padding: 2, style: {
819
- height: "24px",
820
- position: "absolute",
821
- right: "16px",
822
- bottom: "16px",
823
- fontSize: "12px"
824
- }, text: t("action.update"), onClick: (e) => {
825
- e.stopPropagation(), handleUpdate(q_4);
826
- } })
827
- ] }) }, q_4._key);
828
- }), $[27] = currentParams, $[28] = currentQuery, $[29] = deleteQuery, $[30] = editingKey, $[31] = editingTitle, $[32] = formatDate, $[33] = getStateFromUrl, $[34] = handleSave, $[35] = handleTitleSave, $[36] = handleUpdate, $[37] = optimisticTitles, $[38] = queries, $[39] = saving, $[40] = searchQuery, $[41] = selectedUrl, $[42] = setStateFromParsedUrl, $[43] = t, $[44] = T0, $[45] = T1, $[46] = t6, $[47] = t7, $[48] = t8;
829
- } else
830
- T0 = $[44], T1 = $[45], t6 = $[46], t7 = $[47], t8 = $[48];
831
- let t9;
832
- $[72] !== T0 || $[73] !== t6 || $[74] !== t7 ? (t9 = /* @__PURE__ */ jsxRuntime.jsx(T0, { paddingY: t6, children: t7 }), $[72] = T0, $[73] = t6, $[74] = t7, $[75] = t9) : t9 = $[75];
833
- let t10;
834
- return $[76] !== T1 || $[77] !== t8 || $[78] !== t9 ? (t10 = /* @__PURE__ */ jsxRuntime.jsxs(T1, { children: [
835
- t8,
836
- t9
837
- ] }), $[76] = T1, $[77] = t8, $[78] = t9, $[79] = t10) : t10 = $[79], t10;
838
- }
839
- function narrowBreakpoint() {
840
- return typeof window < "u" && window.innerWidth > 600;
841
- }
842
- function calculatePaneSizeOptions(height) {
843
- let rootHeight = height;
844
- return rootHeight || (rootHeight = typeof window < "u" && typeof document < "u" ? document.body.getBoundingClientRect().height - 60 : 0), {
845
- defaultSize: rootHeight / (narrowBreakpoint() ? 2 : 1),
846
- size: rootHeight > 550 ? void 0 : rootHeight * 0.4,
847
- allowResize: rootHeight > 550,
848
- minSize: Math.min(170, Math.max(170, rootHeight / 2)),
849
- maxSize: rootHeight > 650 ? rootHeight * 0.7 : rootHeight * 0.6
850
- };
851
- }
852
- function usePaneSize(t0) {
853
- const $ = reactCompilerRuntime.c(7), {
854
- visionRootRef
855
- } = t0, [isNarrowBreakpoint, setIsNarrowBreakpoint] = react.useState(_temp$3), [paneSizeOptions, setPaneSizeOptions] = react.useState(_temp2$2);
856
- let t1;
857
- $[0] !== visionRootRef.current ? (t1 = () => {
858
- if (!visionRootRef.current)
859
- return;
860
- const handleResize = (entries) => {
861
- setIsNarrowBreakpoint(narrowBreakpoint());
862
- const entry = entries?.[0];
863
- entry && setPaneSizeOptions(calculatePaneSizeOptions(entry.contentRect.height));
864
- }, resizeObserver = new ResizeObserver(handleResize);
865
- return resizeObserver.observe(visionRootRef.current), () => {
866
- resizeObserver.disconnect();
867
- };
868
- }, $[0] = visionRootRef.current, $[1] = t1) : t1 = $[1];
869
- let t2;
870
- $[2] !== visionRootRef ? (t2 = [visionRootRef], $[2] = visionRootRef, $[3] = t2) : t2 = $[3], react.useEffect(t1, t2);
871
- let t3;
872
- return $[4] !== isNarrowBreakpoint || $[5] !== paneSizeOptions ? (t3 = {
873
- paneSizeOptions,
874
- isNarrowBreakpoint
875
- }, $[4] = isNarrowBreakpoint, $[5] = paneSizeOptions, $[6] = t3) : t3 = $[6], t3;
876
- }
877
- function _temp2$2() {
878
- return calculatePaneSizeOptions(void 0);
879
- }
880
- function _temp$3() {
881
- return narrowBreakpoint();
882
- }
883
- function VisionGuiControls(t0) {
884
- const $ = reactCompilerRuntime.c(30), {
885
- hasValidParams,
886
- listenInProgress,
887
- queryInProgress,
888
- onQueryExecution,
889
- onListenExecution
890
- } = t0, {
891
- t
892
- } = sanity.useTranslation(index.visionLocaleNamespace);
893
- let t1;
894
- $[0] !== t ? (t1 = t("params.error.params-invalid-json"), $[0] = t, $[1] = t1) : t1 = $[1];
895
- let t2;
896
- $[2] !== t1 ? (t2 = /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { radius: 4, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: 1, muted: !0, children: t1 }) }), $[2] = t1, $[3] = t2) : t2 = $[3];
897
- let t3;
898
- $[4] === Symbol.for("react.memo_cache_sentinel") ? (t3 = /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { radius: 4, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Hotkeys, { keys: ["Ctrl", "Enter"] }) }), $[4] = t3) : t3 = $[4];
899
- const t4 = queryInProgress ? icons.StopIcon : icons.PlayIcon, t5 = listenInProgress || !hasValidParams, t6 = queryInProgress ? "positive" : "primary";
900
- let t7;
901
- $[5] !== queryInProgress || $[6] !== t ? (t7 = t(queryInProgress ? "action.query-cancel" : "action.query-execute"), $[5] = queryInProgress, $[6] = t, $[7] = t7) : t7 = $[7];
902
- let t8;
903
- $[8] !== onQueryExecution || $[9] !== t4 || $[10] !== t5 || $[11] !== t6 || $[12] !== t7 ? (t8 = /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { flex: 1, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { content: t3, placement: "top", portal: !0, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { width: "fill", onClick: onQueryExecution, type: "button", icon: t4, disabled: t5, tone: t6, text: t7 }) }) }), $[8] = onQueryExecution, $[9] = t4, $[10] = t5, $[11] = t6, $[12] = t7, $[13] = t8) : t8 = $[13];
904
- const t9 = listenInProgress ? icons.StopIcon : icons.PlayIcon;
905
- let t10;
906
- $[14] !== listenInProgress || $[15] !== t ? (t10 = t(listenInProgress ? "action.listen-cancel" : "action.listen-execute"), $[14] = listenInProgress, $[15] = t, $[16] = t10) : t10 = $[16];
907
- const t11 = !hasValidParams, t12 = listenInProgress ? "positive" : "default";
908
- let t13;
909
- $[17] !== onListenExecution || $[18] !== t10 || $[19] !== t11 || $[20] !== t12 || $[21] !== t9 ? (t13 = /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { flex: 1, marginLeft: 3, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { width: "fill", onClick: onListenExecution, type: "button", icon: t9, text: t10, mode: "ghost", disabled: t11, tone: t12 }) }), $[17] = onListenExecution, $[18] = t10, $[19] = t11, $[20] = t12, $[21] = t9, $[22] = t13) : t13 = $[22];
910
- let t14;
911
- $[23] !== t13 || $[24] !== t8 ? (t14 = /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "space-evenly", children: [
912
- t8,
913
- t13
914
- ] }), $[23] = t13, $[24] = t8, $[25] = t14) : t14 = $[25];
915
- let t15;
916
- return $[26] !== hasValidParams || $[27] !== t14 || $[28] !== t2 ? (t15 = /* @__PURE__ */ jsxRuntime.jsx(ControlsContainer, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { padding: 3, paddingX: 3, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { content: t2, placement: "top", disabled: hasValidParams, portal: !0, children: t14 }) }) }), $[26] = hasValidParams, $[27] = t14, $[28] = t2, $[29] = t15) : t15 = $[29], t15;
917
- }
918
- const PerspectivePopoverContent = styledComponents.styled(ui.Box)`
919
- /* This limits the width of the popover content */
920
- max-width: 240px;
921
- `, PerspectivePopoverLink = styledComponents.styled.a`
922
- cursor: pointer;
923
- margin-right: auto;
924
- `, Dot = styledComponents.styled.div`
925
- width: 4px;
926
- height: 4px;
927
- border-radius: 3px;
928
- box-shadow: 0 0 0 1px var(--card-bg-color);
929
- background-color: ${({
930
- $tone
931
- }) => `var(--card-badge-${$tone}-dot-color)`};
932
- `;
933
- function PerspectivePopover() {
934
- const $ = reactCompilerRuntime.c(39), [open, setOpen] = react.useState(!1), buttonRef = react.useRef(null), popoverRef = react.useRef(null);
935
- let t0;
936
- $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = () => setOpen(_temp$2), $[0] = t0) : t0 = $[0];
937
- const handleClick = t0, {
938
- t
939
- } = sanity.useTranslation(index.visionLocaleNamespace);
940
- let t1, t2;
941
- $[1] === Symbol.for("react.memo_cache_sentinel") ? (t1 = () => setOpen(!1), t2 = () => [buttonRef.current, popoverRef.current], $[1] = t1, $[2] = t2) : (t1 = $[1], t2 = $[2]), ui.useClickOutsideEvent(t1, t2);
942
- let t3;
943
- $[3] !== t ? (t3 = t("settings.perspectives.title"), $[3] = t, $[4] = t3) : t3 = $[4];
944
- let t4;
945
- $[5] !== t3 ? (t4 = /* @__PURE__ */ jsxRuntime.jsx(ui.Inline, { space: 2, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "medium", children: t3 }) }), $[5] = t3, $[6] = t4) : t4 = $[6];
946
- let t5;
947
- $[7] !== t ? (t5 = t("settings.perspectives.description"), $[7] = t, $[8] = t5) : t5 = $[8];
948
- let t6;
949
- $[9] !== t5 ? (t6 = /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { muted: !0, children: t5 }) }), $[9] = t5, $[10] = t6) : t6 = $[10];
950
- let t7;
951
- $[11] !== t ? (t7 = t("label.new"), $[11] = t, $[12] = t7) : t7 = $[12];
952
- let t8;
953
- $[13] !== t7 ? (t8 = /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { tone: "primary", children: t7 }) }), $[13] = t7, $[14] = t8) : t8 = $[14];
954
- let t9;
955
- $[15] !== t ? (t9 = /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { muted: !0, children: /* @__PURE__ */ jsxRuntime.jsx(sanity.Translate, { t, i18nKey: "settings.perspective.preview-drafts-renamed-to-drafts.description" }) }), $[15] = t, $[16] = t9) : t9 = $[16];
956
- let t10;
957
- $[17] !== t8 || $[18] !== t9 ? (t10 = /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 2, children: [
958
- t8,
959
- t9
960
- ] }) }), $[17] = t8, $[18] = t9, $[19] = t10) : t10 = $[19];
961
- let t11;
962
- $[20] !== t ? (t11 = null, $[20] = t, $[21] = t11) : t11 = $[21];
963
- let t12;
964
- $[22] !== t ? (t12 = t("settings.perspectives.action.docs-link"), $[22] = t, $[23] = t12) : t12 = $[23];
965
- let t13;
966
- $[24] !== t12 ? (t13 = /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: /* @__PURE__ */ jsxRuntime.jsxs(PerspectivePopoverLink, { href: "https://sanity.io/docs/perspectives", target: "_blank", children: [
967
- t12,
968
- " \u2192"
969
- ] }) }) }), $[24] = t12, $[25] = t13) : t13 = $[25];
970
- let t14;
971
- $[26] !== t10 || $[27] !== t11 || $[28] !== t13 || $[29] !== t4 || $[30] !== t6 ? (t14 = /* @__PURE__ */ jsxRuntime.jsx(PerspectivePopoverContent, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 4, children: [
972
- t4,
973
- t6,
974
- t10,
975
- t11,
976
- t13
977
- ] }) }), $[26] = t10, $[27] = t11, $[28] = t13, $[29] = t4, $[30] = t6, $[31] = t14) : t14 = $[31];
978
- let t15;
979
- $[32] === Symbol.for("react.memo_cache_sentinel") ? (t15 = /* @__PURE__ */ jsxRuntime.jsx(Dot, { $tone: "primary" }), $[32] = t15) : t15 = $[32];
980
- let t16;
981
- $[33] !== open ? (t16 = /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { icon: icons.HelpCircleIcon, mode: "bleed", padding: 2, paddingRight: 1, tone: "primary", fontSize: 1, ref: buttonRef, onClick: handleClick, selected: open, children: t15 }), $[33] = open, $[34] = t16) : t16 = $[34];
982
- let t17;
983
- return $[35] !== open || $[36] !== t14 || $[37] !== t16 ? (t17 = /* @__PURE__ */ jsxRuntime.jsx(ui.Popover, { content: t14, placement: "bottom-start", portal: !0, padding: 3, ref: popoverRef, open, children: t16 }), $[35] = open, $[36] = t14, $[37] = t16, $[38] = t17) : t17 = $[38], t17;
984
- }
985
- function _temp$2(o) {
986
- return !o;
987
- }
988
- const PinnedReleasePerspectiveOption = (t0) => {
989
- const $ = reactCompilerRuntime.c(9), {
990
- pinnedPerspective,
991
- t
992
- } = t0, name = typeof pinnedPerspective.selectedPerspective == "object" ? pinnedPerspective.selectedPerspective.metadata.title : pinnedPerspective.selectedPerspectiveName;
993
- let t1;
994
- $[0] !== pinnedPerspective || $[1] !== t ? (t1 = hasPinnedPerspective(pinnedPerspective) ? `(${t("settings.perspectives.pinned-release-label")})` : t("settings.perspectives.pinned-release-label"), $[0] = pinnedPerspective, $[1] = t, $[2] = t1) : t1 = $[2];
995
- const label = t1;
996
- let t2, t3;
997
- $[3] !== label || $[4] !== name ? (t3 = [name, label].filter(_temp$1), $[3] = label, $[4] = name, $[5] = t3) : t3 = $[5], t2 = t3.join(" ");
998
- const text = t2, t4 = !hasPinnedPerspective(pinnedPerspective);
999
- let t5;
1000
- return $[6] !== t4 || $[7] !== text ? (t5 = /* @__PURE__ */ jsxRuntime.jsx("option", { value: "pinnedRelease", disabled: t4, children: text }), $[6] = t4, $[7] = text, $[8] = t5) : t5 = $[8], t5;
1001
- };
1002
- function VisionGuiHeader(t0) {
1003
- const $ = reactCompilerRuntime.c(64), {
1004
- onChangeDataset,
1005
- dataset,
1006
- customApiVersion,
1007
- apiVersion,
1008
- onChangeApiVersion,
1009
- datasets,
1010
- customApiVersionElementRef,
1011
- onCustomApiVersionChange,
1012
- isValidApiVersion,
1013
- onChangePerspective,
1014
- url,
1015
- perspective
1016
- } = t0, pinnedPerspective = sanity.usePerspective(), {
1017
- t
1018
- } = sanity.useTranslation(index.visionLocaleNamespace), operationUrlElement = react.useRef(null);
1019
- let t1;
1020
- $[0] === Symbol.for("react.memo_cache_sentinel") ? (t1 = () => {
1021
- const el = operationUrlElement.current;
1022
- if (el)
1023
- try {
1024
- el.select(), document.execCommand("copy");
1025
- } catch {
1026
- console.error("Unable to copy to clipboard :(");
1027
- }
1028
- }, $[0] = t1) : t1 = $[0];
1029
- const handleCopyUrl = t1;
1030
- let t2;
1031
- $[1] === Symbol.for("react.memo_cache_sentinel") ? (t2 = [1, 4, 8, 12], $[1] = t2) : t2 = $[1];
1032
- let t3;
1033
- $[2] !== t ? (t3 = t("settings.dataset-label"), $[2] = t, $[3] = t3) : t3 = $[3];
1034
- let t4;
1035
- $[4] !== t3 ? (t4 = /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { paddingTop: 2, paddingBottom: 3, children: /* @__PURE__ */ jsxRuntime.jsx(StyledLabel, { children: t3 }) }), $[4] = t3, $[5] = t4) : t4 = $[5];
1036
- let t5;
1037
- $[6] !== datasets ? (t5 = datasets.map(_temp2$1), $[6] = datasets, $[7] = t5) : t5 = $[7];
1038
- let t6;
1039
- $[8] !== dataset || $[9] !== onChangeDataset || $[10] !== t5 ? (t6 = /* @__PURE__ */ jsxRuntime.jsx(ui.Select, { value: dataset, onChange: onChangeDataset, children: t5 }), $[8] = dataset, $[9] = onChangeDataset, $[10] = t5, $[11] = t6) : t6 = $[11];
1040
- let t7;
1041
- $[12] !== t4 || $[13] !== t6 ? (t7 = /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { padding: 1, column: 2, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { children: [
1042
- t4,
1043
- t6
1044
- ] }) }), $[12] = t4, $[13] = t6, $[14] = t7) : t7 = $[14];
1045
- let t8;
1046
- $[15] !== t ? (t8 = t("settings.api-version-label"), $[15] = t, $[16] = t8) : t8 = $[16];
1047
- let t9;
1048
- $[17] !== t8 ? (t9 = /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { paddingTop: 2, paddingBottom: 3, children: /* @__PURE__ */ jsxRuntime.jsx(StyledLabel, { children: t8 }) }), $[17] = t8, $[18] = t9) : t9 = $[18];
1049
- const t10 = customApiVersion === !1 ? apiVersion : "other";
1050
- let t11;
1051
- $[19] === Symbol.for("react.memo_cache_sentinel") ? (t11 = API_VERSIONS.map(_temp3$1), $[19] = t11) : t11 = $[19];
1052
- let t12;
1053
- $[20] !== t ? (t12 = t("settings.other-api-version-label"), $[20] = t, $[21] = t12) : t12 = $[21];
1054
- let t13;
1055
- $[22] !== t12 ? (t13 = /* @__PURE__ */ jsxRuntime.jsx("option", { value: "other", children: t12 }, "other"), $[22] = t12, $[23] = t13) : t13 = $[23];
1056
- let t14;
1057
- $[24] !== onChangeApiVersion || $[25] !== t10 || $[26] !== t13 ? (t14 = /* @__PURE__ */ jsxRuntime.jsxs(ui.Select, { "data-testid": "api-version-selector", value: t10, onChange: onChangeApiVersion, children: [
1058
- t11,
1059
- t13
1060
- ] }), $[24] = onChangeApiVersion, $[25] = t10, $[26] = t13, $[27] = t14) : t14 = $[27];
1061
- let t15;
1062
- $[28] !== t14 || $[29] !== t9 ? (t15 = /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { padding: 1, column: 2, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { children: [
1063
- t9,
1064
- t14
1065
- ] }) }), $[28] = t14, $[29] = t9, $[30] = t15) : t15 = $[30];
1066
- let t16;
1067
- $[31] !== customApiVersion || $[32] !== customApiVersionElementRef || $[33] !== isValidApiVersion || $[34] !== onCustomApiVersionChange || $[35] !== t ? (t16 = customApiVersion !== !1 && /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { padding: 1, column: 2, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { children: [
1068
- /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { paddingTop: 2, paddingBottom: 3, children: /* @__PURE__ */ jsxRuntime.jsx(StyledLabel, { textOverflow: "ellipsis", children: t("settings.custom-api-version-label") }) }),
1069
- /* @__PURE__ */ jsxRuntime.jsx(ui.TextInput, { ref: customApiVersionElementRef, value: customApiVersion, onChange: onCustomApiVersionChange, customValidity: isValidApiVersion ? void 0 : t("settings.error.invalid-api-version"), maxLength: 11 })
1070
- ] }) }), $[31] = customApiVersion, $[32] = customApiVersionElementRef, $[33] = isValidApiVersion, $[34] = onCustomApiVersionChange, $[35] = t, $[36] = t16) : t16 = $[36];
1071
- let t17;
1072
- $[37] !== t ? (t17 = t("settings.perspective-label"), $[37] = t, $[38] = t17) : t17 = $[38];
1073
- let t18;
1074
- $[39] !== t17 ? (t18 = /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { children: /* @__PURE__ */ jsxRuntime.jsx(StyledLabel, { children: t17 }) }), $[39] = t17, $[40] = t18) : t18 = $[40];
1075
- let t19;
1076
- $[41] === Symbol.for("react.memo_cache_sentinel") ? (t19 = /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { children: /* @__PURE__ */ jsxRuntime.jsx(PerspectivePopover, {}) }), $[41] = t19) : t19 = $[41];
1077
- let t20;
1078
- $[42] !== t18 ? (t20 = /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { paddingBottom: 1, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Inline, { space: 1, children: [
1079
- t18,
1080
- t19
1081
- ] }) }), $[42] = t18, $[43] = t20) : t20 = $[43];
1082
- const t21 = perspective || "default";
1083
- let t22;
1084
- $[44] !== pinnedPerspective || $[45] !== t ? (t22 = SUPPORTED_PERSPECTIVES.map((perspectiveName) => perspectiveName === "pinnedRelease" ? /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
1085
- /* @__PURE__ */ jsxRuntime.jsx(PinnedReleasePerspectiveOption, { pinnedPerspective, t }),
1086
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "default", children: t("settings.perspectives.default") }, "default"),
1087
- /* @__PURE__ */ jsxRuntime.jsx("hr", {})
1088
- ] }, "pinnedRelease") : /* @__PURE__ */ jsxRuntime.jsx("option", { children: perspectiveName }, perspectiveName)), $[44] = pinnedPerspective, $[45] = t, $[46] = t22) : t22 = $[46];
1089
- let t23;
1090
- $[47] !== onChangePerspective || $[48] !== t21 || $[49] !== t22 ? (t23 = /* @__PURE__ */ jsxRuntime.jsx(ui.Select, { value: t21, onChange: onChangePerspective, children: t22 }), $[47] = onChangePerspective, $[48] = t21, $[49] = t22, $[50] = t23) : t23 = $[50];
1091
- let t24;
1092
- $[51] !== t20 || $[52] !== t23 ? (t24 = /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { padding: 1, column: 2, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { children: [
1093
- t20,
1094
- t23
1095
- ] }) }), $[51] = t20, $[52] = t23, $[53] = t24) : t24 = $[53];
1096
- let t25;
1097
- $[54] !== customApiVersion || $[55] !== t || $[56] !== url ? (t25 = typeof url == "string" ? /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { padding: 1, flex: 1, column: customApiVersion === !1 ? 6 : 4, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { children: [
1098
- /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { paddingTop: 2, paddingBottom: 3, children: /* @__PURE__ */ jsxRuntime.jsxs(StyledLabel, { children: [
1099
- t("query.url"),
1100
- "\xA0",
1101
- /* @__PURE__ */ jsxRuntime.jsxs(QueryCopyLink, { onClick: handleCopyUrl, children: [
1102
- "[",
1103
- t("action.copy-url-to-clipboard"),
1104
- "]"
1105
- ] })
1106
- ] }) }),
1107
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { flex: 1, gap: 1, children: [
1108
- /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { flex: 1, children: /* @__PURE__ */ jsxRuntime.jsx(ui.TextInput, { readOnly: !0, type: "url", ref: operationUrlElement, value: url }) }),
1109
- /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { content: t("action.copy-url-to-clipboard"), children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { "aria-label": t("action.copy-url-to-clipboard"), type: "button", mode: "ghost", icon: icons.CopyIcon, onClick: handleCopyUrl }) })
1110
- ] })
1111
- ] }) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { flex: 1 }), $[54] = customApiVersion, $[55] = t, $[56] = url, $[57] = t25) : t25 = $[57];
1112
- let t26;
1113
- return $[58] !== t15 || $[59] !== t16 || $[60] !== t24 || $[61] !== t25 || $[62] !== t7 ? (t26 = /* @__PURE__ */ jsxRuntime.jsx(Header, { paddingX: 3, paddingY: 2, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Grid, { columns: t2, children: [
1114
- t7,
1115
- t15,
1116
- t16,
1117
- t24,
1118
- t25
1119
- ] }) }), $[58] = t15, $[59] = t16, $[60] = t24, $[61] = t25, $[62] = t7, $[63] = t26) : t26 = $[63], t26;
1120
- }
1121
- function _temp3$1(version) {
1122
- return /* @__PURE__ */ jsxRuntime.jsx("option", { children: version }, version);
1123
- }
1124
- function _temp2$1(ds) {
1125
- return /* @__PURE__ */ jsxRuntime.jsx("option", { children: ds }, ds);
1126
- }
1127
- function _temp$1(value) {
1128
- return typeof value < "u";
1129
- }
1130
- function getBlobUrl(content, mimeType) {
1131
- return URL.createObjectURL(new Blob([content], {
1132
- type: mimeType
1133
- }));
1134
- }
1135
- function getMemoizedBlobUrlResolver(mimeType, stringEncoder) {
1136
- return /* @__PURE__ */ (() => {
1137
- let prevResult = "", prevContent = "";
1138
- return (input) => {
1139
- const content = stringEncoder(input);
1140
- if (!(typeof content != "string" || content === ""))
1141
- return content === prevContent || (prevContent = content, prevResult && URL.revokeObjectURL(prevResult), prevResult = getBlobUrl(content, mimeType)), prevResult;
1142
- };
1143
- })();
1144
- }
1145
- const getJsonBlobUrl = getMemoizedBlobUrlResolver("application/json", (input) => JSON.stringify(input, null, 2)), getCsvBlobUrl = getMemoizedBlobUrlResolver("text/csv", (input) => json2Csv.json2csv(Array.isArray(input) ? input : [input]).trim()), ErrorCode = styledComponents.styled(ui.Code)`
1146
- color: ${({
1147
- theme
1148
- }) => theme.sanity.color.muted.critical.enabled.fg};
1149
- `;
1150
- function QueryErrorDetails(t0) {
1151
- const $ = reactCompilerRuntime.c(7), {
1152
- error
1153
- } = t0, {
1154
- t
1155
- } = sanity.useTranslation(index.visionLocaleNamespace);
1156
- if (!("details" in error))
1157
- return null;
1158
- const details = {
1159
- ...error.details,
1160
- ...mapToLegacyDetails(error.details)
1161
- };
1162
- if (!details.line)
1163
- return null;
1164
- const t1 = `${details.line}
1165
- ${dashLine(details.column, details.columnEnd)}`;
1166
- let t2;
1167
- $[0] !== t1 ? (t2 = /* @__PURE__ */ jsxRuntime.jsx(ErrorCode, { size: 1, children: t1 }), $[0] = t1, $[1] = t2) : t2 = $[1];
1168
- const t3 = `${t("query.error.line")}: ${details.lineNumber}
1169
- ${t("query.error.column")}: ${details.column}`;
1170
- let t4;
1171
- $[2] !== t3 ? (t4 = /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { marginTop: 4, children: /* @__PURE__ */ jsxRuntime.jsx(ErrorCode, { size: 1, children: t3 }) }), $[2] = t3, $[3] = t4) : t4 = $[3];
1172
- let t5;
1173
- return $[4] !== t2 || $[5] !== t4 ? (t5 = /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1174
- t2,
1175
- t4
1176
- ] }), $[4] = t2, $[5] = t4, $[6] = t5) : t5 = $[6], t5;
1177
- }
1178
- function mapToLegacyDetails(details) {
1179
- if (!details || typeof details.query != "string" || typeof details.start != "number")
1180
- return {};
1181
- const {
1182
- query,
1183
- start,
1184
- end
1185
- } = details, lineStart = query.slice(0, start).lastIndexOf(`
1186
- `) + 1, lineNumber = (query.slice(0, lineStart).match(/\n/g) || []).length, line = query.slice(lineStart, query.indexOf(`
1187
- `, lineStart)), column = start - lineStart, columnEnd = typeof end == "number" ? end - lineStart : void 0;
1188
- return {
1189
- line,
1190
- lineNumber,
1191
- column,
1192
- columnEnd
1193
- };
1194
- }
1195
- function dashLine(column, columnEnd) {
1196
- const line = "-".repeat(column), hats = "^".repeat(columnEnd ? columnEnd - column : 1);
1197
- return `${line}${hats}`;
1198
- }
1199
- function QueryErrorDialog(props) {
1200
- const $ = reactCompilerRuntime.c(7);
1201
- let t0;
1202
- $[0] !== props.error.message ? (t0 = /* @__PURE__ */ jsxRuntime.jsx(ErrorCode, { size: 1, children: props.error.message }), $[0] = props.error.message, $[1] = t0) : t0 = $[1];
1203
- let t1;
1204
- $[2] !== props.error ? (t1 = /* @__PURE__ */ jsxRuntime.jsx(QueryErrorDetails, { error: props.error }), $[2] = props.error, $[3] = t1) : t1 = $[3];
1205
- let t2;
1206
- return $[4] !== t0 || $[5] !== t1 ? (t2 = /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 5, marginTop: 2, children: [
1207
- t0,
1208
- t1
1209
- ] }), $[4] = t0, $[5] = t1, $[6] = t2) : t2 = $[6], t2;
1210
- }
1211
- const ResultViewWrapper = styledComponents.styled.div(({
1212
- theme
1213
- }) => {
1214
- const {
1215
- color: color2,
1216
- fonts,
1217
- space
1218
- } = theme.sanity;
1219
- return styledComponents.css`
1220
- & .json-inspector,
1221
- & .json-inspector .json-inspector__selection {
1222
- font-family: ${fonts.code.family};
1223
- font-size: ${fonts.code.sizes[2].fontSize}px;
1224
- line-height: ${fonts.code.sizes[2].lineHeight}px;
1225
- color: var(--card-code-fg-color);
1226
- }
1227
-
1228
- & .json-inspector .json-inspector__leaf {
1229
- padding-left: ${ui.rem(space[4])};
1230
- }
1231
-
1232
- & .json-inspector .json-inspector__leaf.json-inspector__leaf_root {
1233
- padding-top: ${ui.rem(space[0])};
1234
- padding-left: 0;
1235
- }
1236
-
1237
- & .json-inspector > .json-inspector__leaf_root > .json-inspector__line > .json-inspector__key {
1238
- display: none;
1239
- }
1240
-
1241
- & .json-inspector .json-inspector__line {
1242
- display: block;
1243
- position: relative;
1244
- cursor: default;
1245
- }
1246
-
1247
- & .json-inspector .json-inspector__line::after {
1248
- content: '';
1249
- position: absolute;
1250
- top: 0;
1251
- left: -200px;
1252
- right: -50px;
1253
- bottom: 0;
1254
- z-index: -1;
1255
- pointer-events: none;
1256
- }
1257
-
1258
- & .json-inspector .json-inspector__line:hover::after {
1259
- background: var(--card-code-bg-color);
1260
- }
1261
-
1262
- & .json-inspector .json-inspector__leaf_composite > .json-inspector__line {
1263
- cursor: pointer;
1264
- }
1265
-
1266
- & .json-inspector .json-inspector__leaf_composite > .json-inspector__line::before {
1267
- content: '▸ ';
1268
- margin-left: calc(0px - ${ui.rem(space[4])});
1269
- font-size: ${fonts.code.sizes[2].fontSize}px;
1270
- line-height: ${fonts.code.sizes[2].lineHeight}px;
1271
- }
1272
-
1273
- &
1274
- .json-inspector
1275
- .json-inspector__leaf_expanded.json-inspector__leaf_composite
1276
- > .json-inspector__line::before {
1277
- content: '▾ ';
1278
- font-size: ${fonts.code.sizes[2].fontSize}px;
1279
- line-height: ${fonts.code.sizes[2].lineHeight}px;
1280
- }
1281
-
1282
- & .json-inspector .json-inspector__radio,
1283
- & .json-inspector .json-inspector__flatpath {
1284
- display: none;
1285
- }
1286
-
1287
- & .json-inspector .json-inspector__value {
1288
- margin-left: ${ui.rem(space[4] / 2)};
1289
- }
1290
-
1291
- &
1292
- .json-inspector
1293
- > .json-inspector__leaf_root
1294
- > .json-inspector__line
1295
- > .json-inspector__key
1296
- + .json-inspector__value {
1297
- margin: 0;
1298
- }
1299
-
1300
- & .json-inspector .json-inspector__key {
1301
- color: ${color2.syntax.property};
1302
- }
1303
-
1304
- & .json-inspector .json-inspector__value_helper,
1305
- & .json-inspector .json-inspector__value_null {
1306
- color: ${color2.syntax.constant};
1307
- }
1308
-
1309
- & .json-inspector .json-inspector__not-found {
1310
- padding-top: ${ui.rem(space[2])};
1311
- }
1312
-
1313
- & .json-inspector .json-inspector__value_string {
1314
- color: ${color2.syntax.string};
1315
- word-break: break-word;
1316
- }
1317
-
1318
- & .json-inspector .json-inspector__value_boolean {
1319
- color: ${color2.syntax.boolean};
1320
- }
1321
-
1322
- & .json-inspector .json-inspector__value_number {
1323
- color: ${color2.syntax.number};
1324
- }
1325
-
1326
- & .json-inspector .json-inspector__show-original {
1327
- display: inline-block;
1328
- padding: 0 6px;
1329
- cursor: pointer;
1330
- }
1331
-
1332
- & .json-inspector .json-inspector__show-original:hover {
1333
- color: inherit;
1334
- }
1335
-
1336
- & .json-inspector .json-inspector__show-original::before {
1337
- content: '↔';
1338
- }
1339
-
1340
- & .json-inspector .json-inspector__show-original:hover::after {
1341
- content: ' expand';
1342
- }
1343
- `;
1344
- }), lru = new LRU__default.default({
1345
- maxSize: 5e4
1346
- });
1347
- function ResultView(props) {
1348
- const $ = reactCompilerRuntime.c(7), {
1349
- data,
1350
- datasetName
1351
- } = props, workspaceDataset = sanity.useDataset();
1352
- if (isRecord(data) || Array.isArray(data)) {
1353
- const t02 = workspaceDataset === datasetName ? DocumentEditLabel : void 0;
1354
- let t12;
1355
- return $[0] !== data || $[1] !== t02 ? (t12 = /* @__PURE__ */ jsxRuntime.jsx(ResultViewWrapper, { children: /* @__PURE__ */ jsxRuntime.jsx(reactJsonInspector.JsonInspector, { data, search: !1, isExpanded, onClick: toggleExpanded, interactiveLabel: t02 }) }), $[0] = data, $[1] = t02, $[2] = t12) : t12 = $[2], t12;
1356
- }
1357
- let t0;
1358
- $[3] !== data ? (t0 = JSON.stringify(data), $[3] = data, $[4] = t0) : t0 = $[4];
1359
- let t1;
1360
- return $[5] !== t0 ? (t1 = /* @__PURE__ */ jsxRuntime.jsx(ui.Code, { language: "json", children: t0 }), $[5] = t0, $[6] = t1) : t1 = $[6], t1;
1361
- }
1362
- function DocumentEditLabel(props) {
1363
- const $ = reactCompilerRuntime.c(5);
1364
- if (props.isKey || !props.keypath.endsWith("_id") && !props.keypath.endsWith("_ref"))
1365
- return null;
1366
- let t0;
1367
- $[0] !== props.value ? (t0 = {
1368
- id: props.value
1369
- }, $[0] = props.value, $[1] = t0) : t0 = $[1];
1370
- let t1;
1371
- $[2] === Symbol.for("react.memo_cache_sentinel") ? (t1 = /* @__PURE__ */ jsxRuntime.jsx(icons.LinkIcon, {}), $[2] = t1) : t1 = $[2];
1372
- let t2;
1373
- return $[3] !== t0 ? (t2 = /* @__PURE__ */ jsxRuntime.jsx(router.IntentLink, { intent: "edit", params: t0, children: t1 }), $[3] = t0, $[4] = t2) : t2 = $[4], t2;
1374
- }
1375
- function isExpanded(keyPath, value) {
1376
- const cached = lru.get(keyPath);
1377
- if (typeof cached == "boolean")
1378
- return cached;
1379
- const segments = keyPath.split(".", 4);
1380
- return segments.length === 4 ? !1 : Array.isArray(value) ? !0 : isRecord(value) && !segments.some((key) => isArrayKeyOverLimit(key));
1381
- }
1382
- function toggleExpanded(event) {
1383
- const {
1384
- path
1385
- } = event, current = lru.get(path);
1386
- current !== void 0 && lru.set(path, !current);
1387
- }
1388
- function isRecord(value) {
1389
- return value !== null && typeof value == "object" && !Array.isArray(value);
1390
- }
1391
- const numeric = /^\d+$/;
1392
- function isArrayKeyOverLimit(segment, limit = 10) {
1393
- return numeric.test(segment) && parseInt(segment, 10) > limit;
1394
- }
1395
- function preventSave(evt) {
1396
- return evt.preventDefault();
1397
- }
1398
- function SaveCsvButton(t0) {
1399
- const $ = reactCompilerRuntime.c(9), {
1400
- blobUrl
1401
- } = t0, {
1402
- t
1403
- } = sanity.useTranslation(index.visionLocaleNamespace), isDisabled = !blobUrl, t1 = isDisabled ? void 0 : "query-result.csv", t2 = isDisabled ? preventSave : void 0;
1404
- let t3;
1405
- $[0] !== blobUrl || $[1] !== isDisabled || $[2] !== t1 || $[3] !== t2 ? (t3 = /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { as: "a", disabled: isDisabled, download: t1, href: blobUrl, icon: icons.DocumentSheetIcon, mode: "ghost", onClick: t2, text: "CSV", tone: "default" }), $[0] = blobUrl, $[1] = isDisabled, $[2] = t1, $[3] = t2, $[4] = t3) : t3 = $[4];
1406
- const button = t3;
1407
- let t4;
1408
- return $[5] !== button || $[6] !== isDisabled || $[7] !== t ? (t4 = isDisabled ? /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { content: t("result.save-result-as-csv.not-csv-encodable"), placement: "top", children: button }) : button, $[5] = button, $[6] = isDisabled, $[7] = t, $[8] = t4) : t4 = $[8], t4;
1409
- }
1410
- function SaveJsonButton(t0) {
1411
- const $ = reactCompilerRuntime.c(2), {
1412
- blobUrl
1413
- } = t0;
1414
- let t1;
1415
- return $[0] !== blobUrl ? (t1 = /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { as: "a", download: "query-result.json", href: blobUrl, icon: icons.DocumentSheetIcon, mode: "ghost", text: "JSON", tone: "default" }), $[0] = blobUrl, $[1] = t1) : t1 = $[1], t1;
1416
- }
1417
- function VisionGuiResult(t0) {
1418
- const $ = reactCompilerRuntime.c(67), {
1419
- error,
1420
- queryInProgress,
1421
- queryResult,
1422
- listenInProgress,
1423
- listenMutations,
1424
- dataset,
1425
- queryTime,
1426
- e2eTime
1427
- } = t0, {
1428
- t
1429
- } = sanity.useTranslation(index.visionLocaleNamespace), hasResult = !error && !queryInProgress && typeof queryResult < "u";
1430
- let t1;
1431
- $[0] !== hasResult || $[1] !== queryResult ? (t1 = hasResult ? getJsonBlobUrl(queryResult) : "", $[0] = hasResult, $[1] = queryResult, $[2] = t1) : t1 = $[2];
1432
- const jsonUrl = t1;
1433
- let t2;
1434
- $[3] !== hasResult || $[4] !== queryResult ? (t2 = hasResult ? getCsvBlobUrl(queryResult) : "", $[3] = hasResult, $[4] = queryResult, $[5] = t2) : t2 = $[5];
1435
- const csvUrl = t2, t3 = error ? "critical" : "default", t4 = !!error;
1436
- let t5;
1437
- $[6] !== t ? (t5 = t("result.label"), $[6] = t, $[7] = t5) : t5 = $[7];
1438
- let t6;
1439
- $[8] !== t5 ? (t6 = /* @__PURE__ */ jsxRuntime.jsx(InputBackgroundContainer, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { marginLeft: 3, children: /* @__PURE__ */ jsxRuntime.jsx(StyledLabel, { muted: !0, children: t5 }) }) }), $[8] = t5, $[9] = t6) : t6 = $[9];
1440
- let t7;
1441
- $[10] !== listenInProgress || $[11] !== listenMutations || $[12] !== queryInProgress ? (t7 = (queryInProgress || listenInProgress && listenMutations.length === 0) && /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { marginTop: 3, children: /* @__PURE__ */ jsxRuntime.jsx(DelayedSpinner, {}) }), $[10] = listenInProgress, $[11] = listenMutations, $[12] = queryInProgress, $[13] = t7) : t7 = $[13];
1442
- let t8;
1443
- $[14] !== error ? (t8 = error && /* @__PURE__ */ jsxRuntime.jsx(QueryErrorDialog, { error }), $[14] = error, $[15] = t8) : t8 = $[15];
1444
- let t9;
1445
- $[16] !== dataset || $[17] !== hasResult || $[18] !== queryResult ? (t9 = hasResult && /* @__PURE__ */ jsxRuntime.jsx(ResultView, { data: queryResult, datasetName: dataset }), $[16] = dataset, $[17] = hasResult, $[18] = queryResult, $[19] = t9) : t9 = $[19];
1446
- let t10;
1447
- $[20] !== dataset || $[21] !== listenInProgress || $[22] !== listenMutations ? (t10 = listenInProgress && listenMutations.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(ResultView, { data: listenMutations, datasetName: dataset }), $[20] = dataset, $[21] = listenInProgress, $[22] = listenMutations, $[23] = t10) : t10 = $[23];
1448
- let t11;
1449
- $[24] !== t10 || $[25] !== t7 || $[26] !== t8 || $[27] !== t9 ? (t11 = /* @__PURE__ */ jsxRuntime.jsxs(ui.Box, { padding: 3, paddingTop: 5, children: [
1450
- t7,
1451
- t8,
1452
- t9,
1453
- t10
1454
- ] }), $[24] = t10, $[25] = t7, $[26] = t8, $[27] = t9, $[28] = t11) : t11 = $[28];
1455
- let t12;
1456
- $[29] !== t11 || $[30] !== t6 ? (t12 = /* @__PURE__ */ jsxRuntime.jsxs(Result, { overflow: "auto", children: [
1457
- t6,
1458
- t11
1459
- ] }), $[29] = t11, $[30] = t6, $[31] = t12) : t12 = $[31];
1460
- let t13;
1461
- $[32] !== t12 || $[33] !== t3 || $[34] !== t4 ? (t13 = /* @__PURE__ */ jsxRuntime.jsx(ResultInnerContainer, { flex: 1, children: /* @__PURE__ */ jsxRuntime.jsx(ResultContainer, { flex: 1, overflow: "hidden", tone: t3, $isInvalid: t4, children: t12 }) }), $[32] = t12, $[33] = t3, $[34] = t4, $[35] = t13) : t13 = $[35];
1462
- let t14;
1463
- $[36] === Symbol.for("react.memo_cache_sentinel") ? (t14 = ["column", "column", "row"], $[36] = t14) : t14 = $[36];
1464
- let t15;
1465
- $[37] !== t ? (t15 = t("result.execution-time-label"), $[37] = t, $[38] = t15) : t15 = $[38];
1466
- let t16;
1467
- $[39] !== queryTime || $[40] !== t ? (t16 = typeof queryTime == "number" ? `${queryTime}ms` : t("result.timing-not-applicable"), $[39] = queryTime, $[40] = t, $[41] = t16) : t16 = $[41];
1468
- let t17;
1469
- $[42] !== t15 || $[43] !== t16 ? (t17 = /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { muted: !0, children: [
1470
- t15,
1471
- ":",
1472
- " ",
1473
- t16
1474
- ] }) }), $[42] = t15, $[43] = t16, $[44] = t17) : t17 = $[44];
1475
- let t18;
1476
- $[45] !== t ? (t18 = t("result.end-to-end-time-label"), $[45] = t, $[46] = t18) : t18 = $[46];
1477
- let t19;
1478
- $[47] !== e2eTime || $[48] !== t ? (t19 = typeof e2eTime == "number" ? `${e2eTime}ms` : t("result.timing-not-applicable"), $[47] = e2eTime, $[48] = t, $[49] = t19) : t19 = $[49];
1479
- let t20;
1480
- $[50] !== t18 || $[51] !== t19 ? (t20 = /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { marginLeft: 4, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { muted: !0, children: [
1481
- t18,
1482
- ":",
1483
- " ",
1484
- t19
1485
- ] }) }), $[50] = t18, $[51] = t19, $[52] = t20) : t20 = $[52];
1486
- let t21;
1487
- $[53] !== t17 || $[54] !== t20 ? (t21 = /* @__PURE__ */ jsxRuntime.jsx(TimingsCard, { paddingX: 4, paddingY: 3, sizing: "border", children: /* @__PURE__ */ jsxRuntime.jsxs(TimingsTextContainer, { align: "center", children: [
1488
- t17,
1489
- t20
1490
- ] }) }), $[53] = t17, $[54] = t20, $[55] = t21) : t21 = $[55];
1491
- let t22;
1492
- $[56] !== csvUrl || $[57] !== hasResult || $[58] !== jsonUrl || $[59] !== t ? (t22 = hasResult && /* @__PURE__ */ jsxRuntime.jsx(DownloadsCard, { paddingX: 4, paddingY: 3, sizing: "border", children: /* @__PURE__ */ jsxRuntime.jsx(SaveResultLabel, { muted: !0, children: /* @__PURE__ */ jsxRuntime.jsx(sanity.Translate, { components: {
1493
- SaveResultButtons: () => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1494
- /* @__PURE__ */ jsxRuntime.jsx(SaveJsonButton, { blobUrl: jsonUrl }),
1495
- /* @__PURE__ */ jsxRuntime.jsx(SaveCsvButton, { blobUrl: csvUrl })
1496
- ] })
1497
- }, i18nKey: "result.save-result-as-format", t }) }) }), $[56] = csvUrl, $[57] = hasResult, $[58] = jsonUrl, $[59] = t, $[60] = t22) : t22 = $[60];
1498
- let t23;
1499
- $[61] !== t21 || $[62] !== t22 ? (t23 = /* @__PURE__ */ jsxRuntime.jsxs(ResultFooter, { justify: "space-between", direction: t14, children: [
1500
- t21,
1501
- t22
1502
- ] }), $[61] = t21, $[62] = t22, $[63] = t23) : t23 = $[63];
1503
- let t24;
1504
- return $[64] !== t13 || $[65] !== t23 ? (t24 = /* @__PURE__ */ jsxRuntime.jsxs(ResultOuterContainer, { direction: "column", "data-testid": "vision-result", children: [
1505
- t13,
1506
- t23
1507
- ] }), $[64] = t13, $[65] = t23, $[66] = t24) : t24 = $[66], t24;
1508
- }
1509
- function nodeContains(node, other) {
1510
- return !node || !other ? !1 : node === other || !!(node.compareDocumentPosition(other) & 16);
1511
- }
1512
- const sanityUrl = /\.(?:api|apicdn)\.sanity\.(?:io|work)\/(vX|v1|v\d{4}-\d\d-\d\d)\/.*?(?:query|listen)\/(.*?)\?(.*)/, isRunHotkey = (event) => isHotkeyEsm.isHotkey("ctrl+enter", event) || isHotkeyEsm.isHotkey("mod+enter", event);
1513
- function VisionGui(props) {
1514
- const {
1515
- datasets,
1516
- config,
1517
- projectId,
1518
- defaultDataset
1519
- } = props, toast = ui.useToast(), {
1520
- t
1521
- } = sanity.useTranslation(index.visionLocaleNamespace), {
1522
- perspectiveStack
1523
- } = sanity.usePerspective(), defaultApiVersion = prefixApiVersion(`${config.defaultApiVersion}`), editorQueryRef = react.useRef(null), editorParamsRef = react.useRef(null), visionRootRef = react.useRef(null), customApiVersionElementRef = react.useRef(null), querySubscriptionRef = react.useRef(void 0), listenSubscriptionRef = react.useRef(void 0), [localStorage2] = react.useState(() => getLocalStorage(projectId || "default")), {
1524
- storedDataset,
1525
- storedApiVersion,
1526
- storedQuery,
1527
- storedParams,
1528
- storedPerspective
1529
- } = react.useMemo(() => ({
1530
- storedDataset: localStorage2.get("dataset", defaultDataset),
1531
- storedApiVersion: localStorage2.get("apiVersion", defaultApiVersion),
1532
- storedQuery: localStorage2.get("query", ""),
1533
- storedParams: localStorage2.get("params", `{
1534
-
1535
- }`),
1536
- storedPerspective: localStorage2.get("perspective", void 0)
1537
- }), [defaultDataset, defaultApiVersion, localStorage2]), [dataset, setDataset] = react.useState(() => datasets.includes(storedDataset) ? storedDataset : datasets.includes(defaultDataset) ? defaultDataset : datasets[0]), [apiVersion, setApiVersion] = react.useState(() => API_VERSIONS.includes(storedApiVersion) ? storedApiVersion : DEFAULT_API_VERSION), [customApiVersion, setCustomApiVersion] = react.useState(() => API_VERSIONS.includes(storedApiVersion) ? !1 : storedApiVersion), [perspective, setPerspectiveState] = react.useState(storedPerspective || "raw"), isValidApiVersion = customApiVersion ? validateApiVersion(customApiVersion) : !0, [url, setUrl] = react.useState(void 0), [query, setQuery] = react.useState(() => typeof storedQuery == "string" ? storedQuery : ""), [params, setParams] = react.useState(() => parseParams(storedParams, t)), [queryResult, setQueryResult] = react.useState(void 0), [listenMutations, setListenMutations] = react.useState([]), [error, setError] = react.useState(void 0), [queryTime, setQueryTime] = react.useState(void 0), [e2eTime, setE2eTime] = react.useState(void 0), [queryInProgress, setQueryInProgress] = react.useState(!1), [listenInProgress, setListenInProgress] = react.useState(!1), [isQueryRecallCollapsed, setIsQueryRecallCollapsed] = react.useState(!1), {
1538
- paneSizeOptions,
1539
- isNarrowBreakpoint
1540
- } = usePaneSize({
1541
- visionRootRef
1542
- }), _client = sanity.useClient({
1543
- apiVersion: isValidApiVersion && customApiVersion ? customApiVersion : apiVersion
1544
- }), client = react.useMemo(() => _client.withConfig({
1545
- apiVersion: isValidApiVersion && customApiVersion ? customApiVersion : apiVersion,
1546
- perspective: getActivePerspective({
1547
- visionPerspective: perspective,
1548
- perspectiveStack
1549
- }),
1550
- dataset,
1551
- allowReconfigure: !0
1552
- }), [perspectiveStack, perspective, customApiVersion, apiVersion, dataset, _client, isValidApiVersion]), cancelQuerySubscription = react.useCallback(() => {
1553
- querySubscriptionRef.current && (querySubscriptionRef.current.unsubscribe(), querySubscriptionRef.current = void 0);
1554
- }, []), cancelListenerSubscription = react.useCallback(() => {
1555
- listenSubscriptionRef.current && (listenSubscriptionRef.current.unsubscribe(), listenSubscriptionRef.current = void 0);
1556
- }, []), handleQueryExecution = react.useCallback((options) => {
1557
- if (queryInProgress) {
1558
- cancelQuerySubscription(), cancelListenerSubscription(), setQueryInProgress(!1);
1559
- return;
1560
- }
1561
- const context = {
1562
- query: options?.query || query,
1563
- dataset: options?.dataset || dataset,
1564
- params: parseParams(JSON.stringify(options?.params || params.parsed, null, 2), t),
1565
- perspective: getActivePerspective({
1566
- visionPerspective: options?.perspective || perspective,
1567
- perspectiveStack
1568
- }),
1569
- apiVersion: options?.apiVersion || (customApiVersion && isValidApiVersion ? customApiVersion : apiVersion)
1570
- };
1571
- if (localStorage2.set("query", context.query), localStorage2.set("params", context.params.raw), cancelListenerSubscription(), setQueryInProgress(!context.params.error && !!context.query), setListenInProgress(!1), setListenMutations([]), setError(context.params.error ? new Error(context.params.error) : void 0), setQueryResult(void 0), setQueryTime(void 0), setE2eTime(void 0), context.params.error)
1572
- return;
1573
- const urlQueryOpts = {
1574
- perspective: context.perspective ?? []
1575
- }, ctxClient = client.withConfig({
1576
- apiVersion: context.apiVersion,
1577
- dataset: context.dataset,
1578
- perspective: context.perspective
1579
- }), newUrl = ctxClient.getUrl(ctxClient.getDataUrl("query", encodeQueryString(context.query, context.params.parsed, urlQueryOpts)));
1580
- setUrl(newUrl);
1581
- const queryStart = Date.now();
1582
- querySubscriptionRef.current = ctxClient.observable.fetch(context.query, context.params.parsed, {
1583
- filterResponse: !1,
1584
- tag: "vision"
1585
- }).subscribe({
1586
- next: (res) => {
1587
- setQueryTime(res.ms), setE2eTime(Date.now() - queryStart), setQueryResult(res.result), setQueryInProgress(!1), setError(void 0);
1588
- },
1589
- error: (err) => {
1590
- setError(err), setQueryInProgress(!1);
1591
- }
1592
- });
1593
- }, [queryInProgress, query, dataset, params.parsed, t, perspective, perspectiveStack, customApiVersion, isValidApiVersion, apiVersion, localStorage2, cancelListenerSubscription, client, cancelQuerySubscription]), setPerspective = react.useCallback((newPerspective) => {
1594
- newPerspective !== void 0 && !isSupportedPerspective(newPerspective) || (setPerspectiveState(newPerspective), localStorage2.set("perspective", newPerspective), handleQueryExecution({
1595
- perspective: newPerspective
1596
- }));
1597
- }, [localStorage2, handleQueryExecution]), handleChangeDataset = react.useCallback((evt) => {
1598
- const newDataset = evt.target.value;
1599
- localStorage2.set("dataset", newDataset), setDataset(newDataset), handleQueryExecution({
1600
- dataset: newDataset
1601
- });
1602
- }, [localStorage2, handleQueryExecution]), handleChangeApiVersion = react.useCallback((evt_0) => {
1603
- const newApiVersion = evt_0.target.value;
1604
- if (newApiVersion?.toLowerCase() === "other") {
1605
- setCustomApiVersion("v"), customApiVersionElementRef.current?.focus();
1606
- return;
1607
- }
1608
- setApiVersion(newApiVersion), setCustomApiVersion(!1), localStorage2.set("apiVersion", newApiVersion), handleQueryExecution({
1609
- apiVersion: newApiVersion
1610
- });
1611
- }, [localStorage2, handleQueryExecution]), handleCustomApiVersionChange = react.useCallback((evt_1) => {
1612
- const newCustomApiVersion = evt_1.target.value || "";
1613
- setCustomApiVersion(newCustomApiVersion || "v"), validateApiVersion(newCustomApiVersion) && (setApiVersion(newCustomApiVersion), localStorage2.set("apiVersion", newCustomApiVersion), handleQueryExecution({
1614
- apiVersion: newCustomApiVersion
1615
- }));
1616
- }, [localStorage2, handleQueryExecution]), handleChangePerspective = react.useCallback((evt_2) => {
1617
- const newPerspective_0 = evt_2.target.value;
1618
- setPerspective(newPerspective_0 === "default" ? void 0 : newPerspective_0);
1619
- }, [setPerspective]), handleListenerEvent = react.useCallback((evt_3) => {
1620
- evt_3.type === "mutation" && setListenMutations((prevMutations) => prevMutations.length === 50 ? [evt_3, ...prevMutations.slice(0, 49)] : [evt_3, ...prevMutations]);
1621
- }, []), handleListenExecution = react.useCallback(() => {
1622
- if (listenInProgress) {
1623
- cancelListenerSubscription(), setListenInProgress(!1);
1624
- return;
1625
- }
1626
- const newUrl_0 = client.getDataUrl("listen", encodeQueryString(query, params.parsed, {})), shouldExecute = !params.error && query.trim().length > 0;
1627
- localStorage2.set("query", query), localStorage2.set("params", params.raw), cancelQuerySubscription(), setUrl(newUrl_0), setListenMutations([]), setQueryInProgress(!1), setQueryResult(void 0), setListenInProgress(shouldExecute), setError(params.error ? new Error(params.error) : void 0), setQueryTime(void 0), setE2eTime(void 0), shouldExecute && (listenSubscriptionRef.current = client.listen(query, params.parsed, {
1628
- events: ["mutation", "welcome"],
1629
- includeAllVersions: !0
1630
- }).subscribe({
1631
- next: handleListenerEvent,
1632
- error: (err_0) => {
1633
- setError(err_0), setListenInProgress(!1);
1634
- }
1635
- }));
1636
- }, [listenInProgress, params, query, localStorage2, cancelQuerySubscription, handleListenerEvent, cancelListenerSubscription, client]), handleParamsChange = react.useCallback((value) => {
1637
- setParams(value), localStorage2.set("params", value.raw);
1638
- }, [localStorage2]), getStateFromUrl = react.useCallback((data) => {
1639
- const match = data.match(sanityUrl);
1640
- if (!match)
1641
- return null;
1642
- const [, usedApiVersion, usedDataset, urlQuery] = match, qs = new URLSearchParams(urlQuery), parts = parseApiQueryString(qs);
1643
- if (!parts) return null;
1644
- let newApiVersion_0, newCustomApiVersion_0;
1645
- validateApiVersion(usedApiVersion) && (API_VERSIONS.includes(usedApiVersion) ? (newApiVersion_0 = usedApiVersion, newCustomApiVersion_0 = !1) : newCustomApiVersion_0 = usedApiVersion);
1646
- const newPerspective_1 = isSupportedPerspective(parts.options.perspective) && !isVirtualPerspective(parts.options.perspective) ? parts.options.perspective : void 0;
1647
- return newPerspective_1 && (!isSupportedPerspective(parts.options.perspective) || isVirtualPerspective(parts.options.perspective)) && toast.push({
1648
- closable: !0,
1649
- id: "vision-paste-unsupported-perspective",
1650
- status: "warning",
1651
- title: 'Perspective in pasted url is currently not supported. Falling back to "raw"'
1652
- }), {
1653
- query: parts.query,
1654
- params: parts.params,
1655
- rawParams: JSON.stringify(parts.params, null, 2),
1656
- dataset: datasets.includes(usedDataset) ? usedDataset : dataset,
1657
- apiVersion: newApiVersion_0 || apiVersion,
1658
- customApiVersion: newCustomApiVersion_0,
1659
- perspective: newPerspective_1 || perspective,
1660
- url: data
1661
- };
1662
- }, [datasets, dataset, apiVersion, perspective, toast]), setStateFromParsedUrl = react.useCallback((parsedUrlObj) => {
1663
- setDataset(parsedUrlObj.dataset), setQuery(parsedUrlObj.query), setParams({
1664
- parsed: parsedUrlObj.params,
1665
- raw: parsedUrlObj.rawParams,
1666
- valid: !0,
1667
- error: void 0
1668
- }), setApiVersion(parsedUrlObj.apiVersion), parsedUrlObj.customApiVersion && setCustomApiVersion(parsedUrlObj.customApiVersion), setPerspectiveState(parsedUrlObj.perspective), setUrl(parsedUrlObj.url), editorQueryRef.current?.resetEditorContent(parsedUrlObj.query), editorParamsRef.current?.resetEditorContent(parsedUrlObj.rawParams), localStorage2.merge({
1669
- query: parsedUrlObj.query,
1670
- params: parsedUrlObj.rawParams,
1671
- dataset: parsedUrlObj.dataset,
1672
- apiVersion: parsedUrlObj.customApiVersion || parsedUrlObj.apiVersion,
1673
- perspective: parsedUrlObj.perspective
1674
- }), handleQueryExecution(parsedUrlObj);
1675
- }, [localStorage2, handleQueryExecution]), handlePaste = react.useCallback((evt_4) => {
1676
- if (!evt_4.clipboardData)
1677
- return;
1678
- const data_0 = evt_4.clipboardData.getData("text/plain");
1679
- evt_4.preventDefault();
1680
- const urlState = getStateFromUrl(data_0);
1681
- urlState && (setStateFromParsedUrl(urlState), toast.push({
1682
- closable: !0,
1683
- id: "vision-paste",
1684
- status: "info",
1685
- title: "Parsed URL to query"
1686
- }));
1687
- }, [getStateFromUrl, setStateFromParsedUrl, toast]), handleKeyDown = react.useCallback((event) => {
1688
- const isWithinRoot = visionRootRef.current && nodeContains(visionRootRef.current, event.target);
1689
- isRunHotkey(event) && isWithinRoot && params.valid && (handleQueryExecution(), event.preventDefault(), event.stopPropagation());
1690
- }, [params.valid, handleQueryExecution]);
1691
- react.useEffect(() => (window.document.addEventListener("paste", handlePaste), window.document.addEventListener("keydown", handleKeyDown), () => {
1692
- window.document.removeEventListener("paste", handlePaste), window.document.removeEventListener("keydown", handleKeyDown);
1693
- }), [handleKeyDown, handlePaste]), react.useEffect(() => () => {
1694
- cancelQuerySubscription(), cancelListenerSubscription();
1695
- }, [cancelQuerySubscription, cancelListenerSubscription]);
1696
- const handleStudioPerspectiveChange = useEffectEvent.useEffectEvent((stack) => {
1697
- stack.length > 0 && setPerspective("pinnedRelease");
1698
- });
1699
- react.useEffect(() => {
1700
- handleStudioPerspectiveChange(perspectiveStack);
1701
- }, [perspectiveStack]);
1702
- const generateUrl = react.useCallback((queryString, queryParams) => {
1703
- const urlQueryOpts_0 = {
1704
- perspective: getActivePerspective({
1705
- visionPerspective: perspective,
1706
- perspectiveStack
1707
- }) ?? []
1708
- };
1709
- return client.getUrl(client.getDataUrl("query", encodeQueryString(queryString, queryParams, urlQueryOpts_0)));
1710
- }, [client, perspective, perspectiveStack]);
1711
- return /* @__PURE__ */ jsxRuntime.jsxs(Root, { direction: "column", height: "fill", ref: visionRootRef, sizing: "border", overflow: "hidden", "data-testid": "vision-root", children: [
1712
- /* @__PURE__ */ jsxRuntime.jsx(VisionGuiHeader, { apiVersion, customApiVersion, dataset, datasets, onChangeDataset: handleChangeDataset, onChangeApiVersion: handleChangeApiVersion, customApiVersionElementRef, onCustomApiVersionChange: handleCustomApiVersionChange, isValidApiVersion, onChangePerspective: handleChangePerspective, url, perspective }),
1713
- /* @__PURE__ */ jsxRuntime.jsx(SplitpaneContainer, { flex: "auto", children: /* @__PURE__ */ jsxRuntime.jsxs(reactSplitPane.SplitPane, { minSize: 800, defaultSize: window.innerWidth - 275, size: isQueryRecallCollapsed ? window.innerWidth : window.innerWidth - 275, maxSize: -225, primary: "first", children: [
1714
- /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { height: "stretch", flex: 1, children: /* @__PURE__ */ jsxRuntime.jsxs(
1715
- reactSplitPane.SplitPane,
1716
- {
1717
- className: "sidebarPanes",
1718
- split: isNarrowBreakpoint ? "vertical" : "horizontal",
1719
- minSize: 300,
1720
- children: [
1721
- /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { height: "stretch", flex: 1, children: /* @__PURE__ */ jsxRuntime.jsxs(reactSplitPane.SplitPane, { className: "sidebarPanes", split: "horizontal", defaultSize: isNarrowBreakpoint ? paneSizeOptions.defaultSize : paneSizeOptions.minSize, size: paneSizeOptions.size, allowResize: paneSizeOptions.allowResize, minSize: isNarrowBreakpoint ? paneSizeOptions.minSize : 100, maxSize: paneSizeOptions.maxSize, primary: "first", children: [
1722
- /* @__PURE__ */ jsxRuntime.jsx(InputContainer, { display: "flex", "data-testid": "vision-query-editor", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Box, { flex: 1, children: [
1723
- /* @__PURE__ */ jsxRuntime.jsx(InputBackgroundContainerLeft, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, { children: /* @__PURE__ */ jsxRuntime.jsx(StyledLabel, { muted: !0, children: t("query.label") }) }) }),
1724
- /* @__PURE__ */ jsxRuntime.jsx(VisionCodeMirror, { initialValue: query, onChange: setQuery, ref: editorQueryRef })
1725
- ] }) }),
1726
- /* @__PURE__ */ jsxRuntime.jsxs(InputContainer, { display: "flex", children: [
1727
- /* @__PURE__ */ jsxRuntime.jsx(ParamsEditor, { value: params.raw, onChange: handleParamsChange, paramsError: params.error, hasValidParams: params.valid, editorRef: editorParamsRef }),
1728
- /* @__PURE__ */ jsxRuntime.jsx(VisionGuiControls, { hasValidParams: params.valid, queryInProgress, listenInProgress, onQueryExecution: handleQueryExecution, onListenExecution: handleListenExecution })
1729
- ] })
1730
- ] }) }),
1731
- /* @__PURE__ */ jsxRuntime.jsx(VisionGuiResult, { error, queryInProgress, queryResult, listenInProgress, listenMutations, dataset, queryTime, e2eTime })
1732
- ]
1733
- }
1734
- ) }),
1735
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Box, { style: {
1736
- position: "relative",
1737
- height: "100%"
1738
- }, children: [
1739
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { mode: "ghost", padding: 2, style: {
1740
- position: "absolute",
1741
- left: -32,
1742
- top: "50%",
1743
- transform: "translateY(-50%)",
1744
- zIndex: 100,
1745
- pointerEvents: "auto"
1746
- }, onClick: () => setIsQueryRecallCollapsed(!isQueryRecallCollapsed), children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: {
1747
- display: "flex",
1748
- alignItems: "center",
1749
- height: "100%"
1750
- }, children: isQueryRecallCollapsed ? /* @__PURE__ */ jsxRuntime.jsx(icons.ChevronLeftIcon, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.ChevronRightIcon, {}) }) }),
1751
- /* @__PURE__ */ jsxRuntime.jsx(QueryRecall, { url, getStateFromUrl, setStateFromParsedUrl, currentQuery: query, currentParams: params.parsed || {}, generateUrl })
1752
- ] })
1753
- ] }) })
1754
- ] });
1755
- }
1756
- function useDatasets(t0) {
1757
- const $ = reactCompilerRuntime.c(7), {
1758
- client,
1759
- datasets: configDatasets
1760
- } = t0;
1761
- let t1;
1762
- bb0: {
1763
- if (Array.isArray(configDatasets)) {
1764
- let t22;
1765
- $[0] !== configDatasets ? (t22 = rxjs.of(configDatasets), $[0] = configDatasets, $[1] = t22) : t22 = $[1], t1 = t22;
1766
- break bb0;
1767
- }
1768
- let t2;
1769
- if ($[2] !== client.observable.datasets || $[3] !== configDatasets) {
1770
- let t3;
1771
- $[5] !== configDatasets ? (t3 = (result) => typeof configDatasets == "function" ? configDatasets(result).map(_temp) : result.map(_temp2), $[5] = configDatasets, $[6] = t3) : t3 = $[6], t2 = client.observable.datasets.list().pipe(rxjs.map(t3), rxjs.catchError(_temp3)), $[2] = client.observable.datasets, $[3] = configDatasets, $[4] = t2;
1772
- } else
1773
- t2 = $[4];
1774
- t1 = t2;
1775
- }
1776
- return reactRx.useObservable(t1, null);
1777
- }
1778
- function _temp3(err) {
1779
- return rxjs.of(err);
1780
- }
1781
- function _temp2(ds) {
1782
- return ds.name;
1783
- }
1784
- function _temp(d) {
1785
- return d.name;
1786
- }
1787
- function VisionContainer(props) {
1788
- const $ = reactCompilerRuntime.c(19);
1789
- let t0;
1790
- $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = {
1791
- apiVersion: "v2025-06-27"
1792
- }, $[0] = t0) : t0 = $[0];
1793
- const datasetsClient = sanity.useClient(t0);
1794
- let t1;
1795
- $[1] !== datasetsClient || $[2] !== props.config.datasets ? (t1 = {
1796
- client: datasetsClient,
1797
- datasets: props.config.datasets
1798
- }, $[1] = datasetsClient, $[2] = props.config.datasets, $[3] = t1) : t1 = $[3];
1799
- const loadedDatasets = useDatasets(t1);
1800
- if (!loadedDatasets) {
1801
- let t22;
1802
- return $[4] === Symbol.for("react.memo_cache_sentinel") ? (t22 = /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, { align: "center", height: "fill", justify: "center", children: /* @__PURE__ */ jsxRuntime.jsx(DelayedSpinner, {}) }), $[4] = t22) : t22 = $[4], t22;
1803
- }
1804
- let t2;
1805
- $[5] !== loadedDatasets || $[6] !== props.client ? (t2 = loadedDatasets instanceof Error ? [props.client.config().dataset || "production"] : loadedDatasets, $[5] = loadedDatasets, $[6] = props.client, $[7] = t2) : t2 = $[7];
1806
- const datasets = t2;
1807
- let t3;
1808
- $[8] !== props.client ? (t3 = props.client.config(), $[8] = props.client, $[9] = t3) : t3 = $[9];
1809
- const projectId = t3.projectId;
1810
- let t4;
1811
- $[10] !== datasets || $[11] !== props.client || $[12] !== props.config.defaultDataset ? (t4 = props.config.defaultDataset || props.client.config().dataset || datasets[0], $[10] = datasets, $[11] = props.client, $[12] = props.config.defaultDataset, $[13] = t4) : t4 = $[13];
1812
- const defaultDataset = t4;
1813
- let t5;
1814
- return $[14] !== datasets || $[15] !== defaultDataset || $[16] !== projectId || $[17] !== props ? (t5 = /* @__PURE__ */ jsxRuntime.jsx(VisionGui, { ...props, datasets, projectId, defaultDataset }, projectId), $[14] = datasets, $[15] = defaultDataset, $[16] = projectId, $[17] = props, $[18] = t5) : t5 = $[18], t5;
1815
- }
1816
- class VisionErrorBoundary extends react.Component {
1817
- constructor(props) {
1818
- super(props), this.state = {
1819
- error: null,
1820
- numRetries: 0
1821
- };
1822
- }
1823
- static getDerivedStateFromError(error) {
1824
- return {
1825
- error: error instanceof Error ? error.message : `${error}`
1826
- };
1827
- }
1828
- handleRetryRender = () => this.setState((prev) => ({
1829
- error: null,
1830
- numRetries: prev.numRetries + 1
1831
- }));
1832
- handleRetryWithCacheClear = () => {
1833
- clearLocalStorage(), this.handleRetryRender();
1834
- };
1835
- render() {
1836
- if (!this.state.error)
1837
- return this.props.children;
1838
- const message = this.state.error, withCacheClear = this.state.numRetries > 0;
1839
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { height: "fill", overflow: "auto", paddingY: [4, 5, 6, 7], paddingX: 4, sizing: "border", tone: "critical", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { width: 3, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 4, children: [
1840
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { onClick: withCacheClear ? this.handleRetryWithCacheClear : this.handleRetryRender, text: withCacheClear ? "Clear cache and retry" : "Retry", tone: "default" }) }),
1841
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "An error occurred" }),
1842
- /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { border: !0, radius: 2, overflow: "auto", padding: 4, tone: "inherit", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Stack, { space: 4, children: message && /* @__PURE__ */ jsxRuntime.jsx(ui.Code, { size: 1, children: /* @__PURE__ */ jsxRuntime.jsxs("strong", { children: [
1843
- "Error: ",
1844
- message
1845
- ] }) }) }) })
1846
- ] }) }) });
1847
- }
1848
- }
1849
- function SanityVision(props) {
1850
- const $ = reactCompilerRuntime.c(6);
1851
- let t0;
1852
- $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = {
1853
- apiVersion: "1"
1854
- }, $[0] = t0) : t0 = $[0];
1855
- const client = sanity.useClient(t0);
1856
- let t1;
1857
- $[1] !== props.tool.options ? (t1 = {
1858
- defaultApiVersion: DEFAULT_API_VERSION,
1859
- ...props.tool.options
1860
- }, $[1] = props.tool.options, $[2] = t1) : t1 = $[2];
1861
- const config = t1;
1862
- let t2;
1863
- return $[3] !== client || $[4] !== config ? (t2 = /* @__PURE__ */ jsxRuntime.jsx(VisionErrorBoundary, { children: /* @__PURE__ */ jsxRuntime.jsx(VisionContainer, { client, config }) }), $[3] = client, $[4] = config, $[5] = t2) : t2 = $[5], t2;
1864
- }
1865
- exports.default = SanityVision;
1866
- //# sourceMappingURL=SanityVision.js.map