@scalar/api-client 3.19.1 → 3.19.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/style.css +26 -26
  3. package/dist/v2/blocks/operation-block/OperationBlock.vue.d.ts +8 -1
  4. package/dist/v2/blocks/operation-block/OperationBlock.vue.d.ts.map +1 -1
  5. package/dist/v2/blocks/operation-block/OperationBlock.vue.js.map +1 -1
  6. package/dist/v2/blocks/operation-block/OperationBlock.vue.script.js +38 -3
  7. package/dist/v2/blocks/operation-block/OperationBlock.vue.script.js.map +1 -1
  8. package/dist/v2/blocks/operation-block/components/Header.vue.d.ts +2 -0
  9. package/dist/v2/blocks/operation-block/components/Header.vue.d.ts.map +1 -1
  10. package/dist/v2/blocks/operation-block/components/Header.vue.js +1 -1
  11. package/dist/v2/blocks/operation-block/components/Header.vue.js.map +1 -1
  12. package/dist/v2/blocks/operation-block/components/Header.vue.script.js +5 -2
  13. package/dist/v2/blocks/operation-block/components/Header.vue.script.js.map +1 -1
  14. package/dist/v2/blocks/request-block/RequestBlock.vue.script.js.map +1 -1
  15. package/dist/v2/blocks/request-block/helpers/create-parameter-rows.d.ts.map +1 -1
  16. package/dist/v2/blocks/request-block/helpers/create-parameter-rows.js +1 -1
  17. package/dist/v2/blocks/request-block/helpers/create-parameter-rows.js.map +1 -1
  18. package/dist/v2/blocks/response-block/ResponseBlock.vue.d.ts +2 -0
  19. package/dist/v2/blocks/response-block/ResponseBlock.vue.d.ts.map +1 -1
  20. package/dist/v2/blocks/response-block/ResponseBlock.vue.js +1 -1
  21. package/dist/v2/blocks/response-block/ResponseBlock.vue.js.map +1 -1
  22. package/dist/v2/blocks/response-block/ResponseBlock.vue.script.js +3 -0
  23. package/dist/v2/blocks/response-block/ResponseBlock.vue.script.js.map +1 -1
  24. package/dist/v2/blocks/response-block/components/ResponseEmpty.vue.d.ts +2 -0
  25. package/dist/v2/blocks/response-block/components/ResponseEmpty.vue.d.ts.map +1 -1
  26. package/dist/v2/blocks/response-block/components/ResponseEmpty.vue.js +1 -1
  27. package/dist/v2/blocks/response-block/components/ResponseEmpty.vue.js.map +1 -1
  28. package/dist/v2/blocks/response-block/components/ResponseEmpty.vue.script.js +4 -1
  29. package/dist/v2/blocks/response-block/components/ResponseEmpty.vue.script.js.map +1 -1
  30. package/dist/v2/blocks/scalar-address-bar-block/components/AddressBar.vue.d.ts +2 -0
  31. package/dist/v2/blocks/scalar-address-bar-block/components/AddressBar.vue.d.ts.map +1 -1
  32. package/dist/v2/blocks/scalar-address-bar-block/components/AddressBar.vue.js +1 -1
  33. package/dist/v2/blocks/scalar-address-bar-block/components/AddressBar.vue.js.map +1 -1
  34. package/dist/v2/blocks/scalar-address-bar-block/components/AddressBar.vue.script.js +3 -2
  35. package/dist/v2/blocks/scalar-address-bar-block/components/AddressBar.vue.script.js.map +1 -1
  36. package/dist/v2/blocks/scalar-auth-selector-block/components/AuthSelector.vue.script.js.map +1 -1
  37. package/dist/v2/constants.js +1 -1
  38. package/dist/v2/features/modal/Modal.vue.d.ts.map +1 -1
  39. package/dist/v2/features/modal/Modal.vue.js.map +1 -1
  40. package/dist/v2/features/modal/Modal.vue.script.js +2 -0
  41. package/dist/v2/features/modal/Modal.vue.script.js.map +1 -1
  42. package/dist/v2/features/operation/Operation.vue.d.ts +2 -0
  43. package/dist/v2/features/operation/Operation.vue.d.ts.map +1 -1
  44. package/dist/v2/features/operation/Operation.vue.js.map +1 -1
  45. package/dist/v2/features/operation/Operation.vue.script.js +29 -7
  46. package/dist/v2/features/operation/Operation.vue.script.js.map +1 -1
  47. package/dist/vue-styles.css +26 -26
  48. package/package.json +8 -8
@@ -41,6 +41,7 @@ var _hoisted_12 = { class: "sr-only" };
41
41
  var AddressBar_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
42
42
  name: "AddressBar",
43
43
  props: {
44
+ executionDisabled: { type: Boolean },
44
45
  path: {},
45
46
  method: {},
46
47
  isWebhook: {
@@ -357,7 +358,7 @@ var AddressBar_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
357
358
  ref: sendButtonRef,
358
359
  class: "relative hidden h-auto shrink-0 overflow-hidden py-1 pr-2.5 pl-2 font-bold @3xl:flex",
359
360
  "data-addressbar-action": "send",
360
- disabled: unref(isLoading),
361
+ disabled: unref(isLoading) || __props.executionDisabled,
361
362
  onClick: _cache[4] || (_cache[4] = ($event) => emit("execute"))
362
363
  }, {
363
364
  default: withCtx(() => [createElementVNode("span", _hoisted_8, [createVNode(unref(ScalarIcon), {
@@ -389,7 +390,7 @@ var AddressBar_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
389
390
  ref: mobileSendButtonRef,
390
391
  class: "relative h-auto shrink-0 overflow-hidden py-1 pr-2.5 pl-2 font-bold",
391
392
  "data-addressbar-action": "send",
392
- disabled: unref(isLoading),
393
+ disabled: unref(isLoading) || __props.executionDisabled,
393
394
  onClick: _cache[5] || (_cache[5] = ($event) => emit("execute"))
394
395
  }, {
395
396
  default: withCtx(() => [createElementVNode("span", _hoisted_11, [createVNode(unref(ScalarIcon), {
@@ -1 +1 @@
1
- {"version":3,"file":"AddressBar.vue.script.js","names":[],"sources":["../../../../../src/v2/blocks/scalar-address-bar-block/components/AddressBar.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * AddressBar component\n * This component is used to display the address bar for the operation block\n * It is used to display the path, method, server, and history for the operation\n */\nexport default {\n name: 'AddressBar',\n}\nexport type AddressBarProps = {\n /** Current request path */\n path: string\n /** Current request method */\n method: HttpMethodType\n /** Whether the request target belongs to an OpenAPI webhook. */\n isWebhook?: boolean\n /** Openapi document slug */\n documentSlug: string\n /** Currently selected example key for the current operation */\n exampleKey: string\n /** Currently selected server */\n server: ServerObject | null\n /** Server list available for operation/document */\n servers: ServerObject[]\n /** List of request history */\n history: History[]\n /** Client layout */\n layout: ClientLayout\n /** Event bus */\n eventBus: WorkspaceEventBus\n /** Environment */\n environment: XScalarEnvironment\n /** Meta information for the server */\n serverMeta: ServerMeta\n}\n</script>\n<script setup lang=\"ts\">\nimport { ScalarButton } from '@scalar/components/button'\nimport { ScalarIcon } from '@scalar/components/icon'\nimport { ScalarWrappingText } from '@scalar/components/wrapping-text'\nimport { getSelector } from '@scalar/helpers/dom/get-selector'\nimport { REQUEST_METHODS } from '@scalar/helpers/http/http-info'\nimport type { HttpMethod as HttpMethodType } from '@scalar/helpers/http/http-methods'\nimport { extractServerFromPath } from '@scalar/helpers/url/extract-server-from-path'\nimport { ScalarIconCopy, ScalarIconWarningCircle } from '@scalar/icons'\nimport { EditorView } from '@scalar/use-codemirror'\nimport type {\n ApiReferenceEvents,\n ServerMeta,\n WorkspaceEventBus,\n} from '@scalar/workspace-store/events'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport type { ServerObject } from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document'\nimport {\n computed,\n nextTick,\n onBeforeUnmount,\n onMounted,\n ref,\n useId,\n useTemplateRef,\n watch,\n} from 'vue'\n\nimport { HttpMethod } from '@/components/HttpMethod'\nimport { getOperationExampleKey } from '@/v2/blocks/operation-block/helpers/response-cache'\nimport { isPlaceholderPath } from '@/v2/blocks/scalar-address-bar-block/helpers/is-placeholder-path'\nimport { refocusBlurTarget } from '@/v2/blocks/scalar-address-bar-block/helpers/refocus-blur-target'\nimport { useLoadingAnimation } from '@/v2/blocks/scalar-address-bar-block/hooks/use-loading-animation'\nimport { usePathMasking } from '@/v2/blocks/scalar-address-bar-block/hooks/use-path-masking'\nimport { CodeInput } from '@/v2/components/code-input'\nimport { ServerDropdown } from '@/v2/components/server'\nimport type { ClientLayout } from '@/v2/types/layout'\n\nimport AddressBarHistory, { type History } from './AddressBarHistory.vue'\n\nconst {\n path,\n method,\n layout,\n eventBus,\n exampleKey,\n documentSlug,\n server,\n servers,\n environment,\n serverMeta,\n isWebhook = false,\n} = defineProps<AddressBarProps>()\n\nconst emit = defineEmits<{\n /** Execute the current operation example */\n (e: 'execute'): void\n /** Select a request history item by index */\n (e: 'select:history:item', payload: { index: number }): void\n /** Update the full destination URL used to deliver a webhook. */\n (e: 'update:webhook-url', url: string): void\n}>()\n\n// ───────────────────────────────────────────────────────────────────\n// Template refs & reactive state\n// ───────────────────────────────────────────────────────────────────\n\nconst id = useId()\nconst sendButtonRef = useTemplateRef('sendButtonRef')\nconst mobileSendButtonRef = useTemplateRef('mobileSendButtonRef')\nconst addressBarRef = useTemplateRef('addressBarRef')\n\nconst { percentage, startLoading, stopLoading, isLoading } =\n useLoadingAnimation()\n\nconst pathConflict = ref<string | null>(null)\nconst methodConflict = ref<HttpMethodType | null>(null)\nconst tabbedOut = ref(false)\nconst isServerDropdownOpen = ref(false)\nconst isHistoryDropdownOpen = ref(false)\n\n// ───────────────────────────────────────────────────────────────────\n// Derived state\n// ───────────────────────────────────────────────────────────────────\n\n/** Keeps the cursor visible past the fade-right overlay while typing */\nconst addressBarScrollMargins = EditorView.scrollMargins.of(() => ({\n right: 24,\n}))\n\n/** Animated background transform for the loading indicator */\nconst style = computed(() => ({\n backgroundColor: `color-mix(in srgb, transparent 90%, ${REQUEST_METHODS[method].colorVar})`,\n transform: `translate3d(-${percentage.value}%,0,0)`,\n}))\n\n/** Whether there is a path or method conflict */\nconst hasConflict = computed(() => methodConflict.value || pathConflict.value)\n\n/**\n * Placeholder for the path field.\n *\n * Webhooks have no server to prefix the path, so the field doubles as the full\n * destination URL. Hint that a complete URL (including the host) is expected,\n * rather than a bare path.\n */\nconst pathPlaceholder = computed(() => {\n if (server) {\n return ''\n }\n return isWebhook\n ? 'Enter the full webhook URL, e.g. https://example.com/hook'\n : 'Enter a URL'\n})\n\n/** Whether either dropdown (server or history) is open */\nconst isDropdownOpen = computed(\n () => isServerDropdownOpen.value || isHistoryDropdownOpen.value,\n)\n\n/** Uniquely identifies the currently selected operation + example */\nconst uniqueKey = computed(() =>\n getOperationExampleKey(method, path, exampleKey, documentSlug),\n)\n\n/** Clear conflict state when switching to a different operation */\nwatch(uniqueKey, () => {\n pathConflict.value = null\n methodConflict.value = null\n})\n\n// ───────────────────────────────────────────────────────────────────\n// Focus helpers\n// ───────────────────────────────────────────────────────────────────\n\nconst handleFocusSendButton = (): void => {\n const desktop = sendButtonRef.value?.$el\n const mobile = mobileSendButtonRef.value?.$el\n\n // Focus whichever send button is currently visible\n if (desktop && desktop.offsetParent !== null) {\n desktop.focus()\n } else {\n mobile?.focus()\n }\n}\n\nconst handleFocusAddressBar = (\n payload: ApiReferenceEvents['ui:focus:address-bar'],\n): void => {\n // On non-desktop layouts, if already focused we let the browser handle the\n // native behavior (e.g. selecting the browser's own address bar).\n if (addressBarRef.value?.isFocused && layout !== 'desktop') {\n return\n }\n\n addressBarRef.value?.focus('end')\n\n if (payload && 'clear' in payload && payload.clear) {\n addressBarRef.value?.setCodeMirrorContent('')\n }\n\n if (payload && 'event' in payload) {\n payload.event.preventDefault()\n }\n}\n\n// ───────────────────────────────────────────────────────────────────\n// Path masking\n//\n// Drafts on `/` and auto-generated `/_scalar_temp...` paths are internal\n// placeholders — the address bar focuses and clears on mount and on\n// navigation so the user sees a blank prompt instead of the internal\n// path. The deferred mask only clears when CodeMirror still contains that\n// placeholder path, so a user edit that lands before the frame is preserved.\n// ───────────────────────────────────────────────────────────────────\n\nusePathMasking({\n isReady: () => addressBarRef.value?.codeMirror,\n operationKey: () => uniqueKey.value,\n shouldMask: () => isPlaceholderPath(path, documentSlug),\n // Defer to the next frame so focus() runs after click-handler side\n // effects that move focus (e.g. a dropdown refocusing its trigger),\n // which would otherwise blur our input and emit a spurious path\n // update against the now-empty value.\n onMask: () =>\n requestAnimationFrame(() => {\n const editorContent =\n addressBarRef.value?.codeMirror?.state.doc.toString()\n\n if (editorContent && editorContent !== path) {\n return\n }\n\n handleFocusAddressBar({ clear: true })\n }),\n})\n\n// ───────────────────────────────────────────────────────────────────\n// Server extraction\n// ───────────────────────────────────────────────────────────────────\n\n/** If the path contains a server URL, extract it and select or add that server */\nconst extractAndSelectServer = (targetPath: string): string => {\n const extracted = extractServerFromPath(targetPath)\n if (!extracted) {\n return targetPath\n }\n\n const [url, remainingPath] = extracted\n\n // Server is already selected — nothing to do\n if (url === server?.url) {\n return remainingPath\n }\n\n const matchingServer = servers.find((s) => s.url === url)\n if (matchingServer) {\n eventBus.emit('server:update:selected', { url, meta: serverMeta })\n } else {\n eventBus.emit('server:add:server', {\n url,\n select: true,\n meta: { type: 'operation', path, method },\n })\n }\n\n return remainingPath\n}\n\n// ───────────────────────────────────────────────────────────────────\n// Path / method updates\n// ───────────────────────────────────────────────────────────────────\n\nconst normalizePath = (value: string): string =>\n value.startsWith('/') ? value : `/${value}`\n\n/** Emit a path/method update and reconcile conflicts + cursor state on the result */\nconst emitPathMethodUpdate = (\n targetMethod: HttpMethodType,\n targetPath: string,\n blurTargetSelector: string | null = null,\n): void => {\n if (isWebhook) {\n // A webhook has no OpenAPI server, so the field holds the full destination\n // URL. Keep exactly what the user entered — do not split it into an invisible\n // server plus a leftover path, and do not force a leading slash. That split\n // is what made a typed URL collapse to a stray \"/\" on blur.\n const webhookUrl = targetPath.trim()\n addressBarRef.value?.setCodeMirrorContent(webhookUrl)\n emit('update:webhook-url', webhookUrl)\n methodConflict.value = null\n pathConflict.value = null\n nextTick(() => refocusBlurTarget(blurTargetSelector))\n return\n }\n\n const extractedPath = extractAndSelectServer(targetPath)\n const normalizedPath = normalizePath(extractedPath)\n\n // Keep CodeMirror in sync so a conflict does not leave a stale value on screen\n addressBarRef.value?.setCodeMirrorContent(normalizedPath)\n\n eventBus.emit('operation:update:pathMethod', {\n meta: { method, path },\n blurTargetSelector,\n payload: { method: targetMethod, path: normalizedPath },\n callback: (status, returnedSelector) => {\n if (status === 'success' || status === 'no-change') {\n methodConflict.value = null\n pathConflict.value = null\n } else if (status === 'conflict') {\n if (targetMethod !== method) {\n methodConflict.value = targetMethod\n }\n if (normalizedPath !== path) {\n pathConflict.value = normalizedPath\n }\n\n return\n }\n\n // Edge case: pasting a full URL extracts the server but leaves the path\n // unchanged. CodeMirror still shows the full URL, so force it back to\n // just the path.\n const mirrorContent = addressBarRef.value?.codeMirrorRef?.textContent\n if (\n status === 'no-change' &&\n mirrorContent &&\n mirrorContent !== extractedPath\n ) {\n addressBarRef.value?.setCodeMirrorContent(extractedPath)\n }\n\n nextTick(() => refocusBlurTarget(returnedSelector))\n },\n })\n}\n\n/** Change the operation's method, preferring the conflicting path if present */\nconst handleMethodChange = (newMethod: HttpMethodType): void =>\n emitPathMethodUpdate(newMethod, pathConflict.value ?? path)\n\n/**\n * Save the path on blur and replay the click that caused the blur (so e.g. a\n * click on the Send button still fires after the async update resolves).\n *\n * Tab-outs do not replay — tabbing to a button should not trigger its click\n * (`tabbedOut` is set on `@keydown.tab`).\n *\n * Programmatic focus moves also do not replay. On first navigation into a\n * draft operation, `usePathMasking` focuses and clears the address bar while\n * `ScalarSidebarNestedItems` focuses the drilled-in Back button in\n * `nextTick`. That steals focus from CodeMirror, fires blur with a\n * `relatedTarget` (the Back button), and without a guard we would treat it\n * like a user click: capture the selector, then `refocusBlurTarget` would\n * synthesize `.click()` on Back and navigate away.\n *\n * `FocusEvent.sourceCapabilities` is null when no input device caused the\n * focus change (e.g. `element.focus()`). A real pointer click sets it on the\n * blur that precedes the click, so we still replay Send and other buttons.\n */\nconst handlePathBlur = (newPath: string, event: FocusEvent): void => {\n const relatedTarget =\n event.relatedTarget instanceof Element ? event.relatedTarget : null\n const blurTargetSelector =\n tabbedOut.value ||\n ('sourceCapabilities' in event && event.sourceCapabilities === null)\n ? null\n : getSelector(relatedTarget)\n tabbedOut.value = false\n\n emitPathMethodUpdate(\n methodConflict.value ?? method,\n newPath,\n blurTargetSelector,\n )\n}\n\n/** Save the path on Enter and trigger the Send button after the update resolves */\nconst handlePathSubmit = (\n newPath: string,\n event: KeyboardEvent | FocusEvent,\n): void => {\n // Prevent the global hotkey listener from also handling this Enter press\n event.stopPropagation()\n\n emitPathMethodUpdate(\n methodConflict.value ?? method,\n newPath,\n '[data-addressbar-action=\"send\"]',\n )\n}\n\n/** Unset the server when backspace is pressed on an empty path */\nconst handlePathBackspace = (event: KeyboardEvent): void => {\n if (event.target instanceof HTMLElement && event.target.innerText === '\\n') {\n // A webhook has no server to unset; its full URL lives in the field itself.\n if (isWebhook) {\n return\n }\n eventBus.emit('server:update:selected', { url: '', meta: serverMeta })\n }\n}\n\nconst handleServerSelect = (\n payload: ApiReferenceEvents['server:update:selected'],\n): void => {\n eventBus.emit('server:update:selected', payload)\n}\n\nconst handleServerVariable = (\n payload: ApiReferenceEvents['server:update:variables'],\n): void => {\n eventBus.emit('server:update:variables', payload)\n}\n\n/** Address bar copy is handled in OperationBlock (same URL as Send). */\nconst requestCopyUrl = (): void => {\n eventBus.emit('copy-url:address-bar')\n}\n\n// ───────────────────────────────────────────────────────────────────\n// Navigation\n// ───────────────────────────────────────────────────────────────────\n\nconst navigateToServersPage = (): void => {\n if (serverMeta.type === 'operation') {\n eventBus.emit('ui:navigate', {\n page: 'operation',\n path: 'servers',\n operationPath: serverMeta.path,\n method: serverMeta.method,\n })\n return\n }\n\n eventBus.emit('ui:navigate', { page: 'document', path: 'servers' })\n}\n\n// ───────────────────────────────────────────────────────────────────\n// Lifecycle\n// ───────────────────────────────────────────────────────────────────\n\nconst unsubscribes: Array<() => void> = []\n\nonMounted(() => {\n unsubscribes.push(\n eventBus.on('ui:focus:address-bar', handleFocusAddressBar),\n eventBus.on('ui:focus:send-button', handleFocusSendButton),\n eventBus.on('hooks:on:request:sent', startLoading),\n eventBus.on('hooks:on:request:complete', stopLoading),\n )\n})\n\nonBeforeUnmount(() => {\n for (const unsubscribe of unsubscribes) {\n unsubscribe()\n }\n\n // Prevents the loading animation from continuing after unmount\n stopLoading()\n})\n\ndefineExpose({\n methodConflict,\n pathConflict,\n})\n</script>\n<template>\n <!--\n Address bar.\n\n The wide-container layout matches the original single-row bar:\n `[Method | URL | Copy | History | Send]`. When the surrounding\n `@container` drops below `@3xl` the bar collapses to\n `[URL | History]` and a second row appears beneath it with a\n duplicate `Method`, `Copy`, and `Send` so the URL gets the full\n container width while every action stays on the same line as the\n send button.\n -->\n <div\n class=\"order-last flex h-auto w-full max-w-3xl grow-3 flex-wrap items-stretch [--scalar-address-bar-height:32px] @3xl:order-0 @3xl:flex-nowrap\">\n <!-- Address Bar -->\n <div\n :id=\"id\"\n class=\"address-bar-bg-states text-xxs group relative flex h-(--scalar-address-bar-height) w-full flex-1 flex-row items-stretch rounded-lg p-0.75\"\n :class=\"{\n 'outline-c-danger outline': hasConflict,\n 'rounded-b-none': isDropdownOpen,\n }\">\n <div\n class=\"pointer-events-none absolute top-0 left-0 block h-full w-full overflow-hidden rounded-lg border\"\n :class=\"{\n 'rounded-b-none': isDropdownOpen,\n }\">\n <div\n class=\"absolute top-0 left-0 h-full w-full\"\n :style />\n </div>\n\n <!--\n Method, Copy, and Send are hidden in mobile mode (container\n narrower than `@3xl`) and the duplicate buttons in the trailing\n mobile actions row take over at that point.\n -->\n <div class=\"hidden @3xl:flex\">\n <HttpMethod\n :isEditable=\"layout !== 'modal' && !isWebhook\"\n isSquare\n :method=\"methodConflict ?? method\"\n teleport\n @change=\"handleMethodChange\" />\n </div>\n\n <div\n class=\"scroll-timeline-x scroll-timeline-x-hidden relative flex w-full bg-blend-normal\">\n <!-- Servers -->\n <ServerDropdown\n v-if=\"servers.length\"\n :layout=\"isWebhook ? 'modal' : layout\"\n :meta=\"serverMeta\"\n :server=\"server\"\n :servers=\"servers\"\n :target=\"id\"\n @update:open=\"(value) => (isServerDropdownOpen = value)\"\n @update:selectedServer=\"handleServerSelect\"\n @update:servers=\"navigateToServersPage\"\n @update:variable=\"handleServerVariable\" />\n\n <!-- Path + URL + env vars -->\n <CodeInput\n ref=\"addressBarRef\"\n alwaysEmitChange\n aria-label=\"Path\"\n class=\"ml-1 min-w-fit pl-px outline-none\"\n disableCloseBrackets\n :disabled=\"layout === 'modal' && !isWebhook\"\n disableEnter\n disableTabIndent\n :emitOnBlur=\"false\"\n :environment=\"environment\"\n :extensions=\"[addressBarScrollMargins]\"\n importCurl\n :layout=\"layout\"\n :modelValue=\"path\"\n :placeholder=\"pathPlaceholder\"\n server\n @blur=\"handlePathBlur\"\n @keydown.delete=\"handlePathBackspace\"\n @keydown.tab=\"tabbedOut = true\"\n @submit=\"handlePathSubmit\" />\n </div>\n\n <!-- Copy url button -->\n <ScalarButton\n class=\"hover:bg-b-3 mx-1 hidden @3xl:flex\"\n size=\"xs\"\n variant=\"ghost\"\n @click=\"requestCopyUrl\">\n <ScalarIconCopy />\n <span class=\"sr-only\">Copy URL</span>\n </ScalarButton>\n\n <AddressBarHistory\n :history=\"history\"\n :target=\"id\"\n @select:history:item=\"(payload) => emit('select:history:item', payload)\"\n @update:open=\"(value) => (isHistoryDropdownOpen = value)\" />\n <!-- Error message -->\n <div\n v-if=\"hasConflict\"\n class=\"z-context absolute inset-x-0 top-[calc(100%+4px)] flex flex-col items-center rounded px-6\">\n <div\n class=\"text-c-danger bg-b-danger border-c-danger flex items-center gap-1 rounded border p-1\">\n <ScalarIconWarningCircle size=\"sm\" />\n <div class=\"min-w-0 flex-1\">\n A\n <em>{{ methodConflict?.toUpperCase() ?? method.toUpperCase() }}</em>\n request to\n <ScalarWrappingText :text=\"pathConflict ?? path\" />\n already exists in this document\n </div>\n </div>\n </div>\n\n <ScalarButton\n ref=\"sendButtonRef\"\n class=\"relative hidden h-auto shrink-0 overflow-hidden py-1 pr-2.5 pl-2 font-bold @3xl:flex\"\n data-addressbar-action=\"send\"\n :disabled=\"isLoading\"\n @click=\"emit('execute')\">\n <span\n aria-hidden=\"true\"\n class=\"inline-flex items-center gap-1\">\n <ScalarIcon\n class=\"relative shrink-0 fill-current\"\n icon=\"Play\"\n size=\"xs\" />\n <span class=\"text-xxs flex\">Send</span>\n </span>\n <span class=\"sr-only\">\n Send {{ method }} request to {{ server?.url ?? '' }}{{ path }}\n </span>\n </ScalarButton>\n </div>\n\n <!--\n Mobile actions row. Visible by default and hidden once the\n container reaches `@3xl`, where the duplicate Method / Copy /\n Send buttons move back into the bar itself.\n -->\n <div\n class=\"mt-2 flex h-(--scalar-address-bar-height) w-full items-stretch gap-1 @3xl:hidden\">\n <HttpMethod\n :isEditable=\"layout !== 'modal' && !isWebhook\"\n isSquare\n :method=\"methodConflict ?? method\"\n teleport\n @change=\"handleMethodChange\" />\n <ScalarButton\n class=\"hover:bg-b-3 ml-auto\"\n size=\"xs\"\n variant=\"ghost\"\n @click=\"requestCopyUrl\">\n <ScalarIconCopy />\n <span class=\"sr-only\">Copy URL</span>\n </ScalarButton>\n <ScalarButton\n ref=\"mobileSendButtonRef\"\n class=\"relative h-auto shrink-0 overflow-hidden py-1 pr-2.5 pl-2 font-bold\"\n data-addressbar-action=\"send\"\n :disabled=\"isLoading\"\n @click=\"emit('execute')\">\n <span\n aria-hidden=\"true\"\n class=\"inline-flex items-center gap-1\">\n <ScalarIcon\n class=\"relative shrink-0 fill-current\"\n icon=\"Play\"\n size=\"xs\" />\n <span class=\"text-xxs\">Send</span>\n </span>\n <span class=\"sr-only\">\n Send {{ method }} request to {{ server?.url ?? '' }}{{ path }}\n </span>\n </ScalarButton>\n </div>\n </div>\n</template>\n<style scoped>\n:deep(.cm-editor) {\n height: 100%;\n outline: none;\n width: 100%;\n}\n:deep(.cm-line) {\n padding: 0;\n}\n:deep(.cm-content) {\n padding: 0;\n display: flex;\n align-items: center;\n font-size: var(--scalar-small);\n}\n.scroll-timeline-x {\n -ms-overflow-style: none;\n /* Fade the URL at the viewport edges. Mask lives on the scrollport (this\n element) rather than on `.cm-scroller`, whose width follows the URL's\n full content and pushes the right edge off-screen when overflowing. */\n mask-image: linear-gradient(\n to right,\n transparent 0,\n black 6px,\n black calc(100% - 24px),\n transparent 100%\n );\n}\n.scroll-timeline-x-hidden {\n overflow-x: auto;\n}\n.scroll-timeline-x-hidden :deep(.cm-scroller) {\n scrollbar-width: none;\n -ms-overflow-style: none;\n padding-right: 20px;\n overflow: auto;\n}\n.scroll-timeline-x-hidden::-webkit-scrollbar {\n width: 0;\n height: 0;\n display: none;\n}\n.scroll-timeline-x-hidden :deep(.cm-scroller::-webkit-scrollbar) {\n width: 0;\n height: 0;\n display: none;\n}\n.scroll-timeline-x-address {\n line-height: 27px;\n scrollbar-width: none; /* Firefox */\n}\n/* make clickable are to left of send button */\n.scroll-timeline-x-address:after {\n content: '';\n position: absolute;\n height: 100%;\n width: 24px;\n right: 0;\n cursor: text;\n}\n.scroll-timeline-x-address:empty:before {\n content: 'Enter URL or cURL request';\n color: var(--scalar-color-3);\n pointer-events: none;\n}\n\n.address-bar-bg-states {\n --scalar-address-bar-bg: color-mix(\n in srgb,\n var(--scalar-background-1),\n var(--scalar-background-2)\n );\n background: var(--scalar-address-bar-bg);\n}\n.address-bar-bg-states:has(.cm-focused) {\n --scalar-address-bar-bg: var(--scalar-background-1);\n border-color: var(--scalar-border-color);\n outline-width: 1px;\n outline-style: solid;\n}\n.address-bar-bg-states:has(.cm-focused) .fade-left,\n.address-bar-bg-states:has(.cm-focused) .fade-right {\n --scalar-address-bar-bg: var(--scalar-background-1);\n}\n</style>\n"],"mappings":"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"}
1
+ {"version":3,"file":"AddressBar.vue.script.js","names":[],"sources":["../../../../../src/v2/blocks/scalar-address-bar-block/components/AddressBar.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * AddressBar component\n * This component is used to display the address bar for the operation block\n * It is used to display the path, method, server, and history for the operation\n */\nexport default {\n name: 'AddressBar',\n}\nexport type AddressBarProps = {\n /** An external example must finish loading before sending. */\n executionDisabled?: boolean\n /** Current request path */\n path: string\n /** Current request method */\n method: HttpMethodType\n /** Whether the request target belongs to an OpenAPI webhook. */\n isWebhook?: boolean\n /** Openapi document slug */\n documentSlug: string\n /** Currently selected example key for the current operation */\n exampleKey: string\n /** Currently selected server */\n server: ServerObject | null\n /** Server list available for operation/document */\n servers: ServerObject[]\n /** List of request history */\n history: History[]\n /** Client layout */\n layout: ClientLayout\n /** Event bus */\n eventBus: WorkspaceEventBus\n /** Environment */\n environment: XScalarEnvironment\n /** Meta information for the server */\n serverMeta: ServerMeta\n}\n</script>\n<script setup lang=\"ts\">\nimport { ScalarButton } from '@scalar/components/button'\nimport { ScalarIcon } from '@scalar/components/icon'\nimport { ScalarWrappingText } from '@scalar/components/wrapping-text'\nimport { getSelector } from '@scalar/helpers/dom/get-selector'\nimport { REQUEST_METHODS } from '@scalar/helpers/http/http-info'\nimport type { HttpMethod as HttpMethodType } from '@scalar/helpers/http/http-methods'\nimport { extractServerFromPath } from '@scalar/helpers/url/extract-server-from-path'\nimport { ScalarIconCopy, ScalarIconWarningCircle } from '@scalar/icons'\nimport { EditorView } from '@scalar/use-codemirror'\nimport type {\n ApiReferenceEvents,\n ServerMeta,\n WorkspaceEventBus,\n} from '@scalar/workspace-store/events'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport type { ServerObject } from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document'\nimport {\n computed,\n nextTick,\n onBeforeUnmount,\n onMounted,\n ref,\n useId,\n useTemplateRef,\n watch,\n} from 'vue'\n\nimport { HttpMethod } from '@/components/HttpMethod'\nimport { getOperationExampleKey } from '@/v2/blocks/operation-block/helpers/response-cache'\nimport { isPlaceholderPath } from '@/v2/blocks/scalar-address-bar-block/helpers/is-placeholder-path'\nimport { refocusBlurTarget } from '@/v2/blocks/scalar-address-bar-block/helpers/refocus-blur-target'\nimport { useLoadingAnimation } from '@/v2/blocks/scalar-address-bar-block/hooks/use-loading-animation'\nimport { usePathMasking } from '@/v2/blocks/scalar-address-bar-block/hooks/use-path-masking'\nimport { CodeInput } from '@/v2/components/code-input'\nimport { ServerDropdown } from '@/v2/components/server'\nimport type { ClientLayout } from '@/v2/types/layout'\n\nimport AddressBarHistory, { type History } from './AddressBarHistory.vue'\n\nconst {\n path,\n method,\n layout,\n eventBus,\n exampleKey,\n documentSlug,\n server,\n servers,\n environment,\n serverMeta,\n isWebhook = false,\n} = defineProps<AddressBarProps>()\n\nconst emit = defineEmits<{\n /** Execute the current operation example */\n (e: 'execute'): void\n /** Select a request history item by index */\n (e: 'select:history:item', payload: { index: number }): void\n /** Update the full destination URL used to deliver a webhook. */\n (e: 'update:webhook-url', url: string): void\n}>()\n\n// ───────────────────────────────────────────────────────────────────\n// Template refs & reactive state\n// ───────────────────────────────────────────────────────────────────\n\nconst id = useId()\nconst sendButtonRef = useTemplateRef('sendButtonRef')\nconst mobileSendButtonRef = useTemplateRef('mobileSendButtonRef')\nconst addressBarRef = useTemplateRef('addressBarRef')\n\nconst { percentage, startLoading, stopLoading, isLoading } =\n useLoadingAnimation()\n\nconst pathConflict = ref<string | null>(null)\nconst methodConflict = ref<HttpMethodType | null>(null)\nconst tabbedOut = ref(false)\nconst isServerDropdownOpen = ref(false)\nconst isHistoryDropdownOpen = ref(false)\n\n// ───────────────────────────────────────────────────────────────────\n// Derived state\n// ───────────────────────────────────────────────────────────────────\n\n/** Keeps the cursor visible past the fade-right overlay while typing */\nconst addressBarScrollMargins = EditorView.scrollMargins.of(() => ({\n right: 24,\n}))\n\n/** Animated background transform for the loading indicator */\nconst style = computed(() => ({\n backgroundColor: `color-mix(in srgb, transparent 90%, ${REQUEST_METHODS[method].colorVar})`,\n transform: `translate3d(-${percentage.value}%,0,0)`,\n}))\n\n/** Whether there is a path or method conflict */\nconst hasConflict = computed(() => methodConflict.value || pathConflict.value)\n\n/**\n * Placeholder for the path field.\n *\n * Webhooks have no server to prefix the path, so the field doubles as the full\n * destination URL. Hint that a complete URL (including the host) is expected,\n * rather than a bare path.\n */\nconst pathPlaceholder = computed(() => {\n if (server) {\n return ''\n }\n return isWebhook\n ? 'Enter the full webhook URL, e.g. https://example.com/hook'\n : 'Enter a URL'\n})\n\n/** Whether either dropdown (server or history) is open */\nconst isDropdownOpen = computed(\n () => isServerDropdownOpen.value || isHistoryDropdownOpen.value,\n)\n\n/** Uniquely identifies the currently selected operation + example */\nconst uniqueKey = computed(() =>\n getOperationExampleKey(method, path, exampleKey, documentSlug),\n)\n\n/** Clear conflict state when switching to a different operation */\nwatch(uniqueKey, () => {\n pathConflict.value = null\n methodConflict.value = null\n})\n\n// ───────────────────────────────────────────────────────────────────\n// Focus helpers\n// ───────────────────────────────────────────────────────────────────\n\nconst handleFocusSendButton = (): void => {\n const desktop = sendButtonRef.value?.$el\n const mobile = mobileSendButtonRef.value?.$el\n\n // Focus whichever send button is currently visible\n if (desktop && desktop.offsetParent !== null) {\n desktop.focus()\n } else {\n mobile?.focus()\n }\n}\n\nconst handleFocusAddressBar = (\n payload: ApiReferenceEvents['ui:focus:address-bar'],\n): void => {\n // On non-desktop layouts, if already focused we let the browser handle the\n // native behavior (e.g. selecting the browser's own address bar).\n if (addressBarRef.value?.isFocused && layout !== 'desktop') {\n return\n }\n\n addressBarRef.value?.focus('end')\n\n if (payload && 'clear' in payload && payload.clear) {\n addressBarRef.value?.setCodeMirrorContent('')\n }\n\n if (payload && 'event' in payload) {\n payload.event.preventDefault()\n }\n}\n\n// ───────────────────────────────────────────────────────────────────\n// Path masking\n//\n// Drafts on `/` and auto-generated `/_scalar_temp...` paths are internal\n// placeholders — the address bar focuses and clears on mount and on\n// navigation so the user sees a blank prompt instead of the internal\n// path. The deferred mask only clears when CodeMirror still contains that\n// placeholder path, so a user edit that lands before the frame is preserved.\n// ───────────────────────────────────────────────────────────────────\n\nusePathMasking({\n isReady: () => addressBarRef.value?.codeMirror,\n operationKey: () => uniqueKey.value,\n shouldMask: () => isPlaceholderPath(path, documentSlug),\n // Defer to the next frame so focus() runs after click-handler side\n // effects that move focus (e.g. a dropdown refocusing its trigger),\n // which would otherwise blur our input and emit a spurious path\n // update against the now-empty value.\n onMask: () =>\n requestAnimationFrame(() => {\n const editorContent =\n addressBarRef.value?.codeMirror?.state.doc.toString()\n\n if (editorContent && editorContent !== path) {\n return\n }\n\n handleFocusAddressBar({ clear: true })\n }),\n})\n\n// ───────────────────────────────────────────────────────────────────\n// Server extraction\n// ───────────────────────────────────────────────────────────────────\n\n/** If the path contains a server URL, extract it and select or add that server */\nconst extractAndSelectServer = (targetPath: string): string => {\n const extracted = extractServerFromPath(targetPath)\n if (!extracted) {\n return targetPath\n }\n\n const [url, remainingPath] = extracted\n\n // Server is already selected — nothing to do\n if (url === server?.url) {\n return remainingPath\n }\n\n const matchingServer = servers.find((s) => s.url === url)\n if (matchingServer) {\n eventBus.emit('server:update:selected', { url, meta: serverMeta })\n } else {\n eventBus.emit('server:add:server', {\n url,\n select: true,\n meta: { type: 'operation', path, method },\n })\n }\n\n return remainingPath\n}\n\n// ───────────────────────────────────────────────────────────────────\n// Path / method updates\n// ───────────────────────────────────────────────────────────────────\n\nconst normalizePath = (value: string): string =>\n value.startsWith('/') ? value : `/${value}`\n\n/** Emit a path/method update and reconcile conflicts + cursor state on the result */\nconst emitPathMethodUpdate = (\n targetMethod: HttpMethodType,\n targetPath: string,\n blurTargetSelector: string | null = null,\n): void => {\n if (isWebhook) {\n // A webhook has no OpenAPI server, so the field holds the full destination\n // URL. Keep exactly what the user entered — do not split it into an invisible\n // server plus a leftover path, and do not force a leading slash. That split\n // is what made a typed URL collapse to a stray \"/\" on blur.\n const webhookUrl = targetPath.trim()\n addressBarRef.value?.setCodeMirrorContent(webhookUrl)\n emit('update:webhook-url', webhookUrl)\n methodConflict.value = null\n pathConflict.value = null\n nextTick(() => refocusBlurTarget(blurTargetSelector))\n return\n }\n\n const extractedPath = extractAndSelectServer(targetPath)\n const normalizedPath = normalizePath(extractedPath)\n\n // Keep CodeMirror in sync so a conflict does not leave a stale value on screen\n addressBarRef.value?.setCodeMirrorContent(normalizedPath)\n\n eventBus.emit('operation:update:pathMethod', {\n meta: { method, path },\n blurTargetSelector,\n payload: { method: targetMethod, path: normalizedPath },\n callback: (status, returnedSelector) => {\n if (status === 'success' || status === 'no-change') {\n methodConflict.value = null\n pathConflict.value = null\n } else if (status === 'conflict') {\n if (targetMethod !== method) {\n methodConflict.value = targetMethod\n }\n if (normalizedPath !== path) {\n pathConflict.value = normalizedPath\n }\n\n return\n }\n\n // Edge case: pasting a full URL extracts the server but leaves the path\n // unchanged. CodeMirror still shows the full URL, so force it back to\n // just the path.\n const mirrorContent = addressBarRef.value?.codeMirrorRef?.textContent\n if (\n status === 'no-change' &&\n mirrorContent &&\n mirrorContent !== extractedPath\n ) {\n addressBarRef.value?.setCodeMirrorContent(extractedPath)\n }\n\n nextTick(() => refocusBlurTarget(returnedSelector))\n },\n })\n}\n\n/** Change the operation's method, preferring the conflicting path if present */\nconst handleMethodChange = (newMethod: HttpMethodType): void =>\n emitPathMethodUpdate(newMethod, pathConflict.value ?? path)\n\n/**\n * Save the path on blur and replay the click that caused the blur (so e.g. a\n * click on the Send button still fires after the async update resolves).\n *\n * Tab-outs do not replay — tabbing to a button should not trigger its click\n * (`tabbedOut` is set on `@keydown.tab`).\n *\n * Programmatic focus moves also do not replay. On first navigation into a\n * draft operation, `usePathMasking` focuses and clears the address bar while\n * `ScalarSidebarNestedItems` focuses the drilled-in Back button in\n * `nextTick`. That steals focus from CodeMirror, fires blur with a\n * `relatedTarget` (the Back button), and without a guard we would treat it\n * like a user click: capture the selector, then `refocusBlurTarget` would\n * synthesize `.click()` on Back and navigate away.\n *\n * `FocusEvent.sourceCapabilities` is null when no input device caused the\n * focus change (e.g. `element.focus()`). A real pointer click sets it on the\n * blur that precedes the click, so we still replay Send and other buttons.\n */\nconst handlePathBlur = (newPath: string, event: FocusEvent): void => {\n const relatedTarget =\n event.relatedTarget instanceof Element ? event.relatedTarget : null\n const blurTargetSelector =\n tabbedOut.value ||\n ('sourceCapabilities' in event && event.sourceCapabilities === null)\n ? null\n : getSelector(relatedTarget)\n tabbedOut.value = false\n\n emitPathMethodUpdate(\n methodConflict.value ?? method,\n newPath,\n blurTargetSelector,\n )\n}\n\n/** Save the path on Enter and trigger the Send button after the update resolves */\nconst handlePathSubmit = (\n newPath: string,\n event: KeyboardEvent | FocusEvent,\n): void => {\n // Prevent the global hotkey listener from also handling this Enter press\n event.stopPropagation()\n\n emitPathMethodUpdate(\n methodConflict.value ?? method,\n newPath,\n '[data-addressbar-action=\"send\"]',\n )\n}\n\n/** Unset the server when backspace is pressed on an empty path */\nconst handlePathBackspace = (event: KeyboardEvent): void => {\n if (event.target instanceof HTMLElement && event.target.innerText === '\\n') {\n // A webhook has no server to unset; its full URL lives in the field itself.\n if (isWebhook) {\n return\n }\n eventBus.emit('server:update:selected', { url: '', meta: serverMeta })\n }\n}\n\nconst handleServerSelect = (\n payload: ApiReferenceEvents['server:update:selected'],\n): void => {\n eventBus.emit('server:update:selected', payload)\n}\n\nconst handleServerVariable = (\n payload: ApiReferenceEvents['server:update:variables'],\n): void => {\n eventBus.emit('server:update:variables', payload)\n}\n\n/** Address bar copy is handled in OperationBlock (same URL as Send). */\nconst requestCopyUrl = (): void => {\n eventBus.emit('copy-url:address-bar')\n}\n\n// ───────────────────────────────────────────────────────────────────\n// Navigation\n// ───────────────────────────────────────────────────────────────────\n\nconst navigateToServersPage = (): void => {\n if (serverMeta.type === 'operation') {\n eventBus.emit('ui:navigate', {\n page: 'operation',\n path: 'servers',\n operationPath: serverMeta.path,\n method: serverMeta.method,\n })\n return\n }\n\n eventBus.emit('ui:navigate', { page: 'document', path: 'servers' })\n}\n\n// ───────────────────────────────────────────────────────────────────\n// Lifecycle\n// ───────────────────────────────────────────────────────────────────\n\nconst unsubscribes: Array<() => void> = []\n\nonMounted(() => {\n unsubscribes.push(\n eventBus.on('ui:focus:address-bar', handleFocusAddressBar),\n eventBus.on('ui:focus:send-button', handleFocusSendButton),\n eventBus.on('hooks:on:request:sent', startLoading),\n eventBus.on('hooks:on:request:complete', stopLoading),\n )\n})\n\nonBeforeUnmount(() => {\n for (const unsubscribe of unsubscribes) {\n unsubscribe()\n }\n\n // Prevents the loading animation from continuing after unmount\n stopLoading()\n})\n\ndefineExpose({\n methodConflict,\n pathConflict,\n})\n</script>\n<template>\n <!--\n Address bar.\n\n The wide-container layout matches the original single-row bar:\n `[Method | URL | Copy | History | Send]`. When the surrounding\n `@container` drops below `@3xl` the bar collapses to\n `[URL | History]` and a second row appears beneath it with a\n duplicate `Method`, `Copy`, and `Send` so the URL gets the full\n container width while every action stays on the same line as the\n send button.\n -->\n <div\n class=\"order-last flex h-auto w-full max-w-3xl grow-3 flex-wrap items-stretch [--scalar-address-bar-height:32px] @3xl:order-0 @3xl:flex-nowrap\">\n <!-- Address Bar -->\n <div\n :id=\"id\"\n class=\"address-bar-bg-states text-xxs group relative flex h-(--scalar-address-bar-height) w-full flex-1 flex-row items-stretch rounded-lg p-0.75\"\n :class=\"{\n 'outline-c-danger outline': hasConflict,\n 'rounded-b-none': isDropdownOpen,\n }\">\n <div\n class=\"pointer-events-none absolute top-0 left-0 block h-full w-full overflow-hidden rounded-lg border\"\n :class=\"{\n 'rounded-b-none': isDropdownOpen,\n }\">\n <div\n class=\"absolute top-0 left-0 h-full w-full\"\n :style />\n </div>\n\n <!--\n Method, Copy, and Send are hidden in mobile mode (container\n narrower than `@3xl`) and the duplicate buttons in the trailing\n mobile actions row take over at that point.\n -->\n <div class=\"hidden @3xl:flex\">\n <HttpMethod\n :isEditable=\"layout !== 'modal' && !isWebhook\"\n isSquare\n :method=\"methodConflict ?? method\"\n teleport\n @change=\"handleMethodChange\" />\n </div>\n\n <div\n class=\"scroll-timeline-x scroll-timeline-x-hidden relative flex w-full bg-blend-normal\">\n <!-- Servers -->\n <ServerDropdown\n v-if=\"servers.length\"\n :layout=\"isWebhook ? 'modal' : layout\"\n :meta=\"serverMeta\"\n :server=\"server\"\n :servers=\"servers\"\n :target=\"id\"\n @update:open=\"(value) => (isServerDropdownOpen = value)\"\n @update:selectedServer=\"handleServerSelect\"\n @update:servers=\"navigateToServersPage\"\n @update:variable=\"handleServerVariable\" />\n\n <!-- Path + URL + env vars -->\n <CodeInput\n ref=\"addressBarRef\"\n alwaysEmitChange\n aria-label=\"Path\"\n class=\"ml-1 min-w-fit pl-px outline-none\"\n disableCloseBrackets\n :disabled=\"layout === 'modal' && !isWebhook\"\n disableEnter\n disableTabIndent\n :emitOnBlur=\"false\"\n :environment=\"environment\"\n :extensions=\"[addressBarScrollMargins]\"\n importCurl\n :layout=\"layout\"\n :modelValue=\"path\"\n :placeholder=\"pathPlaceholder\"\n server\n @blur=\"handlePathBlur\"\n @keydown.delete=\"handlePathBackspace\"\n @keydown.tab=\"tabbedOut = true\"\n @submit=\"handlePathSubmit\" />\n </div>\n\n <!-- Copy url button -->\n <ScalarButton\n class=\"hover:bg-b-3 mx-1 hidden @3xl:flex\"\n size=\"xs\"\n variant=\"ghost\"\n @click=\"requestCopyUrl\">\n <ScalarIconCopy />\n <span class=\"sr-only\">Copy URL</span>\n </ScalarButton>\n\n <AddressBarHistory\n :history=\"history\"\n :target=\"id\"\n @select:history:item=\"(payload) => emit('select:history:item', payload)\"\n @update:open=\"(value) => (isHistoryDropdownOpen = value)\" />\n <!-- Error message -->\n <div\n v-if=\"hasConflict\"\n class=\"z-context absolute inset-x-0 top-[calc(100%+4px)] flex flex-col items-center rounded px-6\">\n <div\n class=\"text-c-danger bg-b-danger border-c-danger flex items-center gap-1 rounded border p-1\">\n <ScalarIconWarningCircle size=\"sm\" />\n <div class=\"min-w-0 flex-1\">\n A\n <em>{{ methodConflict?.toUpperCase() ?? method.toUpperCase() }}</em>\n request to\n <ScalarWrappingText :text=\"pathConflict ?? path\" />\n already exists in this document\n </div>\n </div>\n </div>\n\n <ScalarButton\n ref=\"sendButtonRef\"\n class=\"relative hidden h-auto shrink-0 overflow-hidden py-1 pr-2.5 pl-2 font-bold @3xl:flex\"\n data-addressbar-action=\"send\"\n :disabled=\"isLoading || executionDisabled\"\n @click=\"emit('execute')\">\n <span\n aria-hidden=\"true\"\n class=\"inline-flex items-center gap-1\">\n <ScalarIcon\n class=\"relative shrink-0 fill-current\"\n icon=\"Play\"\n size=\"xs\" />\n <span class=\"text-xxs flex\">Send</span>\n </span>\n <span class=\"sr-only\">\n Send {{ method }} request to {{ server?.url ?? '' }}{{ path }}\n </span>\n </ScalarButton>\n </div>\n\n <!--\n Mobile actions row. Visible by default and hidden once the\n container reaches `@3xl`, where the duplicate Method / Copy /\n Send buttons move back into the bar itself.\n -->\n <div\n class=\"mt-2 flex h-(--scalar-address-bar-height) w-full items-stretch gap-1 @3xl:hidden\">\n <HttpMethod\n :isEditable=\"layout !== 'modal' && !isWebhook\"\n isSquare\n :method=\"methodConflict ?? method\"\n teleport\n @change=\"handleMethodChange\" />\n <ScalarButton\n class=\"hover:bg-b-3 ml-auto\"\n size=\"xs\"\n variant=\"ghost\"\n @click=\"requestCopyUrl\">\n <ScalarIconCopy />\n <span class=\"sr-only\">Copy URL</span>\n </ScalarButton>\n <ScalarButton\n ref=\"mobileSendButtonRef\"\n class=\"relative h-auto shrink-0 overflow-hidden py-1 pr-2.5 pl-2 font-bold\"\n data-addressbar-action=\"send\"\n :disabled=\"isLoading || executionDisabled\"\n @click=\"emit('execute')\">\n <span\n aria-hidden=\"true\"\n class=\"inline-flex items-center gap-1\">\n <ScalarIcon\n class=\"relative shrink-0 fill-current\"\n icon=\"Play\"\n size=\"xs\" />\n <span class=\"text-xxs\">Send</span>\n </span>\n <span class=\"sr-only\">\n Send {{ method }} request to {{ server?.url ?? '' }}{{ path }}\n </span>\n </ScalarButton>\n </div>\n </div>\n</template>\n<style scoped>\n:deep(.cm-editor) {\n height: 100%;\n outline: none;\n width: 100%;\n}\n:deep(.cm-line) {\n padding: 0;\n}\n:deep(.cm-content) {\n padding: 0;\n display: flex;\n align-items: center;\n font-size: var(--scalar-small);\n}\n.scroll-timeline-x {\n -ms-overflow-style: none;\n /* Fade the URL at the viewport edges. Mask lives on the scrollport (this\n element) rather than on `.cm-scroller`, whose width follows the URL's\n full content and pushes the right edge off-screen when overflowing. */\n mask-image: linear-gradient(\n to right,\n transparent 0,\n black 6px,\n black calc(100% - 24px),\n transparent 100%\n );\n}\n.scroll-timeline-x-hidden {\n overflow-x: auto;\n}\n.scroll-timeline-x-hidden :deep(.cm-scroller) {\n scrollbar-width: none;\n -ms-overflow-style: none;\n padding-right: 20px;\n overflow: auto;\n}\n.scroll-timeline-x-hidden::-webkit-scrollbar {\n width: 0;\n height: 0;\n display: none;\n}\n.scroll-timeline-x-hidden :deep(.cm-scroller::-webkit-scrollbar) {\n width: 0;\n height: 0;\n display: none;\n}\n.scroll-timeline-x-address {\n line-height: 27px;\n scrollbar-width: none; /* Firefox */\n}\n/* make clickable are to left of send button */\n.scroll-timeline-x-address:after {\n content: '';\n position: absolute;\n height: 100%;\n width: 24px;\n right: 0;\n cursor: text;\n}\n.scroll-timeline-x-address:empty:before {\n content: 'Enter URL or cURL request';\n color: var(--scalar-color-3);\n pointer-events: none;\n}\n\n.address-bar-bg-states {\n --scalar-address-bar-bg: color-mix(\n in srgb,\n var(--scalar-background-1),\n var(--scalar-background-2)\n );\n background: var(--scalar-address-bar-bg);\n}\n.address-bar-bg-states:has(.cm-focused) {\n --scalar-address-bar-bg: var(--scalar-background-1);\n border-color: var(--scalar-border-color);\n outline-width: 1px;\n outline-style: solid;\n}\n.address-bar-bg-states:has(.cm-focused) .fade-left,\n.address-bar-bg-states:has(.cm-focused) .fade-right {\n --scalar-address-bar-bg: var(--scalar-background-1);\n}\n</style>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"AuthSelector.vue.script.js","names":[],"sources":["../../../../../src/v2/blocks/scalar-auth-selector-block/components/AuthSelector.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n ScalarButton,\n type ScalarButton as ScalarButtonType,\n} from '@scalar/components/button'\nimport { ScalarComboboxMultiselect } from '@scalar/components/combobox'\nimport type { Icon } from '@scalar/components/icon'\nimport { ScalarIconButton } from '@scalar/components/icon-button'\nimport { ScalarListboxCheckbox } from '@scalar/components/listbox'\nimport { useModal } from '@scalar/components/modal'\nimport { ScalarIconCaretDown, ScalarIconTrash } from '@scalar/icons'\nimport type { SelectedSecurity } from '@scalar/workspace-store/entities/auth'\nimport type {\n AuthMeta,\n WorkspaceEventBus,\n} from '@scalar/workspace-store/events'\nimport { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport { unpackProxyObject } from '@scalar/workspace-store/helpers/unpack-proxy'\nimport {\n isAuthOptional,\n type MergedSecuritySchemes,\n} from '@scalar/workspace-store/request-example'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport type {\n OpenApiDocument,\n SecurityRequirementObject,\n ServerObject,\n} from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document'\nimport { computed, ref, useId } from 'vue'\n\nimport DeleteRequestAuthModal from '@/v2/blocks/scalar-auth-selector-block/components/DeleteRequestAuthModal.vue'\nimport type { OAuth2Options } from '@/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue'\nimport {\n formatComplexScheme,\n formatScheme,\n getSecuritySchemeOptions,\n type SecuritySchemeOption,\n} from '@/v2/blocks/scalar-auth-selector-block/helpers/security-scheme'\nimport { CollapsibleSection } from '@/v2/components/layout'\n\nimport RequestAuthDataTable from './RequestAuthDataTable.vue'\n\nconst {\n environment,\n eventBus,\n createAnySecurityScheme = false,\n canDeleteSchemes = true,\n defaultOpen = true,\n isStatic = false,\n meta,\n proxyUrl,\n securityRequirements,\n securitySchemes,\n selectedSecurity,\n server,\n title,\n options,\n documentType,\n} = defineProps<{\n environment: XScalarEnvironment\n eventBus: WorkspaceEventBus\n /** Allows adding authentication which is not in the document */\n createAnySecurityScheme?: boolean\n /**\n * Whether schemes can be deleted from the selector. Enabled for the editable client, disabled in\n * the read-only reference where the schemes come from the document and cannot be removed.\n */\n canDeleteSchemes?: boolean\n /** Whether the authentication disclosure should start expanded */\n defaultOpen?: boolean\n /** Creates a static disclosure that cannot be collapsed */\n isStatic?: boolean\n meta: AuthMeta\n proxyUrl: string\n securityRequirements: OpenApiDocument['security']\n securitySchemes: MergedSecuritySchemes\n selectedSecurity: SelectedSecurity | undefined\n server: ServerObject | null\n title: string\n /** Any config options required for the OAuth2 flow */\n options?: OAuth2Options\n /** Type of the document the schemes belong to, used to label the missing-type warning */\n documentType?: 'openapi' | 'asyncapi'\n}>()\n\nconst titleId = useId()\nconst comboboxButtonRef = ref<typeof ScalarButtonType | null>(null)\nconst isDisclosureOpen = ref(false)\n\nconst deleteModal = useModal()\nconst schemeToDelete = ref<{\n label: string\n payload: SecurityRequirementObject\n} | null>(null)\n\n/**\n * Determines if authentication is required or optional\n *\n * Auth is optional when there is an empty security requirement and no complex requirements.\n * Complex requirements have multiple auth schemes combined (e.g., API key + OAuth).\n */\nconst authIndicator = computed<{ icon: Icon; text: string } | null>(() => {\n if (!securityRequirements?.length) {\n return null\n }\n\n const isOptional = isAuthOptional(securityRequirements)\n\n return {\n icon: isOptional ? 'Unlock' : 'Lock',\n text: isOptional ? 'Optional' : 'Required',\n }\n})\n\n/** All available auth scheme options for the dropdown */\nconst availableSchemeOptions = computed(() =>\n getSecuritySchemeOptions(\n securityRequirements ?? [],\n securitySchemes ?? {},\n selectedSecurity?.selectedSchemes ?? [],\n createAnySecurityScheme,\n ),\n)\n\n/** Currently active auth schemes selected for this operation or collection */\nconst activeSchemeOptions = computed<SecuritySchemeOption[]>(() => {\n const schemes = selectedSecurity?.selectedSchemes\n if (!schemes?.length) {\n return []\n }\n\n return schemes.flatMap((requirement) => {\n const schemeNames = Object.keys(requirement)\n\n if (schemeNames.length === 0) {\n return []\n }\n\n // Complex auth requirement with multiple schemes\n if (schemeNames.length > 1) {\n return formatComplexScheme(requirement)\n }\n\n // Simple auth requirement with single scheme\n const schemeName = schemeNames[0]\n if (!schemeName) {\n return []\n }\n\n const scheme = getResolvedRef(securitySchemes?.[schemeName])\n if (!scheme) {\n return []\n }\n\n return formatScheme({\n name: schemeName,\n value: requirement,\n })\n })\n})\n\n/**\n * Opens the combobox dropdown when clicking the auth indicator badge.\n * Prevents the disclosure from toggling if it is already open.\n */\nconst handleAuthIndicatorClick = (event: Event): void => {\n if (isDisclosureOpen.value) {\n event.stopPropagation()\n }\n comboboxButtonRef.value?.$el.click()\n}\n\n/**\n * Updates the selected auth schemes.\n * Separates existing schemes from newly created ones for the event payload.\n */\nconst handleSchemeSelection = (selected: SecuritySchemeOption[]): void => {\n const existingSchemes = selected\n .filter((option) => option.payload === undefined)\n .map((option) => unpackProxyObject(option.value, { depth: 2 }))\n\n const newSchemes = selected\n .filter((option) => option.payload !== undefined)\n .map((option) => ({\n name: option.label,\n scheme: option.payload!,\n }))\n\n eventBus.emit('auth:update:selected-security-schemes', {\n selectedRequirements: existingSchemes,\n newSchemes,\n meta,\n })\n}\n\n/** Shows the delete confirmation modal for the selected scheme */\nconst handleDeleteRequest = (option: {\n label: string\n value: SecurityRequirementObject\n}): void => {\n schemeToDelete.value = { label: option.label, payload: option.value }\n deleteModal.show()\n}\n\n/** Deletes the selected auth scheme after confirmation */\nconst handleDeleteConfirm = (): void => {\n if (!schemeToDelete.value) {\n return\n }\n\n eventBus.emit('auth:delete:security-scheme', {\n names: Object.keys(schemeToDelete.value.payload),\n })\n\n schemeToDelete.value = null\n deleteModal.hide()\n}\n\ndefineExpose({\n authIndicator,\n selectedSchemeOptions: activeSchemeOptions,\n schemeOptions: availableSchemeOptions,\n})\n</script>\n<template>\n <CollapsibleSection\n class=\"group/params relative\"\n :defaultOpen\n :isStatic=\"isStatic\"\n :itemCount=\"activeSchemeOptions.length\"\n @update:modelValue=\"(open) => (isDisclosureOpen = open)\">\n <template #title>\n <div\n :id=\"titleId\"\n class=\"inline-flex items-center gap-0.5 leading-[20px]\">\n <span>{{ title }}</span>\n\n <span\n v-if=\"authIndicator\"\n class=\"text-c-3 hover:bg-b-3 hover:text-c-1 -my-0.5 -mr-1 cursor-pointer rounded px-1 py-0.5 leading-[normal] font-normal\"\n :class=\"{ 'text-c-1': authIndicator.text === 'Required' }\"\n data-testid=\"auth-indicator\"\n @click=\"handleAuthIndicatorClick\">\n {{ authIndicator.text }}\n </span>\n </div>\n </template>\n\n <!-- Auth Dropdown (hidden when only one scheme is available) -->\n <template #actions>\n <ScalarComboboxMultiselect\n class=\"w-72 text-xs\"\n :modelValue=\"activeSchemeOptions\"\n multiple\n :options=\"availableSchemeOptions\"\n placement=\"bottom-end\"\n teleport\n @delete=\"handleDeleteRequest\"\n @update:modelValue=\"handleSchemeSelection\">\n <ScalarButton\n ref=\"comboboxButtonRef\"\n :aria-describedby=\"titleId\"\n class=\"group/combobox-button hover:text-c-1 text-c-2 flex h-fit w-full items-center gap-1 px-0.75 py-0.25 text-base font-normal\"\n variant=\"ghost\">\n <!-- Single auth scheme selected -->\n <template v-if=\"activeSchemeOptions.length === 1\">\n <span class=\"sr-only\">Selected Auth Type:</span>\n {{ activeSchemeOptions[0]?.label }}\n </template>\n\n <!-- Multiple auth schemes selected -->\n <template v-else-if=\"activeSchemeOptions.length > 1\">\n Multiple\n <span class=\"sr-only\">Auth Types Selected</span>\n </template>\n\n <!-- No auth schemes selected -->\n <template v-else>\n <span class=\"sr-only\">Select</span>\n Auth Type\n </template>\n\n <ScalarIconCaretDown\n class=\"size-3 shrink-0 transition-transform duration-100 group-aria-expanded/combobox-button:rotate-180\"\n weight=\"bold\" />\n </ScalarButton>\n\n <template #option=\"{ option, selected }\">\n <ScalarListboxCheckbox\n multiselect\n :selected=\"selected\" />\n <div class=\"min-w-0 flex-1 truncate\">\n {{ option.label }}\n </div>\n <ScalarIconButton\n v-if=\"option.isDeletable && canDeleteSchemes\"\n class=\"-m-0.5 shrink-0 p-0.5 opacity-0 group-hover/item:opacity-100\"\n :icon=\"ScalarIconTrash\"\n :label=\"`Delete ${option.label}`\"\n size=\"xs\"\n @click.stop=\"handleDeleteRequest(option)\" />\n </template>\n </ScalarComboboxMultiselect>\n </template>\n\n <!-- Auth Table -->\n <RequestAuthDataTable\n :activeAuthIndex=\"selectedSecurity?.selectedIndex ?? 0\"\n :documentType\n :environment\n :eventBus\n :isStatic\n :meta\n :options\n :proxyUrl\n :securitySchemes\n :selectedSchemeOptions=\"activeSchemeOptions\"\n :server />\n\n <!-- Delete Auth Modal -->\n <DeleteRequestAuthModal\n v-if=\"schemeToDelete\"\n :label=\"schemeToDelete.label\"\n :scheme=\"schemeToDelete\"\n :state=\"deleteModal\"\n @close=\"deleteModal.hide()\"\n @delete=\"handleDeleteConfirm\" />\n </CollapsibleSection>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"AuthSelector.vue.script.js","names":[],"sources":["../../../../../src/v2/blocks/scalar-auth-selector-block/components/AuthSelector.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n ScalarButton,\n type ScalarButton as ScalarButtonType,\n} from '@scalar/components/button'\nimport { ScalarComboboxMultiselect } from '@scalar/components/combobox'\nimport type { Icon } from '@scalar/components/icon'\nimport { ScalarIconButton } from '@scalar/components/icon-button'\nimport { ScalarListboxCheckbox } from '@scalar/components/listbox'\nimport { useModal } from '@scalar/components/modal'\nimport { ScalarIconCaretDown, ScalarIconTrash } from '@scalar/icons'\nimport type { SelectedSecurity } from '@scalar/workspace-store/entities/auth'\nimport type {\n AuthMeta,\n WorkspaceEventBus,\n} from '@scalar/workspace-store/events'\nimport { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport { unpackProxyObject } from '@scalar/workspace-store/helpers/unpack-proxy'\nimport {\n isAuthOptional,\n type MergedSecuritySchemes,\n} from '@scalar/workspace-store/request-example'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport type {\n OpenApiDocument,\n SecurityRequirementObject,\n ServerObject,\n} from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document'\nimport { computed, ref, useId } from 'vue'\n\nimport DeleteRequestAuthModal from '@/v2/blocks/scalar-auth-selector-block/components/DeleteRequestAuthModal.vue'\nimport type { OAuth2Options } from '@/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue'\nimport {\n formatComplexScheme,\n formatScheme,\n getSecuritySchemeOptions,\n type SecuritySchemeOption,\n} from '@/v2/blocks/scalar-auth-selector-block/helpers/security-scheme'\nimport { CollapsibleSection } from '@/v2/components/layout'\n\nimport RequestAuthDataTable from './RequestAuthDataTable.vue'\n\nconst {\n environment,\n eventBus,\n createAnySecurityScheme = false,\n canDeleteSchemes = true,\n defaultOpen = true,\n isStatic = false,\n meta,\n proxyUrl,\n securityRequirements,\n securitySchemes,\n selectedSecurity,\n server,\n title,\n options,\n documentType,\n} = defineProps<{\n environment: XScalarEnvironment\n eventBus: WorkspaceEventBus\n /** Allows adding authentication which is not in the document */\n createAnySecurityScheme?: boolean\n /**\n * Whether schemes can be deleted from the selector. Enabled for the editable client, disabled in\n * the read-only reference where the schemes come from the document and cannot be removed.\n */\n canDeleteSchemes?: boolean\n /** Whether the authentication disclosure should start expanded */\n defaultOpen?: boolean\n /** Creates a static disclosure that cannot be collapsed */\n isStatic?: boolean\n meta: AuthMeta\n proxyUrl: string\n securityRequirements: OpenApiDocument['security']\n securitySchemes: MergedSecuritySchemes\n selectedSecurity: SelectedSecurity | undefined\n server: ServerObject | null\n title: string\n /** Any config options required for the OAuth2 flow */\n options?: OAuth2Options\n /** Type of the document the schemes belong to, used to label the missing-type warning */\n documentType?: 'openapi' | 'asyncapi'\n}>()\n\nconst titleId = useId()\nconst comboboxButtonRef = ref<typeof ScalarButtonType | null>(null)\nconst isDisclosureOpen = ref(false)\n\nconst deleteModal = useModal()\nconst schemeToDelete = ref<{\n label: string\n payload: SecurityRequirementObject\n} | null>(null)\n\n/**\n * Determines if authentication is required or optional\n *\n * Auth is optional when there is an empty security requirement and no complex requirements.\n * Complex requirements have multiple auth schemes combined (e.g., API key + OAuth).\n */\nconst authIndicator = computed<{ icon: Icon; text: string } | null>(() => {\n if (!securityRequirements?.length) {\n return null\n }\n\n const isOptional = isAuthOptional(securityRequirements)\n\n return {\n icon: isOptional ? 'Unlock' : 'Lock',\n text: isOptional ? 'Optional' : 'Required',\n }\n})\n\n/** All available auth scheme options for the dropdown */\nconst availableSchemeOptions = computed(() =>\n getSecuritySchemeOptions(\n securityRequirements ?? [],\n securitySchemes ?? {},\n selectedSecurity?.selectedSchemes ?? [],\n createAnySecurityScheme,\n ),\n)\n\n/** Currently active auth schemes selected for this operation or collection */\nconst activeSchemeOptions = computed<SecuritySchemeOption[]>(() => {\n const schemes = selectedSecurity?.selectedSchemes\n if (!schemes?.length) {\n return []\n }\n\n return schemes.flatMap((requirement) => {\n const schemeNames = Object.keys(requirement)\n\n if (schemeNames.length === 0) {\n return []\n }\n\n // Complex auth requirement with multiple schemes\n if (schemeNames.length > 1) {\n return formatComplexScheme(requirement)\n }\n\n // Simple auth requirement with single scheme\n const schemeName = schemeNames[0]\n if (!schemeName) {\n return []\n }\n\n const scheme = getResolvedRef(securitySchemes?.[schemeName])\n if (!scheme) {\n return []\n }\n\n return formatScheme({\n name: schemeName,\n value: requirement,\n })\n })\n})\n\n/**\n * Opens the combobox dropdown when clicking the auth indicator badge.\n * Prevents the disclosure from toggling if it is already open.\n */\nconst handleAuthIndicatorClick = (event: Event): void => {\n if (isDisclosureOpen.value) {\n event.stopPropagation()\n }\n comboboxButtonRef.value?.$el.click()\n}\n\n/**\n * Updates the selected auth schemes.\n * Separates existing schemes from newly created ones for the event payload.\n */\nconst handleSchemeSelection = (selected: SecuritySchemeOption[]): void => {\n const existingSchemes = selected\n .filter((option) => option.payload === undefined)\n .map((option) => unpackProxyObject(option.value, { depth: 2 }))\n\n const newSchemes = selected\n .filter((option) => option.payload !== undefined)\n .map((option) => ({\n name: option.label,\n scheme: option.payload!,\n }))\n\n eventBus.emit('auth:update:selected-security-schemes', {\n selectedRequirements: existingSchemes,\n newSchemes,\n meta,\n })\n}\n\n/** Shows the delete confirmation modal for the selected scheme */\nconst handleDeleteRequest = (option: {\n label: string\n value: SecurityRequirementObject\n}): void => {\n schemeToDelete.value = { label: option.label, payload: option.value }\n deleteModal.show()\n}\n\n/** Deletes the selected auth scheme after confirmation */\nconst handleDeleteConfirm = (): void => {\n if (!schemeToDelete.value) {\n return\n }\n\n eventBus.emit('auth:delete:security-scheme', {\n names: Object.keys(schemeToDelete.value.payload),\n })\n\n schemeToDelete.value = null\n deleteModal.hide()\n}\n\ndefineExpose({\n authIndicator,\n selectedSchemeOptions: activeSchemeOptions,\n schemeOptions: availableSchemeOptions,\n})\n</script>\n<template>\n <CollapsibleSection\n class=\"group/params relative\"\n :defaultOpen\n :isStatic=\"isStatic\"\n :itemCount=\"activeSchemeOptions.length\"\n @update:modelValue=\"(open) => (isDisclosureOpen = open)\">\n <template #title>\n <div\n :id=\"titleId\"\n class=\"inline-flex items-center gap-0.5 leading-[20px]\">\n <span>{{ title }}</span>\n\n <span\n v-if=\"authIndicator\"\n class=\"text-c-3 hover:bg-b-3 hover:text-c-1 -my-0.5 -mr-1 cursor-pointer rounded px-1 py-0.5 leading-[normal] font-normal\"\n :class=\"{ 'text-c-1': authIndicator.text === 'Required' }\"\n data-testid=\"auth-indicator\"\n @click=\"handleAuthIndicatorClick\">\n {{ authIndicator.text }}\n </span>\n </div>\n </template>\n\n <!-- Auth Dropdown (hidden when only one scheme is available) -->\n <template #actions>\n <ScalarComboboxMultiselect\n class=\"w-72 text-xs\"\n :modelValue=\"activeSchemeOptions\"\n multiple\n :options=\"availableSchemeOptions\"\n placement=\"bottom-end\"\n teleport\n @delete=\"handleDeleteRequest\"\n @update:modelValue=\"handleSchemeSelection\">\n <ScalarButton\n ref=\"comboboxButtonRef\"\n :aria-describedby=\"titleId\"\n class=\"group/combobox-button hover:text-c-1 text-c-2 flex h-fit w-full items-center gap-1 px-0.75 py-0.25 text-base font-normal\"\n variant=\"ghost\">\n <!-- Single auth scheme selected -->\n <template v-if=\"activeSchemeOptions.length === 1\">\n <span class=\"sr-only\">Selected Auth Type:</span>\n {{ activeSchemeOptions[0]?.label }}\n </template>\n\n <!-- Multiple auth schemes selected -->\n <template v-else-if=\"activeSchemeOptions.length > 1\">\n Multiple\n <span class=\"sr-only\">Auth Types Selected</span>\n </template>\n\n <!-- No auth schemes selected -->\n <template v-else>\n <span class=\"sr-only\">Select</span>\n Auth Type\n </template>\n\n <ScalarIconCaretDown\n class=\"size-3 shrink-0 transition-transform duration-100 group-aria-expanded/combobox-button:rotate-180\"\n weight=\"bold\" />\n </ScalarButton>\n\n <template #option=\"{ option, selected }\">\n <ScalarListboxCheckbox\n multiselect\n :selected=\"selected\" />\n <div class=\"min-w-0 flex-1 truncate\">\n {{ option.label }}\n </div>\n <ScalarIconButton\n v-if=\"option.isDeletable && canDeleteSchemes\"\n class=\"-m-0.5 shrink-0 p-0.5 opacity-0 group-hover/item:opacity-100\"\n :icon=\"ScalarIconTrash\"\n :label=\"`Delete ${option.label}`\"\n size=\"xs\"\n @click.stop=\"handleDeleteRequest(option)\" />\n </template>\n </ScalarComboboxMultiselect>\n </template>\n\n <!-- Auth Table -->\n <RequestAuthDataTable\n :activeAuthIndex=\"selectedSecurity?.selectedIndex ?? 0\"\n :documentType\n :environment\n :eventBus\n :isStatic\n :meta\n :options\n :proxyUrl\n :securitySchemes\n :selectedSchemeOptions=\"activeSchemeOptions\"\n :server />\n\n <!-- Delete Auth Modal -->\n <DeleteRequestAuthModal\n v-if=\"schemeToDelete\"\n :label=\"schemeToDelete.label\"\n :scheme=\"schemeToDelete\"\n :state=\"deleteModal\"\n @close=\"deleteModal.hide()\"\n @delete=\"handleDeleteConfirm\" />\n </CollapsibleSection>\n</template>\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  //#region src/v2/constants.ts
2
2
  /** The version number taken from the package.json. Consumers can override at build time via define (e.g. OVERRIDE_PACKAGE_VERSION: JSON.stringify('1.2.3')). */
3
- var APP_VERSION = typeof OVERRIDE_PACKAGE_VERSION !== "undefined" ? OVERRIDE_PACKAGE_VERSION : "3.19.1";
3
+ var APP_VERSION = typeof OVERRIDE_PACKAGE_VERSION !== "undefined" ? OVERRIDE_PACKAGE_VERSION : "3.19.3";
4
4
  //#endregion
5
5
  export { APP_VERSION };
6
6
 
@@ -1 +1 @@
1
- {"version":3,"file":"Modal.vue.d.ts","sourceRoot":"","sources":["../../../../src/v2/features/modal/Modal.vue"],"names":[],"mappings":"AAiNA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAA;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAE7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AACpE,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAEvE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8DAA8D,CAAA;AACnG,OAAO,EAKL,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,GAAG,EACT,MAAM,KAAK,CAAA;AAIZ,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,6CAA6C,CAAA;AAKxF,OAAO,KAAK,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AAG/E,MAAM,MAAM,UAAU,GAAG;IACvB,4DAA4D;IAC5D,cAAc,EAAE,cAAc,CAAA;IAC9B,qGAAqG;IACrG,QAAQ,EAAE,WAAW,CAAC,eAAe,GAAG,IAAI,CAAC,CAAA;IAC7C,iDAAiD;IACjD,IAAI,EAAE,WAAW,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IACrC,4CAA4C;IAC5C,QAAQ,EAAE,iBAAiB,CAAA;IAC3B,mDAAmD;IACnD,MAAM,EAAE,WAAW,CAAC,UAAU,GAAG,SAAS,CAAC,CAAA;IAC3C,yDAAyD;IACzD,WAAW,EAAE,WAAW,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IAC5C,kEAAkE;IAClE,SAAS,EAAE,WAAW,CAAC,OAAO,CAAC,CAAA;IAC/B,sEAAsE;IACtE,+BAA+B,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IAC5D,2CAA2C;IAC3C,UAAU,EAAE,UAAU,CAAA;IACtB,0DAA0D;IAC1D,YAAY,EAAE,qBAAqB,CAAA;IACnC,iDAAiD;IACjD,OAAO,EAAE,YAAY,EAAE,CAAA;IACvB,wDAAwD;IACxD,OAAO,EAAE,gBAAgB,CAAC,gBAAgB,CAAC,CAAA;CAC5C,CAAA;AAED;;;;GAIG;wBACkB,OAAO,YAAY;AAAxC,wBAAyC;AAGzC,QAAA,MAAM,YAAY;aAC0C,mBAAmB;;;;;aAAnB,mBAAmB;iGA8Q3E,CAAC"}
1
+ {"version":3,"file":"Modal.vue.d.ts","sourceRoot":"","sources":["../../../../src/v2/features/modal/Modal.vue"],"names":[],"mappings":"AAkNA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAA;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAE7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AACpE,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAEvE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8DAA8D,CAAA;AACnG,OAAO,EAKL,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,GAAG,EACT,MAAM,KAAK,CAAA;AAIZ,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,6CAA6C,CAAA;AAKxF,OAAO,KAAK,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AAG/E,MAAM,MAAM,UAAU,GAAG;IACvB,4DAA4D;IAC5D,cAAc,EAAE,cAAc,CAAA;IAC9B,qGAAqG;IACrG,QAAQ,EAAE,WAAW,CAAC,eAAe,GAAG,IAAI,CAAC,CAAA;IAC7C,iDAAiD;IACjD,IAAI,EAAE,WAAW,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IACrC,4CAA4C;IAC5C,QAAQ,EAAE,iBAAiB,CAAA;IAC3B,mDAAmD;IACnD,MAAM,EAAE,WAAW,CAAC,UAAU,GAAG,SAAS,CAAC,CAAA;IAC3C,yDAAyD;IACzD,WAAW,EAAE,WAAW,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IAC5C,kEAAkE;IAClE,SAAS,EAAE,WAAW,CAAC,OAAO,CAAC,CAAA;IAC/B,sEAAsE;IACtE,+BAA+B,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IAC5D,2CAA2C;IAC3C,UAAU,EAAE,UAAU,CAAA;IACtB,0DAA0D;IAC1D,YAAY,EAAE,qBAAqB,CAAA;IACnC,iDAAiD;IACjD,OAAO,EAAE,YAAY,EAAE,CAAA;IACvB,wDAAwD;IACxD,OAAO,EAAE,gBAAgB,CAAC,gBAAgB,CAAC,CAAA;CAC5C,CAAA;AAED;;;;GAIG;wBACkB,OAAO,YAAY;AAAxC,wBAAyC;AAGzC,QAAA,MAAM,YAAY;aAC0C,mBAAmB;;;;;aAAnB,mBAAmB;iGAgR3E,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Modal.vue.js","names":[],"sources":["../../../../src/v2/features/modal/Modal.vue"],"sourcesContent":["<script lang=\"ts\">\nexport type ModalProps = {\n /** The workspace store must be initialized and passed in */\n workspaceStore: WorkspaceStore\n /** The document must be initialized and passed in. OpenAPI-only — the modal has no AsyncAPI path. */\n document: ComputedRef<OpenApiDocument | null>\n /** The path must be initialized and passed in */\n path: ComputedRef<string | undefined>\n /** The event bus for handling all events */\n eventBus: WorkspaceEventBus\n /** The method must be initialized and passed in */\n method: ComputedRef<HttpMethod | undefined>\n /** The example name must be initialized and passed in */\n exampleName: ComputedRef<string | undefined>\n /** Whether the active route resolves from `document.webhooks`. */\n isWebhook: ComputedRef<boolean>\n /** Selected anyOf/oneOf request-body variants keyed by schema path */\n requestBodyCompositionSelection: Ref<Record<string, number>>\n /** Controls the visibility of the modal */\n modalState: ModalState\n /** The sidebar state must be initialized and passed in */\n sidebarState: UseModalSidebarReturn\n /** Api client plugins to include in the modal */\n plugins: ClientPlugin[]\n /** Subset of the configuration options for the modal */\n options: MaybeRefOrGetter<ApiClientOptions>\n}\n\n/**\n * Scalar Api Client Modal\n *\n * This component is used to render the API Client Modal\n */\nexport default {}\n</script>\n\n<script setup lang=\"ts\">\nimport type { ScalarListboxOption } from '@scalar/components/listbox'\nimport type { ModalState } from '@scalar/components/modal'\nimport type { HttpMethod } from '@scalar/helpers/http/http-methods'\nimport type { ClientPlugin } from '@scalar/oas-utils/helpers'\nimport { ScalarToasts } from '@scalar/use-toasts'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\nimport { type WorkspaceEventBus } from '@scalar/workspace-store/events'\nimport { getActiveEnvironment } from '@scalar/workspace-store/request-example'\nimport type { OpenApiDocument } from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document'\nimport {\n computed,\n onBeforeUnmount,\n ref,\n watch,\n type ComputedRef,\n type MaybeRefOrGetter,\n type Ref,\n} from 'vue'\n\nimport ModalClientContainer from '@/v2/components/modals/ModalClientContainer.vue'\nimport { Sidebar, SidebarToggle } from '@/v2/components/sidebar'\nimport { type UseModalSidebarReturn } from '@/v2/features/modal/hooks/use-modal-sidebar'\nimport { initializeModalEvents } from '@/v2/features/modal/modal-events'\nimport Operation from '@/v2/features/operation/Operation.vue'\nimport { useGlobalHotKeys } from '@/v2/hooks/use-global-hot-keys'\nimport { useScrollLock } from '@/v2/hooks/use-scroll-lock'\nimport type { ApiClientOptions, ApiClientOptionsRef } from '@/v2/types/options'\n\nconst {\n document,\n eventBus,\n modalState,\n options,\n plugins,\n requestBodyCompositionSelection,\n sidebarState,\n workspaceStore,\n} = defineProps<\n Omit<ModalProps, 'options'> & { options: ApiClientOptionsRef }\n>()\n\nconst activeWorkspace: ScalarListboxOption = {\n label: 'default',\n id: 'default',\n}\n\n/** Controls the visibility of the sidebar. */\nconst isSidebarOpen = ref(false)\n\n/** Initialize modal events */\ninitializeModalEvents({\n eventBus,\n isSidebarOpen,\n requestBodyCompositionSelection,\n sidebarState,\n modalState,\n store: workspaceStore,\n})\n\n/** Register global hotkeys for the app, passing the workspace event bus and layout state */\nuseGlobalHotKeys(eventBus, 'modal', () => !modalState.open)\n\n/** Clean up on close */\nconst cleanUp = () => {\n eventBus.emit('operation:cancel:request')\n}\n\nconst isLocked = useScrollLock(() => {\n if (typeof window !== 'undefined') {\n return window.document.body\n }\n return null\n})\n\nwatch(\n () => modalState.open,\n (open) => {\n // Make sure scrolling is locked or unlocked when the modal is opened or closed\n isLocked.value = open\n\n if (!open) {\n cleanUp()\n }\n },\n)\n\n// Ensure we add our scalar wrapper class to the headless ui root\nonBeforeUnmount(() => cleanUp())\n\n/** Default sidebar width in pixels. */\nconst DEFAULT_SIDEBAR_WIDTH = 288\n\n/** Width of the sidebar, with fallback to default. */\nconst sidebarWidth = computed(\n () =>\n workspaceStore?.workspace?.['x-scalar-sidebar-width'] ??\n DEFAULT_SIDEBAR_WIDTH,\n)\n\n/** Handler for sidebar width changes. */\nconst handleSidebarWidthUpdate = (width: number) =>\n workspaceStore?.update('x-scalar-sidebar-width', width)\n\n/**\n * Merged environment variables from workspace and document levels.\n * Variables from both sources are combined, with document variables\n * taking precedence in case of naming conflicts.\n */\nconst environment = computed(\n () => getActiveEnvironment(workspaceStore, document.value).environment,\n)\n\ndefineExpose({\n sidebarWidth,\n environment,\n})\n</script>\n\n<template>\n <ModalClientContainer :modalState>\n <!-- Toasts -->\n <ScalarToasts />\n\n <!-- If we have a document, path and method, render the operation -->\n <main\n v-if=\"document.value && path?.value && method?.value\"\n class=\"relative flex h-full min-h-0 w-full flex-1\">\n <SidebarToggle\n v-model=\"isSidebarOpen\"\n class=\"absolute top-2 left-4 z-10 max-md:top-4\" />\n <Sidebar\n v-show=\"isSidebarOpen\"\n v-model:sidebarWidth=\"sidebarWidth\"\n :activeWorkspace=\"activeWorkspace\"\n class=\"h-full max-md:absolute! max-md:z-5 max-md:w-full!\"\n :documents=\"[document.value]\"\n :eventBus\n :isDroppable=\"() => false\"\n layout=\"modal\"\n :sidebarState=\"sidebarState.state\"\n :workspaces=\"[]\"\n @selectItem=\"sidebarState.handleSelectItem\"\n @update:sidebarWidth=\"handleSidebarWidthUpdate\" />\n <Operation\n :activeWorkspace=\"activeWorkspace\"\n class=\"flex-1\"\n :document=\"document.value\"\n :documentSlug=\"document.value['x-scalar-navigation']?.name ?? ''\"\n :environment\n :eventBus\n :exampleName=\"exampleName?.value\"\n :isWebhook=\"isWebhook.value\"\n layout=\"modal\"\n :method=\"method?.value\"\n :options\n :path=\"path?.value\"\n :plugins\n :requestBodyCompositionSelection=\"requestBodyCompositionSelection.value\"\n :workspaceStore />\n </main>\n <!-- Empty state -->\n <div\n v-else\n class=\"flex h-full w-full items-center justify-center\">\n <span class=\"text-c-3\">No document selected</span>\n </div>\n </ModalClientContainer>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"Modal.vue.js","names":[],"sources":["../../../../src/v2/features/modal/Modal.vue"],"sourcesContent":["<script lang=\"ts\">\nexport type ModalProps = {\n /** The workspace store must be initialized and passed in */\n workspaceStore: WorkspaceStore\n /** The document must be initialized and passed in. OpenAPI-only — the modal has no AsyncAPI path. */\n document: ComputedRef<OpenApiDocument | null>\n /** The path must be initialized and passed in */\n path: ComputedRef<string | undefined>\n /** The event bus for handling all events */\n eventBus: WorkspaceEventBus\n /** The method must be initialized and passed in */\n method: ComputedRef<HttpMethod | undefined>\n /** The example name must be initialized and passed in */\n exampleName: ComputedRef<string | undefined>\n /** Whether the active route resolves from `document.webhooks`. */\n isWebhook: ComputedRef<boolean>\n /** Selected anyOf/oneOf request-body variants keyed by schema path */\n requestBodyCompositionSelection: Ref<Record<string, number>>\n /** Controls the visibility of the modal */\n modalState: ModalState\n /** The sidebar state must be initialized and passed in */\n sidebarState: UseModalSidebarReturn\n /** Api client plugins to include in the modal */\n plugins: ClientPlugin[]\n /** Subset of the configuration options for the modal */\n options: MaybeRefOrGetter<ApiClientOptions>\n}\n\n/**\n * Scalar Api Client Modal\n *\n * This component is used to render the API Client Modal\n */\nexport default {}\n</script>\n\n<script setup lang=\"ts\">\nimport type { ScalarListboxOption } from '@scalar/components/listbox'\nimport type { ModalState } from '@scalar/components/modal'\nimport type { HttpMethod } from '@scalar/helpers/http/http-methods'\nimport type { ClientPlugin } from '@scalar/oas-utils/helpers'\nimport { ScalarToasts } from '@scalar/use-toasts'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\nimport { type WorkspaceEventBus } from '@scalar/workspace-store/events'\nimport { getActiveEnvironment } from '@scalar/workspace-store/request-example'\nimport type { OpenApiDocument } from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document'\nimport {\n computed,\n onBeforeUnmount,\n ref,\n watch,\n type ComputedRef,\n type MaybeRefOrGetter,\n type Ref,\n} from 'vue'\n\nimport ModalClientContainer from '@/v2/components/modals/ModalClientContainer.vue'\nimport { Sidebar, SidebarToggle } from '@/v2/components/sidebar'\nimport { type UseModalSidebarReturn } from '@/v2/features/modal/hooks/use-modal-sidebar'\nimport { initializeModalEvents } from '@/v2/features/modal/modal-events'\nimport Operation from '@/v2/features/operation/Operation.vue'\nimport { useGlobalHotKeys } from '@/v2/hooks/use-global-hot-keys'\nimport { useScrollLock } from '@/v2/hooks/use-scroll-lock'\nimport type { ApiClientOptions, ApiClientOptionsRef } from '@/v2/types/options'\n\nconst {\n document,\n eventBus,\n modalState,\n options,\n plugins,\n requestBodyCompositionSelection,\n sidebarState,\n workspaceStore,\n} = defineProps<\n Omit<ModalProps, 'options'> & { options: ApiClientOptionsRef }\n>()\n\nconst activeWorkspace: ScalarListboxOption = {\n label: 'default',\n id: 'default',\n}\n\n/** Controls the visibility of the sidebar. */\nconst isSidebarOpen = ref(false)\n\n/** Initialize modal events */\ninitializeModalEvents({\n eventBus,\n isSidebarOpen,\n requestBodyCompositionSelection,\n sidebarState,\n modalState,\n store: workspaceStore,\n})\n\n/** Register global hotkeys for the app, passing the workspace event bus and layout state */\nuseGlobalHotKeys(eventBus, 'modal', () => !modalState.open)\n\n/** Clean up on close */\nconst cleanUp = () => {\n eventBus.emit('operation:cancel:request')\n}\n\nconst isLocked = useScrollLock(() => {\n if (typeof window !== 'undefined') {\n return window.document.body\n }\n return null\n})\n\nwatch(\n () => modalState.open,\n (open) => {\n // Make sure scrolling is locked or unlocked when the modal is opened or closed\n isLocked.value = open\n\n if (!open) {\n cleanUp()\n }\n },\n)\n\n// Ensure we add our scalar wrapper class to the headless ui root\nonBeforeUnmount(() => cleanUp())\n\n/** Default sidebar width in pixels. */\nconst DEFAULT_SIDEBAR_WIDTH = 288\n\n/** Width of the sidebar, with fallback to default. */\nconst sidebarWidth = computed(\n () =>\n workspaceStore?.workspace?.['x-scalar-sidebar-width'] ??\n DEFAULT_SIDEBAR_WIDTH,\n)\n\n/** Handler for sidebar width changes. */\nconst handleSidebarWidthUpdate = (width: number) =>\n workspaceStore?.update('x-scalar-sidebar-width', width)\n\n/**\n * Merged environment variables from workspace and document levels.\n * Variables from both sources are combined, with document variables\n * taking precedence in case of naming conflicts.\n */\nconst environment = computed(\n () => getActiveEnvironment(workspaceStore, document.value).environment,\n)\n\ndefineExpose({\n sidebarWidth,\n environment,\n})\n</script>\n\n<template>\n <ModalClientContainer :modalState>\n <!-- Toasts -->\n <ScalarToasts />\n\n <!-- If we have a document, path and method, render the operation -->\n <main\n v-if=\"document.value && path?.value && method?.value\"\n class=\"relative flex h-full min-h-0 w-full flex-1\">\n <SidebarToggle\n v-model=\"isSidebarOpen\"\n class=\"absolute top-2 left-4 z-10 max-md:top-4\" />\n <Sidebar\n v-show=\"isSidebarOpen\"\n v-model:sidebarWidth=\"sidebarWidth\"\n :activeWorkspace=\"activeWorkspace\"\n class=\"h-full max-md:absolute! max-md:z-5 max-md:w-full!\"\n :documents=\"[document.value]\"\n :eventBus\n :isDroppable=\"() => false\"\n layout=\"modal\"\n :sidebarState=\"sidebarState.state\"\n :workspaces=\"[]\"\n @selectItem=\"sidebarState.handleSelectItem\"\n @update:sidebarWidth=\"handleSidebarWidthUpdate\" />\n <Operation\n :activeWorkspace=\"activeWorkspace\"\n class=\"flex-1\"\n :document=\"document.value\"\n :documentSlug=\"document.value['x-scalar-navigation']?.name ?? ''\"\n :environment\n :eventBus\n :exampleName=\"exampleName?.value\"\n :isActive=\"modalState.open\"\n :isWebhook=\"isWebhook.value\"\n layout=\"modal\"\n :method=\"method?.value\"\n :options\n :path=\"path?.value\"\n :plugins\n :requestBodyCompositionSelection=\"requestBodyCompositionSelection.value\"\n :workspaceStore />\n </main>\n <!-- Empty state -->\n <div\n v-else\n class=\"flex h-full w-full items-center justify-center\">\n <span class=\"text-c-3\">No document selected</span>\n </div>\n </ModalClientContainer>\n</template>\n"],"mappings":""}
@@ -115,6 +115,7 @@ var Modal_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComp
115
115
  environment: environment.value,
116
116
  eventBus: __props.eventBus,
117
117
  exampleName: __props.exampleName?.value,
118
+ isActive: __props.modalState.open,
118
119
  isWebhook: __props.isWebhook.value,
119
120
  layout: "modal",
120
121
  method: __props.method?.value,
@@ -129,6 +130,7 @@ var Modal_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComp
129
130
  "environment",
130
131
  "eventBus",
131
132
  "exampleName",
133
+ "isActive",
132
134
  "isWebhook",
133
135
  "method",
134
136
  "options",
@@ -1 +1 @@
1
- {"version":3,"file":"Modal.vue.script.js","names":[],"sources":["../../../../src/v2/features/modal/Modal.vue"],"sourcesContent":["<script lang=\"ts\">\nexport type ModalProps = {\n /** The workspace store must be initialized and passed in */\n workspaceStore: WorkspaceStore\n /** The document must be initialized and passed in. OpenAPI-only — the modal has no AsyncAPI path. */\n document: ComputedRef<OpenApiDocument | null>\n /** The path must be initialized and passed in */\n path: ComputedRef<string | undefined>\n /** The event bus for handling all events */\n eventBus: WorkspaceEventBus\n /** The method must be initialized and passed in */\n method: ComputedRef<HttpMethod | undefined>\n /** The example name must be initialized and passed in */\n exampleName: ComputedRef<string | undefined>\n /** Whether the active route resolves from `document.webhooks`. */\n isWebhook: ComputedRef<boolean>\n /** Selected anyOf/oneOf request-body variants keyed by schema path */\n requestBodyCompositionSelection: Ref<Record<string, number>>\n /** Controls the visibility of the modal */\n modalState: ModalState\n /** The sidebar state must be initialized and passed in */\n sidebarState: UseModalSidebarReturn\n /** Api client plugins to include in the modal */\n plugins: ClientPlugin[]\n /** Subset of the configuration options for the modal */\n options: MaybeRefOrGetter<ApiClientOptions>\n}\n\n/**\n * Scalar Api Client Modal\n *\n * This component is used to render the API Client Modal\n */\nexport default {}\n</script>\n\n<script setup lang=\"ts\">\nimport type { ScalarListboxOption } from '@scalar/components/listbox'\nimport type { ModalState } from '@scalar/components/modal'\nimport type { HttpMethod } from '@scalar/helpers/http/http-methods'\nimport type { ClientPlugin } from '@scalar/oas-utils/helpers'\nimport { ScalarToasts } from '@scalar/use-toasts'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\nimport { type WorkspaceEventBus } from '@scalar/workspace-store/events'\nimport { getActiveEnvironment } from '@scalar/workspace-store/request-example'\nimport type { OpenApiDocument } from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document'\nimport {\n computed,\n onBeforeUnmount,\n ref,\n watch,\n type ComputedRef,\n type MaybeRefOrGetter,\n type Ref,\n} from 'vue'\n\nimport ModalClientContainer from '@/v2/components/modals/ModalClientContainer.vue'\nimport { Sidebar, SidebarToggle } from '@/v2/components/sidebar'\nimport { type UseModalSidebarReturn } from '@/v2/features/modal/hooks/use-modal-sidebar'\nimport { initializeModalEvents } from '@/v2/features/modal/modal-events'\nimport Operation from '@/v2/features/operation/Operation.vue'\nimport { useGlobalHotKeys } from '@/v2/hooks/use-global-hot-keys'\nimport { useScrollLock } from '@/v2/hooks/use-scroll-lock'\nimport type { ApiClientOptions, ApiClientOptionsRef } from '@/v2/types/options'\n\nconst {\n document,\n eventBus,\n modalState,\n options,\n plugins,\n requestBodyCompositionSelection,\n sidebarState,\n workspaceStore,\n} = defineProps<\n Omit<ModalProps, 'options'> & { options: ApiClientOptionsRef }\n>()\n\nconst activeWorkspace: ScalarListboxOption = {\n label: 'default',\n id: 'default',\n}\n\n/** Controls the visibility of the sidebar. */\nconst isSidebarOpen = ref(false)\n\n/** Initialize modal events */\ninitializeModalEvents({\n eventBus,\n isSidebarOpen,\n requestBodyCompositionSelection,\n sidebarState,\n modalState,\n store: workspaceStore,\n})\n\n/** Register global hotkeys for the app, passing the workspace event bus and layout state */\nuseGlobalHotKeys(eventBus, 'modal', () => !modalState.open)\n\n/** Clean up on close */\nconst cleanUp = () => {\n eventBus.emit('operation:cancel:request')\n}\n\nconst isLocked = useScrollLock(() => {\n if (typeof window !== 'undefined') {\n return window.document.body\n }\n return null\n})\n\nwatch(\n () => modalState.open,\n (open) => {\n // Make sure scrolling is locked or unlocked when the modal is opened or closed\n isLocked.value = open\n\n if (!open) {\n cleanUp()\n }\n },\n)\n\n// Ensure we add our scalar wrapper class to the headless ui root\nonBeforeUnmount(() => cleanUp())\n\n/** Default sidebar width in pixels. */\nconst DEFAULT_SIDEBAR_WIDTH = 288\n\n/** Width of the sidebar, with fallback to default. */\nconst sidebarWidth = computed(\n () =>\n workspaceStore?.workspace?.['x-scalar-sidebar-width'] ??\n DEFAULT_SIDEBAR_WIDTH,\n)\n\n/** Handler for sidebar width changes. */\nconst handleSidebarWidthUpdate = (width: number) =>\n workspaceStore?.update('x-scalar-sidebar-width', width)\n\n/**\n * Merged environment variables from workspace and document levels.\n * Variables from both sources are combined, with document variables\n * taking precedence in case of naming conflicts.\n */\nconst environment = computed(\n () => getActiveEnvironment(workspaceStore, document.value).environment,\n)\n\ndefineExpose({\n sidebarWidth,\n environment,\n})\n</script>\n\n<template>\n <ModalClientContainer :modalState>\n <!-- Toasts -->\n <ScalarToasts />\n\n <!-- If we have a document, path and method, render the operation -->\n <main\n v-if=\"document.value && path?.value && method?.value\"\n class=\"relative flex h-full min-h-0 w-full flex-1\">\n <SidebarToggle\n v-model=\"isSidebarOpen\"\n class=\"absolute top-2 left-4 z-10 max-md:top-4\" />\n <Sidebar\n v-show=\"isSidebarOpen\"\n v-model:sidebarWidth=\"sidebarWidth\"\n :activeWorkspace=\"activeWorkspace\"\n class=\"h-full max-md:absolute! max-md:z-5 max-md:w-full!\"\n :documents=\"[document.value]\"\n :eventBus\n :isDroppable=\"() => false\"\n layout=\"modal\"\n :sidebarState=\"sidebarState.state\"\n :workspaces=\"[]\"\n @selectItem=\"sidebarState.handleSelectItem\"\n @update:sidebarWidth=\"handleSidebarWidthUpdate\" />\n <Operation\n :activeWorkspace=\"activeWorkspace\"\n class=\"flex-1\"\n :document=\"document.value\"\n :documentSlug=\"document.value['x-scalar-navigation']?.name ?? ''\"\n :environment\n :eventBus\n :exampleName=\"exampleName?.value\"\n :isWebhook=\"isWebhook.value\"\n layout=\"modal\"\n :method=\"method?.value\"\n :options\n :path=\"path?.value\"\n :plugins\n :requestBodyCompositionSelection=\"requestBodyCompositionSelection.value\"\n :workspaceStore />\n </main>\n <!-- Empty state -->\n <div\n v-else\n class=\"flex h-full w-full items-center justify-center\">\n <span class=\"text-c-3\">No document selected</span>\n </div>\n </ModalClientContainer>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8EA,MAAM,kBAAuC;GAC3C,OAAO;GACP,IAAI;EACN;;EAGA,MAAM,gBAAgB,IAAI,KAAK;;EAG/B,sBAAsB;GACpB,UAAO,QAAA;GACP;GACA,iCAA8B,QAAA;GAC9B,cAAW,QAAA;GACX,YAAS,QAAA;GACT,OAAO,QAAA;EACT,CAAC;;EAGD,iBAAiB,QAAA,UAAU,eAAe,CAAC,QAAA,WAAW,IAAI;;EAG1D,MAAM,gBAAgB;GACpB,QAAA,SAAS,KAAK,0BAA0B;EAC1C;EAEA,MAAM,WAAW,oBAAoB;GACnC,IAAI,OAAO,WAAW,aACpB,OAAO,OAAO,SAAS;GAEzB,OAAO;EACT,CAAC;EAED,YACQ,QAAA,WAAW,OAChB,SAAS;GAER,SAAS,QAAQ;GAEjB,IAAI,CAAC,MACH,QAAQ;EAEZ,CACF;EAGA,sBAAsB,QAAQ,CAAC;;EAG/B,MAAM,wBAAwB;;EAG9B,MAAM,eAAe,eAEjB,QAAA,gBAAgB,YAAY,6BAC5B,qBACJ;;EAGA,MAAM,4BAA4B,UAChC,QAAA,gBAAgB,OAAO,0BAA0B,KAAK;;;;;;EAOxD,MAAM,cAAc,eACZ,qBAAqB,QAAA,gBAAgB,QAAA,SAAS,KAAK,CAAC,CAAC,WAC7D;EAEA,SAAa;GACX;GACA;EACF,CAAC;;uBAIC,YA+CuB,8BAAA,EA/CA,YAAA,QAAA,WAAU,GAAA;2BAEf,CAAhB,YAAgB,MAAA,YAAA,CAAA,GAIR,QAAA,SAAS,SAAS,QAAA,MAAM,SAAS,QAAA,QAAQ,SAAA,UAAA,GADjD,mBAmCO,QAnCP,YAmCO;KAhCL,YAEoD,MAAA,qBAAA,GAAA;kBADzC,cAAA;iFAAa,QAAA;MACtB,OAAM;;oBACR,YAYoD,MAAA,eAAA,GAAA;MAV1C,cAAc,aAAA;mFAAY,QAAA,SAUZ,wBAAA;MATJ;MAClB,OAAM;MACL,WAAS,CAAG,QAAA,SAAS,KAAK;MAC1B,UAAA,QAAA;MACA,mBAAa;MACd,QAAO;MACN,cAAc,QAAA,aAAa;MAC3B,YAAY,CAAA;MACZ,cAAY,QAAA,aAAa;;;;;;;kBAVlB,cAAA,KAAa,CAAA,CAAA;KAYvB,YAeoB,mBAAA;MAdA;MAClB,OAAM;MACL,UAAU,QAAA,SAAS;MACnB,cAAc,QAAA,SAAS,MAAK,sBAAA,EAAyB,QAAI;MACzD,aAAA,YAAA;MACA,UAAA,QAAA;MACA,aAAa,QAAA,aAAa;MAC1B,WAAW,QAAA,UAAU;MACtB,QAAO;MACN,QAAQ,QAAA,QAAQ;MAChB,SAAA,QAAA;MACA,MAAM,QAAA,MAAM;MACZ,SAAA,QAAA;MACA,iCAAiC,QAAA,gCAAgC;MACjE,gBAAA,QAAA;;;;;;;;;;;;;;;wBAGL,mBAIM,OAJN,YAIM,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CADJ,mBAAkD,QAAA,EAA5C,OAAM,WAAU,GAAC,wBAAoB,EAAA,CAAA,EAAA,CAAA,EAAA,CAAA"}
1
+ {"version":3,"file":"Modal.vue.script.js","names":[],"sources":["../../../../src/v2/features/modal/Modal.vue"],"sourcesContent":["<script lang=\"ts\">\nexport type ModalProps = {\n /** The workspace store must be initialized and passed in */\n workspaceStore: WorkspaceStore\n /** The document must be initialized and passed in. OpenAPI-only — the modal has no AsyncAPI path. */\n document: ComputedRef<OpenApiDocument | null>\n /** The path must be initialized and passed in */\n path: ComputedRef<string | undefined>\n /** The event bus for handling all events */\n eventBus: WorkspaceEventBus\n /** The method must be initialized and passed in */\n method: ComputedRef<HttpMethod | undefined>\n /** The example name must be initialized and passed in */\n exampleName: ComputedRef<string | undefined>\n /** Whether the active route resolves from `document.webhooks`. */\n isWebhook: ComputedRef<boolean>\n /** Selected anyOf/oneOf request-body variants keyed by schema path */\n requestBodyCompositionSelection: Ref<Record<string, number>>\n /** Controls the visibility of the modal */\n modalState: ModalState\n /** The sidebar state must be initialized and passed in */\n sidebarState: UseModalSidebarReturn\n /** Api client plugins to include in the modal */\n plugins: ClientPlugin[]\n /** Subset of the configuration options for the modal */\n options: MaybeRefOrGetter<ApiClientOptions>\n}\n\n/**\n * Scalar Api Client Modal\n *\n * This component is used to render the API Client Modal\n */\nexport default {}\n</script>\n\n<script setup lang=\"ts\">\nimport type { ScalarListboxOption } from '@scalar/components/listbox'\nimport type { ModalState } from '@scalar/components/modal'\nimport type { HttpMethod } from '@scalar/helpers/http/http-methods'\nimport type { ClientPlugin } from '@scalar/oas-utils/helpers'\nimport { ScalarToasts } from '@scalar/use-toasts'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\nimport { type WorkspaceEventBus } from '@scalar/workspace-store/events'\nimport { getActiveEnvironment } from '@scalar/workspace-store/request-example'\nimport type { OpenApiDocument } from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document'\nimport {\n computed,\n onBeforeUnmount,\n ref,\n watch,\n type ComputedRef,\n type MaybeRefOrGetter,\n type Ref,\n} from 'vue'\n\nimport ModalClientContainer from '@/v2/components/modals/ModalClientContainer.vue'\nimport { Sidebar, SidebarToggle } from '@/v2/components/sidebar'\nimport { type UseModalSidebarReturn } from '@/v2/features/modal/hooks/use-modal-sidebar'\nimport { initializeModalEvents } from '@/v2/features/modal/modal-events'\nimport Operation from '@/v2/features/operation/Operation.vue'\nimport { useGlobalHotKeys } from '@/v2/hooks/use-global-hot-keys'\nimport { useScrollLock } from '@/v2/hooks/use-scroll-lock'\nimport type { ApiClientOptions, ApiClientOptionsRef } from '@/v2/types/options'\n\nconst {\n document,\n eventBus,\n modalState,\n options,\n plugins,\n requestBodyCompositionSelection,\n sidebarState,\n workspaceStore,\n} = defineProps<\n Omit<ModalProps, 'options'> & { options: ApiClientOptionsRef }\n>()\n\nconst activeWorkspace: ScalarListboxOption = {\n label: 'default',\n id: 'default',\n}\n\n/** Controls the visibility of the sidebar. */\nconst isSidebarOpen = ref(false)\n\n/** Initialize modal events */\ninitializeModalEvents({\n eventBus,\n isSidebarOpen,\n requestBodyCompositionSelection,\n sidebarState,\n modalState,\n store: workspaceStore,\n})\n\n/** Register global hotkeys for the app, passing the workspace event bus and layout state */\nuseGlobalHotKeys(eventBus, 'modal', () => !modalState.open)\n\n/** Clean up on close */\nconst cleanUp = () => {\n eventBus.emit('operation:cancel:request')\n}\n\nconst isLocked = useScrollLock(() => {\n if (typeof window !== 'undefined') {\n return window.document.body\n }\n return null\n})\n\nwatch(\n () => modalState.open,\n (open) => {\n // Make sure scrolling is locked or unlocked when the modal is opened or closed\n isLocked.value = open\n\n if (!open) {\n cleanUp()\n }\n },\n)\n\n// Ensure we add our scalar wrapper class to the headless ui root\nonBeforeUnmount(() => cleanUp())\n\n/** Default sidebar width in pixels. */\nconst DEFAULT_SIDEBAR_WIDTH = 288\n\n/** Width of the sidebar, with fallback to default. */\nconst sidebarWidth = computed(\n () =>\n workspaceStore?.workspace?.['x-scalar-sidebar-width'] ??\n DEFAULT_SIDEBAR_WIDTH,\n)\n\n/** Handler for sidebar width changes. */\nconst handleSidebarWidthUpdate = (width: number) =>\n workspaceStore?.update('x-scalar-sidebar-width', width)\n\n/**\n * Merged environment variables from workspace and document levels.\n * Variables from both sources are combined, with document variables\n * taking precedence in case of naming conflicts.\n */\nconst environment = computed(\n () => getActiveEnvironment(workspaceStore, document.value).environment,\n)\n\ndefineExpose({\n sidebarWidth,\n environment,\n})\n</script>\n\n<template>\n <ModalClientContainer :modalState>\n <!-- Toasts -->\n <ScalarToasts />\n\n <!-- If we have a document, path and method, render the operation -->\n <main\n v-if=\"document.value && path?.value && method?.value\"\n class=\"relative flex h-full min-h-0 w-full flex-1\">\n <SidebarToggle\n v-model=\"isSidebarOpen\"\n class=\"absolute top-2 left-4 z-10 max-md:top-4\" />\n <Sidebar\n v-show=\"isSidebarOpen\"\n v-model:sidebarWidth=\"sidebarWidth\"\n :activeWorkspace=\"activeWorkspace\"\n class=\"h-full max-md:absolute! max-md:z-5 max-md:w-full!\"\n :documents=\"[document.value]\"\n :eventBus\n :isDroppable=\"() => false\"\n layout=\"modal\"\n :sidebarState=\"sidebarState.state\"\n :workspaces=\"[]\"\n @selectItem=\"sidebarState.handleSelectItem\"\n @update:sidebarWidth=\"handleSidebarWidthUpdate\" />\n <Operation\n :activeWorkspace=\"activeWorkspace\"\n class=\"flex-1\"\n :document=\"document.value\"\n :documentSlug=\"document.value['x-scalar-navigation']?.name ?? ''\"\n :environment\n :eventBus\n :exampleName=\"exampleName?.value\"\n :isActive=\"modalState.open\"\n :isWebhook=\"isWebhook.value\"\n layout=\"modal\"\n :method=\"method?.value\"\n :options\n :path=\"path?.value\"\n :plugins\n :requestBodyCompositionSelection=\"requestBodyCompositionSelection.value\"\n :workspaceStore />\n </main>\n <!-- Empty state -->\n <div\n v-else\n class=\"flex h-full w-full items-center justify-center\">\n <span class=\"text-c-3\">No document selected</span>\n </div>\n </ModalClientContainer>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8EA,MAAM,kBAAuC;GAC3C,OAAO;GACP,IAAI;EACN;;EAGA,MAAM,gBAAgB,IAAI,KAAK;;EAG/B,sBAAsB;GACpB,UAAO,QAAA;GACP;GACA,iCAA8B,QAAA;GAC9B,cAAW,QAAA;GACX,YAAS,QAAA;GACT,OAAO,QAAA;EACT,CAAC;;EAGD,iBAAiB,QAAA,UAAU,eAAe,CAAC,QAAA,WAAW,IAAI;;EAG1D,MAAM,gBAAgB;GACpB,QAAA,SAAS,KAAK,0BAA0B;EAC1C;EAEA,MAAM,WAAW,oBAAoB;GACnC,IAAI,OAAO,WAAW,aACpB,OAAO,OAAO,SAAS;GAEzB,OAAO;EACT,CAAC;EAED,YACQ,QAAA,WAAW,OAChB,SAAS;GAER,SAAS,QAAQ;GAEjB,IAAI,CAAC,MACH,QAAQ;EAEZ,CACF;EAGA,sBAAsB,QAAQ,CAAC;;EAG/B,MAAM,wBAAwB;;EAG9B,MAAM,eAAe,eAEjB,QAAA,gBAAgB,YAAY,6BAC5B,qBACJ;;EAGA,MAAM,4BAA4B,UAChC,QAAA,gBAAgB,OAAO,0BAA0B,KAAK;;;;;;EAOxD,MAAM,cAAc,eACZ,qBAAqB,QAAA,gBAAgB,QAAA,SAAS,KAAK,CAAC,CAAC,WAC7D;EAEA,SAAa;GACX;GACA;EACF,CAAC;;uBAIC,YAgDuB,8BAAA,EAhDA,YAAA,QAAA,WAAU,GAAA;2BAEf,CAAhB,YAAgB,MAAA,YAAA,CAAA,GAIR,QAAA,SAAS,SAAS,QAAA,MAAM,SAAS,QAAA,QAAQ,SAAA,UAAA,GADjD,mBAoCO,QApCP,YAoCO;KAjCL,YAEoD,MAAA,qBAAA,GAAA;kBADzC,cAAA;iFAAa,QAAA;MACtB,OAAM;;oBACR,YAYoD,MAAA,eAAA,GAAA;MAV1C,cAAc,aAAA;mFAAY,QAAA,SAUZ,wBAAA;MATJ;MAClB,OAAM;MACL,WAAS,CAAG,QAAA,SAAS,KAAK;MAC1B,UAAA,QAAA;MACA,mBAAa;MACd,QAAO;MACN,cAAc,QAAA,aAAa;MAC3B,YAAY,CAAA;MACZ,cAAY,QAAA,aAAa;;;;;;;kBAVlB,cAAA,KAAa,CAAA,CAAA;KAYvB,YAgBoB,mBAAA;MAfA;MAClB,OAAM;MACL,UAAU,QAAA,SAAS;MACnB,cAAc,QAAA,SAAS,MAAK,sBAAA,EAAyB,QAAI;MACzD,aAAA,YAAA;MACA,UAAA,QAAA;MACA,aAAa,QAAA,aAAa;MAC1B,UAAU,QAAA,WAAW;MACrB,WAAW,QAAA,UAAU;MACtB,QAAO;MACN,QAAQ,QAAA,QAAQ;MAChB,SAAA,QAAA;MACA,MAAM,QAAA,MAAM;MACZ,SAAA,QAAA;MACA,iCAAiC,QAAA,gCAAgC;MACjE,gBAAA,QAAA;;;;;;;;;;;;;;;;wBAGL,mBAIM,OAJN,YAIM,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CADJ,mBAAkD,QAAA,EAA5C,OAAM,WAAU,GAAC,wBAAoB,EAAA,CAAA,EAAA,CAAA,EAAA,CAAA"}
@@ -18,6 +18,8 @@ import type { ApiClientOptions } from '../../../v2/types/options';
18
18
  declare const _default: typeof __VLS_export;
19
19
  export default _default;
20
20
  export type OperationProps = {
21
+ /** Hidden modals keep their operation mounted without downloading examples. */
22
+ isActive?: boolean;
21
23
  /** The slug of the currently selected document in the workspace */
22
24
  documentSlug: string;
23
25
  /** The currently active document — OpenAPI-only, the operation page has no AsyncAPI path */
@@ -1 +1 @@
1
- {"version":3,"file":"Operation.vue.d.ts","sourceRoot":"","sources":["../../../../src/v2/features/operation/Operation.vue"],"names":[],"mappings":"AA8NA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAA;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAKvE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2EAA2E,CAAA;AACnH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8DAA8D,CAAA;AACnG,OAAO,EAAqB,KAAK,gBAAgB,EAAE,MAAM,KAAK,CAAA;AAK9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAG1D;;;;;;;GAOG;wBACkB,OAAO,YAAY;AAAxC,wBAAyC;AAIzC,MAAM,MAAM,cAAc,GAAG;IAC3B,mEAAmE;IACnE,YAAY,EAAE,MAAM,CAAA;IACpB,4FAA4F;IAC5F,QAAQ,EAAE,eAAe,GAAG,IAAI,CAAA;IAChC,8BAA8B;IAC9B,QAAQ,EAAE,iBAAiB,CAAA;IAC3B,+BAA+B;IAC/B,MAAM,EAAE,YAAY,CAAA;IACpB,2DAA2D;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,2EAA2E;IAC3E,MAAM,CAAC,EAAE,UAAU,CAAA;IACnB,mFAAmF;IACnF,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,gEAAgE;IAChE,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,uCAAuC;IACvC,WAAW,EAAE,kBAAkB,CAAA;IAC/B,0BAA0B;IAC1B,cAAc,EAAE,cAAc,CAAA;IAC9B,qBAAqB;IACrB,OAAO,EAAE,YAAY,EAAE,CAAA;IACvB,8DAA8D;IAC9D,OAAO,CAAC,EAAE,gBAAgB,CAAC,gBAAgB,CAAC,CAAA;CAC7C,CAAA;AACD,QAAA,MAAM,YAAY;IAEd,sEAAsE;sCACpC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;;IADxD,sEAAsE;sCACpC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;iGA8PxD,CAAC"}
1
+ {"version":3,"file":"Operation.vue.d.ts","sourceRoot":"","sources":["../../../../src/v2/features/operation/Operation.vue"],"names":[],"mappings":"AAyRA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAA;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAgBvE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2EAA2E,CAAA;AACnH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8DAA8D,CAAA;AACnG,OAAO,EAML,KAAK,gBAAgB,EACtB,MAAM,KAAK,CAAA;AAKZ,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAG1D;;;;;;;GAOG;wBACkB,OAAO,YAAY;AAAxC,wBAAyC;AAIzC,MAAM,MAAM,cAAc,GAAG;IAC3B,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,mEAAmE;IACnE,YAAY,EAAE,MAAM,CAAA;IACpB,4FAA4F;IAC5F,QAAQ,EAAE,eAAe,GAAG,IAAI,CAAA;IAChC,8BAA8B;IAC9B,QAAQ,EAAE,iBAAiB,CAAA;IAC3B,+BAA+B;IAC/B,MAAM,EAAE,YAAY,CAAA;IACpB,2DAA2D;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,2EAA2E;IAC3E,MAAM,CAAC,EAAE,UAAU,CAAA;IACnB,mFAAmF;IACnF,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,gEAAgE;IAChE,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,uCAAuC;IACvC,WAAW,EAAE,kBAAkB,CAAA;IAC/B,0BAA0B;IAC1B,cAAc,EAAE,cAAc,CAAA;IAC9B,qBAAqB;IACrB,OAAO,EAAE,YAAY,EAAE,CAAA;IACvB,8DAA8D;IAC9D,OAAO,CAAC,EAAE,gBAAgB,CAAC,gBAAgB,CAAC,CAAA;CAC7C,CAAA;AACD,QAAA,MAAM,YAAY;IAEd,sEAAsE;sCACpC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;;IADxD,sEAAsE;sCACpC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;iGAoTxD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Operation.vue.js","names":[],"sources":["../../../../src/v2/features/operation/Operation.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Operation example page\n *\n * Displays an operation with a specific example selected\n * - View example request data\n * - Modify example request data\n * - Send example request\n */\nexport default {}\n\nexport type OperationProps = {\n /** The slug of the currently selected document in the workspace */\n documentSlug: string\n /** The currently active document — OpenAPI-only, the operation page has no AsyncAPI path */\n document: OpenApiDocument | null\n /** The workspace event bus */\n eventBus: WorkspaceEventBus\n /** The layout of the client */\n layout: ClientLayout\n /** The API path currently selected (e.g. \"/users/{id}\") */\n path?: string\n /** The HTTP method for the currently selected API path (e.g. GET, POST) */\n method?: HttpMethod\n /** The name of the currently selected example (for examples within an endpoint) */\n exampleName?: string\n /** Resolve the selected entry from the OpenAPI webhooks map. */\n isWebhook?: boolean\n /** The currently active environment */\n environment: XScalarEnvironment\n /** The workspace store */\n workspaceStore: WorkspaceStore\n /** Client plugins */\n plugins: ClientPlugin[]\n /** App or modal options forwarded to operation/auth blocks */\n options?: MaybeRefOrGetter<ApiClientOptions>\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { isElectron } from '@scalar/helpers/general/is-electron'\nimport type { HttpMethod } from '@scalar/helpers/http/http-methods'\nimport type { ClientPlugin } from '@scalar/oas-utils/helpers'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\nimport type { WorkspaceEventBus } from '@scalar/workspace-store/events'\nimport {\n getActiveProxyUrl,\n getRequestExampleContext,\n} from '@scalar/workspace-store/request-example'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport type { OpenApiDocument } from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document'\nimport { computed, toValue, type MaybeRefOrGetter } from 'vue'\n\nimport { OperationBlock } from '@/v2/blocks/operation-block'\nimport { APP_VERSION } from '@/v2/constants'\nimport { mapHiddenClientsConfig } from '@/v2/features/modal/helpers/map-hidden-clients-config'\nimport type { ClientLayout } from '@/v2/types/layout'\nimport type { ApiClientOptions } from '@/v2/types/options'\n\nconst {\n document,\n layout,\n eventBus,\n path,\n method,\n environment,\n exampleName,\n options,\n workspaceStore,\n plugins,\n documentSlug,\n isWebhook = false,\n} = defineProps<\n OperationProps & {\n /** Selected anyOf/oneOf request-body variants keyed by schema path */\n requestBodyCompositionSelection?: Record<string, number>\n }\n>()\n\n/**\n * Shared request-example context (operation, servers, auth scope, cookies). Recomputed when any\n * underlying workspace or route input changes — same reactivity as the previous local computeds.\n */\nconst requestExample = computed(() => {\n if (!path || !method || !exampleName || !document) {\n return null\n }\n\n const result = getRequestExampleContext(\n workspaceStore,\n documentSlug,\n { path, method, exampleName, isWebhook },\n {\n baseServerUrl: toValue(options)?.baseServerURL,\n fallbackDocument: document,\n isElectron: isElectron(),\n layout: layout === 'web' ? 'web' : 'other',\n servers: toValue(options)?.servers,\n appVersion: APP_VERSION,\n authentication: toValue(options)?.authentication,\n },\n )\n\n return result.ok ? result.data : null\n})\n\nconst operation = computed(() => requestExample.value?.operation ?? null)\nconst workspaceCookies = computed(\n () => requestExample.value?.cookies.workspace ?? [],\n)\nconst documentCookies = computed(\n () => requestExample.value?.cookies.document ?? [],\n)\nconst servers = computed(() => requestExample.value?.servers.list ?? [])\nconst selectedServer = computed(\n () => requestExample.value?.servers.selected ?? null,\n)\nconst serverMeta = computed(\n () => requestExample.value?.servers.meta ?? { type: 'document' as const },\n)\n\nconst securitySchemes = computed(\n () => requestExample.value?.security.schemes ?? {},\n)\n\nconst selectedSecurity = computed(\n () =>\n requestExample.value?.security.selected ?? {\n selectedIndex: -1,\n selectedSchemes: [],\n },\n)\nconst selectedSecuritySchemes = computed(\n () => requestExample.value?.security.selectedSchemes ?? [],\n)\nconst securityRequirements = computed(\n () => requestExample.value?.security.requirements ?? [],\n)\nconst authMeta = computed(\n () => requestExample.value?.security.meta ?? { type: 'document' as const },\n)\n\nconst defaultHeaders = computed(\n () => requestExample.value?.headers.default ?? {},\n)\n\n/** Combine environments from document and workspace into a unique array of environment names */\nconst environments = computed(() => {\n return Array.from(\n new Set(\n Object.keys({\n ...document?.['x-scalar-environments'],\n ...workspaceStore.workspace['x-scalar-environments'],\n }),\n ),\n )\n})\n\n/** Temporarily use the old config.hiddenClients until we migrate to the new httpClients config */\nconst httpClients = computed(() =>\n mapHiddenClientsConfig(toValue(options)?.hiddenClients),\n)\n</script>\n\n<template>\n <!-- Operation exists -->\n <template v-if=\"path && method && exampleName && operation && document\">\n <OperationBlock\n :activeEnvironment=\"\n workspaceStore.workspace['x-scalar-active-environment']\n \"\n :appVersion=\"APP_VERSION\"\n :authMeta\n :defaultHeaders\n :document\n :documentCookies\n :documentSecurity=\"document?.security ?? []\"\n :documentSlug\n :documentUrl=\"document?.['x-scalar-original-source-url']\"\n :environment\n :environments\n :eventBus\n :exampleKey=\"exampleName\"\n :hideClientButton=\"toValue(options)?.hideClientButton ?? false\"\n :history=\"workspaceStore.history.getHistory(documentSlug, path, method)\"\n :httpClients\n :layout\n :method\n :isWebhook\n :operation\n :options\n :path\n :plugins=\"plugins\"\n :proxyUrl=\"\n getActiveProxyUrl(\n workspaceStore.workspace['x-scalar-active-proxy'],\n layout === 'web' ? 'web' : 'other',\n ) ?? ''\n \"\n :requestBodyCompositionSelection\n :securityRequirements=\"securityRequirements\"\n :securitySchemes\n :selectedClient=\"workspaceStore.workspace['x-scalar-default-client']\"\n :selectedSecurity=\"selectedSecurity\"\n :selectedSecuritySchemes=\"selectedSecuritySchemes\"\n :server=\"selectedServer\"\n :serverMeta\n :servers\n :workspaceCookies />\n </template>\n\n <!-- Empty state -->\n <div\n v-else\n class=\"flex h-full w-full items-center justify-center\">\n <span class=\"text-c-3\">Select an operation to view details</span>\n </div>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"Operation.vue.js","names":[],"sources":["../../../../src/v2/features/operation/Operation.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Operation example page\n *\n * Displays an operation with a specific example selected\n * - View example request data\n * - Modify example request data\n * - Send example request\n */\nexport default {}\n\nexport type OperationProps = {\n /** Hidden modals keep their operation mounted without downloading examples. */\n isActive?: boolean\n /** The slug of the currently selected document in the workspace */\n documentSlug: string\n /** The currently active document — OpenAPI-only, the operation page has no AsyncAPI path */\n document: OpenApiDocument | null\n /** The workspace event bus */\n eventBus: WorkspaceEventBus\n /** The layout of the client */\n layout: ClientLayout\n /** The API path currently selected (e.g. \"/users/{id}\") */\n path?: string\n /** The HTTP method for the currently selected API path (e.g. GET, POST) */\n method?: HttpMethod\n /** The name of the currently selected example (for examples within an endpoint) */\n exampleName?: string\n /** Resolve the selected entry from the OpenAPI webhooks map. */\n isWebhook?: boolean\n /** The currently active environment */\n environment: XScalarEnvironment\n /** The workspace store */\n workspaceStore: WorkspaceStore\n /** Client plugins */\n plugins: ClientPlugin[]\n /** App or modal options forwarded to operation/auth blocks */\n options?: MaybeRefOrGetter<ApiClientOptions>\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { isElectron } from '@scalar/helpers/general/is-electron'\nimport type { HttpMethod } from '@scalar/helpers/http/http-methods'\nimport type { ClientPlugin } from '@scalar/oas-utils/helpers'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\nimport type { WorkspaceEventBus } from '@scalar/workspace-store/events'\nimport { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport {\n getOperationExamples,\n resolveOperationExamples,\n} from '@scalar/workspace-store/helpers/operation-examples'\nimport {\n EXTERNAL_EXAMPLES,\n useExampleVisibility,\n useExternalExamples,\n} from '@scalar/workspace-store/helpers/use-external-examples'\nimport {\n getActiveProxyUrl,\n getRequestExampleContext,\n getSelectedBodyContentType,\n} from '@scalar/workspace-store/request-example'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport type { OpenApiDocument } from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document'\nimport {\n computed,\n provide,\n ref,\n toValue,\n type ComponentPublicInstance,\n type MaybeRefOrGetter,\n} from 'vue'\n\nimport { OperationBlock } from '@/v2/blocks/operation-block'\nimport { APP_VERSION } from '@/v2/constants'\nimport { mapHiddenClientsConfig } from '@/v2/features/modal/helpers/map-hidden-clients-config'\nimport type { ClientLayout } from '@/v2/types/layout'\nimport type { ApiClientOptions } from '@/v2/types/options'\n\nconst {\n isActive = true,\n document,\n layout,\n eventBus,\n path,\n method,\n environment,\n exampleName,\n options,\n workspaceStore,\n plugins,\n documentSlug,\n isWebhook = false,\n} = defineProps<\n OperationProps & {\n /** Selected anyOf/oneOf request-body variants keyed by schema path */\n requestBodyCompositionSelection?: Record<string, number>\n }\n>()\n\n/**\n * Shared request-example context (operation, servers, auth scope, cookies). Recomputed when any\n * underlying workspace or route input changes — same reactivity as the previous local computeds.\n */\nconst requestExample = computed(() => {\n if (!path || !method || !exampleName || !document) {\n return null\n }\n\n const result = getRequestExampleContext(\n workspaceStore,\n documentSlug,\n { path, method, exampleName, isWebhook },\n {\n baseServerUrl: toValue(options)?.baseServerURL,\n fallbackDocument: document,\n isElectron: isElectron(),\n layout: layout === 'web' ? 'web' : 'other',\n servers: toValue(options)?.servers,\n appVersion: APP_VERSION,\n authentication: toValue(options)?.authentication,\n },\n )\n\n return result.ok ? result.data : null\n})\n\nconst sourceOperation = computed(() => requestExample.value?.operation ?? null)\nconst getResolver = (): ReturnType<WorkspaceStore['externalExamples']> =>\n workspaceStore.externalExamples(documentSlug)\nprovide(EXTERNAL_EXAMPLES, getResolver)\nconst contentType = computed(\n () =>\n getSelectedBodyContentType(\n getResolvedRef(sourceOperation.value?.requestBody),\n exampleName,\n ) ?? undefined,\n)\nconst container = ref<ComponentPublicInstance | null>(null)\nconst visible = useExampleVisibility(container)\nconst externalExamples = useExternalExamples(\n () =>\n sourceOperation.value\n ? getOperationExamples(\n sourceOperation.value,\n exampleName ?? '',\n contentType.value,\n )\n : [],\n () => isActive && visible.value,\n getResolver,\n)\nconst operation = computed(() =>\n sourceOperation.value\n ? resolveOperationExamples(\n sourceOperation.value,\n exampleName ?? '',\n contentType.value,\n externalExamples.resolve,\n )\n : null,\n)\nconst workspaceCookies = computed(\n () => requestExample.value?.cookies.workspace ?? [],\n)\nconst documentCookies = computed(\n () => requestExample.value?.cookies.document ?? [],\n)\nconst servers = computed(() => requestExample.value?.servers.list ?? [])\nconst selectedServer = computed(\n () => requestExample.value?.servers.selected ?? null,\n)\nconst serverMeta = computed(\n () => requestExample.value?.servers.meta ?? { type: 'document' as const },\n)\n\nconst securitySchemes = computed(\n () => requestExample.value?.security.schemes ?? {},\n)\n\nconst selectedSecurity = computed(\n () =>\n requestExample.value?.security.selected ?? {\n selectedIndex: -1,\n selectedSchemes: [],\n },\n)\nconst selectedSecuritySchemes = computed(\n () => requestExample.value?.security.selectedSchemes ?? [],\n)\nconst securityRequirements = computed(\n () => requestExample.value?.security.requirements ?? [],\n)\nconst authMeta = computed(\n () => requestExample.value?.security.meta ?? { type: 'document' as const },\n)\n\nconst defaultHeaders = computed(\n () => requestExample.value?.headers.default ?? {},\n)\n\n/** Combine environments from document and workspace into a unique array of environment names */\nconst environments = computed(() => {\n return Array.from(\n new Set(\n Object.keys({\n ...document?.['x-scalar-environments'],\n ...workspaceStore.workspace['x-scalar-environments'],\n }),\n ),\n )\n})\n\n/** Temporarily use the old config.hiddenClients until we migrate to the new httpClients config */\nconst httpClients = computed(() =>\n mapHiddenClientsConfig(toValue(options)?.hiddenClients),\n)\n</script>\n\n<template>\n <!-- Operation exists -->\n <template v-if=\"path && method && exampleName && operation && document\">\n <OperationBlock\n ref=\"container\"\n :activeEnvironment=\"\n workspaceStore.workspace['x-scalar-active-environment']\n \"\n :appVersion=\"APP_VERSION\"\n :authMeta\n :defaultHeaders\n :document\n :documentCookies\n :documentSecurity=\"document?.security ?? []\"\n :documentSlug\n :documentUrl=\"document?.['x-scalar-original-source-url']\"\n :environment\n :environments\n :eventBus\n :exampleKey=\"exampleName\"\n :externalExamplesFailed=\"externalExamples.failed.value\"\n :externalExamplesPending=\"externalExamples.pending.value\"\n :hideClientButton=\"toValue(options)?.hideClientButton ?? false\"\n :history=\"workspaceStore.history.getHistory(documentSlug, path, method)\"\n :httpClients\n :isWebhook\n :layout\n :method\n :operation\n :options\n :path\n :plugins=\"plugins\"\n :proxyUrl=\"\n getActiveProxyUrl(\n workspaceStore.workspace['x-scalar-active-proxy'],\n layout === 'web' ? 'web' : 'other',\n ) ?? ''\n \"\n :requestBodyCompositionSelection\n :securityRequirements=\"securityRequirements\"\n :securitySchemes\n :selectedClient=\"workspaceStore.workspace['x-scalar-default-client']\"\n :selectedSecurity=\"selectedSecurity\"\n :selectedSecuritySchemes=\"selectedSecuritySchemes\"\n :server=\"selectedServer\"\n :serverMeta\n :servers\n :workspaceCookies\n @retry:externalExamples=\"externalExamples.retry\" />\n </template>\n\n <!-- Empty state -->\n <div\n v-else\n class=\"flex h-full w-full items-center justify-center\">\n <span class=\"text-c-3\">Select an operation to view details</span>\n </div>\n</template>\n"],"mappings":""}
@@ -1,9 +1,12 @@
1
1
  import OperationBlock_default from "../../blocks/operation-block/OperationBlock.vue.js";
2
2
  import { APP_VERSION } from "../../constants.js";
3
3
  import { mapHiddenClientsConfig } from "../modal/helpers/map-hidden-clients-config.js";
4
- import { computed, createBlock, createElementBlock, createElementVNode, defineComponent, openBlock, toValue, unref } from "vue";
5
- import { getActiveProxyUrl, getRequestExampleContext } from "@scalar/workspace-store/request-example";
4
+ import { computed, createBlock, createElementBlock, createElementVNode, defineComponent, openBlock, provide, ref, toValue, unref } from "vue";
5
+ import { getActiveProxyUrl, getRequestExampleContext, getSelectedBodyContentType } from "@scalar/workspace-store/request-example";
6
6
  import { isElectron } from "@scalar/helpers/general/is-electron";
7
+ import { getResolvedRef } from "@scalar/workspace-store/helpers/get-resolved-ref";
8
+ import { getOperationExamples, resolveOperationExamples } from "@scalar/workspace-store/helpers/operation-examples";
9
+ import { EXTERNAL_EXAMPLES, useExampleVisibility, useExternalExamples } from "@scalar/workspace-store/helpers/use-external-examples";
7
10
  //#region src/v2/features/operation/Operation.vue?vue&type=script&setup=true&lang.ts
8
11
  var _hoisted_1 = {
9
12
  key: 1,
@@ -12,6 +15,10 @@ var _hoisted_1 = {
12
15
  var Operation_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
13
16
  __name: "Operation",
14
17
  props: {
18
+ isActive: {
19
+ type: Boolean,
20
+ default: true
21
+ },
15
22
  documentSlug: {},
16
23
  document: {},
17
24
  eventBus: {},
@@ -52,7 +59,14 @@ var Operation_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
52
59
  });
53
60
  return result.ok ? result.data : null;
54
61
  });
55
- const operation = computed(() => requestExample.value?.operation ?? null);
62
+ const sourceOperation = computed(() => requestExample.value?.operation ?? null);
63
+ const getResolver = () => __props.workspaceStore.externalExamples(__props.documentSlug);
64
+ provide(EXTERNAL_EXAMPLES, getResolver);
65
+ const contentType = computed(() => getSelectedBodyContentType(getResolvedRef(sourceOperation.value?.requestBody), __props.exampleName) ?? void 0);
66
+ const container = ref(null);
67
+ const visible = useExampleVisibility(container);
68
+ const externalExamples = useExternalExamples(() => sourceOperation.value ? getOperationExamples(sourceOperation.value, __props.exampleName ?? "", contentType.value) : [], () => __props.isActive && visible.value, getResolver);
69
+ const operation = computed(() => sourceOperation.value ? resolveOperationExamples(sourceOperation.value, __props.exampleName ?? "", contentType.value, externalExamples.resolve) : null);
56
70
  const workspaceCookies = computed(() => requestExample.value?.cookies.workspace ?? []);
57
71
  const documentCookies = computed(() => requestExample.value?.cookies.document ?? []);
58
72
  const servers = computed(() => requestExample.value?.servers.list ?? []);
@@ -79,6 +93,8 @@ var Operation_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
79
93
  return (_ctx, _cache) => {
80
94
  return __props.path && __props.method && __props.exampleName && operation.value && __props.document ? (openBlock(), createBlock(unref(OperationBlock_default), {
81
95
  key: 0,
96
+ ref_key: "container",
97
+ ref: container,
82
98
  activeEnvironment: __props.workspaceStore.workspace["x-scalar-active-environment"],
83
99
  appVersion: unref(APP_VERSION),
84
100
  authMeta: authMeta.value,
@@ -92,12 +108,14 @@ var Operation_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
92
108
  environments: environments.value,
93
109
  eventBus: __props.eventBus,
94
110
  exampleKey: __props.exampleName,
111
+ externalExamplesFailed: unref(externalExamples).failed.value,
112
+ externalExamplesPending: unref(externalExamples).pending.value,
95
113
  hideClientButton: toValue(__props.options)?.hideClientButton ?? false,
96
114
  history: __props.workspaceStore.history.getHistory(__props.documentSlug, __props.path, __props.method),
97
115
  httpClients: httpClients.value,
116
+ isWebhook: __props.isWebhook,
98
117
  layout: __props.layout,
99
118
  method: __props.method,
100
- isWebhook: __props.isWebhook,
101
119
  operation: operation.value,
102
120
  options: __props.options,
103
121
  path: __props.path,
@@ -112,7 +130,8 @@ var Operation_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
112
130
  server: selectedServer.value,
113
131
  serverMeta: serverMeta.value,
114
132
  servers: servers.value,
115
- workspaceCookies: workspaceCookies.value
133
+ workspaceCookies: workspaceCookies.value,
134
+ "onRetry:externalExamples": unref(externalExamples).retry
116
135
  }, null, 8, [
117
136
  "activeEnvironment",
118
137
  "appVersion",
@@ -127,12 +146,14 @@ var Operation_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
127
146
  "environments",
128
147
  "eventBus",
129
148
  "exampleKey",
149
+ "externalExamplesFailed",
150
+ "externalExamplesPending",
130
151
  "hideClientButton",
131
152
  "history",
132
153
  "httpClients",
154
+ "isWebhook",
133
155
  "layout",
134
156
  "method",
135
- "isWebhook",
136
157
  "operation",
137
158
  "options",
138
159
  "path",
@@ -147,7 +168,8 @@ var Operation_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
147
168
  "server",
148
169
  "serverMeta",
149
170
  "servers",
150
- "workspaceCookies"
171
+ "workspaceCookies",
172
+ "onRetry:externalExamples"
151
173
  ])) : (openBlock(), createElementBlock("div", _hoisted_1, [..._cache[0] || (_cache[0] = [createElementVNode("span", { class: "text-c-3" }, "Select an operation to view details", -1)])]));
152
174
  };
153
175
  }