@scalar/api-client 3.16.1 → 3.16.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -0
- package/dist/style.css +9 -9
- package/dist/v2/blocks/request-block/RequestBlock.vue.script.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestBody.vue.d.ts.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestBody.vue.js +1 -1
- package/dist/v2/blocks/request-block/components/RequestBody.vue.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestBody.vue.script.js +15 -1
- package/dist/v2/blocks/request-block/components/RequestBody.vue.script.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestTable.vue.d.ts.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestTable.vue.js +1 -1
- package/dist/v2/blocks/request-block/components/RequestTable.vue.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestTable.vue.script.js +13 -1
- package/dist/v2/blocks/request-block/components/RequestTable.vue.script.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestTableRow.vue.d.ts.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestTableRow.vue.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestTableRow.vue.script.js +5 -1
- package/dist/v2/blocks/request-block/components/RequestTableRow.vue.script.js.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/AuthSelector.vue.script.js.map +1 -1
- package/dist/v2/components/code-input/CodeInputLite.vue.d.ts.map +1 -1
- package/dist/v2/components/code-input/CodeInputLite.vue.js +1 -1
- package/dist/v2/components/code-input/CodeInputLite.vue.js.map +1 -1
- package/dist/v2/components/code-input/CodeInputLite.vue.script.js +7 -0
- package/dist/v2/components/code-input/CodeInputLite.vue.script.js.map +1 -1
- package/dist/v2/constants.js +1 -1
- package/dist/v2/features/modal/helpers/create-api-client-modal.d.ts.map +1 -1
- package/dist/v2/features/modal/helpers/create-api-client-modal.js +1 -5
- package/dist/v2/features/modal/helpers/create-api-client-modal.js.map +1 -1
- package/dist/v2/features/modal/modal-events.d.ts.map +1 -1
- package/dist/v2/features/modal/modal-events.js +4 -2
- package/dist/v2/features/modal/modal-events.js.map +1 -1
- package/dist/v2/features/search/helpers/create-search-index.js +2 -2
- package/dist/v2/features/search/helpers/create-search-index.js.map +1 -1
- package/dist/vue-styles.css +9 -9
- package/package.json +17 -17
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeInputLite.vue.script.js","names":["$attrs","$slots"],"sources":["../../../../src/v2/components/code-input/CodeInputLite.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * CodeInputLite\n *\n * Single-line `contenteditable` editor that renders `{{varname}}` as atomic\n * pill spans (`contenteditable=\"false\"`) and offers an env-variable\n * autocomplete on `{{`. The value is still exposed as a `{{name}}`-bearing\n * string via `update:modelValue`; DOM ↔ model conversion lives in\n * `renderModel` and `serializeEditor`.\n */\nexport default {\n inheritAttrs: false,\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { isDefined } from '@scalar/helpers/array/is-defined'\nimport { REGEX } from '@scalar/helpers/regex/regex-helpers'\nimport {\n CONTEXT_FUNCTION_NAMES,\n getContextFunctionComment,\n isContextFunctionName,\n type ContextFunctionName,\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 {\n computed,\n createApp,\n nextTick,\n onBeforeUnmount,\n onMounted,\n ref,\n useAttrs,\n useTemplateRef,\n watch,\n type App,\n} 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 type { CodeInputModelValue } from './CodeInput.vue'\nimport { buildPillContext } from './helpers/build-pill-context'\nimport { lookupVariableValue } from './helpers/lookup-variable-value'\nimport { pillSignature } from './helpers/pill-signature'\nimport { serializeValue } from './helpers/serialize-value'\nimport PillTooltipHost from './PillTooltipHost.vue'\n\ntype Props = {\n modelValue: CodeInputModelValue\n /** Environment for variable substitution. Pass undefined to disable env vars */\n environment: XScalarEnvironment | undefined\n /** Render as a non-interactive read-only label */\n disabled?: boolean\n /** Render the input with the native `readonly` attribute (still focusable, no edits) */\n readOnly?: boolean\n /** Show error styling */\n error?: boolean\n /** Layout context affects styling and dropdown visibility */\n layout?: ClientLayout\n /** Placeholder text for an empty input */\n placeholder?: string\n /** Show required indicator */\n required?: boolean\n /** Emit submit on blur */\n emitOnBlur?: boolean\n /** Render variable pills + show the autocomplete dropdown */\n withVariables?: boolean\n /** Include `{{$guid}}` etc. in the autocomplete dropdown */\n withFakeData?: boolean\n /** Always emit change events even if the value is unchanged */\n alwaysEmitChange?: boolean\n /** Strike-through styling for the input text (e.g. overridden values) */\n linethrough?: boolean\n /** Schema type — drives boolean select mode when `boolean` is included */\n type?: string | string[]\n /** Predefined enum values; when set the input is replaced by a select */\n enum?: string[]\n /** Example values; when set (and no enum/boolean) the input is replaced by a select */\n examples?: string[]\n /** Default value to suggest in select modes */\n default?: CodeInputModelValue\n /** Whether the boolean select includes a `null` option */\n nullable?: boolean\n}\n\nconst {\n modelValue,\n environment,\n disabled = false,\n readOnly = false,\n error = false,\n layout = 'desktop',\n placeholder,\n required = false,\n emitOnBlur = true,\n alwaysEmitChange = false,\n withVariables = true,\n withFakeData = false,\n linethrough = false,\n type,\n enum: enumProp,\n examples,\n default: defaultProp,\n nullable = false,\n} = defineProps<Props>()\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string]\n 'submit': [value: string, event: KeyboardEvent | FocusEvent]\n 'blur': [value: string, event: FocusEvent]\n 'navigate': [route: { page: 'document'; path: 'environment' }]\n}>()\n\nconst attrs = useAttrs() as { 'id'?: string; 'aria-label'?: string }\n\n/**\n * The id only matters once the dropdown opens (`aria-controls` /\n * `aria-activedescendant`), so we defer `nanoid()` until first focus to\n * keep idle instances cheap. A consumer-supplied `id` attr is preserved.\n */\nconst generatedComponentId = ref<string | null>(null)\nconst componentId = computed(\n (): string | undefined => attrs.id ?? generatedComponentId.value ?? undefined,\n)\nconst ensureComponentId = (): void => {\n if (!attrs.id && generatedComponentId.value === null) {\n generatedComponentId.value = `id-${nanoid()}`\n }\n}\n\nconst editorRef = useTemplateRef<HTMLDivElement>('editorRef')\nconst dropdownRef = ref<InstanceType<\n typeof EnvironmentVariableDropdown\n> | null>(null)\n\n/** Id of the dropdown's `role=\"listbox\"` element, for the combobox wiring. */\nconst listboxId = computed((): string | undefined =>\n componentId.value ? `${componentId.value}-listbox` : undefined,\n)\n\n/**\n * Id of the option the dropdown currently highlights. Mirrors the dropdown's\n * own selection so the editor can expose it via `aria-activedescendant`.\n */\nconst activeOptionId = computed(\n (): string | undefined => dropdownRef.value?.activeOptionId,\n)\n\nconst isFocused = ref(false)\nconst isEmpty = ref(true)\n\n/**\n * True while an IME composition is in progress. Rebuilding the editor DOM\n * mid-composition (e.g. when `{{` forms a pill) cancels the composition, so we\n * defer those rebuilds until `compositionend`.\n */\nconst isComposing = ref(false)\n\n/**\n * Whether the serialized value should count as empty for placeholder display.\n *\n * `contenteditable` can leave behind invisible residue after some delete\n * sequences — most commonly a non-breaking space (` `) — which makes a\n * visually empty field report a non-zero length and silently drop its\n * placeholder. Trimming covers that case; ` ` counts as whitespace, so a\n * field that only holds editor residue is treated as empty. This affects the\n * placeholder flag only, never the value emitted via `serializeEditor`.\n */\nconst isBlankValue = (text: string): boolean => text.trim().length === 0\n\n// ───────────────────────────────────────────────────────────────────\n// Rendering-mode detection (parity with CodeInput's select dispatch)\n// ───────────────────────────────────────────────────────────────────\n\n/** True when the schema type is exactly `boolean` (or includes it in a tuple type). */\nconst isBooleanMode = computed((): boolean => {\n if (enumProp?.length) {\n return false\n }\n return type === 'boolean' || (Array.isArray(type) && type.includes('boolean'))\n})\n\nconst booleanOptions = computed((): string[] =>\n nullable ? ['true', 'false', 'null'] : ['true', 'false'],\n)\n\n/** Default type when the schema is a tuple — picks the first non-null entry. */\nconst defaultType = computed((): string | undefined => {\n if (Array.isArray(type)) {\n return type.find((t) => t !== 'null') ?? 'string'\n }\n return type\n})\n\nconst handleSelectChange = (value: string): void =>\n emit('update:modelValue', value)\n\n// ───────────────────────────────────────────────────────────────────\n// Per-pill tooltip apps\n// ───────────────────────────────────────────────────────────────────\n\nlet pillTooltipApps: App[] = []\n\n/**\n * Per-pill tooltips are the heaviest part of the render (a Vue app +\n * `useTooltip` watch + listeners each), so we defer mounting them until\n * the first interaction (focus, pointerover, or dropdown open). Once on,\n * subsequent rebuilds remount tooltips for the new pills.\n */\nlet tooltipsActive = false\n\nconst teardownPillTooltips = (): void => {\n for (const app of pillTooltipApps) {\n app.unmount()\n }\n pillTooltipApps = []\n}\n\nconst mountPillTooltips = (): void => {\n if (!editorRef.value || layout === 'modal') {\n return\n }\n const pills = editorRef.value.querySelectorAll<HTMLElement>('.scalar-pill')\n for (const pillEl of pills) {\n const variableName = pillEl.dataset.variable ?? ''\n const context = buildPillContext(variableName, environment)\n const app = createApp(PillTooltipHost, { context, target: pillEl })\n // PillTooltipHost is renderless; useTooltip attaches to `target` directly.\n app.mount(document.createElement('div'))\n pillTooltipApps.push(app)\n }\n}\n\n// ───────────────────────────────────────────────────────────────────\n// DOM ↔ model conversion\n// ───────────────────────────────────────────────────────────────────\n\n/**\n * Build a pill `<span>` for the given variable. `contentEditable = 'false'`\n * makes the browser treat it as a single atom (arrow keys jump over it,\n * Backspace deletes it whole); `{{` / `}}` only live in the model string.\n */\nconst createPillElement = (\n name: string,\n start: number,\n end: number,\n): HTMLSpanElement => {\n const isCtx = isContextFunctionName(name)\n const span = document.createElement('span')\n span.className = isCtx ? 'scalar-pill scalar-pill--context-fn' : 'scalar-pill'\n span.contentEditable = 'false'\n span.dataset.variable = name\n // Model-coordinate offsets (the pill stands in for the full `{{name}}`).\n // Used by click forwarding and tests to map a pill back to the value.\n span.dataset.pillStart = String(start)\n span.dataset.pillEnd = String(end)\n\n const color = isCtx\n ? 'var(--scalar-color-3)'\n : environment?.color || 'var(--scalar-color-1)'\n span.style.setProperty('--tw-bg-base', color)\n\n // Fade env pills with no usable value. A falsy check (not just\n // `=== undefined`) matches the tooltip path's `Boolean(value)`, so a\n // variable declared with an empty string fades here too.\n const isUndefinedEnv = !isCtx && !lookupVariableValue(environment, name)\n if (isUndefinedEnv) {\n span.style.opacity = '0.5'\n }\n\n span.textContent = name\n return span\n}\n\n/** Render a model string into the editor as a mix of text nodes + pills. */\nconst renderModel = (text: string): void => {\n const editor = editorRef.value\n if (!editor) {\n return\n }\n\n teardownPillTooltips()\n editor.replaceChildren()\n\n if (!withVariables || !text.includes('{{')) {\n if (text) {\n editor.appendChild(document.createTextNode(text))\n }\n isEmpty.value = isBlankValue(text)\n return\n }\n\n const regex = new RegExp(REGEX.VARIABLES.source, REGEX.VARIABLES.flags)\n let lastIndex = 0\n let match: RegExpExecArray | null\n\n while ((match = regex.exec(text)) !== null) {\n const start = match.index\n const end = start + match[0].length\n if (start > lastIndex) {\n editor.appendChild(document.createTextNode(text.slice(lastIndex, start)))\n }\n editor.appendChild(createPillElement(match[1] ?? '', start, end))\n lastIndex = end\n }\n\n if (lastIndex < text.length) {\n editor.appendChild(document.createTextNode(text.slice(lastIndex)))\n }\n\n isEmpty.value = false\n if (tooltipsActive) {\n mountPillTooltips()\n }\n}\n\n/** Length the given child contributes to the serialized model string. */\nconst modelLengthOf = (node: Node): number => {\n if (node.nodeType === Node.TEXT_NODE) {\n return (node.textContent ?? '').length\n }\n if (node instanceof HTMLElement && node.classList.contains('scalar-pill')) {\n return `{{${node.dataset.variable ?? ''}}}`.length\n }\n // Defensive: a stray element (e.g. browser-inserted <br>) — use its text.\n return (node.textContent ?? '').length\n}\n\n/** Read the editor DOM back into a `{{name}}`-bearing model string. */\nconst serializeEditor = (): string => {\n const editor = editorRef.value\n if (!editor) {\n return ''\n }\n let out = ''\n for (const node of Array.from(editor.childNodes)) {\n if (node.nodeType === Node.TEXT_NODE) {\n out += node.textContent ?? ''\n } else if (\n node instanceof HTMLElement &&\n node.classList.contains('scalar-pill')\n ) {\n out += `{{${node.dataset.variable ?? ''}}}`\n } else if (node instanceof HTMLElement) {\n // Flatten any stray <br> / <div> the browser may inject on paste/Enter.\n out += node.textContent ?? ''\n }\n }\n return out\n}\n\nlet lastPillSignature: string | null = null\nlet lastEnvKey = ''\n\n/**\n * Cache key for the env + `withVariables` state. Includes variable\n * name/value pairs so the watcher notices adds/removes/edits even when\n * `environment.color` is unchanged — without that, pills keep stale\n * `isDefined` opacity and tooltip values until the input itself changes.\n */\nconst computeEnvKey = (): string => {\n const color = environment?.color ?? ''\n const flag = withVariables ? '1' : '0'\n const variables = environment?.variables ?? []\n let vars = ''\n for (const v of variables) {\n const value =\n typeof v.value === 'string' ? v.value : (v.value?.default ?? '')\n // Unit separators (\\x1f / \\x1e) so values can safely contain `|` or `=`.\n vars += `\\x1f${v.name}\\x1e${value}`\n }\n return `${color}|${flag}|${vars}`\n}\n\n/** Idempotent: first call flips `tooltipsActive` and mounts pill tooltips. */\nconst ensureTooltipsActive = (): void => {\n if (tooltipsActive) {\n return\n }\n tooltipsActive = true\n mountPillTooltips()\n}\n\n// ───────────────────────────────────────────────────────────────────\n// Caret ↔ model offset\n// ───────────────────────────────────────────────────────────────────\n\n/** Selection start as a model-string offset, or `null` if not inside the editor. */\nconst getModelCaret = (): number | null => {\n const editor = editorRef.value\n if (!editor) {\n return null\n }\n const selection = window.getSelection()\n if (!selection || selection.rangeCount === 0) {\n return null\n }\n const range = selection.getRangeAt(0)\n if (\n range.startContainer !== editor &&\n !editor.contains(range.startContainer)\n ) {\n return null\n }\n\n // Anchored on the editor itself: `startOffset` is a child index.\n if (range.startContainer === editor) {\n let pos = 0\n for (\n let i = 0;\n i < range.startOffset && i < editor.childNodes.length;\n i++\n ) {\n pos += modelLengthOf(editor.childNodes[i] as Node)\n }\n return pos\n }\n\n let pos = 0\n for (const child of Array.from(editor.childNodes)) {\n if (child === range.startContainer) {\n return pos + range.startOffset\n }\n // Pills are non-editable; if a browser quirk still lands a selection\n // inside one, snap to the nearest boundary instead of getting stuck.\n if (child.contains(range.startContainer)) {\n return range.startOffset === 0 ? pos : pos + modelLengthOf(child)\n }\n pos += modelLengthOf(child)\n }\n return pos\n}\n\n/** Place the caret at the given model offset, walking the DOM to find it. */\nconst setModelCaret = (target: number): void => {\n const editor = editorRef.value\n if (!editor) {\n return\n }\n const range = document.createRange()\n let pos = 0\n let placed = false\n\n for (const child of Array.from(editor.childNodes)) {\n const len = modelLengthOf(child)\n if (pos + len >= target) {\n if (child.nodeType === Node.TEXT_NODE) {\n const into = Math.max(\n 0,\n Math.min(target - pos, (child.textContent ?? '').length),\n )\n range.setStart(child, into)\n } else if (target - pos <= 0) {\n range.setStartBefore(child)\n } else {\n range.setStartAfter(child)\n }\n placed = true\n break\n }\n pos += len\n }\n\n if (!placed) {\n range.selectNodeContents(editor)\n range.collapse(false)\n } else {\n range.collapse(true)\n }\n\n const selection = window.getSelection()\n if (!selection) {\n return\n }\n selection.removeAllRanges()\n selection.addRange(range)\n}\n\n// ───────────────────────────────────────────────────────────────────\n// Environment variable dropdown\n// ───────────────────────────────────────────────────────────────────\n\nconst showDropdown = ref(false)\nconst dropdownQuery = ref('')\nconst dropdownPosition = ref({ left: 0, top: 0 })\n\nconst contextFunctionDropdownItems = computed(() =>\n withFakeData\n ? CONTEXT_FUNCTION_NAMES.map((key) => ({\n key,\n description: getContextFunctionComment(key as ContextFunctionName),\n }))\n : [],\n)\n\nconst displayVariablesDropdown = computed(\n (): boolean =>\n showDropdown.value &&\n withVariables &&\n layout !== 'modal' &&\n (Boolean(environment) || withFakeData),\n)\n\nconst updateDropdownVisibility = (): void => {\n const editor = editorRef.value\n if (!editor) {\n return\n }\n const caret = getModelCaret()\n if (caret === null) {\n showDropdown.value = false\n return\n }\n const text = serializeEditor().slice(0, caret)\n const lastOpen = text.lastIndexOf('{{')\n const lastClose = text.lastIndexOf('}}')\n\n if (lastOpen <= lastClose) {\n showDropdown.value = false\n return\n }\n\n dropdownQuery.value = text.slice(lastOpen + 2)\n // Make sure the combobox has an id before it advertises `aria-expanded`, so\n // `aria-controls` always resolves to the listbox we are about to render.\n ensureComponentId()\n showDropdown.value = true\n\n // Anchor under the caret; `getBoundingClientRect` gives the caret rect in one read.\n nextTick(() => {\n const selection = window.getSelection()\n if (!selection || selection.rangeCount === 0 || !editorRef.value) {\n return\n }\n const r = selection.getRangeAt(0).cloneRange()\n r.collapse(true)\n const rect = r.getBoundingClientRect()\n const editorRect = editorRef.value.getBoundingClientRect()\n // Some browsers collapse empty ranges to a zero rect — fall back to the editor edge.\n dropdownPosition.value = {\n left: rect.left || editorRect.left,\n top: rect.bottom || editorRect.bottom,\n }\n })\n}\n\nconst handleDropdownSelect = (item: string): void => {\n if (readOnly) {\n return\n }\n const caret = getModelCaret() ?? 0\n const value = serializeEditor()\n const from = Math.max(0, caret - dropdownQuery.value.length - 2)\n const to = caret\n const next = `${value.slice(0, from)}{{${item}}}${value.slice(to)}`\n const nextCursor = from + `{{${item}}}`.length\n\n // Pill set changed — force a re-render and reposition the caret.\n lastPillSignature = pillSignature(next, withVariables)\n renderModel(next)\n setModelCaret(nextCursor)\n\n showDropdown.value = false\n emitChange(next, { skipDropdownCheck: true })\n}\n\n// ───────────────────────────────────────────────────────────────────\n// Change / focus / blur\n// ───────────────────────────────────────────────────────────────────\n\nconst emitChange = (\n value: string,\n opts: { skipDropdownCheck?: boolean } = {},\n): void => {\n const same = value === serializeValue(modelValue)\n if (alwaysEmitChange || !same) {\n emit('update:modelValue', value)\n }\n if (!opts.skipDropdownCheck) {\n updateDropdownVisibility()\n }\n}\n\nconst handleInput = (): void => {\n const text = serializeEditor()\n isEmpty.value = isBlankValue(text)\n\n // Only rebuild when the pill set changes (e.g. `}}` closed a pattern, or\n // a value was pasted). Skipping it for plain-text edits preserves the\n // live selection — important for IME composition and double-click select.\n // Also defer while composing; `handleCompositionEnd` re-runs this path so the\n // rebuild happens once the IME has committed its text.\n const sig = pillSignature(text, withVariables)\n if (!isComposing.value && sig !== lastPillSignature) {\n const caret = getModelCaret()\n lastPillSignature = sig\n renderModel(text)\n if (caret !== null) {\n setModelCaret(caret)\n }\n }\n\n emitChange(text)\n}\n\nconst handleCompositionStart = (): void => {\n isComposing.value = true\n}\n\nconst handleCompositionEnd = (): void => {\n isComposing.value = false\n // Run the deferred input path now that the composition has committed, so any\n // pill that formed during composition is rendered.\n handleInput()\n}\n\nconst handleFocus = (): void => {\n isFocused.value = true\n ensureComponentId()\n ensureTooltipsActive()\n}\n\nconst handleBlur = (event: FocusEvent): void => {\n isFocused.value = false\n showDropdown.value = false\n const value = serializeEditor()\n // Check the serialized `value`, not `modelValue` — a `0` or `false` model is\n // a valid non-empty entry that should still submit on blur.\n if (emitOnBlur && value) {\n emit('submit', value, event)\n }\n emit('blur', value, event)\n}\n\n/**\n * Strip rich content on paste; `contenteditable=\"plaintext-only\"` is not\n * reliable cross-browser, so we intercept and use `insertText` to keep undo.\n */\nconst handlePaste = (event: ClipboardEvent): void => {\n event.preventDefault()\n const text = event.clipboardData?.getData('text/plain') ?? ''\n if (!text) {\n return\n }\n document.execCommand('insertText', false, text.replace(/\\r?\\n/g, ' '))\n // `insertText` normally fires an `input` event, but that is not guaranteed\n // across browsers. Run the same path explicitly so pill rendering, emptiness,\n // `update:modelValue`, and the dropdown never lag behind the pasted DOM.\n handleInput()\n}\n\n// ───────────────────────────────────────────────────────────────────\n// Keyboard handling\n// ───────────────────────────────────────────────────────────────────\n\nconst handleKeyDown = (event: KeyboardEvent): void => {\n if (showDropdown.value) {\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault()\n event.stopPropagation()\n dropdownRef.value?.handleArrowKey(\n event.key === 'ArrowDown' ? 'down' : 'up',\n )\n return\n }\n if (event.key === 'Enter') {\n event.preventDefault()\n event.stopPropagation()\n dropdownRef.value?.handleSelect()\n return\n }\n if (event.key === 'Escape') {\n event.preventDefault()\n event.stopPropagation()\n showDropdown.value = false\n return\n }\n }\n\n if (event.key === 'Enter') {\n // Block the browser default so a contenteditable div does not insert\n // <br> / <div> and break single-line semantics, then emit submit\n // (used by the table editors).\n event.preventDefault()\n emit('submit', serializeEditor(), event)\n return\n }\n\n // Backspace / Delete: pill atomicity is handled by the browser via\n // `contenteditable=\"false\"` on pills — no manual `}}`-pair handling needed.\n}\n\n// ───────────────────────────────────────────────────────────────────\n// Click forwarding & lifecycle\n// ───────────────────────────────────────────────────────────────────\n\n/**\n * Clicking a pill selects it whole, so a subsequent Backspace deletes it\n * in one keystroke and typing replaces it — the usual chip/mention model.\n */\nconst handleEditorClick = (event: MouseEvent): void => {\n const target = (event.target as HTMLElement | null)?.closest<HTMLElement>(\n '.scalar-pill',\n )\n if (!target) {\n return\n }\n const editor = editorRef.value\n if (!editor) {\n return\n }\n editor.focus()\n const range = document.createRange()\n range.selectNode(target)\n const selection = window.getSelection()\n selection?.removeAllRanges()\n selection?.addRange(range)\n updateDropdownVisibility()\n}\n\nonMounted(() => {\n const initial = serializeValue(modelValue)\n lastPillSignature = pillSignature(initial, withVariables)\n lastEnvKey = computeEnvKey()\n renderModel(initial)\n isEmpty.value = isBlankValue(initial)\n\n // `autofocus` on a contenteditable div is not honoured natively, so focus\n // the editor ourselves when the consumer passes the attribute.\n if (Object.hasOwn(attrs, 'autofocus')) {\n editorRef.value?.focus()\n }\n})\n\nwatch(\n () => modelValue,\n (next) => {\n const serialized = serializeValue(next)\n // Always sync the placeholder flag, even when the DOM already matches and we\n // skip the rebuild below. Otherwise a value cell that switches from select\n // mode (no editor element) into the empty editor keeps a stale `isEmpty`,\n // and the placeholder silently disappears.\n isEmpty.value = isBlankValue(serialized)\n if (serializeEditor() === serialized) {\n return\n }\n lastPillSignature = pillSignature(serialized, withVariables)\n renderModel(serialized)\n },\n)\n\nwatch(\n [() => environment, () => withVariables],\n () => {\n // Env changes affect pill colour and `isDefined` opacity — rebuild.\n const envKey = computeEnvKey()\n if (envKey === lastEnvKey) {\n return\n }\n lastEnvKey = envKey\n // Most rows are plain text; skip the DOM walk when there are no pills.\n // Pills introduced later flow through `handleInput` / the modelValue\n // watcher, which update `lastPillSignature`.\n if (lastPillSignature === '') {\n return\n }\n lastPillSignature = pillSignature(serializeEditor(), withVariables)\n // Preserve the caret across the rebuild so editing does not jump to the\n // start when the environment changes mid-edit (mirrors `handleInput`).\n const caret = getModelCaret()\n renderModel(serializeEditor())\n if (caret !== null) {\n setModelCaret(caret)\n }\n },\n // Variables are often mutated in place (e.g. editing a value in the env\n // editor) without the object reference changing — deep watch catches it.\n { deep: true },\n)\n\nonBeforeUnmount(() => {\n teardownPillTooltips()\n})\n\n// ───────────────────────────────────────────────────────────────────\n// Public API\n// ───────────────────────────────────────────────────────────────────\n\ndefineExpose({\n /** Focus the editor. `position` controls caret placement. */\n focus: (position?: 'start' | 'end' | number): void => {\n const editor = editorRef.value\n if (!editor) {\n return\n }\n editor.focus()\n if (!isDefined(position)) {\n return\n }\n const length = serializeEditor().length\n const pos =\n position === 'start' ? 0 : position === 'end' ? length : position\n setModelCaret(pos)\n },\n /** Replace the current value programmatically and re-render the pills. */\n setContent: (next = ''): void => {\n if (serializeEditor() === next) {\n return\n }\n lastPillSignature = pillSignature(next, withVariables)\n renderModel(next)\n isEmpty.value = isBlankValue(next)\n },\n /** Read the current value as a `{{name}}`-bearing string. */\n getValue: (): string => serializeEditor(),\n /** Caret offset in the model string. */\n cursorPosition: (): number | undefined => {\n const c = getModelCaret()\n return c === null ? undefined : c\n },\n isFocused,\n editorRef,\n})\n</script>\n\n<template>\n <!-- Disabled mode: read-only label -->\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-lite-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 -->\n <div\n v-else\n :id=\"componentId\"\n v-bind=\"$attrs\"\n class=\"code-input-lite group/code-input-lite peer relative w-full leading-[1.44] -outline-offset-1 has-[:focus-visible]:rounded-[4px] has-[:focus-visible]:outline\"\n :class=\"{\n 'code-input-lite--error': error,\n 'code-input-lite--empty': isEmpty,\n 'line-through': linethrough,\n }\">\n <!-- The single editable surface; see the file header for how pills work. -->\n <div\n ref=\"editorRef\"\n :aria-activedescendant=\"\n displayVariablesDropdown ? activeOptionId : undefined\n \"\n :aria-autocomplete=\"withVariables ? 'list' : undefined\"\n :aria-controls=\"displayVariablesDropdown ? listboxId : undefined\"\n :aria-expanded=\"displayVariablesDropdown ? 'true' : undefined\"\n :aria-invalid=\"error ? 'true' : undefined\"\n :aria-label=\"attrs['aria-label']\"\n :aria-readonly=\"readOnly ? 'true' : undefined\"\n :aria-required=\"required ? 'true' : undefined\"\n class=\"code-input-lite__editor\"\n :contenteditable=\"readOnly ? 'false' : 'true'\"\n :data-placeholder=\"placeholder\"\n :role=\"withVariables ? 'combobox' : 'textbox'\"\n spellcheck=\"false\"\n @blur=\"handleBlur\"\n @click=\"handleEditorClick\"\n @compositionend=\"handleCompositionEnd\"\n @compositionstart=\"handleCompositionStart\"\n @focus=\"handleFocus\"\n @input=\"handleInput\"\n @keydown=\"handleKeyDown\"\n @paste=\"handlePaste\"\n @pointerover=\"ensureTooltipsActive\" />\n </div>\n\n <!--\n Slots and the required indicator are siblings of the mode templates so\n they render in every mode and so `absolute right-0` anchors to the\n surrounding (relative) cell rather than the shrink-wrapped mode wrapper.\n -->\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 <div\n v-if=\"$slots.icon\"\n class=\"centered-y absolute right-0 flex h-full items-center p-1.5 group-has-[.code-input-lite__editor:focus]:z-1\">\n <slot name=\"icon\" />\n </div>\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 peer-has-[.code-input-lite__editor:focus]:opacity-0\">\n Required\n </div>\n\n <EnvironmentVariableDropdown\n v-if=\"displayVariablesDropdown\"\n ref=\"dropdownRef\"\n :contextFunctionItems=\"contextFunctionDropdownItems\"\n :dropdownPosition=\"dropdownPosition\"\n :environment=\"environment\"\n :listboxId=\"listboxId\"\n :query=\"dropdownQuery\"\n @close=\"showDropdown = false\"\n @redirect=\"emit('navigate', { page: 'document', path: 'environment' })\"\n @select=\"handleDropdownSelect\" />\n</template>\n\n<style scoped>\n.code-input-lite {\n /* Flex so the editor centres vertically in whatever height the cell gives us.\n Font properties inherit so we adopt the surrounding typography. */\n display: flex;\n align-items: center;\n}\n\n.code-input-lite__editor {\n /* Everything font-related inherits from the surrounding context. */\n font: inherit;\n letter-spacing: inherit;\n flex: 1;\n min-width: 0;\n background: transparent;\n outline: none;\n color: var(--scalar-color-1);\n caret-color: var(--scalar-color-1);\n /* Single-line: horizontal scroll keeps the caret visible for long values;\n the scrollbar itself is hidden (would be noisy inside a table cell). */\n white-space: pre;\n overflow-x: auto;\n overflow-y: hidden;\n scrollbar-width: none;\n padding: 0 0.5em;\n box-sizing: border-box;\n line-height: 1.44;\n /* Positioning context for the absolutely positioned placeholder. */\n position: relative;\n}\n\n.code-input-lite__editor::-webkit-scrollbar {\n display: none;\n}\n\n/* Absolute so the placeholder does not occupy flow space inside the\n contenteditable; otherwise the caret would land after it on focus.\n `pointer-events: none` lets clicks fall through to focus the editor.\n Hidden on focus so it never renders on top of the text caret. */\n.code-input-lite--empty .code-input-lite__editor:not(:focus)::before {\n content: attr(data-placeholder);\n color: var(--scalar-color-3);\n pointer-events: none;\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0.5em;\n display: flex;\n align-items: center;\n}\n\n.code-input-lite--error .code-input-lite__editor {\n outline: 1px solid var(--scalar-color-red);\n}\n</style>\n\n<style>\n/* Pill styling. Each pill is `<span contenteditable=\"false\">name</span>` —\n an atomic widget; the caret lands before or after it, never inside. */\n.scalar-pill {\n color: var(--scalar-color-2);\n border-radius: var(--scalar-radius-full);\n display: inline-block;\n font-family: var(--scalar-font-code);\n font-size: 0.9em;\n line-height: 1.4;\n vertical-align: baseline;\n background: var(--scalar-background-3);\n padding: 0.125em 0.6em;\n margin-right: 0.35em;\n cursor: text;\n /* Single click selects the whole pill — chip/mention model, deletes in one go. */\n user-select: all;\n -webkit-user-select: all;\n}\n\n.dark-mode .scalar-pill {\n background: color-mix(\n in srgb,\n var(--tw-bg-base, var(--scalar-color-1)),\n transparent 90%\n );\n}\n\n.light-mode .scalar-pill {\n background: var(--scalar-background-3);\n}\n\n.scalar-pill--context-fn {\n /* Inset box-shadow as a border so the layout box stays identical to plain pills. */\n box-shadow: 0 0 0 1px\n color-mix(in srgb, var(--scalar-color-3), transparent 35%) inset;\n}\n\n.dark-mode .scalar-pill--context-fn {\n background: color-mix(in srgb, var(--scalar-background-3), transparent 55%);\n}\n\n.light-mode .scalar-pill--context-fn {\n background: color-mix(in srgb, var(--scalar-background-3), transparent 40%);\n}\n</style>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CodeInputLite.vue.script.js","names":["$attrs","$slots"],"sources":["../../../../src/v2/components/code-input/CodeInputLite.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * CodeInputLite\n *\n * Single-line `contenteditable` editor that renders `{{varname}}` as atomic\n * pill spans (`contenteditable=\"false\"`) and offers an env-variable\n * autocomplete on `{{`. The value is still exposed as a `{{name}}`-bearing\n * string via `update:modelValue`; DOM ↔ model conversion lives in\n * `renderModel` and `serializeEditor`.\n */\nexport default {\n inheritAttrs: false,\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { isDefined } from '@scalar/helpers/array/is-defined'\nimport { REGEX } from '@scalar/helpers/regex/regex-helpers'\nimport {\n CONTEXT_FUNCTION_NAMES,\n getContextFunctionComment,\n isContextFunctionName,\n type ContextFunctionName,\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 {\n computed,\n createApp,\n nextTick,\n onBeforeUnmount,\n onMounted,\n ref,\n useAttrs,\n useTemplateRef,\n watch,\n type App,\n} 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 type { CodeInputModelValue } from './CodeInput.vue'\nimport { buildPillContext } from './helpers/build-pill-context'\nimport { lookupVariableValue } from './helpers/lookup-variable-value'\nimport { pillSignature } from './helpers/pill-signature'\nimport { serializeValue } from './helpers/serialize-value'\nimport PillTooltipHost from './PillTooltipHost.vue'\n\ntype Props = {\n modelValue: CodeInputModelValue\n /** Environment for variable substitution. Pass undefined to disable env vars */\n environment: XScalarEnvironment | undefined\n /** Render as a non-interactive read-only label */\n disabled?: boolean\n /** Render the input with the native `readonly` attribute (still focusable, no edits) */\n readOnly?: boolean\n /** Show error styling */\n error?: boolean\n /** Layout context affects styling and dropdown visibility */\n layout?: ClientLayout\n /** Placeholder text for an empty input */\n placeholder?: string\n /** Show required indicator */\n required?: boolean\n /** Emit submit on blur */\n emitOnBlur?: boolean\n /** Render variable pills + show the autocomplete dropdown */\n withVariables?: boolean\n /** Include `{{$guid}}` etc. in the autocomplete dropdown */\n withFakeData?: boolean\n /** Always emit change events even if the value is unchanged */\n alwaysEmitChange?: boolean\n /** Strike-through styling for the input text (e.g. overridden values) */\n linethrough?: boolean\n /** Schema type — drives boolean select mode when `boolean` is included */\n type?: string | string[]\n /** Predefined enum values; when set the input is replaced by a select */\n enum?: string[]\n /** Example values; when set (and no enum/boolean) the input is replaced by a select */\n examples?: string[]\n /** Default value to suggest in select modes */\n default?: CodeInputModelValue\n /** Whether the boolean select includes a `null` option */\n nullable?: boolean\n}\n\nconst {\n modelValue,\n environment,\n disabled = false,\n readOnly = false,\n error = false,\n layout = 'desktop',\n placeholder,\n required = false,\n emitOnBlur = true,\n alwaysEmitChange = false,\n withVariables = true,\n withFakeData = false,\n linethrough = false,\n type,\n enum: enumProp,\n examples,\n default: defaultProp,\n nullable = false,\n} = defineProps<Props>()\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string]\n 'submit': [value: string, event: KeyboardEvent | FocusEvent]\n 'blur': [value: string, event: FocusEvent]\n 'navigate': [route: { page: 'document'; path: 'environment' }]\n}>()\n\nconst attrs = useAttrs() as { 'id'?: string; 'aria-label'?: string }\n\n/**\n * The id only matters once the dropdown opens (`aria-controls` /\n * `aria-activedescendant`), so we defer `nanoid()` until first focus to\n * keep idle instances cheap. A consumer-supplied `id` attr is preserved.\n */\nconst generatedComponentId = ref<string | null>(null)\nconst componentId = computed(\n (): string | undefined => attrs.id ?? generatedComponentId.value ?? undefined,\n)\nconst ensureComponentId = (): void => {\n if (!attrs.id && generatedComponentId.value === null) {\n generatedComponentId.value = `id-${nanoid()}`\n }\n}\n\nconst editorRef = useTemplateRef<HTMLDivElement>('editorRef')\nconst dropdownRef = ref<InstanceType<\n typeof EnvironmentVariableDropdown\n> | null>(null)\n\n/** Id of the dropdown's `role=\"listbox\"` element, for the combobox wiring. */\nconst listboxId = computed((): string | undefined =>\n componentId.value ? `${componentId.value}-listbox` : undefined,\n)\n\n/**\n * Id of the option the dropdown currently highlights. Mirrors the dropdown's\n * own selection so the editor can expose it via `aria-activedescendant`.\n */\nconst activeOptionId = computed(\n (): string | undefined => dropdownRef.value?.activeOptionId,\n)\n\nconst isFocused = ref(false)\nconst isEmpty = ref(true)\n\n/**\n * True while an IME composition is in progress. Rebuilding the editor DOM\n * mid-composition (e.g. when `{{` forms a pill) cancels the composition, so we\n * defer those rebuilds until `compositionend`.\n */\nconst isComposing = ref(false)\n\n/**\n * Whether the serialized value should count as empty for placeholder display.\n *\n * `contenteditable` can leave behind invisible residue after some delete\n * sequences — most commonly a non-breaking space (` `) — which makes a\n * visually empty field report a non-zero length and silently drop its\n * placeholder. Trimming covers that case; ` ` counts as whitespace, so a\n * field that only holds editor residue is treated as empty. This affects the\n * placeholder flag only, never the value emitted via `serializeEditor`.\n */\nconst isBlankValue = (text: string): boolean => text.trim().length === 0\n\n// ───────────────────────────────────────────────────────────────────\n// Rendering-mode detection (parity with CodeInput's select dispatch)\n// ───────────────────────────────────────────────────────────────────\n\n/** True when the schema type is exactly `boolean` (or includes it in a tuple type). */\nconst isBooleanMode = computed((): boolean => {\n if (enumProp?.length) {\n return false\n }\n return type === 'boolean' || (Array.isArray(type) && type.includes('boolean'))\n})\n\nconst booleanOptions = computed((): string[] =>\n nullable ? ['true', 'false', 'null'] : ['true', 'false'],\n)\n\n/** Default type when the schema is a tuple — picks the first non-null entry. */\nconst defaultType = computed((): string | undefined => {\n if (Array.isArray(type)) {\n return type.find((t) => t !== 'null') ?? 'string'\n }\n return type\n})\n\nconst handleSelectChange = (value: string): void =>\n emit('update:modelValue', value)\n\n// ───────────────────────────────────────────────────────────────────\n// Per-pill tooltip apps\n// ───────────────────────────────────────────────────────────────────\n\nlet pillTooltipApps: App[] = []\n\n/**\n * Per-pill tooltips are the heaviest part of the render (a Vue app +\n * `useTooltip` watch + listeners each), so we defer mounting them until\n * the first interaction (focus, pointerover, or dropdown open). Once on,\n * subsequent rebuilds remount tooltips for the new pills.\n */\nlet tooltipsActive = false\n\nconst teardownPillTooltips = (): void => {\n for (const app of pillTooltipApps) {\n app.unmount()\n }\n pillTooltipApps = []\n}\n\nconst mountPillTooltips = (): void => {\n if (!editorRef.value || layout === 'modal') {\n return\n }\n const pills = editorRef.value.querySelectorAll<HTMLElement>('.scalar-pill')\n for (const pillEl of pills) {\n const variableName = pillEl.dataset.variable ?? ''\n const context = buildPillContext(variableName, environment)\n const app = createApp(PillTooltipHost, { context, target: pillEl })\n // PillTooltipHost is renderless; useTooltip attaches to `target` directly.\n app.mount(document.createElement('div'))\n pillTooltipApps.push(app)\n }\n}\n\n// ───────────────────────────────────────────────────────────────────\n// DOM ↔ model conversion\n// ───────────────────────────────────────────────────────────────────\n\n/**\n * Build a pill `<span>` for the given variable. `contentEditable = 'false'`\n * makes the browser treat it as a single atom (arrow keys jump over it,\n * Backspace deletes it whole); `{{` / `}}` only live in the model string.\n */\nconst createPillElement = (\n name: string,\n start: number,\n end: number,\n): HTMLSpanElement => {\n const isCtx = isContextFunctionName(name)\n const span = document.createElement('span')\n span.className = isCtx ? 'scalar-pill scalar-pill--context-fn' : 'scalar-pill'\n span.contentEditable = 'false'\n span.dataset.variable = name\n // Model-coordinate offsets (the pill stands in for the full `{{name}}`).\n // Used by click forwarding and tests to map a pill back to the value.\n span.dataset.pillStart = String(start)\n span.dataset.pillEnd = String(end)\n\n const color = isCtx\n ? 'var(--scalar-color-3)'\n : environment?.color || 'var(--scalar-color-1)'\n span.style.setProperty('--tw-bg-base', color)\n\n // Fade env pills with no usable value. A falsy check (not just\n // `=== undefined`) matches the tooltip path's `Boolean(value)`, so a\n // variable declared with an empty string fades here too.\n const isUndefinedEnv = !isCtx && !lookupVariableValue(environment, name)\n if (isUndefinedEnv) {\n span.style.opacity = '0.5'\n }\n\n span.textContent = name\n return span\n}\n\n/** Render a model string into the editor as a mix of text nodes + pills. */\nconst renderModel = (text: string): void => {\n const editor = editorRef.value\n if (!editor) {\n return\n }\n\n teardownPillTooltips()\n editor.replaceChildren()\n\n if (!withVariables || !text.includes('{{')) {\n if (text) {\n editor.appendChild(document.createTextNode(text))\n }\n isEmpty.value = isBlankValue(text)\n return\n }\n\n const regex = new RegExp(REGEX.VARIABLES.source, REGEX.VARIABLES.flags)\n let lastIndex = 0\n let match: RegExpExecArray | null\n\n while ((match = regex.exec(text)) !== null) {\n const start = match.index\n const end = start + match[0].length\n if (start > lastIndex) {\n editor.appendChild(document.createTextNode(text.slice(lastIndex, start)))\n }\n editor.appendChild(createPillElement(match[1] ?? '', start, end))\n lastIndex = end\n }\n\n if (lastIndex < text.length) {\n editor.appendChild(document.createTextNode(text.slice(lastIndex)))\n }\n\n isEmpty.value = false\n if (tooltipsActive) {\n mountPillTooltips()\n }\n}\n\n/** Length the given child contributes to the serialized model string. */\nconst modelLengthOf = (node: Node): number => {\n if (node.nodeType === Node.TEXT_NODE) {\n return (node.textContent ?? '').length\n }\n if (node instanceof HTMLElement && node.classList.contains('scalar-pill')) {\n return `{{${node.dataset.variable ?? ''}}}`.length\n }\n // Defensive: a stray element (e.g. browser-inserted <br>) — use its text.\n return (node.textContent ?? '').length\n}\n\n/** Read the editor DOM back into a `{{name}}`-bearing model string. */\nconst serializeEditor = (): string => {\n const editor = editorRef.value\n if (!editor) {\n return ''\n }\n let out = ''\n for (const node of Array.from(editor.childNodes)) {\n if (node.nodeType === Node.TEXT_NODE) {\n out += node.textContent ?? ''\n } else if (\n node instanceof HTMLElement &&\n node.classList.contains('scalar-pill')\n ) {\n out += `{{${node.dataset.variable ?? ''}}}`\n } else if (node instanceof HTMLElement) {\n // Flatten any stray <br> / <div> the browser may inject on paste/Enter.\n out += node.textContent ?? ''\n }\n }\n return out\n}\n\nlet lastPillSignature: string | null = null\nlet lastEnvKey = ''\n\n/**\n * Cache key for the env + `withVariables` state. Includes variable\n * name/value pairs so the watcher notices adds/removes/edits even when\n * `environment.color` is unchanged — without that, pills keep stale\n * `isDefined` opacity and tooltip values until the input itself changes.\n */\nconst computeEnvKey = (): string => {\n const color = environment?.color ?? ''\n const flag = withVariables ? '1' : '0'\n const variables = environment?.variables ?? []\n let vars = ''\n for (const v of variables) {\n const value =\n typeof v.value === 'string' ? v.value : (v.value?.default ?? '')\n // Unit separators (\\x1f / \\x1e) so values can safely contain `|` or `=`.\n vars += `\\x1f${v.name}\\x1e${value}`\n }\n return `${color}|${flag}|${vars}`\n}\n\n/** Idempotent: first call flips `tooltipsActive` and mounts pill tooltips. */\nconst ensureTooltipsActive = (): void => {\n if (tooltipsActive) {\n return\n }\n tooltipsActive = true\n mountPillTooltips()\n}\n\n// ───────────────────────────────────────────────────────────────────\n// Caret ↔ model offset\n// ───────────────────────────────────────────────────────────────────\n\n/** Selection start as a model-string offset, or `null` if not inside the editor. */\nconst getModelCaret = (): number | null => {\n const editor = editorRef.value\n if (!editor) {\n return null\n }\n const selection = window.getSelection()\n if (!selection || selection.rangeCount === 0) {\n return null\n }\n const range = selection.getRangeAt(0)\n if (\n range.startContainer !== editor &&\n !editor.contains(range.startContainer)\n ) {\n return null\n }\n\n // Anchored on the editor itself: `startOffset` is a child index.\n if (range.startContainer === editor) {\n let pos = 0\n for (\n let i = 0;\n i < range.startOffset && i < editor.childNodes.length;\n i++\n ) {\n pos += modelLengthOf(editor.childNodes[i] as Node)\n }\n return pos\n }\n\n let pos = 0\n for (const child of Array.from(editor.childNodes)) {\n if (child === range.startContainer) {\n return pos + range.startOffset\n }\n // Pills are non-editable; if a browser quirk still lands a selection\n // inside one, snap to the nearest boundary instead of getting stuck.\n if (child.contains(range.startContainer)) {\n return range.startOffset === 0 ? pos : pos + modelLengthOf(child)\n }\n pos += modelLengthOf(child)\n }\n return pos\n}\n\n/** Place the caret at the given model offset, walking the DOM to find it. */\nconst setModelCaret = (target: number): void => {\n const editor = editorRef.value\n if (!editor) {\n return\n }\n const range = document.createRange()\n let pos = 0\n let placed = false\n\n for (const child of Array.from(editor.childNodes)) {\n const len = modelLengthOf(child)\n if (pos + len >= target) {\n if (child.nodeType === Node.TEXT_NODE) {\n const into = Math.max(\n 0,\n Math.min(target - pos, (child.textContent ?? '').length),\n )\n range.setStart(child, into)\n } else if (target - pos <= 0) {\n range.setStartBefore(child)\n } else {\n range.setStartAfter(child)\n }\n placed = true\n break\n }\n pos += len\n }\n\n if (!placed) {\n range.selectNodeContents(editor)\n range.collapse(false)\n } else {\n range.collapse(true)\n }\n\n const selection = window.getSelection()\n if (!selection) {\n return\n }\n selection.removeAllRanges()\n selection.addRange(range)\n}\n\n// ───────────────────────────────────────────────────────────────────\n// Environment variable dropdown\n// ───────────────────────────────────────────────────────────────────\n\nconst showDropdown = ref(false)\nconst dropdownQuery = ref('')\nconst dropdownPosition = ref({ left: 0, top: 0 })\n\nconst contextFunctionDropdownItems = computed(() =>\n withFakeData\n ? CONTEXT_FUNCTION_NAMES.map((key) => ({\n key,\n description: getContextFunctionComment(key as ContextFunctionName),\n }))\n : [],\n)\n\nconst displayVariablesDropdown = computed(\n (): boolean =>\n showDropdown.value &&\n withVariables &&\n layout !== 'modal' &&\n (Boolean(environment) || withFakeData),\n)\n\nconst updateDropdownVisibility = (): void => {\n const editor = editorRef.value\n if (!editor) {\n return\n }\n const caret = getModelCaret()\n if (caret === null) {\n showDropdown.value = false\n return\n }\n const text = serializeEditor().slice(0, caret)\n const lastOpen = text.lastIndexOf('{{')\n const lastClose = text.lastIndexOf('}}')\n\n if (lastOpen <= lastClose) {\n showDropdown.value = false\n return\n }\n\n dropdownQuery.value = text.slice(lastOpen + 2)\n // Make sure the combobox has an id before it advertises `aria-expanded`, so\n // `aria-controls` always resolves to the listbox we are about to render.\n ensureComponentId()\n showDropdown.value = true\n\n // Anchor under the caret; `getBoundingClientRect` gives the caret rect in one read.\n nextTick(() => {\n const selection = window.getSelection()\n if (!selection || selection.rangeCount === 0 || !editorRef.value) {\n return\n }\n const r = selection.getRangeAt(0).cloneRange()\n r.collapse(true)\n const rect = r.getBoundingClientRect()\n const editorRect = editorRef.value.getBoundingClientRect()\n // Some browsers collapse empty ranges to a zero rect — fall back to the editor edge.\n dropdownPosition.value = {\n left: rect.left || editorRect.left,\n top: rect.bottom || editorRect.bottom,\n }\n })\n}\n\nconst handleDropdownSelect = (item: string): void => {\n if (readOnly) {\n return\n }\n const caret = getModelCaret() ?? 0\n const value = serializeEditor()\n const from = Math.max(0, caret - dropdownQuery.value.length - 2)\n const to = caret\n const next = `${value.slice(0, from)}{{${item}}}${value.slice(to)}`\n const nextCursor = from + `{{${item}}}`.length\n\n // Pill set changed — force a re-render and reposition the caret.\n lastPillSignature = pillSignature(next, withVariables)\n renderModel(next)\n setModelCaret(nextCursor)\n\n showDropdown.value = false\n emitChange(next, { skipDropdownCheck: true })\n}\n\n// ───────────────────────────────────────────────────────────────────\n// Change / focus / blur\n// ───────────────────────────────────────────────────────────────────\n\nconst emitChange = (\n value: string,\n opts: { skipDropdownCheck?: boolean } = {},\n): void => {\n const same = value === serializeValue(modelValue)\n if (alwaysEmitChange || !same) {\n emit('update:modelValue', value)\n }\n if (!opts.skipDropdownCheck) {\n updateDropdownVisibility()\n }\n}\n\nconst handleInput = (): void => {\n const text = serializeEditor()\n isEmpty.value = isBlankValue(text)\n\n // Only rebuild when the pill set changes (e.g. `}}` closed a pattern, or\n // a value was pasted). Skipping it for plain-text edits preserves the\n // live selection — important for IME composition and double-click select.\n // Also defer while composing; `handleCompositionEnd` re-runs this path so the\n // rebuild happens once the IME has committed its text.\n const sig = pillSignature(text, withVariables)\n if (!isComposing.value && sig !== lastPillSignature) {\n const caret = getModelCaret()\n lastPillSignature = sig\n renderModel(text)\n if (caret !== null) {\n setModelCaret(caret)\n }\n }\n\n emitChange(text)\n}\n\nconst handleCompositionStart = (): void => {\n isComposing.value = true\n}\n\nconst handleCompositionEnd = (): void => {\n isComposing.value = false\n // Run the deferred input path now that the composition has committed, so any\n // pill that formed during composition is rendered.\n handleInput()\n}\n\nconst handleFocus = (): void => {\n isFocused.value = true\n ensureComponentId()\n ensureTooltipsActive()\n}\n\nconst handleBlur = (event: FocusEvent): void => {\n isFocused.value = false\n showDropdown.value = false\n const value = serializeEditor()\n // Check the serialized `value`, not `modelValue` — a `0` or `false` model is\n // a valid non-empty entry that should still submit on blur.\n if (emitOnBlur && value) {\n emit('submit', value, event)\n }\n emit('blur', value, event)\n}\n\n/**\n * Strip rich content on paste; `contenteditable=\"plaintext-only\"` is not\n * reliable cross-browser, so we intercept and use `insertText` to keep undo.\n */\nconst handlePaste = (event: ClipboardEvent): void => {\n event.preventDefault()\n const text = event.clipboardData?.getData('text/plain') ?? ''\n if (!text) {\n return\n }\n document.execCommand('insertText', false, text.replace(/\\r?\\n/g, ' '))\n // `insertText` normally fires an `input` event, but that is not guaranteed\n // across browsers. Run the same path explicitly so pill rendering, emptiness,\n // `update:modelValue`, and the dropdown never lag behind the pasted DOM.\n handleInput()\n}\n\n// ───────────────────────────────────────────────────────────────────\n// Keyboard handling\n// ───────────────────────────────────────────────────────────────────\n\nconst handleKeyDown = (event: KeyboardEvent): void => {\n if (showDropdown.value) {\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault()\n event.stopPropagation()\n dropdownRef.value?.handleArrowKey(\n event.key === 'ArrowDown' ? 'down' : 'up',\n )\n return\n }\n if (event.key === 'Enter') {\n event.preventDefault()\n event.stopPropagation()\n dropdownRef.value?.handleSelect()\n return\n }\n if (event.key === 'Escape') {\n event.preventDefault()\n event.stopPropagation()\n showDropdown.value = false\n return\n }\n }\n\n if (event.key === 'Enter') {\n // Block the browser default so a contenteditable div does not insert\n // <br> / <div> and break single-line semantics, then emit submit\n // (used by the table editors).\n event.preventDefault()\n emit('submit', serializeEditor(), event)\n return\n }\n\n // Backspace / Delete: pill atomicity is handled by the browser via\n // `contenteditable=\"false\"` on pills — no manual `}}`-pair handling needed.\n}\n\n// ───────────────────────────────────────────────────────────────────\n// Click forwarding & lifecycle\n// ───────────────────────────────────────────────────────────────────\n\n/**\n * Clicking a pill selects it whole, so a subsequent Backspace deletes it\n * in one keystroke and typing replaces it — the usual chip/mention model.\n */\nconst handleEditorClick = (event: MouseEvent): void => {\n const target = (event.target as HTMLElement | null)?.closest<HTMLElement>(\n '.scalar-pill',\n )\n if (!target) {\n return\n }\n const editor = editorRef.value\n if (!editor) {\n return\n }\n editor.focus()\n const range = document.createRange()\n range.selectNode(target)\n const selection = window.getSelection()\n selection?.removeAllRanges()\n selection?.addRange(range)\n updateDropdownVisibility()\n}\n\nonMounted(() => {\n const initial = serializeValue(modelValue)\n lastPillSignature = pillSignature(initial, withVariables)\n lastEnvKey = computeEnvKey()\n renderModel(initial)\n isEmpty.value = isBlankValue(initial)\n\n // `autofocus` on a contenteditable div is not honoured natively, so focus\n // the editor ourselves when the consumer passes the attribute.\n if (Object.hasOwn(attrs, 'autofocus')) {\n editorRef.value?.focus()\n }\n})\n\nwatch(\n () => modelValue,\n (next) => {\n const serialized = serializeValue(next)\n // Always sync the placeholder flag, even when the DOM already matches and we\n // skip the rebuild below. Otherwise a value cell that switches from select\n // mode (no editor element) into the empty editor keeps a stale `isEmpty`,\n // and the placeholder silently disappears.\n isEmpty.value = isBlankValue(serialized)\n if (serializeEditor() === serialized) {\n return\n }\n lastPillSignature = pillSignature(serialized, withVariables)\n renderModel(serialized)\n },\n)\n\n// The editable surface only exists in \"editor mode\" (see template). When a row switches into editor\n// mode after mount — most notably when this component instance is reused for a different table row —\n// `onMounted` has already run and the `modelValue` watch fired while `editorRef` was still null, so\n// the model was never painted into the freshly created element and the cell renders empty.\n//\n// Paint the model when the element appears, but only into a still-empty editor: an editor that\n// already holds text is either up to date or ahead of `modelValue` with an uncommitted edit/paste,\n// and must not be clobbered.\n//\n// `flush: 'sync'` makes the paint part of the same step that creates the element. Vue assigns a\n// non-null template ref from a post-render effect, so the element is already mounted and patched\n// when this runs — deferring any further (the `pre` default, or `post`) only pushes the paint past\n// the consumer effects that run later in the same flush. A parent that focuses the cell as it\n// switches into editor mode would then place the caret in a still-empty editor, and the paint's\n// `replaceChildren` would drop that selection.\nwatch(\n editorRef,\n (editor) => {\n if (!editor || !isBlankValue(serializeEditor())) {\n return\n }\n const serialized = serializeValue(modelValue)\n if (serialized === '') {\n return\n }\n lastPillSignature = pillSignature(serialized, withVariables)\n renderModel(serialized)\n },\n { flush: 'sync' },\n)\n\nwatch(\n [() => environment, () => withVariables],\n () => {\n // Env changes affect pill colour and `isDefined` opacity — rebuild.\n const envKey = computeEnvKey()\n if (envKey === lastEnvKey) {\n return\n }\n lastEnvKey = envKey\n // Most rows are plain text; skip the DOM walk when there are no pills.\n // Pills introduced later flow through `handleInput` / the modelValue\n // watcher, which update `lastPillSignature`.\n if (lastPillSignature === '') {\n return\n }\n lastPillSignature = pillSignature(serializeEditor(), withVariables)\n // Preserve the caret across the rebuild so editing does not jump to the\n // start when the environment changes mid-edit (mirrors `handleInput`).\n const caret = getModelCaret()\n renderModel(serializeEditor())\n if (caret !== null) {\n setModelCaret(caret)\n }\n },\n // Variables are often mutated in place (e.g. editing a value in the env\n // editor) without the object reference changing — deep watch catches it.\n { deep: true },\n)\n\nonBeforeUnmount(() => {\n teardownPillTooltips()\n})\n\n// ───────────────────────────────────────────────────────────────────\n// Public API\n// ───────────────────────────────────────────────────────────────────\n\ndefineExpose({\n /** Focus the editor. `position` controls caret placement. */\n focus: (position?: 'start' | 'end' | number): void => {\n const editor = editorRef.value\n if (!editor) {\n return\n }\n editor.focus()\n if (!isDefined(position)) {\n return\n }\n const length = serializeEditor().length\n const pos =\n position === 'start' ? 0 : position === 'end' ? length : position\n setModelCaret(pos)\n },\n /** Replace the current value programmatically and re-render the pills. */\n setContent: (next = ''): void => {\n if (serializeEditor() === next) {\n return\n }\n lastPillSignature = pillSignature(next, withVariables)\n renderModel(next)\n isEmpty.value = isBlankValue(next)\n },\n /** Read the current value as a `{{name}}`-bearing string. */\n getValue: (): string => serializeEditor(),\n /** Caret offset in the model string. */\n cursorPosition: (): number | undefined => {\n const c = getModelCaret()\n return c === null ? undefined : c\n },\n isFocused,\n editorRef,\n})\n</script>\n\n<template>\n <!-- Disabled mode: read-only label -->\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-lite-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 -->\n <div\n v-else\n :id=\"componentId\"\n v-bind=\"$attrs\"\n class=\"code-input-lite group/code-input-lite peer relative w-full leading-[1.44] -outline-offset-1 has-[:focus-visible]:rounded-[4px] has-[:focus-visible]:outline\"\n :class=\"{\n 'code-input-lite--error': error,\n 'code-input-lite--empty': isEmpty,\n 'line-through': linethrough,\n }\">\n <!-- The single editable surface; see the file header for how pills work. -->\n <div\n ref=\"editorRef\"\n :aria-activedescendant=\"\n displayVariablesDropdown ? activeOptionId : undefined\n \"\n :aria-autocomplete=\"withVariables ? 'list' : undefined\"\n :aria-controls=\"displayVariablesDropdown ? listboxId : undefined\"\n :aria-expanded=\"displayVariablesDropdown ? 'true' : undefined\"\n :aria-invalid=\"error ? 'true' : undefined\"\n :aria-label=\"attrs['aria-label']\"\n :aria-readonly=\"readOnly ? 'true' : undefined\"\n :aria-required=\"required ? 'true' : undefined\"\n class=\"code-input-lite__editor\"\n :contenteditable=\"readOnly ? 'false' : 'true'\"\n :data-placeholder=\"placeholder\"\n :role=\"withVariables ? 'combobox' : 'textbox'\"\n spellcheck=\"false\"\n @blur=\"handleBlur\"\n @click=\"handleEditorClick\"\n @compositionend=\"handleCompositionEnd\"\n @compositionstart=\"handleCompositionStart\"\n @focus=\"handleFocus\"\n @input=\"handleInput\"\n @keydown=\"handleKeyDown\"\n @paste=\"handlePaste\"\n @pointerover=\"ensureTooltipsActive\" />\n </div>\n\n <!--\n Slots and the required indicator are siblings of the mode templates so\n they render in every mode and so `absolute right-0` anchors to the\n surrounding (relative) cell rather than the shrink-wrapped mode wrapper.\n -->\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 <div\n v-if=\"$slots.icon\"\n class=\"centered-y absolute right-0 flex h-full items-center p-1.5 group-has-[.code-input-lite__editor:focus]:z-1\">\n <slot name=\"icon\" />\n </div>\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 peer-has-[.code-input-lite__editor:focus]:opacity-0\">\n Required\n </div>\n\n <EnvironmentVariableDropdown\n v-if=\"displayVariablesDropdown\"\n ref=\"dropdownRef\"\n :contextFunctionItems=\"contextFunctionDropdownItems\"\n :dropdownPosition=\"dropdownPosition\"\n :environment=\"environment\"\n :listboxId=\"listboxId\"\n :query=\"dropdownQuery\"\n @close=\"showDropdown = false\"\n @redirect=\"emit('navigate', { page: 'document', path: 'environment' })\"\n @select=\"handleDropdownSelect\" />\n</template>\n\n<style scoped>\n.code-input-lite {\n /* Flex so the editor centres vertically in whatever height the cell gives us.\n Font properties inherit so we adopt the surrounding typography. */\n display: flex;\n align-items: center;\n}\n\n.code-input-lite__editor {\n /* Everything font-related inherits from the surrounding context. */\n font: inherit;\n letter-spacing: inherit;\n flex: 1;\n min-width: 0;\n background: transparent;\n outline: none;\n color: var(--scalar-color-1);\n caret-color: var(--scalar-color-1);\n /* Single-line: horizontal scroll keeps the caret visible for long values;\n the scrollbar itself is hidden (would be noisy inside a table cell). */\n white-space: pre;\n overflow-x: auto;\n overflow-y: hidden;\n scrollbar-width: none;\n padding: 0 0.5em;\n box-sizing: border-box;\n line-height: 1.44;\n /* Positioning context for the absolutely positioned placeholder. */\n position: relative;\n}\n\n.code-input-lite__editor::-webkit-scrollbar {\n display: none;\n}\n\n/* Absolute so the placeholder does not occupy flow space inside the\n contenteditable; otherwise the caret would land after it on focus.\n `pointer-events: none` lets clicks fall through to focus the editor.\n Hidden on focus so it never renders on top of the text caret. */\n.code-input-lite--empty .code-input-lite__editor:not(:focus)::before {\n content: attr(data-placeholder);\n color: var(--scalar-color-3);\n pointer-events: none;\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0.5em;\n display: flex;\n align-items: center;\n}\n\n.code-input-lite--error .code-input-lite__editor {\n outline: 1px solid var(--scalar-color-red);\n}\n</style>\n\n<style>\n/* Pill styling. Each pill is `<span contenteditable=\"false\">name</span>` —\n an atomic widget; the caret lands before or after it, never inside. */\n.scalar-pill {\n color: var(--scalar-color-2);\n border-radius: var(--scalar-radius-full);\n display: inline-block;\n font-family: var(--scalar-font-code);\n font-size: 0.9em;\n line-height: 1.4;\n vertical-align: baseline;\n background: var(--scalar-background-3);\n padding: 0.125em 0.6em;\n margin-right: 0.35em;\n cursor: text;\n /* Single click selects the whole pill — chip/mention model, deletes in one go. */\n user-select: all;\n -webkit-user-select: all;\n}\n\n.dark-mode .scalar-pill {\n background: color-mix(\n in srgb,\n var(--tw-bg-base, var(--scalar-color-1)),\n transparent 90%\n );\n}\n\n.light-mode .scalar-pill {\n background: var(--scalar-background-3);\n}\n\n.scalar-pill--context-fn {\n /* Inset box-shadow as a border so the layout box stays identical to plain pills. */\n box-shadow: 0 0 0 1px\n color-mix(in srgb, var(--scalar-color-3), transparent 35%) inset;\n}\n\n.dark-mode .scalar-pill--context-fn {\n background: color-mix(in srgb, var(--scalar-background-3), transparent 55%);\n}\n\n.light-mode .scalar-pill--context-fn {\n background: color-mix(in srgb, var(--scalar-background-3), transparent 40%);\n}\n</style>\n"],"mappings":"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"}
|
package/dist/v2/constants.js
CHANGED
|
@@ -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.16.
|
|
3
|
+
var APP_VERSION = typeof OVERRIDE_PACKAGE_VERSION !== "undefined" ? OVERRIDE_PACKAGE_VERSION : "3.16.3";
|
|
4
4
|
//#endregion
|
|
5
5
|
export { APP_VERSION };
|
|
6
6
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-api-client-modal.d.ts","sourceRoot":"","sources":["../../../../../src/v2/features/modal/helpers/create-api-client-modal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAAY,MAAM,0BAA0B,CAAA;AACpE,OAAO,EAAE,KAAK,YAAY,EAAyB,MAAM,2BAA2B,CAAA;AACpF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AACpE,OAAO,EAAE,KAAK,iBAAiB,EAA2B,MAAM,gCAAgC,CAAA;AAEhG,OAAO,EAAE,KAAK,GAAG,EAAE,KAAK,gBAAgB,EAA6D,MAAM,KAAK,CAAA;AAEhH,OAAO,EAEL,KAAK,YAAY,EAElB,MAAM,sDAAsD,CAAA;AAG7D,OAAO,KAAK,EAAE,gBAAgB,EAAuB,MAAM,oBAAoB,CAAA;AAE/E,KAAK,sBAAsB,GAAG;IAC5B,4CAA4C;IAC5C,EAAE,EAAE,WAAW,GAAG,IAAI,CAAA;IACtB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,kFAAkF;IAClF,QAAQ,CAAC,EAAE,iBAAiB,CAAA;IAC5B,6DAA6D;IAC7D,cAAc,EAAE,cAAc,CAAA;IAC9B,iDAAiD;IACjD,OAAO,CAAC,EAAE,YAAY,EAAE,CAAA;IACxB,wGAAwG;IACxG,OAAO,CAAC,EAAE,gBAAgB,CAAC,gBAAgB,CAAC,CAAA;CAC7C,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,GAAG,EAAE,GAAG,CAAA;IACR,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE,YAAY,KAAK,IAAI,CAAA;IACtC,KAAK,EAAE,CAAC,UAAU,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAA;IAC/C,KAAK,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,CAAA;IACtC,aAAa,EAAE,CAAC,WAAW,EAAE,gBAAgB,EAAE,SAAS,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;IAC3E,UAAU,EAAE,UAAU,CAAA;CACvB,CAAA;AAcD;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,GAAI,wEASlC,sBAAsB,KAAG,
|
|
1
|
+
{"version":3,"file":"create-api-client-modal.d.ts","sourceRoot":"","sources":["../../../../../src/v2/features/modal/helpers/create-api-client-modal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAAY,MAAM,0BAA0B,CAAA;AACpE,OAAO,EAAE,KAAK,YAAY,EAAyB,MAAM,2BAA2B,CAAA;AACpF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AACpE,OAAO,EAAE,KAAK,iBAAiB,EAA2B,MAAM,gCAAgC,CAAA;AAEhG,OAAO,EAAE,KAAK,GAAG,EAAE,KAAK,gBAAgB,EAA6D,MAAM,KAAK,CAAA;AAEhH,OAAO,EAEL,KAAK,YAAY,EAElB,MAAM,sDAAsD,CAAA;AAG7D,OAAO,KAAK,EAAE,gBAAgB,EAAuB,MAAM,oBAAoB,CAAA;AAE/E,KAAK,sBAAsB,GAAG;IAC5B,4CAA4C;IAC5C,EAAE,EAAE,WAAW,GAAG,IAAI,CAAA;IACtB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,kFAAkF;IAClF,QAAQ,CAAC,EAAE,iBAAiB,CAAA;IAC5B,6DAA6D;IAC7D,cAAc,EAAE,cAAc,CAAA;IAC9B,iDAAiD;IACjD,OAAO,CAAC,EAAE,YAAY,EAAE,CAAA;IACxB,wGAAwG;IACxG,OAAO,CAAC,EAAE,gBAAgB,CAAC,gBAAgB,CAAC,CAAA;CAC7C,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,GAAG,EAAE,GAAG,CAAA;IACR,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE,YAAY,KAAK,IAAI,CAAA;IACtC,KAAK,EAAE,CAAC,UAAU,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAA;IAC/C,KAAK,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,CAAA;IACtC,aAAa,EAAE,CAAC,WAAW,EAAE,gBAAgB,EAAE,SAAS,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;IAC3E,UAAU,EAAE,UAAU,CAAA;CACvB,CAAA;AAcD;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,GAAI,wEASlC,sBAAsB,KAAG,cA0I3B,CAAA"}
|
|
@@ -73,10 +73,6 @@ var createApiClientModal = ({ el, eventBus = createWorkspaceEventBus({ debug: fa
|
|
|
73
73
|
workspaceStore,
|
|
74
74
|
options: optionsRef
|
|
75
75
|
});
|
|
76
|
-
/** Restore the workspace store when the modal is closed. */
|
|
77
|
-
const handleModalClose = () => {
|
|
78
|
-
requestBodyCompositionSelection.value = {};
|
|
79
|
-
};
|
|
80
76
|
/** Initialize plugins and subscribe to event bus events */
|
|
81
77
|
const pluginUnsubscribes = [];
|
|
82
78
|
for (const plugin of plugins) {
|
|
@@ -88,7 +84,6 @@ var createApiClientModal = ({ el, eventBus = createWorkspaceEventBus({ debug: fa
|
|
|
88
84
|
for (const unsub of pluginUnsubscribes) unsub();
|
|
89
85
|
for (const plugin of plugins) plugin.lifecycle?.onDestroy?.();
|
|
90
86
|
});
|
|
91
|
-
watch(() => modalState.open, (open) => open ? null : handleModalClose());
|
|
92
87
|
watch(() => toValue(optionsRef).proxyUrl, (newProxyUrl) => workspaceStore.update("x-scalar-active-proxy", newProxyUrl), { immediate: true });
|
|
93
88
|
app.config.idPrefix = `scalar-client-${modalAppCount++}`;
|
|
94
89
|
/** Mount the modal to a given element. */
|
|
@@ -105,6 +100,7 @@ var createApiClientModal = ({ el, eventBus = createWorkspaceEventBus({ debug: fa
|
|
|
105
100
|
app,
|
|
106
101
|
/** Open the modal and optionally navigate to a specific route. */
|
|
107
102
|
open: (payload) => {
|
|
103
|
+
requestBodyCompositionSelection.value = {};
|
|
108
104
|
modalState.open = true;
|
|
109
105
|
if (payload) route(payload);
|
|
110
106
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-api-client-modal.js","names":[],"sources":["../../../../../src/v2/features/modal/helpers/create-api-client-modal.ts"],"sourcesContent":["import { type ModalState, useModal } from '@scalar/components/modal'\nimport { type ClientPlugin, subscribePluginEvents } from '@scalar/oas-utils/helpers'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\nimport { type WorkspaceEventBus, createWorkspaceEventBus } from '@scalar/workspace-store/events'\nimport { isOpenApiDocument } from '@scalar/workspace-store/schemas/type-guards'\nimport { type App, type MaybeRefOrGetter, computed, createApp, isRef, reactive, ref, toValue, watch } from 'vue'\n\nimport {\n type DefaultEntities,\n type RoutePayload,\n resolveRouteParameters,\n} from '@/v2/features/modal/helpers/resolve-route-parameters'\nimport { useModalSidebar } from '@/v2/features/modal/hooks/use-modal-sidebar'\nimport Modal, { type ModalProps } from '@/v2/features/modal/Modal.vue'\nimport type { ApiClientOptions, ApiClientOptionsRef } from '@/v2/types/options'\n\ntype CreateApiClientOptions = {\n /** Element to mount the client modal to. */\n el: HTMLElement | null\n /**\n * Will attempt to mount the references immediately.\n * For SSR this may need to be disabled and handled manually on the client side.\n */\n mountOnInitialize?: boolean\n /** You can pass in an event bus if you have one already, or we will create one */\n eventBus?: WorkspaceEventBus\n /** The workspace store must be initialized and passed in. */\n workspaceStore: WorkspaceStore\n /** Api client plugins to include in the modal */\n plugins?: ClientPlugin[]\n /** Subset of the configuration options for the modal, if you want it to be reactive ensure its a ref */\n options?: MaybeRefOrGetter<ApiClientOptions>\n}\n\nexport type ApiClientModal = {\n app: App\n open: (payload?: RoutePayload) => void\n mount: (mountingEl: HTMLElement | null) => void\n route: (payload: RoutePayload) => void\n updateOptions: (nextOptions: ApiClientOptions, overwrite?: boolean) => void\n modalState: ModalState\n}\n\n/**\n * Monotonic counter used to give every modal Vue app a unique `idPrefix`.\n *\n * Vue derives `useId()` values (and therefore our teleport target ids) from the app's\n * `idPrefix`. When more than one client app mounts on the same page — for example, the\n * API reference embeds this modal alongside another client instance — a shared prefix\n * makes both apps emit identical ids. A teleported popover then resolves to the first\n * matching target in the DOM, which can be a hidden app, so the popover never appears.\n * A per-app suffix keeps the ids unique across instances.\n */\nlet modalAppCount = 0\n\n/**\n * Creates the API Client Modal.\n *\n * The modal does not require a router. Instead, navigation is handled by setting\n * active entities directly through the returned `route` function.\n */\nexport const createApiClientModal = ({\n el,\n eventBus = createWorkspaceEventBus({\n debug: import.meta.env.DEV,\n }),\n mountOnInitialize = true,\n plugins = [],\n workspaceStore,\n options = {},\n}: CreateApiClientOptions): ApiClientModal => {\n const requestBodyCompositionSelection = ref<Record<string, number>>({})\n\n /** This is to ensure that the options are a ref if they are not already, useful for react */\n const optionsRef = (isRef(options) ? options : ref(toValue(options))) as ApiClientOptionsRef\n\n const defaultEntities: DefaultEntities = {\n path: 'default',\n method: 'default',\n example: 'default',\n documentSlug: workspaceStore.workspace['x-scalar-active-document'] || 'default',\n }\n\n const parameters = reactive<DefaultEntities>({ ...defaultEntities })\n\n /** Navigate to the specified path, method, and example. */\n const route = (payload: RoutePayload): void => {\n Object.assign(parameters, defaultEntities, payload)\n }\n\n /** Resolved parameters from the workspace store. */\n const resolvedParameters = computed(() => resolveRouteParameters(workspaceStore, parameters))\n const documentSlug = computed(() => resolvedParameters.value.documentSlug)\n const path = computed(() => resolvedParameters.value.path)\n const method = computed(() => resolvedParameters.value.method)\n const exampleName = computed(() => resolvedParameters.value.example)\n /** The document from the workspace store. Modal is OpenAPI-only; AsyncAPI docs surface as null. */\n const document = computed(() => {\n const doc = workspaceStore.workspace.documents[documentSlug.value ?? '']\n return isOpenApiDocument(doc) ? doc : null\n })\n\n /** Sidebar state and selection handling. */\n const sidebarState = useModalSidebar({\n workspaceStore,\n documentSlug: documentSlug,\n path: path,\n method: method,\n exampleName: exampleName,\n route,\n })\n\n const modalState = useModal()\n\n const app = createApp(Modal, {\n document,\n eventBus,\n exampleName,\n method,\n modalState,\n path,\n plugins,\n requestBodyCompositionSelection,\n sidebarState,\n workspaceStore,\n options: optionsRef,\n } satisfies ModalProps)\n\n /**
|
|
1
|
+
{"version":3,"file":"create-api-client-modal.js","names":[],"sources":["../../../../../src/v2/features/modal/helpers/create-api-client-modal.ts"],"sourcesContent":["import { type ModalState, useModal } from '@scalar/components/modal'\nimport { type ClientPlugin, subscribePluginEvents } from '@scalar/oas-utils/helpers'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\nimport { type WorkspaceEventBus, createWorkspaceEventBus } from '@scalar/workspace-store/events'\nimport { isOpenApiDocument } from '@scalar/workspace-store/schemas/type-guards'\nimport { type App, type MaybeRefOrGetter, computed, createApp, isRef, reactive, ref, toValue, watch } from 'vue'\n\nimport {\n type DefaultEntities,\n type RoutePayload,\n resolveRouteParameters,\n} from '@/v2/features/modal/helpers/resolve-route-parameters'\nimport { useModalSidebar } from '@/v2/features/modal/hooks/use-modal-sidebar'\nimport Modal, { type ModalProps } from '@/v2/features/modal/Modal.vue'\nimport type { ApiClientOptions, ApiClientOptionsRef } from '@/v2/types/options'\n\ntype CreateApiClientOptions = {\n /** Element to mount the client modal to. */\n el: HTMLElement | null\n /**\n * Will attempt to mount the references immediately.\n * For SSR this may need to be disabled and handled manually on the client side.\n */\n mountOnInitialize?: boolean\n /** You can pass in an event bus if you have one already, or we will create one */\n eventBus?: WorkspaceEventBus\n /** The workspace store must be initialized and passed in. */\n workspaceStore: WorkspaceStore\n /** Api client plugins to include in the modal */\n plugins?: ClientPlugin[]\n /** Subset of the configuration options for the modal, if you want it to be reactive ensure its a ref */\n options?: MaybeRefOrGetter<ApiClientOptions>\n}\n\nexport type ApiClientModal = {\n app: App\n open: (payload?: RoutePayload) => void\n mount: (mountingEl: HTMLElement | null) => void\n route: (payload: RoutePayload) => void\n updateOptions: (nextOptions: ApiClientOptions, overwrite?: boolean) => void\n modalState: ModalState\n}\n\n/**\n * Monotonic counter used to give every modal Vue app a unique `idPrefix`.\n *\n * Vue derives `useId()` values (and therefore our teleport target ids) from the app's\n * `idPrefix`. When more than one client app mounts on the same page — for example, the\n * API reference embeds this modal alongside another client instance — a shared prefix\n * makes both apps emit identical ids. A teleported popover then resolves to the first\n * matching target in the DOM, which can be a hidden app, so the popover never appears.\n * A per-app suffix keeps the ids unique across instances.\n */\nlet modalAppCount = 0\n\n/**\n * Creates the API Client Modal.\n *\n * The modal does not require a router. Instead, navigation is handled by setting\n * active entities directly through the returned `route` function.\n */\nexport const createApiClientModal = ({\n el,\n eventBus = createWorkspaceEventBus({\n debug: import.meta.env.DEV,\n }),\n mountOnInitialize = true,\n plugins = [],\n workspaceStore,\n options = {},\n}: CreateApiClientOptions): ApiClientModal => {\n const requestBodyCompositionSelection = ref<Record<string, number>>({})\n\n /** This is to ensure that the options are a ref if they are not already, useful for react */\n const optionsRef = (isRef(options) ? options : ref(toValue(options))) as ApiClientOptionsRef\n\n const defaultEntities: DefaultEntities = {\n path: 'default',\n method: 'default',\n example: 'default',\n documentSlug: workspaceStore.workspace['x-scalar-active-document'] || 'default',\n }\n\n const parameters = reactive<DefaultEntities>({ ...defaultEntities })\n\n /** Navigate to the specified path, method, and example. */\n const route = (payload: RoutePayload): void => {\n Object.assign(parameters, defaultEntities, payload)\n }\n\n /** Resolved parameters from the workspace store. */\n const resolvedParameters = computed(() => resolveRouteParameters(workspaceStore, parameters))\n const documentSlug = computed(() => resolvedParameters.value.documentSlug)\n const path = computed(() => resolvedParameters.value.path)\n const method = computed(() => resolvedParameters.value.method)\n const exampleName = computed(() => resolvedParameters.value.example)\n /** The document from the workspace store. Modal is OpenAPI-only; AsyncAPI docs surface as null. */\n const document = computed(() => {\n const doc = workspaceStore.workspace.documents[documentSlug.value ?? '']\n return isOpenApiDocument(doc) ? doc : null\n })\n\n /** Sidebar state and selection handling. */\n const sidebarState = useModalSidebar({\n workspaceStore,\n documentSlug: documentSlug,\n path: path,\n method: method,\n exampleName: exampleName,\n route,\n })\n\n const modalState = useModal()\n\n const app = createApp(Modal, {\n document,\n eventBus,\n exampleName,\n method,\n modalState,\n path,\n plugins,\n requestBodyCompositionSelection,\n sidebarState,\n workspaceStore,\n options: optionsRef,\n } satisfies ModalProps)\n\n /** Initialize plugins and subscribe to event bus events */\n const pluginUnsubscribes: (() => void)[] = []\n for (const plugin of plugins) {\n plugin.lifecycle?.onInit?.()\n\n pluginUnsubscribes.push(subscribePluginEvents(eventBus, plugin))\n }\n\n /** Clean up plugin lifecycle and event bus subscriptions when the app is unmounted */\n app.onUnmount(() => {\n for (const unsub of pluginUnsubscribes) {\n unsub()\n }\n for (const plugin of plugins) {\n plugin.lifecycle?.onDestroy?.()\n }\n })\n\n // Update the active proxy when the proxyUrl changes\n watch(\n () => toValue(optionsRef).proxyUrl,\n (newProxyUrl) => workspaceStore.update('x-scalar-active-proxy', newProxyUrl),\n { immediate: true },\n )\n\n // Use a unique id prefix to prevent collisions with other Vue apps on the page.\n // The suffix keeps the prefix unique even when several client apps mount together.\n app.config.idPrefix = `scalar-client-${modalAppCount++}`\n\n /** Mount the modal to a given element. */\n const mount = (mountingEl: HTMLElement | null = el): void => {\n if (!mountingEl) {\n console.error(\n '[@scalar/api-client] Could not create the API client Modal.',\n 'Invalid HTML element provided.',\n 'Read more: https://github.com/scalar/scalar/tree/main/packages/api-client',\n )\n return\n }\n app.mount(mountingEl)\n }\n\n if (mountOnInitialize) {\n mount()\n }\n\n return {\n /** The Vue app instance for the modal. Use with caution. */\n app,\n /** Open the modal and optionally navigate to a specific route. */\n open: (payload?: RoutePayload): void => {\n // This path does not carry a composition selection, so clear any selection left over from a\n // previously opened operation. (The event-driven open path re-establishes it from its payload.)\n requestBodyCompositionSelection.value = {}\n modalState.open = true\n if (payload) {\n route(payload)\n }\n },\n /** Mount the modal to a given element. */\n mount,\n /** Navigate to the specified path, method, and example. */\n route,\n /** Controls the visibility of the modal. */\n modalState,\n /**\n * Merge new options into the current modal options.\n *\n * @param newOptions - The new options to merge into the current modal options.\n * @param overwrite - Whether to overwrite the current modal options with the new options. If false, the new options will be merged with the current options.\n */\n updateOptions: (newOptions: ApiClientOptions, overwrite = false): void => {\n optionsRef.value = overwrite\n ? newOptions\n : {\n ...optionsRef.value,\n ...newOptions,\n }\n },\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAqDA,IAAI,gBAAgB;;;;;;;AAQpB,IAAa,wBAAwB,EACnC,IACA,WAAW,wBAAwB,EACjC,OAAA,MACF,CAAC,GACD,oBAAoB,MACpB,UAAU,CAAC,GACX,gBACA,UAAU,CAAC,QACiC;CAC5C,MAAM,kCAAkC,IAA4B,CAAC,CAAC;;CAGtE,MAAM,aAAc,MAAM,OAAO,IAAI,UAAU,IAAI,QAAQ,OAAO,CAAC;CAEnE,MAAM,kBAAmC;EACvC,MAAM;EACN,QAAQ;EACR,SAAS;EACT,cAAc,eAAe,UAAU,+BAA+B;CACxE;CAEA,MAAM,aAAa,SAA0B,EAAE,GAAG,gBAAgB,CAAC;;CAGnE,MAAM,SAAS,YAAgC;EAC7C,OAAO,OAAO,YAAY,iBAAiB,OAAO;CACpD;;CAGA,MAAM,qBAAqB,eAAe,uBAAuB,gBAAgB,UAAU,CAAC;CAC5F,MAAM,eAAe,eAAe,mBAAmB,MAAM,YAAY;CACzE,MAAM,OAAO,eAAe,mBAAmB,MAAM,IAAI;CACzD,MAAM,SAAS,eAAe,mBAAmB,MAAM,MAAM;CAC7D,MAAM,cAAc,eAAe,mBAAmB,MAAM,OAAO;;CAEnE,MAAM,WAAW,eAAe;EAC9B,MAAM,MAAM,eAAe,UAAU,UAAU,aAAa,SAAS;EACrE,OAAO,kBAAkB,GAAG,IAAI,MAAM;CACxC,CAAC;;CAGD,MAAM,eAAe,gBAAgB;EACnC;EACc;EACR;EACE;EACK;EACb;CACF,CAAC;CAED,MAAM,aAAa,SAAS;CAE5B,MAAM,MAAM,UAAU,eAAO;EAC3B;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAAS;CACX,CAAsB;;CAGtB,MAAM,qBAAqC,CAAC;CAC5C,KAAK,MAAM,UAAU,SAAS;EAC5B,OAAO,WAAW,SAAS;EAE3B,mBAAmB,KAAK,sBAAsB,UAAU,MAAM,CAAC;CACjE;;CAGA,IAAI,gBAAgB;EAClB,KAAK,MAAM,SAAS,oBAClB,MAAM;EAER,KAAK,MAAM,UAAU,SACnB,OAAO,WAAW,YAAY;CAElC,CAAC;CAGD,YACQ,QAAQ,UAAU,CAAC,CAAC,WACzB,gBAAgB,eAAe,OAAO,yBAAyB,WAAW,GAC3E,EAAE,WAAW,KAAK,CACpB;CAIA,IAAI,OAAO,WAAW,iBAAiB;;CAGvC,MAAM,SAAS,aAAiC,OAAa;EAC3D,IAAI,CAAC,YAAY;GACf,QAAQ,MACN,+DACA,kCACA,2EACF;GACA;EACF;EACA,IAAI,MAAM,UAAU;CACtB;CAEA,IAAI,mBACF,MAAM;CAGR,OAAO;;EAEL;;EAEA,OAAO,YAAiC;GAGtC,gCAAgC,QAAQ,CAAC;GACzC,WAAW,OAAO;GAClB,IAAI,SACF,MAAM,OAAO;EAEjB;;EAEA;;EAEA;;EAEA;;;;;;;EAOA,gBAAgB,YAA8B,YAAY,UAAgB;GACxE,WAAW,QAAQ,YACf,aACA;IACE,GAAG,WAAW;IACd,GAAG;GACL;EACN;CACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"modal-events.d.ts","sourceRoot":"","sources":["../../../../src/v2/features/modal/modal-events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAGvE,OAAO,EAAE,KAAK,GAAG,EAAO,MAAM,KAAK,CAAA;AAEnC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,6CAA6C,CAAA;
|
|
1
|
+
{"version":3,"file":"modal-events.d.ts","sourceRoot":"","sources":["../../../../src/v2/features/modal/modal-events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAGvE,OAAO,EAAE,KAAK,GAAG,EAAO,MAAM,KAAK,CAAA;AAEnC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,6CAA6C,CAAA;AAOxF,wBAAgB,qBAAqB,CAAC,EACpC,QAAQ,EACR,aAAa,EACb,+BAA+B,EAC/B,YAAY,EACZ,UAAU,EACV,KAAK,GACN,EAAE;IACD,QAAQ,EAAE,iBAAiB,CAAA;IAC3B,aAAa,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IAC3B,+BAA+B,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IAC5D,YAAY,EAAE,qBAAqB,CAAA;IACnC,UAAU,EAAE,UAAU,CAAA;IACtB,KAAK,EAAE,cAAc,CAAA;CACtB,QA0EA"}
|
|
@@ -2,7 +2,7 @@ import { initializeWorkspaceEventHandlers } from "../../workspace-events.js";
|
|
|
2
2
|
import { ref } from "vue";
|
|
3
3
|
import { isOpenApiDocument } from "@scalar/workspace-store/schemas/type-guards";
|
|
4
4
|
//#region src/v2/features/modal/modal-events.ts
|
|
5
|
-
var EMPTY_REQUEST_BODY_COMPOSITION_SELECTION = {};
|
|
5
|
+
var EMPTY_REQUEST_BODY_COMPOSITION_SELECTION = Object.freeze({});
|
|
6
6
|
function initializeModalEvents({ eventBus, isSidebarOpen, requestBodyCompositionSelection, sidebarState, modalState, store }) {
|
|
7
7
|
/** Initialize workspace event handlers */
|
|
8
8
|
initializeWorkspaceEventHandlers({
|
|
@@ -14,8 +14,9 @@ function initializeModalEvents({ eventBus, isSidebarOpen, requestBodyComposition
|
|
|
14
14
|
eventBus.on("ui:toggle:sidebar", () => isSidebarOpen.value = !isSidebarOpen.value);
|
|
15
15
|
eventBus.on("ui:close:client-modal", () => modalState.hide());
|
|
16
16
|
eventBus.on("ui:open:client-modal", (payload) => {
|
|
17
|
-
|
|
17
|
+
const nextRequestBodyCompositionSelection = payload && "requestBodyCompositionSelection" in payload && payload.requestBodyCompositionSelection ? payload.requestBodyCompositionSelection : EMPTY_REQUEST_BODY_COMPOSITION_SELECTION;
|
|
18
18
|
if (!payload) {
|
|
19
|
+
requestBodyCompositionSelection.value = nextRequestBodyCompositionSelection;
|
|
19
20
|
modalState.show();
|
|
20
21
|
return;
|
|
21
22
|
}
|
|
@@ -38,6 +39,7 @@ function initializeModalEvents({ eventBus, isSidebarOpen, requestBodyComposition
|
|
|
38
39
|
example: payload.exampleName
|
|
39
40
|
})?.id ?? "");
|
|
40
41
|
}
|
|
42
|
+
requestBodyCompositionSelection.value = nextRequestBodyCompositionSelection;
|
|
41
43
|
modalState.show();
|
|
42
44
|
});
|
|
43
45
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"modal-events.js","names":[],"sources":["../../../../src/v2/features/modal/modal-events.ts"],"sourcesContent":["import type { ModalState } from '@scalar/components/modal'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\nimport type { WorkspaceEventBus } from '@scalar/workspace-store/events'\nimport type { TraversedEntry } from '@scalar/workspace-store/schemas/navigation'\nimport { isOpenApiDocument } from '@scalar/workspace-store/schemas/type-guards'\nimport { type Ref, ref } from 'vue'\n\nimport type { UseModalSidebarReturn } from '@/v2/features/modal/hooks/use-modal-sidebar'\nimport { initializeWorkspaceEventHandlers } from '@/v2/workspace-events'\n\nconst EMPTY_REQUEST_BODY_COMPOSITION_SELECTION = {} as Record<string, number>\n\nexport function initializeModalEvents({\n eventBus,\n isSidebarOpen,\n requestBodyCompositionSelection,\n sidebarState,\n modalState,\n store,\n}: {\n eventBus: WorkspaceEventBus\n isSidebarOpen: Ref<boolean>\n requestBodyCompositionSelection: Ref<Record<string, number>>\n sidebarState: UseModalSidebarReturn\n modalState: ModalState\n store: WorkspaceStore\n}) {\n /** Initialize workspace event handlers */\n initializeWorkspaceEventHandlers({\n eventBus,\n store: ref(store),\n hooks: {},\n })\n\n //------------------------------------------------------------------------------------\n // Navigation Event Handlers\n //------------------------------------------------------------------------------------\n eventBus.on('scroll-to:nav-item', ({ id }) => sidebarState.handleSelectItem(id))\n\n //------------------------------------------------------------------------------------\n // UI Related Event Handlers\n //------------------------------------------------------------------------------------\n eventBus.on('ui:toggle:sidebar', () => (isSidebarOpen.value = !isSidebarOpen.value))\n eventBus.on('ui:close:client-modal', () => modalState.hide())\n eventBus.on('ui:open:client-modal', (payload) => {\n const nextRequestBodyCompositionSelection = (\n payload && 'requestBodyCompositionSelection' in payload && payload.requestBodyCompositionSelection\n ? payload.requestBodyCompositionSelection\n : EMPTY_REQUEST_BODY_COMPOSITION_SELECTION\n ) as Record<string, number>\n\n
|
|
1
|
+
{"version":3,"file":"modal-events.js","names":[],"sources":["../../../../src/v2/features/modal/modal-events.ts"],"sourcesContent":["import type { ModalState } from '@scalar/components/modal'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\nimport type { WorkspaceEventBus } from '@scalar/workspace-store/events'\nimport type { TraversedEntry } from '@scalar/workspace-store/schemas/navigation'\nimport { isOpenApiDocument } from '@scalar/workspace-store/schemas/type-guards'\nimport { type Ref, ref } from 'vue'\n\nimport type { UseModalSidebarReturn } from '@/v2/features/modal/hooks/use-modal-sidebar'\nimport { initializeWorkspaceEventHandlers } from '@/v2/workspace-events'\n\n// Frozen so this shared fallback cannot be mutated in place, which would leak a stale selection into\n// every future open that falls back to empty. Callers only ever reassign the ref, never mutate it.\nconst EMPTY_REQUEST_BODY_COMPOSITION_SELECTION = Object.freeze({}) as Record<string, number>\n\nexport function initializeModalEvents({\n eventBus,\n isSidebarOpen,\n requestBodyCompositionSelection,\n sidebarState,\n modalState,\n store,\n}: {\n eventBus: WorkspaceEventBus\n isSidebarOpen: Ref<boolean>\n requestBodyCompositionSelection: Ref<Record<string, number>>\n sidebarState: UseModalSidebarReturn\n modalState: ModalState\n store: WorkspaceStore\n}) {\n /** Initialize workspace event handlers */\n initializeWorkspaceEventHandlers({\n eventBus,\n store: ref(store),\n hooks: {},\n })\n\n //------------------------------------------------------------------------------------\n // Navigation Event Handlers\n //------------------------------------------------------------------------------------\n eventBus.on('scroll-to:nav-item', ({ id }) => sidebarState.handleSelectItem(id))\n\n //------------------------------------------------------------------------------------\n // UI Related Event Handlers\n //------------------------------------------------------------------------------------\n eventBus.on('ui:toggle:sidebar', () => (isSidebarOpen.value = !isSidebarOpen.value))\n eventBus.on('ui:close:client-modal', () => modalState.hide())\n eventBus.on('ui:open:client-modal', (payload) => {\n // Every open re-establishes the selection (falling back to empty), so the modal no longer needs\n // to reset it on close. Keep this assignment unconditional to preserve that invariant.\n const nextRequestBodyCompositionSelection = (\n payload && 'requestBodyCompositionSelection' in payload && payload.requestBodyCompositionSelection\n ? payload.requestBodyCompositionSelection\n : EMPTY_REQUEST_BODY_COMPOSITION_SELECTION\n ) as Record<string, number>\n\n // Just open the modal\n if (!payload) {\n requestBodyCompositionSelection.value = nextRequestBodyCompositionSelection\n modalState.show()\n return\n }\n\n // We route to the exact ID\n if ('id' in payload && payload.id) {\n let targetId = payload.id\n\n // If exampleName is provided, try to find the specific example entry\n if ('exampleName' in payload && payload.exampleName) {\n const operationEntry = sidebarState.state.getEntryById(payload.id)\n\n // Try to find the specific example in the operation's children\n if (operationEntry && 'children' in operationEntry && operationEntry.children) {\n const exampleEntry = operationEntry.children.find(\n (child: TraversedEntry) => child.type === 'example' && child.name === payload.exampleName,\n )\n if (exampleEntry) {\n targetId = exampleEntry.id\n }\n }\n }\n\n sidebarState.handleSelectItem(targetId)\n }\n // We must find the ID first from the entries\n else if ('method' in payload && 'path' in payload) {\n const activeDoc = store.workspace.activeDocument\n sidebarState.handleSelectItem(\n sidebarState.getEntryByLocation({\n document: isOpenApiDocument(activeDoc) ? (activeDoc['x-scalar-navigation']?.id ?? '') : '',\n path: payload.path,\n method: payload.method,\n example: payload.exampleName,\n })?.id ?? '',\n )\n }\n\n // Apply the selection after routing so the request body compares it with the selection used\n // for this operation, rather than briefly resetting the operation that was previously open.\n requestBodyCompositionSelection.value = nextRequestBodyCompositionSelection\n\n modalState.show()\n })\n}\n"],"mappings":";;;;AAYA,IAAM,2CAA2C,OAAO,OAAO,CAAC,CAAC;AAEjE,SAAgB,sBAAsB,EACpC,UACA,eACA,iCACA,cACA,YACA,SAQC;;CAED,iCAAiC;EAC/B;EACA,OAAO,IAAI,KAAK;EAChB,OAAO,CAAC;CACV,CAAC;CAKD,SAAS,GAAG,uBAAuB,EAAE,SAAS,aAAa,iBAAiB,EAAE,CAAC;CAK/E,SAAS,GAAG,2BAA4B,cAAc,QAAQ,CAAC,cAAc,KAAM;CACnF,SAAS,GAAG,+BAA+B,WAAW,KAAK,CAAC;CAC5D,SAAS,GAAG,yBAAyB,YAAY;EAG/C,MAAM,sCACJ,WAAW,qCAAqC,WAAW,QAAQ,kCAC/D,QAAQ,kCACR;EAIN,IAAI,CAAC,SAAS;GACZ,gCAAgC,QAAQ;GACxC,WAAW,KAAK;GAChB;EACF;EAGA,IAAI,QAAQ,WAAW,QAAQ,IAAI;GACjC,IAAI,WAAW,QAAQ;GAGvB,IAAI,iBAAiB,WAAW,QAAQ,aAAa;IACnD,MAAM,iBAAiB,aAAa,MAAM,aAAa,QAAQ,EAAE;IAGjE,IAAI,kBAAkB,cAAc,kBAAkB,eAAe,UAAU;KAC7E,MAAM,eAAe,eAAe,SAAS,MAC1C,UAA0B,MAAM,SAAS,aAAa,MAAM,SAAS,QAAQ,WAChF;KACA,IAAI,cACF,WAAW,aAAa;IAE5B;GACF;GAEA,aAAa,iBAAiB,QAAQ;EACxC,OAEK,IAAI,YAAY,WAAW,UAAU,SAAS;GACjD,MAAM,YAAY,MAAM,UAAU;GAClC,aAAa,iBACX,aAAa,mBAAmB;IAC9B,UAAU,kBAAkB,SAAS,IAAK,UAAU,sBAAsB,EAAE,MAAM,KAAM;IACxF,MAAM,QAAQ;IACd,QAAQ,QAAQ;IAChB,SAAS,QAAQ;GACnB,CAAC,CAAC,EAAE,MAAM,EACZ;EACF;EAIA,gCAAgC,QAAQ;EAExC,WAAW,KAAK;CAClB,CAAC;AACH"}
|
|
@@ -37,7 +37,7 @@ function addEntryToIndex(entry, index, document) {
|
|
|
37
37
|
});
|
|
38
38
|
return;
|
|
39
39
|
}
|
|
40
|
-
if (entry.type === "tag" && entry.
|
|
40
|
+
if (entry.type === "tag" && entry.isTagGroup !== true) {
|
|
41
41
|
index.push({
|
|
42
42
|
id: entry.id,
|
|
43
43
|
title: entry.title,
|
|
@@ -48,7 +48,7 @@ function addEntryToIndex(entry, index, document) {
|
|
|
48
48
|
});
|
|
49
49
|
return;
|
|
50
50
|
}
|
|
51
|
-
if (entry.type === "tag" && entry.
|
|
51
|
+
if (entry.type === "tag" && entry.isTagGroup === true) {
|
|
52
52
|
index.push({
|
|
53
53
|
id: entry.id,
|
|
54
54
|
title: entry.title,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-search-index.js","names":[],"sources":["../../../../../src/v2/features/search/helpers/create-search-index.ts"],"sourcesContent":["import { getPathItemOperation } from '@scalar/workspace-store/helpers/for-each-path-item-operation'\nimport { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport type { TraversedEntry } from '@scalar/workspace-store/schemas/navigation'\nimport type { OpenApiDocument } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\n\nimport type { FuseData } from '@/v2/features/search/types'\n\n/**\n * Create a search index from a list of entries.\n */\nexport function createSearchIndex(documents: OpenApiDocument[]): FuseData[] {\n const index: FuseData[] = []\n\n /**\n * Recursively processes entries and their children to build the search index.\n */\n function processEntries(entriesToProcess: TraversedEntry[], document?: OpenApiDocument): void {\n entriesToProcess.forEach((entry) => {\n addEntryToIndex(entry, index, document)\n\n // Recursively process children if they exist\n if ('children' in entry && entry.children) {\n processEntries(entry.children, document)\n }\n })\n }\n\n documents?.forEach((document) => processEntries(document['x-scalar-navigation']?.children ?? [], document))\n\n return index\n}\n\n/**\n * Adds a single entry to the search index, handling all entry types recursively.\n */\nfunction addEntryToIndex(entry: TraversedEntry, index: FuseData[], document?: OpenApiDocument): void {\n // Operation\n if (entry.type === 'operation') {\n const operation = getResolvedRef(getPathItemOperation(document?.paths?.[entry.path], entry.method)) ?? {}\n\n index.push({\n type: 'operation',\n title: entry.title,\n id: entry.id,\n description: operation.description || '',\n method: entry.method,\n path: entry.path,\n operationId: operation.operationId,\n entry,\n documentName: document?.info.title ?? '',\n })\n\n return\n }\n\n if (entry.type === 'tag' && entry.
|
|
1
|
+
{"version":3,"file":"create-search-index.js","names":[],"sources":["../../../../../src/v2/features/search/helpers/create-search-index.ts"],"sourcesContent":["import { getPathItemOperation } from '@scalar/workspace-store/helpers/for-each-path-item-operation'\nimport { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport type { TraversedEntry } from '@scalar/workspace-store/schemas/navigation'\nimport type { OpenApiDocument } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\n\nimport type { FuseData } from '@/v2/features/search/types'\n\n/**\n * Create a search index from a list of entries.\n */\nexport function createSearchIndex(documents: OpenApiDocument[]): FuseData[] {\n const index: FuseData[] = []\n\n /**\n * Recursively processes entries and their children to build the search index.\n */\n function processEntries(entriesToProcess: TraversedEntry[], document?: OpenApiDocument): void {\n entriesToProcess.forEach((entry) => {\n addEntryToIndex(entry, index, document)\n\n // Recursively process children if they exist\n if ('children' in entry && entry.children) {\n processEntries(entry.children, document)\n }\n })\n }\n\n documents?.forEach((document) => processEntries(document['x-scalar-navigation']?.children ?? [], document))\n\n return index\n}\n\n/**\n * Adds a single entry to the search index, handling all entry types recursively.\n */\nfunction addEntryToIndex(entry: TraversedEntry, index: FuseData[], document?: OpenApiDocument): void {\n // Operation\n if (entry.type === 'operation') {\n const operation = getResolvedRef(getPathItemOperation(document?.paths?.[entry.path], entry.method)) ?? {}\n\n index.push({\n type: 'operation',\n title: entry.title,\n id: entry.id,\n description: operation.description || '',\n method: entry.method,\n path: entry.path,\n operationId: operation.operationId,\n entry,\n documentName: document?.info.title ?? '',\n })\n\n return\n }\n\n // Regular tags, including OpenAPI 3.2 operation-less parent sections (which are `isGroup: true`\n // but real tags), keep their own description.\n if (entry.type === 'tag' && entry.isTagGroup !== true) {\n index.push({\n id: entry.id,\n title: entry.title,\n description: entry.description || '',\n type: 'tag',\n entry,\n documentName: document?.info.title ?? '',\n })\n\n return\n }\n\n // Legacy `x-tagGroups` wrappers are not real tags, so they carry the generic group label.\n if (entry.type === 'tag' && entry.isTagGroup === true) {\n index.push({\n id: entry.id,\n title: entry.title,\n description: 'Tag Group',\n type: 'tag',\n entry,\n documentName: document?.info.title ?? '',\n })\n\n return\n }\n\n // Headings from info.description\n if (entry.type === 'text') {\n index.push({\n id: entry.id,\n type: 'heading',\n title: entry.title ?? '',\n description: 'Heading',\n entry,\n documentName: document?.info.title ?? '',\n })\n\n return\n }\n}\n"],"mappings":";;;;;;AAUA,SAAgB,kBAAkB,WAA0C;CAC1E,MAAM,QAAoB,CAAC;;;;CAK3B,SAAS,eAAe,kBAAoC,UAAkC;EAC5F,iBAAiB,SAAS,UAAU;GAClC,gBAAgB,OAAO,OAAO,QAAQ;GAGtC,IAAI,cAAc,SAAS,MAAM,UAC/B,eAAe,MAAM,UAAU,QAAQ;EAE3C,CAAC;CACH;CAEA,WAAW,SAAS,aAAa,eAAe,SAAS,sBAAsB,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC;CAE1G,OAAO;AACT;;;;AAKA,SAAS,gBAAgB,OAAuB,OAAmB,UAAkC;CAEnG,IAAI,MAAM,SAAS,aAAa;EAC9B,MAAM,YAAY,eAAe,qBAAqB,UAAU,QAAQ,MAAM,OAAO,MAAM,MAAM,CAAC,KAAK,CAAC;EAExG,MAAM,KAAK;GACT,MAAM;GACN,OAAO,MAAM;GACb,IAAI,MAAM;GACV,aAAa,UAAU,eAAe;GACtC,QAAQ,MAAM;GACd,MAAM,MAAM;GACZ,aAAa,UAAU;GACvB;GACA,cAAc,UAAU,KAAK,SAAS;EACxC,CAAC;EAED;CACF;CAIA,IAAI,MAAM,SAAS,SAAS,MAAM,eAAe,MAAM;EACrD,MAAM,KAAK;GACT,IAAI,MAAM;GACV,OAAO,MAAM;GACb,aAAa,MAAM,eAAe;GAClC,MAAM;GACN;GACA,cAAc,UAAU,KAAK,SAAS;EACxC,CAAC;EAED;CACF;CAGA,IAAI,MAAM,SAAS,SAAS,MAAM,eAAe,MAAM;EACrD,MAAM,KAAK;GACT,IAAI,MAAM;GACV,OAAO,MAAM;GACb,aAAa;GACb,MAAM;GACN;GACA,cAAc,UAAU,KAAK,SAAS;EACxC,CAAC;EAED;CACF;CAGA,IAAI,MAAM,SAAS,QAAQ;EACzB,MAAM,KAAK;GACT,IAAI,MAAM;GACV,MAAM;GACN,OAAO,MAAM,SAAS;GACtB,aAAa;GACb;GACA,cAAc,UAAU,KAAK,SAAS;EACxC,CAAC;EAED;CACF;AACF"}
|
package/dist/vue-styles.css
CHANGED
|
@@ -314,13 +314,13 @@ to {
|
|
|
314
314
|
color: var(--scalar-color-1);
|
|
315
315
|
}
|
|
316
316
|
|
|
317
|
-
.code-input-lite[data-v-
|
|
317
|
+
.code-input-lite[data-v-4dfd05a3] {
|
|
318
318
|
/* Flex so the editor centres vertically in whatever height the cell gives us.
|
|
319
319
|
Font properties inherit so we adopt the surrounding typography. */
|
|
320
320
|
display: flex;
|
|
321
321
|
align-items: center;
|
|
322
322
|
}
|
|
323
|
-
.code-input-lite__editor[data-v-
|
|
323
|
+
.code-input-lite__editor[data-v-4dfd05a3] {
|
|
324
324
|
/* Everything font-related inherits from the surrounding context. */
|
|
325
325
|
font: inherit;
|
|
326
326
|
letter-spacing: inherit;
|
|
@@ -342,7 +342,7 @@ to {
|
|
|
342
342
|
/* Positioning context for the absolutely positioned placeholder. */
|
|
343
343
|
position: relative;
|
|
344
344
|
}
|
|
345
|
-
.code-input-lite__editor[data-v-
|
|
345
|
+
.code-input-lite__editor[data-v-4dfd05a3]::-webkit-scrollbar {
|
|
346
346
|
display: none;
|
|
347
347
|
}
|
|
348
348
|
|
|
@@ -350,7 +350,7 @@ to {
|
|
|
350
350
|
contenteditable; otherwise the caret would land after it on focus.
|
|
351
351
|
`pointer-events: none` lets clicks fall through to focus the editor.
|
|
352
352
|
Hidden on focus so it never renders on top of the text caret. */
|
|
353
|
-
.code-input-lite--empty .code-input-lite__editor[data-v-
|
|
353
|
+
.code-input-lite--empty .code-input-lite__editor[data-v-4dfd05a3]:not(:focus)::before {
|
|
354
354
|
content: attr(data-placeholder);
|
|
355
355
|
color: var(--scalar-color-3);
|
|
356
356
|
pointer-events: none;
|
|
@@ -361,7 +361,7 @@ to {
|
|
|
361
361
|
display: flex;
|
|
362
362
|
align-items: center;
|
|
363
363
|
}
|
|
364
|
-
.code-input-lite--error .code-input-lite__editor[data-v-
|
|
364
|
+
.code-input-lite--error .code-input-lite__editor[data-v-4dfd05a3] {
|
|
365
365
|
outline: 1px solid var(--scalar-color-red);
|
|
366
366
|
}
|
|
367
367
|
|
|
@@ -405,20 +405,20 @@ to {
|
|
|
405
405
|
background: color-mix(in srgb, var(--scalar-background-3), transparent 40%);
|
|
406
406
|
}
|
|
407
407
|
|
|
408
|
-
[data-v-
|
|
408
|
+
[data-v-13500378] .code-input-lite__editor {
|
|
409
409
|
background-color: transparent;
|
|
410
410
|
font-family: var(--scalar-font);
|
|
411
411
|
font-size: var(--scalar-small);
|
|
412
412
|
padding: 5px 8px;
|
|
413
413
|
}
|
|
414
|
-
[data-v-
|
|
414
|
+
[data-v-13500378] .scalar-pill:not(:last-of-type) {
|
|
415
415
|
margin-right: 0.15em;
|
|
416
416
|
}
|
|
417
|
-
[data-v-
|
|
417
|
+
[data-v-13500378] .scalar-pill:not(:first-of-type) {
|
|
418
418
|
margin-left: 0.5px;
|
|
419
419
|
}
|
|
420
420
|
|
|
421
|
-
[data-v-
|
|
421
|
+
[data-v-c8ab7ba2] .cm-content {
|
|
422
422
|
font-size: var(--scalar-small);
|
|
423
423
|
}
|
|
424
424
|
|
package/package.json
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"rest",
|
|
19
19
|
"testing"
|
|
20
20
|
],
|
|
21
|
-
"version": "3.16.
|
|
21
|
+
"version": "3.16.3",
|
|
22
22
|
"engines": {
|
|
23
23
|
"node": ">=22"
|
|
24
24
|
},
|
|
@@ -300,7 +300,7 @@
|
|
|
300
300
|
"@vueuse/integrations": "13.9.0",
|
|
301
301
|
"focus-trap": "^7.8.0",
|
|
302
302
|
"fuse.js": "^7.5.0",
|
|
303
|
-
"js-base64": "^3.
|
|
303
|
+
"js-base64": "^3.9.2",
|
|
304
304
|
"jsonc-parser": "3.3.1",
|
|
305
305
|
"nanoid": "^5.1.6",
|
|
306
306
|
"pretty-ms": "^9.3.0",
|
|
@@ -309,27 +309,27 @@
|
|
|
309
309
|
"vue": "^3.5.40",
|
|
310
310
|
"yaml": "^2.9.0",
|
|
311
311
|
"zod": "^4.3.5",
|
|
312
|
-
"@scalar/blocks": "0.1.
|
|
313
|
-
"@scalar/components": "0.
|
|
314
|
-
"@scalar/
|
|
315
|
-
"@scalar/
|
|
316
|
-
"@scalar/
|
|
317
|
-
"@scalar/
|
|
318
|
-
"@scalar/
|
|
319
|
-
"@scalar/
|
|
320
|
-
"@scalar/
|
|
321
|
-
"@scalar/
|
|
322
|
-
"@scalar/use-
|
|
323
|
-
"@scalar/
|
|
324
|
-
"@scalar/use-toasts": "0.10.
|
|
325
|
-
"@scalar/workspace-store": "0.
|
|
312
|
+
"@scalar/blocks": "0.1.14",
|
|
313
|
+
"@scalar/components": "0.28.1",
|
|
314
|
+
"@scalar/helpers": "0.11.1",
|
|
315
|
+
"@scalar/icons": "0.7.6",
|
|
316
|
+
"@scalar/oas-utils": "0.19.14",
|
|
317
|
+
"@scalar/openapi-types": "0.9.5",
|
|
318
|
+
"@scalar/snippetz": "0.9.28",
|
|
319
|
+
"@scalar/sidebar": "0.10.1",
|
|
320
|
+
"@scalar/themes": "0.17.3",
|
|
321
|
+
"@scalar/use-codemirror": "0.14.15",
|
|
322
|
+
"@scalar/use-hooks": "0.4.10",
|
|
323
|
+
"@scalar/types": "0.18.2",
|
|
324
|
+
"@scalar/use-toasts": "0.10.5",
|
|
325
|
+
"@scalar/workspace-store": "0.58.1"
|
|
326
326
|
},
|
|
327
327
|
"devDependencies": {
|
|
328
328
|
"@tailwindcss/cli": "^4.3.3",
|
|
329
329
|
"@tailwindcss/vite": "^4.3.3",
|
|
330
330
|
"@vitejs/plugin-vue": "^6.0.8",
|
|
331
331
|
"@vue/test-utils": "2.4.11",
|
|
332
|
-
"fake-indexeddb": "6.2.
|
|
332
|
+
"fake-indexeddb": "6.2.5",
|
|
333
333
|
"jsdom": "27.4.0",
|
|
334
334
|
"posthog-js": "1.407.5",
|
|
335
335
|
"tailwindcss": "^4.3.3",
|