@scalar/api-client 3.0.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/README.md +41 -0
- package/dist/components/HttpMethod/HttpMethod.vue.d.ts +2 -2
- package/dist/components/Sidebar/Actions/SidebarListElementForm.vue.d.ts +2 -2
- package/dist/plugins/posthog/index.d.ts +23 -0
- package/dist/plugins/posthog/index.d.ts.map +1 -0
- package/dist/plugins/posthog/index.js +58 -0
- package/dist/plugins/posthog/index.js.map +1 -0
- package/dist/style.css +121 -61
- package/dist/v2/blocks/operation-block/OperationBlock.vue.d.ts.map +1 -1
- package/dist/v2/blocks/operation-block/OperationBlock.vue.js.map +1 -1
- package/dist/v2/blocks/operation-block/OperationBlock.vue.script.js +15 -12
- package/dist/v2/blocks/operation-block/OperationBlock.vue.script.js.map +1 -1
- package/dist/v2/blocks/operation-block/helpers/decode-buffer.d.ts +5 -2
- package/dist/v2/blocks/operation-block/helpers/decode-buffer.d.ts.map +1 -1
- package/dist/v2/blocks/operation-block/helpers/decode-buffer.js +5 -2
- package/dist/v2/blocks/operation-block/helpers/decode-buffer.js.map +1 -1
- package/dist/v2/blocks/operation-block/helpers/har-to-fetch-request.d.ts +8 -9
- package/dist/v2/blocks/operation-block/helpers/har-to-fetch-request.d.ts.map +1 -1
- package/dist/v2/blocks/operation-block/helpers/har-to-fetch-request.js +8 -10
- package/dist/v2/blocks/operation-block/helpers/har-to-fetch-request.js.map +1 -1
- package/dist/v2/blocks/operation-block/helpers/response-cache.d.ts +2 -1
- package/dist/v2/blocks/operation-block/helpers/response-cache.d.ts.map +1 -1
- package/dist/v2/blocks/operation-block/helpers/response-cache.js.map +1 -1
- package/dist/v2/blocks/operation-block/helpers/send-request.d.ts +11 -3
- package/dist/v2/blocks/operation-block/helpers/send-request.d.ts.map +1 -1
- package/dist/v2/blocks/operation-block/helpers/send-request.js +19 -12
- package/dist/v2/blocks/operation-block/helpers/send-request.js.map +1 -1
- package/dist/v2/blocks/operation-code-sample/components/OperationCodeSample.vue.d.ts.map +1 -1
- package/dist/v2/blocks/operation-code-sample/components/OperationCodeSample.vue.js +1 -1
- package/dist/v2/blocks/operation-code-sample/components/OperationCodeSample.vue.js.map +1 -1
- package/dist/v2/blocks/operation-code-sample/components/OperationCodeSample.vue.script.js +4 -0
- package/dist/v2/blocks/operation-code-sample/components/OperationCodeSample.vue.script.js.map +1 -1
- package/dist/v2/blocks/request-block/RequestBlock.vue.script.js +1 -1
- package/dist/v2/blocks/request-block/components/RequestBody.vue.d.ts.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestBody.vue.js +1 -1
- package/dist/v2/blocks/request-block/components/RequestBody.vue.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestBody.vue.script.js +1 -0
- package/dist/v2/blocks/request-block/components/RequestBody.vue.script.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestTableRow.vue.d.ts.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestTableRow.vue.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestTableRow.vue.script.js +1 -0
- package/dist/v2/blocks/request-block/components/RequestTableRow.vue.script.js.map +1 -1
- package/dist/v2/blocks/request-block/helpers/get-default-headers.js +1 -1
- package/dist/v2/blocks/response-block/ResponseBlock.vue.d.ts +3 -2
- package/dist/v2/blocks/response-block/ResponseBlock.vue.d.ts.map +1 -1
- package/dist/v2/blocks/response-block/ResponseBlock.vue.js +1 -1
- package/dist/v2/blocks/response-block/ResponseBlock.vue.js.map +1 -1
- package/dist/v2/blocks/response-block/ResponseBlock.vue.script.js +12 -6
- package/dist/v2/blocks/response-block/ResponseBlock.vue.script.js.map +1 -1
- package/dist/v2/blocks/response-block/components/ResponseBody.vue.d.ts +2 -0
- package/dist/v2/blocks/response-block/components/ResponseBody.vue.d.ts.map +1 -1
- package/dist/v2/blocks/response-block/components/ResponseBody.vue.js +1 -1
- package/dist/v2/blocks/response-block/components/ResponseBody.vue.js.map +1 -1
- package/dist/v2/blocks/response-block/components/ResponseBody.vue.script.js +34 -14
- package/dist/v2/blocks/response-block/components/ResponseBody.vue.script.js.map +1 -1
- package/dist/v2/blocks/response-block/helpers/process-response-body.d.ts +1 -1
- package/dist/v2/blocks/response-block/helpers/process-response-body.js +2 -3
- package/dist/v2/blocks/response-block/helpers/process-response-body.js.map +1 -1
- package/dist/v2/blocks/response-block/helpers/resolve-response-body-handler.d.ts +11 -0
- package/dist/v2/blocks/response-block/helpers/resolve-response-body-handler.d.ts.map +1 -0
- package/dist/v2/blocks/response-block/helpers/resolve-response-body-handler.js +44 -0
- package/dist/v2/blocks/response-block/helpers/resolve-response-body-handler.js.map +1 -0
- package/dist/v2/blocks/response-block/helpers/resolve-response-content-type.d.ts +14 -0
- package/dist/v2/blocks/response-block/helpers/resolve-response-content-type.d.ts.map +1 -0
- package/dist/v2/blocks/response-block/helpers/resolve-response-content-type.js +13 -0
- package/dist/v2/blocks/response-block/helpers/resolve-response-content-type.js.map +1 -0
- package/dist/v2/blocks/scalar-address-bar-block/components/AddressBar.vue.d.ts +1 -1
- package/dist/v2/blocks/scalar-address-bar-block/components/EnvironmentSelector.vue.js.map +1 -1
- package/dist/v2/blocks/scalar-address-bar-block/components/EnvironmentSelector.vue.script.js +3 -3
- package/dist/v2/blocks/scalar-address-bar-block/components/EnvironmentSelector.vue.script.js.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/AuthSelector.vue.script.js.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue.d.ts.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue.js.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue.script.js +131 -48
- package/dist/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue.script.js.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/OAuthScopesAddModal.vue.d.ts +2 -2
- package/dist/v2/blocks/scalar-auth-selector-block/components/OAuthScopesAddModal.vue.d.ts.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/helpers/extract-security-scheme-secrets.d.ts.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth.d.ts +16 -0
- package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth.d.ts.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth.js +43 -1
- package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth.js.map +1 -1
- package/dist/v2/components/code-input/CodeInput.vue.d.ts +6 -2
- package/dist/v2/components/code-input/CodeInput.vue.d.ts.map +1 -1
- package/dist/v2/components/code-input/CodeInput.vue.js +1 -1
- package/dist/v2/components/code-input/CodeInput.vue.js.map +1 -1
- package/dist/v2/components/code-input/CodeInput.vue.script.js +9 -4
- package/dist/v2/components/code-input/CodeInput.vue.script.js.map +1 -1
- package/dist/v2/components/data-table/DataTableInput.vue.d.ts +3 -0
- package/dist/v2/components/data-table/DataTableInput.vue.d.ts.map +1 -1
- package/dist/v2/components/data-table/DataTableInput.vue.js +1 -1
- package/dist/v2/components/data-table/DataTableInput.vue.js.map +1 -1
- package/dist/v2/components/data-table/DataTableInput.vue.script.js +7 -1
- package/dist/v2/components/data-table/DataTableInput.vue.script.js.map +1 -1
- package/dist/v2/components/forms/ConfirmationForm.vue.d.ts +2 -2
- package/dist/v2/constants.js +1 -1
- package/dist/v2/features/app/App.vue.d.ts.map +1 -1
- package/dist/v2/features/app/App.vue.js.map +1 -1
- package/dist/v2/features/app/App.vue.script.js +17 -4
- package/dist/v2/features/app/App.vue.script.js.map +1 -1
- package/dist/v2/features/app/app-state.d.ts +6 -1
- package/dist/v2/features/app/app-state.d.ts.map +1 -1
- package/dist/v2/features/app/app-state.js +5 -3
- package/dist/v2/features/app/app-state.js.map +1 -1
- package/dist/v2/features/app/components/DesktopTab.vue.d.ts +2 -2
- package/dist/v2/features/app/helpers/create-api-client-app.d.ts +9 -1
- package/dist/v2/features/app/helpers/create-api-client-app.d.ts.map +1 -1
- package/dist/v2/features/app/helpers/create-api-client-app.js +3 -2
- package/dist/v2/features/app/helpers/create-api-client-app.js.map +1 -1
- package/dist/v2/features/app/helpers/create-temp-operation.d.ts.map +1 -1
- package/dist/v2/features/app/helpers/create-temp-operation.js +4 -1
- package/dist/v2/features/app/helpers/create-temp-operation.js.map +1 -1
- package/dist/v2/features/app/helpers/routes.d.ts +4 -2
- package/dist/v2/features/app/helpers/routes.d.ts.map +1 -1
- package/dist/v2/features/app/helpers/routes.js.map +1 -1
- package/dist/v2/features/collection/DocumentCollection.vue.script.js +2 -1
- package/dist/v2/features/collection/DocumentCollection.vue.script.js.map +1 -1
- package/dist/v2/features/collection/OperationCollection.vue.script.js +2 -1
- package/dist/v2/features/collection/OperationCollection.vue.script.js.map +1 -1
- package/dist/v2/features/collection/WorkspaceCollection.vue.script.js +2 -1
- package/dist/v2/features/collection/WorkspaceCollection.vue.script.js.map +1 -1
- package/dist/v2/features/collection/components/Authentication.vue.d.ts.map +1 -1
- package/dist/v2/features/collection/components/Authentication.vue.js +1 -1
- package/dist/v2/features/collection/components/Authentication.vue.js.map +1 -1
- package/dist/v2/features/collection/components/Authentication.vue.script.js +10 -1
- package/dist/v2/features/collection/components/Authentication.vue.script.js.map +1 -1
- package/dist/v2/features/collection/components/Cookies.vue.script.js +1 -0
- package/dist/v2/features/collection/components/Cookies.vue.script.js.map +1 -1
- package/dist/v2/features/collection/components/Editor/Editor.vue.script.js +1 -0
- package/dist/v2/features/collection/components/Editor/Editor.vue.script.js.map +1 -1
- package/dist/v2/features/collection/components/Environment.vue.script.js +1 -0
- package/dist/v2/features/collection/components/Environment.vue.script.js.map +1 -1
- package/dist/v2/features/collection/components/Form.vue.d.ts +2 -0
- package/dist/v2/features/collection/components/Form.vue.d.ts.map +1 -1
- package/dist/v2/features/collection/components/Form.vue.js.map +1 -1
- package/dist/v2/features/collection/components/Form.vue.script.js +4 -1
- package/dist/v2/features/collection/components/Form.vue.script.js.map +1 -1
- package/dist/v2/features/collection/components/LabelInput.vue.d.ts +1 -1
- package/dist/v2/features/collection/components/Overview.vue.script.js +1 -0
- package/dist/v2/features/collection/components/Overview.vue.script.js.map +1 -1
- package/dist/v2/features/collection/components/Runner/components/Runner.vue.d.ts.map +1 -1
- package/dist/v2/features/collection/components/Runner/components/Runner.vue.js.map +1 -1
- package/dist/v2/features/collection/components/Runner/components/Runner.vue.script.js +4 -2
- package/dist/v2/features/collection/components/Runner/components/Runner.vue.script.js.map +1 -1
- package/dist/v2/features/collection/components/Runner/components/RunnerTree.vue.d.ts +2 -2
- package/dist/v2/features/collection/components/Runner/hooks/use-runner-execution.d.ts +4 -2
- package/dist/v2/features/collection/components/Runner/hooks/use-runner-execution.d.ts.map +1 -1
- package/dist/v2/features/collection/components/Runner/hooks/use-runner-execution.js +3 -2
- package/dist/v2/features/collection/components/Runner/hooks/use-runner-execution.js.map +1 -1
- package/dist/v2/features/collection/components/Scripts.vue.script.js +1 -0
- package/dist/v2/features/collection/components/Scripts.vue.script.js.map +1 -1
- package/dist/v2/features/collection/components/Servers.vue.d.ts.map +1 -1
- package/dist/v2/features/collection/components/Servers.vue.js.map +1 -1
- package/dist/v2/features/collection/components/Servers.vue.script.js +3 -1
- package/dist/v2/features/collection/components/Servers.vue.script.js.map +1 -1
- package/dist/v2/features/collection/components/Settings.vue.script.js +1 -0
- package/dist/v2/features/collection/components/Settings.vue.script.js.map +1 -1
- package/dist/v2/features/command-palette/components/CommandActionForm.vue.d.ts +2 -2
- package/dist/v2/features/command-palette/components/CommandPaletteImport.vue.d.ts.map +1 -1
- package/dist/v2/features/command-palette/components/CommandPaletteImport.vue.js.map +1 -1
- package/dist/v2/features/command-palette/components/CommandPaletteImport.vue.script.js +1 -1
- package/dist/v2/features/command-palette/components/CommandPaletteImport.vue.script.js.map +1 -1
- package/dist/v2/features/command-palette/components/CommandPaletteImportPostman.vue.d.ts.map +1 -1
- package/dist/v2/features/command-palette/components/CommandPaletteImportPostman.vue.js.map +1 -1
- package/dist/v2/features/command-palette/components/CommandPaletteImportPostman.vue.script.js +26 -21
- package/dist/v2/features/command-palette/components/CommandPaletteImportPostman.vue.script.js.map +1 -1
- package/dist/v2/features/command-palette/components/PostmanImportPreview.vue.js +1 -1
- package/dist/v2/features/command-palette/components/PostmanImportPreview.vue.js.map +1 -1
- package/dist/v2/features/command-palette/components/PostmanImportPreview.vue.script.js +1 -1
- package/dist/v2/features/command-palette/components/PostmanImportPreview.vue.script.js.map +1 -1
- package/dist/v2/features/command-palette/helpers/get-postman-convert-options.d.ts +14 -0
- package/dist/v2/features/command-palette/helpers/get-postman-convert-options.d.ts.map +1 -0
- package/dist/v2/features/command-palette/helpers/get-postman-convert-options.js +19 -0
- package/dist/v2/features/command-palette/helpers/get-postman-convert-options.js.map +1 -0
- package/dist/v2/features/command-palette/helpers/get-postman-document-details.js +1 -1
- package/dist/v2/features/command-palette/helpers/get-postman-document-details.js.map +1 -1
- package/dist/v2/features/command-palette/helpers/load-document-from-source.d.ts.map +1 -1
- package/dist/v2/features/command-palette/helpers/load-document-from-source.js +1 -1
- package/dist/v2/features/command-palette/helpers/load-document-from-source.js.map +1 -1
- package/dist/v2/features/environments/components/EnvironmentDeleteModal.vue.d.ts +2 -2
- package/dist/v2/features/environments/components/EnvironmentVariablesDropdown.vue.d.ts +1 -1
- package/dist/v2/features/environments/components/EnvironmentVariablesDropdown.vue.d.ts.map +1 -1
- package/dist/v2/features/environments/components/EnvironmentVariablesDropdown.vue.js.map +1 -1
- package/dist/v2/features/environments/components/EnvironmentVariablesDropdown.vue.script.js +2 -2
- package/dist/v2/features/environments/components/EnvironmentVariablesDropdown.vue.script.js.map +1 -1
- package/dist/v2/features/global-cookies/components/CookiesTable.vue.d.ts.map +1 -1
- package/dist/v2/features/global-cookies/components/CookiesTable.vue.js +1 -1
- package/dist/v2/features/global-cookies/components/CookiesTable.vue.js.map +1 -1
- package/dist/v2/features/global-cookies/components/CookiesTable.vue.script.js +2 -0
- package/dist/v2/features/global-cookies/components/CookiesTable.vue.script.js.map +1 -1
- package/dist/v2/features/modal/Modal.vue.d.ts +7 -6
- package/dist/v2/features/modal/Modal.vue.d.ts.map +1 -1
- package/dist/v2/features/modal/Modal.vue.js.map +1 -1
- package/dist/v2/features/modal/Modal.vue.script.js.map +1 -1
- package/dist/v2/features/modal/helpers/create-api-client-modal.d.ts +5 -5
- package/dist/v2/features/modal/helpers/create-api-client-modal.d.ts.map +1 -1
- package/dist/v2/features/modal/helpers/create-api-client-modal.js +11 -0
- package/dist/v2/features/modal/helpers/create-api-client-modal.js.map +1 -1
- package/dist/v2/features/modal/helpers/types.d.ts +1 -7
- package/dist/v2/features/modal/helpers/types.d.ts.map +1 -1
- package/dist/v2/features/modal/index.d.ts +1 -1
- package/dist/v2/features/modal/index.d.ts.map +1 -1
- package/dist/v2/features/operation/Operation.vue.d.ts +0 -5
- package/dist/v2/features/operation/Operation.vue.d.ts.map +1 -1
- package/dist/v2/features/operation/Operation.vue.js.map +1 -1
- package/dist/v2/features/operation/Operation.vue.script.js.map +1 -1
- package/dist/v2/types/options.d.ts +15 -0
- package/dist/v2/types/options.d.ts.map +1 -0
- package/package.json +21 -16
- package/dist/v2/features/command-palette/helpers/is-postman-collection.d.ts +0 -11
- package/dist/v2/features/command-palette/helpers/is-postman-collection.d.ts.map +0 -1
- package/dist/v2/features/command-palette/helpers/is-postman-collection.js +0 -24
- package/dist/v2/features/command-palette/helpers/is-postman-collection.js.map +0 -1
- package/dist/v2/posthog.d.ts +0 -3
- package/dist/v2/posthog.d.ts.map +0 -1
- package/dist/v2/posthog.js +0 -20
- package/dist/v2/posthog.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ResponseBlock.vue.js","names":[],"sources":["../../../../src/v2/blocks/response-block/ResponseBlock.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ScalarErrorBoundary } from '@scalar/components'\nimport { isDefined } from '@scalar/helpers/array/is-defined'\nimport type { ClientPlugin } from '@scalar/oas-utils/helpers'\nimport type { WorkspaceEventBus } from '@scalar/workspace-store/events'\nimport { computed, ref, useId } from 'vue'\n\nimport SectionFilter from '@/components/SectionFilter.vue'\nimport ViewLayoutSection from '@/components/ViewLayout/ViewLayoutSection.vue'\nimport type { ResponseInstance } from '@/v2/blocks/operation-block/helpers/send-request'\nimport
|
|
1
|
+
{"version":3,"file":"ResponseBlock.vue.js","names":[],"sources":["../../../../src/v2/blocks/response-block/ResponseBlock.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ScalarErrorBoundary } from '@scalar/components'\nimport { isDefined } from '@scalar/helpers/array/is-defined'\nimport type { ClientPlugin } from '@scalar/oas-utils/helpers'\nimport type { WorkspaceEventBus } from '@scalar/workspace-store/events'\nimport type { RequestPayload } from '@scalar/workspace-store/request-example'\nimport { computed, ref, useId } from 'vue'\n\nimport SectionFilter from '@/components/SectionFilter.vue'\nimport ViewLayoutSection from '@/components/ViewLayout/ViewLayoutSection.vue'\nimport type { ResponseInstance } from '@/v2/blocks/operation-block/helpers/send-request'\nimport HeadersComponent from '@/v2/blocks/response-block/components/Headers.vue'\nimport ResponseBody from '@/v2/blocks/response-block/components/ResponseBody.vue'\nimport ResponseBodyStreaming from '@/v2/blocks/response-block/components/ResponseBodyStreaming.vue'\nimport ResponseBodyVirtual from '@/v2/blocks/response-block/components/ResponseBodyVirtual.vue'\nimport ResponseCookies from '@/v2/blocks/response-block/components/ResponseCookies.vue'\nimport ResponseEmpty from '@/v2/blocks/response-block/components/ResponseEmpty.vue'\nimport ResponseLoadingOverlay from '@/v2/blocks/response-block/components/ResponseLoadingOverlay.vue'\nimport ResponseMetaInformation from '@/v2/blocks/response-block/components/ResponseMetaInformation.vue'\nimport { textMediaTypes } from '@/v2/blocks/response-block/helpers/media-types'\nimport { parseSetCookie } from '@/v2/blocks/response-block/helpers/parse-set-cookie'\nimport type { ClientLayout } from '@/v2/types/layout'\n\nconst { layout, totalPerformedRequests, response, requestPayload } =\n defineProps<{\n /** Preprocessed response */\n response: ResponseInstance | null\n /** Original request as a [url, RequestInit] tuple */\n requestPayload: RequestPayload | null\n /** Client layout */\n layout: ClientLayout\n /** Total number of performed requests */\n totalPerformedRequests: number\n /** Application version */\n appVersion: string\n /** Registered app plugins */\n plugins: ClientPlugin[]\n /** Workspace event bus */\n eventBus: WorkspaceEventBus\n }>()\n\n// Headers\nconst responseHeaders = computed(() => {\n const headers = response?.headers\n\n return headers\n ? Object.keys(headers).map((key) => ({\n name: key,\n value: headers[key] ?? '',\n }))\n : []\n})\n\n// Cookies\nconst responseCookies = computed(\n () =>\n response?.cookieHeaderKeys\n .map((setCookieValue) => parseSetCookie(setCookieValue))\n .filter(isDefined) ?? [],\n)\n\nconst responseSections = ['Cookies', 'Headers', 'Body'] as const\ntype Filter = 'All' | (typeof responseSections)[number]\nconst activeFilter = ref<Filter>('All')\n\nconst filters = computed<Filter[]>(() => ['All', ...responseSections])\n\nconst filterIds = computed(\n () =>\n Object.fromEntries(\n filters.value.map((section) => [section, useId()]),\n ) as Record<Filter, string>,\n)\n\n/** Threshold for virtualizing response bodies in bytes */\nconst VIRTUALIZATION_THRESHOLD = 200_000\nconst shouldVirtualize = computed(() => {\n if (!response || !('size' in response)) {\n return false\n }\n\n // Get content type from headers\n const contentType =\n response.headers?.['content-type'] || response.headers?.['Content-Type']\n\n // If no content type or response size is small, don't virtualize\n if (!contentType || (response.size ?? 0) <= VIRTUALIZATION_THRESHOLD) {\n return false\n }\n\n // Do not virtualize html\n if (contentType.includes('text/html')) {\n return false\n }\n\n // Check if content type matches any text-based type\n const isTextBased = textMediaTypes.some((type) => contentType.includes(type))\n\n return isTextBased && (response.size ?? 0) > VIRTUALIZATION_THRESHOLD\n})\n\nconst requestHeaders = computed(() => {\n const headers = requestPayload?.[1]?.headers\n if (!headers) {\n return []\n }\n\n // Normalise via the Headers constructor, and then spread\n return [...new Headers(headers)].map(([name, value]) => ({\n name,\n value,\n required: false,\n }))\n})\n\nconst isSectionVisible = (\n section: (typeof responseSections)[number] | 'All',\n) => {\n if (activeFilter.value === 'All' || activeFilter.value === section) {\n return true\n }\n return false\n}\n\ndefineExpose({\n responseHeaders,\n responseCookies,\n requestHeaders,\n shouldVirtualize,\n activeFilter,\n filters,\n})\n</script>\n<template>\n <ViewLayoutSection aria-label=\"Response\">\n <template #title>\n <div class=\"flex h-8 flex-1 items-center\">\n <div\n aria-live=\"polite\"\n class=\"flex items-center\"\n :class=\"{ 'animate-response-heading': response }\">\n <span class=\"response-heading pointer-events-none absolute\">\n Response\n </span>\n <ResponseMetaInformation\n v-if=\"response\"\n class=\"animate-response-children\"\n :eventBus=\"eventBus\"\n :response=\"response\" />\n </div>\n <SectionFilter\n v-model=\"activeFilter\"\n :filterIds=\"filterIds\"\n :filters=\"filters\" />\n </div>\n </template>\n <div\n :id=\"filterIds.All\"\n class=\"custom-scroll response-section-content relative grid h-full justify-stretch\"\n :class=\"{\n 'content-start': response,\n }\"\n :role=\"activeFilter === 'All' && response ? 'tabpanel' : 'none'\">\n <template v-if=\"!response\">\n <ResponseEmpty\n :appVersion=\"appVersion\"\n :layout=\"layout\"\n :totalPerformedRequests=\"totalPerformedRequests\"\n @addRequest=\"\n eventBus.emit('ui:open:command-palette', {\n action: 'create-request',\n payload: undefined,\n })\n \"\n @openCommandPalette=\"eventBus.emit('ui:open:command-palette')\"\n @sendRequest=\"eventBus.emit('operation:send:request:hotkey')\" />\n </template>\n <template v-else>\n <!-- Cookies section -->\n <ResponseCookies\n v-if=\"isSectionVisible('Cookies')\"\n :id=\"filterIds.Cookies\"\n class=\"response-section-content-cookies\"\n :cookies=\"responseCookies\"\n :role=\"activeFilter === 'All' ? 'none' : 'tabpanel'\" />\n <!-- Request headers section -->\n <HeadersComponent\n v-if=\"isSectionVisible('Headers')\"\n :id=\"filterIds.Headers\"\n class=\"response-section-content-headers\"\n :headers=\"requestHeaders\"\n :role=\"activeFilter === 'All' ? 'none' : 'tabpanel'\">\n <template #title>Request Headers</template>\n </HeadersComponent>\n <!-- Response headers section -->\n <HeadersComponent\n v-if=\"isSectionVisible('Headers')\"\n :id=\"filterIds.Headers\"\n class=\"response-section-content-headers\"\n :headers=\"responseHeaders\"\n :role=\"activeFilter === 'All' ? 'none' : 'tabpanel'\">\n <template #title>Response Headers</template>\n </HeadersComponent>\n\n <!-- Inject response section plugin components -->\n <ScalarErrorBoundary\n v-for=\"(plugin, index) in plugins\"\n :key=\"index\">\n <component\n :is=\"plugin.components.response.component\"\n v-if=\"plugin?.components?.response\"\n v-show=\"activeFilter === 'All'\"\n v-bind=\"plugin.components.response.additionalProps\" />\n </ScalarErrorBoundary>\n\n <template v-if=\"activeFilter === 'All' || activeFilter === 'Body'\">\n <!-- Streaming response body -->\n <ResponseBodyStreaming\n v-if=\"'reader' in response\"\n :id=\"filterIds.Body\"\n class=\"response-section-content-body\"\n :reader=\"response.reader\" />\n\n <!-- Virtualized Text for massive responses -->\n <ResponseBodyVirtual\n v-else-if=\"shouldVirtualize && typeof response?.data === 'string'\"\n :id=\"filterIds.Body\"\n :content=\"response!.data\"\n :data=\"response?.data\"\n :headers=\"responseHeaders\"\n :role=\"activeFilter === 'All' ? 'none' : 'tabpanel'\" />\n\n <!-- Regular response body -->\n <ResponseBody\n v-else\n :id=\"filterIds.Body\"\n :active=\"true\"\n class=\"response-section-content-body\"\n :data=\"response?.data\"\n :headers=\"responseHeaders\"\n layout=\"client\"\n :plugins=\"plugins\"\n :role=\"activeFilter === 'All' ? 'none' : 'tabpanel'\"\n title=\"Body\" />\n </template>\n </template>\n <ResponseLoadingOverlay :eventBus=\"eventBus\" />\n </div>\n </ViewLayoutSection>\n</template>\n<style scoped>\n.animate-response-heading .response-heading {\n animation: push-response 0.2s ease-in-out forwards;\n opacity: 1;\n}\n@keyframes push-response {\n from {\n opacity: 1;\n transform: translateY(0);\n }\n to {\n opacity: 0;\n transform: translateY(-4px);\n }\n}\n.animate-response-heading .animate-response-children {\n animation: response-spans 0.2s ease-in-out forwards 0.05s;\n opacity: 0;\n}\n\n@keyframes response-spans {\n from {\n opacity: 0;\n transform: translateY(4px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n</style>\n"],"mappings":""}
|
|
@@ -21,7 +21,7 @@ var ResponseBlock_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
|
|
|
21
21
|
__name: "ResponseBlock",
|
|
22
22
|
props: {
|
|
23
23
|
response: {},
|
|
24
|
-
|
|
24
|
+
requestPayload: {},
|
|
25
25
|
layout: {},
|
|
26
26
|
totalPerformedRequests: {},
|
|
27
27
|
appVersion: {},
|
|
@@ -53,11 +53,15 @@ var ResponseBlock_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
|
|
|
53
53
|
if (contentType.includes("text/html")) return false;
|
|
54
54
|
return textMediaTypes.some((type) => contentType.includes(type)) && (__props.response.size ?? 0) > VIRTUALIZATION_THRESHOLD;
|
|
55
55
|
});
|
|
56
|
-
const requestHeaders = computed(() =>
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
56
|
+
const requestHeaders = computed(() => {
|
|
57
|
+
const headers = __props.requestPayload?.[1]?.headers;
|
|
58
|
+
if (!headers) return [];
|
|
59
|
+
return [...new Headers(headers)].map(([name, value]) => ({
|
|
60
|
+
name,
|
|
61
|
+
value,
|
|
62
|
+
required: false
|
|
63
|
+
}));
|
|
64
|
+
});
|
|
61
65
|
const isSectionVisible = (section) => {
|
|
62
66
|
if (activeFilter.value === "All" || activeFilter.value === section) return true;
|
|
63
67
|
return false;
|
|
@@ -184,12 +188,14 @@ var ResponseBlock_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
|
|
|
184
188
|
data: __props.response?.data,
|
|
185
189
|
headers: responseHeaders.value,
|
|
186
190
|
layout: "client",
|
|
191
|
+
plugins: __props.plugins,
|
|
187
192
|
role: activeFilter.value === "All" ? "none" : "tabpanel",
|
|
188
193
|
title: "Body"
|
|
189
194
|
}, null, 8, [
|
|
190
195
|
"id",
|
|
191
196
|
"data",
|
|
192
197
|
"headers",
|
|
198
|
+
"plugins",
|
|
193
199
|
"role"
|
|
194
200
|
]))], 64)) : createCommentVNode("", true)
|
|
195
201
|
], 64)), createVNode(ResponseLoadingOverlay_default, { eventBus: __props.eventBus }, null, 8, ["eventBus"])], 10, _hoisted_2)]),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ResponseBlock.vue.script.js","names":[],"sources":["../../../../src/v2/blocks/response-block/ResponseBlock.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ScalarErrorBoundary } from '@scalar/components'\nimport { isDefined } from '@scalar/helpers/array/is-defined'\nimport type { ClientPlugin } from '@scalar/oas-utils/helpers'\nimport type { WorkspaceEventBus } from '@scalar/workspace-store/events'\nimport { computed, ref, useId } from 'vue'\n\nimport SectionFilter from '@/components/SectionFilter.vue'\nimport ViewLayoutSection from '@/components/ViewLayout/ViewLayoutSection.vue'\nimport type { ResponseInstance } from '@/v2/blocks/operation-block/helpers/send-request'\nimport Headers from '@/v2/blocks/response-block/components/Headers.vue'\nimport ResponseBody from '@/v2/blocks/response-block/components/ResponseBody.vue'\nimport ResponseBodyStreaming from '@/v2/blocks/response-block/components/ResponseBodyStreaming.vue'\nimport ResponseBodyVirtual from '@/v2/blocks/response-block/components/ResponseBodyVirtual.vue'\nimport ResponseCookies from '@/v2/blocks/response-block/components/ResponseCookies.vue'\nimport ResponseEmpty from '@/v2/blocks/response-block/components/ResponseEmpty.vue'\nimport ResponseLoadingOverlay from '@/v2/blocks/response-block/components/ResponseLoadingOverlay.vue'\nimport ResponseMetaInformation from '@/v2/blocks/response-block/components/ResponseMetaInformation.vue'\nimport { textMediaTypes } from '@/v2/blocks/response-block/helpers/media-types'\nimport { parseSetCookie } from '@/v2/blocks/response-block/helpers/parse-set-cookie'\nimport type { ClientLayout } from '@/v2/types/layout'\n\nconst { layout, totalPerformedRequests, response, request } = defineProps<{\n /** Preprocessed response */\n response: ResponseInstance | null\n /** Original request instance */\n request: Request | null\n /** Client layout */\n layout: ClientLayout\n /** Total number of performed requests */\n totalPerformedRequests: number\n /** Application version */\n appVersion: string\n /** Registered app plugins */\n plugins: ClientPlugin[]\n /** Workspace event bus */\n eventBus: WorkspaceEventBus\n}>()\n\n// Headers\nconst responseHeaders = computed(() => {\n const headers = response?.headers\n\n return headers\n ? Object.keys(headers).map((key) => ({\n name: key,\n value: headers[key] ?? '',\n }))\n : []\n})\n\n// Cookies\nconst responseCookies = computed(\n () =>\n response?.cookieHeaderKeys\n .map((setCookieValue) => parseSetCookie(setCookieValue))\n .filter(isDefined) ?? [],\n)\n\nconst responseSections = ['Cookies', 'Headers', 'Body'] as const\ntype Filter = 'All' | (typeof responseSections)[number]\nconst activeFilter = ref<Filter>('All')\n\nconst filters = computed<Filter[]>(() => ['All', ...responseSections])\n\nconst filterIds = computed(\n () =>\n Object.fromEntries(\n filters.value.map((section) => [section, useId()]),\n ) as Record<Filter, string>,\n)\n\n/** Threshold for virtualizing response bodies in bytes */\nconst VIRTUALIZATION_THRESHOLD = 200_000\nconst shouldVirtualize = computed(() => {\n if (!response || !('size' in response)) {\n return false\n }\n\n // Get content type from headers\n const contentType =\n response.headers?.['content-type'] || response.headers?.['Content-Type']\n\n // If no content type or response size is small, don't virtualize\n if (!contentType || (response.size ?? 0) <= VIRTUALIZATION_THRESHOLD) {\n return false\n }\n\n // Do not virtualize html\n if (contentType.includes('text/html')) {\n return false\n }\n\n // Check if content type matches any text-based type\n const isTextBased = textMediaTypes.some((type) => contentType.includes(type))\n\n return isTextBased && (response.size ?? 0) > VIRTUALIZATION_THRESHOLD\n})\n\nconst requestHeaders = computed(() =>\n request?.headers\n ? [...request.headers].map((header) => ({\n name: header[0],\n value: header[1],\n required: false,\n }))\n : [],\n)\n\nconst isSectionVisible = (\n section: (typeof responseSections)[number] | 'All',\n) => {\n if (activeFilter.value === 'All' || activeFilter.value === section) {\n return true\n }\n return false\n}\n\ndefineExpose({\n responseHeaders,\n responseCookies,\n requestHeaders,\n shouldVirtualize,\n activeFilter,\n filters,\n})\n</script>\n<template>\n <ViewLayoutSection aria-label=\"Response\">\n <template #title>\n <div class=\"flex h-8 flex-1 items-center\">\n <div\n aria-live=\"polite\"\n class=\"flex items-center\"\n :class=\"{ 'animate-response-heading': response }\">\n <span class=\"response-heading pointer-events-none absolute\">\n Response\n </span>\n <ResponseMetaInformation\n v-if=\"response\"\n class=\"animate-response-children\"\n :eventBus=\"eventBus\"\n :response=\"response\" />\n </div>\n <SectionFilter\n v-model=\"activeFilter\"\n :filterIds=\"filterIds\"\n :filters=\"filters\" />\n </div>\n </template>\n <div\n :id=\"filterIds.All\"\n class=\"custom-scroll response-section-content relative grid h-full justify-stretch\"\n :class=\"{\n 'content-start': response,\n }\"\n :role=\"activeFilter === 'All' && response ? 'tabpanel' : 'none'\">\n <template v-if=\"!response\">\n <ResponseEmpty\n :appVersion=\"appVersion\"\n :layout=\"layout\"\n :totalPerformedRequests=\"totalPerformedRequests\"\n @addRequest=\"\n eventBus.emit('ui:open:command-palette', {\n action: 'create-request',\n payload: undefined,\n })\n \"\n @openCommandPalette=\"eventBus.emit('ui:open:command-palette')\"\n @sendRequest=\"eventBus.emit('operation:send:request:hotkey')\" />\n </template>\n <template v-else>\n <!-- Cookies section -->\n <ResponseCookies\n v-if=\"isSectionVisible('Cookies')\"\n :id=\"filterIds.Cookies\"\n class=\"response-section-content-cookies\"\n :cookies=\"responseCookies\"\n :role=\"activeFilter === 'All' ? 'none' : 'tabpanel'\" />\n <!-- Request headers section -->\n <Headers\n v-if=\"isSectionVisible('Headers')\"\n :id=\"filterIds.Headers\"\n class=\"response-section-content-headers\"\n :headers=\"requestHeaders\"\n :role=\"activeFilter === 'All' ? 'none' : 'tabpanel'\">\n <template #title>Request Headers</template>\n </Headers>\n <!-- Response headers section -->\n <Headers\n v-if=\"isSectionVisible('Headers')\"\n :id=\"filterIds.Headers\"\n class=\"response-section-content-headers\"\n :headers=\"responseHeaders\"\n :role=\"activeFilter === 'All' ? 'none' : 'tabpanel'\">\n <template #title>Response Headers</template>\n </Headers>\n\n <!-- Inject response section plugin components -->\n <ScalarErrorBoundary\n v-for=\"(plugin, index) in plugins\"\n :key=\"index\">\n <component\n :is=\"plugin.components.response.component\"\n v-if=\"plugin?.components?.response\"\n v-show=\"activeFilter === 'All'\"\n v-bind=\"plugin.components.response.additionalProps\" />\n </ScalarErrorBoundary>\n\n <template v-if=\"activeFilter === 'All' || activeFilter === 'Body'\">\n <!-- Streaming response body -->\n <ResponseBodyStreaming\n v-if=\"'reader' in response\"\n :id=\"filterIds.Body\"\n class=\"response-section-content-body\"\n :reader=\"response.reader\" />\n\n <!-- Virtualized Text for massive responses -->\n <ResponseBodyVirtual\n v-else-if=\"shouldVirtualize && typeof response?.data === 'string'\"\n :id=\"filterIds.Body\"\n :content=\"response!.data\"\n :data=\"response?.data\"\n :headers=\"responseHeaders\"\n :role=\"activeFilter === 'All' ? 'none' : 'tabpanel'\" />\n\n <!-- Regular response body -->\n <ResponseBody\n v-else\n :id=\"filterIds.Body\"\n :active=\"true\"\n class=\"response-section-content-body\"\n :data=\"response?.data\"\n :headers=\"responseHeaders\"\n layout=\"client\"\n :role=\"activeFilter === 'All' ? 'none' : 'tabpanel'\"\n title=\"Body\" />\n </template>\n </template>\n <ResponseLoadingOverlay :eventBus=\"eventBus\" />\n </div>\n </ViewLayoutSection>\n</template>\n<style scoped>\n.animate-response-heading .response-heading {\n animation: push-response 0.2s ease-in-out forwards;\n opacity: 1;\n}\n@keyframes push-response {\n from {\n opacity: 1;\n transform: translateY(0);\n }\n to {\n opacity: 0;\n transform: translateY(-4px);\n }\n}\n.animate-response-heading .animate-response-children {\n animation: response-spans 0.2s ease-in-out forwards 0.05s;\n opacity: 0;\n}\n\n@keyframes response-spans {\n from {\n opacity: 0;\n transform: translateY(4px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n</style>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ResponseBlock.vue.script.js","names":[],"sources":["../../../../src/v2/blocks/response-block/ResponseBlock.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ScalarErrorBoundary } from '@scalar/components'\nimport { isDefined } from '@scalar/helpers/array/is-defined'\nimport type { ClientPlugin } from '@scalar/oas-utils/helpers'\nimport type { WorkspaceEventBus } from '@scalar/workspace-store/events'\nimport type { RequestPayload } from '@scalar/workspace-store/request-example'\nimport { computed, ref, useId } from 'vue'\n\nimport SectionFilter from '@/components/SectionFilter.vue'\nimport ViewLayoutSection from '@/components/ViewLayout/ViewLayoutSection.vue'\nimport type { ResponseInstance } from '@/v2/blocks/operation-block/helpers/send-request'\nimport HeadersComponent from '@/v2/blocks/response-block/components/Headers.vue'\nimport ResponseBody from '@/v2/blocks/response-block/components/ResponseBody.vue'\nimport ResponseBodyStreaming from '@/v2/blocks/response-block/components/ResponseBodyStreaming.vue'\nimport ResponseBodyVirtual from '@/v2/blocks/response-block/components/ResponseBodyVirtual.vue'\nimport ResponseCookies from '@/v2/blocks/response-block/components/ResponseCookies.vue'\nimport ResponseEmpty from '@/v2/blocks/response-block/components/ResponseEmpty.vue'\nimport ResponseLoadingOverlay from '@/v2/blocks/response-block/components/ResponseLoadingOverlay.vue'\nimport ResponseMetaInformation from '@/v2/blocks/response-block/components/ResponseMetaInformation.vue'\nimport { textMediaTypes } from '@/v2/blocks/response-block/helpers/media-types'\nimport { parseSetCookie } from '@/v2/blocks/response-block/helpers/parse-set-cookie'\nimport type { ClientLayout } from '@/v2/types/layout'\n\nconst { layout, totalPerformedRequests, response, requestPayload } =\n defineProps<{\n /** Preprocessed response */\n response: ResponseInstance | null\n /** Original request as a [url, RequestInit] tuple */\n requestPayload: RequestPayload | null\n /** Client layout */\n layout: ClientLayout\n /** Total number of performed requests */\n totalPerformedRequests: number\n /** Application version */\n appVersion: string\n /** Registered app plugins */\n plugins: ClientPlugin[]\n /** Workspace event bus */\n eventBus: WorkspaceEventBus\n }>()\n\n// Headers\nconst responseHeaders = computed(() => {\n const headers = response?.headers\n\n return headers\n ? Object.keys(headers).map((key) => ({\n name: key,\n value: headers[key] ?? '',\n }))\n : []\n})\n\n// Cookies\nconst responseCookies = computed(\n () =>\n response?.cookieHeaderKeys\n .map((setCookieValue) => parseSetCookie(setCookieValue))\n .filter(isDefined) ?? [],\n)\n\nconst responseSections = ['Cookies', 'Headers', 'Body'] as const\ntype Filter = 'All' | (typeof responseSections)[number]\nconst activeFilter = ref<Filter>('All')\n\nconst filters = computed<Filter[]>(() => ['All', ...responseSections])\n\nconst filterIds = computed(\n () =>\n Object.fromEntries(\n filters.value.map((section) => [section, useId()]),\n ) as Record<Filter, string>,\n)\n\n/** Threshold for virtualizing response bodies in bytes */\nconst VIRTUALIZATION_THRESHOLD = 200_000\nconst shouldVirtualize = computed(() => {\n if (!response || !('size' in response)) {\n return false\n }\n\n // Get content type from headers\n const contentType =\n response.headers?.['content-type'] || response.headers?.['Content-Type']\n\n // If no content type or response size is small, don't virtualize\n if (!contentType || (response.size ?? 0) <= VIRTUALIZATION_THRESHOLD) {\n return false\n }\n\n // Do not virtualize html\n if (contentType.includes('text/html')) {\n return false\n }\n\n // Check if content type matches any text-based type\n const isTextBased = textMediaTypes.some((type) => contentType.includes(type))\n\n return isTextBased && (response.size ?? 0) > VIRTUALIZATION_THRESHOLD\n})\n\nconst requestHeaders = computed(() => {\n const headers = requestPayload?.[1]?.headers\n if (!headers) {\n return []\n }\n\n // Normalise via the Headers constructor, and then spread\n return [...new Headers(headers)].map(([name, value]) => ({\n name,\n value,\n required: false,\n }))\n})\n\nconst isSectionVisible = (\n section: (typeof responseSections)[number] | 'All',\n) => {\n if (activeFilter.value === 'All' || activeFilter.value === section) {\n return true\n }\n return false\n}\n\ndefineExpose({\n responseHeaders,\n responseCookies,\n requestHeaders,\n shouldVirtualize,\n activeFilter,\n filters,\n})\n</script>\n<template>\n <ViewLayoutSection aria-label=\"Response\">\n <template #title>\n <div class=\"flex h-8 flex-1 items-center\">\n <div\n aria-live=\"polite\"\n class=\"flex items-center\"\n :class=\"{ 'animate-response-heading': response }\">\n <span class=\"response-heading pointer-events-none absolute\">\n Response\n </span>\n <ResponseMetaInformation\n v-if=\"response\"\n class=\"animate-response-children\"\n :eventBus=\"eventBus\"\n :response=\"response\" />\n </div>\n <SectionFilter\n v-model=\"activeFilter\"\n :filterIds=\"filterIds\"\n :filters=\"filters\" />\n </div>\n </template>\n <div\n :id=\"filterIds.All\"\n class=\"custom-scroll response-section-content relative grid h-full justify-stretch\"\n :class=\"{\n 'content-start': response,\n }\"\n :role=\"activeFilter === 'All' && response ? 'tabpanel' : 'none'\">\n <template v-if=\"!response\">\n <ResponseEmpty\n :appVersion=\"appVersion\"\n :layout=\"layout\"\n :totalPerformedRequests=\"totalPerformedRequests\"\n @addRequest=\"\n eventBus.emit('ui:open:command-palette', {\n action: 'create-request',\n payload: undefined,\n })\n \"\n @openCommandPalette=\"eventBus.emit('ui:open:command-palette')\"\n @sendRequest=\"eventBus.emit('operation:send:request:hotkey')\" />\n </template>\n <template v-else>\n <!-- Cookies section -->\n <ResponseCookies\n v-if=\"isSectionVisible('Cookies')\"\n :id=\"filterIds.Cookies\"\n class=\"response-section-content-cookies\"\n :cookies=\"responseCookies\"\n :role=\"activeFilter === 'All' ? 'none' : 'tabpanel'\" />\n <!-- Request headers section -->\n <HeadersComponent\n v-if=\"isSectionVisible('Headers')\"\n :id=\"filterIds.Headers\"\n class=\"response-section-content-headers\"\n :headers=\"requestHeaders\"\n :role=\"activeFilter === 'All' ? 'none' : 'tabpanel'\">\n <template #title>Request Headers</template>\n </HeadersComponent>\n <!-- Response headers section -->\n <HeadersComponent\n v-if=\"isSectionVisible('Headers')\"\n :id=\"filterIds.Headers\"\n class=\"response-section-content-headers\"\n :headers=\"responseHeaders\"\n :role=\"activeFilter === 'All' ? 'none' : 'tabpanel'\">\n <template #title>Response Headers</template>\n </HeadersComponent>\n\n <!-- Inject response section plugin components -->\n <ScalarErrorBoundary\n v-for=\"(plugin, index) in plugins\"\n :key=\"index\">\n <component\n :is=\"plugin.components.response.component\"\n v-if=\"plugin?.components?.response\"\n v-show=\"activeFilter === 'All'\"\n v-bind=\"plugin.components.response.additionalProps\" />\n </ScalarErrorBoundary>\n\n <template v-if=\"activeFilter === 'All' || activeFilter === 'Body'\">\n <!-- Streaming response body -->\n <ResponseBodyStreaming\n v-if=\"'reader' in response\"\n :id=\"filterIds.Body\"\n class=\"response-section-content-body\"\n :reader=\"response.reader\" />\n\n <!-- Virtualized Text for massive responses -->\n <ResponseBodyVirtual\n v-else-if=\"shouldVirtualize && typeof response?.data === 'string'\"\n :id=\"filterIds.Body\"\n :content=\"response!.data\"\n :data=\"response?.data\"\n :headers=\"responseHeaders\"\n :role=\"activeFilter === 'All' ? 'none' : 'tabpanel'\" />\n\n <!-- Regular response body -->\n <ResponseBody\n v-else\n :id=\"filterIds.Body\"\n :active=\"true\"\n class=\"response-section-content-body\"\n :data=\"response?.data\"\n :headers=\"responseHeaders\"\n layout=\"client\"\n :plugins=\"plugins\"\n :role=\"activeFilter === 'All' ? 'none' : 'tabpanel'\"\n title=\"Body\" />\n </template>\n </template>\n <ResponseLoadingOverlay :eventBus=\"eventBus\" />\n </div>\n </ViewLayoutSection>\n</template>\n<style scoped>\n.animate-response-heading .response-heading {\n animation: push-response 0.2s ease-in-out forwards;\n opacity: 1;\n}\n@keyframes push-response {\n from {\n opacity: 1;\n transform: translateY(0);\n }\n to {\n opacity: 0;\n transform: translateY(-4px);\n }\n}\n.animate-response-heading .animate-response-children {\n animation: response-spans 0.2s ease-in-out forwards 0.05s;\n opacity: 0;\n}\n\n@keyframes response-spans {\n from {\n opacity: 0;\n transform: translateY(4px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n</style>\n"],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ClientPlugin } from '@scalar/oas-utils/helpers';
|
|
1
2
|
type __VLS_Props = {
|
|
2
3
|
title: string;
|
|
3
4
|
layout: 'client' | 'reference';
|
|
@@ -6,6 +7,7 @@ type __VLS_Props = {
|
|
|
6
7
|
name: string;
|
|
7
8
|
value: string;
|
|
8
9
|
}[];
|
|
10
|
+
plugins?: ClientPlugin[];
|
|
9
11
|
};
|
|
10
12
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
11
13
|
declare const _default: typeof __VLS_export;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ResponseBody.vue.d.ts","sourceRoot":"","sources":["../../../../../src/v2/blocks/response-block/components/ResponseBody.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ResponseBody.vue.d.ts","sourceRoot":"","sources":["../../../../../src/v2/blocks/response-block/components/ResponseBody.vue"],"names":[],"mappings":"AAyIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAe7D,KAAK,WAAW,GAAG;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,QAAQ,GAAG,WAAW,CAAA;IAC9B,IAAI,EAAE,OAAO,CAAA;IACb,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IAC1C,OAAO,CAAC,EAAE,YAAY,EAAE,CAAA;CACzB,CAAC;AA4OF,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 ResponseBody_vue_vue_type_script_setup_true_lang_default from "./ResponseBody.vue.script.js";
|
|
3
3
|
/* empty css */
|
|
4
4
|
//#region src/v2/blocks/response-block/components/ResponseBody.vue
|
|
5
|
-
var ResponseBody_default = /* @__PURE__ */ _plugin_vue_export_helper_default(ResponseBody_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-
|
|
5
|
+
var ResponseBody_default = /* @__PURE__ */ _plugin_vue_export_helper_default(ResponseBody_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-30c34ea4"]]);
|
|
6
6
|
//#endregion
|
|
7
7
|
export { ResponseBody_default as default };
|
|
8
8
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ResponseBody.vue.js","names":[],"sources":["../../../../../src/v2/blocks/response-block/components/ResponseBody.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { computed, ref } from 'vue'\n\nimport { getMediaTypeConfig } from '@/v2/blocks/response-block/helpers/media-types'\nimport { processResponseBody } from '@/v2/blocks/response-block/helpers/process-response-body'\nimport { CollapsibleSection } from '@/v2/components/layout'\n\nimport ResponseBodyDownload from './ResponseBodyDownload.vue'\nimport ResponseBodyInfo from './ResponseBodyInfo.vue'\nimport ResponseBodyPreview from './ResponseBodyPreview.vue'\nimport ResponseBodyRaw from './ResponseBodyRaw.vue'\nimport ResponseBodyToggle from './ResponseBodyToggle.vue'\n\nconst {
|
|
1
|
+
{"version":3,"file":"ResponseBody.vue.js","names":[],"sources":["../../../../../src/v2/blocks/response-block/components/ResponseBody.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type { ClientPlugin } from '@scalar/oas-utils/helpers'\nimport type { CodeMirrorLanguage } from '@scalar/use-codemirror'\nimport { computed, ref } from 'vue'\n\nimport { getMediaTypeConfig } from '@/v2/blocks/response-block/helpers/media-types'\nimport { processResponseBody } from '@/v2/blocks/response-block/helpers/process-response-body'\nimport { resolveResponseBodyHandler } from '@/v2/blocks/response-block/helpers/resolve-response-body-handler'\nimport { CollapsibleSection } from '@/v2/components/layout'\n\nimport ResponseBodyDownload from './ResponseBodyDownload.vue'\nimport ResponseBodyInfo from './ResponseBodyInfo.vue'\nimport ResponseBodyPreview from './ResponseBodyPreview.vue'\nimport ResponseBodyRaw from './ResponseBodyRaw.vue'\nimport ResponseBodyToggle from './ResponseBodyToggle.vue'\n\nconst {\n data,\n headers,\n plugins = [],\n} = defineProps<{\n title: string\n layout: 'client' | 'reference'\n data: unknown\n headers: { name: string; value: string }[]\n plugins?: ClientPlugin[]\n}>()\n\n/** Preview / Raw toggle */\nconst toggle = ref(true)\n\nconst responseBody = computed(() =>\n processResponseBody({\n data,\n headers,\n }),\n)\n\nconst mimeEssence = computed(() => responseBody.value.mimeType.essence)\n\nconst mediaConfig = computed(() => getMediaTypeConfig(mimeEssence.value))\n\nconst pluginHandler = computed(() =>\n resolveResponseBodyHandler(mimeEssence.value, plugins),\n)\n\nconst hasRaw = computed(\n () =>\n !!pluginHandler.value?.rawComponent ||\n !!pluginHandler.value?.decode ||\n !!mediaConfig.value?.raw,\n)\n\nconst hasPreview = computed(\n () => !!pluginHandler.value?.previewComponent || !!mediaConfig.value?.preview,\n)\n\nconst showToggle = computed(() => hasRaw.value && hasPreview.value)\n\nconst showPreview = computed(() => toggle.value || !showToggle.value)\nconst showRaw = computed(() => !toggle.value || !showToggle.value)\n\nconst rawLanguage = computed(\n () => pluginHandler.value?.language ?? mediaConfig.value?.language,\n)\n</script>\n<template>\n <CollapsibleSection\n class=\"max-h-content overflow-y-hidden\"\n :isStatic=\"layout === 'reference'\">\n <template #title>{{ title }}</template>\n <template\n v-if=\"data && responseBody.dataUrl\"\n #actions>\n <ResponseBodyDownload\n :filename=\"responseBody.attachmentFilename\"\n :href=\"responseBody.dataUrl\"\n :type=\"responseBody.mimeType?.essence\" />\n </template>\n <div\n v-if=\"data\"\n class=\"bg-b-1 flex max-h-[calc(100%-32px)] flex-col overflow-hidden\">\n <div\n class=\"box-content flex min-h-8 items-center justify-between border-y px-3\">\n <span class=\"text-xxs font-code leading-5\">\n {{ mimeEssence }}\n </span>\n <ResponseBodyToggle\n v-if=\"showToggle\"\n v-model=\"toggle\" />\n </div>\n\n <!-- Plugin custom raw component -->\n <component\n :is=\"pluginHandler.rawComponent\"\n v-if=\"pluginHandler?.rawComponent && hasRaw && showRaw\"\n :key=\"`plugin-raw-${responseBody.dataUrl}`\"\n :content=\"data\"\n :contentType=\"mimeEssence\" />\n <!-- Default raw renderer (used when plugin provides decode but no custom component) -->\n <ResponseBodyRaw\n v-else-if=\"hasRaw && showRaw\"\n :key=\"`raw-${responseBody.dataUrl}`\"\n :content=\"data\"\n :language=\"rawLanguage as CodeMirrorLanguage\" />\n\n <!-- Plugin custom preview component -->\n <component\n :is=\"pluginHandler.previewComponent\"\n v-if=\"pluginHandler?.previewComponent && hasPreview && showPreview\"\n :key=\"`plugin-preview-${responseBody.dataUrl}`\"\n :content=\"data\"\n :contentType=\"mimeEssence\"\n :dataUrl=\"responseBody.dataUrl\" />\n <!-- Default preview renderer -->\n <ResponseBodyPreview\n v-else-if=\"mediaConfig?.preview && showPreview\"\n :key=\"`preview-${responseBody.dataUrl}`\"\n :alpha=\"mediaConfig.alpha\"\n :mode=\"mediaConfig.preview\"\n :src=\"responseBody.dataUrl\"\n :type=\"mimeEssence\" />\n\n <ResponseBodyInfo v-if=\"!hasRaw && !hasPreview\">\n Binary file\n </ResponseBodyInfo>\n </div>\n </CollapsibleSection>\n</template>\n<style scoped>\n.scalar-code-block :deep(.hljs *) {\n font-size: var(--scalar-small);\n}\n</style>\n"],"mappings":""}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolveResponseBodyHandler } from "../helpers/resolve-response-body-handler.js";
|
|
1
2
|
import { getMediaTypeConfig } from "../helpers/media-types.js";
|
|
2
3
|
import CollapsibleSection_default from "../../../components/layout/CollapsibleSection.vue.js";
|
|
3
4
|
import { processResponseBody } from "../helpers/process-response-body.js";
|
|
@@ -6,7 +7,7 @@ import ResponseBodyInfo_default from "./ResponseBodyInfo.vue.js";
|
|
|
6
7
|
import ResponseBodyPreview_default from "./ResponseBodyPreview.vue.js";
|
|
7
8
|
import ResponseBodyRaw_default from "./ResponseBodyRaw.vue.js";
|
|
8
9
|
import ResponseBodyToggle_default from "./ResponseBodyToggle.vue.js";
|
|
9
|
-
import { computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createSlots, createTextVNode, createVNode, defineComponent, openBlock, ref, toDisplayString, unref, withCtx } from "vue";
|
|
10
|
+
import { computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createSlots, createTextVNode, createVNode, defineComponent, openBlock, ref, resolveDynamicComponent, toDisplayString, unref, withCtx } from "vue";
|
|
10
11
|
//#region src/v2/blocks/response-block/components/ResponseBody.vue?vue&type=script&setup=true&lang.ts
|
|
11
12
|
var _hoisted_1 = {
|
|
12
13
|
key: 0,
|
|
@@ -20,19 +21,25 @@ var ResponseBody_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ d
|
|
|
20
21
|
title: {},
|
|
21
22
|
layout: {},
|
|
22
23
|
data: {},
|
|
23
|
-
headers: {}
|
|
24
|
+
headers: {},
|
|
25
|
+
plugins: { default: () => [] }
|
|
24
26
|
},
|
|
25
27
|
setup(__props) {
|
|
26
28
|
/** Preview / Raw toggle */
|
|
27
29
|
const toggle = ref(true);
|
|
28
|
-
const showToggle = computed(() => !!(mediaConfig.value?.raw && mediaConfig.value.preview));
|
|
29
|
-
const showPreview = computed(() => toggle.value || !showToggle.value);
|
|
30
|
-
const showRaw = computed(() => !toggle.value || !showToggle.value);
|
|
31
30
|
const responseBody = computed(() => processResponseBody({
|
|
32
31
|
data: __props.data,
|
|
33
32
|
headers: __props.headers
|
|
34
33
|
}));
|
|
35
|
-
const
|
|
34
|
+
const mimeEssence = computed(() => responseBody.value.mimeType.essence);
|
|
35
|
+
const mediaConfig = computed(() => getMediaTypeConfig(mimeEssence.value));
|
|
36
|
+
const pluginHandler = computed(() => resolveResponseBodyHandler(mimeEssence.value, __props.plugins));
|
|
37
|
+
const hasRaw = computed(() => !!pluginHandler.value?.rawComponent || !!pluginHandler.value?.decode || !!mediaConfig.value?.raw);
|
|
38
|
+
const hasPreview = computed(() => !!pluginHandler.value?.previewComponent || !!mediaConfig.value?.preview);
|
|
39
|
+
const showToggle = computed(() => hasRaw.value && hasPreview.value);
|
|
40
|
+
const showPreview = computed(() => toggle.value || !showToggle.value);
|
|
41
|
+
const showRaw = computed(() => !toggle.value || !showToggle.value);
|
|
42
|
+
const rawLanguage = computed(() => pluginHandler.value?.language ?? mediaConfig.value?.language);
|
|
36
43
|
return (_ctx, _cache) => {
|
|
37
44
|
return openBlock(), createBlock(unref(CollapsibleSection_default), {
|
|
38
45
|
class: "max-h-content overflow-y-hidden",
|
|
@@ -40,29 +47,42 @@ var ResponseBody_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ d
|
|
|
40
47
|
}, createSlots({
|
|
41
48
|
title: withCtx(() => [createTextVNode(toDisplayString(__props.title), 1)]),
|
|
42
49
|
default: withCtx(() => [__props.data ? (openBlock(), createElementBlock("div", _hoisted_1, [
|
|
43
|
-
createElementVNode("div", _hoisted_2, [createElementVNode("span", _hoisted_3, toDisplayString(
|
|
50
|
+
createElementVNode("div", _hoisted_2, [createElementVNode("span", _hoisted_3, toDisplayString(mimeEssence.value), 1), showToggle.value ? (openBlock(), createBlock(ResponseBodyToggle_default, {
|
|
44
51
|
key: 0,
|
|
45
52
|
modelValue: toggle.value,
|
|
46
53
|
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => toggle.value = $event)
|
|
47
54
|
}, null, 8, ["modelValue"])) : createCommentVNode("", true)]),
|
|
48
|
-
|
|
49
|
-
key: responseBody.value.dataUrl
|
|
55
|
+
pluginHandler.value?.rawComponent && hasRaw.value && showRaw.value ? (openBlock(), createBlock(resolveDynamicComponent(pluginHandler.value.rawComponent), {
|
|
56
|
+
key: `plugin-raw-${responseBody.value.dataUrl}`,
|
|
50
57
|
content: __props.data,
|
|
51
|
-
|
|
58
|
+
contentType: mimeEssence.value
|
|
59
|
+
}, null, 8, ["content", "contentType"])) : hasRaw.value && showRaw.value ? (openBlock(), createBlock(ResponseBodyRaw_default, {
|
|
60
|
+
key: `raw-${responseBody.value.dataUrl}`,
|
|
61
|
+
content: __props.data,
|
|
62
|
+
language: rawLanguage.value
|
|
52
63
|
}, null, 8, ["content", "language"])) : createCommentVNode("", true),
|
|
53
|
-
|
|
54
|
-
key: responseBody.value.dataUrl
|
|
64
|
+
pluginHandler.value?.previewComponent && hasPreview.value && showPreview.value ? (openBlock(), createBlock(resolveDynamicComponent(pluginHandler.value.previewComponent), {
|
|
65
|
+
key: `plugin-preview-${responseBody.value.dataUrl}`,
|
|
66
|
+
content: __props.data,
|
|
67
|
+
contentType: mimeEssence.value,
|
|
68
|
+
dataUrl: responseBody.value.dataUrl
|
|
69
|
+
}, null, 8, [
|
|
70
|
+
"content",
|
|
71
|
+
"contentType",
|
|
72
|
+
"dataUrl"
|
|
73
|
+
])) : mediaConfig.value?.preview && showPreview.value ? (openBlock(), createBlock(ResponseBodyPreview_default, {
|
|
74
|
+
key: `preview-${responseBody.value.dataUrl}`,
|
|
55
75
|
alpha: mediaConfig.value.alpha,
|
|
56
76
|
mode: mediaConfig.value.preview,
|
|
57
77
|
src: responseBody.value.dataUrl,
|
|
58
|
-
type:
|
|
78
|
+
type: mimeEssence.value
|
|
59
79
|
}, null, 8, [
|
|
60
80
|
"alpha",
|
|
61
81
|
"mode",
|
|
62
82
|
"src",
|
|
63
83
|
"type"
|
|
64
84
|
])) : createCommentVNode("", true),
|
|
65
|
-
!
|
|
85
|
+
!hasRaw.value && !hasPreview.value ? (openBlock(), createBlock(ResponseBodyInfo_default, { key: 4 }, {
|
|
66
86
|
default: withCtx(() => [..._cache[1] || (_cache[1] = [createTextVNode(" Binary file ", -1)])]),
|
|
67
87
|
_: 1
|
|
68
88
|
})) : createCommentVNode("", true)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ResponseBody.vue.script.js","names":[],"sources":["../../../../../src/v2/blocks/response-block/components/ResponseBody.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { computed, ref } from 'vue'\n\nimport { getMediaTypeConfig } from '@/v2/blocks/response-block/helpers/media-types'\nimport { processResponseBody } from '@/v2/blocks/response-block/helpers/process-response-body'\nimport { CollapsibleSection } from '@/v2/components/layout'\n\nimport ResponseBodyDownload from './ResponseBodyDownload.vue'\nimport ResponseBodyInfo from './ResponseBodyInfo.vue'\nimport ResponseBodyPreview from './ResponseBodyPreview.vue'\nimport ResponseBodyRaw from './ResponseBodyRaw.vue'\nimport ResponseBodyToggle from './ResponseBodyToggle.vue'\n\nconst {
|
|
1
|
+
{"version":3,"file":"ResponseBody.vue.script.js","names":[],"sources":["../../../../../src/v2/blocks/response-block/components/ResponseBody.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type { ClientPlugin } from '@scalar/oas-utils/helpers'\nimport type { CodeMirrorLanguage } from '@scalar/use-codemirror'\nimport { computed, ref } from 'vue'\n\nimport { getMediaTypeConfig } from '@/v2/blocks/response-block/helpers/media-types'\nimport { processResponseBody } from '@/v2/blocks/response-block/helpers/process-response-body'\nimport { resolveResponseBodyHandler } from '@/v2/blocks/response-block/helpers/resolve-response-body-handler'\nimport { CollapsibleSection } from '@/v2/components/layout'\n\nimport ResponseBodyDownload from './ResponseBodyDownload.vue'\nimport ResponseBodyInfo from './ResponseBodyInfo.vue'\nimport ResponseBodyPreview from './ResponseBodyPreview.vue'\nimport ResponseBodyRaw from './ResponseBodyRaw.vue'\nimport ResponseBodyToggle from './ResponseBodyToggle.vue'\n\nconst {\n data,\n headers,\n plugins = [],\n} = defineProps<{\n title: string\n layout: 'client' | 'reference'\n data: unknown\n headers: { name: string; value: string }[]\n plugins?: ClientPlugin[]\n}>()\n\n/** Preview / Raw toggle */\nconst toggle = ref(true)\n\nconst responseBody = computed(() =>\n processResponseBody({\n data,\n headers,\n }),\n)\n\nconst mimeEssence = computed(() => responseBody.value.mimeType.essence)\n\nconst mediaConfig = computed(() => getMediaTypeConfig(mimeEssence.value))\n\nconst pluginHandler = computed(() =>\n resolveResponseBodyHandler(mimeEssence.value, plugins),\n)\n\nconst hasRaw = computed(\n () =>\n !!pluginHandler.value?.rawComponent ||\n !!pluginHandler.value?.decode ||\n !!mediaConfig.value?.raw,\n)\n\nconst hasPreview = computed(\n () => !!pluginHandler.value?.previewComponent || !!mediaConfig.value?.preview,\n)\n\nconst showToggle = computed(() => hasRaw.value && hasPreview.value)\n\nconst showPreview = computed(() => toggle.value || !showToggle.value)\nconst showRaw = computed(() => !toggle.value || !showToggle.value)\n\nconst rawLanguage = computed(\n () => pluginHandler.value?.language ?? mediaConfig.value?.language,\n)\n</script>\n<template>\n <CollapsibleSection\n class=\"max-h-content overflow-y-hidden\"\n :isStatic=\"layout === 'reference'\">\n <template #title>{{ title }}</template>\n <template\n v-if=\"data && responseBody.dataUrl\"\n #actions>\n <ResponseBodyDownload\n :filename=\"responseBody.attachmentFilename\"\n :href=\"responseBody.dataUrl\"\n :type=\"responseBody.mimeType?.essence\" />\n </template>\n <div\n v-if=\"data\"\n class=\"bg-b-1 flex max-h-[calc(100%-32px)] flex-col overflow-hidden\">\n <div\n class=\"box-content flex min-h-8 items-center justify-between border-y px-3\">\n <span class=\"text-xxs font-code leading-5\">\n {{ mimeEssence }}\n </span>\n <ResponseBodyToggle\n v-if=\"showToggle\"\n v-model=\"toggle\" />\n </div>\n\n <!-- Plugin custom raw component -->\n <component\n :is=\"pluginHandler.rawComponent\"\n v-if=\"pluginHandler?.rawComponent && hasRaw && showRaw\"\n :key=\"`plugin-raw-${responseBody.dataUrl}`\"\n :content=\"data\"\n :contentType=\"mimeEssence\" />\n <!-- Default raw renderer (used when plugin provides decode but no custom component) -->\n <ResponseBodyRaw\n v-else-if=\"hasRaw && showRaw\"\n :key=\"`raw-${responseBody.dataUrl}`\"\n :content=\"data\"\n :language=\"rawLanguage as CodeMirrorLanguage\" />\n\n <!-- Plugin custom preview component -->\n <component\n :is=\"pluginHandler.previewComponent\"\n v-if=\"pluginHandler?.previewComponent && hasPreview && showPreview\"\n :key=\"`plugin-preview-${responseBody.dataUrl}`\"\n :content=\"data\"\n :contentType=\"mimeEssence\"\n :dataUrl=\"responseBody.dataUrl\" />\n <!-- Default preview renderer -->\n <ResponseBodyPreview\n v-else-if=\"mediaConfig?.preview && showPreview\"\n :key=\"`preview-${responseBody.dataUrl}`\"\n :alpha=\"mediaConfig.alpha\"\n :mode=\"mediaConfig.preview\"\n :src=\"responseBody.dataUrl\"\n :type=\"mimeEssence\" />\n\n <ResponseBodyInfo v-if=\"!hasRaw && !hasPreview\">\n Binary file\n </ResponseBodyInfo>\n </div>\n </CollapsibleSection>\n</template>\n<style scoped>\n.scalar-code-block :deep(.hljs *) {\n font-size: var(--scalar-small);\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6BA,MAAM,SAAS,IAAI,KAAI;EAEvB,MAAM,eAAe,eACnB,oBAAoB;GAClB,MAAG,QAAA;GACH,SAAM,QAAA;GACP,CAAC,CACJ;EAEA,MAAM,cAAc,eAAe,aAAa,MAAM,SAAS,QAAO;EAEtE,MAAM,cAAc,eAAe,mBAAmB,YAAY,MAAM,CAAA;EAExE,MAAM,gBAAgB,eACpB,2BAA2B,YAAY,OAAO,QAAA,QAAQ,CACxD;EAEA,MAAM,SAAS,eAEX,CAAC,CAAC,cAAc,OAAO,gBACvB,CAAC,CAAC,cAAc,OAAO,UACvB,CAAC,CAAC,YAAY,OAAO,IACzB;EAEA,MAAM,aAAa,eACX,CAAC,CAAC,cAAc,OAAO,oBAAoB,CAAC,CAAC,YAAY,OAAO,QACxE;EAEA,MAAM,aAAa,eAAe,OAAO,SAAS,WAAW,MAAK;EAElE,MAAM,cAAc,eAAe,OAAO,SAAS,CAAC,WAAW,MAAK;EACpE,MAAM,UAAU,eAAe,CAAC,OAAO,SAAS,CAAC,WAAW,MAAK;EAEjE,MAAM,cAAc,eACZ,cAAc,OAAO,YAAY,YAAY,OAAO,SAC5D;;uBAGE,YA4DqB,MAAA,2BAAA,EAAA;IA3DnB,OAAM;IACL,UAAU,QAAA,WAAM;;IACN,OAAK,cAAY,CAAA,gBAAA,gBAAR,QAAA,MAAK,EAAA,EAAA,CAAA,CAAA;2BAwDnB,CA9CE,QAAA,QAAA,WAAA,EADR,mBA+CM,OA/CN,YA+CM;KA5CJ,mBAQM,OARN,YAQM,CANJ,mBAEO,QAFP,YAEO,gBADF,YAAA,MAAW,EAAA,EAAA,EAGR,WAAA,SAAA,WAAA,EADR,YAEqB,4BAAA;;kBAAV,OAAA;0EAAM,QAAA;;KAMX,cAAA,OAAe,gBAAgB,OAAA,SAAU,QAAA,SAAA,WAAA,EAFjD,YAK+B,wBAJxB,cAAA,MAAc,aAAY,EAAA;MAE9B,KAAG,cAAgB,aAAA,MAAa;MAChC,SAAS,QAAA;MACT,aAAa,YAAA;gDAGH,OAAA,SAAU,QAAA,SAAA,WAAA,EADvB,YAIkD,yBAAA;MAF/C,KAAG,OAAS,aAAA,MAAa;MACzB,SAAS,QAAA;MACT,UAAU,YAAA;;KAKL,cAAA,OAAe,oBAAoB,WAAA,SAAc,YAAA,SAAA,WAAA,EAFzD,YAMoC,wBAL7B,cAAA,MAAc,iBAAgB,EAAA;MAElC,KAAG,kBAAoB,aAAA,MAAa;MACpC,SAAS,QAAA;MACT,aAAa,YAAA;MACb,SAAS,aAAA,MAAa;;;;;WAGZ,YAAA,OAAa,WAAW,YAAA,SAAA,WAAA,EADrC,YAMwB,6BAAA;MAJrB,KAAG,WAAa,aAAA,MAAa;MAC7B,OAAO,YAAA,MAAY;MACnB,MAAM,YAAA,MAAY;MAClB,KAAK,aAAA,MAAa;MAClB,MAAM,YAAA;;;;;;;MAEgB,OAAA,SAAM,CAAK,WAAA,SAAA,WAAA,EAApC,YAEmB,0BAAA,EAAA,KAAA,GAAA,EAAA;6BAAnB,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CAAA,gBAFgD,iBAEhD,GAAA,CAAA,EAAA,CAAA;;;;;OArDM,QAAA,QAAQ,aAAA,MAAa,UAAA;UAC1B;sBAI0C,CAH3C,YAG2C,8BAAA;KAFxC,UAAU,aAAA,MAAa;KACvB,MAAM,aAAA,MAAa;KACnB,MAAM,aAAA,MAAa,UAAU"}
|
|
@@ -9,7 +9,7 @@ export declare function processResponseBody({ data, headers }: {
|
|
|
9
9
|
value: string;
|
|
10
10
|
}[];
|
|
11
11
|
}): {
|
|
12
|
-
mimeType: import("@scalar/helpers/http/mime-type").ParsedMimeType
|
|
12
|
+
mimeType: import("@scalar/helpers/http/mime-type").ParsedMimeType;
|
|
13
13
|
attachmentFilename: string;
|
|
14
14
|
dataUrl: string;
|
|
15
15
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { resolveResponseMimeType } from "./resolve-response-content-type.js";
|
|
1
2
|
import { extractFilename } from "./extract-filename.js";
|
|
2
|
-
import { parseMimeType } from "@scalar/helpers/http/mime-type";
|
|
3
3
|
//#region src/v2/blocks/response-block/helpers/process-response-body.ts
|
|
4
4
|
var isBlob = (b) => b instanceof Blob;
|
|
5
5
|
/**
|
|
@@ -7,8 +7,7 @@ var isBlob = (b) => b instanceof Blob;
|
|
|
7
7
|
* Extracts MIME type, attachment filename, and generates a data URL.
|
|
8
8
|
*/
|
|
9
9
|
function processResponseBody({ data, headers }) {
|
|
10
|
-
const
|
|
11
|
-
const mimeType = contentType?.value ? parseMimeType(contentType.value) : void 0;
|
|
10
|
+
const mimeType = resolveResponseMimeType(headers.find((header) => header.name.toLowerCase() === "content-type")?.value);
|
|
12
11
|
return {
|
|
13
12
|
mimeType,
|
|
14
13
|
attachmentFilename: extractFilename(headers.find((header) => header.name.toLowerCase() === "content-disposition")?.value ?? ""),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-response-body.js","names":[],"sources":["../../../../../src/v2/blocks/response-block/helpers/process-response-body.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"process-response-body.js","names":[],"sources":["../../../../../src/v2/blocks/response-block/helpers/process-response-body.ts"],"sourcesContent":["import { resolveResponseMimeType } from '@/v2/blocks/response-block/helpers/resolve-response-content-type'\n\nimport { extractFilename } from './../helpers/extract-filename'\n\nconst isBlob = (b: any): b is Blob => b instanceof Blob\n\n/**\n * Processes the response body of an HTTP request.\n * Extracts MIME type, attachment filename, and generates a data URL.\n */\nexport function processResponseBody({ data, headers }: { data: unknown; headers: { name: string; value: string }[] }) {\n const contentType = headers.find((header) => header.name.toLowerCase() === 'content-type')\n const mimeType = resolveResponseMimeType(contentType?.value)\n const attachmentFilename = extractFilename(\n headers.find((header) => header.name.toLowerCase() === 'content-disposition')?.value ?? '',\n )\n\n const dataUrl = (() => {\n if (isBlob(data)) {\n return URL.createObjectURL(data)\n }\n if (typeof data === 'string') {\n return URL.createObjectURL(new Blob([data], { type: mimeType ? mimeType.toString() : undefined }))\n }\n if (data instanceof Object && Object.keys(data).length) {\n return URL.createObjectURL(\n new Blob([JSON.stringify(data)], {\n type: mimeType ? mimeType.toString() : undefined,\n }),\n )\n }\n return ''\n })()\n\n return { mimeType, attachmentFilename, dataUrl }\n}\n"],"mappings":";;;AAIA,IAAM,UAAU,MAAsB,aAAa;;;;;AAMnD,SAAgB,oBAAoB,EAAE,MAAM,WAA0E;CAEpH,MAAM,WAAW,wBADG,QAAQ,MAAM,WAAW,OAAO,KAAK,aAAa,KAAK,eAAe,EACpC,MAAM;AAsB5D,QAAO;EAAE;EAAU,oBArBQ,gBACzB,QAAQ,MAAM,WAAW,OAAO,KAAK,aAAa,KAAK,sBAAsB,EAAE,SAAS,GACzF;EAmBsC,gBAjBhB;AACrB,OAAI,OAAO,KAAK,CACd,QAAO,IAAI,gBAAgB,KAAK;AAElC,OAAI,OAAO,SAAS,SAClB,QAAO,IAAI,gBAAgB,IAAI,KAAK,CAAC,KAAK,EAAE,EAAE,MAAM,WAAW,SAAS,UAAU,GAAG,KAAA,GAAW,CAAC,CAAC;AAEpG,OAAI,gBAAgB,UAAU,OAAO,KAAK,KAAK,CAAC,OAC9C,QAAO,IAAI,gBACT,IAAI,KAAK,CAAC,KAAK,UAAU,KAAK,CAAC,EAAE,EAC/B,MAAM,WAAW,SAAS,UAAU,GAAG,KAAA,GACxC,CAAC,CACH;AAEH,UAAO;MACL;EAE4C"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ClientPlugin, ResponseBodyHandler } from '@scalar/oas-utils/helpers';
|
|
2
|
+
/**
|
|
3
|
+
* Find the first plugin response body handler that matches a given MIME type.
|
|
4
|
+
* Plugins are checked in order — first match wins, allowing users to override native behavior.
|
|
5
|
+
*
|
|
6
|
+
* Matching supports:
|
|
7
|
+
* - Exact match: "application/msgpack"
|
|
8
|
+
* - Suffix wildcard: "application/vnd.*+json" matches "application/vnd.api+json"
|
|
9
|
+
*/
|
|
10
|
+
export declare const resolveResponseBodyHandler: (mimeType: string, plugins: ClientPlugin[]) => ResponseBodyHandler | undefined;
|
|
11
|
+
//# sourceMappingURL=resolve-response-body-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-response-body-handler.d.ts","sourceRoot":"","sources":["../../../../../src/v2/blocks/response-block/helpers/resolve-response-body-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAA;AAElF;;;;;;;GAOG;AACH,eAAO,MAAM,0BAA0B,GACrC,UAAU,MAAM,EAChB,SAAS,YAAY,EAAE,KACtB,mBAAmB,GAAG,SAcxB,CAAA"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
//#region src/v2/blocks/response-block/helpers/resolve-response-body-handler.ts
|
|
2
|
+
/**
|
|
3
|
+
* Find the first plugin response body handler that matches a given MIME type.
|
|
4
|
+
* Plugins are checked in order — first match wins, allowing users to override native behavior.
|
|
5
|
+
*
|
|
6
|
+
* Matching supports:
|
|
7
|
+
* - Exact match: "application/msgpack"
|
|
8
|
+
* - Suffix wildcard: "application/vnd.*+json" matches "application/vnd.api+json"
|
|
9
|
+
*/
|
|
10
|
+
var resolveResponseBodyHandler = (mimeType, plugins) => {
|
|
11
|
+
for (const plugin of plugins) {
|
|
12
|
+
if (!plugin.responseBody) continue;
|
|
13
|
+
for (const handler of plugin.responseBody) if (matchesMimeType(mimeType, handler.mimeTypes)) return handler;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Checks if the given MIME type matches any of the provided MIME type patterns.
|
|
18
|
+
* Supports both exact match (e.g. "application/json") and wildcard patterns (e.g. "application/*", "application/vnd.*+json").
|
|
19
|
+
*
|
|
20
|
+
* Example:
|
|
21
|
+
* matchesMimeType('application/json', ['application/*']) // true
|
|
22
|
+
* matchesMimeType('application/vnd.api+json', ['application/vnd.*+json']) // true
|
|
23
|
+
* matchesMimeType('text/plain', ['application/json']) // false
|
|
24
|
+
*
|
|
25
|
+
* @param actual - The MIME type to match (e.g., "application/json")
|
|
26
|
+
* @param patterns - List of patterns that may include wildcards (e.g., ["application/*", "text/*"])
|
|
27
|
+
* @returns true if actual matches any pattern; false otherwise
|
|
28
|
+
*/
|
|
29
|
+
var matchesMimeType = (actual, patterns) => {
|
|
30
|
+
const normalized = actual.toLowerCase();
|
|
31
|
+
for (const pattern of patterns) {
|
|
32
|
+
const normalizedPattern = pattern.toLowerCase();
|
|
33
|
+
if (normalizedPattern === normalized) return true;
|
|
34
|
+
if (normalizedPattern.includes("*")) {
|
|
35
|
+
const escaped = normalizedPattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
|
|
36
|
+
if (new RegExp(`^${escaped}$`).test(normalized)) return true;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return false;
|
|
40
|
+
};
|
|
41
|
+
//#endregion
|
|
42
|
+
export { resolveResponseBodyHandler };
|
|
43
|
+
|
|
44
|
+
//# sourceMappingURL=resolve-response-body-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-response-body-handler.js","names":[],"sources":["../../../../../src/v2/blocks/response-block/helpers/resolve-response-body-handler.ts"],"sourcesContent":["import type { ClientPlugin, ResponseBodyHandler } from '@scalar/oas-utils/helpers'\n\n/**\n * Find the first plugin response body handler that matches a given MIME type.\n * Plugins are checked in order — first match wins, allowing users to override native behavior.\n *\n * Matching supports:\n * - Exact match: \"application/msgpack\"\n * - Suffix wildcard: \"application/vnd.*+json\" matches \"application/vnd.api+json\"\n */\nexport const resolveResponseBodyHandler = (\n mimeType: string,\n plugins: ClientPlugin[],\n): ResponseBodyHandler | undefined => {\n for (const plugin of plugins) {\n if (!plugin.responseBody) {\n continue\n }\n\n for (const handler of plugin.responseBody) {\n if (matchesMimeType(mimeType, handler.mimeTypes)) {\n return handler\n }\n }\n }\n\n return undefined\n}\n\n/**\n * Checks if the given MIME type matches any of the provided MIME type patterns.\n * Supports both exact match (e.g. \"application/json\") and wildcard patterns (e.g. \"application/*\", \"application/vnd.*+json\").\n *\n * Example:\n * matchesMimeType('application/json', ['application/*']) // true\n * matchesMimeType('application/vnd.api+json', ['application/vnd.*+json']) // true\n * matchesMimeType('text/plain', ['application/json']) // false\n *\n * @param actual - The MIME type to match (e.g., \"application/json\")\n * @param patterns - List of patterns that may include wildcards (e.g., [\"application/*\", \"text/*\"])\n * @returns true if actual matches any pattern; false otherwise\n */\nconst matchesMimeType = (actual: string, patterns: string[]): boolean => {\n const normalized = actual.toLowerCase()\n\n for (const pattern of patterns) {\n const normalizedPattern = pattern.toLowerCase()\n\n // Exact match: \"application/json\" === \"application/json\"\n if (normalizedPattern === normalized) {\n return true\n }\n\n // Wildcard match: \"application/*\" or \"application/vnd.*+json\"\n if (normalizedPattern.includes('*')) {\n // Escape regex special chars except for *\n const escaped = normalizedPattern.replace(/[.+?^${}()|[\\]\\\\]/g, '\\\\$&').replace(/\\*/g, '.*')\n const regex = new RegExp(`^${escaped}$`)\n if (regex.test(normalized)) {\n return true\n }\n }\n }\n\n return false\n}\n"],"mappings":";;;;;;;;;AAUA,IAAa,8BACX,UACA,YACoC;AACpC,MAAK,MAAM,UAAU,SAAS;AAC5B,MAAI,CAAC,OAAO,aACV;AAGF,OAAK,MAAM,WAAW,OAAO,aAC3B,KAAI,gBAAgB,UAAU,QAAQ,UAAU,CAC9C,QAAO;;;;;;;;;;;;;;;;AAqBf,IAAM,mBAAmB,QAAgB,aAAgC;CACvE,MAAM,aAAa,OAAO,aAAa;AAEvC,MAAK,MAAM,WAAW,UAAU;EAC9B,MAAM,oBAAoB,QAAQ,aAAa;AAG/C,MAAI,sBAAsB,WACxB,QAAO;AAIT,MAAI,kBAAkB,SAAS,IAAI,EAAE;GAEnC,MAAM,UAAU,kBAAkB,QAAQ,sBAAsB,OAAO,CAAC,QAAQ,OAAO,KAAK;AAE5F,OADc,IAAI,OAAO,IAAI,QAAQ,GAAG,CAC9B,KAAK,WAAW,CACxB,QAAO;;;AAKb,QAAO"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser fetch uses text/plain;charset=UTF-8 as the default body type
|
|
3
|
+
* when the response does not include a Content-Type header.
|
|
4
|
+
*/
|
|
5
|
+
export declare const DEFAULT_RESPONSE_CONTENT_TYPE = "text/plain;charset=UTF-8";
|
|
6
|
+
/**
|
|
7
|
+
* Resolve the response content type with a consistent fallback.
|
|
8
|
+
*/
|
|
9
|
+
export declare const resolveResponseContentType: (contentType: string | null | undefined) => string;
|
|
10
|
+
/**
|
|
11
|
+
* Parse the effective response MIME type using the fallback content type.
|
|
12
|
+
*/
|
|
13
|
+
export declare const resolveResponseMimeType: (contentType: string | null | undefined) => import("@scalar/helpers/http/mime-type").ParsedMimeType;
|
|
14
|
+
//# sourceMappingURL=resolve-response-content-type.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-response-content-type.d.ts","sourceRoot":"","sources":["../../../../../src/v2/blocks/response-block/helpers/resolve-response-content-type.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,eAAO,MAAM,6BAA6B,6BAA6B,CAAA;AAEvE;;GAEG;AACH,eAAO,MAAM,0BAA0B,GAAI,aAAa,MAAM,GAAG,IAAI,GAAG,SAAS,KAAG,MACtC,CAAA;AAE9C;;GAEG;AACH,eAAO,MAAM,uBAAuB,GAAI,aAAa,MAAM,GAAG,IAAI,GAAG,SAAS,4DACtB,CAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { parseMimeType } from "@scalar/helpers/http/mime-type";
|
|
2
|
+
/**
|
|
3
|
+
* Resolve the response content type with a consistent fallback.
|
|
4
|
+
*/
|
|
5
|
+
var resolveResponseContentType = (contentType) => contentType ?? "text/plain;charset=UTF-8";
|
|
6
|
+
/**
|
|
7
|
+
* Parse the effective response MIME type using the fallback content type.
|
|
8
|
+
*/
|
|
9
|
+
var resolveResponseMimeType = (contentType) => parseMimeType(resolveResponseContentType(contentType));
|
|
10
|
+
//#endregion
|
|
11
|
+
export { resolveResponseContentType, resolveResponseMimeType };
|
|
12
|
+
|
|
13
|
+
//# sourceMappingURL=resolve-response-content-type.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-response-content-type.js","names":[],"sources":["../../../../../src/v2/blocks/response-block/helpers/resolve-response-content-type.ts"],"sourcesContent":["import { parseMimeType } from '@scalar/helpers/http/mime-type'\n\n/**\n * Browser fetch uses text/plain;charset=UTF-8 as the default body type\n * when the response does not include a Content-Type header.\n */\nexport const DEFAULT_RESPONSE_CONTENT_TYPE = 'text/plain;charset=UTF-8'\n\n/**\n * Resolve the response content type with a consistent fallback.\n */\nexport const resolveResponseContentType = (contentType: string | null | undefined): string =>\n contentType ?? DEFAULT_RESPONSE_CONTENT_TYPE\n\n/**\n * Parse the effective response MIME type using the fallback content type.\n */\nexport const resolveResponseMimeType = (contentType: string | null | undefined) =>\n parseMimeType(resolveResponseContentType(contentType))\n"],"mappings":";;;;AAWA,IAAa,8BAA8B,gBACzC,eAAA;;;;AAKF,IAAa,2BAA2B,gBACtC,cAAc,2BAA2B,YAAY,CAAC"}
|
|
@@ -32,7 +32,7 @@ export type AddressBarProps = {
|
|
|
32
32
|
serverMeta: ServerMeta;
|
|
33
33
|
};
|
|
34
34
|
declare const __VLS_export: import("vue").DefineComponent<AddressBarProps, {
|
|
35
|
-
methodConflict: import("vue").Ref<"
|
|
35
|
+
methodConflict: import("vue").Ref<"head" | "delete" | "get" | "options" | "patch" | "post" | "put" | "trace" | null, "head" | "delete" | "get" | "options" | "patch" | "post" | "put" | "trace" | null>;
|
|
36
36
|
pathConflict: import("vue").Ref<string | null, string | null>;
|
|
37
37
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
38
38
|
execute: () => any;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EnvironmentSelector.vue.js","names":[],"sources":["../../../../../src/v2/blocks/scalar-address-bar-block/components/EnvironmentSelector.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n ScalarButton,\n ScalarDropdown,\n ScalarDropdownDivider,\n ScalarDropdownItem,\n ScalarIcon,\n} from '@scalar/components'\nimport { computed } from 'vue'\n\nconst { environments = [], activeEnvironment } = defineProps<{\n /** List of available environments */\n environments?: string[]\n /** Currently selected environment */\n activeEnvironment?: string\n}>()\n\nconst emit = defineEmits<{\n /** Emitted when an environment is selected */\n (e: 'select:environment', environmentName: string): void\n /** Emitted when user wants to add a new environment */\n (e: 'add:environment'): void\n}>()\n\n/** Whether an environment is currently active */\nconst hasActiveEnvironment = computed(() => !!activeEnvironment)\n\n/** Whether environments exist */\nconst hasEnvironments = computed(() => environments.length > 0)\n\n/** Whether the currently selected environment exists in the dropdown options */\nconst hasSelectedEnvironmentInOptions = computed(() => {\n if (!activeEnvironment) {\n return false\n }\n\n return environments.includes(activeEnvironment)\n})\n\n/** True when an environment is selected but unavailable in the current context */\nconst hasMissingActiveEnvironment = computed(\n () => hasActiveEnvironment.value && !hasSelectedEnvironmentInOptions.value,\n)\n\n/** Display text for the button */\nconst displayText = computed(() => {\n if (hasMissingActiveEnvironment.value) {\n return `${activeEnvironment} (Unavailable)`\n }\n\n if (hasActiveEnvironment.value) {\n return activeEnvironment\n }\n if (!hasEnvironments.value) {\n return 'Add Environment'\n }\n return 'Select Environment'\n})\n\n/** Button styling based on state */\nconst buttonClass = computed(() => {\n if (hasMissingActiveEnvironment.value) {\n return 'hover:bg-b-2 text-c-2 border-transparent'\n }\n\n if (hasActiveEnvironment.value) {\n return 'bg-c-accent/10 text-c-accent hover:bg-c-accent/20 border-c-accent/30'\n }\n if (!hasEnvironments.value) {\n return 'hover:bg-b-2 text-c-3 border-transparent'\n }\n return 'hover:bg-b-2 text-c-2 border-transparent'\n})\n\nconst handleAddEnvironment = () => {\n emit('add:environment')\n}\n\nconst handleSelectEnvironment = (environmentName: string) => {\n emit('select:environment', environmentName)\n}\n</script>\n\n<template>\n <div class=\"relative flex items-center\">\n <!-- Environment indicator badge (only show when active) -->\n\n <ScalarDropdown>\n <ScalarButton\n :aria-label=\"`Current environment: ${displayText}`\"\n class=\"line-clamp-1 h-full w-fit justify-start border px-2 py-1 font-normal transition-colors\"\n :class=\"buttonClass\"\n size=\"sm\"\n variant=\"ghost\">\n <div class=\"flex max-w-[220px] min-w-0 items-center gap-1.5\">\n <!-- Icon indicator -->\n <ScalarIcon\n class=\"shrink-0\"\n :class=\"\n hasActiveEnvironment && !hasMissingActiveEnvironment\n ? 'text-c-accent'\n : 'text-c-3'\n \"\n icon=\"Globe\"\n size=\"sm\" />\n\n <!-- Environment name -->\n <span\n class=\"text-xxs block max-w-[160px] min-w-0 truncate text-left font-medium\">\n {{ displayText }}\n </span>\n\n <!-- Dropdown arrow -->\n <ScalarIcon\n class=\"shrink-0\"\n icon=\"ChevronDown\"\n size=\"xs\" />\n </div>\n </ScalarButton>\n\n <template #items>\n <!-- No environment option (clear selection) -->\n <ScalarDropdownItem\n v-if=\"hasActiveEnvironment\"\n class=\"group/item flex w-full items-center gap-1.5\"\n @click
|
|
1
|
+
{"version":3,"file":"EnvironmentSelector.vue.js","names":[],"sources":["../../../../../src/v2/blocks/scalar-address-bar-block/components/EnvironmentSelector.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n ScalarButton,\n ScalarDropdown,\n ScalarDropdownDivider,\n ScalarDropdownItem,\n ScalarIcon,\n} from '@scalar/components'\nimport { computed } from 'vue'\n\nconst { environments = [], activeEnvironment } = defineProps<{\n /** List of available environments */\n environments?: string[]\n /** Currently selected environment */\n activeEnvironment?: string\n}>()\n\nconst emit = defineEmits<{\n /** Emitted when an environment is selected */\n (e: 'select:environment', environmentName: string): void\n /** Emitted when user wants to add a new environment */\n (e: 'add:environment'): void\n}>()\n\n/** Whether an environment is currently active */\nconst hasActiveEnvironment = computed(() => !!activeEnvironment)\n\n/** Whether environments exist */\nconst hasEnvironments = computed(() => environments.length > 0)\n\n/** Whether the currently selected environment exists in the dropdown options */\nconst hasSelectedEnvironmentInOptions = computed(() => {\n if (!activeEnvironment) {\n return false\n }\n\n return environments.includes(activeEnvironment)\n})\n\n/** True when an environment is selected but unavailable in the current context */\nconst hasMissingActiveEnvironment = computed(\n () => hasActiveEnvironment.value && !hasSelectedEnvironmentInOptions.value,\n)\n\n/** Display text for the button */\nconst displayText = computed(() => {\n if (hasMissingActiveEnvironment.value) {\n return `${activeEnvironment} (Unavailable)`\n }\n\n if (hasActiveEnvironment.value) {\n return activeEnvironment\n }\n if (!hasEnvironments.value) {\n return 'Add Environment'\n }\n return 'Select Environment'\n})\n\n/** Button styling based on state */\nconst buttonClass = computed(() => {\n if (hasMissingActiveEnvironment.value) {\n return 'hover:bg-b-2 text-c-2 border-transparent'\n }\n\n if (hasActiveEnvironment.value) {\n return 'bg-c-accent/10 text-c-accent hover:bg-c-accent/20 border-c-accent/30'\n }\n if (!hasEnvironments.value) {\n return 'hover:bg-b-2 text-c-3 border-transparent'\n }\n return 'hover:bg-b-2 text-c-2 border-transparent'\n})\n\nconst handleAddEnvironment = () => {\n emit('add:environment')\n}\n\nconst handleSelectEnvironment = (environmentName: string) => {\n emit('select:environment', environmentName)\n}\n</script>\n\n<template>\n <div class=\"relative flex items-center\">\n <!-- Environment indicator badge (only show when active) -->\n\n <ScalarDropdown>\n <ScalarButton\n :aria-label=\"`Current environment: ${displayText}`\"\n class=\"line-clamp-1 h-full w-fit justify-start border px-2 py-1 font-normal transition-colors\"\n :class=\"buttonClass\"\n size=\"sm\"\n variant=\"ghost\">\n <div class=\"flex max-w-[220px] min-w-0 items-center gap-1.5\">\n <!-- Icon indicator -->\n <ScalarIcon\n class=\"shrink-0\"\n :class=\"\n hasActiveEnvironment && !hasMissingActiveEnvironment\n ? 'text-c-accent'\n : 'text-c-3'\n \"\n icon=\"Globe\"\n size=\"sm\" />\n\n <!-- Environment name -->\n <span\n class=\"text-xxs block max-w-[160px] min-w-0 truncate text-left font-medium\">\n {{ displayText }}\n </span>\n\n <!-- Dropdown arrow -->\n <ScalarIcon\n class=\"shrink-0\"\n icon=\"ChevronDown\"\n size=\"xs\" />\n </div>\n </ScalarButton>\n\n <template #items>\n <!-- No environment option (clear selection) -->\n <ScalarDropdownItem\n v-if=\"hasActiveEnvironment\"\n class=\"group/item flex w-full items-center gap-1.5\"\n @click=\"handleSelectEnvironment('')\">\n <div\n class=\"flex h-4 w-4 items-center justify-center rounded-full p-[3px]\"\n :class=\"\n !activeEnvironment\n ? 'bg-c-accent text-b-1'\n : 'shadow-border text-transparent'\n \">\n <ScalarIcon\n class=\"size-2.5\"\n icon=\"Checkmark\"\n thickness=\"3\" />\n </div>\n <span class=\"text-c-2\">No Environment</span>\n </ScalarDropdownItem>\n\n <ScalarDropdownDivider v-if=\"hasActiveEnvironment && hasEnvironments\" />\n\n <!-- Environment list -->\n <ScalarDropdownItem\n v-for=\"environmentName in environments\"\n :key=\"environmentName\"\n class=\"group/item flex w-full min-w-0 items-center gap-1.5 overflow-hidden text-ellipsis whitespace-nowrap\"\n @click=\"handleSelectEnvironment(environmentName)\">\n <div\n class=\"flex h-4 w-4 items-center justify-center rounded-full p-[3px]\"\n :class=\"\n activeEnvironment === environmentName\n ? 'bg-c-accent text-b-1'\n : 'shadow-border text-transparent'\n \">\n <ScalarIcon\n class=\"size-2.5\"\n icon=\"Checkmark\"\n thickness=\"3\" />\n </div>\n <span class=\"min-w-0 flex-1 truncate\">{{ environmentName }}</span>\n </ScalarDropdownItem>\n <ScalarDropdownDivider v-if=\"hasMissingActiveEnvironment\" />\n\n <ScalarDropdownItem\n v-if=\"hasMissingActiveEnvironment\"\n class=\"group/item flex h-auto w-full min-w-0 items-start gap-1.5 overflow-hidden\"\n disabled>\n <div\n class=\"bg-c-accent text-b-1 mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded-full p-[3px]\">\n <ScalarIcon\n class=\"size-2.5\"\n icon=\"Checkmark\"\n thickness=\"3\" />\n </div>\n <div class=\"min-w-0 flex-1 text-left\">\n <span class=\"block truncate\">\n {{ activeEnvironment }}\n </span>\n <span class=\"text-c-3 block truncate text-xs\">\n Not available in this context\n </span>\n </div>\n </ScalarDropdownItem>\n\n <ScalarDropdownDivider v-if=\"hasEnvironments\" />\n\n <!-- Add new environment button -->\n <ScalarDropdownItem\n class=\"text-c-accent flex items-center gap-1.5\"\n @click=\"handleAddEnvironment\">\n <div class=\"flex h-4 w-4 items-center justify-center\">\n <ScalarIcon\n icon=\"Add\"\n size=\"sm\" />\n </div>\n <span>{{\n hasEnvironments ? 'New Environment' : 'Create Environment'\n }}</span>\n </ScalarDropdownItem>\n\n <!-- Helper text for empty state -->\n <div\n v-if=\"!hasEnvironments && !hasActiveEnvironment\"\n class=\"text-c-3 px-2 py-1.5 text-xs\">\n <p class=\"mb-1\">\n Environments let you manage variables like API keys and base URLs\n across different contexts.\n </p>\n </div>\n </template>\n </ScalarDropdown>\n </div>\n</template>\n"],"mappings":""}
|