@scalar/api-client 3.19.0 → 3.19.1

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 (58) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/style.css +55 -25
  3. package/dist/v2/blocks/request-block/RequestBlock.vue.script.js.map +1 -1
  4. package/dist/v2/blocks/request-block/components/RequestBody.vue.d.ts.map +1 -1
  5. package/dist/v2/blocks/request-block/components/RequestBody.vue.js +1 -1
  6. package/dist/v2/blocks/request-block/components/RequestBody.vue.js.map +1 -1
  7. package/dist/v2/blocks/request-block/components/RequestBody.vue.script.js +21 -5
  8. package/dist/v2/blocks/request-block/components/RequestBody.vue.script.js.map +1 -1
  9. package/dist/v2/blocks/response-block/components/ResponseBodyRaw.vue.d.ts.map +1 -1
  10. package/dist/v2/blocks/response-block/components/ResponseBodyRaw.vue.js +1 -1
  11. package/dist/v2/blocks/response-block/components/ResponseBodyRaw.vue.js.map +1 -1
  12. package/dist/v2/blocks/response-block/components/ResponseBodyRaw.vue.script.js +42 -16
  13. package/dist/v2/blocks/response-block/components/ResponseBodyRaw.vue.script.js.map +1 -1
  14. package/dist/v2/blocks/response-block/helpers/media-types.d.ts.map +1 -1
  15. package/dist/v2/blocks/response-block/helpers/media-types.js +5 -0
  16. package/dist/v2/blocks/response-block/helpers/media-types.js.map +1 -1
  17. package/dist/v2/blocks/scalar-auth-selector-block/components/AuthSelector.vue.script.js.map +1 -1
  18. package/dist/v2/blocks/scalar-auth-selector-block/components/OAuth2Metadata.vue.d.ts +16 -0
  19. package/dist/v2/blocks/scalar-auth-selector-block/components/OAuth2Metadata.vue.d.ts.map +1 -0
  20. package/dist/v2/blocks/scalar-auth-selector-block/components/OAuth2Metadata.vue.js +7 -0
  21. package/dist/v2/blocks/scalar-auth-selector-block/components/OAuth2Metadata.vue.js.map +1 -0
  22. package/dist/v2/blocks/scalar-auth-selector-block/components/OAuth2Metadata.vue.script.js +86 -0
  23. package/dist/v2/blocks/scalar-auth-selector-block/components/OAuth2Metadata.vue.script.js.map +1 -0
  24. package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue.d.ts.map +1 -1
  25. package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue.js.map +1 -1
  26. package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue.script.js +19 -2
  27. package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue.script.js.map +1 -1
  28. package/dist/v2/blocks/scalar-auth-selector-block/helpers/fetch-oauth2-metadata.d.ts +6 -0
  29. package/dist/v2/blocks/scalar-auth-selector-block/helpers/fetch-oauth2-metadata.d.ts.map +1 -0
  30. package/dist/v2/blocks/scalar-auth-selector-block/helpers/fetch-oauth2-metadata.js +25 -0
  31. package/dist/v2/blocks/scalar-auth-selector-block/helpers/fetch-oauth2-metadata.js.map +1 -0
  32. package/dist/v2/blocks/scalar-auth-selector-block/helpers/fetch-openid-connect-discovery.d.ts +1 -2
  33. package/dist/v2/blocks/scalar-auth-selector-block/helpers/fetch-openid-connect-discovery.d.ts.map +1 -1
  34. package/dist/v2/blocks/scalar-auth-selector-block/helpers/fetch-openid-connect-discovery.js +2 -2
  35. package/dist/v2/blocks/scalar-auth-selector-block/helpers/fetch-openid-connect-discovery.js.map +1 -1
  36. package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth.d.ts.map +1 -1
  37. package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth.js +13 -9
  38. package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth.js.map +1 -1
  39. package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth2-metadata-to-flows.d.ts +9 -0
  40. package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth2-metadata-to-flows.d.ts.map +1 -0
  41. package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth2-metadata-to-flows.js +36 -0
  42. package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth2-metadata-to-flows.js.map +1 -0
  43. package/dist/v2/components/code-input/CodeInput.vue.d.ts +2 -2
  44. package/dist/v2/components/code-input/CodeInput.vue.d.ts.map +1 -1
  45. package/dist/v2/components/code-input/CodeInput.vue.js +1 -1
  46. package/dist/v2/components/code-input/CodeInput.vue.js.map +1 -1
  47. package/dist/v2/components/code-input/CodeInput.vue.script.js +40 -9
  48. package/dist/v2/components/code-input/CodeInput.vue.script.js.map +1 -1
  49. package/dist/v2/components/server/ServerDropdown.vue.d.ts.map +1 -1
  50. package/dist/v2/components/server/ServerDropdown.vue.js.map +1 -1
  51. package/dist/v2/components/server/ServerDropdown.vue.script.js +1 -1
  52. package/dist/v2/components/server/ServerDropdown.vue.script.js.map +1 -1
  53. package/dist/v2/constants.js +1 -1
  54. package/dist/v2/features/modal/helpers/resolve-route-parameters.d.ts +9 -3
  55. package/dist/v2/features/modal/helpers/resolve-route-parameters.d.ts.map +1 -1
  56. package/dist/v2/features/modal/helpers/resolve-route-parameters.js.map +1 -1
  57. package/dist/vue-styles.css +33 -23
  58. package/package.json +16 -16
@@ -1 +1 @@
1
- {"version":3,"file":"CodeInput.vue.script.js","names":["$attrs","$slots"],"sources":["../../../../src/v2/components/code-input/CodeInput.vue"],"sourcesContent":["<script lang=\"ts\">\nexport type CodeInputModelValue =\n | string\n | number\n | boolean\n | Array<string | number | boolean>\n | Record<string, unknown>\n\n/**\n * CodeInput\n *\n * A versatile input component that adapts its rendering based on props:\n * - Disabled mode: Read-only text display\n * - Select mode: Dropdown for enums, booleans, or examples\n * - Editor mode: CodeMirror with environment variable support\n *\n * Type `{{` to trigger autocomplete for environment variables and runtime context functions\n * (for example `{{$guid}}`) when an environment is provided.\n * It takes in any data but always will emit a string value,\n * this string should then be parsed in accordance to the schema or content type.\n *\n * @example\n * ```vue\n * <!-- Basic input with environment variables -->\n * <CodeInput v-model=\"value\" :environment=\"env\" />\n *\n * <!-- Boolean select -->\n * <CodeInput v-model=\"flag\" type=\"boolean\" />\n *\n * <!-- JSON editor with linting -->\n * <CodeInput v-model=\"data\" language=\"json\" :lint=\"true\" />\n * ```\n */\nexport default {\n inheritAttrs: false,\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { isDefined } from '@scalar/helpers/array/is-defined'\nimport {\n colorPicker as colorPickerExtension,\n useCodeMirror,\n useDropdown,\n type CodeMirrorLanguage,\n type Extension,\n} from '@scalar/use-codemirror'\nimport {\n CONTEXT_FUNCTION_NAMES,\n getContextFunctionComment,\n isContextFunctionName,\n} from '@scalar/workspace-store/request-example'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport { nanoid } from 'nanoid'\nimport { computed, ref, toRef, useAttrs, watch, type Ref } from 'vue'\n\nimport DataTableInputSelect from '@/v2/components/data-table/DataTableInputSelect.vue'\nimport EnvironmentVariableDropdown from '@/v2/features/environments/components/EnvironmentVariablesDropdown.vue'\nimport type { ClientLayout } from '@/v2/types/layout'\n\nimport { backspaceCommand, pillPlugin } from './code-variable-widget'\n\ntype Props = {\n modelValue: CodeInputModelValue\n /** Environment for variable substitution. Pass undefined to disable environment variables */\n environment: XScalarEnvironment | undefined\n /** Type of the input value, affects rendering mode for booleans */\n type?: string | string[]\n /** Render as disabled text display */\n disabled?: boolean\n /** Show error styling */\n error?: boolean\n /** Layout context affects styling and behavior */\n layout?: ClientLayout\n /** Predefined enum values, triggers select mode */\n enum?: string[]\n /** Example values, triggers select mode */\n examples?: string[]\n /** Default value to show in select mode */\n default?: Props['modelValue']\n /** Allow null in boolean select options */\n nullable?: boolean\n /** Placeholder text for empty input */\n placeholder?: string\n /** Show required indicator */\n required?: boolean\n /** Enable color picker extension */\n colorPicker?: boolean\n /** Show line numbers in editor */\n lineNumbers?: boolean\n /** Enable linting */\n lint?: boolean\n /** Enable line wrapping */\n lineWrapping?: boolean\n /** CodeMirror language mode */\n language?: CodeMirrorLanguage\n /** Additional CodeMirror extensions */\n extensions?: Extension[]\n /** Disable tab key for indentation */\n disableTabIndent?: boolean\n /** Disable enter key */\n disableEnter?: boolean\n /** Disable automatic bracket closing */\n disableCloseBrackets?: boolean\n /** Emit submit event on blur */\n emitOnBlur?: boolean\n /** Enable environment variable pills */\n withVariables?: boolean\n /** Enable fake data suggestions like $guid, $timestamp, etc. Should only be enabled for parameters and request bodies */\n withFakeData?: boolean\n /** Emit change event even if the value is the same */\n alwaysEmitChange?: boolean\n /** Custom change handler, prevents default emit */\n handleFieldChange?: (value: string) => void\n /** Custom submit handler, prevents default emit */\n handleFieldSubmit?: (value: string) => void\n /** Put a linethrough on the input text */\n linethrough?: boolean\n}\n\nconst {\n modelValue,\n environment,\n type,\n disabled = false,\n error = false,\n layout = 'desktop',\n enum: enumProp,\n examples,\n default: defaultProp,\n nullable = false,\n placeholder,\n required,\n colorPicker = false,\n lineNumbers = false,\n lint = false,\n lineWrapping = false,\n language,\n extensions = [],\n disableTabIndent = false,\n disableEnter = false,\n disableCloseBrackets = false,\n emitOnBlur = true,\n alwaysEmitChange = false,\n withVariables = true,\n withFakeData = false,\n handleFieldChange,\n handleFieldSubmit,\n} = defineProps<Props>()\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string]\n 'submit': [value: string, event: KeyboardEvent | FocusEvent]\n 'navigate': [route: { page: 'document'; path: 'environment' }]\n 'blur': [value: string, event: FocusEvent]\n}>()\n\n// ---------------------------------------------------------------------------\n// Component identity and focus state\n\nconst attrs = useAttrs()\nconst componentId =\n (typeof attrs.id === 'string' && attrs.id) || `id-${nanoid()}`\nconst isFocused = ref(false)\n\n// ---------------------------------------------------------------------------\n// Rendering mode detection\n\n/**\n * Determines if we should render a select dropdown for boolean types.\n */\nconst isBooleanMode = computed((): boolean => {\n if (enumProp?.length) {\n return false\n }\n return type === 'boolean' || (Array.isArray(type) && type.includes('boolean'))\n})\n\n/**\n * Options for boolean select mode.\n */\nconst booleanOptions = computed((): string[] =>\n nullable ? ['true', 'false', 'null'] : ['true', 'false'],\n)\n\n/**\n * Default type when dealing with type arrays.\n * Finds the first non-null type.\n */\nconst defaultType = computed((): string | undefined => {\n if (Array.isArray(type)) {\n return type.find((t) => t !== 'null') ?? 'string'\n }\n return type\n})\n\n// ---------------------------------------------------------------------------\n// Event handlers\n\n/**\n * Handles value changes during typing.\n */\nconst handleChange = (value: string): void => {\n if (!alwaysEmitChange && value === serializeValue(modelValue)) {\n return\n }\n\n // Use custom handler or emit update\n if (handleFieldChange) {\n handleFieldChange(value)\n } else {\n emit('update:modelValue', value)\n }\n}\n\n/**\n * Handles form submission (enter key or blur with emitOnBlur).\n */\nconst handleSubmit = (\n value: string,\n event: KeyboardEvent | FocusEvent,\n): void => {\n if (handleFieldSubmit) {\n handleFieldSubmit(value)\n } else {\n emit('submit', value, event)\n }\n}\n\n/**\n * Handles input blur event.\n */\nconst handleBlur = (value: string, event: FocusEvent): void => {\n isFocused.value = false\n\n if (emitOnBlur && modelValue) {\n handleSubmit(value, event)\n }\n\n emit('blur', value, event)\n}\n\n/**\n * Handles model value updates from select components.\n */\nconst handleSelectChange = (value: string): void =>\n emit('update:modelValue', value)\n\n// ---------------------------------------------------------------------------\n// CodeMirror setup\n\n/**\n * Build extensions array.\n * Note: Extensions are not reactive after initialization.\n */\nconst buildExtensions = (): Extension[] => {\n const extensionsList: Extension[] = [...extensions]\n\n if (colorPicker) {\n extensionsList.push(colorPickerExtension)\n }\n\n return extensionsList\n}\n\n/**\n * Reactive pill plugin for environment variable visualization.\n */\nconst contextFunctionDropdownItems = computed(() =>\n withFakeData\n ? CONTEXT_FUNCTION_NAMES.map((key) => ({\n key,\n description: getContextFunctionComment(key),\n }))\n : [],\n)\n\nconst pillPluginExtension = computed(() =>\n pillPlugin({\n environment,\n isContextFunctionName,\n isReadOnly: layout === 'modal',\n }),\n)\n\n/**\n * Combined extensions for CodeMirror.\n */\nconst codeMirrorExtensions = computed((): Extension[] => [\n ...buildExtensions(),\n pillPluginExtension.value,\n backspaceCommand,\n])\n\nconst codeMirrorRef: Ref<HTMLDivElement | null> = ref(null)\n\n/** Converts the model value to a string for CodeMirror */\nconst serializeValue = (value: CodeInputModelValue): string => {\n if (typeof value === 'string') {\n return value\n }\n return JSON.stringify(value)\n}\n\nconst { codeMirror, setCodeMirrorContent } = useCodeMirror({\n content: toRef(() => serializeValue(modelValue)),\n onChange: (value) => {\n handleChange(value)\n updateDropdownVisibility()\n },\n onFocus: () => {\n isFocused.value = true\n },\n onBlur: handleBlur,\n codeMirrorRef,\n disableTabIndent: toRef(() => disableTabIndent),\n disableEnter: toRef(() => disableEnter),\n disableCloseBrackets: toRef(() => disableCloseBrackets),\n lineNumbers: toRef(() => lineNumbers),\n language: toRef(() => language),\n lint: toRef(() => lint),\n extensions: codeMirrorExtensions,\n placeholder: toRef(() => placeholder),\n})\n\n/**\n * Handle autofocus attribute.\n */\nwatch(codeMirror, () => {\n if (codeMirror.value && Object.hasOwn(attrs, 'autofocus')) {\n codeMirror.value.focus()\n }\n})\n\n// ---------------------------------------------------------------------------\n// Environment variable dropdown\n\nconst showDropdown = ref(false)\nconst dropdownQuery = ref('')\nconst dropdownPosition = ref({ left: 0, top: 0 })\nconst dropdownRef = ref<InstanceType<\n typeof EnvironmentVariableDropdown\n> | null>(null)\n\nconst { handleDropdownSelect, updateDropdownVisibility } = useDropdown({\n codeMirror,\n query: dropdownQuery,\n showDropdown,\n dropdownPosition,\n})\n\n/**\n * Determines if the environment variable dropdown should be visible.\n * Shows when environment is defined (for env vars) or withFakeData is true (for context functions)\n */\nconst displayVariablesDropdown = computed((): boolean => {\n return (\n showDropdown.value &&\n withVariables &&\n layout !== 'modal' &&\n (Boolean(environment) || withFakeData)\n )\n})\n\n// ---------------------------------------------------------------------------\n// Keyboard event handling\n\n/**\n * Handles keyboard navigation for dropdown and form submission.\n */\nconst handleKeyDown = (key: string, event: KeyboardEvent): void => {\n if (showDropdown.value) {\n if (key === 'down' || key === 'up') {\n event.preventDefault()\n dropdownRef.value?.handleArrowKey(key)\n } else if (key === 'enter') {\n event.preventDefault()\n dropdownRef.value?.handleSelect()\n }\n return\n }\n\n if (key === 'escape' && !disableTabIndent) {\n event.stopPropagation()\n }\n\n if (key === 'enter' && event.target instanceof HTMLDivElement) {\n handleSubmit(codeMirror.value?.state.doc.toString() ?? '', event)\n }\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n\ndefineExpose({\n /**\n * Focus the codemirror element\n *\n * @param cursorAtEnd boolean place the cursor at the end of the input\n */\n focus: (position?: 'start' | 'end' | number) => {\n if (!codeMirror.value) {\n return\n }\n codeMirror.value.focus()\n\n if (!isDefined(position)) {\n return\n }\n\n const anchor = (() => {\n if (position === 'start') {\n return 0\n }\n if (position === 'end') {\n return codeMirror.value.state.doc.length\n }\n return position\n })()\n\n // Move the cursor to the specified position\n codeMirror.value.dispatch({\n selection: { anchor },\n scrollIntoView: true,\n })\n },\n isFocused,\n handleChange,\n handleSubmit,\n handleBlur,\n booleanOptions,\n codeMirror,\n codeMirrorRef,\n modelValue,\n setCodeMirrorContent,\n cursorPosition: () => codeMirror.value?.state.selection.main.head,\n serializeValue,\n})\n</script>\n\n<template>\n <!-- Disabled mode: read-only text display -->\n <div\n v-if=\"disabled\"\n class=\"text-c-2 flex cursor-default items-center justify-center\"\n :class=\"{\n 'font-code pr-2 pl-1 text-base': layout === 'modal',\n 'px-2': layout !== 'modal',\n 'line-through': linethrough,\n }\"\n data-testid=\"code-input-disabled\">\n <span class=\"whitespace-nowrap\">{{ modelValue }}</span>\n </div>\n\n <!-- Enum mode: select dropdown with predefined values -->\n <DataTableInputSelect\n v-else-if=\"enumProp?.length\"\n :default=\"defaultProp\"\n :modelValue=\"modelValue\"\n :type=\"defaultType\"\n :value=\"enumProp\"\n @update:modelValue=\"handleSelectChange\" />\n\n <!-- Boolean mode: select dropdown with true/false (and optionally null) -->\n <DataTableInputSelect\n v-else-if=\"isBooleanMode\"\n :default=\"defaultProp\"\n :modelValue=\"modelValue\"\n :value=\"booleanOptions\"\n @update:modelValue=\"handleSelectChange\" />\n\n <!-- Examples mode: select dropdown with example values -->\n <DataTableInputSelect\n v-else-if=\"examples?.length\"\n :default=\"defaultProp\"\n :modelValue=\"modelValue\"\n :value=\"examples\"\n @update:modelValue=\"handleSelectChange\" />\n\n <!-- Editor mode: CodeMirror with environment variable support -->\n <div\n v-else\n :id=\"componentId\"\n v-bind=\"$attrs\"\n ref=\"codeMirrorRef\"\n class=\"group/input group-[.alert]:outline-orange group-[.error]:outline-red font-code peer relative w-full overflow-hidden text-xs leading-[1.44] whitespace-nowrap -outline-offset-1 has-[:focus-visible]:rounded-[4px] has-[:focus-visible]:outline\"\n :class=\"{\n 'line-wrapping has-[:focus-visible]:bg-b-1 has-[:focus-visible]:absolute has-[:focus-visible]:z-1':\n lineWrapping,\n 'flow-code-input--error': error,\n 'line-through': linethrough,\n }\"\n @keydown.down.stop=\"handleKeyDown('down', $event)\"\n @keydown.enter=\"handleKeyDown('enter', $event)\"\n @keydown.escape=\"handleKeyDown('escape', $event)\"\n @keydown.up.stop=\"handleKeyDown('up', $event)\">\n <!-- Tab exit hint (shown when focused) -->\n <div\n v-if=\"!disableTabIndent\"\n class=\"z-context text-c-2 absolute right-1.5 bottom-1 hidden font-sans group-has-[:focus-visible]/input:block\"\n role=\"alert\">\n Press\n <kbd class=\"-mx-0.25 rounded border px-0.5 font-mono\">Esc</kbd> then\n <kbd class=\"-mx-0.25 rounded border px-0.5 font-mono\">Tab</kbd> to exit\n </div>\n </div>\n\n <!-- Warning slot (positioned absolutely) -->\n <div\n v-if=\"$slots.warning\"\n class=\"centered-y text-orange absolute right-7 text-xs\">\n <slot name=\"warning\" />\n </div>\n\n <!-- Icon slot (positioned absolutely) -->\n <div\n v-if=\"$slots.icon\"\n class=\"centered-y absolute right-0 flex h-full items-center p-1.5 group-has-[.cm-focused]:z-1\">\n <slot name=\"icon\" />\n </div>\n\n <!-- Required indicator -->\n <div\n v-if=\"required\"\n class=\"required centered-y text-xxs text-c-3 group-[.error]:text-red bg-b-1 pointer-events-none absolute right-0 mr-0.5 pt-px pr-2 opacity-100 shadow-[-8px_0_4px_var(--scalar-background-1)] transition-opacity duration-150 group-[.alert]:bg-transparent group-[.alert]:shadow-none group-[.error]:bg-transparent group-[.error]:shadow-none peer-has-[.cm-focused]:opacity-0\">\n Required\n </div>\n\n <!-- Environment variable autocomplete dropdown -->\n <EnvironmentVariableDropdown\n v-if=\"displayVariablesDropdown\"\n ref=\"dropdownRef\"\n :contextFunctionItems=\"contextFunctionDropdownItems\"\n :dropdownPosition=\"dropdownPosition\"\n :environment=\"environment\"\n :query=\"dropdownQuery\"\n @close=\"showDropdown = false\"\n @redirect=\"emit('navigate', { page: 'document', path: 'environment' })\"\n @select=\"handleDropdownSelect\" />\n</template>\n<style scoped>\n/*\n Deep styling for customizing Codemirror\n */\n:deep(.cm-editor) {\n height: 100%;\n outline: none;\n padding: 0;\n background: transparent;\n}\n:deep(.cm-placeholder) {\n color: var(--scalar-color-3);\n}\n:deep(.cm-content) {\n font-family: var(--scalar-font-code);\n font-size: var(--scalar-small);\n max-height: 20px;\n padding: 8px 0;\n}\n/* Tooltip helper */\n:deep(.cm-tooltip) {\n background: transparent !important;\n filter: brightness(var(--scalar-lifted-brightness));\n border-radius: var(--scalar-radius);\n box-shadow: var(--scalar-shadow-2);\n border: none !important;\n outline: none !important;\n overflow: hidden !important;\n}\n:deep(.cm-tooltip-autocomplete ul li) {\n padding: 3px 6px !important;\n}\n:deep(.cm-completionIcon-type:after) {\n color: var(--scalar-color-3) !important;\n}\n:deep(.cm-tooltip-autocomplete ul li[aria-selected]) {\n background: var(--scalar-background-2) !important;\n color: var(--scalar-color-1) !important;\n}\n:deep(.cm-tooltip-autocomplete ul) {\n padding: 6px !important;\n position: relative;\n}\n:deep(.cm-tooltip-autocomplete ul li:hover) {\n border-radius: 3px;\n color: var(--scalar-color-1) !important;\n background: var(--scalar-background-3) !important;\n}\n/* Disable active line highlighting */\n:deep(.cm-activeLine),\n:deep(.cm-activeLineGutter) {\n background-color: transparent;\n}\n/* Color selection matching */\n:deep(.cm-selectionMatch),\n:deep(.cm-matchingBracket) {\n border-radius: var(--scalar-radius);\n background: var(--scalar-background-4) !important;\n}\n/* Color Picker Swatches */\n:deep(.cm-css-color-picker-wrapper) {\n display: inline-flex;\n outline: 1px solid var(--scalar-background-3);\n border-radius: 3px;\n overflow: hidden;\n}\n/* Number gutter */\n:deep(.cm-gutters) {\n background-color: transparent;\n border-right: none;\n color: var(--scalar-color-3);\n font-size: var(--scalar-small);\n line-height: 22px;\n border-radius: 0 0 0 3px;\n}\n:deep(.cm-gutters:before) {\n content: '';\n position: absolute;\n top: 2px;\n left: 2px;\n width: calc(100% - 2px);\n height: calc(100% - 4px);\n border-radius: var(--scalar-radius) 0 0 var(--scalar-radius);\n background-color: var(--scalar-background-1);\n}\n:deep(.cm-gutterElement) {\n font-family: var(--scalar-font-code) !important;\n padding-left: 0px !important;\n padding-right: 6px !important;\n display: flex;\n align-items: center;\n justify-content: flex-end;\n position: relative;\n}\n:deep(.cm-lineNumbers .cm-gutterElement) {\n min-width: fit-content;\n}\n:deep(.cm-gutter + .cm-gutter :not(.cm-foldGutter) .cm-gutterElement) {\n padding-left: 0 !important;\n}\n:deep(.cm-scroller) {\n overflow: auto;\n}\n.line-wrapping:focus-within :deep(.cm-content) {\n display: inline-table;\n min-height: fit-content;\n padding: 3px 6px;\n white-space: break-spaces;\n word-break: break-all;\n}\n</style>\n<style>\n.cm-pill {\n color: var(--scalar-color-1) !important;\n padding: 0px 9px;\n display: inline-block;\n border-radius: var(--scalar-radius-full);\n font-size: var(--scalar-small);\n}\n.light-mode .cm-pill {\n background: var(--scalar-background-3) !important;\n}\n.dark-mode .cm-pill {\n background: color-mix(in srgb, var(--tw-bg-base), transparent 90%) !important;\n}\n.cm-pill--context-fn {\n border: 1px dashed color-mix(in srgb, var(--scalar-color-3), transparent 35%);\n padding: 0px 8px;\n}\n.light-mode .cm-pill--context-fn {\n background: color-mix(\n in srgb,\n var(--scalar-background-3),\n transparent 40%\n ) !important;\n}\n.dark-mode .cm-pill--context-fn {\n background: color-mix(\n in srgb,\n var(--scalar-background-3),\n transparent 55%\n ) !important;\n}\n.cm-pill:first-of-type {\n margin-left: 0;\n}\n.cm-editor .cm-widgetBuffer {\n display: none;\n}\n.cm-foldPlaceholder:hover {\n color: var(--scalar-color-1);\n}\n.cm-foldGutter .cm-gutterElement {\n font-size: var(--scalar-heading-4);\n padding: 2px !important;\n}\n.cm-foldGutter .cm-gutterElement:first-of-type {\n display: none;\n}\n.cm-foldGutter .cm-gutterElement .cm-foldMarker {\n padding: 2px;\n padding-top: 2px;\n}\n.cm-foldGutter .cm-gutterElement:hover .cm-foldMarker {\n background: var(--scalar-background-2);\n border-radius: var(--scalar-radius);\n color: var(--scalar-color-1);\n}\n</style>\n"],"mappings":"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"}
1
+ {"version":3,"file":"CodeInput.vue.script.js","names":["$attrs","$slots"],"sources":["../../../../src/v2/components/code-input/CodeInput.vue"],"sourcesContent":["<script lang=\"ts\">\nexport type CodeInputModelValue =\n | string\n | number\n | boolean\n | Array<string | number | boolean>\n | Record<string, unknown>\n\n/**\n * CodeInput\n *\n * A versatile input component that adapts its rendering based on props:\n * - Disabled mode: Read-only text display\n * - Select mode: Dropdown for enums, booleans, or examples\n * - Editor mode: CodeMirror with environment variable support\n *\n * Type `{{` to trigger autocomplete for environment variables and runtime context functions\n * (for example `{{$guid}}`) when an environment is provided.\n * It takes in any data but always will emit a string value,\n * this string should then be parsed in accordance to the schema or content type.\n *\n * @example\n * ```vue\n * <!-- Basic input with environment variables -->\n * <CodeInput v-model=\"value\" :environment=\"env\" />\n *\n * <!-- Boolean select -->\n * <CodeInput v-model=\"flag\" type=\"boolean\" />\n *\n * <!-- JSON editor with linting -->\n * <CodeInput v-model=\"data\" language=\"json\" :lint=\"true\" />\n * ```\n */\nexport default {\n inheritAttrs: false,\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { ScalarIconButton } from '@scalar/components/icon-button'\nimport { isDefined } from '@scalar/helpers/array/is-defined'\nimport { ScalarIconArrowElbowDownLeft } from '@scalar/icons'\nimport {\n colorPicker as colorPickerExtension,\n EditorView,\n useCodeMirror,\n useDropdown,\n type CodeMirrorLanguage,\n type Extension,\n} from '@scalar/use-codemirror'\nimport {\n CONTEXT_FUNCTION_NAMES,\n getContextFunctionComment,\n isContextFunctionName,\n} from '@scalar/workspace-store/request-example'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport { nanoid } from 'nanoid'\nimport { computed, ref, toRef, useAttrs, watch, type Ref } from 'vue'\n\nimport DataTableInputSelect from '@/v2/components/data-table/DataTableInputSelect.vue'\nimport EnvironmentVariableDropdown from '@/v2/features/environments/components/EnvironmentVariablesDropdown.vue'\nimport type { ClientLayout } from '@/v2/types/layout'\n\nimport { backspaceCommand, pillPlugin } from './code-variable-widget'\n\ntype Props = {\n modelValue: CodeInputModelValue\n /** Environment for variable substitution. Pass undefined to disable environment variables */\n environment: XScalarEnvironment | undefined\n /** Type of the input value, affects rendering mode for booleans */\n type?: string | string[]\n /** Render as disabled text display */\n disabled?: boolean\n /** Show error styling */\n error?: boolean\n /** Layout context affects styling and behavior */\n layout?: ClientLayout\n /** Predefined enum values, triggers select mode */\n enum?: string[]\n /** Example values, triggers select mode */\n examples?: string[]\n /** Default value to show in select mode */\n default?: Props['modelValue']\n /** Allow null in boolean select options */\n nullable?: boolean\n /** Placeholder text for empty input */\n placeholder?: string\n /** Show required indicator */\n required?: boolean\n /** Enable color picker extension */\n colorPicker?: boolean\n /** Show line numbers in editor */\n lineNumbers?: boolean\n /** Enable linting */\n lint?: boolean\n /** Enable line wrapping */\n lineWrapping?: boolean\n /** CodeMirror language mode */\n language?: CodeMirrorLanguage\n /** Additional CodeMirror extensions */\n extensions?: Extension[]\n /** Disable tab key for indentation */\n disableTabIndent?: boolean\n /** Disable enter key */\n disableEnter?: boolean\n /** Disable automatic bracket closing */\n disableCloseBrackets?: boolean\n /** Emit submit event on blur */\n emitOnBlur?: boolean\n /** Enable environment variable pills */\n withVariables?: boolean\n /** Enable fake data suggestions like $guid, $timestamp, etc. Should only be enabled for parameters and request bodies */\n withFakeData?: boolean\n /** Emit change event even if the value is the same */\n alwaysEmitChange?: boolean\n /** Custom change handler, prevents default emit */\n handleFieldChange?: (value: string) => void\n /** Custom submit handler, prevents default emit */\n handleFieldSubmit?: (value: string) => void\n /** Put a linethrough on the input text */\n linethrough?: boolean\n}\n\nconst {\n modelValue,\n environment,\n type,\n disabled = false,\n error = false,\n layout = 'desktop',\n enum: enumProp,\n examples,\n default: defaultProp,\n nullable = false,\n placeholder,\n required,\n colorPicker = false,\n lineNumbers = false,\n lint = false,\n lineWrapping = false,\n language,\n extensions = [],\n disableTabIndent = false,\n disableEnter = false,\n disableCloseBrackets = false,\n emitOnBlur = true,\n alwaysEmitChange = false,\n withVariables = true,\n withFakeData = false,\n handleFieldChange,\n handleFieldSubmit,\n} = defineProps<Props>()\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string]\n 'submit': [value: string, event: KeyboardEvent | FocusEvent]\n 'navigate': [route: { page: 'document'; path: 'environment' }]\n 'blur': [value: string, event: FocusEvent]\n}>()\n\n// ---------------------------------------------------------------------------\n// Component identity and focus state\n\nconst attrs = useAttrs()\nconst componentId =\n (typeof attrs.id === 'string' && attrs.id) || `id-${nanoid()}`\nconst isFocused = ref(false)\n\n// ---------------------------------------------------------------------------\n// Rendering mode detection\n\n/**\n * Determines if we should render a select dropdown for boolean types.\n */\nconst isBooleanMode = computed((): boolean => {\n if (enumProp?.length) {\n return false\n }\n return type === 'boolean' || (Array.isArray(type) && type.includes('boolean'))\n})\n\n/**\n * Options for boolean select mode.\n */\nconst booleanOptions = computed((): string[] =>\n nullable ? ['true', 'false', 'null'] : ['true', 'false'],\n)\n\n/**\n * Default type when dealing with type arrays.\n * Finds the first non-null type.\n */\nconst defaultType = computed((): string | undefined => {\n if (Array.isArray(type)) {\n return type.find((t) => t !== 'null') ?? 'string'\n }\n return type\n})\n\n// ---------------------------------------------------------------------------\n// Event handlers\n\n/**\n * Handles value changes during typing.\n */\nconst handleChange = (value: string): void => {\n if (!alwaysEmitChange && value === serializeValue(modelValue)) {\n return\n }\n\n // Use custom handler or emit update\n if (handleFieldChange) {\n handleFieldChange(value)\n } else {\n emit('update:modelValue', value)\n }\n}\n\n/**\n * Handles form submission (enter key or blur with emitOnBlur).\n */\nconst handleSubmit = (\n value: string,\n event: KeyboardEvent | FocusEvent,\n): void => {\n if (handleFieldSubmit) {\n handleFieldSubmit(value)\n } else {\n emit('submit', value, event)\n }\n}\n\n/**\n * Handles input blur event.\n */\nconst handleBlur = (value: string, event: FocusEvent): void => {\n isFocused.value = false\n\n if (emitOnBlur && modelValue) {\n handleSubmit(value, event)\n }\n\n emit('blur', value, event)\n}\n\n/**\n * Handles model value updates from select components.\n */\nconst handleSelectChange = (value: string): void =>\n emit('update:modelValue', value)\n\n// ---------------------------------------------------------------------------\n// CodeMirror setup\n\n/**\n * Build extensions array.\n * Note: Extensions are not reactive after initialization.\n */\nconst buildExtensions = (): Extension[] => {\n const extensionsList: Extension[] = [...extensions]\n\n if (colorPicker) {\n extensionsList.push(colorPickerExtension)\n }\n\n return extensionsList\n}\n\n/**\n * Reactive pill plugin for environment variable visualization.\n */\nconst contextFunctionDropdownItems = computed(() =>\n withFakeData\n ? CONTEXT_FUNCTION_NAMES.map((key) => ({\n key,\n description: getContextFunctionComment(key),\n }))\n : [],\n)\n\nconst pillPluginExtension = computed(() =>\n pillPlugin({\n environment,\n isContextFunctionName,\n isReadOnly: layout === 'modal',\n }),\n)\n\nconst isLineWrapping = ref(lineWrapping)\n\nwatch(\n () => lineWrapping,\n (val) => {\n isLineWrapping.value = val\n },\n)\n\nconst toggleLineWrapping = (): void => {\n isLineWrapping.value = !isLineWrapping.value\n}\n\nconst lineWrappingExtension = computed(() =>\n isLineWrapping.value ? [EditorView.lineWrapping] : [],\n)\n\n/**\n * Combined extensions for CodeMirror.\n */\nconst codeMirrorExtensions = computed((): Extension[] => [\n ...buildExtensions(),\n ...lineWrappingExtension.value,\n pillPluginExtension.value,\n backspaceCommand,\n])\n\nconst codeMirrorRef: Ref<HTMLDivElement | null> = ref(null)\n\n/** Converts the model value to a string for CodeMirror */\nconst serializeValue = (value: CodeInputModelValue): string => {\n if (typeof value === 'string') {\n return value\n }\n return JSON.stringify(value)\n}\n\nconst { codeMirror, setCodeMirrorContent } = useCodeMirror({\n content: toRef(() => serializeValue(modelValue)),\n onChange: (value) => {\n handleChange(value)\n updateDropdownVisibility()\n },\n onFocus: () => {\n isFocused.value = true\n },\n onBlur: handleBlur,\n codeMirrorRef,\n disableTabIndent: toRef(() => disableTabIndent),\n disableEnter: toRef(() => disableEnter),\n disableCloseBrackets: toRef(() => disableCloseBrackets),\n lineNumbers: toRef(() => lineNumbers),\n language: toRef(() => language),\n lint: toRef(() => lint),\n extensions: codeMirrorExtensions,\n placeholder: toRef(() => placeholder),\n})\n\n/**\n * Handle autofocus attribute.\n */\nwatch(codeMirror, () => {\n if (codeMirror.value && Object.hasOwn(attrs, 'autofocus')) {\n codeMirror.value.focus()\n }\n})\n\n// ---------------------------------------------------------------------------\n// Environment variable dropdown\n\nconst showDropdown = ref(false)\nconst dropdownQuery = ref('')\nconst dropdownPosition = ref({ left: 0, top: 0 })\nconst dropdownRef = ref<InstanceType<\n typeof EnvironmentVariableDropdown\n> | null>(null)\n\nconst { handleDropdownSelect, updateDropdownVisibility } = useDropdown({\n codeMirror,\n query: dropdownQuery,\n showDropdown,\n dropdownPosition,\n})\n\n/**\n * Determines if the environment variable dropdown should be visible.\n * Shows when environment is defined (for env vars) or withFakeData is true (for context functions)\n */\nconst displayVariablesDropdown = computed((): boolean => {\n return (\n showDropdown.value &&\n withVariables &&\n layout !== 'modal' &&\n (Boolean(environment) || withFakeData)\n )\n})\n\n// ---------------------------------------------------------------------------\n// Keyboard event handling\n\n/**\n * Handles keyboard navigation for dropdown and form submission.\n */\nconst handleKeyDown = (key: string, event: KeyboardEvent): void => {\n if (showDropdown.value) {\n if (key === 'down' || key === 'up') {\n event.preventDefault()\n dropdownRef.value?.handleArrowKey(key)\n } else if (key === 'enter') {\n event.preventDefault()\n dropdownRef.value?.handleSelect()\n }\n return\n }\n\n if (key === 'escape' && !disableTabIndent) {\n event.stopPropagation()\n }\n\n if (key === 'enter' && event.target instanceof HTMLDivElement) {\n handleSubmit(codeMirror.value?.state.doc.toString() ?? '', event)\n }\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n\ndefineExpose({\n /**\n * Focus the codemirror element\n *\n * @param cursorAtEnd boolean place the cursor at the end of the input\n */\n focus: (position?: 'start' | 'end' | number) => {\n if (!codeMirror.value) {\n return\n }\n codeMirror.value.focus()\n\n if (!isDefined(position)) {\n return\n }\n\n const anchor = (() => {\n if (position === 'start') {\n return 0\n }\n if (position === 'end') {\n return codeMirror.value.state.doc.length\n }\n return position\n })()\n\n // Move the cursor to the specified position\n codeMirror.value.dispatch({\n selection: { anchor },\n scrollIntoView: true,\n })\n },\n isFocused,\n handleChange,\n handleSubmit,\n handleBlur,\n booleanOptions,\n codeMirror,\n codeMirrorRef,\n modelValue,\n setCodeMirrorContent,\n cursorPosition: () => codeMirror.value?.state.selection.main.head,\n serializeValue,\n})\n</script>\n\n<template>\n <!-- Disabled mode: read-only text display -->\n <div\n v-if=\"disabled\"\n class=\"text-c-2 flex cursor-default items-center justify-center\"\n :class=\"{\n 'font-code pr-2 pl-1 text-base': layout === 'modal',\n 'px-2': layout !== 'modal',\n 'line-through': linethrough,\n }\"\n data-testid=\"code-input-disabled\">\n <span class=\"whitespace-nowrap\">{{ modelValue }}</span>\n </div>\n\n <!-- Enum mode: select dropdown with predefined values -->\n <DataTableInputSelect\n v-else-if=\"enumProp?.length\"\n :default=\"defaultProp\"\n :modelValue=\"modelValue\"\n :type=\"defaultType\"\n :value=\"enumProp\"\n @update:modelValue=\"handleSelectChange\" />\n\n <!-- Boolean mode: select dropdown with true/false (and optionally null) -->\n <DataTableInputSelect\n v-else-if=\"isBooleanMode\"\n :default=\"defaultProp\"\n :modelValue=\"modelValue\"\n :value=\"booleanOptions\"\n @update:modelValue=\"handleSelectChange\" />\n\n <!-- Examples mode: select dropdown with example values -->\n <DataTableInputSelect\n v-else-if=\"examples?.length\"\n :default=\"defaultProp\"\n :modelValue=\"modelValue\"\n :value=\"examples\"\n @update:modelValue=\"handleSelectChange\" />\n\n <!-- Editor mode: CodeMirror with environment variable support -->\n <div\n v-else\n :id=\"componentId\"\n v-bind=\"$attrs\"\n ref=\"codeMirrorRef\"\n class=\"group/input group-[.alert]:outline-orange group-[.error]:outline-red font-code peer relative w-full overflow-hidden text-xs leading-[1.44] whitespace-nowrap -outline-offset-1 has-[:focus-visible]:rounded-[4px] has-[:focus-visible]:outline\"\n :class=\"{\n 'line-wrapping has-[:focus-visible]:bg-b-1 has-[:focus-visible]:absolute has-[:focus-visible]:z-1':\n lineWrapping,\n 'flow-code-input--error': error,\n 'line-through': linethrough,\n }\"\n @keydown.down.stop=\"handleKeyDown('down', $event)\"\n @keydown.enter=\"handleKeyDown('enter', $event)\"\n @keydown.escape=\"handleKeyDown('escape', $event)\"\n @keydown.up.stop=\"handleKeyDown('up', $event)\">\n <!-- Wrap toggle button for multi-line editor (e.g. Request Body) -->\n <div\n v-if=\"lineNumbers\"\n class=\"absolute top-2 right-2 z-10 flex items-center opacity-0 transition-opacity duration-150 group-hover/input:opacity-100 group-has-focus-visible/input:opacity-100\">\n <ScalarIconButton\n class=\"bg-b-2 text-c-2 hover:text-c-1\"\n :class=\"{ '!bg-b-3 !text-c-1': isLineWrapping }\"\n :icon=\"ScalarIconArrowElbowDownLeft\"\n :aria-pressed=\"isLineWrapping\"\n :aria-label=\"isLineWrapping ? 'Disable line wrap' : 'Wrap lines'\"\n :label=\"isLineWrapping ? 'Disable line wrap' : 'Wrap lines'\"\n size=\"sm\"\n tooltip\n variant=\"ghost\"\n @click.stop=\"toggleLineWrapping\" />\n </div>\n\n <!-- Tab exit hint (shown when focused) -->\n <div\n v-if=\"!disableTabIndent\"\n class=\"z-context text-c-2 absolute right-1.5 bottom-1 hidden font-sans group-has-[:focus-visible]/input:block\"\n role=\"alert\">\n Press\n <kbd class=\"-mx-0.25 rounded border px-0.5 font-mono\">Esc</kbd> then\n <kbd class=\"-mx-0.25 rounded border px-0.5 font-mono\">Tab</kbd> to exit\n </div>\n </div>\n\n <!-- Warning slot (positioned absolutely) -->\n <div\n v-if=\"$slots.warning\"\n class=\"centered-y text-orange absolute right-7 text-xs\">\n <slot name=\"warning\" />\n </div>\n\n <!-- Icon slot (positioned absolutely) -->\n <div\n v-if=\"$slots.icon\"\n class=\"centered-y absolute right-0 flex h-full items-center p-1.5 group-has-[.cm-focused]:z-1\">\n <slot name=\"icon\" />\n </div>\n\n <!-- Required indicator -->\n <div\n v-if=\"required\"\n class=\"required centered-y text-xxs text-c-3 group-[.error]:text-red bg-b-1 pointer-events-none absolute right-0 mr-0.5 pt-px pr-2 opacity-100 shadow-[-8px_0_4px_var(--scalar-background-1)] transition-opacity duration-150 group-[.alert]:bg-transparent group-[.alert]:shadow-none group-[.error]:bg-transparent group-[.error]:shadow-none peer-has-[.cm-focused]:opacity-0\">\n Required\n </div>\n\n <!-- Environment variable autocomplete dropdown -->\n <EnvironmentVariableDropdown\n v-if=\"displayVariablesDropdown\"\n ref=\"dropdownRef\"\n :contextFunctionItems=\"contextFunctionDropdownItems\"\n :dropdownPosition=\"dropdownPosition\"\n :environment=\"environment\"\n :query=\"dropdownQuery\"\n @close=\"showDropdown = false\"\n @redirect=\"emit('navigate', { page: 'document', path: 'environment' })\"\n @select=\"handleDropdownSelect\" />\n</template>\n<style scoped>\n/*\n Deep styling for customizing Codemirror\n */\n:deep(.cm-editor) {\n height: 100%;\n outline: none;\n padding: 0;\n background: transparent;\n}\n:deep(.cm-placeholder) {\n color: var(--scalar-color-3);\n}\n:deep(.cm-content) {\n font-family: var(--scalar-font-code);\n font-size: var(--scalar-small);\n max-height: 20px;\n padding: 8px 0;\n}\n/* Tooltip helper */\n:deep(.cm-tooltip) {\n background: transparent !important;\n filter: brightness(var(--scalar-lifted-brightness));\n border-radius: var(--scalar-radius);\n box-shadow: var(--scalar-shadow-2);\n border: none !important;\n outline: none !important;\n overflow: hidden !important;\n}\n:deep(.cm-tooltip-autocomplete ul li) {\n padding: 3px 6px !important;\n}\n:deep(.cm-completionIcon-type:after) {\n color: var(--scalar-color-3) !important;\n}\n:deep(.cm-tooltip-autocomplete ul li[aria-selected]) {\n background: var(--scalar-background-2) !important;\n color: var(--scalar-color-1) !important;\n}\n:deep(.cm-tooltip-autocomplete ul) {\n padding: 6px !important;\n position: relative;\n}\n:deep(.cm-tooltip-autocomplete ul li:hover) {\n border-radius: 3px;\n color: var(--scalar-color-1) !important;\n background: var(--scalar-background-3) !important;\n}\n/* Disable active line highlighting */\n:deep(.cm-activeLine),\n:deep(.cm-activeLineGutter) {\n background-color: transparent;\n}\n/* Color selection matching */\n:deep(.cm-selectionMatch),\n:deep(.cm-matchingBracket) {\n border-radius: var(--scalar-radius);\n background: var(--scalar-background-4) !important;\n}\n/* Color Picker Swatches */\n:deep(.cm-css-color-picker-wrapper) {\n display: inline-flex;\n outline: 1px solid var(--scalar-background-3);\n border-radius: 3px;\n overflow: hidden;\n}\n/* Number gutter */\n:deep(.cm-gutters) {\n background-color: transparent;\n border-right: none;\n color: var(--scalar-color-3);\n font-size: var(--scalar-small);\n line-height: 22px;\n border-radius: 0 0 0 3px;\n}\n:deep(.cm-gutters:before) {\n content: '';\n position: absolute;\n top: 2px;\n left: 2px;\n width: calc(100% - 2px);\n height: calc(100% - 4px);\n border-radius: var(--scalar-radius) 0 0 var(--scalar-radius);\n background-color: var(--scalar-background-1);\n}\n:deep(.cm-gutterElement) {\n font-family: var(--scalar-font-code) !important;\n padding-left: 0px !important;\n padding-right: 6px !important;\n display: flex;\n align-items: center;\n justify-content: flex-end;\n position: relative;\n}\n:deep(.cm-lineNumbers .cm-gutterElement) {\n min-width: fit-content;\n}\n:deep(.cm-gutter + .cm-gutter :not(.cm-foldGutter) .cm-gutterElement) {\n padding-left: 0 !important;\n}\n:deep(.cm-scroller) {\n overflow: auto;\n}\n:deep(.cm-lineWrapping .cm-line) {\n word-break: break-all;\n}\n:deep(.cm-lineWrapping .cm-content) {\n white-space: pre-wrap;\n max-height: none;\n}\n.line-wrapping:focus-within :deep(.cm-content) {\n display: inline-table;\n min-height: fit-content;\n padding: 3px 6px;\n white-space: break-spaces;\n word-break: break-all;\n}\n</style>\n<style>\n.cm-pill {\n color: var(--scalar-color-1) !important;\n padding: 0px 9px;\n display: inline-block;\n border-radius: var(--scalar-radius-full);\n font-size: var(--scalar-small);\n}\n.light-mode .cm-pill {\n background: var(--scalar-background-3) !important;\n}\n.dark-mode .cm-pill {\n background: color-mix(in srgb, var(--tw-bg-base), transparent 90%) !important;\n}\n.cm-pill--context-fn {\n border: 1px dashed color-mix(in srgb, var(--scalar-color-3), transparent 35%);\n padding: 0px 8px;\n}\n.light-mode .cm-pill--context-fn {\n background: color-mix(\n in srgb,\n var(--scalar-background-3),\n transparent 40%\n ) !important;\n}\n.dark-mode .cm-pill--context-fn {\n background: color-mix(\n in srgb,\n var(--scalar-background-3),\n transparent 55%\n ) !important;\n}\n.cm-pill:first-of-type {\n margin-left: 0;\n}\n.cm-editor .cm-widgetBuffer {\n display: none;\n}\n.cm-foldPlaceholder:hover {\n color: var(--scalar-color-1);\n}\n.cm-foldGutter .cm-gutterElement {\n font-size: var(--scalar-heading-4);\n padding: 2px !important;\n}\n.cm-foldGutter .cm-gutterElement:first-of-type {\n display: none;\n}\n.cm-foldGutter .cm-gutterElement .cm-foldMarker {\n padding: 2px;\n padding-top: 2px;\n}\n.cm-foldGutter .cm-gutterElement:hover .cm-foldMarker {\n background: var(--scalar-background-2);\n border-radius: var(--scalar-radius);\n color: var(--scalar-color-1);\n}\n</style>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ServerDropdown.vue.d.ts","sourceRoot":"","sources":["../../../../src/v2/components/server/ServerDropdown.vue"],"names":[],"mappings":"AA8IA,OAAO,KAAK,EAEV,UAAU,EACX,MAAM,gCAAgC,CAAA;AACvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8DAA8D,CAAA;AAIhG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAKrD;;;GAGG;wBACkB,OAAO,YAAY;AAAxC,wBAAyC;AAMzC,MAAM,MAAM,mBAAmB,GAAG;IAChC,0CAA0C;IAC1C,IAAI,EAAE,UAAU,CAAA;IAChB,0EAA0E;IAC1E,OAAO,EAAE,YAAY,EAAE,CAAA;IACvB,gCAAgC;IAChC,MAAM,EAAE,YAAY,GAAG,IAAI,CAAA;IAC3B,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAA;IACd,oBAAoB;IACpB,MAAM,EAAE,YAAY,CAAA;CACrB,CAAA;AACD,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;kFAoSd,CAAC"}
1
+ {"version":3,"file":"ServerDropdown.vue.d.ts","sourceRoot":"","sources":["../../../../src/v2/components/server/ServerDropdown.vue"],"names":[],"mappings":"AA+IA,OAAO,KAAK,EAEV,UAAU,EACX,MAAM,gCAAgC,CAAA;AACvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8DAA8D,CAAA;AAIhG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAKrD;;;GAGG;wBACkB,OAAO,YAAY;AAAxC,wBAAyC;AAMzC,MAAM,MAAM,mBAAmB,GAAG;IAChC,0CAA0C;IAC1C,IAAI,EAAE,UAAU,CAAA;IAChB,0EAA0E;IAC1E,OAAO,EAAE,YAAY,EAAE,CAAA;IACvB,gCAAgC;IAChC,MAAM,EAAE,YAAY,GAAG,IAAI,CAAA;IAC3B,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAA;IACd,oBAAoB;IACpB,MAAM,EAAE,YAAY,CAAA;CACrB,CAAA;AACD,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;kFAqSd,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ServerDropdown.vue.js","names":[],"sources":["../../../../src/v2/components/server/ServerDropdown.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * ServerDropdown component\n * This component is used to display the server dropdown for the operation block\n */\nexport default {\n name: 'ServerDropdown',\n}\n\nexport type ServerDropdownProps = {\n /** The meta information for the server */\n meta: ServerMeta\n /** List of servers that are available for the operation/document level */\n servers: ServerObject[]\n /** Currently selected server */\n server: ServerObject | null\n /** The id of the target to use for the popover (e.g. address bar) */\n target: string\n /** Client layout */\n layout: ClientLayout\n}\n</script>\n<script setup lang=\"ts\">\nimport { ScalarButton } from '@scalar/components/button'\nimport { ScalarFloatingBackdrop } from '@scalar/components/floating'\nimport { ScalarPopover } from '@scalar/components/popover'\nimport { ScalarIconPencilSimple, ScalarIconPlus } from '@scalar/icons'\nimport type {\n ApiReferenceEvents,\n ServerMeta,\n} from '@scalar/workspace-store/events'\nimport type { ServerObject } from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document'\nimport { computed } from 'vue'\n\nimport ValueEmitter from '@/v2/components/layout/ValueEmitter.vue'\nimport type { ClientLayout } from '@/v2/types/layout'\n\nimport ServerDropdownItem from './ServerDropdownItem.vue'\n\nconst { target, server, servers, meta } = defineProps<ServerDropdownProps>()\n\nconst emit = defineEmits<{\n /** Update a server variable for the selected server */\n (\n e: 'update:selectedServer',\n payload: ApiReferenceEvents['server:update:selected'],\n ): void\n (\n e: 'update:variable',\n payload: ApiReferenceEvents['server:update:variables'],\n ): void\n (e: 'update:servers'): void\n /** Update the open state of the server dropdown */\n (e: 'update:open', value: boolean): void\n}>()\n\nconst requestServerOptions = computed(() =>\n servers.map((s) => ({\n id: s.url,\n label: s.url ?? 'Unknown server',\n })),\n)\n\nconst serverUrlWithoutTrailingSlash = computed(() => {\n if (server?.url?.endsWith('/')) {\n return server.url.slice(0, -1)\n }\n return server?.url || ''\n})\n</script>\n<template>\n <ScalarPopover\n class=\"max-h-[inherit] p-0 text-base\"\n focus\n :offset=\"0\"\n placement=\"bottom\"\n resize\n :target=\"target\"\n :teleport=\"`#${target}`\">\n <ScalarButton\n class=\"hover:bg-b-2 font-code text-c-2 h-auto gap-0.75 rounded border px-1.5 text-base whitespace-nowrap @3xl:ml-0.75\"\n variant=\"ghost\">\n <template v-if=\"server\">\n <span class=\"sr-only\">Server:</span>\n {{ serverUrlWithoutTrailingSlash }}\n </template>\n <template v-else>\n <span class=\"sr-only\">Add Server</span>\n <ScalarIconPlus class=\"size-3\" />\n </template>\n </ScalarButton>\n\n <template #popover=\"{ close }\">\n <div\n class=\"custom-scroll flex max-h-[inherit] flex-col gap-1 p-1\"\n @click=\"close\">\n <!-- Request -->\n <ServerDropdownItem\n v-for=\"(serverOption, index) in requestServerOptions\"\n :key=\"serverOption.id\"\n :server=\"server\"\n :serverOption=\"serverOption\"\n type=\"request\"\n @update:selectedServer=\"\n emit('update:selectedServer', { url: serverOption.id, meta })\n \"\n @update:variable=\"\n (key, value) => emit('update:variable', { index, key, value, meta })\n \" />\n\n <!-- Add Server -->\n <template v-if=\"layout !== 'modal'\">\n <button\n class=\"text-xxs hover:bg-b-2 flex cursor-pointer items-center gap-1.5 rounded p-1.75\"\n type=\"button\"\n @click=\"emit('update:servers')\">\n <div class=\"flex items-center justify-center\">\n <ScalarIconPencilSimple class=\"size-4\" />\n </div>\n <span>Update Servers</span>\n </button>\n </template>\n </div>\n </template>\n <template #backdrop=\"{ open }\">\n <!-- Emit the slot value back out the parent -->\n <ValueEmitter\n :value=\"open\"\n @change=\"(value) => emit('update:open', value)\"\n @unmount=\"emit('update:open', false)\" />\n\n <ScalarFloatingBackdrop class=\"inset-x-px rounded-none rounded-b-lg\" />\n </template>\n </ScalarPopover>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"ServerDropdown.vue.js","names":[],"sources":["../../../../src/v2/components/server/ServerDropdown.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * ServerDropdown component\n * This component is used to display the server dropdown for the operation block\n */\nexport default {\n name: 'ServerDropdown',\n}\n\nexport type ServerDropdownProps = {\n /** The meta information for the server */\n meta: ServerMeta\n /** List of servers that are available for the operation/document level */\n servers: ServerObject[]\n /** Currently selected server */\n server: ServerObject | null\n /** The id of the target to use for the popover (e.g. address bar) */\n target: string\n /** Client layout */\n layout: ClientLayout\n}\n</script>\n<script setup lang=\"ts\">\nimport { ScalarButton } from '@scalar/components/button'\nimport { ScalarFloatingBackdrop } from '@scalar/components/floating'\nimport { ScalarPopover } from '@scalar/components/popover'\nimport { ScalarIconPencilSimple, ScalarIconPlus } from '@scalar/icons'\nimport type {\n ApiReferenceEvents,\n ServerMeta,\n} from '@scalar/workspace-store/events'\nimport type { ServerObject } from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document'\nimport { computed } from 'vue'\n\nimport ValueEmitter from '@/v2/components/layout/ValueEmitter.vue'\nimport type { ClientLayout } from '@/v2/types/layout'\n\nimport ServerDropdownItem from './ServerDropdownItem.vue'\n\nconst { target, server, servers, meta } = defineProps<ServerDropdownProps>()\n\nconst emit = defineEmits<{\n /** Update a server variable for the selected server */\n (\n e: 'update:selectedServer',\n payload: ApiReferenceEvents['server:update:selected'],\n ): void\n (\n e: 'update:variable',\n payload: ApiReferenceEvents['server:update:variables'],\n ): void\n (e: 'update:servers'): void\n /** Update the open state of the server dropdown */\n (e: 'update:open', value: boolean): void\n}>()\n\nconst requestServerOptions = computed(() =>\n servers.map((s) => ({\n id: s.url,\n // Prefer the server name (OpenAPI 3.2) as a friendly label, falling back to the URL\n label: s.name || s.url || 'Unknown server',\n })),\n)\n\nconst serverUrlWithoutTrailingSlash = computed(() => {\n if (server?.url?.endsWith('/')) {\n return server.url.slice(0, -1)\n }\n return server?.url || ''\n})\n</script>\n<template>\n <ScalarPopover\n class=\"max-h-[inherit] p-0 text-base\"\n focus\n :offset=\"0\"\n placement=\"bottom\"\n resize\n :target=\"target\"\n :teleport=\"`#${target}`\">\n <ScalarButton\n class=\"hover:bg-b-2 font-code text-c-2 h-auto gap-0.75 rounded border px-1.5 text-base whitespace-nowrap @3xl:ml-0.75\"\n variant=\"ghost\">\n <template v-if=\"server\">\n <span class=\"sr-only\">Server:</span>\n {{ serverUrlWithoutTrailingSlash }}\n </template>\n <template v-else>\n <span class=\"sr-only\">Add Server</span>\n <ScalarIconPlus class=\"size-3\" />\n </template>\n </ScalarButton>\n\n <template #popover=\"{ close }\">\n <div\n class=\"custom-scroll flex max-h-[inherit] flex-col gap-1 p-1\"\n @click=\"close\">\n <!-- Request -->\n <ServerDropdownItem\n v-for=\"(serverOption, index) in requestServerOptions\"\n :key=\"serverOption.id\"\n :server=\"server\"\n :serverOption=\"serverOption\"\n type=\"request\"\n @update:selectedServer=\"\n emit('update:selectedServer', { url: serverOption.id, meta })\n \"\n @update:variable=\"\n (key, value) => emit('update:variable', { index, key, value, meta })\n \" />\n\n <!-- Add Server -->\n <template v-if=\"layout !== 'modal'\">\n <button\n class=\"text-xxs hover:bg-b-2 flex cursor-pointer items-center gap-1.5 rounded p-1.75\"\n type=\"button\"\n @click=\"emit('update:servers')\">\n <div class=\"flex items-center justify-center\">\n <ScalarIconPencilSimple class=\"size-4\" />\n </div>\n <span>Update Servers</span>\n </button>\n </template>\n </div>\n </template>\n <template #backdrop=\"{ open }\">\n <!-- Emit the slot value back out the parent -->\n <ValueEmitter\n :value=\"open\"\n @change=\"(value) => emit('update:open', value)\"\n @unmount=\"emit('update:open', false)\" />\n\n <ScalarFloatingBackdrop class=\"inset-x-px rounded-none rounded-b-lg\" />\n </template>\n </ScalarPopover>\n</template>\n"],"mappings":""}
@@ -27,7 +27,7 @@ var ServerDropdown_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ d
27
27
  const emit = __emit;
28
28
  const requestServerOptions = computed(() => __props.servers.map((s) => ({
29
29
  id: s.url,
30
- label: s.url ?? "Unknown server"
30
+ label: s.name || s.url || "Unknown server"
31
31
  })));
32
32
  const serverUrlWithoutTrailingSlash = computed(() => {
33
33
  if (__props.server?.url?.endsWith("/")) return __props.server.url.slice(0, -1);
@@ -1 +1 @@
1
- {"version":3,"file":"ServerDropdown.vue.script.js","names":[],"sources":["../../../../src/v2/components/server/ServerDropdown.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * ServerDropdown component\n * This component is used to display the server dropdown for the operation block\n */\nexport default {\n name: 'ServerDropdown',\n}\n\nexport type ServerDropdownProps = {\n /** The meta information for the server */\n meta: ServerMeta\n /** List of servers that are available for the operation/document level */\n servers: ServerObject[]\n /** Currently selected server */\n server: ServerObject | null\n /** The id of the target to use for the popover (e.g. address bar) */\n target: string\n /** Client layout */\n layout: ClientLayout\n}\n</script>\n<script setup lang=\"ts\">\nimport { ScalarButton } from '@scalar/components/button'\nimport { ScalarFloatingBackdrop } from '@scalar/components/floating'\nimport { ScalarPopover } from '@scalar/components/popover'\nimport { ScalarIconPencilSimple, ScalarIconPlus } from '@scalar/icons'\nimport type {\n ApiReferenceEvents,\n ServerMeta,\n} from '@scalar/workspace-store/events'\nimport type { ServerObject } from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document'\nimport { computed } from 'vue'\n\nimport ValueEmitter from '@/v2/components/layout/ValueEmitter.vue'\nimport type { ClientLayout } from '@/v2/types/layout'\n\nimport ServerDropdownItem from './ServerDropdownItem.vue'\n\nconst { target, server, servers, meta } = defineProps<ServerDropdownProps>()\n\nconst emit = defineEmits<{\n /** Update a server variable for the selected server */\n (\n e: 'update:selectedServer',\n payload: ApiReferenceEvents['server:update:selected'],\n ): void\n (\n e: 'update:variable',\n payload: ApiReferenceEvents['server:update:variables'],\n ): void\n (e: 'update:servers'): void\n /** Update the open state of the server dropdown */\n (e: 'update:open', value: boolean): void\n}>()\n\nconst requestServerOptions = computed(() =>\n servers.map((s) => ({\n id: s.url,\n label: s.url ?? 'Unknown server',\n })),\n)\n\nconst serverUrlWithoutTrailingSlash = computed(() => {\n if (server?.url?.endsWith('/')) {\n return server.url.slice(0, -1)\n }\n return server?.url || ''\n})\n</script>\n<template>\n <ScalarPopover\n class=\"max-h-[inherit] p-0 text-base\"\n focus\n :offset=\"0\"\n placement=\"bottom\"\n resize\n :target=\"target\"\n :teleport=\"`#${target}`\">\n <ScalarButton\n class=\"hover:bg-b-2 font-code text-c-2 h-auto gap-0.75 rounded border px-1.5 text-base whitespace-nowrap @3xl:ml-0.75\"\n variant=\"ghost\">\n <template v-if=\"server\">\n <span class=\"sr-only\">Server:</span>\n {{ serverUrlWithoutTrailingSlash }}\n </template>\n <template v-else>\n <span class=\"sr-only\">Add Server</span>\n <ScalarIconPlus class=\"size-3\" />\n </template>\n </ScalarButton>\n\n <template #popover=\"{ close }\">\n <div\n class=\"custom-scroll flex max-h-[inherit] flex-col gap-1 p-1\"\n @click=\"close\">\n <!-- Request -->\n <ServerDropdownItem\n v-for=\"(serverOption, index) in requestServerOptions\"\n :key=\"serverOption.id\"\n :server=\"server\"\n :serverOption=\"serverOption\"\n type=\"request\"\n @update:selectedServer=\"\n emit('update:selectedServer', { url: serverOption.id, meta })\n \"\n @update:variable=\"\n (key, value) => emit('update:variable', { index, key, value, meta })\n \" />\n\n <!-- Add Server -->\n <template v-if=\"layout !== 'modal'\">\n <button\n class=\"text-xxs hover:bg-b-2 flex cursor-pointer items-center gap-1.5 rounded p-1.75\"\n type=\"button\"\n @click=\"emit('update:servers')\">\n <div class=\"flex items-center justify-center\">\n <ScalarIconPencilSimple class=\"size-4\" />\n </div>\n <span>Update Servers</span>\n </button>\n </template>\n </div>\n </template>\n <template #backdrop=\"{ open }\">\n <!-- Emit the slot value back out the parent -->\n <ValueEmitter\n :value=\"open\"\n @change=\"(value) => emit('update:open', value)\"\n @unmount=\"emit('update:open', false)\" />\n\n <ScalarFloatingBackdrop class=\"inset-x-px rounded-none rounded-b-lg\" />\n </template>\n </ScalarPopover>\n</template>\n"],"mappings":";;;;;;;;;;;CAME,MAAM;;;;;;;;;;;;;;;EAmCR,MAAM,OAAO;EAeb,MAAM,uBAAuB,eAC3B,QAAA,QAAQ,KAAK,OAAO;GAClB,IAAI,EAAE;GACN,OAAO,EAAE,OAAO;EAClB,EAAE,CACJ;EAEA,MAAM,gCAAgC,eAAe;GACnD,IAAI,QAAA,QAAQ,KAAK,SAAS,GAAG,GAC3B,OAAO,QAAA,OAAO,IAAI,MAAM,GAAG,EAAE;GAE/B,OAAO,QAAA,QAAQ,OAAO;EACxB,CAAC;;uBAGC,YA8DgB,MAAA,aAAA,GAAA;IA7Dd,OAAM;IACN,OAAA;IACC,QAAQ;IACT,WAAU;IACV,QAAA;IACC,QAAQ,QAAA;IACR,UAAQ,IAAM,QAAA;;IAcJ,SAAO,SA8BV,EA9Bc,YAAK,CACzB,mBA6BM,OAAA;KA5BJ,OAAM;KACL,SAAO;0BAER,mBAWM,UAAA,MAAA,WAV4B,qBAAA,QAAxB,cAAc,UAAK;yBAD7B,YAWM,4BAAA;MATH,KAAK,aAAa;MAClB,QAAQ,QAAA;MACM;MACf,MAAK;MACJ,4BAAqB,WAAe,KAAI,yBAAA;OAAA,KAAiC,aAAa;OAAE,MAAE,QAAA;MAAI,CAAA;MAG9F,sBAA+B,KAAK,UAAU,KAAI,mBAAA;OAAsB;OAAO;OAAK;OAAK,MAAE,QAAA;MAAI,CAAA;;;;;;;eAKlF,QAAA,WAAM,WAAA,UAAA,GACpB,mBAQS,UAAA;;KAPP,OAAM;KACN,MAAK;KACJ,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,KAAI,gBAAA;QACZ,mBAEM,OAFN,YAEM,CADJ,YAAyC,MAAA,sBAAA,GAAA,EAAjB,OAAM,SAAQ,CAAA,CAAA,CAAA,GAAA,OAAA,OAAA,OAAA,KAExC,mBAA2B,QAAA,MAArB,kBAAc,EAAA,EAAA,CAAA,KAAA,mBAAA,IAAA,IAAA,CAAA,GAAA,GAAA,UAAA,CAAA,CAAA;IAKjB,UAAQ,SAKyB,EALrB,WAAI,CAEzB,YAG0C,sBAAA;KAFvC,OAAO;KACP,UAAM,OAAA,OAAA,OAAA,MAAG,UAAU,KAAI,eAAgB,KAAK;KAC5C,WAAO,OAAA,OAAA,OAAA,MAAA,WAAE,KAAI,eAAA,KAAA;4BAEhB,YAAuE,MAAA,sBAAA,GAAA,EAA/C,OAAM,uCAAsC,CAAA,CAAA,CAAA;2BAzCvD,CAXf,YAWe,MAAA,YAAA,GAAA;KAVb,OAAM;KACN,SAAQ;;4BAIG,CAHK,QAAA,UAAA,UAAA,GAAhB,mBAGW,UAAA,EAAA,KAAA,EAAA,GAAA,CAAA,OAAA,OAAA,OAAA,KAFT,mBAAoC,QAAA,EAA9B,OAAM,UAAS,GAAC,WAAO,EAAA,IAAA,gBAAO,MACpC,gBAAG,8BAAA,KAA6B,GAAA,CAAA,CAAA,GAAA,EAAA,MAAA,UAAA,GAElC,mBAGW,UAAA,EAAA,KAAA,EAAA,GAAA,CAAA,OAAA,OAAA,OAAA,KAFT,mBAAuC,QAAA,EAAjC,OAAM,UAAS,GAAC,cAAU,EAAA,IAChC,YAAiC,MAAA,cAAA,GAAA,EAAjB,OAAM,SAAQ,CAAA,CAAA,GAAA,EAAA,EAAA,CAAA"}
1
+ {"version":3,"file":"ServerDropdown.vue.script.js","names":[],"sources":["../../../../src/v2/components/server/ServerDropdown.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * ServerDropdown component\n * This component is used to display the server dropdown for the operation block\n */\nexport default {\n name: 'ServerDropdown',\n}\n\nexport type ServerDropdownProps = {\n /** The meta information for the server */\n meta: ServerMeta\n /** List of servers that are available for the operation/document level */\n servers: ServerObject[]\n /** Currently selected server */\n server: ServerObject | null\n /** The id of the target to use for the popover (e.g. address bar) */\n target: string\n /** Client layout */\n layout: ClientLayout\n}\n</script>\n<script setup lang=\"ts\">\nimport { ScalarButton } from '@scalar/components/button'\nimport { ScalarFloatingBackdrop } from '@scalar/components/floating'\nimport { ScalarPopover } from '@scalar/components/popover'\nimport { ScalarIconPencilSimple, ScalarIconPlus } from '@scalar/icons'\nimport type {\n ApiReferenceEvents,\n ServerMeta,\n} from '@scalar/workspace-store/events'\nimport type { ServerObject } from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document'\nimport { computed } from 'vue'\n\nimport ValueEmitter from '@/v2/components/layout/ValueEmitter.vue'\nimport type { ClientLayout } from '@/v2/types/layout'\n\nimport ServerDropdownItem from './ServerDropdownItem.vue'\n\nconst { target, server, servers, meta } = defineProps<ServerDropdownProps>()\n\nconst emit = defineEmits<{\n /** Update a server variable for the selected server */\n (\n e: 'update:selectedServer',\n payload: ApiReferenceEvents['server:update:selected'],\n ): void\n (\n e: 'update:variable',\n payload: ApiReferenceEvents['server:update:variables'],\n ): void\n (e: 'update:servers'): void\n /** Update the open state of the server dropdown */\n (e: 'update:open', value: boolean): void\n}>()\n\nconst requestServerOptions = computed(() =>\n servers.map((s) => ({\n id: s.url,\n // Prefer the server name (OpenAPI 3.2) as a friendly label, falling back to the URL\n label: s.name || s.url || 'Unknown server',\n })),\n)\n\nconst serverUrlWithoutTrailingSlash = computed(() => {\n if (server?.url?.endsWith('/')) {\n return server.url.slice(0, -1)\n }\n return server?.url || ''\n})\n</script>\n<template>\n <ScalarPopover\n class=\"max-h-[inherit] p-0 text-base\"\n focus\n :offset=\"0\"\n placement=\"bottom\"\n resize\n :target=\"target\"\n :teleport=\"`#${target}`\">\n <ScalarButton\n class=\"hover:bg-b-2 font-code text-c-2 h-auto gap-0.75 rounded border px-1.5 text-base whitespace-nowrap @3xl:ml-0.75\"\n variant=\"ghost\">\n <template v-if=\"server\">\n <span class=\"sr-only\">Server:</span>\n {{ serverUrlWithoutTrailingSlash }}\n </template>\n <template v-else>\n <span class=\"sr-only\">Add Server</span>\n <ScalarIconPlus class=\"size-3\" />\n </template>\n </ScalarButton>\n\n <template #popover=\"{ close }\">\n <div\n class=\"custom-scroll flex max-h-[inherit] flex-col gap-1 p-1\"\n @click=\"close\">\n <!-- Request -->\n <ServerDropdownItem\n v-for=\"(serverOption, index) in requestServerOptions\"\n :key=\"serverOption.id\"\n :server=\"server\"\n :serverOption=\"serverOption\"\n type=\"request\"\n @update:selectedServer=\"\n emit('update:selectedServer', { url: serverOption.id, meta })\n \"\n @update:variable=\"\n (key, value) => emit('update:variable', { index, key, value, meta })\n \" />\n\n <!-- Add Server -->\n <template v-if=\"layout !== 'modal'\">\n <button\n class=\"text-xxs hover:bg-b-2 flex cursor-pointer items-center gap-1.5 rounded p-1.75\"\n type=\"button\"\n @click=\"emit('update:servers')\">\n <div class=\"flex items-center justify-center\">\n <ScalarIconPencilSimple class=\"size-4\" />\n </div>\n <span>Update Servers</span>\n </button>\n </template>\n </div>\n </template>\n <template #backdrop=\"{ open }\">\n <!-- Emit the slot value back out the parent -->\n <ValueEmitter\n :value=\"open\"\n @change=\"(value) => emit('update:open', value)\"\n @unmount=\"emit('update:open', false)\" />\n\n <ScalarFloatingBackdrop class=\"inset-x-px rounded-none rounded-b-lg\" />\n </template>\n </ScalarPopover>\n</template>\n"],"mappings":";;;;;;;;;;;CAME,MAAM;;;;;;;;;;;;;;;EAmCR,MAAM,OAAO;EAeb,MAAM,uBAAuB,eAC3B,QAAA,QAAQ,KAAK,OAAO;GAClB,IAAI,EAAE;GAEN,OAAO,EAAE,QAAQ,EAAE,OAAO;EAC5B,EAAE,CACJ;EAEA,MAAM,gCAAgC,eAAe;GACnD,IAAI,QAAA,QAAQ,KAAK,SAAS,GAAG,GAC3B,OAAO,QAAA,OAAO,IAAI,MAAM,GAAG,EAAE;GAE/B,OAAO,QAAA,QAAQ,OAAO;EACxB,CAAC;;uBAGC,YA8DgB,MAAA,aAAA,GAAA;IA7Dd,OAAM;IACN,OAAA;IACC,QAAQ;IACT,WAAU;IACV,QAAA;IACC,QAAQ,QAAA;IACR,UAAQ,IAAM,QAAA;;IAcJ,SAAO,SA8BV,EA9Bc,YAAK,CACzB,mBA6BM,OAAA;KA5BJ,OAAM;KACL,SAAO;0BAER,mBAWM,UAAA,MAAA,WAV4B,qBAAA,QAAxB,cAAc,UAAK;yBAD7B,YAWM,4BAAA;MATH,KAAK,aAAa;MAClB,QAAQ,QAAA;MACM;MACf,MAAK;MACJ,4BAAqB,WAAe,KAAI,yBAAA;OAAA,KAAiC,aAAa;OAAE,MAAE,QAAA;MAAI,CAAA;MAG9F,sBAA+B,KAAK,UAAU,KAAI,mBAAA;OAAsB;OAAO;OAAK;OAAK,MAAE,QAAA;MAAI,CAAA;;;;;;;eAKlF,QAAA,WAAM,WAAA,UAAA,GACpB,mBAQS,UAAA;;KAPP,OAAM;KACN,MAAK;KACJ,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,KAAI,gBAAA;QACZ,mBAEM,OAFN,YAEM,CADJ,YAAyC,MAAA,sBAAA,GAAA,EAAjB,OAAM,SAAQ,CAAA,CAAA,CAAA,GAAA,OAAA,OAAA,OAAA,KAExC,mBAA2B,QAAA,MAArB,kBAAc,EAAA,EAAA,CAAA,KAAA,mBAAA,IAAA,IAAA,CAAA,GAAA,GAAA,UAAA,CAAA,CAAA;IAKjB,UAAQ,SAKyB,EALrB,WAAI,CAEzB,YAG0C,sBAAA;KAFvC,OAAO;KACP,UAAM,OAAA,OAAA,OAAA,MAAG,UAAU,KAAI,eAAgB,KAAK;KAC5C,WAAO,OAAA,OAAA,OAAA,MAAA,WAAE,KAAI,eAAA,KAAA;4BAEhB,YAAuE,MAAA,sBAAA,GAAA,EAA/C,OAAM,uCAAsC,CAAA,CAAA,CAAA;2BAzCvD,CAXf,YAWe,MAAA,YAAA,GAAA;KAVb,OAAM;KACN,SAAQ;;4BAIG,CAHK,QAAA,UAAA,UAAA,GAAhB,mBAGW,UAAA,EAAA,KAAA,EAAA,GAAA,CAAA,OAAA,OAAA,OAAA,KAFT,mBAAoC,QAAA,EAA9B,OAAM,UAAS,GAAC,WAAO,EAAA,IAAA,gBAAO,MACpC,gBAAG,8BAAA,KAA6B,GAAA,CAAA,CAAA,GAAA,EAAA,MAAA,UAAA,GAElC,mBAGW,UAAA,EAAA,KAAA,EAAA,GAAA,CAAA,OAAA,OAAA,OAAA,KAFT,mBAAuC,QAAA,EAAjC,OAAM,UAAS,GAAC,cAAU,EAAA,IAChC,YAAiC,MAAA,cAAA,GAAA,EAAjB,OAAM,SAAQ,CAAA,CAAA,GAAA,EAAA,EAAA,CAAA"}
@@ -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.0";
3
+ var APP_VERSION = typeof OVERRIDE_PACKAGE_VERSION !== "undefined" ? OVERRIDE_PACKAGE_VERSION : "3.19.1";
4
4
  //#endregion
5
5
  export { APP_VERSION };
6
6
 
@@ -1,11 +1,17 @@
1
1
  import type { HttpMethod } from '@scalar/helpers/http/http-methods';
2
2
  import type { WorkspaceStore } from '@scalar/workspace-store/client';
3
3
  import type { TraversedEntry } from '@scalar/workspace-store/schemas/navigation';
4
- /** Payload for routing and opening the API client modal. */
4
+ /**
5
+ * Payload for routing and opening the API client modal.
6
+ *
7
+ * `path` and `method` are optional so a caller can update `documentSlug` on its own.
8
+ * `route()` fills in whichever fields are missing from its "default" placeholders, which
9
+ * resolve to the document's first operation instead of a route that does not exist.
10
+ */
5
11
  export type RoutePayload = {
6
12
  /** API path, or webhook name when `isWebhook` is true. */
7
- path: string;
8
- method: HttpMethod;
13
+ path?: string;
14
+ method?: HttpMethod;
9
15
  example?: string;
10
16
  documentSlug?: string;
11
17
  /** Resolve `path` from the OpenAPI webhooks map. */
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-route-parameters.d.ts","sourceRoot":"","sources":["../../../../../src/v2/features/modal/helpers/resolve-route-parameters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAA;AAEnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAGpE,OAAO,KAAK,EAAE,cAAc,EAAoB,MAAM,4CAA4C,CAAA;AAGlG,4DAA4D;AAC5D,MAAM,MAAM,YAAY,GAAG;IACzB,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,UAAU,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,oDAAoD;IACpD,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,CAAA;AAED,gEAAgE;AAChE,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,CAAA;AAED,uEAAuE;AACvE,KAAK,eAAe,GAAG;IACrB,KAAK,EAAE,cAAc,CAAA;IACrB,YAAY,EAAE,MAAM,GAAG,SAAS,CAAA;CACjC,CAAA;AAeD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB,GAAI,OAAO,cAAc,EAAE,MAAM,MAAM,GAAG,SAAS,KAAG,MAAM,GAAG,SAe9F,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GAAI,KAAK,eAAe,EAAE,MAAM,MAAM,GAAG,SAAS,EAAE,mBAAiB,KAAG,MAAM,GAAG,SAYxG,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,aAAa,GACxB,KAAK,eAAe,EACpB,MAAM,MAAM,GAAG,SAAS,EACxB,QAAQ,MAAM,GAAG,SAAS,EAC1B,mBAAiB,KAChB,UAAU,GAAG,SAiBf,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAC7B,KAAK,eAAe,EACpB,WAAW,cAAc,GAAG,SAAS,EACrC,YAAY,MAAM,GAAG,SAAS,KAC7B,MAmBF,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,GAAI,OAAO,cAAc,EAAE,QAAQ,eAAe,KAAG,OAAO,CAAC,YAAY,CAsB3G,CAAA"}
1
+ {"version":3,"file":"resolve-route-parameters.d.ts","sourceRoot":"","sources":["../../../../../src/v2/features/modal/helpers/resolve-route-parameters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAA;AAEnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAGpE,OAAO,KAAK,EAAE,cAAc,EAAoB,MAAM,4CAA4C,CAAA;AAGlG;;;;;;GAMG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,0DAA0D;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,UAAU,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,oDAAoD;IACpD,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,CAAA;AAED,gEAAgE;AAChE,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,CAAA;AAED,uEAAuE;AACvE,KAAK,eAAe,GAAG;IACrB,KAAK,EAAE,cAAc,CAAA;IACrB,YAAY,EAAE,MAAM,GAAG,SAAS,CAAA;CACjC,CAAA;AAeD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB,GAAI,OAAO,cAAc,EAAE,MAAM,MAAM,GAAG,SAAS,KAAG,MAAM,GAAG,SAe9F,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GAAI,KAAK,eAAe,EAAE,MAAM,MAAM,GAAG,SAAS,EAAE,mBAAiB,KAAG,MAAM,GAAG,SAYxG,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,aAAa,GACxB,KAAK,eAAe,EACpB,MAAM,MAAM,GAAG,SAAS,EACxB,QAAQ,MAAM,GAAG,SAAS,EAC1B,mBAAiB,KAChB,UAAU,GAAG,SAiBf,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAC7B,KAAK,eAAe,EACpB,WAAW,cAAc,GAAG,SAAS,EACrC,YAAY,MAAM,GAAG,SAAS,KAC7B,MAmBF,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,GAAI,OAAO,cAAc,EAAE,QAAQ,eAAe,KAAG,OAAO,CAAC,YAAY,CAsB3G,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-route-parameters.js","names":[],"sources":["../../../../../src/v2/features/modal/helpers/resolve-route-parameters.ts"],"sourcesContent":["import type { HttpMethod } from '@scalar/helpers/http/http-methods'\nimport { isHttpMethod } from '@scalar/helpers/http/is-http-method'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\nimport { getResolvedPathItem } from '@scalar/workspace-store/helpers/for-each-path-item-operation'\nimport { getOperationEntries } from '@scalar/workspace-store/navigation'\nimport type { TraversedEntry, TraversedExample } from '@scalar/workspace-store/schemas/navigation'\nimport { isOpenApiDocument } from '@scalar/workspace-store/schemas/type-guards'\n\n/** Payload for routing and opening the API client modal. */\nexport type RoutePayload = {\n /** API path, or webhook name when `isWebhook` is true. */\n path: string\n method: HttpMethod\n example?: string\n documentSlug?: string\n /** Resolve `path` from the OpenAPI webhooks map. */\n isWebhook?: boolean\n}\n\n/** Raw input values that may contain \"default\" placeholders. */\nexport type DefaultEntities = {\n path: string\n method: string\n example: string\n documentSlug: string\n isWebhook?: boolean\n}\n\n/** Context for resolving route parameters from the workspace store. */\ntype ResolverContext = {\n store: WorkspaceStore\n documentSlug: string | undefined\n}\n\n/** Type guard to check if an entry is an example. */\nconst isExample = (entry: TraversedEntry): entry is TraversedExample => entry.type === 'example'\n\n/**\n * Gets the document from the workspace store.\n * Returns undefined if the document slug is not provided or the document does not exist.\n * Modal routing is OpenAPI-only — AsyncAPI docs surface as undefined here.\n */\nconst getDocument = (ctx: ResolverContext) => {\n const doc = ctx.store.workspace.documents[ctx.documentSlug ?? '']\n return isOpenApiDocument(doc) ? doc : undefined\n}\n\n/**\n * Resolves the document slug from a raw input value.\n *\n * When \"default\" is specified and no document exists with that slug,\n * we fall back to the active document or the first available document.\n * Modal routing is OpenAPI-only, so the fallback skips AsyncAPI documents —\n * otherwise opening the modal with default params on a workspace that has\n * an AsyncAPI active or first document would hand a slug back that\n * `getDocument` then resolves to undefined, rendering the modal with\n * `document: null` even when OpenAPI documents exist.\n */\nexport const resolveDocumentSlug = (store: WorkspaceStore, slug: string | undefined): string | undefined => {\n const hasMatchingDocument = slug !== 'default' || store.workspace.documents[slug] !== undefined\n\n if (hasMatchingDocument) {\n return slug\n }\n\n // Prefer the active document when it is OpenAPI; otherwise pick the first\n // OpenAPI document in the workspace.\n const activeSlug = store.workspace['x-scalar-active-document']\n if (activeSlug && isOpenApiDocument(store.workspace.documents[activeSlug])) {\n return activeSlug\n }\n\n return Object.entries(store.workspace.documents).find(([, document]) => isOpenApiDocument(document))?.[0]\n}\n\n/**\n * Resolves the path from a raw input value.\n *\n * When \"default\" is specified, returns the first available path in the document.\n * This is useful for initial navigation when no specific path is requested.\n */\nexport const resolvePath = (ctx: ResolverContext, path: string | undefined, isWebhook = false): string | undefined => {\n const document = getDocument(ctx)\n\n if (!document) {\n return undefined\n }\n\n if (path === 'default') {\n return Object.keys(isWebhook ? (document.webhooks ?? {}) : (document.paths ?? {}))[0]\n }\n\n return path\n}\n\n/**\n * Resolves the HTTP method from a raw input value.\n *\n * When \"default\" is specified, returns the first valid HTTP method for the given path.\n * This ensures we select a real method rather than metadata keys like \"parameters\" or \"summary\".\n */\nexport const resolveMethod = (\n ctx: ResolverContext,\n path: string | undefined,\n method: string | undefined,\n isWebhook = false,\n): HttpMethod | undefined => {\n const document = getDocument(ctx)\n\n if (!document || !path) {\n return undefined\n }\n\n if (method === 'default') {\n const pathItem = getResolvedPathItem(isWebhook ? document.webhooks?.[path] : document.paths?.[path])\n if (!pathItem) {\n return undefined\n }\n const pathMethods = Object.keys(pathItem).filter(isHttpMethod)\n return pathMethods[0]\n }\n\n return isHttpMethod(method) ? method : undefined\n}\n\n/**\n * Resolves the example name from a raw input value.\n *\n * When \"default\" is specified, returns the first available example name.\n * Falls back to \"default\" when no examples exist, which signals to use the default request body.\n */\nexport const resolveExampleName = (\n ctx: ResolverContext,\n operation: TraversedEntry | undefined,\n exampleKey: string | undefined,\n): string => {\n const document = getDocument(ctx)\n\n if (!document || operation?.type !== 'operation') {\n return 'default'\n }\n\n const examples = operation.children?.filter(isExample) ?? []\n const matchingExample = examples.find((child) => child.name === exampleKey)\n\n if (matchingExample) {\n return matchingExample.name\n }\n\n if (exampleKey === 'default') {\n return examples[0]?.name ?? 'default'\n }\n\n return 'default'\n}\n\n/**\n * Resolves all route parameters from raw input values to their actual values.\n *\n * This function handles \"default\" placeholders by looking up actual values from the workspace store.\n * It ensures the modal can be opened even when the caller does not know specific paths, methods, or examples.\n */\nexport const resolveRouteParameters = (store: WorkspaceStore, params: DefaultEntities): Partial<RoutePayload> => {\n const documentSlug = resolveDocumentSlug(store, params.documentSlug)\n const ctx: ResolverContext = { store, documentSlug }\n const isWebhook = params.isWebhook ?? false\n\n const path = resolvePath(ctx, params.path, isWebhook)\n const method = resolveMethod(ctx, path, params.method, isWebhook)\n const routeType = isWebhook ? { isWebhook: true as const } : {}\n\n const traversedDocument = getDocument(ctx)?.['x-scalar-navigation']\n\n if (!traversedDocument) {\n return { documentSlug, path, method, example: 'default', ...routeType }\n }\n\n const operations = getOperationEntries(traversedDocument)\n const operation = operations\n .get(`${path}|${method}`)\n ?.find((entry) => entry.type === (isWebhook ? 'webhook' : 'operation'))\n const example = resolveExampleName(ctx, operation, params.example)\n\n return { documentSlug, path, method, example, ...routeType }\n}\n"],"mappings":";;;;;;AAmCA,IAAM,aAAa,UAAqD,MAAM,SAAS;;;;;;AAOvF,IAAM,eAAe,QAAyB;CAC5C,MAAM,MAAM,IAAI,MAAM,UAAU,UAAU,IAAI,gBAAgB;CAC9D,OAAO,kBAAkB,GAAG,IAAI,MAAM,KAAA;AACxC;;;;;;;;;;;;AAaA,IAAa,uBAAuB,OAAuB,SAAiD;CAG1G,IAF4B,SAAS,aAAa,MAAM,UAAU,UAAU,UAAU,KAAA,GAGpF,OAAO;CAKT,MAAM,aAAa,MAAM,UAAU;CACnC,IAAI,cAAc,kBAAkB,MAAM,UAAU,UAAU,WAAW,GACvE,OAAO;CAGT,OAAO,OAAO,QAAQ,MAAM,UAAU,SAAS,CAAC,CAAC,MAAM,GAAG,cAAc,kBAAkB,QAAQ,CAAC,CAAC,GAAG;AACzG;;;;;;;AAQA,IAAa,eAAe,KAAsB,MAA0B,YAAY,UAA8B;CACpH,MAAM,WAAW,YAAY,GAAG;CAEhC,IAAI,CAAC,UACH;CAGF,IAAI,SAAS,WACX,OAAO,OAAO,KAAK,YAAa,SAAS,YAAY,CAAC,IAAM,SAAS,SAAS,CAAC,CAAE,CAAC,CAAC;CAGrF,OAAO;AACT;;;;;;;AAQA,IAAa,iBACX,KACA,MACA,QACA,YAAY,UACe;CAC3B,MAAM,WAAW,YAAY,GAAG;CAEhC,IAAI,CAAC,YAAY,CAAC,MAChB;CAGF,IAAI,WAAW,WAAW;EACxB,MAAM,WAAW,oBAAoB,YAAY,SAAS,WAAW,QAAQ,SAAS,QAAQ,KAAK;EACnG,IAAI,CAAC,UACH;EAGF,OADoB,OAAO,KAAK,QAAQ,CAAC,CAAC,OAAO,YAC1C,CAAA,CAAY;CACrB;CAEA,OAAO,aAAa,MAAM,IAAI,SAAS,KAAA;AACzC;;;;;;;AAQA,IAAa,sBACX,KACA,WACA,eACW;CAGX,IAAI,CAFa,YAAY,GAExB,KAAY,WAAW,SAAS,aACnC,OAAO;CAGT,MAAM,WAAW,UAAU,UAAU,OAAO,SAAS,KAAK,CAAC;CAC3D,MAAM,kBAAkB,SAAS,MAAM,UAAU,MAAM,SAAS,UAAU;CAE1E,IAAI,iBACF,OAAO,gBAAgB;CAGzB,IAAI,eAAe,WACjB,OAAO,SAAS,EAAE,EAAE,QAAQ;CAG9B,OAAO;AACT;;;;;;;AAQA,IAAa,0BAA0B,OAAuB,WAAmD;CAC/G,MAAM,eAAe,oBAAoB,OAAO,OAAO,YAAY;CACnE,MAAM,MAAuB;EAAE;EAAO;CAAa;CACnD,MAAM,YAAY,OAAO,aAAa;CAEtC,MAAM,OAAO,YAAY,KAAK,OAAO,MAAM,SAAS;CACpD,MAAM,SAAS,cAAc,KAAK,MAAM,OAAO,QAAQ,SAAS;CAChE,MAAM,YAAY,YAAY,EAAE,WAAW,KAAc,IAAI,CAAC;CAE9D,MAAM,oBAAoB,YAAY,GAAG,CAAC,GAAG;CAE7C,IAAI,CAAC,mBACH,OAAO;EAAE;EAAc;EAAM;EAAQ,SAAS;EAAW,GAAG;CAAU;CAIxE,MAAM,YADa,oBAAoB,iBACrB,CAAA,CACf,IAAI,GAAG,KAAK,GAAG,QAAQ,CAAC,EACvB,MAAM,UAAU,MAAM,UAAU,YAAY,YAAY,YAAY;CAGxE,OAAO;EAAE;EAAc;EAAM;EAAQ,SAFrB,mBAAmB,KAAK,WAAW,OAAO,OAErB;EAAS,GAAG;CAAU;AAC7D"}
1
+ {"version":3,"file":"resolve-route-parameters.js","names":[],"sources":["../../../../../src/v2/features/modal/helpers/resolve-route-parameters.ts"],"sourcesContent":["import type { HttpMethod } from '@scalar/helpers/http/http-methods'\nimport { isHttpMethod } from '@scalar/helpers/http/is-http-method'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\nimport { getResolvedPathItem } from '@scalar/workspace-store/helpers/for-each-path-item-operation'\nimport { getOperationEntries } from '@scalar/workspace-store/navigation'\nimport type { TraversedEntry, TraversedExample } from '@scalar/workspace-store/schemas/navigation'\nimport { isOpenApiDocument } from '@scalar/workspace-store/schemas/type-guards'\n\n/**\n * Payload for routing and opening the API client modal.\n *\n * `path` and `method` are optional so a caller can update `documentSlug` on its own.\n * `route()` fills in whichever fields are missing from its \"default\" placeholders, which\n * resolve to the document's first operation instead of a route that does not exist.\n */\nexport type RoutePayload = {\n /** API path, or webhook name when `isWebhook` is true. */\n path?: string\n method?: HttpMethod\n example?: string\n documentSlug?: string\n /** Resolve `path` from the OpenAPI webhooks map. */\n isWebhook?: boolean\n}\n\n/** Raw input values that may contain \"default\" placeholders. */\nexport type DefaultEntities = {\n path: string\n method: string\n example: string\n documentSlug: string\n isWebhook?: boolean\n}\n\n/** Context for resolving route parameters from the workspace store. */\ntype ResolverContext = {\n store: WorkspaceStore\n documentSlug: string | undefined\n}\n\n/** Type guard to check if an entry is an example. */\nconst isExample = (entry: TraversedEntry): entry is TraversedExample => entry.type === 'example'\n\n/**\n * Gets the document from the workspace store.\n * Returns undefined if the document slug is not provided or the document does not exist.\n * Modal routing is OpenAPI-only — AsyncAPI docs surface as undefined here.\n */\nconst getDocument = (ctx: ResolverContext) => {\n const doc = ctx.store.workspace.documents[ctx.documentSlug ?? '']\n return isOpenApiDocument(doc) ? doc : undefined\n}\n\n/**\n * Resolves the document slug from a raw input value.\n *\n * When \"default\" is specified and no document exists with that slug,\n * we fall back to the active document or the first available document.\n * Modal routing is OpenAPI-only, so the fallback skips AsyncAPI documents —\n * otherwise opening the modal with default params on a workspace that has\n * an AsyncAPI active or first document would hand a slug back that\n * `getDocument` then resolves to undefined, rendering the modal with\n * `document: null` even when OpenAPI documents exist.\n */\nexport const resolveDocumentSlug = (store: WorkspaceStore, slug: string | undefined): string | undefined => {\n const hasMatchingDocument = slug !== 'default' || store.workspace.documents[slug] !== undefined\n\n if (hasMatchingDocument) {\n return slug\n }\n\n // Prefer the active document when it is OpenAPI; otherwise pick the first\n // OpenAPI document in the workspace.\n const activeSlug = store.workspace['x-scalar-active-document']\n if (activeSlug && isOpenApiDocument(store.workspace.documents[activeSlug])) {\n return activeSlug\n }\n\n return Object.entries(store.workspace.documents).find(([, document]) => isOpenApiDocument(document))?.[0]\n}\n\n/**\n * Resolves the path from a raw input value.\n *\n * When \"default\" is specified, returns the first available path in the document.\n * This is useful for initial navigation when no specific path is requested.\n */\nexport const resolvePath = (ctx: ResolverContext, path: string | undefined, isWebhook = false): string | undefined => {\n const document = getDocument(ctx)\n\n if (!document) {\n return undefined\n }\n\n if (path === 'default') {\n return Object.keys(isWebhook ? (document.webhooks ?? {}) : (document.paths ?? {}))[0]\n }\n\n return path\n}\n\n/**\n * Resolves the HTTP method from a raw input value.\n *\n * When \"default\" is specified, returns the first valid HTTP method for the given path.\n * This ensures we select a real method rather than metadata keys like \"parameters\" or \"summary\".\n */\nexport const resolveMethod = (\n ctx: ResolverContext,\n path: string | undefined,\n method: string | undefined,\n isWebhook = false,\n): HttpMethod | undefined => {\n const document = getDocument(ctx)\n\n if (!document || !path) {\n return undefined\n }\n\n if (method === 'default') {\n const pathItem = getResolvedPathItem(isWebhook ? document.webhooks?.[path] : document.paths?.[path])\n if (!pathItem) {\n return undefined\n }\n const pathMethods = Object.keys(pathItem).filter(isHttpMethod)\n return pathMethods[0]\n }\n\n return isHttpMethod(method) ? method : undefined\n}\n\n/**\n * Resolves the example name from a raw input value.\n *\n * When \"default\" is specified, returns the first available example name.\n * Falls back to \"default\" when no examples exist, which signals to use the default request body.\n */\nexport const resolveExampleName = (\n ctx: ResolverContext,\n operation: TraversedEntry | undefined,\n exampleKey: string | undefined,\n): string => {\n const document = getDocument(ctx)\n\n if (!document || operation?.type !== 'operation') {\n return 'default'\n }\n\n const examples = operation.children?.filter(isExample) ?? []\n const matchingExample = examples.find((child) => child.name === exampleKey)\n\n if (matchingExample) {\n return matchingExample.name\n }\n\n if (exampleKey === 'default') {\n return examples[0]?.name ?? 'default'\n }\n\n return 'default'\n}\n\n/**\n * Resolves all route parameters from raw input values to their actual values.\n *\n * This function handles \"default\" placeholders by looking up actual values from the workspace store.\n * It ensures the modal can be opened even when the caller does not know specific paths, methods, or examples.\n */\nexport const resolveRouteParameters = (store: WorkspaceStore, params: DefaultEntities): Partial<RoutePayload> => {\n const documentSlug = resolveDocumentSlug(store, params.documentSlug)\n const ctx: ResolverContext = { store, documentSlug }\n const isWebhook = params.isWebhook ?? false\n\n const path = resolvePath(ctx, params.path, isWebhook)\n const method = resolveMethod(ctx, path, params.method, isWebhook)\n const routeType = isWebhook ? { isWebhook: true as const } : {}\n\n const traversedDocument = getDocument(ctx)?.['x-scalar-navigation']\n\n if (!traversedDocument) {\n return { documentSlug, path, method, example: 'default', ...routeType }\n }\n\n const operations = getOperationEntries(traversedDocument)\n const operation = operations\n .get(`${path}|${method}`)\n ?.find((entry) => entry.type === (isWebhook ? 'webhook' : 'operation'))\n const example = resolveExampleName(ctx, operation, params.example)\n\n return { documentSlug, path, method, example, ...routeType }\n}\n"],"mappings":";;;;;;AAyCA,IAAM,aAAa,UAAqD,MAAM,SAAS;;;;;;AAOvF,IAAM,eAAe,QAAyB;CAC5C,MAAM,MAAM,IAAI,MAAM,UAAU,UAAU,IAAI,gBAAgB;CAC9D,OAAO,kBAAkB,GAAG,IAAI,MAAM,KAAA;AACxC;;;;;;;;;;;;AAaA,IAAa,uBAAuB,OAAuB,SAAiD;CAG1G,IAF4B,SAAS,aAAa,MAAM,UAAU,UAAU,UAAU,KAAA,GAGpF,OAAO;CAKT,MAAM,aAAa,MAAM,UAAU;CACnC,IAAI,cAAc,kBAAkB,MAAM,UAAU,UAAU,WAAW,GACvE,OAAO;CAGT,OAAO,OAAO,QAAQ,MAAM,UAAU,SAAS,CAAC,CAAC,MAAM,GAAG,cAAc,kBAAkB,QAAQ,CAAC,CAAC,GAAG;AACzG;;;;;;;AAQA,IAAa,eAAe,KAAsB,MAA0B,YAAY,UAA8B;CACpH,MAAM,WAAW,YAAY,GAAG;CAEhC,IAAI,CAAC,UACH;CAGF,IAAI,SAAS,WACX,OAAO,OAAO,KAAK,YAAa,SAAS,YAAY,CAAC,IAAM,SAAS,SAAS,CAAC,CAAE,CAAC,CAAC;CAGrF,OAAO;AACT;;;;;;;AAQA,IAAa,iBACX,KACA,MACA,QACA,YAAY,UACe;CAC3B,MAAM,WAAW,YAAY,GAAG;CAEhC,IAAI,CAAC,YAAY,CAAC,MAChB;CAGF,IAAI,WAAW,WAAW;EACxB,MAAM,WAAW,oBAAoB,YAAY,SAAS,WAAW,QAAQ,SAAS,QAAQ,KAAK;EACnG,IAAI,CAAC,UACH;EAGF,OADoB,OAAO,KAAK,QAAQ,CAAC,CAAC,OAAO,YAC1C,CAAA,CAAY;CACrB;CAEA,OAAO,aAAa,MAAM,IAAI,SAAS,KAAA;AACzC;;;;;;;AAQA,IAAa,sBACX,KACA,WACA,eACW;CAGX,IAAI,CAFa,YAAY,GAExB,KAAY,WAAW,SAAS,aACnC,OAAO;CAGT,MAAM,WAAW,UAAU,UAAU,OAAO,SAAS,KAAK,CAAC;CAC3D,MAAM,kBAAkB,SAAS,MAAM,UAAU,MAAM,SAAS,UAAU;CAE1E,IAAI,iBACF,OAAO,gBAAgB;CAGzB,IAAI,eAAe,WACjB,OAAO,SAAS,EAAE,EAAE,QAAQ;CAG9B,OAAO;AACT;;;;;;;AAQA,IAAa,0BAA0B,OAAuB,WAAmD;CAC/G,MAAM,eAAe,oBAAoB,OAAO,OAAO,YAAY;CACnE,MAAM,MAAuB;EAAE;EAAO;CAAa;CACnD,MAAM,YAAY,OAAO,aAAa;CAEtC,MAAM,OAAO,YAAY,KAAK,OAAO,MAAM,SAAS;CACpD,MAAM,SAAS,cAAc,KAAK,MAAM,OAAO,QAAQ,SAAS;CAChE,MAAM,YAAY,YAAY,EAAE,WAAW,KAAc,IAAI,CAAC;CAE9D,MAAM,oBAAoB,YAAY,GAAG,CAAC,GAAG;CAE7C,IAAI,CAAC,mBACH,OAAO;EAAE;EAAc;EAAM;EAAQ,SAAS;EAAW,GAAG;CAAU;CAIxE,MAAM,YADa,oBAAoB,iBACrB,CAAA,CACf,IAAI,GAAG,KAAK,GAAG,QAAQ,CAAC,EACvB,MAAM,UAAU,MAAM,UAAU,YAAY,YAAY,YAAY;CAGxE,OAAO;EAAE;EAAc;EAAM;EAAQ,SAFrB,mBAAmB,KAAK,WAAW,OAAO,OAErB;EAAS,GAAG;CAAU;AAC7D"}
@@ -152,23 +152,23 @@ to {
152
152
  /*
153
153
  Deep styling for customizing Codemirror
154
154
  */
155
- [data-v-b5082dc8] .cm-editor {
155
+ [data-v-dbc85839] .cm-editor {
156
156
  height: 100%;
157
157
  outline: none;
158
158
  padding: 0;
159
159
  background: transparent;
160
160
  }
161
- [data-v-b5082dc8] .cm-placeholder {
161
+ [data-v-dbc85839] .cm-placeholder {
162
162
  color: var(--scalar-color-3);
163
163
  }
164
- [data-v-b5082dc8] .cm-content {
164
+ [data-v-dbc85839] .cm-content {
165
165
  font-family: var(--scalar-font-code);
166
166
  font-size: var(--scalar-small);
167
167
  max-height: 20px;
168
168
  padding: 8px 0;
169
169
  }
170
170
  /* Tooltip helper */
171
- [data-v-b5082dc8] .cm-tooltip {
171
+ [data-v-dbc85839] .cm-tooltip {
172
172
  background: transparent !important;
173
173
  filter: brightness(var(--scalar-lifted-brightness));
174
174
  border-radius: var(--scalar-radius);
@@ -177,43 +177,43 @@ to {
177
177
  outline: none !important;
178
178
  overflow: hidden !important;
179
179
  }
180
- [data-v-b5082dc8] .cm-tooltip-autocomplete ul li {
180
+ [data-v-dbc85839] .cm-tooltip-autocomplete ul li {
181
181
  padding: 3px 6px !important;
182
182
  }
183
- [data-v-b5082dc8] .cm-completionIcon-type:after {
183
+ [data-v-dbc85839] .cm-completionIcon-type:after {
184
184
  color: var(--scalar-color-3) !important;
185
185
  }
186
- [data-v-b5082dc8] .cm-tooltip-autocomplete ul li[aria-selected] {
186
+ [data-v-dbc85839] .cm-tooltip-autocomplete ul li[aria-selected] {
187
187
  background: var(--scalar-background-2) !important;
188
188
  color: var(--scalar-color-1) !important;
189
189
  }
190
- [data-v-b5082dc8] .cm-tooltip-autocomplete ul {
190
+ [data-v-dbc85839] .cm-tooltip-autocomplete ul {
191
191
  padding: 6px !important;
192
192
  position: relative;
193
193
  }
194
- [data-v-b5082dc8] .cm-tooltip-autocomplete ul li:hover {
194
+ [data-v-dbc85839] .cm-tooltip-autocomplete ul li:hover {
195
195
  border-radius: 3px;
196
196
  color: var(--scalar-color-1) !important;
197
197
  background: var(--scalar-background-3) !important;
198
198
  }
199
199
  /* Disable active line highlighting */
200
- [data-v-b5082dc8] .cm-activeLine,[data-v-b5082dc8] .cm-activeLineGutter {
200
+ [data-v-dbc85839] .cm-activeLine,[data-v-dbc85839] .cm-activeLineGutter {
201
201
  background-color: transparent;
202
202
  }
203
203
  /* Color selection matching */
204
- [data-v-b5082dc8] .cm-selectionMatch,[data-v-b5082dc8] .cm-matchingBracket {
204
+ [data-v-dbc85839] .cm-selectionMatch,[data-v-dbc85839] .cm-matchingBracket {
205
205
  border-radius: var(--scalar-radius);
206
206
  background: var(--scalar-background-4) !important;
207
207
  }
208
208
  /* Color Picker Swatches */
209
- [data-v-b5082dc8] .cm-css-color-picker-wrapper {
209
+ [data-v-dbc85839] .cm-css-color-picker-wrapper {
210
210
  display: inline-flex;
211
211
  outline: 1px solid var(--scalar-background-3);
212
212
  border-radius: 3px;
213
213
  overflow: hidden;
214
214
  }
215
215
  /* Number gutter */
216
- [data-v-b5082dc8] .cm-gutters {
216
+ [data-v-dbc85839] .cm-gutters {
217
217
  background-color: transparent;
218
218
  border-right: none;
219
219
  color: var(--scalar-color-3);
@@ -221,7 +221,7 @@ to {
221
221
  line-height: 22px;
222
222
  border-radius: 0 0 0 3px;
223
223
  }
224
- [data-v-b5082dc8] .cm-gutters:before {
224
+ [data-v-dbc85839] .cm-gutters:before {
225
225
  content: '';
226
226
  position: absolute;
227
227
  top: 2px;
@@ -231,7 +231,7 @@ to {
231
231
  border-radius: var(--scalar-radius) 0 0 var(--scalar-radius);
232
232
  background-color: var(--scalar-background-1);
233
233
  }
234
- [data-v-b5082dc8] .cm-gutterElement {
234
+ [data-v-dbc85839] .cm-gutterElement {
235
235
  font-family: var(--scalar-font-code) !important;
236
236
  padding-left: 0px !important;
237
237
  padding-right: 6px !important;
@@ -240,16 +240,23 @@ to {
240
240
  justify-content: flex-end;
241
241
  position: relative;
242
242
  }
243
- [data-v-b5082dc8] .cm-lineNumbers .cm-gutterElement {
243
+ [data-v-dbc85839] .cm-lineNumbers .cm-gutterElement {
244
244
  min-width: fit-content;
245
245
  }
246
- [data-v-b5082dc8] .cm-gutter + .cm-gutter :not(.cm-foldGutter) .cm-gutterElement {
246
+ [data-v-dbc85839] .cm-gutter + .cm-gutter :not(.cm-foldGutter) .cm-gutterElement {
247
247
  padding-left: 0 !important;
248
248
  }
249
- [data-v-b5082dc8] .cm-scroller {
249
+ [data-v-dbc85839] .cm-scroller {
250
250
  overflow: auto;
251
251
  }
252
- .line-wrapping[data-v-b5082dc8]:focus-within .cm-content {
252
+ [data-v-dbc85839] .cm-lineWrapping .cm-line {
253
+ word-break: break-all;
254
+ }
255
+ [data-v-dbc85839] .cm-lineWrapping .cm-content {
256
+ white-space: pre-wrap;
257
+ max-height: none;
258
+ }
259
+ .line-wrapping[data-v-dbc85839]:focus-within .cm-content {
253
260
  display: inline-table;
254
261
  min-height: fit-content;
255
262
  padding: 3px 6px;
@@ -418,7 +425,7 @@ to {
418
425
  margin-left: 0.5px;
419
426
  }
420
427
 
421
- [data-v-ed64587d] .cm-content {
428
+ [data-v-d1ae5565] .cm-content {
422
429
  font-size: var(--scalar-small);
423
430
  }
424
431
 
@@ -496,19 +503,22 @@ input[data-v-a6f4752a]::placeholder {
496
503
  border-color: var(--scalar-border-color) !important;
497
504
  }
498
505
 
499
- [data-v-8c1df828] .cm-editor {
506
+ [data-v-6e055eb2] .cm-editor {
500
507
  background-color: transparent;
501
508
  font-size: var(--scalar-small);
502
509
  outline: none;
503
510
  }
504
- [data-v-8c1df828] .cm-gutters {
511
+ [data-v-6e055eb2] .cm-gutters {
505
512
  background-color: var(--scalar-background-1);
506
513
  border-radius: var(--scalar-radius) 0 0 var(--scalar-radius);
507
514
  }
508
- [data-v-8c1df828] .cm-scroller {
515
+ [data-v-6e055eb2] .cm-scroller {
509
516
  overflow: auto;
510
517
  min-width: 100%;
511
518
  }
519
+ [data-v-6e055eb2] .cm-lineWrapping .cm-line {
520
+ word-break: break-all;
521
+ }
512
522
 
513
523
  .light-mode .bg-preview[data-v-a10b4008] {
514
524
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='%23000' fill-opacity='10%25'%3E%3Crect width='8' height='8' /%3E%3Crect x='8' y='8' width='8' height='8' /%3E%3C/svg%3E");
package/package.json CHANGED
@@ -18,7 +18,7 @@
18
18
  "rest",
19
19
  "testing"
20
20
  ],
21
- "version": "3.19.0",
21
+ "version": "3.19.1",
22
22
  "engines": {
23
23
  "node": ">=22"
24
24
  },
@@ -295,7 +295,21 @@
295
295
  "dependencies": {
296
296
  "@headlessui/tailwindcss": "^0.2.2",
297
297
  "@headlessui/vue": "1.7.23",
298
+ "@scalar/blocks": "0.1.18",
299
+ "@scalar/components": "0.29.3",
300
+ "@scalar/helpers": "0.12.0",
301
+ "@scalar/icons": "0.7.6",
302
+ "@scalar/oas-utils": "0.20.1",
303
+ "@scalar/openapi-types": "0.9.6",
304
+ "@scalar/sidebar": "0.11.3",
305
+ "@scalar/snippetz": "0.9.31",
306
+ "@scalar/themes": "0.18.0",
298
307
  "@scalar/typebox": "^0.1.3",
308
+ "@scalar/types": "0.20.0",
309
+ "@scalar/use-codemirror": "0.14.15",
310
+ "@scalar/use-hooks": "0.4.12",
311
+ "@scalar/use-toasts": "0.10.5",
312
+ "@scalar/workspace-store": "0.62.0",
299
313
  "@vueuse/core": "13.9.0",
300
314
  "@vueuse/integrations": "13.9.0",
301
315
  "focus-trap": "^7.8.0",
@@ -308,21 +322,7 @@
308
322
  "set-cookie-parser": "3.1.0",
309
323
  "vue": "^3.5.40",
310
324
  "yaml": "^2.9.0",
311
- "zod": "^4.4.3",
312
- "@scalar/blocks": "0.1.17",
313
- "@scalar/components": "0.29.2",
314
- "@scalar/helpers": "0.12.0",
315
- "@scalar/icons": "0.7.6",
316
- "@scalar/sidebar": "0.11.2",
317
- "@scalar/oas-utils": "0.20.0",
318
- "@scalar/openapi-types": "0.9.6",
319
- "@scalar/snippetz": "0.9.31",
320
- "@scalar/types": "0.20.0",
321
- "@scalar/use-hooks": "0.4.12",
322
- "@scalar/themes": "0.18.0",
323
- "@scalar/use-codemirror": "0.14.15",
324
- "@scalar/use-toasts": "0.10.5",
325
- "@scalar/workspace-store": "0.61.0"
325
+ "zod": "^4.4.3"
326
326
  },
327
327
  "devDependencies": {
328
328
  "@tailwindcss/cli": "^4.3.3",