@scalar/api-client 3.15.0 → 3.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/style.css +2 -2
  3. package/dist/v2/blocks/operation-block/OperationBlock.vue.d.ts.map +1 -1
  4. package/dist/v2/blocks/operation-block/OperationBlock.vue.js.map +1 -1
  5. package/dist/v2/blocks/operation-block/OperationBlock.vue.script.js +34 -4
  6. package/dist/v2/blocks/operation-block/OperationBlock.vue.script.js.map +1 -1
  7. package/dist/v2/blocks/operation-block/helpers/persist-script-environment.d.ts +53 -0
  8. package/dist/v2/blocks/operation-block/helpers/persist-script-environment.d.ts.map +1 -0
  9. package/dist/v2/blocks/operation-block/helpers/persist-script-environment.js +91 -0
  10. package/dist/v2/blocks/operation-block/helpers/persist-script-environment.js.map +1 -0
  11. package/dist/v2/blocks/request-block/RequestBlock.vue.script.js.map +1 -1
  12. package/dist/v2/blocks/response-block/components/ResponseBodyPreview.vue.d.ts.map +1 -1
  13. package/dist/v2/blocks/response-block/components/ResponseBodyPreview.vue.js +1 -1
  14. package/dist/v2/blocks/response-block/components/ResponseBodyPreview.vue.js.map +1 -1
  15. package/dist/v2/blocks/response-block/components/ResponseBodyPreview.vue.script.js +9 -2
  16. package/dist/v2/blocks/response-block/components/ResponseBodyPreview.vue.script.js.map +1 -1
  17. package/dist/v2/blocks/response-block/helpers/media-types.d.ts +1 -1
  18. package/dist/v2/blocks/response-block/helpers/media-types.d.ts.map +1 -1
  19. package/dist/v2/blocks/response-block/helpers/media-types.js +12 -0
  20. package/dist/v2/blocks/response-block/helpers/media-types.js.map +1 -1
  21. package/dist/v2/blocks/response-block/helpers/prettify-ndjson.d.ts +12 -0
  22. package/dist/v2/blocks/response-block/helpers/prettify-ndjson.d.ts.map +1 -0
  23. package/dist/v2/blocks/response-block/helpers/prettify-ndjson.js +19 -0
  24. package/dist/v2/blocks/response-block/helpers/prettify-ndjson.js.map +1 -0
  25. package/dist/v2/blocks/scalar-auth-selector-block/components/AuthSelector.vue.script.js.map +1 -1
  26. package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue.d.ts.map +1 -1
  27. package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue.js.map +1 -1
  28. package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue.script.js +23 -16
  29. package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue.script.js.map +1 -1
  30. package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth-flows.d.ts +20 -0
  31. package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth-flows.d.ts.map +1 -0
  32. package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth-flows.js +27 -0
  33. package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth-flows.js.map +1 -0
  34. package/dist/v2/blocks/scalar-auth-selector-block/helpers/security-scheme.d.ts.map +1 -1
  35. package/dist/v2/blocks/scalar-auth-selector-block/helpers/security-scheme.js +15 -6
  36. package/dist/v2/blocks/scalar-auth-selector-block/helpers/security-scheme.js.map +1 -1
  37. package/dist/v2/constants.js +1 -1
  38. package/dist/vue-styles.css +2 -2
  39. package/package.json +8 -8
@@ -1 +1 @@
1
- {"version":3,"file":"RequestBlock.vue.script.js","names":[],"sources":["../../../../src/v2/blocks/request-block/RequestBlock.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ClientOptionGroup } from '@scalar/blocks/code-example'\nimport { ScalarErrorBoundary } from '@scalar/components/error-boundary'\nimport { canMethodHaveBody } from '@scalar/helpers/http/can-method-have-body'\nimport type { HttpMethod } from '@scalar/helpers/http/http-methods'\nimport { REGEX } from '@scalar/helpers/regex/regex-helpers'\nimport { replaceEnvVariables } from '@scalar/helpers/regex/replace-variables'\nimport type { ClientPlugin } from '@scalar/oas-utils/helpers'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\nimport type { SelectedSecurity } from '@scalar/workspace-store/entities/auth'\nimport type {\n ApiReferenceEvents,\n AuthMeta,\n WorkspaceEventBus,\n} from '@scalar/workspace-store/events'\nimport { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport { unpackProxyObject } from '@scalar/workspace-store/helpers/unpack-proxy'\nimport {\n filterGlobalCookie,\n getEnvironmentVariables,\n getResolvedUrl,\n type MergedSecuritySchemes,\n type SecuritySchemeObjectSecret,\n} from '@scalar/workspace-store/request-example'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport type { XScalarCookie } from '@scalar/workspace-store/schemas/extensions/general/x-scalar-cookies'\nimport type {\n OpenApiDocument,\n OperationObject,\n ServerObject,\n} from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport { computed, ref, useId, watch } from 'vue'\n\nimport SectionFilter from '@/components/SectionFilter.vue'\nimport ViewLayoutSection from '@/components/ViewLayout/ViewLayoutSection.vue'\nimport RequestBody from '@/v2/blocks/request-block/components/RequestBody.vue'\nimport RequestCodeSnippet from '@/v2/blocks/request-block/components/RequestCodeSnippet.vue'\nimport RequestParams from '@/v2/blocks/request-block/components/RequestParams.vue'\nimport type { TableRow } from '@/v2/blocks/request-block/components/RequestTableRow.vue'\nimport { createParameterHandlers } from '@/v2/blocks/request-block/helpers/create-parameter-handlers'\nimport { createParameterRows } from '@/v2/blocks/request-block/helpers/create-parameter-rows'\nimport { groupBy } from '@/v2/blocks/request-block/helpers/group-by'\nimport { groupGlobalCookies } from '@/v2/blocks/request-block/helpers/group-global-cookies'\nimport { AuthSelector } from '@/v2/blocks/scalar-auth-selector-block'\nimport type { OAuth2Options } from '@/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue'\nimport type { ClientLayout } from '@/v2/types/layout'\n\ntype Filter =\n | 'All'\n | 'Auth'\n | 'Variables'\n | 'Cookies'\n | 'Headers'\n | 'Query'\n | 'Body'\n\nexport type RequestBlockProps = {\n authMeta: AuthMeta\n clientOptions: ClientOptionGroup[]\n environment: XScalarEnvironment\n eventBus: WorkspaceEventBus\n exampleKey: string\n workspaceCookies: XScalarCookie[]\n documentCookies: XScalarCookie[]\n layout: ClientLayout\n method: HttpMethod\n operation: OperationObject\n path: string\n plugins: ClientPlugin[]\n proxyUrl: string\n securityRequirements: OpenApiDocument['security']\n securitySchemes: MergedSecuritySchemes\n requestBodyCompositionSelection?: Record<string, number>\n selectedClient: WorkspaceStore['workspace']['x-scalar-default-client']\n selectedSecurity: SelectedSecurity\n selectedSecuritySchemes: SecuritySchemeObjectSecret[]\n server: ServerObject | null\n defaultHeaders: Record<string, string>\n /** Any config options required for the OAuth2 flow */\n options?: OAuth2Options\n}\n\nconst {\n authMeta = { type: 'document' },\n clientOptions,\n environment,\n eventBus,\n exampleKey,\n workspaceCookies,\n documentCookies,\n layout,\n method,\n operation,\n path,\n plugins,\n proxyUrl,\n requestBodyCompositionSelection,\n securityRequirements,\n securitySchemes,\n selectedClient,\n selectedSecurity,\n selectedSecuritySchemes,\n server,\n defaultHeaders: autoGeneratedHeaders,\n} = defineProps<RequestBlockProps>()\n\n/** Operation metadata used across event emissions */\nconst meta = computed(() => ({\n method,\n path,\n exampleKey,\n}))\n\nconst deletedExpandedParameterPaths = ref<Record<string, string[][]>>({})\n\n/** Renamed expanded rows, tracked as old-schema-path -> typed-value-path per parameter. */\nconst renamedExpandedParameterPaths = ref<\n Record<string, { from: string[]; to: string[] }[]>\n>({})\n\nconst getExpandedParameterKey = (parameter: {\n in: string\n name: string\n}): string => `${parameter.in}:${parameter.name}`\n\nconst getHiddenValuePaths = (parameter: {\n in: string\n name: string\n}): string[][] =>\n deletedExpandedParameterPaths.value[getExpandedParameterKey(parameter)] ?? []\n\nconst getRenamedValuePaths = (parameter: {\n in: string\n name: string\n}): { from: string[]; to: string[] }[] =>\n renamedExpandedParameterPaths.value[getExpandedParameterKey(parameter)] ?? []\n\nconst pathsEqual = (a: string[], b: string[]): boolean =>\n a.length === b.length && a.every((segment, index) => segment === b[index])\n\n/**\n * Hides the schema path of an expanded row so it does not reappear as an empty suggestion. Used\n * both when a row is deleted and when its key is renamed (the old key should not pop back up).\n */\nconst hideExpandedRowPath = (row: TableRow): void => {\n if (!row.originalParameter || !row.sourceParameterValuePath) {\n return\n }\n\n const key = getExpandedParameterKey(row.originalParameter)\n deletedExpandedParameterPaths.value = {\n ...deletedExpandedParameterPaths.value,\n [key]: [\n ...(deletedExpandedParameterPaths.value[key] ?? []),\n row.sourceParameterValuePath,\n ],\n }\n}\n\n/**\n * Records that an expanded row was renamed from its current value path to the typed one, so the\n * read side can render the renamed key in the original property's slot instead of appending it to\n * the end of the table. Repeated renames of the same row stay anchored to the original schema path.\n */\nconst recordExpandedRowRename = (\n row: TableRow,\n newValuePath: string[],\n): void => {\n if (!row.originalParameter || !row.sourceParameterValuePath) {\n return\n }\n\n const from = row.sourceParameterValuePath\n const key = getExpandedParameterKey(row.originalParameter)\n const existing = renamedExpandedParameterPaths.value[key] ?? []\n\n // If this row was already renamed, the row's current path is the previous target. Re-anchor that\n // entry to the new target so a second rename does not create an orphaned mapping.\n const chained = existing.find((entry) => pathsEqual(entry.to, from))\n const next = chained\n ? existing.map((entry) =>\n entry === chained ? { from: entry.from, to: newValuePath } : entry,\n )\n : [...existing, { from, to: newValuePath }]\n\n renamedExpandedParameterPaths.value = {\n ...renamedExpandedParameterPaths.value,\n [key]: next,\n }\n}\n\n/** Parameters grouped by type (path, query, header, cookie) */\nconst sections = computed(() =>\n groupBy(\n operation.parameters\n ?.map((param) => getResolvedRef(param))\n .flatMap((param) =>\n createParameterRows(param, exampleKey, {\n hiddenValuePaths:\n param.in === 'query' ? getHiddenValuePaths(param) : [],\n renamedValuePaths:\n param.in === 'query' ? getRenamedValuePaths(param) : [],\n }).map((row) => ({\n ...row,\n in: param.in,\n })),\n ) ?? [],\n 'in',\n ({ in: _in, ...row }) => {\n return row as TableRow\n },\n ),\n)\n\n// Generate a reverse map for fast lookup of headers by the name\nconst headersMap = computed(() =>\n groupBy(\n sections.value.header?.map((it) => ({\n ...it,\n name: it.name.toLowerCase(),\n })) ?? [],\n 'name',\n ),\n)\n\nconst defaultHeaders = computed(() => {\n const disableParameters =\n operation['x-scalar-disable-parameters']?.['default-headers']?.[\n exampleKey\n ] ?? {}\n\n const isOverridden = (name: string) => {\n const header = headersMap.value[name.toLowerCase()]?.[0]\n\n if (!header) {\n return false\n }\n\n return !header.isDisabled\n }\n\n return Object.entries(autoGeneratedHeaders).map(([name, value]) => {\n return {\n name,\n value,\n schema: undefined,\n isOverridden: isOverridden(name),\n isReadonly: true,\n isDisabled: disableParameters[name.toLowerCase()] ?? false,\n } satisfies TableRow\n })\n})\n\nconst headers = computed(() => [\n ...defaultHeaders.value,\n ...(sections.value.header ?? []),\n])\n\n/** Resolved request URL, used to filter global cookies by their domain and path. */\nconst requestCookieUrl = computed(() => {\n const environmentVariables = getEnvironmentVariables(environment)\n const resolvedUrl = getResolvedUrl({ server, path })\n return replaceEnvVariables(resolvedUrl, environmentVariables)\n})\n\n/**\n * Global cookies grouped by name. Same-named cookies collapse into a single logical cookie so\n * duplicate names no longer share one disabled state (which made toggling one toggle them all).\n * A name with multiple values becomes a preset the user can switch between.\n */\nconst globalCookieGroups = computed(() =>\n groupGlobalCookies({\n sources: [\n { location: 'workspace', cookies: workspaceCookies },\n { location: 'document', cookies: documentCookies },\n ],\n // Keep domain/path filtering but ignore the disabled flag, so a disabled preset value stays\n // selectable in the switcher (it is only hidden from the request, not from the dropdown).\n shouldInclude: (cookie) =>\n filterGlobalCookie({\n cookie: { ...cookie, isDisabled: false },\n url: requestCookieUrl.value,\n disabledGlobalCookies: {},\n }),\n }),\n)\n\nconst defaultCookies = computed<TableRow[]>(() => {\n const disabledGlobalCookies =\n operation['x-scalar-disable-parameters']?.['global-cookies']?.[\n exampleKey\n ] ?? {}\n\n return globalCookieGroups.value.map((group) => ({\n name: group.name,\n value: group.selectedValue,\n globalRoute: { page: group.location, path: 'cookies' } as const,\n isReadonly: true,\n isDisabled: disabledGlobalCookies[group.name.toLowerCase()] ?? false,\n presetOptions: group.isPreset ? group.options : undefined,\n }))\n})\n\n/**\n * Switch a grouped global cookie preset to the chosen value by enabling the matching sibling and\n * disabling the rest. Selection is written back to the source `x-scalar-cookies` list so it\n * persists, and the send path drops disabled cookies, so only the selected value is sent.\n */\nconst handleSelectCookiePreset = (index: number, value: string): void => {\n const group = globalCookieGroups.value[index]\n if (!group) {\n return\n }\n\n for (const sibling of group.siblings) {\n eventBus.emit('cookie:upsert:cookie', {\n collectionType: sibling.location,\n index: sibling.index,\n payload: { isDisabled: sibling.value !== value },\n })\n }\n}\n\nconst cookies = computed(() => [\n ...(defaultCookies.value ?? []),\n ...(sections.value.cookie ?? []),\n])\n\n/** Currently selected filter for the request sections */\nconst selectedFilter = ref<Filter>('All')\n\n/** Available operation sections */\nconst OPERATION_SECTIONS: readonly Filter[] = [\n 'Auth',\n 'Variables',\n 'Cookies',\n 'Headers',\n 'Query',\n 'Body',\n] as const\n\n/**\n * Pre-generated stable IDs for all possible filter sections.\n * These are created once at setup time to avoid regenerating IDs on re-render.\n */\nconst sectionIds: Record<Filter, string> = {\n All: useId(),\n Auth: useId(),\n Variables: useId(),\n Cookies: useId(),\n Headers: useId(),\n Query: useId(),\n Body: useId(),\n}\n\n/** Filters available based on operation state */\nconst filters = computed<Filter[]>(() => {\n const availableFilters = new Set<Filter>(['All', ...OPERATION_SECTIONS])\n\n if (!sections.value.path?.length) {\n availableFilters.delete('Variables')\n }\n if (!canMethodHaveBody(method)) {\n availableFilters.delete('Body')\n }\n if (isAuthHidden.value) {\n availableFilters.delete('Auth')\n }\n\n return [...availableFilters]\n})\n\n/**\n * Map available filters to their pre-generated stable IDs.\n * Only includes IDs for filters that are currently available.\n */\nconst filterIds = computed(\n () =>\n Object.fromEntries(\n filters.value.map((section) => [section, sectionIds[section]]),\n ) as Record<Filter, string>,\n)\n\n/**\n * Hide auth selector in readonly mode when no security schemes are defined.\n * This keeps the UI clean when there are no authentication options available.\n */\nconst isAuthHidden = computed(\n () => layout === 'modal' && !Object.keys(securitySchemes ?? {}).length,\n)\n\n/**\n * Keep auth available for unauthenticated operations, but collapse it by default\n * in readonly modal layouts unless a requirement or manual selection exists.\n */\nconst isAuthDefaultOpen = computed(\n () =>\n layout !== 'modal' ||\n Boolean(\n securityRequirements?.length || selectedSecurity.selectedSchemes.length,\n ),\n)\n\n/** Get a sensible placeholder for the request name input */\nconst requestNamePlaceholder = computed(() => {\n if (operation.summary) {\n return operation.summary\n }\n const cleanPath = path.replace(REGEX.PROTOCOL, '')\n return cleanPath || 'Request Name'\n})\n\n/** Check if the section should be shown based on the selected filter */\nconst isSectionVisible = (section: Filter): boolean => {\n return selectedFilter.value === 'All' || selectedFilter.value === section\n}\n\n/**\n * Reset filter to 'All' if Body filter is selected but method changes to one that cannot have a body.\n * This prevents showing an empty Body section when switching methods.\n */\nwatch(\n () => method,\n (newMethod) => {\n if (selectedFilter.value === 'Body' && !canMethodHaveBody(newMethod)) {\n selectedFilter.value = 'All'\n }\n },\n)\n\n// Expanded-row bookkeeping is keyed by `in:name`, which is not unique across operations or\n// examples. Reset both maps when the operation or example changes so stale delete/rename mappings\n// do not leak onto another request that happens to share a query parameter name.\nwatch(\n () => [method, path, exampleKey],\n () => {\n deletedExpandedParameterPaths.value = {}\n renamedExpandedParameterPaths.value = {}\n },\n)\n\n/** Handle operation summary updates */\nconst handleSummaryUpdate = (event: Event): void => {\n const summary = (event.target as HTMLInputElement).value\n eventBus.emit('operation:update:meta', {\n meta: meta.value,\n payload: { summary: summary.trim() },\n })\n}\n\n/** Parameter handlers */\nconst parameterHandlers = computed(() => ({\n path: createParameterHandlers('path', eventBus, meta.value, {\n context: sections.value.path ?? [],\n }),\n cookie: {\n ...createParameterHandlers('cookie', eventBus, meta.value, {\n context: cookies.value ?? [],\n globalParameters: defaultCookies.value.length,\n }),\n selectPreset: handleSelectCookiePreset,\n },\n header: createParameterHandlers('header', eventBus, meta.value, {\n context: headers.value,\n defaultParameters: defaultHeaders.value.length,\n }),\n query: createParameterHandlers('query', eventBus, meta.value, {\n context: sections.value.query ?? [],\n onDeleteExpandedRow: hideExpandedRowPath,\n onRenameExpandedRow: recordExpandedRowRename,\n }),\n}))\n\n/** Handle request body content type update */\nconst handleUpdateContentType = (payload: { value: string }): void =>\n eventBus.emit('operation:update:requestBody:contentType', {\n payload: { contentType: payload.value },\n meta: meta.value,\n })\n\n/** Handle request body value update */\nconst handleUpdateBodyValue = ({\n payload,\n contentType,\n}: Pick<\n ApiReferenceEvents['operation:update:requestBody:value'],\n 'payload' | 'contentType'\n>): void => {\n const debounceKey =\n typeof payload === 'string'\n ? `update:requestBody:value-${contentType}`\n : undefined\n\n eventBus.emit(\n 'operation:update:requestBody:value',\n {\n payload,\n contentType,\n meta: meta.value,\n },\n {\n debounceKey,\n },\n )\n}\n\n/** Handle request body value update */\nconst handleUpdateBodyFormValue = ({\n payload,\n contentType,\n}: Pick<\n ApiReferenceEvents['operation:update:requestBody:formValue'],\n 'payload' | 'contentType'\n>): void => {\n const debounceKey = `update:requestBody:${contentType}-form-value`\n\n eventBus.emit(\n 'operation:update:requestBody:formValue',\n {\n payload: payload.map((row) => unpackProxyObject(row, { depth: 1 })),\n contentType,\n meta: meta.value,\n },\n {\n debounceKey,\n },\n )\n}\n\nconst labelRequestNameId = useId()\n\nconst globalCookies = computed(() => [...workspaceCookies, ...documentCookies])\n\n/** Allow updating the operation extensions for the plugins */\nconst updateOperationExtension = (\n payload: ApiReferenceEvents['operation:update:extension']['payload'],\n): void =>\n eventBus.emit('operation:update:extension', { payload, meta: meta.value })\n</script>\n<template>\n <ViewLayoutSection :aria-label=\"`Request: ${operation.summary}`\">\n <template #title>\n <div\n class=\"group pointer-events-none flex flex-1 items-center gap-1 lg:pr-24\">\n <label\n v-if=\"layout !== 'modal'\"\n class=\"pointer-events-auto absolute top-0 left-0 h-full w-full cursor-text opacity-0\"\n :for=\"labelRequestNameId\" />\n <input\n v-if=\"layout !== 'modal'\"\n :id=\"labelRequestNameId\"\n class=\"text-c-1 group-hover-input pointer-events-auto relative z-10 -ml-0.5 h-8 w-full rounded pl-1.25 has-[:focus-visible]:outline md:-ml-1.25\"\n :placeholder=\"requestNamePlaceholder\"\n :value=\"operation.summary\"\n @blur=\"handleSummaryUpdate\" />\n <span\n v-else\n class=\"text-c-1 flex h-8 items-center\">\n {{ operation.summary }}\n </span>\n </div>\n <SectionFilter\n v-model=\"selectedFilter\"\n :filterIds=\"filterIds\"\n :filters=\"filters\" />\n </template>\n\n <div\n :id=\"filterIds.All\"\n class=\"request-section-content custom-scroll relative flex flex-1 flex-col\"\n :role=\"selectedFilter === 'All' ? 'tabpanel' : 'none'\">\n <!-- Auth Selector -->\n <AuthSelector\n v-show=\"isSectionVisible('Auth') && !isAuthHidden\"\n :id=\"filterIds.Auth\"\n :createAnySecurityScheme=\"layout !== 'modal'\"\n :defaultOpen=\"isAuthDefaultOpen\"\n :environment\n :eventBus\n :meta=\"authMeta\"\n :options\n :proxyUrl\n :securityRequirements\n :securitySchemes\n :selectedSecurity\n :selectedSecuritySchemes\n :server\n title=\"Authentication\" />\n\n <!-- Variables (Path Parameters) -->\n <RequestParams\n v-show=\"isSectionVisible('Variables') && sections.path?.length\"\n :id=\"filterIds.Variables\"\n :environment\n :eventBus\n :exampleKey\n :rows=\"sections.path ?? []\"\n :showAddRowPlaceholder=\"false\"\n title=\"Variables\"\n v-on=\"parameterHandlers.path\" />\n\n <!-- Cookies -->\n <RequestParams\n v-show=\"isSectionVisible('Cookies')\"\n :id=\"filterIds.Cookies\"\n :environment\n :eventBus\n :exampleKey\n :rows=\"cookies ?? []\"\n :showAddRowPlaceholder=\"true\"\n title=\"Cookies\"\n v-on=\"parameterHandlers.cookie\" />\n\n <!-- Headers -->\n <RequestParams\n v-show=\"isSectionVisible('Headers')\"\n :id=\"filterIds.Headers\"\n :environment\n :eventBus\n :exampleKey\n :rows=\"headers ?? []\"\n title=\"Headers\"\n v-on=\"parameterHandlers.header\" />\n\n <!-- Query Parameters -->\n <RequestParams\n v-show=\"isSectionVisible('Query')\"\n :id=\"filterIds.Query\"\n :environment\n :eventBus\n :exampleKey\n :rows=\"sections.query ?? []\"\n title=\"Query Parameters\"\n v-on=\"parameterHandlers.query\" />\n\n <!-- Request Body -->\n <RequestBody\n v-show=\"isSectionVisible('Body') && canMethodHaveBody(method)\"\n :id=\"filterIds.Body\"\n :environment\n :exampleKey\n :requestBody=\"getResolvedRef(operation.requestBody)\"\n :requestBodyCompositionSelection\n title=\"Request Body\"\n @update:contentType=\"handleUpdateContentType\"\n @update:formValue=\"handleUpdateBodyFormValue\"\n @update:value=\"handleUpdateBodyValue\" />\n\n <!-- Inject request section plugin components -->\n <ScalarErrorBoundary\n v-for=\"(plugin, index) in plugins\"\n :key=\"index\">\n <component\n :is=\"plugin.components.request.component\"\n v-if=\"plugin?.components?.request\"\n v-show=\"selectedFilter === 'All'\"\n :operation\n v-bind=\"plugin.components.request.additionalProps\"\n @operation:update:extension=\"updateOperationExtension\" />\n </ScalarErrorBoundary>\n\n <!-- Spacer -->\n <div class=\"flex grow\" />\n <!-- Code Snippet -->\n <RequestCodeSnippet\n v-show=\"selectedFilter === 'All'\"\n :clientOptions\n :eventBus\n :globalCookies\n integration=\"client\"\n :method\n :operation\n :path\n :securitySchemes=\"selectedSecuritySchemes\"\n :selectedClient\n :selectedContentType=\"\n getResolvedRef(operation.requestBody)?.[\n 'x-scalar-selected-content-type'\n ]?.[exampleKey]\n \"\n :selectedServer=\"server ?? undefined\" />\n </div>\n </ViewLayoutSection>\n</template>\n<style scoped>\n.request-section-content {\n --scalar-border-width: 0.5px;\n}\n.request-section-content-filter {\n box-shadow: 0 -10px 0 10px var(--scalar-background-1);\n}\n.request-item:focus-within .request-meta-buttons {\n opacity: 1;\n}\n.group-hover-input {\n border-width: var(--scalar-border-width);\n border-color: transparent;\n}\n.group:hover .group-hover-input {\n background: color-mix(\n in srgb,\n var(--scalar-background-1),\n var(--scalar-background-2)\n );\n border-color: var(--scalar-border-color);\n}\n.group-hover-input:focus {\n background: transparent !important;\n border-color: var(--scalar-border-color) !important;\n}\n</style>\n"],"mappings":"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"}
1
+ {"version":3,"file":"RequestBlock.vue.script.js","names":[],"sources":["../../../../src/v2/blocks/request-block/RequestBlock.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ClientOptionGroup } from '@scalar/blocks/code-example'\nimport { ScalarErrorBoundary } from '@scalar/components/error-boundary'\nimport { canMethodHaveBody } from '@scalar/helpers/http/can-method-have-body'\nimport type { HttpMethod } from '@scalar/helpers/http/http-methods'\nimport { REGEX } from '@scalar/helpers/regex/regex-helpers'\nimport { replaceEnvVariables } from '@scalar/helpers/regex/replace-variables'\nimport type { ClientPlugin } from '@scalar/oas-utils/helpers'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\nimport type { SelectedSecurity } from '@scalar/workspace-store/entities/auth'\nimport type {\n ApiReferenceEvents,\n AuthMeta,\n WorkspaceEventBus,\n} from '@scalar/workspace-store/events'\nimport { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport { unpackProxyObject } from '@scalar/workspace-store/helpers/unpack-proxy'\nimport {\n filterGlobalCookie,\n getEnvironmentVariables,\n getResolvedUrl,\n type MergedSecuritySchemes,\n type SecuritySchemeObjectSecret,\n} from '@scalar/workspace-store/request-example'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport type { XScalarCookie } from '@scalar/workspace-store/schemas/extensions/general/x-scalar-cookies'\nimport type {\n OpenApiDocument,\n OperationObject,\n ServerObject,\n} from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport { computed, ref, useId, watch } from 'vue'\n\nimport SectionFilter from '@/components/SectionFilter.vue'\nimport ViewLayoutSection from '@/components/ViewLayout/ViewLayoutSection.vue'\nimport RequestBody from '@/v2/blocks/request-block/components/RequestBody.vue'\nimport RequestCodeSnippet from '@/v2/blocks/request-block/components/RequestCodeSnippet.vue'\nimport RequestParams from '@/v2/blocks/request-block/components/RequestParams.vue'\nimport type { TableRow } from '@/v2/blocks/request-block/components/RequestTableRow.vue'\nimport { createParameterHandlers } from '@/v2/blocks/request-block/helpers/create-parameter-handlers'\nimport { createParameterRows } from '@/v2/blocks/request-block/helpers/create-parameter-rows'\nimport { groupBy } from '@/v2/blocks/request-block/helpers/group-by'\nimport { groupGlobalCookies } from '@/v2/blocks/request-block/helpers/group-global-cookies'\nimport { AuthSelector } from '@/v2/blocks/scalar-auth-selector-block'\nimport type { OAuth2Options } from '@/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue'\nimport type { ClientLayout } from '@/v2/types/layout'\n\ntype Filter =\n | 'All'\n | 'Auth'\n | 'Variables'\n | 'Cookies'\n | 'Headers'\n | 'Query'\n | 'Body'\n\nexport type RequestBlockProps = {\n authMeta: AuthMeta\n clientOptions: ClientOptionGroup[]\n environment: XScalarEnvironment\n eventBus: WorkspaceEventBus\n exampleKey: string\n workspaceCookies: XScalarCookie[]\n documentCookies: XScalarCookie[]\n layout: ClientLayout\n method: HttpMethod\n operation: OperationObject\n path: string\n plugins: ClientPlugin[]\n proxyUrl: string\n securityRequirements: OpenApiDocument['security']\n securitySchemes: MergedSecuritySchemes\n requestBodyCompositionSelection?: Record<string, number>\n selectedClient: WorkspaceStore['workspace']['x-scalar-default-client']\n selectedSecurity: SelectedSecurity\n selectedSecuritySchemes: SecuritySchemeObjectSecret[]\n server: ServerObject | null\n defaultHeaders: Record<string, string>\n /** Any config options required for the OAuth2 flow */\n options?: OAuth2Options\n}\n\nconst {\n authMeta = { type: 'document' },\n clientOptions,\n environment,\n eventBus,\n exampleKey,\n workspaceCookies,\n documentCookies,\n layout,\n method,\n operation,\n path,\n plugins,\n proxyUrl,\n requestBodyCompositionSelection,\n securityRequirements,\n securitySchemes,\n selectedClient,\n selectedSecurity,\n selectedSecuritySchemes,\n server,\n defaultHeaders: autoGeneratedHeaders,\n} = defineProps<RequestBlockProps>()\n\n/** Operation metadata used across event emissions */\nconst meta = computed(() => ({\n method,\n path,\n exampleKey,\n}))\n\nconst deletedExpandedParameterPaths = ref<Record<string, string[][]>>({})\n\n/** Renamed expanded rows, tracked as old-schema-path -> typed-value-path per parameter. */\nconst renamedExpandedParameterPaths = ref<\n Record<string, { from: string[]; to: string[] }[]>\n>({})\n\nconst getExpandedParameterKey = (parameter: {\n in: string\n name: string\n}): string => `${parameter.in}:${parameter.name}`\n\nconst getHiddenValuePaths = (parameter: {\n in: string\n name: string\n}): string[][] =>\n deletedExpandedParameterPaths.value[getExpandedParameterKey(parameter)] ?? []\n\nconst getRenamedValuePaths = (parameter: {\n in: string\n name: string\n}): { from: string[]; to: string[] }[] =>\n renamedExpandedParameterPaths.value[getExpandedParameterKey(parameter)] ?? []\n\nconst pathsEqual = (a: string[], b: string[]): boolean =>\n a.length === b.length && a.every((segment, index) => segment === b[index])\n\n/**\n * Hides the schema path of an expanded row so it does not reappear as an empty suggestion. Used\n * both when a row is deleted and when its key is renamed (the old key should not pop back up).\n */\nconst hideExpandedRowPath = (row: TableRow): void => {\n if (!row.originalParameter || !row.sourceParameterValuePath) {\n return\n }\n\n const key = getExpandedParameterKey(row.originalParameter)\n deletedExpandedParameterPaths.value = {\n ...deletedExpandedParameterPaths.value,\n [key]: [\n ...(deletedExpandedParameterPaths.value[key] ?? []),\n row.sourceParameterValuePath,\n ],\n }\n}\n\n/**\n * Records that an expanded row was renamed from its current value path to the typed one, so the\n * read side can render the renamed key in the original property's slot instead of appending it to\n * the end of the table. Repeated renames of the same row stay anchored to the original schema path.\n */\nconst recordExpandedRowRename = (\n row: TableRow,\n newValuePath: string[],\n): void => {\n if (!row.originalParameter || !row.sourceParameterValuePath) {\n return\n }\n\n const from = row.sourceParameterValuePath\n const key = getExpandedParameterKey(row.originalParameter)\n const existing = renamedExpandedParameterPaths.value[key] ?? []\n\n // If this row was already renamed, the row's current path is the previous target. Re-anchor that\n // entry to the new target so a second rename does not create an orphaned mapping.\n const chained = existing.find((entry) => pathsEqual(entry.to, from))\n const next = chained\n ? existing.map((entry) =>\n entry === chained ? { from: entry.from, to: newValuePath } : entry,\n )\n : [...existing, { from, to: newValuePath }]\n\n renamedExpandedParameterPaths.value = {\n ...renamedExpandedParameterPaths.value,\n [key]: next,\n }\n}\n\n/** Parameters grouped by type (path, query, header, cookie) */\nconst sections = computed(() =>\n groupBy(\n operation.parameters\n ?.map((param) => getResolvedRef(param))\n .flatMap((param) =>\n createParameterRows(param, exampleKey, {\n hiddenValuePaths:\n param.in === 'query' ? getHiddenValuePaths(param) : [],\n renamedValuePaths:\n param.in === 'query' ? getRenamedValuePaths(param) : [],\n }).map((row) => ({\n ...row,\n in: param.in,\n })),\n ) ?? [],\n 'in',\n ({ in: _in, ...row }) => {\n return row as TableRow\n },\n ),\n)\n\n// Generate a reverse map for fast lookup of headers by the name\nconst headersMap = computed(() =>\n groupBy(\n sections.value.header?.map((it) => ({\n ...it,\n name: it.name.toLowerCase(),\n })) ?? [],\n 'name',\n ),\n)\n\nconst defaultHeaders = computed(() => {\n const disableParameters =\n operation['x-scalar-disable-parameters']?.['default-headers']?.[\n exampleKey\n ] ?? {}\n\n const isOverridden = (name: string) => {\n const header = headersMap.value[name.toLowerCase()]?.[0]\n\n if (!header) {\n return false\n }\n\n return !header.isDisabled\n }\n\n return Object.entries(autoGeneratedHeaders).map(([name, value]) => {\n return {\n name,\n value,\n schema: undefined,\n isOverridden: isOverridden(name),\n isReadonly: true,\n isDisabled: disableParameters[name.toLowerCase()] ?? false,\n } satisfies TableRow\n })\n})\n\nconst headers = computed(() => [\n ...defaultHeaders.value,\n ...(sections.value.header ?? []),\n])\n\n/** Resolved request URL, used to filter global cookies by their domain and path. */\nconst requestCookieUrl = computed(() => {\n const environmentVariables = getEnvironmentVariables(environment)\n const resolvedUrl = getResolvedUrl({ server, path })\n return replaceEnvVariables(resolvedUrl, environmentVariables)\n})\n\n/**\n * Global cookies grouped by name. Same-named cookies collapse into a single logical cookie so\n * duplicate names no longer share one disabled state (which made toggling one toggle them all).\n * A name with multiple values becomes a preset the user can switch between.\n */\nconst globalCookieGroups = computed(() =>\n groupGlobalCookies({\n sources: [\n { location: 'workspace', cookies: workspaceCookies },\n { location: 'document', cookies: documentCookies },\n ],\n // Keep domain/path filtering but ignore the disabled flag, so a disabled preset value stays\n // selectable in the switcher (it is only hidden from the request, not from the dropdown).\n shouldInclude: (cookie) =>\n filterGlobalCookie({\n cookie: { ...cookie, isDisabled: false },\n url: requestCookieUrl.value,\n disabledGlobalCookies: {},\n }),\n }),\n)\n\nconst defaultCookies = computed<TableRow[]>(() => {\n const disabledGlobalCookies =\n operation['x-scalar-disable-parameters']?.['global-cookies']?.[\n exampleKey\n ] ?? {}\n\n return globalCookieGroups.value.map((group) => ({\n name: group.name,\n value: group.selectedValue,\n globalRoute: { page: group.location, path: 'cookies' } as const,\n isReadonly: true,\n isDisabled: disabledGlobalCookies[group.name.toLowerCase()] ?? false,\n presetOptions: group.isPreset ? group.options : undefined,\n }))\n})\n\n/**\n * Switch a grouped global cookie preset to the chosen value by enabling the matching sibling and\n * disabling the rest. Selection is written back to the source `x-scalar-cookies` list so it\n * persists, and the send path drops disabled cookies, so only the selected value is sent.\n */\nconst handleSelectCookiePreset = (index: number, value: string): void => {\n const group = globalCookieGroups.value[index]\n if (!group) {\n return\n }\n\n for (const sibling of group.siblings) {\n eventBus.emit('cookie:upsert:cookie', {\n collectionType: sibling.location,\n index: sibling.index,\n payload: { isDisabled: sibling.value !== value },\n })\n }\n}\n\nconst cookies = computed(() => [\n ...(defaultCookies.value ?? []),\n ...(sections.value.cookie ?? []),\n])\n\n/** Currently selected filter for the request sections */\nconst selectedFilter = ref<Filter>('All')\n\n/** Available operation sections */\nconst OPERATION_SECTIONS: readonly Filter[] = [\n 'Auth',\n 'Variables',\n 'Cookies',\n 'Headers',\n 'Query',\n 'Body',\n] as const\n\n/**\n * Pre-generated stable IDs for all possible filter sections.\n * These are created once at setup time to avoid regenerating IDs on re-render.\n */\nconst sectionIds: Record<Filter, string> = {\n All: useId(),\n Auth: useId(),\n Variables: useId(),\n Cookies: useId(),\n Headers: useId(),\n Query: useId(),\n Body: useId(),\n}\n\n/** Filters available based on operation state */\nconst filters = computed<Filter[]>(() => {\n const availableFilters = new Set<Filter>(['All', ...OPERATION_SECTIONS])\n\n if (!sections.value.path?.length) {\n availableFilters.delete('Variables')\n }\n if (!canMethodHaveBody(method)) {\n availableFilters.delete('Body')\n }\n if (isAuthHidden.value) {\n availableFilters.delete('Auth')\n }\n\n return [...availableFilters]\n})\n\n/**\n * Map available filters to their pre-generated stable IDs.\n * Only includes IDs for filters that are currently available.\n */\nconst filterIds = computed(\n () =>\n Object.fromEntries(\n filters.value.map((section) => [section, sectionIds[section]]),\n ) as Record<Filter, string>,\n)\n\n/**\n * Hide auth selector in readonly mode when no security schemes are defined.\n * This keeps the UI clean when there are no authentication options available.\n */\nconst isAuthHidden = computed(\n () => layout === 'modal' && !Object.keys(securitySchemes ?? {}).length,\n)\n\n/**\n * Keep auth available for unauthenticated operations, but collapse it by default\n * in readonly modal layouts unless a requirement or manual selection exists.\n */\nconst isAuthDefaultOpen = computed(\n () =>\n layout !== 'modal' ||\n Boolean(\n securityRequirements?.length || selectedSecurity.selectedSchemes.length,\n ),\n)\n\n/** Get a sensible placeholder for the request name input */\nconst requestNamePlaceholder = computed(() => {\n if (operation.summary) {\n return operation.summary\n }\n const cleanPath = path.replace(REGEX.PROTOCOL, '')\n return cleanPath || 'Request Name'\n})\n\n/** Check if the section should be shown based on the selected filter */\nconst isSectionVisible = (section: Filter): boolean => {\n return selectedFilter.value === 'All' || selectedFilter.value === section\n}\n\n/**\n * Reset filter to 'All' if Body filter is selected but method changes to one that cannot have a body.\n * This prevents showing an empty Body section when switching methods.\n */\nwatch(\n () => method,\n (newMethod) => {\n if (selectedFilter.value === 'Body' && !canMethodHaveBody(newMethod)) {\n selectedFilter.value = 'All'\n }\n },\n)\n\n// Expanded-row bookkeeping is keyed by `in:name`, which is not unique across operations or\n// examples. Reset both maps when the operation or example changes so stale delete/rename mappings\n// do not leak onto another request that happens to share a query parameter name.\nwatch(\n () => [method, path, exampleKey],\n () => {\n deletedExpandedParameterPaths.value = {}\n renamedExpandedParameterPaths.value = {}\n },\n)\n\n/** Handle operation summary updates */\nconst handleSummaryUpdate = (event: Event): void => {\n const summary = (event.target as HTMLInputElement).value\n eventBus.emit('operation:update:meta', {\n meta: meta.value,\n payload: { summary: summary.trim() },\n })\n}\n\n/** Parameter handlers */\nconst parameterHandlers = computed(() => ({\n path: createParameterHandlers('path', eventBus, meta.value, {\n context: sections.value.path ?? [],\n }),\n cookie: {\n ...createParameterHandlers('cookie', eventBus, meta.value, {\n context: cookies.value ?? [],\n globalParameters: defaultCookies.value.length,\n }),\n selectPreset: handleSelectCookiePreset,\n },\n header: createParameterHandlers('header', eventBus, meta.value, {\n context: headers.value,\n defaultParameters: defaultHeaders.value.length,\n }),\n query: createParameterHandlers('query', eventBus, meta.value, {\n context: sections.value.query ?? [],\n onDeleteExpandedRow: hideExpandedRowPath,\n onRenameExpandedRow: recordExpandedRowRename,\n }),\n}))\n\n/** Handle request body content type update */\nconst handleUpdateContentType = (payload: { value: string }): void =>\n eventBus.emit('operation:update:requestBody:contentType', {\n payload: { contentType: payload.value },\n meta: meta.value,\n })\n\n/** Handle request body value update */\nconst handleUpdateBodyValue = ({\n payload,\n contentType,\n}: Pick<\n ApiReferenceEvents['operation:update:requestBody:value'],\n 'payload' | 'contentType'\n>): void => {\n const debounceKey =\n typeof payload === 'string'\n ? `update:requestBody:value-${contentType}`\n : undefined\n\n eventBus.emit(\n 'operation:update:requestBody:value',\n {\n payload,\n contentType,\n meta: meta.value,\n },\n {\n debounceKey,\n },\n )\n}\n\n/** Handle request body value update */\nconst handleUpdateBodyFormValue = ({\n payload,\n contentType,\n}: Pick<\n ApiReferenceEvents['operation:update:requestBody:formValue'],\n 'payload' | 'contentType'\n>): void => {\n const debounceKey = `update:requestBody:${contentType}-form-value`\n\n eventBus.emit(\n 'operation:update:requestBody:formValue',\n {\n payload: payload.map((row) => unpackProxyObject(row, { depth: 1 })),\n contentType,\n meta: meta.value,\n },\n {\n debounceKey,\n },\n )\n}\n\nconst labelRequestNameId = useId()\n\nconst globalCookies = computed(() => [...workspaceCookies, ...documentCookies])\n\n/** Allow updating the operation extensions for the plugins */\nconst updateOperationExtension = (\n payload: ApiReferenceEvents['operation:update:extension']['payload'],\n): void =>\n eventBus.emit('operation:update:extension', { payload, meta: meta.value })\n</script>\n<template>\n <ViewLayoutSection :aria-label=\"`Request: ${operation.summary}`\">\n <template #title>\n <div\n class=\"group pointer-events-none flex flex-1 items-center gap-1 lg:pr-24\">\n <label\n v-if=\"layout !== 'modal'\"\n class=\"pointer-events-auto absolute top-0 left-0 h-full w-full cursor-text opacity-0\"\n :for=\"labelRequestNameId\" />\n <input\n v-if=\"layout !== 'modal'\"\n :id=\"labelRequestNameId\"\n class=\"text-c-1 group-hover-input pointer-events-auto relative z-10 -ml-0.5 h-8 w-full rounded pl-1.25 has-[:focus-visible]:outline md:-ml-1.25\"\n :placeholder=\"requestNamePlaceholder\"\n :value=\"operation.summary\"\n @blur=\"handleSummaryUpdate\" />\n <span\n v-else\n class=\"text-c-1 flex h-8 items-center\">\n {{ operation.summary }}\n </span>\n </div>\n <SectionFilter\n v-model=\"selectedFilter\"\n :filterIds=\"filterIds\"\n :filters=\"filters\" />\n </template>\n\n <div\n :id=\"filterIds.All\"\n class=\"request-section-content custom-scroll relative flex flex-1 flex-col\"\n :role=\"selectedFilter === 'All' ? 'tabpanel' : 'none'\">\n <!-- Auth Selector -->\n <AuthSelector\n v-show=\"isSectionVisible('Auth') && !isAuthHidden\"\n :id=\"filterIds.Auth\"\n :createAnySecurityScheme=\"layout !== 'modal'\"\n :defaultOpen=\"isAuthDefaultOpen\"\n :environment\n :eventBus\n :meta=\"authMeta\"\n :options\n :proxyUrl\n :securityRequirements\n :securitySchemes\n :selectedSecurity\n :selectedSecuritySchemes\n :server\n title=\"Authentication\" />\n\n <!-- Variables (Path Parameters) -->\n <RequestParams\n v-show=\"isSectionVisible('Variables') && sections.path?.length\"\n :id=\"filterIds.Variables\"\n :environment\n :eventBus\n :exampleKey\n :rows=\"sections.path ?? []\"\n :showAddRowPlaceholder=\"false\"\n title=\"Variables\"\n v-on=\"parameterHandlers.path\" />\n\n <!-- Cookies -->\n <RequestParams\n v-show=\"isSectionVisible('Cookies')\"\n :id=\"filterIds.Cookies\"\n :environment\n :eventBus\n :exampleKey\n :rows=\"cookies ?? []\"\n :showAddRowPlaceholder=\"true\"\n title=\"Cookies\"\n v-on=\"parameterHandlers.cookie\" />\n\n <!-- Headers -->\n <RequestParams\n v-show=\"isSectionVisible('Headers')\"\n :id=\"filterIds.Headers\"\n :environment\n :eventBus\n :exampleKey\n :rows=\"headers ?? []\"\n title=\"Headers\"\n v-on=\"parameterHandlers.header\" />\n\n <!-- Query Parameters -->\n <RequestParams\n v-show=\"isSectionVisible('Query')\"\n :id=\"filterIds.Query\"\n :environment\n :eventBus\n :exampleKey\n :rows=\"sections.query ?? []\"\n title=\"Query Parameters\"\n v-on=\"parameterHandlers.query\" />\n\n <!-- Request Body -->\n <RequestBody\n v-show=\"isSectionVisible('Body') && canMethodHaveBody(method)\"\n :id=\"filterIds.Body\"\n :environment\n :exampleKey\n :requestBody=\"getResolvedRef(operation.requestBody)\"\n :requestBodyCompositionSelection\n title=\"Request Body\"\n @update:contentType=\"handleUpdateContentType\"\n @update:formValue=\"handleUpdateBodyFormValue\"\n @update:value=\"handleUpdateBodyValue\" />\n\n <!-- Inject request section plugin components -->\n <ScalarErrorBoundary\n v-for=\"(plugin, index) in plugins\"\n :key=\"index\">\n <component\n :is=\"plugin.components.request.component\"\n v-if=\"plugin?.components?.request\"\n v-show=\"selectedFilter === 'All'\"\n :operation\n v-bind=\"plugin.components.request.additionalProps\"\n @operation:update:extension=\"updateOperationExtension\" />\n </ScalarErrorBoundary>\n\n <!-- Spacer -->\n <div class=\"flex grow\" />\n <!-- Code Snippet -->\n <RequestCodeSnippet\n v-show=\"selectedFilter === 'All'\"\n :clientOptions\n :eventBus\n :globalCookies\n integration=\"client\"\n :method\n :operation\n :path\n :securitySchemes=\"selectedSecuritySchemes\"\n :selectedClient\n :selectedContentType=\"\n getResolvedRef(operation.requestBody)?.[\n 'x-scalar-selected-content-type'\n ]?.[exampleKey]\n \"\n :selectedServer=\"server ?? undefined\" />\n </div>\n </ViewLayoutSection>\n</template>\n<style scoped>\n.request-section-content {\n --scalar-border-width: 0.5px;\n}\n.request-section-content-filter {\n box-shadow: 0 -10px 0 10px var(--scalar-background-1);\n}\n.request-item:focus-within .request-meta-buttons {\n opacity: 1;\n}\n.group-hover-input {\n border-width: var(--scalar-border-width);\n border-color: transparent;\n}\n.group:hover .group-hover-input {\n background: color-mix(\n in srgb,\n var(--scalar-background-1),\n var(--scalar-background-2)\n );\n border-color: var(--scalar-border-color);\n}\n.group-hover-input:focus {\n background: transparent !important;\n border-color: var(--scalar-border-color) !important;\n}\n</style>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ResponseBodyPreview.vue.d.ts","sourceRoot":"","sources":["../../../../../src/v2/blocks/response-block/components/ResponseBodyPreview.vue"],"names":[],"mappings":"AAsLA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,gDAAgD,CAAA;AAKlF,KAAK,WAAW,GAAG;IACjB,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,YAAY,CAAA;IAClB,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC3B,sGAAsG;IACtG,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB,CAAC;AA+OF,QAAA,MAAM,YAAY,kSAEhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
1
+ {"version":3,"file":"ResponseBodyPreview.vue.d.ts","sourceRoot":"","sources":["../../../../../src/v2/blocks/response-block/components/ResponseBodyPreview.vue"],"names":[],"mappings":"AAgMA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,gDAAgD,CAAA;AAMlF,KAAK,WAAW,GAAG;IACjB,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,YAAY,CAAA;IAClB,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC3B,sGAAsG;IACtG,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB,CAAC;AAuQF,QAAA,MAAM,YAAY,kSAEhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
@@ -2,7 +2,7 @@ import _plugin_vue_export_helper_default from "../../../../_virtual/_plugin-vue_
2
2
  import ResponseBodyPreview_vue_vue_type_script_setup_true_lang_default from "./ResponseBodyPreview.vue.script.js";
3
3
  /* empty css */
4
4
  //#region src/v2/blocks/response-block/components/ResponseBodyPreview.vue
5
- var ResponseBodyPreview_default = /*#__PURE__*/ _plugin_vue_export_helper_default(ResponseBodyPreview_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-8bc927e4"]]);
5
+ var ResponseBodyPreview_default = /*#__PURE__*/ _plugin_vue_export_helper_default(ResponseBodyPreview_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-a10b4008"]]);
6
6
  //#endregion
7
7
  export { ResponseBodyPreview_default as default };
8
8
 
@@ -1 +1 @@
1
- {"version":3,"file":"ResponseBodyPreview.vue.js","names":[],"sources":["../../../../../src/v2/blocks/response-block/components/ResponseBodyPreview.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { computed, ref, watch } from 'vue'\n\nimport { type MediaPreview } from '@/v2/blocks/response-block/helpers/media-types'\n\nimport ResponseBodyInfo from './ResponseBodyInfo.vue'\nimport ResponseBodyRaw from './ResponseBodyRaw.vue'\n\nconst {\n src,\n type,\n mode,\n alpha = false,\n content,\n} = defineProps<{\n src: string\n type: string\n mode: MediaPreview\n alpha?: boolean | undefined\n /** Decoded body; used when `mode` is `json` for pretty-printed preview (no JSON.parse round-trip). */\n content?: unknown\n}>()\n\nconst jsonPreviewContent = computed((): string => {\n const value = content\n if (typeof value === 'string') {\n return value\n }\n if (value == null) {\n return ''\n }\n return String(value)\n})\n\n/**\n * Validates the `src` against an allow-list of safe protocols before it is\n * passed to a rendering element. This blocks XSS vectors such as\n * `javascript:` and `vbscript:` URIs and also prevents accidentally embedding\n * a `data:text/html` payload that could execute script in the app origin.\n *\n * Allowed:\n * - `blob:` (the standard case — generated client-side by `URL.createObjectURL`)\n * - `http:` / `https:`\n * - `data:` URIs whose MIME type is a known safe media kind\n * (`image/*`, `video/*`, `audio/*`, `application/pdf`, `application/octet-stream`)\n *\n * Anything else (including malformed or relative URLs) collapses to an empty\n * string so the template falls back to the \"Preview unavailable\" message.\n */\nconst safeSrc = computed((): string => {\n if (!src) {\n return ''\n }\n\n if (/^data:/i.test(src)) {\n // The MIME type must be one of the known safe kinds AND be terminated by\n // `;` (parameters / `;base64`) or `,` (start of the payload). Anchoring\n // at the terminator prevents prefix-matching tricks like\n // `data:image/png-but-actually-html,…`.\n return /^data:(?:(?:image|video|audio)\\/[a-z0-9.+-]+|application\\/pdf|application\\/octet-stream)[;,]/i.test(\n src,\n )\n ? src\n : ''\n }\n\n try {\n const parsed = new URL(src)\n if (\n parsed.protocol === 'blob:' ||\n parsed.protocol === 'http:' ||\n parsed.protocol === 'https:'\n ) {\n return src\n }\n } catch {\n // Malformed or relative URL — refuse to render.\n }\n\n return ''\n})\n\nconst error = ref(false)\n\n/**\n * Whether the embedded document is a PDF.\n *\n * PDFs are rendered by the browser's own PDF engine (e.g. PDFium), which runs\n * in an isolated context that cannot reach this app's origin — its DOM,\n * cookies or storage. A PDF's embedded JavaScript therefore cannot be used to\n * attack us, and a strict `sandbox=\"\"` does not confine that engine; it only\n * prevents Chromium from loading the PDF viewer at all (it boots as a scripted\n * extension page), leaving the user with a blank frame. So PDFs are rendered\n * without the `sandbox` attribute, matching the original `<object>` behaviour.\n *\n * Everything else that reaches the iframe (notably `text/html`, the genuine\n * XSS vector) keeps the strict empty sandbox.\n */\nconst isPdf = computed(\n (): boolean => type.trim().toLowerCase() === 'application/pdf',\n)\n\nwatch(\n () => src,\n () => (error.value = false),\n)\n</script>\n<template>\n <ResponseBodyRaw\n v-if=\"mode === 'json'\"\n :content=\"jsonPreviewContent\"\n language=\"json\"\n prettyPrintJson />\n <div\n v-else-if=\"!error && safeSrc\"\n class=\"flex justify-center overflow-auto rounded-b\"\n :class=\"{ 'bg-preview p-2': alpha }\">\n <img\n v-if=\"mode === 'image'\"\n class=\"h-full max-w-full\"\n :class=\"{ rounded: alpha }\"\n :src=\"safeSrc\"\n referrerpolicy=\"no-referrer\"\n @error=\"error = true\" />\n <video\n v-else-if=\"mode === 'video'\"\n autoplay\n controls\n referrerpolicy=\"no-referrer\"\n width=\"100%\"\n @error=\"error = true\">\n <source\n :src=\"safeSrc\"\n :type=\"type\" />\n </video>\n <audio\n v-else-if=\"mode === 'audio'\"\n class=\"my-12\"\n controls\n referrerpolicy=\"no-referrer\"\n @error=\"error = true\">\n <source\n :src=\"safeSrc\"\n :type=\"type\" />\n </audio>\n <!--\n `<object>` would execute scripts inside the embedded document in the\n app's origin, so we render arbitrary previews inside an `<iframe>`\n instead. Non-PDF documents (notably `text/html`) get an empty `sandbox`\n attribute, which disables scripts, forms, popups and same-origin access.\n PDFs are exempted (see `isPdf` above): the empty sandbox does not confine\n the browser's PDF engine, it only stops the viewer from loading at all.\n\n Note: an `error` event on `<iframe>` is not reliably fired for failed\n navigations — browsers usually fire `load` even when the response is\n blank or an error page, and a cross-origin sandboxed frame cannot be\n introspected from JavaScript. There is therefore no useful runtime\n fallback for an unreachable URL; the URL allow-list above is what\n keeps unsafe content out in the first place.\n -->\n <iframe\n v-else\n class=\"aspect-[4/3] w-full border-0\"\n :src=\"safeSrc\"\n :sandbox=\"isPdf ? undefined : ''\"\n referrerpolicy=\"no-referrer\" />\n </div>\n <ResponseBodyInfo v-else>Preview unavailable</ResponseBodyInfo>\n</template>\n<style scoped>\n.light-mode .bg-preview {\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='%23000' fill-opacity='10%25'%3E%3Crect width='8' height='8' /%3E%3Crect x='8' y='8' width='8' height='8' /%3E%3C/svg%3E\");\n}\n.dark-mode .bg-preview {\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='%23FFF' fill-opacity='10%25'%3E%3Crect width='8' height='8' /%3E%3Crect x='8' y='8' width='8' height='8' /%3E%3C/svg%3E\");\n}\n</style>\n"],"mappings":""}
1
+ {"version":3,"file":"ResponseBodyPreview.vue.js","names":[],"sources":["../../../../../src/v2/blocks/response-block/components/ResponseBodyPreview.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { computed, ref, watch } from 'vue'\n\nimport { type MediaPreview } from '@/v2/blocks/response-block/helpers/media-types'\nimport { prettifyNdjson } from '@/v2/blocks/response-block/helpers/prettify-ndjson'\n\nimport ResponseBodyInfo from './ResponseBodyInfo.vue'\nimport ResponseBodyRaw from './ResponseBodyRaw.vue'\n\nconst {\n src,\n type,\n mode,\n alpha = false,\n content,\n} = defineProps<{\n src: string\n type: string\n mode: MediaPreview\n alpha?: boolean | undefined\n /** Decoded body; used when `mode` is `json` for pretty-printed preview (no JSON.parse round-trip). */\n content?: unknown\n}>()\n\nconst jsonPreviewContent = computed((): string => {\n const value = content\n if (typeof value === 'string') {\n return value\n }\n if (value == null) {\n return ''\n }\n return String(value)\n})\n\n/** NDJSON pretty-printed one record per block for the `ndjson` preview. */\nconst ndjsonPreviewContent = computed((): string =>\n prettifyNdjson(jsonPreviewContent.value),\n)\n\n/**\n * Validates the `src` against an allow-list of safe protocols before it is\n * passed to a rendering element. This blocks XSS vectors such as\n * `javascript:` and `vbscript:` URIs and also prevents accidentally embedding\n * a `data:text/html` payload that could execute script in the app origin.\n *\n * Allowed:\n * - `blob:` (the standard case — generated client-side by `URL.createObjectURL`)\n * - `http:` / `https:`\n * - `data:` URIs whose MIME type is a known safe media kind\n * (`image/*`, `video/*`, `audio/*`, `application/pdf`, `application/octet-stream`)\n *\n * Anything else (including malformed or relative URLs) collapses to an empty\n * string so the template falls back to the \"Preview unavailable\" message.\n */\nconst safeSrc = computed((): string => {\n if (!src) {\n return ''\n }\n\n if (/^data:/i.test(src)) {\n // The MIME type must be one of the known safe kinds AND be terminated by\n // `;` (parameters / `;base64`) or `,` (start of the payload). Anchoring\n // at the terminator prevents prefix-matching tricks like\n // `data:image/png-but-actually-html,…`.\n return /^data:(?:(?:image|video|audio)\\/[a-z0-9.+-]+|application\\/pdf|application\\/octet-stream)[;,]/i.test(\n src,\n )\n ? src\n : ''\n }\n\n try {\n const parsed = new URL(src)\n if (\n parsed.protocol === 'blob:' ||\n parsed.protocol === 'http:' ||\n parsed.protocol === 'https:'\n ) {\n return src\n }\n } catch {\n // Malformed or relative URL — refuse to render.\n }\n\n return ''\n})\n\nconst error = ref(false)\n\n/**\n * Whether the embedded document is a PDF.\n *\n * PDFs are rendered by the browser's own PDF engine (e.g. PDFium), which runs\n * in an isolated context that cannot reach this app's origin — its DOM,\n * cookies or storage. A PDF's embedded JavaScript therefore cannot be used to\n * attack us, and a strict `sandbox=\"\"` does not confine that engine; it only\n * prevents Chromium from loading the PDF viewer at all (it boots as a scripted\n * extension page), leaving the user with a blank frame. So PDFs are rendered\n * without the `sandbox` attribute, matching the original `<object>` behaviour.\n *\n * Everything else that reaches the iframe (notably `text/html`, the genuine\n * XSS vector) keeps the strict empty sandbox.\n */\nconst isPdf = computed(\n (): boolean => type.trim().toLowerCase() === 'application/pdf',\n)\n\nwatch(\n () => src,\n () => (error.value = false),\n)\n</script>\n<template>\n <ResponseBodyRaw\n v-if=\"mode === 'json'\"\n :content=\"jsonPreviewContent\"\n language=\"json\"\n prettyPrintJson />\n <ResponseBodyRaw\n v-else-if=\"mode === 'ndjson'\"\n :content=\"ndjsonPreviewContent\"\n language=\"json\" />\n <div\n v-else-if=\"!error && safeSrc\"\n class=\"flex justify-center overflow-auto rounded-b\"\n :class=\"{ 'bg-preview p-2': alpha }\">\n <img\n v-if=\"mode === 'image'\"\n class=\"h-full max-w-full\"\n :class=\"{ rounded: alpha }\"\n :src=\"safeSrc\"\n referrerpolicy=\"no-referrer\"\n @error=\"error = true\" />\n <video\n v-else-if=\"mode === 'video'\"\n autoplay\n controls\n referrerpolicy=\"no-referrer\"\n width=\"100%\"\n @error=\"error = true\">\n <source\n :src=\"safeSrc\"\n :type=\"type\" />\n </video>\n <audio\n v-else-if=\"mode === 'audio'\"\n class=\"my-12\"\n controls\n referrerpolicy=\"no-referrer\"\n @error=\"error = true\">\n <source\n :src=\"safeSrc\"\n :type=\"type\" />\n </audio>\n <!--\n `<object>` would execute scripts inside the embedded document in the\n app's origin, so we render arbitrary previews inside an `<iframe>`\n instead. Non-PDF documents (notably `text/html`) get an empty `sandbox`\n attribute, which disables scripts, forms, popups and same-origin access.\n PDFs are exempted (see `isPdf` above): the empty sandbox does not confine\n the browser's PDF engine, it only stops the viewer from loading at all.\n\n Note: an `error` event on `<iframe>` is not reliably fired for failed\n navigations — browsers usually fire `load` even when the response is\n blank or an error page, and a cross-origin sandboxed frame cannot be\n introspected from JavaScript. There is therefore no useful runtime\n fallback for an unreachable URL; the URL allow-list above is what\n keeps unsafe content out in the first place.\n -->\n <iframe\n v-else\n class=\"aspect-[4/3] w-full border-0\"\n :src=\"safeSrc\"\n :sandbox=\"isPdf ? undefined : ''\"\n referrerpolicy=\"no-referrer\" />\n </div>\n <ResponseBodyInfo v-else>Preview unavailable</ResponseBodyInfo>\n</template>\n<style scoped>\n.light-mode .bg-preview {\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='%23000' fill-opacity='10%25'%3E%3Crect width='8' height='8' /%3E%3Crect x='8' y='8' width='8' height='8' /%3E%3C/svg%3E\");\n}\n.dark-mode .bg-preview {\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='%23FFF' fill-opacity='10%25'%3E%3Crect width='8' height='8' /%3E%3Crect x='8' y='8' width='8' height='8' /%3E%3C/svg%3E\");\n}\n</style>\n"],"mappings":""}
@@ -1,4 +1,5 @@
1
1
  import ResponseBodyInfo_default from "./ResponseBodyInfo.vue.js";
2
+ import { prettifyNdjson } from "../helpers/prettify-ndjson.js";
2
3
  import ResponseBodyRaw_default from "./ResponseBodyRaw.vue.js";
3
4
  import { computed, createBlock, createElementBlock, createElementVNode, createTextVNode, defineComponent, normalizeClass, openBlock, ref, watch, withCtx } from "vue";
4
5
  //#region src/v2/blocks/response-block/components/ResponseBodyPreview.vue?vue&type=script&setup=true&lang.ts
@@ -25,6 +26,8 @@ var ResponseBodyPreview_vue_vue_type_script_setup_true_lang_default = /*@__PURE_
25
26
  if (value == null) return "";
26
27
  return String(value);
27
28
  });
29
+ /** NDJSON pretty-printed one record per block for the `ndjson` preview. */
30
+ const ndjsonPreviewContent = computed(() => prettifyNdjson(jsonPreviewContent.value));
28
31
  /**
29
32
  * Validates the `src` against an allow-list of safe protocols before it is
30
33
  * passed to a rendering element. This blocks XSS vectors such as
@@ -72,8 +75,12 @@ var ResponseBodyPreview_vue_vue_type_script_setup_true_lang_default = /*@__PURE_
72
75
  content: jsonPreviewContent.value,
73
76
  language: "json",
74
77
  prettyPrintJson: ""
75
- }, null, 8, ["content"])) : !error.value && safeSrc.value ? (openBlock(), createElementBlock("div", {
78
+ }, null, 8, ["content"])) : __props.mode === "ndjson" ? (openBlock(), createBlock(ResponseBodyRaw_default, {
76
79
  key: 1,
80
+ content: ndjsonPreviewContent.value,
81
+ language: "json"
82
+ }, null, 8, ["content"])) : !error.value && safeSrc.value ? (openBlock(), createElementBlock("div", {
83
+ key: 2,
77
84
  class: normalizeClass(["flex justify-center overflow-auto rounded-b", { "bg-preview p-2": __props.alpha }])
78
85
  }, [__props.mode === "image" ? (openBlock(), createElementBlock("img", {
79
86
  key: 0,
@@ -106,7 +113,7 @@ var ResponseBodyPreview_vue_vue_type_script_setup_true_lang_default = /*@__PURE_
106
113
  src: safeSrc.value,
107
114
  sandbox: isPdf.value ? void 0 : "",
108
115
  referrerpolicy: "no-referrer"
109
- }, null, 8, _hoisted_4))], 2)) : (openBlock(), createBlock(ResponseBodyInfo_default, { key: 2 }, {
116
+ }, null, 8, _hoisted_4))], 2)) : (openBlock(), createBlock(ResponseBodyInfo_default, { key: 3 }, {
110
117
  default: withCtx(() => [..._cache[3] || (_cache[3] = [createTextVNode("Preview unavailable", -1)])]),
111
118
  _: 1
112
119
  }));
@@ -1 +1 @@
1
- {"version":3,"file":"ResponseBodyPreview.vue.script.js","names":[],"sources":["../../../../../src/v2/blocks/response-block/components/ResponseBodyPreview.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { computed, ref, watch } from 'vue'\n\nimport { type MediaPreview } from '@/v2/blocks/response-block/helpers/media-types'\n\nimport ResponseBodyInfo from './ResponseBodyInfo.vue'\nimport ResponseBodyRaw from './ResponseBodyRaw.vue'\n\nconst {\n src,\n type,\n mode,\n alpha = false,\n content,\n} = defineProps<{\n src: string\n type: string\n mode: MediaPreview\n alpha?: boolean | undefined\n /** Decoded body; used when `mode` is `json` for pretty-printed preview (no JSON.parse round-trip). */\n content?: unknown\n}>()\n\nconst jsonPreviewContent = computed((): string => {\n const value = content\n if (typeof value === 'string') {\n return value\n }\n if (value == null) {\n return ''\n }\n return String(value)\n})\n\n/**\n * Validates the `src` against an allow-list of safe protocols before it is\n * passed to a rendering element. This blocks XSS vectors such as\n * `javascript:` and `vbscript:` URIs and also prevents accidentally embedding\n * a `data:text/html` payload that could execute script in the app origin.\n *\n * Allowed:\n * - `blob:` (the standard case — generated client-side by `URL.createObjectURL`)\n * - `http:` / `https:`\n * - `data:` URIs whose MIME type is a known safe media kind\n * (`image/*`, `video/*`, `audio/*`, `application/pdf`, `application/octet-stream`)\n *\n * Anything else (including malformed or relative URLs) collapses to an empty\n * string so the template falls back to the \"Preview unavailable\" message.\n */\nconst safeSrc = computed((): string => {\n if (!src) {\n return ''\n }\n\n if (/^data:/i.test(src)) {\n // The MIME type must be one of the known safe kinds AND be terminated by\n // `;` (parameters / `;base64`) or `,` (start of the payload). Anchoring\n // at the terminator prevents prefix-matching tricks like\n // `data:image/png-but-actually-html,…`.\n return /^data:(?:(?:image|video|audio)\\/[a-z0-9.+-]+|application\\/pdf|application\\/octet-stream)[;,]/i.test(\n src,\n )\n ? src\n : ''\n }\n\n try {\n const parsed = new URL(src)\n if (\n parsed.protocol === 'blob:' ||\n parsed.protocol === 'http:' ||\n parsed.protocol === 'https:'\n ) {\n return src\n }\n } catch {\n // Malformed or relative URL — refuse to render.\n }\n\n return ''\n})\n\nconst error = ref(false)\n\n/**\n * Whether the embedded document is a PDF.\n *\n * PDFs are rendered by the browser's own PDF engine (e.g. PDFium), which runs\n * in an isolated context that cannot reach this app's origin — its DOM,\n * cookies or storage. A PDF's embedded JavaScript therefore cannot be used to\n * attack us, and a strict `sandbox=\"\"` does not confine that engine; it only\n * prevents Chromium from loading the PDF viewer at all (it boots as a scripted\n * extension page), leaving the user with a blank frame. So PDFs are rendered\n * without the `sandbox` attribute, matching the original `<object>` behaviour.\n *\n * Everything else that reaches the iframe (notably `text/html`, the genuine\n * XSS vector) keeps the strict empty sandbox.\n */\nconst isPdf = computed(\n (): boolean => type.trim().toLowerCase() === 'application/pdf',\n)\n\nwatch(\n () => src,\n () => (error.value = false),\n)\n</script>\n<template>\n <ResponseBodyRaw\n v-if=\"mode === 'json'\"\n :content=\"jsonPreviewContent\"\n language=\"json\"\n prettyPrintJson />\n <div\n v-else-if=\"!error && safeSrc\"\n class=\"flex justify-center overflow-auto rounded-b\"\n :class=\"{ 'bg-preview p-2': alpha }\">\n <img\n v-if=\"mode === 'image'\"\n class=\"h-full max-w-full\"\n :class=\"{ rounded: alpha }\"\n :src=\"safeSrc\"\n referrerpolicy=\"no-referrer\"\n @error=\"error = true\" />\n <video\n v-else-if=\"mode === 'video'\"\n autoplay\n controls\n referrerpolicy=\"no-referrer\"\n width=\"100%\"\n @error=\"error = true\">\n <source\n :src=\"safeSrc\"\n :type=\"type\" />\n </video>\n <audio\n v-else-if=\"mode === 'audio'\"\n class=\"my-12\"\n controls\n referrerpolicy=\"no-referrer\"\n @error=\"error = true\">\n <source\n :src=\"safeSrc\"\n :type=\"type\" />\n </audio>\n <!--\n `<object>` would execute scripts inside the embedded document in the\n app's origin, so we render arbitrary previews inside an `<iframe>`\n instead. Non-PDF documents (notably `text/html`) get an empty `sandbox`\n attribute, which disables scripts, forms, popups and same-origin access.\n PDFs are exempted (see `isPdf` above): the empty sandbox does not confine\n the browser's PDF engine, it only stops the viewer from loading at all.\n\n Note: an `error` event on `<iframe>` is not reliably fired for failed\n navigations — browsers usually fire `load` even when the response is\n blank or an error page, and a cross-origin sandboxed frame cannot be\n introspected from JavaScript. There is therefore no useful runtime\n fallback for an unreachable URL; the URL allow-list above is what\n keeps unsafe content out in the first place.\n -->\n <iframe\n v-else\n class=\"aspect-[4/3] w-full border-0\"\n :src=\"safeSrc\"\n :sandbox=\"isPdf ? undefined : ''\"\n referrerpolicy=\"no-referrer\" />\n </div>\n <ResponseBodyInfo v-else>Preview unavailable</ResponseBodyInfo>\n</template>\n<style scoped>\n.light-mode .bg-preview {\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='%23000' fill-opacity='10%25'%3E%3Crect width='8' height='8' /%3E%3Crect x='8' y='8' width='8' height='8' /%3E%3C/svg%3E\");\n}\n.dark-mode .bg-preview {\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='%23FFF' fill-opacity='10%25'%3E%3Crect width='8' height='8' /%3E%3Crect x='8' y='8' width='8' height='8' /%3E%3C/svg%3E\");\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;EAuBA,MAAM,qBAAqB,eAAuB;GAChD,MAAM,QAAQ,QAAA;GACd,IAAI,OAAO,UAAU,UACnB,OAAO;GAET,IAAI,SAAS,MACX,OAAO;GAET,OAAO,OAAO,KAAK;EACrB,CAAC;;;;;;;;;;;;;;;;EAiBD,MAAM,UAAU,eAAuB;GACrC,IAAI,CAAC,QAAA,KACH,OAAO;GAGT,IAAI,UAAU,KAAK,QAAA,GAAG,GAKpB,OAAO,gGAAgG,KACrG,QAAA,GACF,IACI,QAAA,MACA;GAGN,IAAI;IACF,MAAM,SAAS,IAAI,IAAI,QAAA,GAAG;IAC1B,IACE,OAAO,aAAa,WACpB,OAAO,aAAa,WACpB,OAAO,aAAa,UAEpB,OAAO,QAAA;GAEX,QAAQ,CAER;GAEA,OAAO;EACT,CAAC;EAED,MAAM,QAAQ,IAAI,KAAK;;;;;;;;;;;;;;;EAgBvB,MAAM,QAAQ,eACG,QAAA,KAAK,KAAK,CAAC,CAAC,YAAY,MAAM,iBAC/C;EAEA,YACQ,QAAA,WACC,MAAM,QAAQ,KACvB;;UAIU,QAAA,SAAI,UAAA,UAAA,GADZ,YAIoB,yBAAA;;IAFjB,SAAS,mBAAA;IACV,UAAS;IACT,iBAAA;gCAEY,MAAA,SAAS,QAAA,SAAA,UAAA,GADvB,mBAqDM,OAAA;;IAnDJ,OAAK,eAAA,CAAC,+CAA6C,EAAA,kBACvB,QAAA,MAAK,CAAA,CAAA;OAEzB,QAAA,SAAI,WAAA,UAAA,GADZ,mBAM0B,OAAA;;IAJxB,OAAK,eAAA,CAAC,qBAAmB,EAAA,SACN,QAAA,MAAK,CAAA,CAAA;IACvB,KAAK,QAAA;IACN,gBAAe;IACd,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,MAAA,QAAK;+BAEF,QAAA,SAAI,WAAA,UAAA,GADjB,mBAUQ,SAAA;;IARN,UAAA;IACA,UAAA;IACA,gBAAe;IACf,OAAM;IACL,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,MAAA,QAAK;OACb,mBAEiB,UAAA;IADd,KAAK,QAAA;IACL,MAAM,QAAA;oCAGE,QAAA,SAAI,WAAA,UAAA,GADjB,mBASQ,SAAA;;IAPN,OAAM;IACN,UAAA;IACA,gBAAe;IACd,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,MAAA,QAAK;OACb,mBAEiB,UAAA;IADd,KAAK,QAAA;IACL,MAAM,QAAA;kDAiBX,mBAKiC,UAAA;;IAH/B,OAAM;IACL,KAAK,QAAA;IACL,SAAS,MAAA,QAAQ,KAAA,IAAS;IAC3B,gBAAe;kDAEnB,YAA+D,0BAAA,EAAA,KAAA,EAAA,GAAA;2BAAnB,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CAAA,gBAAnB,uBAAmB,EAAA,CAAA,EAAA,CAAA"}
1
+ {"version":3,"file":"ResponseBodyPreview.vue.script.js","names":[],"sources":["../../../../../src/v2/blocks/response-block/components/ResponseBodyPreview.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { computed, ref, watch } from 'vue'\n\nimport { type MediaPreview } from '@/v2/blocks/response-block/helpers/media-types'\nimport { prettifyNdjson } from '@/v2/blocks/response-block/helpers/prettify-ndjson'\n\nimport ResponseBodyInfo from './ResponseBodyInfo.vue'\nimport ResponseBodyRaw from './ResponseBodyRaw.vue'\n\nconst {\n src,\n type,\n mode,\n alpha = false,\n content,\n} = defineProps<{\n src: string\n type: string\n mode: MediaPreview\n alpha?: boolean | undefined\n /** Decoded body; used when `mode` is `json` for pretty-printed preview (no JSON.parse round-trip). */\n content?: unknown\n}>()\n\nconst jsonPreviewContent = computed((): string => {\n const value = content\n if (typeof value === 'string') {\n return value\n }\n if (value == null) {\n return ''\n }\n return String(value)\n})\n\n/** NDJSON pretty-printed one record per block for the `ndjson` preview. */\nconst ndjsonPreviewContent = computed((): string =>\n prettifyNdjson(jsonPreviewContent.value),\n)\n\n/**\n * Validates the `src` against an allow-list of safe protocols before it is\n * passed to a rendering element. This blocks XSS vectors such as\n * `javascript:` and `vbscript:` URIs and also prevents accidentally embedding\n * a `data:text/html` payload that could execute script in the app origin.\n *\n * Allowed:\n * - `blob:` (the standard case — generated client-side by `URL.createObjectURL`)\n * - `http:` / `https:`\n * - `data:` URIs whose MIME type is a known safe media kind\n * (`image/*`, `video/*`, `audio/*`, `application/pdf`, `application/octet-stream`)\n *\n * Anything else (including malformed or relative URLs) collapses to an empty\n * string so the template falls back to the \"Preview unavailable\" message.\n */\nconst safeSrc = computed((): string => {\n if (!src) {\n return ''\n }\n\n if (/^data:/i.test(src)) {\n // The MIME type must be one of the known safe kinds AND be terminated by\n // `;` (parameters / `;base64`) or `,` (start of the payload). Anchoring\n // at the terminator prevents prefix-matching tricks like\n // `data:image/png-but-actually-html,…`.\n return /^data:(?:(?:image|video|audio)\\/[a-z0-9.+-]+|application\\/pdf|application\\/octet-stream)[;,]/i.test(\n src,\n )\n ? src\n : ''\n }\n\n try {\n const parsed = new URL(src)\n if (\n parsed.protocol === 'blob:' ||\n parsed.protocol === 'http:' ||\n parsed.protocol === 'https:'\n ) {\n return src\n }\n } catch {\n // Malformed or relative URL — refuse to render.\n }\n\n return ''\n})\n\nconst error = ref(false)\n\n/**\n * Whether the embedded document is a PDF.\n *\n * PDFs are rendered by the browser's own PDF engine (e.g. PDFium), which runs\n * in an isolated context that cannot reach this app's origin — its DOM,\n * cookies or storage. A PDF's embedded JavaScript therefore cannot be used to\n * attack us, and a strict `sandbox=\"\"` does not confine that engine; it only\n * prevents Chromium from loading the PDF viewer at all (it boots as a scripted\n * extension page), leaving the user with a blank frame. So PDFs are rendered\n * without the `sandbox` attribute, matching the original `<object>` behaviour.\n *\n * Everything else that reaches the iframe (notably `text/html`, the genuine\n * XSS vector) keeps the strict empty sandbox.\n */\nconst isPdf = computed(\n (): boolean => type.trim().toLowerCase() === 'application/pdf',\n)\n\nwatch(\n () => src,\n () => (error.value = false),\n)\n</script>\n<template>\n <ResponseBodyRaw\n v-if=\"mode === 'json'\"\n :content=\"jsonPreviewContent\"\n language=\"json\"\n prettyPrintJson />\n <ResponseBodyRaw\n v-else-if=\"mode === 'ndjson'\"\n :content=\"ndjsonPreviewContent\"\n language=\"json\" />\n <div\n v-else-if=\"!error && safeSrc\"\n class=\"flex justify-center overflow-auto rounded-b\"\n :class=\"{ 'bg-preview p-2': alpha }\">\n <img\n v-if=\"mode === 'image'\"\n class=\"h-full max-w-full\"\n :class=\"{ rounded: alpha }\"\n :src=\"safeSrc\"\n referrerpolicy=\"no-referrer\"\n @error=\"error = true\" />\n <video\n v-else-if=\"mode === 'video'\"\n autoplay\n controls\n referrerpolicy=\"no-referrer\"\n width=\"100%\"\n @error=\"error = true\">\n <source\n :src=\"safeSrc\"\n :type=\"type\" />\n </video>\n <audio\n v-else-if=\"mode === 'audio'\"\n class=\"my-12\"\n controls\n referrerpolicy=\"no-referrer\"\n @error=\"error = true\">\n <source\n :src=\"safeSrc\"\n :type=\"type\" />\n </audio>\n <!--\n `<object>` would execute scripts inside the embedded document in the\n app's origin, so we render arbitrary previews inside an `<iframe>`\n instead. Non-PDF documents (notably `text/html`) get an empty `sandbox`\n attribute, which disables scripts, forms, popups and same-origin access.\n PDFs are exempted (see `isPdf` above): the empty sandbox does not confine\n the browser's PDF engine, it only stops the viewer from loading at all.\n\n Note: an `error` event on `<iframe>` is not reliably fired for failed\n navigations — browsers usually fire `load` even when the response is\n blank or an error page, and a cross-origin sandboxed frame cannot be\n introspected from JavaScript. There is therefore no useful runtime\n fallback for an unreachable URL; the URL allow-list above is what\n keeps unsafe content out in the first place.\n -->\n <iframe\n v-else\n class=\"aspect-[4/3] w-full border-0\"\n :src=\"safeSrc\"\n :sandbox=\"isPdf ? undefined : ''\"\n referrerpolicy=\"no-referrer\" />\n </div>\n <ResponseBodyInfo v-else>Preview unavailable</ResponseBodyInfo>\n</template>\n<style scoped>\n.light-mode .bg-preview {\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='%23000' fill-opacity='10%25'%3E%3Crect width='8' height='8' /%3E%3Crect x='8' y='8' width='8' height='8' /%3E%3C/svg%3E\");\n}\n.dark-mode .bg-preview {\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='%23FFF' fill-opacity='10%25'%3E%3Crect width='8' height='8' /%3E%3Crect x='8' y='8' width='8' height='8' /%3E%3C/svg%3E\");\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;EAwBA,MAAM,qBAAqB,eAAuB;GAChD,MAAM,QAAQ,QAAA;GACd,IAAI,OAAO,UAAU,UACnB,OAAO;GAET,IAAI,SAAS,MACX,OAAO;GAET,OAAO,OAAO,KAAK;EACrB,CAAC;;EAGD,MAAM,uBAAuB,eAC3B,eAAe,mBAAmB,KAAK,CACzC;;;;;;;;;;;;;;;;EAiBA,MAAM,UAAU,eAAuB;GACrC,IAAI,CAAC,QAAA,KACH,OAAO;GAGT,IAAI,UAAU,KAAK,QAAA,GAAG,GAKpB,OAAO,gGAAgG,KACrG,QAAA,GACF,IACI,QAAA,MACA;GAGN,IAAI;IACF,MAAM,SAAS,IAAI,IAAI,QAAA,GAAG;IAC1B,IACE,OAAO,aAAa,WACpB,OAAO,aAAa,WACpB,OAAO,aAAa,UAEpB,OAAO,QAAA;GAEX,QAAQ,CAER;GAEA,OAAO;EACT,CAAC;EAED,MAAM,QAAQ,IAAI,KAAK;;;;;;;;;;;;;;;EAgBvB,MAAM,QAAQ,eACG,QAAA,KAAK,KAAK,CAAC,CAAC,YAAY,MAAM,iBAC/C;EAEA,YACQ,QAAA,WACC,MAAM,QAAQ,KACvB;;UAIU,QAAA,SAAI,UAAA,UAAA,GADZ,YAIoB,yBAAA;;IAFjB,SAAS,mBAAA;IACV,UAAS;IACT,iBAAA;+BAEW,QAAA,SAAI,YAAA,UAAA,GADjB,YAGoB,yBAAA;;IADjB,SAAS,qBAAA;IACV,UAAS;gCAEG,MAAA,SAAS,QAAA,SAAA,UAAA,GADvB,mBAqDM,OAAA;;IAnDJ,OAAK,eAAA,CAAC,+CAA6C,EAAA,kBACvB,QAAA,MAAK,CAAA,CAAA;OAEzB,QAAA,SAAI,WAAA,UAAA,GADZ,mBAM0B,OAAA;;IAJxB,OAAK,eAAA,CAAC,qBAAmB,EAAA,SACN,QAAA,MAAK,CAAA,CAAA;IACvB,KAAK,QAAA;IACN,gBAAe;IACd,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,MAAA,QAAK;+BAEF,QAAA,SAAI,WAAA,UAAA,GADjB,mBAUQ,SAAA;;IARN,UAAA;IACA,UAAA;IACA,gBAAe;IACf,OAAM;IACL,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,MAAA,QAAK;OACb,mBAEiB,UAAA;IADd,KAAK,QAAA;IACL,MAAM,QAAA;oCAGE,QAAA,SAAI,WAAA,UAAA,GADjB,mBASQ,SAAA;;IAPN,OAAM;IACN,UAAA;IACA,gBAAe;IACd,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,MAAA,QAAK;OACb,mBAEiB,UAAA;IADd,KAAK,QAAA;IACL,MAAM,QAAA;kDAiBX,mBAKiC,UAAA;;IAH/B,OAAM;IACL,KAAK,QAAA;IACL,SAAS,MAAA,QAAQ,KAAA,IAAS;IAC3B,gBAAe;kDAEnB,YAA+D,0BAAA,EAAA,KAAA,EAAA,GAAA;2BAAnB,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CAAA,gBAAnB,uBAAmB,EAAA,CAAA,EAAA,CAAA"}
@@ -1,5 +1,5 @@
1
1
  import type { CodeMirrorLanguage } from '@scalar/use-codemirror';
2
- export type MediaPreview = 'object' | 'image' | 'video' | 'audio' | 'json';
2
+ export type MediaPreview = 'object' | 'image' | 'video' | 'audio' | 'json' | 'ndjson';
3
3
  type MediaConfig = {
4
4
  preview?: MediaPreview;
5
5
  alpha?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"media-types.d.ts","sourceRoot":"","sources":["../../../../../src/v2/blocks/response-block/helpers/media-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAEhE,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,CAAA;AAE1E,KAAK,WAAW,GAAG;IACjB,OAAO,CAAC,EAAE,YAAY,CAAA;IACtB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,QAAQ,CAAC,EAAE,kBAAkB,CAAA;IAC7B,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AA8ID,iEAAiE;AACjE,eAAO,MAAM,cAAc,EAAE,MAAM,EAEX,CAAA;AAExB,sCAAsC;AACtC,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAiBxE;AAED,8DAA8D;AAC9D,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAErD"}
1
+ {"version":3,"file":"media-types.d.ts","sourceRoot":"","sources":["../../../../../src/v2/blocks/response-block/helpers/media-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAEhE,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAA;AAErF,KAAK,WAAW,GAAG;IACjB,OAAO,CAAC,EAAE,YAAY,CAAA;IACtB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,QAAQ,CAAC,EAAE,kBAAkB,CAAA;IAC7B,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AA6JD,iEAAiE;AACjE,eAAO,MAAM,cAAc,EAAE,MAAM,EAEX,CAAA;AAExB,sCAAsC;AACtC,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAiBxE;AAED,8DAA8D;AAC9D,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAErD"}
@@ -38,6 +38,18 @@ var mediaTypes = {
38
38
  language: "json",
39
39
  preview: "json"
40
40
  },
41
+ "application/x-ndjson": {
42
+ extension: ".ndjson",
43
+ raw: true,
44
+ language: "json",
45
+ preview: "ndjson"
46
+ },
47
+ "application/ndjson": {
48
+ extension: ".ndjson",
49
+ raw: true,
50
+ language: "json",
51
+ preview: "ndjson"
52
+ },
41
53
  "application/msword": { extension: ".doc" },
42
54
  "application/octet-stream": { extension: ".bin" },
43
55
  "application/ogg": { extension: ".ogx" },
@@ -1 +1 @@
1
- {"version":3,"file":"media-types.js","names":[],"sources":["../../../../../src/v2/blocks/response-block/helpers/media-types.ts"],"sourcesContent":["import type { CodeMirrorLanguage } from '@scalar/use-codemirror'\n\nexport type MediaPreview = 'object' | 'image' | 'video' | 'audio' | 'json'\n\ntype MediaConfig = {\n preview?: MediaPreview\n alpha?: boolean\n raw?: boolean\n language?: CodeMirrorLanguage\n extension: string\n}\n\n/** Media Type (MIME Type) Definitions */\nconst mediaTypes: { [type: string]: MediaConfig | undefined } = {\n 'application/epub+zip': { extension: '.epub' },\n 'application/gzip': { extension: '.gz' },\n 'application/java-archive': { extension: '.jar' },\n 'application/javascript': { extension: '.js', raw: true },\n 'application/json': {\n extension: '.json',\n raw: true,\n language: 'json',\n preview: 'json',\n },\n 'application/ld+json': {\n extension: '.jsonld',\n raw: true,\n language: 'json',\n preview: 'json',\n },\n 'application/problem+json': {\n extension: '.json',\n raw: true,\n language: 'json',\n preview: 'json',\n },\n 'application/vnd.api+json': {\n extension: '.json',\n raw: true,\n language: 'json',\n preview: 'json',\n },\n 'application/dns-json': {\n extension: '.json',\n raw: true,\n language: 'json',\n preview: 'json',\n },\n 'application/msword': { extension: '.doc' },\n 'application/octet-stream': { extension: '.bin' },\n 'application/ogg': { extension: '.ogx' },\n 'application/pdf': { extension: '.pdf', preview: 'object' },\n 'application/rtf': { extension: '.rtf', raw: true },\n 'application/vnd.amazon.ebook': { extension: '.azw' },\n 'application/vnd.apple.installer+xml': {\n extension: '.mpkg',\n raw: true,\n language: 'xml',\n },\n 'application/vnd.mozilla.xul+xml': {\n extension: '.xul',\n raw: true,\n language: 'xml',\n },\n 'application/vnd.ms-excel': { extension: '.xls' },\n 'application/vnd.ms-fontobject': { extension: '.eot' },\n 'application/vnd.ms-powerpoint': { extension: '.ppt' },\n 'application/vnd.oasis.opendocument.presentation': { extension: '.odp' },\n 'application/vnd.oasis.opendocument.spreadsheet': { extension: '.ods' },\n 'application/vnd.oasis.opendocument.text': { extension: '.odt' },\n 'application/vnd.openxmlformats-officedocument.presentationml.presentation': {\n extension: '.pptx',\n },\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': {\n extension: '.xlsx',\n },\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': {\n extension: '.docx',\n },\n 'application/vnd.rar': { extension: '.rar' },\n 'application/vnd.visio': { extension: '.vsd' },\n 'application/x-7z-compressed': { extension: '.7z' },\n 'application/x-abiword': { extension: '.abw' },\n 'application/x-bzip': { extension: '.bz' },\n 'application/x-bzip2': { extension: '.bz2' },\n 'application/x-cdf': { extension: '.cda' },\n 'application/x-csh': { extension: '.csh' },\n 'application/x-freearc': { extension: '.arc' },\n 'application/x-httpd-php': { extension: '.php', raw: true },\n 'application/x-sh': { extension: '.sh', raw: true },\n 'application/x-tar': { extension: '.tar' },\n 'application/xhtml+xml': { extension: '.xhtml', raw: true, language: 'html' },\n 'application/xml': { extension: '.xml', raw: true, language: 'xml' },\n 'application/yaml': { extension: '.yaml', raw: true, language: 'yaml' },\n 'application/zip': { extension: '.zip' },\n 'audio/aac': { extension: '.aac' },\n 'audio/midi': { extension: '.midi' },\n 'audio/mpeg': { extension: '.mp3', preview: 'audio' },\n 'audio/ogg': { extension: '.oga' },\n 'audio/wav': { extension: '.wav' },\n 'audio/webm': { extension: '.weba' },\n 'font/otf': { extension: '.otf' },\n 'font/ttf': { extension: '.ttf' },\n 'font/woff': { extension: '.woff' },\n 'font/woff2': { extension: '.woff2' },\n 'image/apng': { extension: '.apng', preview: 'image', alpha: true },\n 'image/avif': { extension: '.avif', preview: 'image' },\n 'image/bmp': { extension: '.bmp', preview: 'image' },\n 'image/gif': { extension: '.gif', preview: 'image', alpha: true },\n 'image/jpeg': { extension: '.jpg', preview: 'image' },\n 'image/png': { extension: '.png', preview: 'image', alpha: true },\n 'image/svg+xml': {\n extension: '.svg',\n raw: true,\n language: 'xml',\n preview: 'image',\n alpha: true,\n },\n 'image/tiff': { extension: '.tiff' },\n 'image/vnd.microsoft.icon': { extension: '.ico', preview: 'image' },\n 'image/webp': { extension: '.webp', preview: 'image', alpha: true },\n 'text/calendar': { extension: '.ics', raw: true },\n 'text/css': { extension: '.css', raw: true, language: 'css' },\n 'text/csv': { extension: '.csv', raw: true },\n 'text/html': {\n extension: '.html',\n raw: true,\n language: 'html',\n preview: 'object',\n },\n 'text/javascript': { extension: '.js', raw: true },\n 'text/json': {\n extension: '.json',\n raw: true,\n language: 'json',\n preview: 'json',\n },\n 'text/plain': { extension: '.txt', raw: true },\n 'text/xml': { extension: '.xml', raw: true, language: 'xml' },\n 'text/yaml': { extension: '.yaml', raw: true, language: 'yaml' },\n 'video/3gpp': { extension: '.3gp' },\n 'audio/3gpp': { extension: '.3gp' },\n 'video/3gpp2': { extension: '.3g2' },\n 'audio/3gpp2': { extension: '.3g2' },\n 'video/mp2t': { extension: '.ts' },\n 'video/mp4': { extension: '.mp4', preview: 'video' },\n 'video/mpeg': { extension: '.mpeg' },\n 'video/ogg': { extension: '.ogv' },\n 'video/webm': { extension: '.webm', preview: 'video' },\n 'video/x-msvideo': { extension: '.avi' },\n}\n\n/** Media Types (MIME Types) that can be displayed as raw text */\nexport const textMediaTypes: string[] = Object.entries(mediaTypes)\n .filter(([, config]) => config?.raw)\n .map(([type]) => type)\n\n/** Get the config for a media type */\nexport function getMediaTypeConfig(type: string): MediaConfig | undefined {\n const config = mediaTypes[type]\n if (config) {\n return config\n }\n\n // Fallback for +json types\n if (type.endsWith('+json')) {\n return {\n extension: '.json',\n raw: true,\n language: 'json',\n preview: 'json',\n }\n }\n\n return undefined\n}\n\n/** Check if a media type that can be displayed as raw text */\nexport function isTextMediaType(type: string): boolean {\n return !!getMediaTypeConfig(type)?.raw\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"media-types.js","names":[],"sources":["../../../../../src/v2/blocks/response-block/helpers/media-types.ts"],"sourcesContent":["import type { CodeMirrorLanguage } from '@scalar/use-codemirror'\n\nexport type MediaPreview = 'object' | 'image' | 'video' | 'audio' | 'json' | 'ndjson'\n\ntype MediaConfig = {\n preview?: MediaPreview\n alpha?: boolean\n raw?: boolean\n language?: CodeMirrorLanguage\n extension: string\n}\n\n/** Media Type (MIME Type) Definitions */\nconst mediaTypes: { [type: string]: MediaConfig | undefined } = {\n 'application/epub+zip': { extension: '.epub' },\n 'application/gzip': { extension: '.gz' },\n 'application/java-archive': { extension: '.jar' },\n 'application/javascript': { extension: '.js', raw: true },\n 'application/json': {\n extension: '.json',\n raw: true,\n language: 'json',\n preview: 'json',\n },\n 'application/ld+json': {\n extension: '.jsonld',\n raw: true,\n language: 'json',\n preview: 'json',\n },\n 'application/problem+json': {\n extension: '.json',\n raw: true,\n language: 'json',\n preview: 'json',\n },\n 'application/vnd.api+json': {\n extension: '.json',\n raw: true,\n language: 'json',\n preview: 'json',\n },\n 'application/dns-json': {\n extension: '.json',\n raw: true,\n language: 'json',\n preview: 'json',\n },\n // Newline-delimited JSON is many JSON objects separated by newlines, not one\n // JSON document. The `ndjson` preview pretty-prints each line on its own, while\n // Raw keeps the exact wire format of one object per line.\n 'application/x-ndjson': {\n extension: '.ndjson',\n raw: true,\n language: 'json',\n preview: 'ndjson',\n },\n 'application/ndjson': {\n extension: '.ndjson',\n raw: true,\n language: 'json',\n preview: 'ndjson',\n },\n 'application/msword': { extension: '.doc' },\n 'application/octet-stream': { extension: '.bin' },\n 'application/ogg': { extension: '.ogx' },\n 'application/pdf': { extension: '.pdf', preview: 'object' },\n 'application/rtf': { extension: '.rtf', raw: true },\n 'application/vnd.amazon.ebook': { extension: '.azw' },\n 'application/vnd.apple.installer+xml': {\n extension: '.mpkg',\n raw: true,\n language: 'xml',\n },\n 'application/vnd.mozilla.xul+xml': {\n extension: '.xul',\n raw: true,\n language: 'xml',\n },\n 'application/vnd.ms-excel': { extension: '.xls' },\n 'application/vnd.ms-fontobject': { extension: '.eot' },\n 'application/vnd.ms-powerpoint': { extension: '.ppt' },\n 'application/vnd.oasis.opendocument.presentation': { extension: '.odp' },\n 'application/vnd.oasis.opendocument.spreadsheet': { extension: '.ods' },\n 'application/vnd.oasis.opendocument.text': { extension: '.odt' },\n 'application/vnd.openxmlformats-officedocument.presentationml.presentation': {\n extension: '.pptx',\n },\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': {\n extension: '.xlsx',\n },\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': {\n extension: '.docx',\n },\n 'application/vnd.rar': { extension: '.rar' },\n 'application/vnd.visio': { extension: '.vsd' },\n 'application/x-7z-compressed': { extension: '.7z' },\n 'application/x-abiword': { extension: '.abw' },\n 'application/x-bzip': { extension: '.bz' },\n 'application/x-bzip2': { extension: '.bz2' },\n 'application/x-cdf': { extension: '.cda' },\n 'application/x-csh': { extension: '.csh' },\n 'application/x-freearc': { extension: '.arc' },\n 'application/x-httpd-php': { extension: '.php', raw: true },\n 'application/x-sh': { extension: '.sh', raw: true },\n 'application/x-tar': { extension: '.tar' },\n 'application/xhtml+xml': { extension: '.xhtml', raw: true, language: 'html' },\n 'application/xml': { extension: '.xml', raw: true, language: 'xml' },\n 'application/yaml': { extension: '.yaml', raw: true, language: 'yaml' },\n 'application/zip': { extension: '.zip' },\n 'audio/aac': { extension: '.aac' },\n 'audio/midi': { extension: '.midi' },\n 'audio/mpeg': { extension: '.mp3', preview: 'audio' },\n 'audio/ogg': { extension: '.oga' },\n 'audio/wav': { extension: '.wav' },\n 'audio/webm': { extension: '.weba' },\n 'font/otf': { extension: '.otf' },\n 'font/ttf': { extension: '.ttf' },\n 'font/woff': { extension: '.woff' },\n 'font/woff2': { extension: '.woff2' },\n 'image/apng': { extension: '.apng', preview: 'image', alpha: true },\n 'image/avif': { extension: '.avif', preview: 'image' },\n 'image/bmp': { extension: '.bmp', preview: 'image' },\n 'image/gif': { extension: '.gif', preview: 'image', alpha: true },\n 'image/jpeg': { extension: '.jpg', preview: 'image' },\n 'image/png': { extension: '.png', preview: 'image', alpha: true },\n 'image/svg+xml': {\n extension: '.svg',\n raw: true,\n language: 'xml',\n preview: 'image',\n alpha: true,\n },\n 'image/tiff': { extension: '.tiff' },\n 'image/vnd.microsoft.icon': { extension: '.ico', preview: 'image' },\n 'image/webp': { extension: '.webp', preview: 'image', alpha: true },\n 'text/calendar': { extension: '.ics', raw: true },\n 'text/css': { extension: '.css', raw: true, language: 'css' },\n 'text/csv': { extension: '.csv', raw: true },\n 'text/html': {\n extension: '.html',\n raw: true,\n language: 'html',\n preview: 'object',\n },\n 'text/javascript': { extension: '.js', raw: true },\n 'text/json': {\n extension: '.json',\n raw: true,\n language: 'json',\n preview: 'json',\n },\n 'text/plain': { extension: '.txt', raw: true },\n 'text/xml': { extension: '.xml', raw: true, language: 'xml' },\n 'text/yaml': { extension: '.yaml', raw: true, language: 'yaml' },\n 'video/3gpp': { extension: '.3gp' },\n 'audio/3gpp': { extension: '.3gp' },\n 'video/3gpp2': { extension: '.3g2' },\n 'audio/3gpp2': { extension: '.3g2' },\n 'video/mp2t': { extension: '.ts' },\n 'video/mp4': { extension: '.mp4', preview: 'video' },\n 'video/mpeg': { extension: '.mpeg' },\n 'video/ogg': { extension: '.ogv' },\n 'video/webm': { extension: '.webm', preview: 'video' },\n 'video/x-msvideo': { extension: '.avi' },\n}\n\n/** Media Types (MIME Types) that can be displayed as raw text */\nexport const textMediaTypes: string[] = Object.entries(mediaTypes)\n .filter(([, config]) => config?.raw)\n .map(([type]) => type)\n\n/** Get the config for a media type */\nexport function getMediaTypeConfig(type: string): MediaConfig | undefined {\n const config = mediaTypes[type]\n if (config) {\n return config\n }\n\n // Fallback for +json types\n if (type.endsWith('+json')) {\n return {\n extension: '.json',\n raw: true,\n language: 'json',\n preview: 'json',\n }\n }\n\n return undefined\n}\n\n/** Check if a media type that can be displayed as raw text */\nexport function isTextMediaType(type: string): boolean {\n return !!getMediaTypeConfig(type)?.raw\n}\n"],"mappings":";;AAaA,IAAM,aAA0D;CAC9D,wBAAwB,EAAE,WAAW,QAAQ;CAC7C,oBAAoB,EAAE,WAAW,MAAM;CACvC,4BAA4B,EAAE,WAAW,OAAO;CAChD,0BAA0B;EAAE,WAAW;EAAO,KAAK;CAAK;CACxD,oBAAoB;EAClB,WAAW;EACX,KAAK;EACL,UAAU;EACV,SAAS;CACX;CACA,uBAAuB;EACrB,WAAW;EACX,KAAK;EACL,UAAU;EACV,SAAS;CACX;CACA,4BAA4B;EAC1B,WAAW;EACX,KAAK;EACL,UAAU;EACV,SAAS;CACX;CACA,4BAA4B;EAC1B,WAAW;EACX,KAAK;EACL,UAAU;EACV,SAAS;CACX;CACA,wBAAwB;EACtB,WAAW;EACX,KAAK;EACL,UAAU;EACV,SAAS;CACX;CAIA,wBAAwB;EACtB,WAAW;EACX,KAAK;EACL,UAAU;EACV,SAAS;CACX;CACA,sBAAsB;EACpB,WAAW;EACX,KAAK;EACL,UAAU;EACV,SAAS;CACX;CACA,sBAAsB,EAAE,WAAW,OAAO;CAC1C,4BAA4B,EAAE,WAAW,OAAO;CAChD,mBAAmB,EAAE,WAAW,OAAO;CACvC,mBAAmB;EAAE,WAAW;EAAQ,SAAS;CAAS;CAC1D,mBAAmB;EAAE,WAAW;EAAQ,KAAK;CAAK;CAClD,gCAAgC,EAAE,WAAW,OAAO;CACpD,uCAAuC;EACrC,WAAW;EACX,KAAK;EACL,UAAU;CACZ;CACA,mCAAmC;EACjC,WAAW;EACX,KAAK;EACL,UAAU;CACZ;CACA,4BAA4B,EAAE,WAAW,OAAO;CAChD,iCAAiC,EAAE,WAAW,OAAO;CACrD,iCAAiC,EAAE,WAAW,OAAO;CACrD,mDAAmD,EAAE,WAAW,OAAO;CACvE,kDAAkD,EAAE,WAAW,OAAO;CACtE,2CAA2C,EAAE,WAAW,OAAO;CAC/D,6EAA6E,EAC3E,WAAW,QACb;CACA,qEAAqE,EACnE,WAAW,QACb;CACA,2EAA2E,EACzE,WAAW,QACb;CACA,uBAAuB,EAAE,WAAW,OAAO;CAC3C,yBAAyB,EAAE,WAAW,OAAO;CAC7C,+BAA+B,EAAE,WAAW,MAAM;CAClD,yBAAyB,EAAE,WAAW,OAAO;CAC7C,sBAAsB,EAAE,WAAW,MAAM;CACzC,uBAAuB,EAAE,WAAW,OAAO;CAC3C,qBAAqB,EAAE,WAAW,OAAO;CACzC,qBAAqB,EAAE,WAAW,OAAO;CACzC,yBAAyB,EAAE,WAAW,OAAO;CAC7C,2BAA2B;EAAE,WAAW;EAAQ,KAAK;CAAK;CAC1D,oBAAoB;EAAE,WAAW;EAAO,KAAK;CAAK;CAClD,qBAAqB,EAAE,WAAW,OAAO;CACzC,yBAAyB;EAAE,WAAW;EAAU,KAAK;EAAM,UAAU;CAAO;CAC5E,mBAAmB;EAAE,WAAW;EAAQ,KAAK;EAAM,UAAU;CAAM;CACnE,oBAAoB;EAAE,WAAW;EAAS,KAAK;EAAM,UAAU;CAAO;CACtE,mBAAmB,EAAE,WAAW,OAAO;CACvC,aAAa,EAAE,WAAW,OAAO;CACjC,cAAc,EAAE,WAAW,QAAQ;CACnC,cAAc;EAAE,WAAW;EAAQ,SAAS;CAAQ;CACpD,aAAa,EAAE,WAAW,OAAO;CACjC,aAAa,EAAE,WAAW,OAAO;CACjC,cAAc,EAAE,WAAW,QAAQ;CACnC,YAAY,EAAE,WAAW,OAAO;CAChC,YAAY,EAAE,WAAW,OAAO;CAChC,aAAa,EAAE,WAAW,QAAQ;CAClC,cAAc,EAAE,WAAW,SAAS;CACpC,cAAc;EAAE,WAAW;EAAS,SAAS;EAAS,OAAO;CAAK;CAClE,cAAc;EAAE,WAAW;EAAS,SAAS;CAAQ;CACrD,aAAa;EAAE,WAAW;EAAQ,SAAS;CAAQ;CACnD,aAAa;EAAE,WAAW;EAAQ,SAAS;EAAS,OAAO;CAAK;CAChE,cAAc;EAAE,WAAW;EAAQ,SAAS;CAAQ;CACpD,aAAa;EAAE,WAAW;EAAQ,SAAS;EAAS,OAAO;CAAK;CAChE,iBAAiB;EACf,WAAW;EACX,KAAK;EACL,UAAU;EACV,SAAS;EACT,OAAO;CACT;CACA,cAAc,EAAE,WAAW,QAAQ;CACnC,4BAA4B;EAAE,WAAW;EAAQ,SAAS;CAAQ;CAClE,cAAc;EAAE,WAAW;EAAS,SAAS;EAAS,OAAO;CAAK;CAClE,iBAAiB;EAAE,WAAW;EAAQ,KAAK;CAAK;CAChD,YAAY;EAAE,WAAW;EAAQ,KAAK;EAAM,UAAU;CAAM;CAC5D,YAAY;EAAE,WAAW;EAAQ,KAAK;CAAK;CAC3C,aAAa;EACX,WAAW;EACX,KAAK;EACL,UAAU;EACV,SAAS;CACX;CACA,mBAAmB;EAAE,WAAW;EAAO,KAAK;CAAK;CACjD,aAAa;EACX,WAAW;EACX,KAAK;EACL,UAAU;EACV,SAAS;CACX;CACA,cAAc;EAAE,WAAW;EAAQ,KAAK;CAAK;CAC7C,YAAY;EAAE,WAAW;EAAQ,KAAK;EAAM,UAAU;CAAM;CAC5D,aAAa;EAAE,WAAW;EAAS,KAAK;EAAM,UAAU;CAAO;CAC/D,cAAc,EAAE,WAAW,OAAO;CAClC,cAAc,EAAE,WAAW,OAAO;CAClC,eAAe,EAAE,WAAW,OAAO;CACnC,eAAe,EAAE,WAAW,OAAO;CACnC,cAAc,EAAE,WAAW,MAAM;CACjC,aAAa;EAAE,WAAW;EAAQ,SAAS;CAAQ;CACnD,cAAc,EAAE,WAAW,QAAQ;CACnC,aAAa,EAAE,WAAW,OAAO;CACjC,cAAc;EAAE,WAAW;EAAS,SAAS;CAAQ;CACrD,mBAAmB,EAAE,WAAW,OAAO;AACzC;;AAGA,IAAa,iBAA2B,OAAO,QAAQ,UAAU,CAAC,CAC/D,QAAQ,GAAG,YAAY,QAAQ,GAAG,CAAC,CACnC,KAAK,CAAC,UAAU,IAAI;;AAGvB,SAAgB,mBAAmB,MAAuC;CACxE,MAAM,SAAS,WAAW;CAC1B,IAAI,QACF,OAAO;CAIT,IAAI,KAAK,SAAS,OAAO,GACvB,OAAO;EACL,WAAW;EACX,KAAK;EACL,UAAU;EACV,SAAS;CACX;AAIJ;;AAGA,SAAgB,gBAAgB,MAAuB;CACrD,OAAO,CAAC,CAAC,mBAAmB,IAAI,CAAC,EAAE;AACrC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Pretty-print newline-delimited JSON (NDJSON) for preview.
3
+ *
4
+ * NDJSON is one JSON value per line, so we format each line on its own and
5
+ * separate the records with a blank line to keep them visually distinct.
6
+ * Empty lines are dropped. Formatting is lenient: each line is reformatted as
7
+ * far as the JSONC formatter can restructure it, and anything it cannot parse
8
+ * is left as-is rather than rejected, so a malformed or partial record never
9
+ * breaks the whole preview.
10
+ */
11
+ export declare function prettifyNdjson(content: string): string;
12
+ //# sourceMappingURL=prettify-ndjson.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prettify-ndjson.d.ts","sourceRoot":"","sources":["../../../../../src/v2/blocks/response-block/helpers/prettify-ndjson.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAOtD"}
@@ -0,0 +1,19 @@
1
+ import { prettifyJsoncString } from "./prettify-jsonc-string.js";
2
+ //#region src/v2/blocks/response-block/helpers/prettify-ndjson.ts
3
+ /**
4
+ * Pretty-print newline-delimited JSON (NDJSON) for preview.
5
+ *
6
+ * NDJSON is one JSON value per line, so we format each line on its own and
7
+ * separate the records with a blank line to keep them visually distinct.
8
+ * Empty lines are dropped. Formatting is lenient: each line is reformatted as
9
+ * far as the JSONC formatter can restructure it, and anything it cannot parse
10
+ * is left as-is rather than rejected, so a malformed or partial record never
11
+ * breaks the whole preview.
12
+ */
13
+ function prettifyNdjson(content) {
14
+ return content.split("\n").map((line) => line.trim()).filter((line) => line.length > 0).map((line) => prettifyJsoncString(line)).join("\n\n");
15
+ }
16
+ //#endregion
17
+ export { prettifyNdjson };
18
+
19
+ //# sourceMappingURL=prettify-ndjson.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prettify-ndjson.js","names":[],"sources":["../../../../../src/v2/blocks/response-block/helpers/prettify-ndjson.ts"],"sourcesContent":["import { prettifyJsoncString } from '@/v2/blocks/response-block/helpers/prettify-jsonc-string'\n\n/**\n * Pretty-print newline-delimited JSON (NDJSON) for preview.\n *\n * NDJSON is one JSON value per line, so we format each line on its own and\n * separate the records with a blank line to keep them visually distinct.\n * Empty lines are dropped. Formatting is lenient: each line is reformatted as\n * far as the JSONC formatter can restructure it, and anything it cannot parse\n * is left as-is rather than rejected, so a malformed or partial record never\n * breaks the whole preview.\n */\nexport function prettifyNdjson(content: string): string {\n return content\n .split('\\n')\n .map((line) => line.trim())\n .filter((line) => line.length > 0)\n .map((line) => prettifyJsoncString(line))\n .join('\\n\\n')\n}\n"],"mappings":";;;;;;;;;;;;AAYA,SAAgB,eAAe,SAAyB;CACtD,OAAO,QACJ,MAAM,IAAI,CAAC,CACX,KAAK,SAAS,KAAK,KAAK,CAAC,CAAC,CAC1B,QAAQ,SAAS,KAAK,SAAS,CAAC,CAAC,CACjC,KAAK,SAAS,oBAAoB,IAAI,CAAC,CAAC,CACxC,KAAK,MAAM;AAChB"}
@@ -1 +1 @@
1
- {"version":3,"file":"AuthSelector.vue.script.js","names":[],"sources":["../../../../../src/v2/blocks/scalar-auth-selector-block/components/AuthSelector.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n ScalarButton,\n type ScalarButton as ScalarButtonType,\n} from '@scalar/components/button'\nimport { ScalarComboboxMultiselect } from '@scalar/components/combobox'\nimport type { Icon } from '@scalar/components/icon'\nimport { ScalarIconButton } from '@scalar/components/icon-button'\nimport { ScalarListboxCheckbox } from '@scalar/components/listbox'\nimport { useModal } from '@scalar/components/modal'\nimport { ScalarIconCaretDown, ScalarIconTrash } from '@scalar/icons'\nimport type { SelectedSecurity } from '@scalar/workspace-store/entities/auth'\nimport type {\n AuthMeta,\n WorkspaceEventBus,\n} from '@scalar/workspace-store/events'\nimport { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport { unpackProxyObject } from '@scalar/workspace-store/helpers/unpack-proxy'\nimport {\n isAuthOptional,\n type MergedSecuritySchemes,\n} from '@scalar/workspace-store/request-example'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport type {\n OpenApiDocument,\n SecurityRequirementObject,\n ServerObject,\n} from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport { computed, ref, useId } from 'vue'\n\nimport DeleteRequestAuthModal from '@/v2/blocks/scalar-auth-selector-block/components/DeleteRequestAuthModal.vue'\nimport type { OAuth2Options } from '@/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue'\nimport {\n formatComplexScheme,\n formatScheme,\n getSecuritySchemeOptions,\n type SecuritySchemeOption,\n} from '@/v2/blocks/scalar-auth-selector-block/helpers/security-scheme'\nimport { CollapsibleSection } from '@/v2/components/layout'\n\nimport RequestAuthDataTable from './RequestAuthDataTable.vue'\n\nconst {\n environment,\n eventBus,\n createAnySecurityScheme = false,\n canDeleteSchemes = true,\n defaultOpen = true,\n isStatic = false,\n meta,\n proxyUrl,\n securityRequirements,\n securitySchemes,\n selectedSecurity,\n server,\n title,\n options,\n documentType,\n} = defineProps<{\n environment: XScalarEnvironment\n eventBus: WorkspaceEventBus\n /** Allows adding authentication which is not in the document */\n createAnySecurityScheme?: boolean\n /**\n * Whether schemes can be deleted from the selector. Enabled for the editable client, disabled in\n * the read-only reference where the schemes come from the document and cannot be removed.\n */\n canDeleteSchemes?: boolean\n /** Whether the authentication disclosure should start expanded */\n defaultOpen?: boolean\n /** Creates a static disclosure that cannot be collapsed */\n isStatic?: boolean\n meta: AuthMeta\n proxyUrl: string\n securityRequirements: OpenApiDocument['security']\n securitySchemes: MergedSecuritySchemes\n selectedSecurity: SelectedSecurity | undefined\n server: ServerObject | null\n title: string\n /** Any config options required for the OAuth2 flow */\n options?: OAuth2Options\n /** Type of the document the schemes belong to, used to label the missing-type warning */\n documentType?: 'openapi' | 'asyncapi'\n}>()\n\nconst titleId = useId()\nconst comboboxButtonRef = ref<typeof ScalarButtonType | null>(null)\nconst isDisclosureOpen = ref(false)\n\nconst deleteModal = useModal()\nconst schemeToDelete = ref<{\n label: string\n payload: SecurityRequirementObject\n} | null>(null)\n\n/**\n * Determines if authentication is required or optional\n *\n * Auth is optional when there is an empty security requirement and no complex requirements.\n * Complex requirements have multiple auth schemes combined (e.g., API key + OAuth).\n */\nconst authIndicator = computed<{ icon: Icon; text: string } | null>(() => {\n if (!securityRequirements?.length) {\n return null\n }\n\n const isOptional = isAuthOptional(securityRequirements)\n\n return {\n icon: isOptional ? 'Unlock' : 'Lock',\n text: isOptional ? 'Optional' : 'Required',\n }\n})\n\n/** All available auth scheme options for the dropdown */\nconst availableSchemeOptions = computed(() =>\n getSecuritySchemeOptions(\n securityRequirements ?? [],\n securitySchemes ?? {},\n selectedSecurity?.selectedSchemes ?? [],\n createAnySecurityScheme,\n ),\n)\n\n/** Currently active auth schemes selected for this operation or collection */\nconst activeSchemeOptions = computed<SecuritySchemeOption[]>(() => {\n const schemes = selectedSecurity?.selectedSchemes\n if (!schemes?.length) {\n return []\n }\n\n return schemes.flatMap((requirement) => {\n const schemeNames = Object.keys(requirement)\n\n if (schemeNames.length === 0) {\n return []\n }\n\n // Complex auth requirement with multiple schemes\n if (schemeNames.length > 1) {\n return formatComplexScheme(requirement)\n }\n\n // Simple auth requirement with single scheme\n const schemeName = schemeNames[0]\n if (!schemeName) {\n return []\n }\n\n const scheme = getResolvedRef(securitySchemes?.[schemeName])\n if (!scheme) {\n return []\n }\n\n return formatScheme({\n name: schemeName,\n value: requirement,\n })\n })\n})\n\n/**\n * Opens the combobox dropdown when clicking the auth indicator badge.\n * Prevents the disclosure from toggling if it is already open.\n */\nconst handleAuthIndicatorClick = (event: Event): void => {\n if (isDisclosureOpen.value) {\n event.stopPropagation()\n }\n comboboxButtonRef.value?.$el.click()\n}\n\n/**\n * Updates the selected auth schemes.\n * Separates existing schemes from newly created ones for the event payload.\n */\nconst handleSchemeSelection = (selected: SecuritySchemeOption[]): void => {\n const existingSchemes = selected\n .filter((option) => option.payload === undefined)\n .map((option) => unpackProxyObject(option.value, { depth: 2 }))\n\n const newSchemes = selected\n .filter((option) => option.payload !== undefined)\n .map((option) => ({\n name: option.label,\n scheme: option.payload!,\n }))\n\n eventBus.emit('auth:update:selected-security-schemes', {\n selectedRequirements: existingSchemes,\n newSchemes,\n meta,\n })\n}\n\n/** Shows the delete confirmation modal for the selected scheme */\nconst handleDeleteRequest = (option: {\n label: string\n value: SecurityRequirementObject\n}): void => {\n schemeToDelete.value = { label: option.label, payload: option.value }\n deleteModal.show()\n}\n\n/** Deletes the selected auth scheme after confirmation */\nconst handleDeleteConfirm = (): void => {\n if (!schemeToDelete.value) {\n return\n }\n\n eventBus.emit('auth:delete:security-scheme', {\n names: Object.keys(schemeToDelete.value.payload),\n })\n\n schemeToDelete.value = null\n deleteModal.hide()\n}\n\ndefineExpose({\n authIndicator,\n selectedSchemeOptions: activeSchemeOptions,\n schemeOptions: availableSchemeOptions,\n})\n</script>\n<template>\n <CollapsibleSection\n class=\"group/params relative\"\n :defaultOpen\n :isStatic=\"isStatic\"\n :itemCount=\"activeSchemeOptions.length\"\n @update:modelValue=\"(open) => (isDisclosureOpen = open)\">\n <template #title>\n <div\n :id=\"titleId\"\n class=\"inline-flex items-center gap-0.5 leading-[20px]\">\n <span>{{ title }}</span>\n\n <span\n v-if=\"authIndicator\"\n class=\"text-c-3 hover:bg-b-3 hover:text-c-1 -my-0.5 -mr-1 cursor-pointer rounded px-1 py-0.5 leading-[normal] font-normal\"\n :class=\"{ 'text-c-1': authIndicator.text === 'Required' }\"\n data-testid=\"auth-indicator\"\n @click=\"handleAuthIndicatorClick\">\n {{ authIndicator.text }}\n </span>\n </div>\n </template>\n\n <!-- Auth Dropdown (hidden when only one scheme is available) -->\n <template #actions>\n <ScalarComboboxMultiselect\n class=\"w-72 text-xs\"\n :modelValue=\"activeSchemeOptions\"\n multiple\n :options=\"availableSchemeOptions\"\n placement=\"bottom-end\"\n teleport\n @delete=\"handleDeleteRequest\"\n @update:modelValue=\"handleSchemeSelection\">\n <ScalarButton\n ref=\"comboboxButtonRef\"\n :aria-describedby=\"titleId\"\n class=\"group/combobox-button hover:text-c-1 text-c-2 flex h-fit w-full items-center gap-1 px-0.75 py-0.25 text-base font-normal\"\n variant=\"ghost\">\n <!-- Single auth scheme selected -->\n <template v-if=\"activeSchemeOptions.length === 1\">\n <span class=\"sr-only\">Selected Auth Type:</span>\n {{ activeSchemeOptions[0]?.label }}\n </template>\n\n <!-- Multiple auth schemes selected -->\n <template v-else-if=\"activeSchemeOptions.length > 1\">\n Multiple\n <span class=\"sr-only\">Auth Types Selected</span>\n </template>\n\n <!-- No auth schemes selected -->\n <template v-else>\n <span class=\"sr-only\">Select</span>\n Auth Type\n </template>\n\n <ScalarIconCaretDown\n class=\"size-3 shrink-0 transition-transform duration-100 group-aria-expanded/combobox-button:rotate-180\"\n weight=\"bold\" />\n </ScalarButton>\n\n <template #option=\"{ option, selected }\">\n <ScalarListboxCheckbox\n multiselect\n :selected=\"selected\" />\n <div class=\"min-w-0 flex-1 truncate\">\n {{ option.label }}\n </div>\n <ScalarIconButton\n v-if=\"option.isDeletable && canDeleteSchemes\"\n class=\"-m-0.5 shrink-0 p-0.5 opacity-0 group-hover/item:opacity-100\"\n :icon=\"ScalarIconTrash\"\n :label=\"`Delete ${option.label}`\"\n size=\"xs\"\n @click.stop=\"handleDeleteRequest(option)\" />\n </template>\n </ScalarComboboxMultiselect>\n </template>\n\n <!-- Auth Table -->\n <RequestAuthDataTable\n :activeAuthIndex=\"selectedSecurity?.selectedIndex ?? 0\"\n :documentType\n :environment\n :eventBus\n :isStatic\n :meta\n :options\n :proxyUrl\n :securitySchemes\n :selectedSchemeOptions=\"activeSchemeOptions\"\n :server />\n\n <!-- Delete Auth Modal -->\n <DeleteRequestAuthModal\n v-if=\"schemeToDelete\"\n :label=\"schemeToDelete.label\"\n :scheme=\"schemeToDelete\"\n :state=\"deleteModal\"\n @close=\"deleteModal.hide()\"\n @delete=\"handleDeleteConfirm\" />\n </CollapsibleSection>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"AuthSelector.vue.script.js","names":[],"sources":["../../../../../src/v2/blocks/scalar-auth-selector-block/components/AuthSelector.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n ScalarButton,\n type ScalarButton as ScalarButtonType,\n} from '@scalar/components/button'\nimport { ScalarComboboxMultiselect } from '@scalar/components/combobox'\nimport type { Icon } from '@scalar/components/icon'\nimport { ScalarIconButton } from '@scalar/components/icon-button'\nimport { ScalarListboxCheckbox } from '@scalar/components/listbox'\nimport { useModal } from '@scalar/components/modal'\nimport { ScalarIconCaretDown, ScalarIconTrash } from '@scalar/icons'\nimport type { SelectedSecurity } from '@scalar/workspace-store/entities/auth'\nimport type {\n AuthMeta,\n WorkspaceEventBus,\n} from '@scalar/workspace-store/events'\nimport { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport { unpackProxyObject } from '@scalar/workspace-store/helpers/unpack-proxy'\nimport {\n isAuthOptional,\n type MergedSecuritySchemes,\n} from '@scalar/workspace-store/request-example'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport type {\n OpenApiDocument,\n SecurityRequirementObject,\n ServerObject,\n} from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport { computed, ref, useId } from 'vue'\n\nimport DeleteRequestAuthModal from '@/v2/blocks/scalar-auth-selector-block/components/DeleteRequestAuthModal.vue'\nimport type { OAuth2Options } from '@/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue'\nimport {\n formatComplexScheme,\n formatScheme,\n getSecuritySchemeOptions,\n type SecuritySchemeOption,\n} from '@/v2/blocks/scalar-auth-selector-block/helpers/security-scheme'\nimport { CollapsibleSection } from '@/v2/components/layout'\n\nimport RequestAuthDataTable from './RequestAuthDataTable.vue'\n\nconst {\n environment,\n eventBus,\n createAnySecurityScheme = false,\n canDeleteSchemes = true,\n defaultOpen = true,\n isStatic = false,\n meta,\n proxyUrl,\n securityRequirements,\n securitySchemes,\n selectedSecurity,\n server,\n title,\n options,\n documentType,\n} = defineProps<{\n environment: XScalarEnvironment\n eventBus: WorkspaceEventBus\n /** Allows adding authentication which is not in the document */\n createAnySecurityScheme?: boolean\n /**\n * Whether schemes can be deleted from the selector. Enabled for the editable client, disabled in\n * the read-only reference where the schemes come from the document and cannot be removed.\n */\n canDeleteSchemes?: boolean\n /** Whether the authentication disclosure should start expanded */\n defaultOpen?: boolean\n /** Creates a static disclosure that cannot be collapsed */\n isStatic?: boolean\n meta: AuthMeta\n proxyUrl: string\n securityRequirements: OpenApiDocument['security']\n securitySchemes: MergedSecuritySchemes\n selectedSecurity: SelectedSecurity | undefined\n server: ServerObject | null\n title: string\n /** Any config options required for the OAuth2 flow */\n options?: OAuth2Options\n /** Type of the document the schemes belong to, used to label the missing-type warning */\n documentType?: 'openapi' | 'asyncapi'\n}>()\n\nconst titleId = useId()\nconst comboboxButtonRef = ref<typeof ScalarButtonType | null>(null)\nconst isDisclosureOpen = ref(false)\n\nconst deleteModal = useModal()\nconst schemeToDelete = ref<{\n label: string\n payload: SecurityRequirementObject\n} | null>(null)\n\n/**\n * Determines if authentication is required or optional\n *\n * Auth is optional when there is an empty security requirement and no complex requirements.\n * Complex requirements have multiple auth schemes combined (e.g., API key + OAuth).\n */\nconst authIndicator = computed<{ icon: Icon; text: string } | null>(() => {\n if (!securityRequirements?.length) {\n return null\n }\n\n const isOptional = isAuthOptional(securityRequirements)\n\n return {\n icon: isOptional ? 'Unlock' : 'Lock',\n text: isOptional ? 'Optional' : 'Required',\n }\n})\n\n/** All available auth scheme options for the dropdown */\nconst availableSchemeOptions = computed(() =>\n getSecuritySchemeOptions(\n securityRequirements ?? [],\n securitySchemes ?? {},\n selectedSecurity?.selectedSchemes ?? [],\n createAnySecurityScheme,\n ),\n)\n\n/** Currently active auth schemes selected for this operation or collection */\nconst activeSchemeOptions = computed<SecuritySchemeOption[]>(() => {\n const schemes = selectedSecurity?.selectedSchemes\n if (!schemes?.length) {\n return []\n }\n\n return schemes.flatMap((requirement) => {\n const schemeNames = Object.keys(requirement)\n\n if (schemeNames.length === 0) {\n return []\n }\n\n // Complex auth requirement with multiple schemes\n if (schemeNames.length > 1) {\n return formatComplexScheme(requirement)\n }\n\n // Simple auth requirement with single scheme\n const schemeName = schemeNames[0]\n if (!schemeName) {\n return []\n }\n\n const scheme = getResolvedRef(securitySchemes?.[schemeName])\n if (!scheme) {\n return []\n }\n\n return formatScheme({\n name: schemeName,\n value: requirement,\n })\n })\n})\n\n/**\n * Opens the combobox dropdown when clicking the auth indicator badge.\n * Prevents the disclosure from toggling if it is already open.\n */\nconst handleAuthIndicatorClick = (event: Event): void => {\n if (isDisclosureOpen.value) {\n event.stopPropagation()\n }\n comboboxButtonRef.value?.$el.click()\n}\n\n/**\n * Updates the selected auth schemes.\n * Separates existing schemes from newly created ones for the event payload.\n */\nconst handleSchemeSelection = (selected: SecuritySchemeOption[]): void => {\n const existingSchemes = selected\n .filter((option) => option.payload === undefined)\n .map((option) => unpackProxyObject(option.value, { depth: 2 }))\n\n const newSchemes = selected\n .filter((option) => option.payload !== undefined)\n .map((option) => ({\n name: option.label,\n scheme: option.payload!,\n }))\n\n eventBus.emit('auth:update:selected-security-schemes', {\n selectedRequirements: existingSchemes,\n newSchemes,\n meta,\n })\n}\n\n/** Shows the delete confirmation modal for the selected scheme */\nconst handleDeleteRequest = (option: {\n label: string\n value: SecurityRequirementObject\n}): void => {\n schemeToDelete.value = { label: option.label, payload: option.value }\n deleteModal.show()\n}\n\n/** Deletes the selected auth scheme after confirmation */\nconst handleDeleteConfirm = (): void => {\n if (!schemeToDelete.value) {\n return\n }\n\n eventBus.emit('auth:delete:security-scheme', {\n names: Object.keys(schemeToDelete.value.payload),\n })\n\n schemeToDelete.value = null\n deleteModal.hide()\n}\n\ndefineExpose({\n authIndicator,\n selectedSchemeOptions: activeSchemeOptions,\n schemeOptions: availableSchemeOptions,\n})\n</script>\n<template>\n <CollapsibleSection\n class=\"group/params relative\"\n :defaultOpen\n :isStatic=\"isStatic\"\n :itemCount=\"activeSchemeOptions.length\"\n @update:modelValue=\"(open) => (isDisclosureOpen = open)\">\n <template #title>\n <div\n :id=\"titleId\"\n class=\"inline-flex items-center gap-0.5 leading-[20px]\">\n <span>{{ title }}</span>\n\n <span\n v-if=\"authIndicator\"\n class=\"text-c-3 hover:bg-b-3 hover:text-c-1 -my-0.5 -mr-1 cursor-pointer rounded px-1 py-0.5 leading-[normal] font-normal\"\n :class=\"{ 'text-c-1': authIndicator.text === 'Required' }\"\n data-testid=\"auth-indicator\"\n @click=\"handleAuthIndicatorClick\">\n {{ authIndicator.text }}\n </span>\n </div>\n </template>\n\n <!-- Auth Dropdown (hidden when only one scheme is available) -->\n <template #actions>\n <ScalarComboboxMultiselect\n class=\"w-72 text-xs\"\n :modelValue=\"activeSchemeOptions\"\n multiple\n :options=\"availableSchemeOptions\"\n placement=\"bottom-end\"\n teleport\n @delete=\"handleDeleteRequest\"\n @update:modelValue=\"handleSchemeSelection\">\n <ScalarButton\n ref=\"comboboxButtonRef\"\n :aria-describedby=\"titleId\"\n class=\"group/combobox-button hover:text-c-1 text-c-2 flex h-fit w-full items-center gap-1 px-0.75 py-0.25 text-base font-normal\"\n variant=\"ghost\">\n <!-- Single auth scheme selected -->\n <template v-if=\"activeSchemeOptions.length === 1\">\n <span class=\"sr-only\">Selected Auth Type:</span>\n {{ activeSchemeOptions[0]?.label }}\n </template>\n\n <!-- Multiple auth schemes selected -->\n <template v-else-if=\"activeSchemeOptions.length > 1\">\n Multiple\n <span class=\"sr-only\">Auth Types Selected</span>\n </template>\n\n <!-- No auth schemes selected -->\n <template v-else>\n <span class=\"sr-only\">Select</span>\n Auth Type\n </template>\n\n <ScalarIconCaretDown\n class=\"size-3 shrink-0 transition-transform duration-100 group-aria-expanded/combobox-button:rotate-180\"\n weight=\"bold\" />\n </ScalarButton>\n\n <template #option=\"{ option, selected }\">\n <ScalarListboxCheckbox\n multiselect\n :selected=\"selected\" />\n <div class=\"min-w-0 flex-1 truncate\">\n {{ option.label }}\n </div>\n <ScalarIconButton\n v-if=\"option.isDeletable && canDeleteSchemes\"\n class=\"-m-0.5 shrink-0 p-0.5 opacity-0 group-hover/item:opacity-100\"\n :icon=\"ScalarIconTrash\"\n :label=\"`Delete ${option.label}`\"\n size=\"xs\"\n @click.stop=\"handleDeleteRequest(option)\" />\n </template>\n </ScalarComboboxMultiselect>\n </template>\n\n <!-- Auth Table -->\n <RequestAuthDataTable\n :activeAuthIndex=\"selectedSecurity?.selectedIndex ?? 0\"\n :documentType\n :environment\n :eventBus\n :isStatic\n :meta\n :options\n :proxyUrl\n :securitySchemes\n :selectedSchemeOptions=\"activeSchemeOptions\"\n :server />\n\n <!-- Delete Auth Modal -->\n <DeleteRequestAuthModal\n v-if=\"schemeToDelete\"\n :label=\"schemeToDelete.label\"\n :scheme=\"schemeToDelete\"\n :state=\"deleteModal\"\n @close=\"deleteModal.hide()\"\n @delete=\"handleDeleteConfirm\" />\n </CollapsibleSection>\n</template>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"RequestAuthTab.vue.d.ts","sourceRoot":"","sources":["../../../../../src/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue"],"names":[],"mappings":"AA4yBA,OAAO,KAAK,EAEV,iBAAiB,EAClB,MAAM,gCAAgC,CAAA;AAEvC,OAAO,EAML,KAAK,qBAAqB,EAI3B,MAAM,yCAAyC,CAAA;AAChD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2EAA2E,CAAA;AAEnH,OAAO,KAAK,EAEV,yBAAyB,EACzB,YAAY,EACb,MAAM,8DAA8D,CAAA;AAerE,OAAe,EAAE,KAAK,aAAa,EAAE,MAAM,cAAc,CAAA;AAUzD,KAAK,WAAW,GAAG;IACjB,wCAAwC;IACxC,WAAW,EAAE,kBAAkB,CAAA;IAC/B,yFAAyF;IACzF,QAAQ,EAAE,OAAO,CAAA;IACjB,gBAAgB;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,+BAA+B;IAC/B,uBAAuB,EAAE,yBAAyB,CAAA;IAClD,oGAAoG;IACpG,eAAe,EAAE,qBAAqB,CAAA;IACtC,mCAAmC;IACnC,MAAM,EAAE,YAAY,GAAG,IAAI,CAAA;IAC3B,2CAA2C;IAC3C,QAAQ,EAAE,iBAAiB,CAAA;IAC3B,uDAAuD;IACvD,OAAO,CAAC,EAAE,aAAa,CAAA;IACvB,yFAAyF;IACzF,YAAY,CAAC,EAAE,SAAS,GAAG,UAAU,CAAA;CACtC,CAAC;AA09CF,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kFAGhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
1
+ {"version":3,"file":"RequestAuthTab.vue.d.ts","sourceRoot":"","sources":["../../../../../src/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue"],"names":[],"mappings":"AAuzBA,OAAO,KAAK,EAEV,iBAAiB,EAClB,MAAM,gCAAgC,CAAA;AAEvC,OAAO,EAML,KAAK,qBAAqB,EAK3B,MAAM,yCAAyC,CAAA;AAChD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2EAA2E,CAAA;AAEnH,OAAO,KAAK,EAEV,yBAAyB,EACzB,YAAY,EACb,MAAM,8DAA8D,CAAA;AAgBrE,OAAe,EAAE,KAAK,aAAa,EAAE,MAAM,cAAc,CAAA;AAYzD,KAAK,WAAW,GAAG;IACjB,wCAAwC;IACxC,WAAW,EAAE,kBAAkB,CAAA;IAC/B,yFAAyF;IACzF,QAAQ,EAAE,OAAO,CAAA;IACjB,gBAAgB;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,+BAA+B;IAC/B,uBAAuB,EAAE,yBAAyB,CAAA;IAClD,oGAAoG;IACpG,eAAe,EAAE,qBAAqB,CAAA;IACtC,mCAAmC;IACnC,MAAM,EAAE,YAAY,GAAG,IAAI,CAAA;IAC3B,2CAA2C;IAC3C,QAAQ,EAAE,iBAAiB,CAAA;IAC3B,uDAAuD;IACvD,OAAO,CAAC,EAAE,aAAa,CAAA;IACvB,yFAAyF;IACzF,YAAY,CAAC,EAAE,SAAS,GAAG,UAAU,CAAA;CACtC,CAAC;AAi+CF,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kFAGhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}