@scalar/api-client 3.14.0 → 3.16.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 +34 -0
- package/dist/assets/computer.ascii.virtual.js.map +1 -1
- package/dist/components/HelpfulLink.vue.script.js +1 -1
- package/dist/components/HelpfulLink.vue.script.js.map +1 -1
- package/dist/components/HttpMethod/HttpMethod.vue.js +1 -1
- package/dist/components/HttpMethod/HttpMethod.vue.script.js +1 -1
- package/dist/components/HttpMethod/HttpMethod.vue.script.js.map +1 -1
- package/dist/components/ScalarAsciiArt/ScalarAsciiArt.vue.js +1 -1
- package/dist/components/ScalarAsciiArt/ScalarAsciiArt.vue.script.js +1 -1
- package/dist/components/ScalarAsciiArt/ScalarAsciiArt.vue.script.js.map +1 -1
- package/dist/components/SectionFilter.vue.d.ts +1 -1
- package/dist/components/SectionFilter.vue.d.ts.map +1 -1
- package/dist/components/SectionFilter.vue.js +1 -1
- package/dist/components/SectionFilter.vue.script.js +2 -2
- package/dist/components/SectionFilter.vue.script.js.map +1 -1
- package/dist/components/SectionFilterButton.vue.script.js +1 -1
- package/dist/components/SectionFilterButton.vue.script.js.map +1 -1
- package/dist/components/Server/ServerVariablesForm.vue.d.ts.map +1 -1
- package/dist/components/Server/ServerVariablesForm.vue.script.js +1 -1
- package/dist/components/Server/ServerVariablesForm.vue.script.js.map +1 -1
- package/dist/components/Server/ServerVariablesSelect.vue.script.js +1 -1
- package/dist/components/Server/ServerVariablesSelect.vue.script.js.map +1 -1
- package/dist/components/Server/ServerVariablesTextbox.vue.script.js +1 -1
- package/dist/components/Server/ServerVariablesTextbox.vue.script.js.map +1 -1
- package/dist/components/Sidebar/Actions/DeleteSidebarListElement.vue.d.ts.map +1 -1
- package/dist/components/Sidebar/Actions/DeleteSidebarListElement.vue.script.js +1 -1
- package/dist/components/Sidebar/Actions/DeleteSidebarListElement.vue.script.js.map +1 -1
- package/dist/components/Sidebar/Actions/SidebarListElementForm.vue.d.ts.map +1 -1
- package/dist/components/Sidebar/Actions/SidebarListElementForm.vue.script.js +1 -1
- package/dist/components/Sidebar/Actions/SidebarListElementForm.vue.script.js.map +1 -1
- package/dist/components/ViewLayout/ViewLayout.vue.script.js +1 -1
- package/dist/components/ViewLayout/ViewLayout.vue.script.js.map +1 -1
- package/dist/components/ViewLayout/ViewLayoutContent.vue.js +1 -1
- package/dist/components/ViewLayout/ViewLayoutContent.vue.js.map +1 -1
- package/dist/components/ViewLayout/ViewLayoutSection.vue.script.js +1 -1
- package/dist/components/ViewLayout/ViewLayoutSection.vue.script.js.map +1 -1
- package/dist/hooks/use-file-dialog.js +2 -1
- package/dist/hooks/use-file-dialog.js.map +1 -1
- package/dist/plugins/posthog/index.js.map +1 -1
- package/dist/plugins/posthog/sanitize-event-payload.js +1 -1
- package/dist/plugins/posthog/sanitize-event-payload.js.map +1 -1
- package/dist/style.css +298 -275
- 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 +38 -6
- package/dist/v2/blocks/operation-block/OperationBlock.vue.script.js.map +1 -1
- package/dist/v2/blocks/operation-block/components/Header.vue.d.ts.map +1 -1
- package/dist/v2/blocks/operation-block/components/Header.vue.js +1 -1
- package/dist/v2/blocks/operation-block/components/Header.vue.script.js +1 -1
- package/dist/v2/blocks/operation-block/components/Header.vue.script.js.map +1 -1
- package/dist/v2/blocks/operation-block/components/OpenApiClientButton.vue.js +1 -1
- package/dist/v2/blocks/operation-block/components/OpenApiClientButton.vue.script.js +1 -1
- package/dist/v2/blocks/operation-block/components/OpenApiClientButton.vue.script.js.map +1 -1
- package/dist/v2/blocks/operation-block/helpers/decode-buffer.js.map +1 -1
- package/dist/v2/blocks/operation-block/helpers/get-cookie-header-keys.js.map +1 -1
- package/dist/v2/blocks/operation-block/helpers/har-to-fetch-request.js.map +1 -1
- package/dist/v2/blocks/operation-block/helpers/har-to-fetch-response.js.map +1 -1
- package/dist/v2/blocks/operation-block/helpers/persist-response-cookies.js.map +1 -1
- package/dist/v2/blocks/operation-block/helpers/persist-script-environment.d.ts +53 -0
- package/dist/v2/blocks/operation-block/helpers/persist-script-environment.d.ts.map +1 -0
- package/dist/v2/blocks/operation-block/helpers/persist-script-environment.js +91 -0
- package/dist/v2/blocks/operation-block/helpers/persist-script-environment.js.map +1 -0
- package/dist/v2/blocks/operation-block/helpers/response-cache.js.map +1 -1
- package/dist/v2/blocks/operation-block/helpers/send-request.js.map +1 -1
- package/dist/v2/blocks/operation-block/helpers/validate-path-parameters.js.map +1 -1
- package/dist/v2/blocks/request-block/RequestBlock.vue.d.ts.map +1 -1
- package/dist/v2/blocks/request-block/RequestBlock.vue.js +1 -1
- package/dist/v2/blocks/request-block/RequestBlock.vue.js.map +1 -1
- package/dist/v2/blocks/request-block/RequestBlock.vue.script.js +58 -29
- package/dist/v2/blocks/request-block/RequestBlock.vue.script.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestBody.vue.d.ts.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestBody.vue.js +1 -1
- package/dist/v2/blocks/request-block/components/RequestBody.vue.script.js +1 -1
- package/dist/v2/blocks/request-block/components/RequestBody.vue.script.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestBodyForm.vue.d.ts.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestBodyForm.vue.script.js +1 -1
- package/dist/v2/blocks/request-block/components/RequestBodyForm.vue.script.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestBodyStructured.vue.d.ts.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestBodyStructured.vue.script.js +1 -1
- package/dist/v2/blocks/request-block/components/RequestBodyStructured.vue.script.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestBodyViewToggle.vue.script.js +1 -1
- package/dist/v2/blocks/request-block/components/RequestBodyViewToggle.vue.script.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestCodeSnippet.vue.d.ts.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestCodeSnippet.vue.script.js +1 -1
- package/dist/v2/blocks/request-block/components/RequestCodeSnippet.vue.script.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestParams.vue.d.ts +2 -0
- package/dist/v2/blocks/request-block/components/RequestParams.vue.d.ts.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestParams.vue.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestParams.vue.script.js +5 -3
- package/dist/v2/blocks/request-block/components/RequestParams.vue.script.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestTable.vue.d.ts +2 -0
- package/dist/v2/blocks/request-block/components/RequestTable.vue.d.ts.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestTable.vue.js +1 -1
- package/dist/v2/blocks/request-block/components/RequestTable.vue.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestTable.vue.script.js +6 -3
- package/dist/v2/blocks/request-block/components/RequestTable.vue.script.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestTableRow.vue.d.ts +8 -0
- 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 +29 -16
- package/dist/v2/blocks/request-block/components/RequestTableRow.vue.script.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestTableTooltip.vue.script.js +1 -1
- package/dist/v2/blocks/request-block/components/RequestTableTooltip.vue.script.js.map +1 -1
- package/dist/v2/blocks/request-block/helpers/create-parameter-handlers.js.map +1 -1
- package/dist/v2/blocks/request-block/helpers/create-parameter-rows.js +1 -1
- package/dist/v2/blocks/request-block/helpers/create-parameter-rows.js.map +1 -1
- package/dist/v2/blocks/request-block/helpers/files.js.map +1 -1
- package/dist/v2/blocks/request-block/helpers/fold-structured-body-rows.js.map +1 -1
- package/dist/v2/blocks/request-block/helpers/get-form-body-rows.js +10 -5
- package/dist/v2/blocks/request-block/helpers/get-form-body-rows.js.map +1 -1
- package/dist/v2/blocks/request-block/helpers/get-parameter-content.js.map +1 -1
- package/dist/v2/blocks/request-block/helpers/get-parameter-schema.js.map +1 -1
- package/dist/v2/blocks/request-block/helpers/get-structured-body-rows.js.map +1 -1
- package/dist/v2/blocks/request-block/helpers/group-by.js.map +1 -1
- package/dist/v2/blocks/request-block/helpers/group-global-cookies.d.ts +54 -0
- package/dist/v2/blocks/request-block/helpers/group-global-cookies.d.ts.map +1 -0
- package/dist/v2/blocks/request-block/helpers/group-global-cookies.js +56 -0
- package/dist/v2/blocks/request-block/helpers/group-global-cookies.js.map +1 -0
- package/dist/v2/blocks/request-block/helpers/structured-body-codec.js +1 -1
- package/dist/v2/blocks/request-block/helpers/structured-body-codec.js.map +1 -1
- package/dist/v2/blocks/request-block/helpers/validate-parameter.js.map +1 -1
- 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.script.js +1 -1
- package/dist/v2/blocks/response-block/ResponseBlock.vue.script.js.map +1 -1
- package/dist/v2/blocks/response-block/components/Headers.vue.script.js +1 -1
- package/dist/v2/blocks/response-block/components/Headers.vue.script.js.map +1 -1
- package/dist/v2/blocks/response-block/components/ResponseBody.vue.js +1 -1
- package/dist/v2/blocks/response-block/components/ResponseBody.vue.script.js +1 -1
- package/dist/v2/blocks/response-block/components/ResponseBody.vue.script.js.map +1 -1
- package/dist/v2/blocks/response-block/components/ResponseBodyDownload.vue.script.js +1 -1
- package/dist/v2/blocks/response-block/components/ResponseBodyDownload.vue.script.js.map +1 -1
- package/dist/v2/blocks/response-block/components/ResponseBodyInfo.vue.js +1 -1
- package/dist/v2/blocks/response-block/components/ResponseBodyInfo.vue.js.map +1 -1
- package/dist/v2/blocks/response-block/components/ResponseBodyPreview.vue.d.ts.map +1 -1
- package/dist/v2/blocks/response-block/components/ResponseBodyPreview.vue.js +1 -1
- package/dist/v2/blocks/response-block/components/ResponseBodyPreview.vue.js.map +1 -1
- package/dist/v2/blocks/response-block/components/ResponseBodyPreview.vue.script.js +10 -3
- package/dist/v2/blocks/response-block/components/ResponseBodyPreview.vue.script.js.map +1 -1
- package/dist/v2/blocks/response-block/components/ResponseBodyRaw.vue.js +1 -1
- package/dist/v2/blocks/response-block/components/ResponseBodyRaw.vue.script.js +1 -1
- package/dist/v2/blocks/response-block/components/ResponseBodyRaw.vue.script.js.map +1 -1
- package/dist/v2/blocks/response-block/components/ResponseBodyStreaming.vue.d.ts.map +1 -1
- package/dist/v2/blocks/response-block/components/ResponseBodyStreaming.vue.script.js +1 -1
- package/dist/v2/blocks/response-block/components/ResponseBodyStreaming.vue.script.js.map +1 -1
- package/dist/v2/blocks/response-block/components/ResponseBodyToggle.vue.script.js +1 -1
- package/dist/v2/blocks/response-block/components/ResponseBodyToggle.vue.script.js.map +1 -1
- package/dist/v2/blocks/response-block/components/ResponseBodyVirtual.vue.script.js +1 -1
- package/dist/v2/blocks/response-block/components/ResponseBodyVirtual.vue.script.js.map +1 -1
- package/dist/v2/blocks/response-block/components/ResponseCookies.vue.script.js +1 -1
- package/dist/v2/blocks/response-block/components/ResponseCookies.vue.script.js.map +1 -1
- package/dist/v2/blocks/response-block/components/ResponseEmpty.vue.js +1 -1
- package/dist/v2/blocks/response-block/components/ResponseEmpty.vue.script.js +1 -1
- package/dist/v2/blocks/response-block/components/ResponseEmpty.vue.script.js.map +1 -1
- package/dist/v2/blocks/response-block/components/ResponseLoadingOverlay.vue.d.ts.map +1 -1
- package/dist/v2/blocks/response-block/components/ResponseLoadingOverlay.vue.js +1 -1
- package/dist/v2/blocks/response-block/components/ResponseLoadingOverlay.vue.script.js +1 -1
- package/dist/v2/blocks/response-block/components/ResponseLoadingOverlay.vue.script.js.map +1 -1
- package/dist/v2/blocks/response-block/components/ResponseMetaInformation.vue.script.js +1 -1
- package/dist/v2/blocks/response-block/components/ResponseMetaInformation.vue.script.js.map +1 -1
- package/dist/v2/blocks/response-block/helpers/extract-filename.js.map +1 -1
- package/dist/v2/blocks/response-block/helpers/get-content-length.js.map +1 -1
- package/dist/v2/blocks/response-block/helpers/media-types.d.ts +1 -1
- package/dist/v2/blocks/response-block/helpers/media-types.d.ts.map +1 -1
- package/dist/v2/blocks/response-block/helpers/media-types.js +12 -0
- package/dist/v2/blocks/response-block/helpers/media-types.js.map +1 -1
- package/dist/v2/blocks/response-block/helpers/parse-set-cookie.js.map +1 -1
- package/dist/v2/blocks/response-block/helpers/prettify-jsonc-string.js.map +1 -1
- package/dist/v2/blocks/response-block/helpers/prettify-ndjson.d.ts +12 -0
- package/dist/v2/blocks/response-block/helpers/prettify-ndjson.d.ts.map +1 -0
- package/dist/v2/blocks/response-block/helpers/prettify-ndjson.js +19 -0
- package/dist/v2/blocks/response-block/helpers/prettify-ndjson.js.map +1 -0
- 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.js.map +1 -1
- package/dist/v2/blocks/response-block/helpers/resolve-response-content-type.js +7 -1
- package/dist/v2/blocks/response-block/helpers/resolve-response-content-type.js.map +1 -1
- package/dist/v2/blocks/scalar-address-bar-block/components/AddressBar.vue.d.ts.map +1 -1
- package/dist/v2/blocks/scalar-address-bar-block/components/AddressBar.vue.js +1 -1
- package/dist/v2/blocks/scalar-address-bar-block/components/AddressBar.vue.script.js +1 -1
- package/dist/v2/blocks/scalar-address-bar-block/components/AddressBar.vue.script.js.map +1 -1
- package/dist/v2/blocks/scalar-address-bar-block/components/AddressBarHistory.vue.d.ts.map +1 -1
- package/dist/v2/blocks/scalar-address-bar-block/components/AddressBarHistory.vue.js +1 -1
- package/dist/v2/blocks/scalar-address-bar-block/components/AddressBarHistory.vue.script.js +1 -1
- package/dist/v2/blocks/scalar-address-bar-block/components/AddressBarHistory.vue.script.js.map +1 -1
- package/dist/v2/blocks/scalar-address-bar-block/components/EnvironmentSelector.vue.d.ts.map +1 -1
- package/dist/v2/blocks/scalar-address-bar-block/components/EnvironmentSelector.vue.script.js +1 -1
- package/dist/v2/blocks/scalar-address-bar-block/components/EnvironmentSelector.vue.script.js.map +1 -1
- package/dist/v2/blocks/scalar-address-bar-block/components/httpStatusCodeColors.js +3 -1
- package/dist/v2/blocks/scalar-address-bar-block/components/httpStatusCodeColors.js.map +1 -1
- package/dist/v2/blocks/scalar-address-bar-block/helpers/is-placeholder-path.js.map +1 -1
- package/dist/v2/blocks/scalar-address-bar-block/helpers/refocus-blur-target.js.map +1 -1
- package/dist/v2/blocks/scalar-address-bar-block/hooks/use-loading-animation.js.map +1 -1
- package/dist/v2/blocks/scalar-address-bar-block/hooks/use-path-masking.js.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/AuthSelector.vue.d.ts.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/AuthSelector.vue.script.js +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/DeleteRequestAuthModal.vue.d.ts.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/DeleteRequestAuthModal.vue.script.js +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/DeleteRequestAuthModal.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.script.js +1 -1
- 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.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/OAuthScopesAddModal.vue.script.js +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/OAuthScopesAddModal.vue.script.js.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/OAuthScopesInput.vue.d.ts.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/OAuthScopesInput.vue.script.js +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/OAuthScopesInput.vue.script.js.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/OpenIDConnect.vue.d.ts.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/OpenIDConnect.vue.script.js +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/OpenIDConnect.vue.script.js.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthDataTable.vue.d.ts.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthDataTable.vue.script.js +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthDataTable.vue.script.js.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthDataTableInput.vue.d.ts.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthDataTableInput.vue.script.js +3 -3
- package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthDataTableInput.vue.script.js.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue.d.ts.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue.js.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue.script.js +24 -17
- package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue.script.js.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/helpers/auth-options.js.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/helpers/fetch-openid-connect-discovery.js +5 -0
- package/dist/v2/blocks/scalar-auth-selector-block/helpers/fetch-openid-connect-discovery.js.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth-callback.js +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth-callback.js.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth-flows.d.ts +20 -0
- package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth-flows.d.ts.map +1 -0
- package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth-flows.js +27 -0
- package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth-flows.js.map +1 -0
- package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth.js +2 -2
- package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth.js.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/helpers/openid-discovery-to-flows.js.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/helpers/resolve-default-oauth2-redirect-url.js.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/helpers/run-oauth2-authorize.js.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/helpers/security-scheme.d.ts.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/helpers/security-scheme.js +15 -6
- package/dist/v2/blocks/scalar-auth-selector-block/helpers/security-scheme.js.map +1 -1
- 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.script.js +6 -1
- package/dist/v2/components/code-input/CodeInput.vue.script.js.map +1 -1
- package/dist/v2/components/code-input/CodeInputLite.vue.d.ts.map +1 -1
- package/dist/v2/components/code-input/CodeInputLite.vue.js +1 -1
- package/dist/v2/components/code-input/CodeInputLite.vue.script.js +5 -1
- package/dist/v2/components/code-input/CodeInputLite.vue.script.js.map +1 -1
- package/dist/v2/components/code-input/PillTooltipHost.vue.script.js +1 -1
- package/dist/v2/components/code-input/PillTooltipHost.vue.script.js.map +1 -1
- package/dist/v2/components/code-input/code-variable-widget.js +1 -0
- package/dist/v2/components/code-input/code-variable-widget.js.map +1 -1
- package/dist/v2/components/code-input/helpers/build-pill-context.js.map +1 -1
- package/dist/v2/components/code-input/helpers/lookup-variable-value.js.map +1 -1
- package/dist/v2/components/code-input/helpers/pill-signature.js.map +1 -1
- package/dist/v2/components/code-input/helpers/serialize-value.js.map +1 -1
- package/dist/v2/components/context-menu/ContextMenu.vue.script.js +1 -1
- package/dist/v2/components/context-menu/ContextMenu.vue.script.js.map +1 -1
- package/dist/v2/components/data-table/DataTable.vue.script.js +1 -1
- package/dist/v2/components/data-table/DataTable.vue.script.js.map +1 -1
- package/dist/v2/components/data-table/DataTableCell.vue.script.js +1 -1
- package/dist/v2/components/data-table/DataTableCell.vue.script.js.map +1 -1
- package/dist/v2/components/data-table/DataTableCheckbox.vue.script.js +1 -1
- package/dist/v2/components/data-table/DataTableCheckbox.vue.script.js.map +1 -1
- package/dist/v2/components/data-table/DataTableHeader.vue.script.js +1 -1
- package/dist/v2/components/data-table/DataTableHeader.vue.script.js.map +1 -1
- 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.script.js +1 -1
- package/dist/v2/components/data-table/DataTableInput.vue.script.js.map +1 -1
- package/dist/v2/components/data-table/DataTableInputSelect.vue.d.ts.map +1 -1
- package/dist/v2/components/data-table/DataTableInputSelect.vue.script.js +3 -2
- package/dist/v2/components/data-table/DataTableInputSelect.vue.script.js.map +1 -1
- package/dist/v2/components/data-table/DataTableRow.vue.js +1 -1
- package/dist/v2/components/data-table/DataTableRow.vue.js.map +1 -1
- package/dist/v2/components/data-table/DataTableText.vue.script.js +1 -1
- package/dist/v2/components/data-table/DataTableText.vue.script.js.map +1 -1
- package/dist/v2/components/forms/ConfirmationForm.vue.d.ts.map +1 -1
- package/dist/v2/components/forms/ConfirmationForm.vue.script.js +1 -1
- package/dist/v2/components/forms/ConfirmationForm.vue.script.js.map +1 -1
- package/dist/v2/components/layout/CollapsibleSection.vue.d.ts.map +1 -1
- package/dist/v2/components/layout/CollapsibleSection.vue.script.js +1 -1
- package/dist/v2/components/layout/CollapsibleSection.vue.script.js.map +1 -1
- package/dist/v2/components/layout/ValueEmitter.vue.d.ts +1 -1
- package/dist/v2/components/layout/ValueEmitter.vue.d.ts.map +1 -1
- package/dist/v2/components/layout/ValueEmitter.vue.script.js +1 -1
- package/dist/v2/components/layout/ValueEmitter.vue.script.js.map +1 -1
- package/dist/v2/components/modals/DeleteModal.vue.d.ts.map +1 -1
- package/dist/v2/components/modals/DeleteModal.vue.script.js +1 -1
- package/dist/v2/components/modals/DeleteModal.vue.script.js.map +1 -1
- package/dist/v2/components/modals/ModalClientContainer.vue.js +1 -1
- package/dist/v2/components/modals/ModalClientContainer.vue.script.js +1 -1
- package/dist/v2/components/modals/ModalClientContainer.vue.script.js.map +1 -1
- package/dist/v2/components/resize/Resize.vue.js +1 -1
- package/dist/v2/components/resize/Resize.vue.script.js +1 -1
- package/dist/v2/components/resize/Resize.vue.script.js.map +1 -1
- package/dist/v2/components/resize/use-split-resize.js +4 -2
- package/dist/v2/components/resize/use-split-resize.js.map +1 -1
- package/dist/v2/components/server/ServerDropdown.vue.d.ts.map +1 -1
- package/dist/v2/components/server/ServerDropdown.vue.script.js +1 -1
- package/dist/v2/components/server/ServerDropdown.vue.script.js.map +1 -1
- package/dist/v2/components/server/ServerDropdownItem.vue.d.ts.map +1 -1
- package/dist/v2/components/server/ServerDropdownItem.vue.js +1 -1
- package/dist/v2/components/server/ServerDropdownItem.vue.script.js +1 -1
- package/dist/v2/components/server/ServerDropdownItem.vue.script.js.map +1 -1
- package/dist/v2/components/sidebar/Sidebar.vue.d.ts.map +1 -1
- package/dist/v2/components/sidebar/Sidebar.vue.script.js +3 -3
- package/dist/v2/components/sidebar/Sidebar.vue.script.js.map +1 -1
- package/dist/v2/components/sidebar/SidebarMenu.vue.d.ts.map +1 -1
- package/dist/v2/components/sidebar/SidebarMenu.vue.script.js +1 -1
- package/dist/v2/components/sidebar/SidebarMenu.vue.script.js.map +1 -1
- package/dist/v2/components/sidebar/SidebarToggle.vue.script.js +1 -1
- package/dist/v2/components/sidebar/SidebarToggle.vue.script.js.map +1 -1
- package/dist/v2/constants.js +1 -1
- package/dist/v2/features/command-palette/components/CommandActionForm.vue.script.js +1 -1
- package/dist/v2/features/command-palette/components/CommandActionForm.vue.script.js.map +1 -1
- package/dist/v2/features/command-palette/components/CommandActionInput.vue.script.js +1 -1
- package/dist/v2/features/command-palette/components/CommandActionInput.vue.script.js.map +1 -1
- package/dist/v2/features/environments/EnvironmentsList.vue.d.ts.map +1 -1
- package/dist/v2/features/environments/EnvironmentsList.vue.script.js +1 -1
- package/dist/v2/features/environments/EnvironmentsList.vue.script.js.map +1 -1
- package/dist/v2/features/environments/components/Environment.vue.d.ts.map +1 -1
- package/dist/v2/features/environments/components/Environment.vue.script.js +1 -1
- package/dist/v2/features/environments/components/Environment.vue.script.js.map +1 -1
- package/dist/v2/features/environments/components/EnvironmentColors.vue.script.js +3 -2
- package/dist/v2/features/environments/components/EnvironmentColors.vue.script.js.map +1 -1
- package/dist/v2/features/environments/components/EnvironmentCreateModal.vue.d.ts.map +1 -1
- package/dist/v2/features/environments/components/EnvironmentCreateModal.vue.script.js +1 -1
- package/dist/v2/features/environments/components/EnvironmentCreateModal.vue.script.js.map +1 -1
- package/dist/v2/features/environments/components/EnvironmentDeleteModal.vue.d.ts.map +1 -1
- package/dist/v2/features/environments/components/EnvironmentDeleteModal.vue.script.js +1 -1
- package/dist/v2/features/environments/components/EnvironmentDeleteModal.vue.script.js.map +1 -1
- package/dist/v2/features/environments/components/EnvironmentVariablesDropdown.vue.d.ts.map +1 -1
- package/dist/v2/features/environments/components/EnvironmentVariablesDropdown.vue.script.js +1 -1
- package/dist/v2/features/environments/components/EnvironmentVariablesDropdown.vue.script.js.map +1 -1
- package/dist/v2/features/environments/components/EnvironmentVariablesTable.vue.d.ts.map +1 -1
- package/dist/v2/features/environments/components/EnvironmentVariablesTable.vue.js +1 -1
- package/dist/v2/features/environments/components/EnvironmentVariablesTable.vue.script.js +1 -1
- package/dist/v2/features/environments/components/EnvironmentVariablesTable.vue.script.js.map +1 -1
- package/dist/v2/features/modal/Modal.vue.d.ts.map +1 -1
- package/dist/v2/features/modal/Modal.vue.script.js +1 -1
- package/dist/v2/features/modal/Modal.vue.script.js.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/map-hidden-clients-config.js.map +1 -1
- package/dist/v2/features/modal/helpers/resolve-route-parameters.js +1 -1
- package/dist/v2/features/modal/helpers/resolve-route-parameters.js.map +1 -1
- package/dist/v2/features/modal/hooks/use-modal-sidebar.js.map +1 -1
- package/dist/v2/features/modal/modal-events.js.map +1 -1
- package/dist/v2/features/operation/Operation.vue.script.js +1 -1
- package/dist/v2/features/operation/Operation.vue.script.js.map +1 -1
- package/dist/v2/features/search/components/DocumentSearchModal.vue.d.ts.map +1 -1
- package/dist/v2/features/search/components/DocumentSearchModal.vue.js +1 -1
- package/dist/v2/features/search/components/DocumentSearchModal.vue.script.js +1 -1
- package/dist/v2/features/search/components/DocumentSearchModal.vue.script.js.map +1 -1
- package/dist/v2/features/search/components/SearchResult.vue.d.ts.map +1 -1
- package/dist/v2/features/search/components/SearchResult.vue.script.js +1 -1
- package/dist/v2/features/search/components/SearchResult.vue.script.js.map +1 -1
- package/dist/v2/features/search/helpers/create-fuse-instance.js.map +1 -1
- package/dist/v2/features/search/helpers/create-search-index.js.map +1 -1
- package/dist/v2/features/search/hooks/use-document-search.js.map +1 -1
- package/dist/v2/features/search/hooks/use-search-index.js.map +1 -1
- package/dist/v2/helpers/generate-location-id.js.map +1 -1
- package/dist/v2/helpers/handle-hotkeys.js +1 -1
- package/dist/v2/helpers/handle-hotkeys.js.map +1 -1
- package/dist/v2/helpers/test-utils.js.map +1 -1
- package/dist/v2/hooks/use-global-hot-keys.js.map +1 -1
- package/dist/v2/hooks/use-scroll-lock.js.map +1 -1
- package/dist/v2/workspace-events.js.map +1 -1
- package/dist/vue-styles.css +229 -236
- package/package.json +20 -20
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-parameter-rows.js","names":[],"sources":["../../../../../src/v2/blocks/request-block/helpers/create-parameter-rows.ts"],"sourcesContent":["import { getValueAtPath } from '@scalar/helpers/object/get-value-at-path'\nimport { isObject } from '@scalar/helpers/object/is-object'\nimport { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport { deSerializeParameter, getExample, isParamDisabled } from '@scalar/workspace-store/request-example'\nimport type {\n ParameterObject,\n ParameterWithSchemaObject,\n ReferenceType,\n SchemaObject,\n} from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport { isArraySchema, isObjectSchema } from '@scalar/workspace-store/schemas/v3.1/strict/type-guards'\n\nimport type { TableRow } from '../components/RequestTableRow.vue'\nimport { getParameterSchema } from './get-parameter-schema'\n\ntype ParameterWithRequiredSchema = ParameterWithSchemaObject & {\n schema: ReferenceType<SchemaObject>\n}\n\n/** Serialization mode for object-typed query parameters that we expand into multiple rows. */\ntype ExpansionMode = 'form' | 'deepObject'\n\nconst isParameterWithSchema = (parameter: ParameterObject): parameter is ParameterWithRequiredSchema =>\n 'schema' in parameter && parameter.schema !== undefined\n\nconst resolveSchema = (schema: unknown): SchemaObject | undefined => {\n const resolvedSchema = getResolvedRef(schema as SchemaObject | { '$ref': string; '$ref-value': SchemaObject })\n\n return resolvedSchema as SchemaObject | undefined\n}\n\n/**\n * Resolves the OpenAPI serialization style and explode flag for a parameter, falling back to the\n * spec defaults (style: 'form', explode: true when style is 'form').\n */\nconst getParameterStyleAndExplode = (parameter: ParameterObject): { style: string; explode: boolean } => {\n const style = 'style' in parameter && parameter.style ? parameter.style : 'form'\n const explode = 'explode' in parameter && parameter.explode !== undefined ? parameter.explode : style === 'form'\n\n return { style, explode }\n}\n\n/**\n * Decides whether an object-typed query parameter should be expanded into one row per property,\n * and which expansion mode to use. Returns null when the parameter should stay as a single row\n * (non-query, non-object schema, or a serialization style we do not expand).\n */\nconst getExpansionMode = (parameter: ParameterObject, schema: SchemaObject | undefined): ExpansionMode | null => {\n if (parameter.in !== 'query' || !isParameterWithSchema(parameter) || !schema || !isObjectSchema(schema)) {\n return null\n }\n\n const { style, explode } = getParameterStyleAndExplode(parameter)\n if (!explode) {\n return null\n }\n\n if (style === 'form') {\n return 'form'\n }\n if (style === 'deepObject') {\n return 'deepObject'\n }\n\n return null\n}\n\nconst toTableValue = (value: unknown): string => {\n if (value === undefined || value === null) {\n return ''\n }\n\n if (Array.isArray(value)) {\n return value.join(',')\n }\n\n if (typeof value === 'object') {\n return JSON.stringify(value)\n }\n\n return String(value)\n}\n\nconst toPathKey = (path: readonly string[]): string => path.join('\\u0000')\n\nconst toTableRow = ({\n parameter,\n name,\n value,\n description,\n schema,\n isRequired,\n isDisabled,\n sourceParameterValuePath,\n}: {\n parameter: ParameterObject\n name: string\n value: unknown\n description: string | undefined\n schema: SchemaObject | undefined\n isRequired: boolean | undefined\n isDisabled: boolean\n sourceParameterValuePath?: string[]\n}): TableRow => ({\n name,\n value: toTableValue(value),\n description,\n schema,\n isRequired,\n isDisabled,\n originalParameter: parameter,\n sourceParameterValuePath,\n})\n\n/**\n * Builds the row name for an expanded property at a given value path. deepObject rows mirror the\n * wire format (`parent[a][b]`); form-style explode uses the bare top-level key.\n */\nconst getExpandedRowName = (parameter: ParameterObject, path: string[], mode: ExpansionMode): string =>\n mode === 'deepObject' ? `${parameter.name}${path.map((segment) => `[${segment}]`).join('')}` : (path[0] ?? '')\n\n/**\n * Appends the display-only trailing `[]` to deepObject array leaves so the name matches the\n * serialized `parent[ids][]=1&parent[ids][]=2` form. The bracket is display-only — the row's\n * `sourceParameterValuePath` stays bracket-free. It also lets write-back recognize the leaf as an\n * array even on renamed and unmapped rows, which carry no schema.\n */\nconst withArrayBracket = (name: string, mode: ExpansionMode, isArray: boolean): string =>\n mode === 'deepObject' && isArray ? `${name}[]` : name\n\n/** Build the single-row representation used when a parameter is not expanded. */\nconst toSingleParameterRow = (\n parameter: ParameterObject,\n schema: SchemaObject | undefined,\n value: unknown,\n isDisabled: boolean,\n): TableRow =>\n toTableRow({\n parameter,\n name: parameter.name,\n value,\n description: parameter.description,\n schema,\n isRequired: parameter.required,\n isDisabled,\n })\n\n/**\n * Walks an object schema and produces one row per property.\n *\n * - In `form` mode (the OpenAPI default for query parameters) only the top-level properties are\n * flattened, and each row is named after the property itself (`status`).\n * - In `deepObject` mode we recurse into nested objects and emit bracketed names that mirror the\n * serialization on the wire (`filter[user][id]`).\n *\n * `pathPrefix` tracks the path inside the parent parameter value so the handler can later\n * reassemble all sibling rows back into a single object payload.\n */\nconst getExpandedPropertyRows = ({\n parameter,\n schema,\n value,\n pathPrefix,\n namePrefix,\n mode,\n isDisabled,\n hiddenValuePaths,\n renamedValuePaths,\n renameTargetPaths,\n}: {\n parameter: ParameterObject\n schema: Extract<SchemaObject, { type: 'object' }>\n value: unknown\n pathPrefix: string[]\n namePrefix: string\n mode: ExpansionMode\n isDisabled: boolean\n hiddenValuePaths: ReadonlySet<string>\n renamedValuePaths: ReadonlyMap<string, string[]>\n renameTargetPaths: ReadonlySet<string>\n}): TableRow[] => {\n if (!schema.properties) {\n return []\n }\n\n const requiredProperties = new Set(schema.required ?? [])\n\n return Object.entries(schema.properties).flatMap(([propertyName, propertySchema]) => {\n const resolvedPropertySchema = resolveSchema(propertySchema)\n if (!resolvedPropertySchema) {\n return []\n }\n\n const path = [...pathPrefix, propertyName]\n const name = namePrefix ? `${namePrefix}[${propertyName}]` : propertyName\n\n // When this property was renamed, the value lives at the typed key instead of the schema path.\n // Keep the row in its original slot so it does not jump to the end of the table.\n const renamedTo = renamedValuePaths.get(toPathKey(path))\n const effectivePath = renamedTo ?? path\n\n if (hiddenValuePaths.has(toPathKey(effectivePath))) {\n return []\n }\n\n if (renamedTo) {\n // The value move is debounced, so until it lands the value still sits at the old schema path.\n // Fall back to it so the renamed row shows its value immediately instead of flickering empty.\n const renamedValue = getValueAtPath(value, renamedTo)\n const effectiveValue = renamedValue === undefined ? getValueAtPath(value, path) : renamedValue\n\n return [\n toTableRow({\n parameter,\n // The renamed key carries no schema, so the value's array-ness drives the `[]` marker.\n name: withArrayBracket(getExpandedRowName(parameter, renamedTo, mode), mode, Array.isArray(effectiveValue)),\n value: effectiveValue,\n description: parameter.description,\n // The renamed key no longer maps to the schema property, so it carries no schema.\n schema: undefined,\n isRequired: false,\n isDisabled,\n sourceParameterValuePath: renamedTo,\n }),\n ]\n }\n\n // Another property was renamed onto this path (for example \"a\" renamed to an existing \"b\").\n // The renamed row already occupies this slot, so skip the schema-derived row to avoid rendering\n // two rows for the same value path.\n if (renameTargetPaths.has(toPathKey(path))) {\n return []\n }\n\n // Only deepObject style recurses into nested objects. The OpenAPI 3.1 spec says form-style\n // explode flattens only the top-level properties.\n const shouldRecurse =\n mode === 'deepObject' && isObjectSchema(resolvedPropertySchema) && Boolean(resolvedPropertySchema.properties)\n\n if (shouldRecurse) {\n return getExpandedPropertyRows({\n parameter,\n schema: resolvedPropertySchema,\n value,\n pathPrefix: path,\n namePrefix: name,\n mode,\n isDisabled,\n hiddenValuePaths,\n renamedValuePaths,\n renameTargetPaths,\n })\n }\n\n const leafValue = getValueAtPath(value, path)\n\n // deepObject array values serialize with the trailing-bracket convention\n // (filter[ids][]=1&filter[ids][]=2), so mirror that in the displayed name. We base this on the\n // resolved value too, since the schema can be a composition (anyOf) that hides the array type.\n const displayName = withArrayBracket(name, mode, isArraySchema(resolvedPropertySchema) || Array.isArray(leafValue))\n\n return [\n toTableRow({\n parameter,\n name: displayName,\n value: leafValue,\n description: resolvedPropertySchema.description ?? parameter.description,\n schema: resolvedPropertySchema,\n isRequired: requiredProperties.has(propertyName),\n isDisabled,\n sourceParameterValuePath: path,\n }),\n ]\n })\n}\n\n/**\n * Collects the leaf paths of an object value. In `form` mode only the top-level keys are leaves\n * (form-style explode does not flatten nested objects); in `deepObject` mode we recurse into nested\n * objects, mirroring how the rows and serialization are built.\n */\nconst collectValueLeafPaths = (value: unknown, mode: ExpansionMode): string[][] => {\n if (!isObject(value)) {\n return []\n }\n\n const paths: string[][] = []\n\n const walk = (node: Record<string, unknown>, prefix: string[]): void => {\n for (const [key, val] of Object.entries(node)) {\n const path = [...prefix, key]\n\n if (mode === 'deepObject' && isObject(val)) {\n walk(val, path)\n } else {\n paths.push(path)\n }\n }\n }\n\n walk(value, [])\n\n return paths\n}\n\n/**\n * Builds rows for value paths that the schema does not describe. This keeps user-edited keys (for\n * example a property that was renamed in the table) visible instead of snapping back to the\n * schema-derived rows on the next render.\n */\nconst getUnmappedValueRows = ({\n parameter,\n value,\n schemaRows,\n mode,\n isDisabled,\n renamedValuePaths,\n}: {\n parameter: ParameterObject\n value: unknown\n schemaRows: TableRow[]\n mode: ExpansionMode\n isDisabled: boolean\n renamedValuePaths: ReadonlyMap<string, string[]>\n}): TableRow[] => {\n // Skip the renamed-away source paths too: the value move is debounced, so the old key lingers in\n // the value for a moment and would otherwise flash as a duplicate row next to the renamed one.\n const seen = new Set([\n ...schemaRows.map((row) => toPathKey(row.sourceParameterValuePath ?? [])),\n ...renamedValuePaths.keys(),\n ])\n\n // These rows always render: a key that carries a value should stay visible. The hidden-path set\n // only suppresses empty schema suggestions, so it is intentionally not applied here.\n return collectValueLeafPaths(value, mode)\n .filter((path) => !seen.has(toPathKey(path)))\n .map((path) => {\n const leafValue = getValueAtPath(value, path)\n\n return toTableRow({\n parameter,\n // No schema describes these rows, so the value's array-ness drives the `[]` marker.\n name: withArrayBracket(getExpandedRowName(parameter, path, mode), mode, Array.isArray(leafValue)),\n value: leafValue,\n description: parameter.description,\n schema: undefined,\n isRequired: false,\n isDisabled,\n sourceParameterValuePath: path,\n })\n })\n}\n\n/**\n * Turns a single OpenAPI parameter into one or more table rows.\n *\n * For object-typed query parameters with `form`/`explode: true` (the default) or `deepObject`\n * serialization, each property becomes its own row so the user can edit them individually,\n * matching how tools like Postman present the same parameter. Every other parameter passes\n * through as a single row.\n */\nexport const createParameterRows = (\n parameter: ParameterObject,\n exampleKey: string,\n options: {\n hiddenValuePaths?: readonly string[][]\n renamedValuePaths?: readonly { from: string[]; to: string[] }[]\n } = {},\n): TableRow[] => {\n const example = getExample(parameter, exampleKey, undefined)\n const isDisabled = isParamDisabled(parameter, example)\n const schema = getParameterSchema(parameter)\n const mode = getExpansionMode(parameter, schema)\n\n // Non-expandable parameters: render as a single row.\n if (mode === null || !schema || !isObjectSchema(schema)) {\n return [toSingleParameterRow(parameter, schema, example?.value, isDisabled)]\n }\n\n // Expand into per-property rows. The deserialized value is used so existing per-property values\n // can be displayed in the table even when the example arrives as a serialized string.\n const value = example?.value === undefined ? undefined : deSerializeParameter(example.value, parameter)\n\n // Fall back to a single row only when the schema has no properties to expand.\n if (!schema.properties) {\n return [toSingleParameterRow(parameter, schema, example?.value, isDisabled)]\n }\n\n const hiddenValuePaths = new Set(options.hiddenValuePaths?.map(toPathKey) ?? [])\n const renamedValuePaths = new Map((options.renamedValuePaths ?? []).map(({ from, to }) => [toPathKey(from), to]))\n // Paths a property was renamed onto, used to suppress the colliding schema-derived row.\n const renameTargetPaths = new Set((options.renamedValuePaths ?? []).map(({ to }) => toPathKey(to)))\n\n const rows = getExpandedPropertyRows({\n parameter,\n schema,\n value,\n pathPrefix: [],\n // deepObject names every row with a `parent[child]` prefix; form-style names use bare property names.\n namePrefix: mode === 'deepObject' ? parameter.name : '',\n mode,\n isDisabled,\n hiddenValuePaths,\n renamedValuePaths,\n renameTargetPaths,\n })\n\n // Surface keys present in the value but not in the schema (for example a renamed property) so the\n // edited key keeps showing up instead of snapping back to the schema-derived rows.\n const unmappedRows = getUnmappedValueRows({\n parameter,\n value,\n schemaRows: rows,\n mode,\n isDisabled,\n renamedValuePaths,\n })\n\n return [...rows, ...unmappedRows]\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"create-parameter-rows.js","names":[],"sources":["../../../../../src/v2/blocks/request-block/helpers/create-parameter-rows.ts"],"sourcesContent":["import { getValueAtPath } from '@scalar/helpers/object/get-value-at-path'\nimport { isObject } from '@scalar/helpers/object/is-object'\nimport { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport { deSerializeParameter, getExample, isParamDisabled } from '@scalar/workspace-store/request-example'\nimport type {\n ParameterObject,\n ParameterWithSchemaObject,\n ReferenceType,\n SchemaObject,\n} from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport { isArraySchema, isObjectSchema } from '@scalar/workspace-store/schemas/v3.1/strict/type-guards'\n\nimport type { TableRow } from '../components/RequestTableRow.vue'\nimport { getParameterSchema } from './get-parameter-schema'\n\ntype ParameterWithRequiredSchema = ParameterWithSchemaObject & {\n schema: ReferenceType<SchemaObject>\n}\n\n/** Serialization mode for object-typed query parameters that we expand into multiple rows. */\ntype ExpansionMode = 'form' | 'deepObject'\n\nconst isParameterWithSchema = (parameter: ParameterObject): parameter is ParameterWithRequiredSchema =>\n 'schema' in parameter && parameter.schema !== undefined\n\nconst resolveSchema = (schema: unknown): SchemaObject | undefined => {\n const resolvedSchema = getResolvedRef(schema as SchemaObject | { '$ref': string; '$ref-value': SchemaObject })\n\n return resolvedSchema as SchemaObject | undefined\n}\n\n/**\n * Resolves the OpenAPI serialization style and explode flag for a parameter, falling back to the\n * spec defaults (style: 'form', explode: true when style is 'form').\n */\nconst getParameterStyleAndExplode = (parameter: ParameterObject): { style: string; explode: boolean } => {\n const style = 'style' in parameter && parameter.style ? parameter.style : 'form'\n const explode = 'explode' in parameter && parameter.explode !== undefined ? parameter.explode : style === 'form'\n\n return { style, explode }\n}\n\n/**\n * Decides whether an object-typed query parameter should be expanded into one row per property,\n * and which expansion mode to use. Returns null when the parameter should stay as a single row\n * (non-query, non-object schema, or a serialization style we do not expand).\n */\nconst getExpansionMode = (parameter: ParameterObject, schema: SchemaObject | undefined): ExpansionMode | null => {\n if (parameter.in !== 'query' || !isParameterWithSchema(parameter) || !schema || !isObjectSchema(schema)) {\n return null\n }\n\n const { style, explode } = getParameterStyleAndExplode(parameter)\n if (!explode) {\n return null\n }\n\n if (style === 'form') {\n return 'form'\n }\n if (style === 'deepObject') {\n return 'deepObject'\n }\n\n return null\n}\n\nconst toTableValue = (value: unknown): string => {\n if (value === undefined || value === null) {\n return ''\n }\n\n if (Array.isArray(value)) {\n return value.join(',')\n }\n\n if (typeof value === 'object') {\n return JSON.stringify(value)\n }\n\n return String(value)\n}\n\nconst toPathKey = (path: readonly string[]): string => path.join('\\u0000')\n\nconst toTableRow = ({\n parameter,\n name,\n value,\n description,\n schema,\n isRequired,\n isDisabled,\n sourceParameterValuePath,\n}: {\n parameter: ParameterObject\n name: string\n value: unknown\n description: string | undefined\n schema: SchemaObject | undefined\n isRequired: boolean | undefined\n isDisabled: boolean\n sourceParameterValuePath?: string[]\n}): TableRow => ({\n name,\n value: toTableValue(value),\n description,\n schema,\n isRequired,\n isDisabled,\n originalParameter: parameter,\n sourceParameterValuePath,\n})\n\n/**\n * Builds the row name for an expanded property at a given value path. deepObject rows mirror the\n * wire format (`parent[a][b]`); form-style explode uses the bare top-level key.\n */\nconst getExpandedRowName = (parameter: ParameterObject, path: string[], mode: ExpansionMode): string =>\n mode === 'deepObject' ? `${parameter.name}${path.map((segment) => `[${segment}]`).join('')}` : (path[0] ?? '')\n\n/**\n * Appends the display-only trailing `[]` to deepObject array leaves so the name matches the\n * serialized `parent[ids][]=1&parent[ids][]=2` form. The bracket is display-only — the row's\n * `sourceParameterValuePath` stays bracket-free. It also lets write-back recognize the leaf as an\n * array even on renamed and unmapped rows, which carry no schema.\n */\nconst withArrayBracket = (name: string, mode: ExpansionMode, isArray: boolean): string =>\n mode === 'deepObject' && isArray ? `${name}[]` : name\n\n/** Build the single-row representation used when a parameter is not expanded. */\nconst toSingleParameterRow = (\n parameter: ParameterObject,\n schema: SchemaObject | undefined,\n value: unknown,\n isDisabled: boolean,\n): TableRow =>\n toTableRow({\n parameter,\n name: parameter.name,\n value,\n description: parameter.description,\n schema,\n isRequired: parameter.required,\n isDisabled,\n })\n\n/**\n * Walks an object schema and produces one row per property.\n *\n * - In `form` mode (the OpenAPI default for query parameters) only the top-level properties are\n * flattened, and each row is named after the property itself (`status`).\n * - In `deepObject` mode we recurse into nested objects and emit bracketed names that mirror the\n * serialization on the wire (`filter[user][id]`).\n *\n * `pathPrefix` tracks the path inside the parent parameter value so the handler can later\n * reassemble all sibling rows back into a single object payload.\n */\nconst getExpandedPropertyRows = ({\n parameter,\n schema,\n value,\n pathPrefix,\n namePrefix,\n mode,\n isDisabled,\n hiddenValuePaths,\n renamedValuePaths,\n renameTargetPaths,\n}: {\n parameter: ParameterObject\n schema: Extract<SchemaObject, { type: 'object' }>\n value: unknown\n pathPrefix: string[]\n namePrefix: string\n mode: ExpansionMode\n isDisabled: boolean\n hiddenValuePaths: ReadonlySet<string>\n renamedValuePaths: ReadonlyMap<string, string[]>\n renameTargetPaths: ReadonlySet<string>\n}): TableRow[] => {\n if (!schema.properties) {\n return []\n }\n\n const requiredProperties = new Set(schema.required ?? [])\n\n return Object.entries(schema.properties).flatMap(([propertyName, propertySchema]) => {\n const resolvedPropertySchema = resolveSchema(propertySchema)\n if (!resolvedPropertySchema) {\n return []\n }\n\n const path = [...pathPrefix, propertyName]\n const name = namePrefix ? `${namePrefix}[${propertyName}]` : propertyName\n\n // When this property was renamed, the value lives at the typed key instead of the schema path.\n // Keep the row in its original slot so it does not jump to the end of the table.\n const renamedTo = renamedValuePaths.get(toPathKey(path))\n const effectivePath = renamedTo ?? path\n\n if (hiddenValuePaths.has(toPathKey(effectivePath))) {\n return []\n }\n\n if (renamedTo) {\n // The value move is debounced, so until it lands the value still sits at the old schema path.\n // Fall back to it so the renamed row shows its value immediately instead of flickering empty.\n const renamedValue = getValueAtPath(value, renamedTo)\n const effectiveValue = renamedValue === undefined ? getValueAtPath(value, path) : renamedValue\n\n return [\n toTableRow({\n parameter,\n // The renamed key carries no schema, so the value's array-ness drives the `[]` marker.\n name: withArrayBracket(getExpandedRowName(parameter, renamedTo, mode), mode, Array.isArray(effectiveValue)),\n value: effectiveValue,\n description: parameter.description,\n // The renamed key no longer maps to the schema property, so it carries no schema.\n schema: undefined,\n isRequired: false,\n isDisabled,\n sourceParameterValuePath: renamedTo,\n }),\n ]\n }\n\n // Another property was renamed onto this path (for example \"a\" renamed to an existing \"b\").\n // The renamed row already occupies this slot, so skip the schema-derived row to avoid rendering\n // two rows for the same value path.\n if (renameTargetPaths.has(toPathKey(path))) {\n return []\n }\n\n // Only deepObject style recurses into nested objects. The OpenAPI 3.1 spec says form-style\n // explode flattens only the top-level properties.\n const shouldRecurse =\n mode === 'deepObject' && isObjectSchema(resolvedPropertySchema) && Boolean(resolvedPropertySchema.properties)\n\n if (shouldRecurse) {\n return getExpandedPropertyRows({\n parameter,\n schema: resolvedPropertySchema,\n value,\n pathPrefix: path,\n namePrefix: name,\n mode,\n isDisabled,\n hiddenValuePaths,\n renamedValuePaths,\n renameTargetPaths,\n })\n }\n\n const leafValue = getValueAtPath(value, path)\n\n // deepObject array values serialize with the trailing-bracket convention\n // (filter[ids][]=1&filter[ids][]=2), so mirror that in the displayed name. We base this on the\n // resolved value too, since the schema can be a composition (anyOf) that hides the array type.\n const displayName = withArrayBracket(name, mode, isArraySchema(resolvedPropertySchema) || Array.isArray(leafValue))\n\n return [\n toTableRow({\n parameter,\n name: displayName,\n value: leafValue,\n description: resolvedPropertySchema.description ?? parameter.description,\n schema: resolvedPropertySchema,\n isRequired: requiredProperties.has(propertyName),\n isDisabled,\n sourceParameterValuePath: path,\n }),\n ]\n })\n}\n\n/**\n * Collects the leaf paths of an object value. In `form` mode only the top-level keys are leaves\n * (form-style explode does not flatten nested objects); in `deepObject` mode we recurse into nested\n * objects, mirroring how the rows and serialization are built.\n */\nconst collectValueLeafPaths = (value: unknown, mode: ExpansionMode): string[][] => {\n if (!isObject(value)) {\n return []\n }\n\n const paths: string[][] = []\n\n const walk = (node: Record<string, unknown>, prefix: string[]): void => {\n for (const [key, val] of Object.entries(node)) {\n const path = [...prefix, key]\n\n if (mode === 'deepObject' && isObject(val)) {\n walk(val, path)\n } else {\n paths.push(path)\n }\n }\n }\n\n walk(value, [])\n\n return paths\n}\n\n/**\n * Builds rows for value paths that the schema does not describe. This keeps user-edited keys (for\n * example a property that was renamed in the table) visible instead of snapping back to the\n * schema-derived rows on the next render.\n */\nconst getUnmappedValueRows = ({\n parameter,\n value,\n schemaRows,\n mode,\n isDisabled,\n renamedValuePaths,\n}: {\n parameter: ParameterObject\n value: unknown\n schemaRows: TableRow[]\n mode: ExpansionMode\n isDisabled: boolean\n renamedValuePaths: ReadonlyMap<string, string[]>\n}): TableRow[] => {\n // Skip the renamed-away source paths too: the value move is debounced, so the old key lingers in\n // the value for a moment and would otherwise flash as a duplicate row next to the renamed one.\n const seen = new Set([\n ...schemaRows.map((row) => toPathKey(row.sourceParameterValuePath ?? [])),\n ...renamedValuePaths.keys(),\n ])\n\n // These rows always render: a key that carries a value should stay visible. The hidden-path set\n // only suppresses empty schema suggestions, so it is intentionally not applied here.\n return collectValueLeafPaths(value, mode)\n .filter((path) => !seen.has(toPathKey(path)))\n .map((path) => {\n const leafValue = getValueAtPath(value, path)\n\n return toTableRow({\n parameter,\n // No schema describes these rows, so the value's array-ness drives the `[]` marker.\n name: withArrayBracket(getExpandedRowName(parameter, path, mode), mode, Array.isArray(leafValue)),\n value: leafValue,\n description: parameter.description,\n schema: undefined,\n isRequired: false,\n isDisabled,\n sourceParameterValuePath: path,\n })\n })\n}\n\n/**\n * Turns a single OpenAPI parameter into one or more table rows.\n *\n * For object-typed query parameters with `form`/`explode: true` (the default) or `deepObject`\n * serialization, each property becomes its own row so the user can edit them individually,\n * matching how tools like Postman present the same parameter. Every other parameter passes\n * through as a single row.\n */\nexport const createParameterRows = (\n parameter: ParameterObject,\n exampleKey: string,\n options: {\n hiddenValuePaths?: readonly string[][]\n renamedValuePaths?: readonly { from: string[]; to: string[] }[]\n } = {},\n): TableRow[] => {\n const example = getExample(parameter, exampleKey, undefined)\n const isDisabled = isParamDisabled(parameter, example)\n const schema = getParameterSchema(parameter)\n const mode = getExpansionMode(parameter, schema)\n\n // Non-expandable parameters: render as a single row.\n if (mode === null || !schema || !isObjectSchema(schema)) {\n return [toSingleParameterRow(parameter, schema, example?.value, isDisabled)]\n }\n\n // Expand into per-property rows. The deserialized value is used so existing per-property values\n // can be displayed in the table even when the example arrives as a serialized string.\n const value = example?.value === undefined ? undefined : deSerializeParameter(example.value, parameter)\n\n // Fall back to a single row only when the schema has no properties to expand.\n if (!schema.properties) {\n return [toSingleParameterRow(parameter, schema, example?.value, isDisabled)]\n }\n\n const hiddenValuePaths = new Set(options.hiddenValuePaths?.map(toPathKey) ?? [])\n const renamedValuePaths = new Map((options.renamedValuePaths ?? []).map(({ from, to }) => [toPathKey(from), to]))\n // Paths a property was renamed onto, used to suppress the colliding schema-derived row.\n const renameTargetPaths = new Set((options.renamedValuePaths ?? []).map(({ to }) => toPathKey(to)))\n\n const rows = getExpandedPropertyRows({\n parameter,\n schema,\n value,\n pathPrefix: [],\n // deepObject names every row with a `parent[child]` prefix; form-style names use bare property names.\n namePrefix: mode === 'deepObject' ? parameter.name : '',\n mode,\n isDisabled,\n hiddenValuePaths,\n renamedValuePaths,\n renameTargetPaths,\n })\n\n // Surface keys present in the value but not in the schema (for example a renamed property) so the\n // edited key keeps showing up instead of snapping back to the schema-derived rows.\n const unmappedRows = getUnmappedValueRows({\n parameter,\n value,\n schemaRows: rows,\n mode,\n isDisabled,\n renamedValuePaths,\n })\n\n return [...rows, ...unmappedRows]\n}\n"],"mappings":";;;;;;;AAsBA,IAAM,yBAAyB,cAC7B,YAAY,aAAa,UAAU,WAAW,KAAA;AAEhD,IAAM,iBAAiB,WAA8C;CAGnE,OAFuB,eAAe,MAE/B;AACT;;;;;AAMA,IAAM,+BAA+B,cAAoE;CACvG,MAAM,QAAQ,WAAW,aAAa,UAAU,QAAQ,UAAU,QAAQ;CAG1E,OAAO;EAAE;EAAO,SAFA,aAAa,aAAa,UAAU,YAAY,KAAA,IAAY,UAAU,UAAU,UAAU;CAElF;AAC1B;;;;;;AAOA,IAAM,oBAAoB,WAA4B,WAA2D;CAC/G,IAAI,UAAU,OAAO,WAAW,CAAC,sBAAsB,SAAS,KAAK,CAAC,UAAU,CAAC,eAAe,MAAM,GACpG,OAAO;CAGT,MAAM,EAAE,OAAO,YAAY,4BAA4B,SAAS;CAChE,IAAI,CAAC,SACH,OAAO;CAGT,IAAI,UAAU,QACZ,OAAO;CAET,IAAI,UAAU,cACZ,OAAO;CAGT,OAAO;AACT;AAEA,IAAM,gBAAgB,UAA2B;CAC/C,IAAI,UAAU,KAAA,KAAa,UAAU,MACnC,OAAO;CAGT,IAAI,MAAM,QAAQ,KAAK,GACrB,OAAO,MAAM,KAAK,GAAG;CAGvB,IAAI,OAAO,UAAU,UACnB,OAAO,KAAK,UAAU,KAAK;CAG7B,OAAO,OAAO,KAAK;AACrB;AAEA,IAAM,aAAa,SAAoC,KAAK,KAAK,IAAQ;AAEzE,IAAM,cAAc,EAClB,WACA,MACA,OACA,aACA,QACA,YACA,YACA,gCAUe;CACf;CACA,OAAO,aAAa,KAAK;CACzB;CACA;CACA;CACA;CACA,mBAAmB;CACnB;AACF;;;;;AAMA,IAAM,sBAAsB,WAA4B,MAAgB,SACtE,SAAS,eAAe,GAAG,UAAU,OAAO,KAAK,KAAK,YAAY,IAAI,QAAQ,EAAE,CAAC,CAAC,KAAK,EAAE,MAAO,KAAK,MAAM;;;;;;;AAQ7G,IAAM,oBAAoB,MAAc,MAAqB,YAC3D,SAAS,gBAAgB,UAAU,GAAG,KAAK,MAAM;;AAGnD,IAAM,wBACJ,WACA,QACA,OACA,eAEA,WAAW;CACT;CACA,MAAM,UAAU;CAChB;CACA,aAAa,UAAU;CACvB;CACA,YAAY,UAAU;CACtB;AACF,CAAC;;;;;;;;;;;;AAaH,IAAM,2BAA2B,EAC/B,WACA,QACA,OACA,YACA,YACA,MACA,YACA,kBACA,mBACA,wBAYgB;CAChB,IAAI,CAAC,OAAO,YACV,OAAO,CAAC;CAGV,MAAM,qBAAqB,IAAI,IAAI,OAAO,YAAY,CAAC,CAAC;CAExD,OAAO,OAAO,QAAQ,OAAO,UAAU,CAAC,CAAC,SAAS,CAAC,cAAc,oBAAoB;EACnF,MAAM,yBAAyB,cAAc,cAAc;EAC3D,IAAI,CAAC,wBACH,OAAO,CAAC;EAGV,MAAM,OAAO,CAAC,GAAG,YAAY,YAAY;EACzC,MAAM,OAAO,aAAa,GAAG,WAAW,GAAG,aAAa,KAAK;EAI7D,MAAM,YAAY,kBAAkB,IAAI,UAAU,IAAI,CAAC;EACvD,MAAM,gBAAgB,aAAa;EAEnC,IAAI,iBAAiB,IAAI,UAAU,aAAa,CAAC,GAC/C,OAAO,CAAC;EAGV,IAAI,WAAW;GAGb,MAAM,eAAe,eAAe,OAAO,SAAS;GACpD,MAAM,iBAAiB,iBAAiB,KAAA,IAAY,eAAe,OAAO,IAAI,IAAI;GAElF,OAAO,CACL,WAAW;IACT;IAEA,MAAM,iBAAiB,mBAAmB,WAAW,WAAW,IAAI,GAAG,MAAM,MAAM,QAAQ,cAAc,CAAC;IAC1G,OAAO;IACP,aAAa,UAAU;IAEvB,QAAQ,KAAA;IACR,YAAY;IACZ;IACA,0BAA0B;GAC5B,CAAC,CACH;EACF;EAKA,IAAI,kBAAkB,IAAI,UAAU,IAAI,CAAC,GACvC,OAAO,CAAC;EAQV,IAFE,SAAS,gBAAgB,eAAe,sBAAsB,KAAK,QAAQ,uBAAuB,UAAU,GAG5G,OAAO,wBAAwB;GAC7B;GACA,QAAQ;GACR;GACA,YAAY;GACZ,YAAY;GACZ;GACA;GACA;GACA;GACA;EACF,CAAC;EAGH,MAAM,YAAY,eAAe,OAAO,IAAI;EAO5C,OAAO,CACL,WAAW;GACT;GACA,MALgB,iBAAiB,MAAM,MAAM,cAAc,sBAAsB,KAAK,MAAM,QAAQ,SAAS,CAKvG;GACN,OAAO;GACP,aAAa,uBAAuB,eAAe,UAAU;GAC7D,QAAQ;GACR,YAAY,mBAAmB,IAAI,YAAY;GAC/C;GACA,0BAA0B;EAC5B,CAAC,CACH;CACF,CAAC;AACH;;;;;;AAOA,IAAM,yBAAyB,OAAgB,SAAoC;CACjF,IAAI,CAAC,SAAS,KAAK,GACjB,OAAO,CAAC;CAGV,MAAM,QAAoB,CAAC;CAE3B,MAAM,QAAQ,MAA+B,WAA2B;EACtE,KAAK,MAAM,CAAC,KAAK,QAAQ,OAAO,QAAQ,IAAI,GAAG;GAC7C,MAAM,OAAO,CAAC,GAAG,QAAQ,GAAG;GAE5B,IAAI,SAAS,gBAAgB,SAAS,GAAG,GACvC,KAAK,KAAK,IAAI;QAEd,MAAM,KAAK,IAAI;EAEnB;CACF;CAEA,KAAK,OAAO,CAAC,CAAC;CAEd,OAAO;AACT;;;;;;AAOA,IAAM,wBAAwB,EAC5B,WACA,OACA,YACA,MACA,YACA,wBAQgB;CAGhB,MAAM,uBAAO,IAAI,IAAI,CACnB,GAAG,WAAW,KAAK,QAAQ,UAAU,IAAI,4BAA4B,CAAC,CAAC,CAAC,GACxE,GAAG,kBAAkB,KAAK,CAC5B,CAAC;CAID,OAAO,sBAAsB,OAAO,IAAI,CAAC,CACtC,QAAQ,SAAS,CAAC,KAAK,IAAI,UAAU,IAAI,CAAC,CAAC,CAAC,CAC5C,KAAK,SAAS;EACb,MAAM,YAAY,eAAe,OAAO,IAAI;EAE5C,OAAO,WAAW;GAChB;GAEA,MAAM,iBAAiB,mBAAmB,WAAW,MAAM,IAAI,GAAG,MAAM,MAAM,QAAQ,SAAS,CAAC;GAChG,OAAO;GACP,aAAa,UAAU;GACvB,QAAQ,KAAA;GACR,YAAY;GACZ;GACA,0BAA0B;EAC5B,CAAC;CACH,CAAC;AACL;;;;;;;;;AAUA,IAAa,uBACX,WACA,YACA,UAGI,CAAC,MACU;CACf,MAAM,UAAU,WAAW,WAAW,YAAY,KAAA,CAAS;CAC3D,MAAM,aAAa,gBAAgB,WAAW,OAAO;CACrD,MAAM,SAAS,mBAAmB,SAAS;CAC3C,MAAM,OAAO,iBAAiB,WAAW,MAAM;CAG/C,IAAI,SAAS,QAAQ,CAAC,UAAU,CAAC,eAAe,MAAM,GACpD,OAAO,CAAC,qBAAqB,WAAW,QAAQ,SAAS,OAAO,UAAU,CAAC;CAK7E,MAAM,QAAQ,SAAS,UAAU,KAAA,IAAY,KAAA,IAAY,qBAAqB,QAAQ,OAAO,SAAS;CAGtG,IAAI,CAAC,OAAO,YACV,OAAO,CAAC,qBAAqB,WAAW,QAAQ,SAAS,OAAO,UAAU,CAAC;CAG7E,MAAM,mBAAmB,IAAI,IAAI,QAAQ,kBAAkB,IAAI,SAAS,KAAK,CAAC,CAAC;CAC/E,MAAM,oBAAoB,IAAI,KAAK,QAAQ,qBAAqB,CAAC,EAAA,CAAG,KAAK,EAAE,MAAM,SAAS,CAAC,UAAU,IAAI,GAAG,EAAE,CAAC,CAAC;CAEhH,MAAM,oBAAoB,IAAI,KAAK,QAAQ,qBAAqB,CAAC,EAAA,CAAG,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC,CAAC;CAElG,MAAM,OAAO,wBAAwB;EACnC;EACA;EACA;EACA,YAAY,CAAC;EAEb,YAAY,SAAS,eAAe,UAAU,OAAO;EACrD;EACA;EACA;EACA;EACA;CACF,CAAC;CAID,MAAM,eAAe,qBAAqB;EACxC;EACA;EACA,YAAY;EACZ;EACA;EACA;CACF,CAAC;CAED,OAAO,CAAC,GAAG,MAAM,GAAG,YAAY;AAClC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"files.js","names":[],"sources":["../../../../../src/v2/blocks/request-block/helpers/files.ts"],"sourcesContent":["/**\n * Extract file name from an input\n */\nexport const getFileName = (input: unknown) => {\n if (input instanceof File) {\n return input.name\n }\n return undefined\n}\n"],"mappings":";;;;AAGA,IAAa,eAAe,UAAmB;
|
|
1
|
+
{"version":3,"file":"files.js","names":[],"sources":["../../../../../src/v2/blocks/request-block/helpers/files.ts"],"sourcesContent":["/**\n * Extract file name from an input\n */\nexport const getFileName = (input: unknown) => {\n if (input instanceof File) {\n return input.name\n }\n return undefined\n}\n"],"mappings":";;;;AAGA,IAAa,eAAe,UAAmB;CAC7C,IAAI,iBAAiB,MACnB,OAAO,MAAM;AAGjB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fold-structured-body-rows.js","names":[],"sources":["../../../../../src/v2/blocks/request-block/helpers/fold-structured-body-rows.ts"],"sourcesContent":["import { setValueAtPath } from '@scalar/helpers/object/set-value-at-path'\nimport {\n buildDottedNestedRowPredicate,\n coerceLeafValueToSchemaType,\n coerceUntypedValue,\n resolveLeafSchema,\n} from '@scalar/workspace-store/request-example'\nimport type { SchemaObject } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\n\nimport type { TableRow } from '@/v2/blocks/request-block/components/RequestTableRow.vue'\n\n/**\n * Fold form-table rows back into the structured body object.\n *\n * Inverse of `getStructuredBodyRows`: dotted names fold into nested objects only when\n * the schema declares the top segment as a nested object (same predicate the multipart\n * builder uses), so a user-typed literal key like `user.email` on an undeclared prefix\n * stays flat. Values come back from the table as strings and are restored to their\n * schema-declared type; undeclared leaves get best-effort JSON coercion so untouched\n * numbers/booleans survive a form round-trip.\n *\n * Disabled rows and empty values are omitted — leaving a field empty is how a user\n * drops an optional property from the body.\n */\nexport const foldStructuredBodyRows = (rows: TableRow[], schema?: SchemaObject): Record<string, unknown> => {\n const isDottedNestedRow = buildDottedNestedRowPredicate(schema)\n const result: Record<string, unknown> = {}\n\n for (const row of rows) {\n if (row.isDisabled || !row.name) {\n continue\n }\n const value = row.value\n if (typeof value !== 'string' || value === '') {\n continue\n }\n\n const segments = isDottedNestedRow(row.name, value) ? row.name.split('.') : [row.name]\n const leafSchema = resolveLeafSchema(schema, segments)\n\n // A leaf schema without a declared type gives no signal to keep `\"5\"` a string, so\n // fall back to best-effort coercion — same as fully undeclared keys.\n const hasDeclaredType = leafSchema && 'type' in leafSchema && leafSchema.type != null\n const coerced = hasDeclaredType ? coerceLeafValueToSchemaType(value, leafSchema) : coerceUntypedValue(value)\n\n setValueAtPath(result, segments, coerced)\n }\n\n return result\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAwBA,IAAa,0BAA0B,MAAkB,WAAmD;CAC1G,MAAM,oBAAoB,8BAA8B,
|
|
1
|
+
{"version":3,"file":"fold-structured-body-rows.js","names":[],"sources":["../../../../../src/v2/blocks/request-block/helpers/fold-structured-body-rows.ts"],"sourcesContent":["import { setValueAtPath } from '@scalar/helpers/object/set-value-at-path'\nimport {\n buildDottedNestedRowPredicate,\n coerceLeafValueToSchemaType,\n coerceUntypedValue,\n resolveLeafSchema,\n} from '@scalar/workspace-store/request-example'\nimport type { SchemaObject } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\n\nimport type { TableRow } from '@/v2/blocks/request-block/components/RequestTableRow.vue'\n\n/**\n * Fold form-table rows back into the structured body object.\n *\n * Inverse of `getStructuredBodyRows`: dotted names fold into nested objects only when\n * the schema declares the top segment as a nested object (same predicate the multipart\n * builder uses), so a user-typed literal key like `user.email` on an undeclared prefix\n * stays flat. Values come back from the table as strings and are restored to their\n * schema-declared type; undeclared leaves get best-effort JSON coercion so untouched\n * numbers/booleans survive a form round-trip.\n *\n * Disabled rows and empty values are omitted — leaving a field empty is how a user\n * drops an optional property from the body.\n */\nexport const foldStructuredBodyRows = (rows: TableRow[], schema?: SchemaObject): Record<string, unknown> => {\n const isDottedNestedRow = buildDottedNestedRowPredicate(schema)\n const result: Record<string, unknown> = {}\n\n for (const row of rows) {\n if (row.isDisabled || !row.name) {\n continue\n }\n const value = row.value\n if (typeof value !== 'string' || value === '') {\n continue\n }\n\n const segments = isDottedNestedRow(row.name, value) ? row.name.split('.') : [row.name]\n const leafSchema = resolveLeafSchema(schema, segments)\n\n // A leaf schema without a declared type gives no signal to keep `\"5\"` a string, so\n // fall back to best-effort coercion — same as fully undeclared keys.\n const hasDeclaredType = leafSchema && 'type' in leafSchema && leafSchema.type != null\n const coerced = hasDeclaredType ? coerceLeafValueToSchemaType(value, leafSchema) : coerceUntypedValue(value)\n\n setValueAtPath(result, segments, coerced)\n }\n\n return result\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAwBA,IAAa,0BAA0B,MAAkB,WAAmD;CAC1G,MAAM,oBAAoB,8BAA8B,MAAM;CAC9D,MAAM,SAAkC,CAAC;CAEzC,KAAK,MAAM,OAAO,MAAM;EACtB,IAAI,IAAI,cAAc,CAAC,IAAI,MACzB;EAEF,MAAM,QAAQ,IAAI;EAClB,IAAI,OAAO,UAAU,YAAY,UAAU,IACzC;EAGF,MAAM,WAAW,kBAAkB,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,MAAM,GAAG,IAAI,CAAC,IAAI,IAAI;EACrF,MAAM,aAAa,kBAAkB,QAAQ,QAAQ;EAOrD,eAAe,QAAQ,UAHC,cAAc,UAAU,cAAc,WAAW,QAAQ,OAC/C,4BAA4B,OAAO,UAAU,IAAI,mBAAmB,KAAK,CAEnE;CAC1C;CAEA,OAAO;AACT"}
|
|
@@ -92,11 +92,16 @@ var getFormBodyRows = (example, contentType, formBodySchema) => {
|
|
|
92
92
|
return row;
|
|
93
93
|
};
|
|
94
94
|
if (Array.isArray(example.value)) return example.value.map((exampleValue) => {
|
|
95
|
-
if (isObject(exampleValue))
|
|
96
|
-
name
|
|
97
|
-
value
|
|
98
|
-
isDisabled
|
|
99
|
-
|
|
95
|
+
if (isObject(exampleValue)) {
|
|
96
|
+
const name = String(exampleValue.name);
|
|
97
|
+
const value = exampleValue.value instanceof File ? exampleValue.value : String(exampleValue.value);
|
|
98
|
+
const isDisabled = Boolean(exampleValue.isDisabled);
|
|
99
|
+
return mapRow({
|
|
100
|
+
name,
|
|
101
|
+
value,
|
|
102
|
+
isDisabled
|
|
103
|
+
});
|
|
104
|
+
}
|
|
100
105
|
return {
|
|
101
106
|
name: "",
|
|
102
107
|
value: exampleValue,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-form-body-rows.js","names":[],"sources":["../../../../../src/v2/blocks/request-block/helpers/get-form-body-rows.ts"],"sourcesContent":["import { isObject } from '@scalar/helpers/object/is-object'\nimport { objectEntries } from '@scalar/helpers/object/object-entries'\nimport { resolve } from '@scalar/workspace-store/resolve'\nimport type { ExampleObject, SchemaObject } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport { isObjectSchema } from '@scalar/workspace-store/schemas/v3.1/strict/type-guards'\n\nimport type { TableRow } from '@/v2/blocks/request-block/components/RequestTableRow.vue'\n\nexport const stringifyValue = (value: unknown) => {\n if (value instanceof File) {\n return value.name\n }\n if (typeof value === 'object' && value !== null) {\n return JSON.stringify(value)\n }\n return String(value)\n}\n\nexport type LeafRow = {\n path: string[]\n schema: SchemaObject | undefined\n isRequired: boolean\n}\n\n/**\n * Walk a (possibly nested) object schema and collect one entry per leaf property.\n *\n * A \"leaf\" is any property whose resolved schema is not an `{ type: 'object' }` schema\n * with named `properties` — i.e. primitives, arrays, files, and `additionalProperties`\n * placeholders all stop the recursion. Object properties recurse, so the widget example\n * (`file` + `props.{name,description,created_at}`) yields four leaves.\n */\nexport const collectLeafProperties = (\n schema: SchemaObject,\n parentPath: string[] = [],\n parentRequired = true,\n): LeafRow[] => {\n // Nothing to walk if this is not an object schema or has no declared properties.\n if (!isObjectSchema(schema) || !schema.properties) {\n return []\n }\n\n // `required` is a list of property names on *this* schema, so build it once per level.\n const requiredSet = new Set(schema.required ?? [])\n const leaves: LeafRow[] = []\n\n for (const [key, rawChildSchema] of objectEntries(schema.properties)) {\n const childSchema = resolve.schema(rawChildSchema)\n const path = [...parentPath, String(key)]\n\n // A leaf is only required when *every* ancestor was also required — a non-required\n // parent makes the whole subtree optional regardless of inner `required` lists.\n const isRequired = parentRequired && requiredSet.has(String(key))\n\n // Nested objects with named properties recurse so each leaf gets its own row;\n // everything else (primitives, arrays, files, additionalProperties placeholders)\n // is treated as a leaf and stops the descent.\n if (childSchema && isObjectSchema(childSchema) && childSchema.properties) {\n leaves.push(...collectLeafProperties(childSchema, path, isRequired))\n } else {\n leaves.push({ path, schema: childSchema, isRequired })\n }\n }\n\n return leaves\n}\n\n/**\n * Walk a schema + example together and collect one row per leaf, including example-only\n * keys that the schema does not declare. Schema-declared properties come first in schema\n * order; extras present in the example follow in example order at each level.\n *\n * Unlike `collectLeafProperties` (which is schema-only and feeds the dotted-name index),\n * this walker drives what the user actually sees in the form: a row for every leaf the\n * example contains, even when the schema is partial or out of date.\n */\nexport const collectExampleRows = (\n example: unknown,\n schema: SchemaObject | undefined,\n parentPath: string[] = [],\n): { path: string[]; value: unknown }[] => {\n const rows: { path: string[]; value: unknown }[] = []\n const exampleEntries = isObject(example) ? objectEntries(example as Record<string, unknown>) : []\n const exampleByKey = new Map<string, unknown>(exampleEntries.map(([key, value]) => [String(key), value]))\n const declaredKeys = new Set<string>()\n const schemaProperties = schema && isObjectSchema(schema) ? (schema.properties ?? {}) : {}\n\n // Schema-declared properties first, in schema order. Nested object schemas recurse so\n // each leaf gets its own row; otherwise the schema-declared key is a leaf and uses the\n // matching example value (or `undefined` when the example does not provide one).\n for (const [key, rawChildSchema] of objectEntries(schemaProperties)) {\n const keyStr = String(key)\n declaredKeys.add(keyStr)\n const childSchema = resolve.schema(rawChildSchema)\n const path = [...parentPath, keyStr]\n const exampleSubvalue = exampleByKey.get(keyStr)\n\n if (childSchema && isObjectSchema(childSchema) && childSchema.properties) {\n rows.push(...collectExampleRows(exampleSubvalue, childSchema, path))\n } else {\n rows.push({ path, value: exampleSubvalue })\n }\n }\n\n // Example-only properties at this level (preserve example order). Their inner shape is\n // not descended into — without a schema saying \"this is a nested object\" we have no\n // signal to flatten, so an object value becomes a single JSON-stringified row, matching\n // the schema-less fallback below.\n for (const [key, value] of exampleEntries) {\n const keyStr = String(key)\n if (declaredKeys.has(keyStr)) {\n continue\n }\n rows.push({ path: [...parentPath, keyStr], value })\n }\n\n return rows\n}\n\n/** Build the table rows for the form data, optionally enriched with schema (e.g. enum) per property */\nexport const getFormBodyRows = (\n example: ExampleObject | undefined | null,\n contentType: string,\n formBodySchema?: SchemaObject,\n): TableRow[] => {\n // We only need the rows for formData\n if (\n !example?.value ||\n (contentType !== 'multipart/form-data' && contentType !== 'application/x-www-form-urlencoded')\n ) {\n return []\n }\n\n // Get all the schema properties if the schema is an object schema\n const schemaWithProperties = formBodySchema && isObjectSchema(formBodySchema) ? formBodySchema : undefined\n const requiredSet = schemaWithProperties ? new Set(schemaWithProperties.required ?? []) : undefined\n\n // Pre-compute the leaf-by-dotted-name index up front so both the array and the\n // schema-driven branches can pull each row's leaf schema and required flag without\n // re-walking the schema. Without this, edited rows lose the per-leaf `Required`\n // badge because a top-level `properties[name]` lookup misses dotted names.\n const leafByDottedName = new Map<string, LeafRow>()\n if (schemaWithProperties) {\n for (const leaf of collectLeafProperties(schemaWithProperties)) {\n leafByDottedName.set(leaf.path.join('.'), leaf)\n }\n }\n\n const mapRow = ({\n name,\n value,\n isDisabled = false,\n }: {\n name: string\n value: string | File\n isDisabled?: boolean\n }): TableRow => {\n const row: TableRow = { name, value, isDisabled }\n if (!schemaWithProperties || !name) {\n return row\n }\n // Prefer the pre-resolved leaf (handles dotted names like `props.name`); fall back\n // to a top-level property lookup so user-added rows keep working.\n const leaf = leafByDottedName.get(name)\n const propSchema = leaf?.schema ?? resolve.schema(schemaWithProperties.properties?.[name])\n row.schema = propSchema\n row.description = propSchema?.description\n row.isRequired = leaf?.isRequired ?? requiredSet?.has(name) ?? false\n return row\n }\n\n // We have form data stored as an array\n if (Array.isArray(example.value)) {\n return example.value.map((exampleValue) => {\n if (isObject(exampleValue)) {\n const name = String(exampleValue.name)\n const value = exampleValue.value instanceof File ? exampleValue.value : String(exampleValue.value)\n const isDisabled = Boolean(exampleValue.isDisabled)\n return mapRow({ name, value, isDisabled })\n }\n return { name: '', value: exampleValue, isDisabled: false }\n })\n }\n\n // Schema-driven path: when the form body schema describes nested objects, emit one row\n // per leaf so users can edit individual fields. The dotted name (`props.name`) is folded\n // back into a single JSON multipart part by `build-request-body.ts` before the request is\n // sent. Gated to `multipart/form-data` because urlencoded has no regrouping step on send,\n // so dotted leaves would otherwise reach the wire as separate `props.name`-style fields.\n //\n // We walk the example alongside the schema so example-only properties (top-level extras\n // or undeclared keys inside a nested object) are still visible and editable instead of\n // being silently dropped to whatever the schema happens to declare.\n if (contentType === 'multipart/form-data' && schemaWithProperties && typeof example.value === 'object') {\n return collectExampleRows(example.value, schemaWithProperties).map(({ path, value }) => {\n // Missing values and explicit `null` (e.g. for a nullable schema) render as empty\n // inputs so the user can type a value rather than seeing the string \"null\".\n const rendered =\n value instanceof File ? value : value === undefined || value === null ? '' : stringifyValue(value)\n return mapRow({ name: path.join('.'), value: rendered })\n })\n }\n\n // We got an object try to convert it to an array of rows\n if (typeof example.value === 'object' && example.value) {\n return objectEntries(example.value).map(([key, value]) =>\n mapRow({ name: String(key), value: stringifyValue(value) }),\n )\n }\n\n return []\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"get-form-body-rows.js","names":[],"sources":["../../../../../src/v2/blocks/request-block/helpers/get-form-body-rows.ts"],"sourcesContent":["import { isObject } from '@scalar/helpers/object/is-object'\nimport { objectEntries } from '@scalar/helpers/object/object-entries'\nimport { resolve } from '@scalar/workspace-store/resolve'\nimport type { ExampleObject, SchemaObject } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport { isObjectSchema } from '@scalar/workspace-store/schemas/v3.1/strict/type-guards'\n\nimport type { TableRow } from '@/v2/blocks/request-block/components/RequestTableRow.vue'\n\nexport const stringifyValue = (value: unknown) => {\n if (value instanceof File) {\n return value.name\n }\n if (typeof value === 'object' && value !== null) {\n return JSON.stringify(value)\n }\n return String(value)\n}\n\nexport type LeafRow = {\n path: string[]\n schema: SchemaObject | undefined\n isRequired: boolean\n}\n\n/**\n * Walk a (possibly nested) object schema and collect one entry per leaf property.\n *\n * A \"leaf\" is any property whose resolved schema is not an `{ type: 'object' }` schema\n * with named `properties` — i.e. primitives, arrays, files, and `additionalProperties`\n * placeholders all stop the recursion. Object properties recurse, so the widget example\n * (`file` + `props.{name,description,created_at}`) yields four leaves.\n */\nexport const collectLeafProperties = (\n schema: SchemaObject,\n parentPath: string[] = [],\n parentRequired = true,\n): LeafRow[] => {\n // Nothing to walk if this is not an object schema or has no declared properties.\n if (!isObjectSchema(schema) || !schema.properties) {\n return []\n }\n\n // `required` is a list of property names on *this* schema, so build it once per level.\n const requiredSet = new Set(schema.required ?? [])\n const leaves: LeafRow[] = []\n\n for (const [key, rawChildSchema] of objectEntries(schema.properties)) {\n const childSchema = resolve.schema(rawChildSchema)\n const path = [...parentPath, String(key)]\n\n // A leaf is only required when *every* ancestor was also required — a non-required\n // parent makes the whole subtree optional regardless of inner `required` lists.\n const isRequired = parentRequired && requiredSet.has(String(key))\n\n // Nested objects with named properties recurse so each leaf gets its own row;\n // everything else (primitives, arrays, files, additionalProperties placeholders)\n // is treated as a leaf and stops the descent.\n if (childSchema && isObjectSchema(childSchema) && childSchema.properties) {\n leaves.push(...collectLeafProperties(childSchema, path, isRequired))\n } else {\n leaves.push({ path, schema: childSchema, isRequired })\n }\n }\n\n return leaves\n}\n\n/**\n * Walk a schema + example together and collect one row per leaf, including example-only\n * keys that the schema does not declare. Schema-declared properties come first in schema\n * order; extras present in the example follow in example order at each level.\n *\n * Unlike `collectLeafProperties` (which is schema-only and feeds the dotted-name index),\n * this walker drives what the user actually sees in the form: a row for every leaf the\n * example contains, even when the schema is partial or out of date.\n */\nexport const collectExampleRows = (\n example: unknown,\n schema: SchemaObject | undefined,\n parentPath: string[] = [],\n): { path: string[]; value: unknown }[] => {\n const rows: { path: string[]; value: unknown }[] = []\n const exampleEntries = isObject(example) ? objectEntries(example as Record<string, unknown>) : []\n const exampleByKey = new Map<string, unknown>(exampleEntries.map(([key, value]) => [String(key), value]))\n const declaredKeys = new Set<string>()\n const schemaProperties = schema && isObjectSchema(schema) ? (schema.properties ?? {}) : {}\n\n // Schema-declared properties first, in schema order. Nested object schemas recurse so\n // each leaf gets its own row; otherwise the schema-declared key is a leaf and uses the\n // matching example value (or `undefined` when the example does not provide one).\n for (const [key, rawChildSchema] of objectEntries(schemaProperties)) {\n const keyStr = String(key)\n declaredKeys.add(keyStr)\n const childSchema = resolve.schema(rawChildSchema)\n const path = [...parentPath, keyStr]\n const exampleSubvalue = exampleByKey.get(keyStr)\n\n if (childSchema && isObjectSchema(childSchema) && childSchema.properties) {\n rows.push(...collectExampleRows(exampleSubvalue, childSchema, path))\n } else {\n rows.push({ path, value: exampleSubvalue })\n }\n }\n\n // Example-only properties at this level (preserve example order). Their inner shape is\n // not descended into — without a schema saying \"this is a nested object\" we have no\n // signal to flatten, so an object value becomes a single JSON-stringified row, matching\n // the schema-less fallback below.\n for (const [key, value] of exampleEntries) {\n const keyStr = String(key)\n if (declaredKeys.has(keyStr)) {\n continue\n }\n rows.push({ path: [...parentPath, keyStr], value })\n }\n\n return rows\n}\n\n/** Build the table rows for the form data, optionally enriched with schema (e.g. enum) per property */\nexport const getFormBodyRows = (\n example: ExampleObject | undefined | null,\n contentType: string,\n formBodySchema?: SchemaObject,\n): TableRow[] => {\n // We only need the rows for formData\n if (\n !example?.value ||\n (contentType !== 'multipart/form-data' && contentType !== 'application/x-www-form-urlencoded')\n ) {\n return []\n }\n\n // Get all the schema properties if the schema is an object schema\n const schemaWithProperties = formBodySchema && isObjectSchema(formBodySchema) ? formBodySchema : undefined\n const requiredSet = schemaWithProperties ? new Set(schemaWithProperties.required ?? []) : undefined\n\n // Pre-compute the leaf-by-dotted-name index up front so both the array and the\n // schema-driven branches can pull each row's leaf schema and required flag without\n // re-walking the schema. Without this, edited rows lose the per-leaf `Required`\n // badge because a top-level `properties[name]` lookup misses dotted names.\n const leafByDottedName = new Map<string, LeafRow>()\n if (schemaWithProperties) {\n for (const leaf of collectLeafProperties(schemaWithProperties)) {\n leafByDottedName.set(leaf.path.join('.'), leaf)\n }\n }\n\n const mapRow = ({\n name,\n value,\n isDisabled = false,\n }: {\n name: string\n value: string | File\n isDisabled?: boolean\n }): TableRow => {\n const row: TableRow = { name, value, isDisabled }\n if (!schemaWithProperties || !name) {\n return row\n }\n // Prefer the pre-resolved leaf (handles dotted names like `props.name`); fall back\n // to a top-level property lookup so user-added rows keep working.\n const leaf = leafByDottedName.get(name)\n const propSchema = leaf?.schema ?? resolve.schema(schemaWithProperties.properties?.[name])\n row.schema = propSchema\n row.description = propSchema?.description\n row.isRequired = leaf?.isRequired ?? requiredSet?.has(name) ?? false\n return row\n }\n\n // We have form data stored as an array\n if (Array.isArray(example.value)) {\n return example.value.map((exampleValue) => {\n if (isObject(exampleValue)) {\n const name = String(exampleValue.name)\n const value = exampleValue.value instanceof File ? exampleValue.value : String(exampleValue.value)\n const isDisabled = Boolean(exampleValue.isDisabled)\n return mapRow({ name, value, isDisabled })\n }\n return { name: '', value: exampleValue, isDisabled: false }\n })\n }\n\n // Schema-driven path: when the form body schema describes nested objects, emit one row\n // per leaf so users can edit individual fields. The dotted name (`props.name`) is folded\n // back into a single JSON multipart part by `build-request-body.ts` before the request is\n // sent. Gated to `multipart/form-data` because urlencoded has no regrouping step on send,\n // so dotted leaves would otherwise reach the wire as separate `props.name`-style fields.\n //\n // We walk the example alongside the schema so example-only properties (top-level extras\n // or undeclared keys inside a nested object) are still visible and editable instead of\n // being silently dropped to whatever the schema happens to declare.\n if (contentType === 'multipart/form-data' && schemaWithProperties && typeof example.value === 'object') {\n return collectExampleRows(example.value, schemaWithProperties).map(({ path, value }) => {\n // Missing values and explicit `null` (e.g. for a nullable schema) render as empty\n // inputs so the user can type a value rather than seeing the string \"null\".\n const rendered =\n value instanceof File ? value : value === undefined || value === null ? '' : stringifyValue(value)\n return mapRow({ name: path.join('.'), value: rendered })\n })\n }\n\n // We got an object try to convert it to an array of rows\n if (typeof example.value === 'object' && example.value) {\n return objectEntries(example.value).map(([key, value]) =>\n mapRow({ name: String(key), value: stringifyValue(value) }),\n )\n }\n\n return []\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-parameter-content.js","names":[],"sources":["../../../../../src/v2/blocks/request-block/helpers/get-parameter-content.ts"],"sourcesContent":["import type { MediaTypeObject, ParameterObject } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\n\n/**\n * Extract content value from parameter object\n *\n * Parameters MUST only have one specified content key\n */\nexport const getParameterContentValue = (parameter: ParameterObject): MediaTypeObject | undefined => {\n if ('content' in parameter && parameter.content) {\n const keys = Object.keys(parameter.content)\n\n if (keys.length !== 1) {\n return undefined\n }\n\n return parameter.content[keys[0]!]\n }\n\n return undefined\n}\n"],"mappings":";;;;;;AAOA,IAAa,4BAA4B,cAA4D;
|
|
1
|
+
{"version":3,"file":"get-parameter-content.js","names":[],"sources":["../../../../../src/v2/blocks/request-block/helpers/get-parameter-content.ts"],"sourcesContent":["import type { MediaTypeObject, ParameterObject } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\n\n/**\n * Extract content value from parameter object\n *\n * Parameters MUST only have one specified content key\n */\nexport const getParameterContentValue = (parameter: ParameterObject): MediaTypeObject | undefined => {\n if ('content' in parameter && parameter.content) {\n const keys = Object.keys(parameter.content)\n\n if (keys.length !== 1) {\n return undefined\n }\n\n return parameter.content[keys[0]!]\n }\n\n return undefined\n}\n"],"mappings":";;;;;;AAOA,IAAa,4BAA4B,cAA4D;CACnG,IAAI,aAAa,aAAa,UAAU,SAAS;EAC/C,MAAM,OAAO,OAAO,KAAK,UAAU,OAAO;EAE1C,IAAI,KAAK,WAAW,GAClB;EAGF,OAAO,UAAU,QAAQ,KAAK;CAChC;AAGF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-parameter-schema.js","names":[],"sources":["../../../../../src/v2/blocks/request-block/helpers/get-parameter-schema.ts"],"sourcesContent":["import { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport type { ParameterObject, SchemaObject } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\n\nimport { getParameterContentValue } from './get-parameter-content'\n\n/**\n * Extract the schema from the parameter object\n */\nexport const getParameterSchema = (parameter: ParameterObject): SchemaObject | undefined => {\n if ('schema' in parameter && parameter.schema) {\n return getResolvedRef(parameter.schema)\n }\n\n return getResolvedRef(getParameterContentValue(parameter)?.schema)\n}\n"],"mappings":";;;;;;AAQA,IAAa,sBAAsB,cAAyD;
|
|
1
|
+
{"version":3,"file":"get-parameter-schema.js","names":[],"sources":["../../../../../src/v2/blocks/request-block/helpers/get-parameter-schema.ts"],"sourcesContent":["import { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport type { ParameterObject, SchemaObject } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\n\nimport { getParameterContentValue } from './get-parameter-content'\n\n/**\n * Extract the schema from the parameter object\n */\nexport const getParameterSchema = (parameter: ParameterObject): SchemaObject | undefined => {\n if ('schema' in parameter && parameter.schema) {\n return getResolvedRef(parameter.schema)\n }\n\n return getResolvedRef(getParameterContentValue(parameter)?.schema)\n}\n"],"mappings":";;;;;;AAQA,IAAa,sBAAsB,cAAyD;CAC1F,IAAI,YAAY,aAAa,UAAU,QACrC,OAAO,eAAe,UAAU,MAAM;CAGxC,OAAO,eAAe,yBAAyB,SAAS,CAAC,EAAE,MAAM;AACnE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-structured-body-rows.js","names":[],"sources":["../../../../../src/v2/blocks/request-block/helpers/get-structured-body-rows.ts"],"sourcesContent":["import { isObject } from '@scalar/helpers/object/is-object'\nimport { resolve } from '@scalar/workspace-store/resolve'\nimport type { SchemaObject } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport { isObjectSchema } from '@scalar/workspace-store/schemas/v3.1/strict/type-guards'\n\nimport type { TableRow } from '@/v2/blocks/request-block/components/RequestTableRow.vue'\nimport {\n type LeafRow,\n collectExampleRows,\n collectLeafProperties,\n stringifyValue,\n} from '@/v2/blocks/request-block/helpers/get-form-body-rows'\n\n/**\n * Build form-table rows for a structured (JSON/YAML) request body.\n *\n * The parsed body value is walked alongside the schema exactly like the multipart form\n * editor does: schema-declared properties first in schema order (nested objects flatten\n * into dotted-path leaves like `props.name`), example-only keys after in example order.\n * Each row is enriched with its leaf schema so the table shows enum dropdowns, required\n * badges, defaults, and validation per field.\n */\nexport const getStructuredBodyRows = (parsedValue: unknown, schema?: SchemaObject): TableRow[] => {\n const objectSchema = schema && isObjectSchema(schema) ? schema : undefined\n\n // Nothing to build rows from: neither a body object nor an object schema.\n if (!isObject(parsedValue) && !objectSchema) {\n return []\n }\n\n // Leaf index by dotted name so nested leaves keep their schema and required flag.\n const leafByDottedName = new Map<string, LeafRow>()\n if (objectSchema) {\n for (const leaf of collectLeafProperties(objectSchema)) {\n leafByDottedName.set(leaf.path.join('.'), leaf)\n }\n }\n const requiredSet = new Set(objectSchema?.required ?? [])\n\n return collectExampleRows(isObject(parsedValue) ? parsedValue : {}, objectSchema).map(({ path, value }) => {\n const name = path.join('.')\n\n // Missing values and explicit `null` render as empty inputs so the user can type a\n // value rather than seeing the string \"null\". Empty rows are omitted on fold-back.\n const rendered = value === undefined || value === null ? '' : stringifyValue(value)\n\n const row: TableRow = { name, value: rendered, isDisabled: false }\n\n const leaf = leafByDottedName.get(name)\n const propSchema = leaf?.schema ?? (objectSchema ? resolve.schema(objectSchema.properties?.[name]) : undefined)\n row.schema = propSchema\n row.description = propSchema?.description\n row.isRequired = leaf?.isRequired ?? requiredSet.has(name)\n\n return row\n })\n}\n"],"mappings":";;;;;;;;;;;;;;AAsBA,IAAa,yBAAyB,aAAsB,WAAsC;CAChG,MAAM,eAAe,UAAU,eAAe,
|
|
1
|
+
{"version":3,"file":"get-structured-body-rows.js","names":[],"sources":["../../../../../src/v2/blocks/request-block/helpers/get-structured-body-rows.ts"],"sourcesContent":["import { isObject } from '@scalar/helpers/object/is-object'\nimport { resolve } from '@scalar/workspace-store/resolve'\nimport type { SchemaObject } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport { isObjectSchema } from '@scalar/workspace-store/schemas/v3.1/strict/type-guards'\n\nimport type { TableRow } from '@/v2/blocks/request-block/components/RequestTableRow.vue'\nimport {\n type LeafRow,\n collectExampleRows,\n collectLeafProperties,\n stringifyValue,\n} from '@/v2/blocks/request-block/helpers/get-form-body-rows'\n\n/**\n * Build form-table rows for a structured (JSON/YAML) request body.\n *\n * The parsed body value is walked alongside the schema exactly like the multipart form\n * editor does: schema-declared properties first in schema order (nested objects flatten\n * into dotted-path leaves like `props.name`), example-only keys after in example order.\n * Each row is enriched with its leaf schema so the table shows enum dropdowns, required\n * badges, defaults, and validation per field.\n */\nexport const getStructuredBodyRows = (parsedValue: unknown, schema?: SchemaObject): TableRow[] => {\n const objectSchema = schema && isObjectSchema(schema) ? schema : undefined\n\n // Nothing to build rows from: neither a body object nor an object schema.\n if (!isObject(parsedValue) && !objectSchema) {\n return []\n }\n\n // Leaf index by dotted name so nested leaves keep their schema and required flag.\n const leafByDottedName = new Map<string, LeafRow>()\n if (objectSchema) {\n for (const leaf of collectLeafProperties(objectSchema)) {\n leafByDottedName.set(leaf.path.join('.'), leaf)\n }\n }\n const requiredSet = new Set(objectSchema?.required ?? [])\n\n return collectExampleRows(isObject(parsedValue) ? parsedValue : {}, objectSchema).map(({ path, value }) => {\n const name = path.join('.')\n\n // Missing values and explicit `null` render as empty inputs so the user can type a\n // value rather than seeing the string \"null\". Empty rows are omitted on fold-back.\n const rendered = value === undefined || value === null ? '' : stringifyValue(value)\n\n const row: TableRow = { name, value: rendered, isDisabled: false }\n\n const leaf = leafByDottedName.get(name)\n const propSchema = leaf?.schema ?? (objectSchema ? resolve.schema(objectSchema.properties?.[name]) : undefined)\n row.schema = propSchema\n row.description = propSchema?.description\n row.isRequired = leaf?.isRequired ?? requiredSet.has(name)\n\n return row\n })\n}\n"],"mappings":";;;;;;;;;;;;;;AAsBA,IAAa,yBAAyB,aAAsB,WAAsC;CAChG,MAAM,eAAe,UAAU,eAAe,MAAM,IAAI,SAAS,KAAA;CAGjE,IAAI,CAAC,SAAS,WAAW,KAAK,CAAC,cAC7B,OAAO,CAAC;CAIV,MAAM,mCAAmB,IAAI,IAAqB;CAClD,IAAI,cACF,KAAK,MAAM,QAAQ,sBAAsB,YAAY,GACnD,iBAAiB,IAAI,KAAK,KAAK,KAAK,GAAG,GAAG,IAAI;CAGlD,MAAM,cAAc,IAAI,IAAI,cAAc,YAAY,CAAC,CAAC;CAExD,OAAO,mBAAmB,SAAS,WAAW,IAAI,cAAc,CAAC,GAAG,YAAY,CAAC,CAAC,KAAK,EAAE,MAAM,YAAY;EACzG,MAAM,OAAO,KAAK,KAAK,GAAG;EAM1B,MAAM,MAAgB;GAAE;GAAM,OAFb,UAAU,KAAA,KAAa,UAAU,OAAO,KAAK,eAAe,KAAK;GAEnC,YAAY;EAAM;EAEjE,MAAM,OAAO,iBAAiB,IAAI,IAAI;EACtC,MAAM,aAAa,MAAM,WAAW,eAAe,QAAQ,OAAO,aAAa,aAAa,KAAK,IAAI,KAAA;EACrG,IAAI,SAAS;EACb,IAAI,cAAc,YAAY;EAC9B,IAAI,aAAa,MAAM,cAAc,YAAY,IAAI,IAAI;EAEzD,OAAO;CACT,CAAC;AACH"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"group-by.js","names":[],"sources":["../../../../../src/v2/blocks/request-block/helpers/group-by.ts"],"sourcesContent":["/**\n * Group together array objects by a specific key\n */\nexport const groupBy = <\n T extends Record<string, unknown>,\n K extends keyof T,\n V extends string | number | symbol = Extract<T[K], string | number | symbol>,\n R = T,\n>(\n arr: T[],\n key: K,\n transform?: (item: T) => R,\n): Record<V, R[]> => {\n return arr.reduce(\n (acc, obj) => {\n const transformedItem = transform ? transform(obj) : (obj as unknown as R)\n ;(acc[obj[key] as V] ??= []).push(transformedItem)\n return acc\n },\n {} as Record<V, R[]>,\n )\n}\n"],"mappings":";;;;AAGA,IAAa,WAMX,KACA,KACA,cACmB;
|
|
1
|
+
{"version":3,"file":"group-by.js","names":[],"sources":["../../../../../src/v2/blocks/request-block/helpers/group-by.ts"],"sourcesContent":["/**\n * Group together array objects by a specific key\n */\nexport const groupBy = <\n T extends Record<string, unknown>,\n K extends keyof T,\n V extends string | number | symbol = Extract<T[K], string | number | symbol>,\n R = T,\n>(\n arr: T[],\n key: K,\n transform?: (item: T) => R,\n): Record<V, R[]> => {\n return arr.reduce(\n (acc, obj) => {\n const transformedItem = transform ? transform(obj) : (obj as unknown as R)\n ;(acc[obj[key] as V] ??= []).push(transformedItem)\n return acc\n },\n {} as Record<V, R[]>,\n )\n}\n"],"mappings":";;;;AAGA,IAAa,WAMX,KACA,KACA,cACmB;CACnB,OAAO,IAAI,QACR,KAAK,QAAQ;EACZ,MAAM,kBAAkB,YAAY,UAAU,GAAG,IAAK;EACrD,CAAC,IAAI,IAAI,UAAe,CAAC,EAAA,CAAG,KAAK,eAAe;EACjD,OAAO;CACT,GACA,CAAC,CACH;AACF"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { XScalarCookie } from '@scalar/workspace-store/schemas/extensions/general/x-scalar-cookies';
|
|
2
|
+
/**
|
|
3
|
+
* A global cookie collection paired with where it lives, so a selection can be written back to the
|
|
4
|
+
* correct source: the workspace or the active document `x-scalar-cookies` list.
|
|
5
|
+
*/
|
|
6
|
+
type GlobalCookieSource = {
|
|
7
|
+
location: 'document' | 'workspace';
|
|
8
|
+
cookies: XScalarCookie[];
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* A single cookie within a preset group, carrying just enough to mutate its source: which
|
|
12
|
+
* collection it belongs to and its index within that collection's `x-scalar-cookies` array.
|
|
13
|
+
*/
|
|
14
|
+
type GlobalCookieSibling = {
|
|
15
|
+
location: 'document' | 'workspace';
|
|
16
|
+
index: number;
|
|
17
|
+
value: string;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Global cookies that share a name, grouped into a single logical cookie. When more than one value
|
|
21
|
+
* exists for the same name the group becomes a preset the user can switch between (for example a
|
|
22
|
+
* `Culture` cookie with `PL` and `EN` values).
|
|
23
|
+
*/
|
|
24
|
+
type GlobalCookieGroup = {
|
|
25
|
+
/** The shared cookie name. */
|
|
26
|
+
name: string;
|
|
27
|
+
/** The value of the currently active (enabled) sibling — the one that is sent. */
|
|
28
|
+
selectedValue: string;
|
|
29
|
+
/** Distinct selectable values, in first-seen order. Only populated for presets. */
|
|
30
|
+
options: string[];
|
|
31
|
+
/** Whether this group offers more than one value to switch between. */
|
|
32
|
+
isPreset: boolean;
|
|
33
|
+
/** Location of the first sibling, used to navigate to the global cookie settings. */
|
|
34
|
+
location: 'document' | 'workspace';
|
|
35
|
+
/** Every sibling sharing this name, so a selection can enable one and disable the rest. */
|
|
36
|
+
siblings: GlobalCookieSibling[];
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Groups global cookies by name so duplicate names collapse into a single row. Same-named cookies
|
|
40
|
+
* used to render as independent rows that all shared one disabled state, so toggling one toggled
|
|
41
|
+
* them all. Grouping them lets a name expose its values as a preset switcher instead.
|
|
42
|
+
*
|
|
43
|
+
* The `shouldInclude` predicate applies the caller's domain and path filtering while the original
|
|
44
|
+
* index is still known, so a selection can be written back to the right entry. That predicate
|
|
45
|
+
* deliberately ignores the disabled flag for preset values: a disabled value is only hidden from
|
|
46
|
+
* the request, not from the switcher, so the user can select it again.
|
|
47
|
+
*/
|
|
48
|
+
export declare const groupGlobalCookies: ({ sources, shouldInclude, }: {
|
|
49
|
+
sources: GlobalCookieSource[];
|
|
50
|
+
/** Whether a cookie is applicable to the current request (domain/path), ignoring its disabled state. */
|
|
51
|
+
shouldInclude: (cookie: XScalarCookie) => boolean;
|
|
52
|
+
}) => GlobalCookieGroup[];
|
|
53
|
+
export {};
|
|
54
|
+
//# sourceMappingURL=group-global-cookies.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"group-global-cookies.d.ts","sourceRoot":"","sources":["../../../../../src/v2/blocks/request-block/helpers/group-global-cookies.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qEAAqE,CAAA;AAExG;;;GAGG;AACH,KAAK,kBAAkB,GAAG;IACxB,QAAQ,EAAE,UAAU,GAAG,WAAW,CAAA;IAClC,OAAO,EAAE,aAAa,EAAE,CAAA;CACzB,CAAA;AAED;;;GAGG;AACH,KAAK,mBAAmB,GAAG;IACzB,QAAQ,EAAE,UAAU,GAAG,WAAW,CAAA;IAClC,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED;;;;GAIG;AACH,KAAK,iBAAiB,GAAG;IACvB,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,kFAAkF;IAClF,aAAa,EAAE,MAAM,CAAA;IACrB,mFAAmF;IACnF,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,uEAAuE;IACvE,QAAQ,EAAE,OAAO,CAAA;IACjB,qFAAqF;IACrF,QAAQ,EAAE,UAAU,GAAG,WAAW,CAAA;IAClC,2FAA2F;IAC3F,QAAQ,EAAE,mBAAmB,EAAE,CAAA;CAChC,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,GAAI,6BAGhC;IACD,OAAO,EAAE,kBAAkB,EAAE,CAAA;IAC7B,wGAAwG;IACxG,aAAa,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,OAAO,CAAA;CAClD,KAAG,iBAAiB,EA4DpB,CAAA"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
//#region src/v2/blocks/request-block/helpers/group-global-cookies.ts
|
|
2
|
+
/**
|
|
3
|
+
* Groups global cookies by name so duplicate names collapse into a single row. Same-named cookies
|
|
4
|
+
* used to render as independent rows that all shared one disabled state, so toggling one toggled
|
|
5
|
+
* them all. Grouping them lets a name expose its values as a preset switcher instead.
|
|
6
|
+
*
|
|
7
|
+
* The `shouldInclude` predicate applies the caller's domain and path filtering while the original
|
|
8
|
+
* index is still known, so a selection can be written back to the right entry. That predicate
|
|
9
|
+
* deliberately ignores the disabled flag for preset values: a disabled value is only hidden from
|
|
10
|
+
* the request, not from the switcher, so the user can select it again.
|
|
11
|
+
*/
|
|
12
|
+
var groupGlobalCookies = ({ sources, shouldInclude }) => {
|
|
13
|
+
/** Names in first-seen order so the rendered rows keep a stable, predictable order. */
|
|
14
|
+
const order = [];
|
|
15
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
16
|
+
for (const { location, cookies } of sources) cookies.forEach((cookie, index) => {
|
|
17
|
+
if (!cookie.name || !shouldInclude(cookie)) return;
|
|
18
|
+
if (!grouped.has(cookie.name)) {
|
|
19
|
+
grouped.set(cookie.name, []);
|
|
20
|
+
order.push(cookie.name);
|
|
21
|
+
}
|
|
22
|
+
grouped.get(cookie.name)?.push({
|
|
23
|
+
location,
|
|
24
|
+
value: cookie.value,
|
|
25
|
+
isDisabled: cookie.isDisabled ?? false,
|
|
26
|
+
index
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
const groups = [];
|
|
30
|
+
for (const name of order) {
|
|
31
|
+
const entries = grouped.get(name) ?? [];
|
|
32
|
+
const first = entries[0];
|
|
33
|
+
if (!first) continue;
|
|
34
|
+
const enabled = entries.filter((entry) => !entry.isDisabled);
|
|
35
|
+
const options = [...new Set(entries.map((entry) => entry.value))];
|
|
36
|
+
const isPreset = options.length > 1;
|
|
37
|
+
if (!isPreset && enabled.length === 0) continue;
|
|
38
|
+
groups.push({
|
|
39
|
+
name,
|
|
40
|
+
selectedValue: (enabled[0] ?? first).value,
|
|
41
|
+
options: isPreset ? options : [],
|
|
42
|
+
isPreset,
|
|
43
|
+
location: first.location,
|
|
44
|
+
siblings: entries.map(({ location, index, value }) => ({
|
|
45
|
+
location,
|
|
46
|
+
index,
|
|
47
|
+
value
|
|
48
|
+
}))
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
return groups;
|
|
52
|
+
};
|
|
53
|
+
//#endregion
|
|
54
|
+
export { groupGlobalCookies };
|
|
55
|
+
|
|
56
|
+
//# sourceMappingURL=group-global-cookies.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"group-global-cookies.js","names":[],"sources":["../../../../../src/v2/blocks/request-block/helpers/group-global-cookies.ts"],"sourcesContent":["import type { XScalarCookie } from '@scalar/workspace-store/schemas/extensions/general/x-scalar-cookies'\n\n/**\n * A global cookie collection paired with where it lives, so a selection can be written back to the\n * correct source: the workspace or the active document `x-scalar-cookies` list.\n */\ntype GlobalCookieSource = {\n location: 'document' | 'workspace'\n cookies: XScalarCookie[]\n}\n\n/**\n * A single cookie within a preset group, carrying just enough to mutate its source: which\n * collection it belongs to and its index within that collection's `x-scalar-cookies` array.\n */\ntype GlobalCookieSibling = {\n location: 'document' | 'workspace'\n index: number\n value: string\n}\n\n/**\n * Global cookies that share a name, grouped into a single logical cookie. When more than one value\n * exists for the same name the group becomes a preset the user can switch between (for example a\n * `Culture` cookie with `PL` and `EN` values).\n */\ntype GlobalCookieGroup = {\n /** The shared cookie name. */\n name: string\n /** The value of the currently active (enabled) sibling — the one that is sent. */\n selectedValue: string\n /** Distinct selectable values, in first-seen order. Only populated for presets. */\n options: string[]\n /** Whether this group offers more than one value to switch between. */\n isPreset: boolean\n /** Location of the first sibling, used to navigate to the global cookie settings. */\n location: 'document' | 'workspace'\n /** Every sibling sharing this name, so a selection can enable one and disable the rest. */\n siblings: GlobalCookieSibling[]\n}\n\n/**\n * Groups global cookies by name so duplicate names collapse into a single row. Same-named cookies\n * used to render as independent rows that all shared one disabled state, so toggling one toggled\n * them all. Grouping them lets a name expose its values as a preset switcher instead.\n *\n * The `shouldInclude` predicate applies the caller's domain and path filtering while the original\n * index is still known, so a selection can be written back to the right entry. That predicate\n * deliberately ignores the disabled flag for preset values: a disabled value is only hidden from\n * the request, not from the switcher, so the user can select it again.\n */\nexport const groupGlobalCookies = ({\n sources,\n shouldInclude,\n}: {\n sources: GlobalCookieSource[]\n /** Whether a cookie is applicable to the current request (domain/path), ignoring its disabled state. */\n shouldInclude: (cookie: XScalarCookie) => boolean\n}): GlobalCookieGroup[] => {\n /** Names in first-seen order so the rendered rows keep a stable, predictable order. */\n const order: string[] = []\n const grouped = new Map<\n string,\n { location: 'document' | 'workspace'; value: string; isDisabled: boolean; index: number }[]\n >()\n\n for (const { location, cookies } of sources) {\n cookies.forEach((cookie, index) => {\n if (!cookie.name || !shouldInclude(cookie)) {\n return\n }\n\n if (!grouped.has(cookie.name)) {\n grouped.set(cookie.name, [])\n order.push(cookie.name)\n }\n\n grouped.get(cookie.name)?.push({\n location,\n value: cookie.value,\n isDisabled: cookie.isDisabled ?? false,\n index,\n })\n })\n }\n\n const groups: GlobalCookieGroup[] = []\n\n for (const name of order) {\n const entries = grouped.get(name) ?? []\n const first = entries[0]\n if (!first) {\n continue\n }\n\n const enabled = entries.filter((entry) => !entry.isDisabled)\n const options = [...new Set(entries.map((entry) => entry.value))]\n const isPreset = options.length > 1\n\n // Preserve the previous behavior for plain cookies: a fully disabled single cookie stays hidden\n // from the request view. A preset always renders so its value can be switched back on.\n if (!isPreset && enabled.length === 0) {\n continue\n }\n\n groups.push({\n name,\n // The enabled sibling is the one that is sent; fall back to the first value when the whole\n // group happens to be disabled so the switcher still has something to show.\n selectedValue: (enabled[0] ?? first).value,\n options: isPreset ? options : [],\n isPreset,\n location: first.location,\n siblings: entries.map(({ location, index, value }) => ({ location, index, value })),\n })\n }\n\n return groups\n}\n"],"mappings":";;;;;;;;;;;AAmDA,IAAa,sBAAsB,EACjC,SACA,oBAKyB;;CAEzB,MAAM,QAAkB,CAAC;CACzB,MAAM,0BAAU,IAAI,IAGlB;CAEF,KAAK,MAAM,EAAE,UAAU,aAAa,SAClC,QAAQ,SAAS,QAAQ,UAAU;EACjC,IAAI,CAAC,OAAO,QAAQ,CAAC,cAAc,MAAM,GACvC;EAGF,IAAI,CAAC,QAAQ,IAAI,OAAO,IAAI,GAAG;GAC7B,QAAQ,IAAI,OAAO,MAAM,CAAC,CAAC;GAC3B,MAAM,KAAK,OAAO,IAAI;EACxB;EAEA,QAAQ,IAAI,OAAO,IAAI,CAAC,EAAE,KAAK;GAC7B;GACA,OAAO,OAAO;GACd,YAAY,OAAO,cAAc;GACjC;EACF,CAAC;CACH,CAAC;CAGH,MAAM,SAA8B,CAAC;CAErC,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,UAAU,QAAQ,IAAI,IAAI,KAAK,CAAC;EACtC,MAAM,QAAQ,QAAQ;EACtB,IAAI,CAAC,OACH;EAGF,MAAM,UAAU,QAAQ,QAAQ,UAAU,CAAC,MAAM,UAAU;EAC3D,MAAM,UAAU,CAAC,GAAG,IAAI,IAAI,QAAQ,KAAK,UAAU,MAAM,KAAK,CAAC,CAAC;EAChE,MAAM,WAAW,QAAQ,SAAS;EAIlC,IAAI,CAAC,YAAY,QAAQ,WAAW,GAClC;EAGF,OAAO,KAAK;GACV;GAGA,gBAAgB,QAAQ,MAAM,MAAA,CAAO;GACrC,SAAS,WAAW,UAAU,CAAC;GAC/B;GACA,UAAU,MAAM;GAChB,UAAU,QAAQ,KAAK,EAAE,UAAU,OAAO,aAAa;IAAE;IAAU;IAAO;GAAM,EAAE;EACpF,CAAC;CACH;CAEA,OAAO;AACT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"structured-body-codec.js","names":[],"sources":["../../../../../src/v2/blocks/request-block/helpers/structured-body-codec.ts"],"sourcesContent":["import { parseMimeType } from '@scalar/helpers/http/mime-type'\nimport { parse as parseYaml, stringify as stringifyYaml } from 'yaml'\n\n/** Parse/serialize pair for a structured (form-editable) body content type. */\ntype StructuredBodyCodec = {\n /** Language for the raw code editor, doubles as the codec family id */\n language: 'json' | 'yaml'\n parse: (text: string) => unknown\n stringify: (value: unknown) => string\n}\n\nconst jsonCodec: StructuredBodyCodec = {\n language: 'json',\n parse: (text) => JSON.parse(text),\n stringify: (value) => JSON.stringify(value, null, 2),\n}\n\nconst yamlCodec: StructuredBodyCodec = {\n language: 'yaml',\n parse: (text) => parseYaml(text),\n stringify: (value) => stringifyYaml(value),\n}\n\nconst YAML_ESSENCES = new Set(['application/yaml', 'application/x-yaml', 'text/yaml', 'text/x-yaml'])\n\n/**\n * Return the codec for content types whose body is a structured document we can edit as\n * a form (JSON and YAML families, including `+json` / `+yaml` vendor suffixes), or\n * `undefined` for everything else (multipart and urlencoded keep their own form editor).\n */\nexport const getStructuredBodyCodec = (contentType: string): StructuredBodyCodec | undefined => {\n const essence = parseMimeType(contentType).essence\n\n if (essence === 'application/json' || essence.endsWith('+json')) {\n return jsonCodec\n }\n if (YAML_ESSENCES.has(essence) || essence.endsWith('+yaml')) {\n return yamlCodec\n }\n return undefined\n}\n"],"mappings":";;;AAWA,IAAM,YAAiC;CACrC,UAAU;CACV,QAAQ,SAAS,KAAK,MAAM,
|
|
1
|
+
{"version":3,"file":"structured-body-codec.js","names":[],"sources":["../../../../../src/v2/blocks/request-block/helpers/structured-body-codec.ts"],"sourcesContent":["import { parseMimeType } from '@scalar/helpers/http/mime-type'\nimport { parse as parseYaml, stringify as stringifyYaml } from 'yaml'\n\n/** Parse/serialize pair for a structured (form-editable) body content type. */\ntype StructuredBodyCodec = {\n /** Language for the raw code editor, doubles as the codec family id */\n language: 'json' | 'yaml'\n parse: (text: string) => unknown\n stringify: (value: unknown) => string\n}\n\nconst jsonCodec: StructuredBodyCodec = {\n language: 'json',\n parse: (text) => JSON.parse(text),\n stringify: (value) => JSON.stringify(value, null, 2),\n}\n\nconst yamlCodec: StructuredBodyCodec = {\n language: 'yaml',\n parse: (text) => parseYaml(text),\n stringify: (value) => stringifyYaml(value),\n}\n\nconst YAML_ESSENCES = new Set(['application/yaml', 'application/x-yaml', 'text/yaml', 'text/x-yaml'])\n\n/**\n * Return the codec for content types whose body is a structured document we can edit as\n * a form (JSON and YAML families, including `+json` / `+yaml` vendor suffixes), or\n * `undefined` for everything else (multipart and urlencoded keep their own form editor).\n */\nexport const getStructuredBodyCodec = (contentType: string): StructuredBodyCodec | undefined => {\n const essence = parseMimeType(contentType).essence\n\n if (essence === 'application/json' || essence.endsWith('+json')) {\n return jsonCodec\n }\n if (YAML_ESSENCES.has(essence) || essence.endsWith('+yaml')) {\n return yamlCodec\n }\n return undefined\n}\n"],"mappings":";;;AAWA,IAAM,YAAiC;CACrC,UAAU;CACV,QAAQ,SAAS,KAAK,MAAM,IAAI;CAChC,YAAY,UAAU,KAAK,UAAU,OAAO,MAAM,CAAC;AACrD;AAEA,IAAM,YAAiC;CACrC,UAAU;CACV,QAAQ,SAAS,MAAU,IAAI;CAC/B,YAAY,UAAU,UAAc,KAAK;AAC3C;AAEA,IAAM,gCAAgB,IAAI,IAAI;CAAC;CAAoB;CAAsB;CAAa;AAAa,CAAC;;;;;;AAOpG,IAAa,0BAA0B,gBAAyD;CAC9F,MAAM,UAAU,cAAc,WAAW,CAAC,CAAC;CAE3C,IAAI,YAAY,sBAAsB,QAAQ,SAAS,OAAO,GAC5D,OAAO;CAET,IAAI,cAAc,IAAI,OAAO,KAAK,QAAQ,SAAS,OAAO,GACxD,OAAO;AAGX"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate-parameter.js","names":[],"sources":["../../../../../src/v2/blocks/request-block/helpers/validate-parameter.ts"],"sourcesContent":["import type { SchemaObject } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\n\n/**\n * Checks if the value of a example parameter is the expected type or format\n */\nexport const validateParameter = (\n schema?: SchemaObject,\n value?: string | File | null,\n): { ok: true } | { ok: false; message: string } => {\n if (!schema || !('type' in schema) || typeof value !== 'string') {\n return { ok: true }\n }\n\n // Numbers and integers validation\n if (schema.type === 'integer' || schema.type === 'number') {\n const numberValue = Number(value)\n\n if (isNaN(numberValue)) {\n return { ok: false, message: 'Value must be a number (e.g., 42.5)' }\n }\n\n if (schema.type === 'integer' && !Number.isInteger(numberValue)) {\n return { ok: false, message: 'Value must be a whole number (e.g., 42)' }\n }\n\n if (schema.minimum !== undefined && numberValue < schema.minimum) {\n return { ok: false, message: `Value must be ${schema.minimum} or greater` }\n }\n if (schema.maximum !== undefined && numberValue > schema.maximum) {\n return { ok: false, message: `Value must be ${schema.maximum} or less` }\n }\n }\n\n // string validations\n if (schema.type === 'string' && schema.format) {\n if (schema.format === 'date' && !/^\\d{4}-\\d{2}-\\d{2}$/.test(value ?? '')) {\n return { ok: false, message: 'Please enter a valid date in YYYY-MM-DD format (e.g., 2024-03-20)' }\n }\n if (\n schema.format === 'date-time' &&\n !/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(Z|[+-]\\d{2}:\\d{2})$/.test(value ?? '')\n ) {\n return {\n ok: false,\n message: 'Please enter a valid date and time in RFC 3339 format (e.g., 2024-03-20T13:45:30Z)',\n }\n }\n if (schema.format === 'email' && !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value ?? '')) {\n return { ok: false, message: 'Please enter a valid email address (e.g., user@example.com)' }\n }\n if (schema.format === 'uri' && !/^[a-zA-Z][a-zA-Z0-9+.-]*:.+$/.test(value ?? '')) {\n return { ok: false, message: 'Please enter a valid URI (e.g., https://example.com)' }\n }\n }\n\n return { ok: true }\n}\n"],"mappings":";;;;AAKA,IAAa,qBACX,QACA,UACkD;
|
|
1
|
+
{"version":3,"file":"validate-parameter.js","names":[],"sources":["../../../../../src/v2/blocks/request-block/helpers/validate-parameter.ts"],"sourcesContent":["import type { SchemaObject } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\n\n/**\n * Checks if the value of a example parameter is the expected type or format\n */\nexport const validateParameter = (\n schema?: SchemaObject,\n value?: string | File | null,\n): { ok: true } | { ok: false; message: string } => {\n if (!schema || !('type' in schema) || typeof value !== 'string') {\n return { ok: true }\n }\n\n // Numbers and integers validation\n if (schema.type === 'integer' || schema.type === 'number') {\n const numberValue = Number(value)\n\n if (isNaN(numberValue)) {\n return { ok: false, message: 'Value must be a number (e.g., 42.5)' }\n }\n\n if (schema.type === 'integer' && !Number.isInteger(numberValue)) {\n return { ok: false, message: 'Value must be a whole number (e.g., 42)' }\n }\n\n if (schema.minimum !== undefined && numberValue < schema.minimum) {\n return { ok: false, message: `Value must be ${schema.minimum} or greater` }\n }\n if (schema.maximum !== undefined && numberValue > schema.maximum) {\n return { ok: false, message: `Value must be ${schema.maximum} or less` }\n }\n }\n\n // string validations\n if (schema.type === 'string' && schema.format) {\n if (schema.format === 'date' && !/^\\d{4}-\\d{2}-\\d{2}$/.test(value ?? '')) {\n return { ok: false, message: 'Please enter a valid date in YYYY-MM-DD format (e.g., 2024-03-20)' }\n }\n if (\n schema.format === 'date-time' &&\n !/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(Z|[+-]\\d{2}:\\d{2})$/.test(value ?? '')\n ) {\n return {\n ok: false,\n message: 'Please enter a valid date and time in RFC 3339 format (e.g., 2024-03-20T13:45:30Z)',\n }\n }\n if (schema.format === 'email' && !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value ?? '')) {\n return { ok: false, message: 'Please enter a valid email address (e.g., user@example.com)' }\n }\n if (schema.format === 'uri' && !/^[a-zA-Z][a-zA-Z0-9+.-]*:.+$/.test(value ?? '')) {\n return { ok: false, message: 'Please enter a valid URI (e.g., https://example.com)' }\n }\n }\n\n return { ok: true }\n}\n"],"mappings":";;;;AAKA,IAAa,qBACX,QACA,UACkD;CAClD,IAAI,CAAC,UAAU,EAAE,UAAU,WAAW,OAAO,UAAU,UACrD,OAAO,EAAE,IAAI,KAAK;CAIpB,IAAI,OAAO,SAAS,aAAa,OAAO,SAAS,UAAU;EACzD,MAAM,cAAc,OAAO,KAAK;EAEhC,IAAI,MAAM,WAAW,GACnB,OAAO;GAAE,IAAI;GAAO,SAAS;EAAsC;EAGrE,IAAI,OAAO,SAAS,aAAa,CAAC,OAAO,UAAU,WAAW,GAC5D,OAAO;GAAE,IAAI;GAAO,SAAS;EAA0C;EAGzE,IAAI,OAAO,YAAY,KAAA,KAAa,cAAc,OAAO,SACvD,OAAO;GAAE,IAAI;GAAO,SAAS,iBAAiB,OAAO,QAAQ;EAAa;EAE5E,IAAI,OAAO,YAAY,KAAA,KAAa,cAAc,OAAO,SACvD,OAAO;GAAE,IAAI;GAAO,SAAS,iBAAiB,OAAO,QAAQ;EAAU;CAE3E;CAGA,IAAI,OAAO,SAAS,YAAY,OAAO,QAAQ;EAC7C,IAAI,OAAO,WAAW,UAAU,CAAC,sBAAsB,KAAK,SAAS,EAAE,GACrE,OAAO;GAAE,IAAI;GAAO,SAAS;EAAoE;EAEnG,IACE,OAAO,WAAW,eAClB,CAAC,mEAAmE,KAAK,SAAS,EAAE,GAEpF,OAAO;GACL,IAAI;GACJ,SAAS;EACX;EAEF,IAAI,OAAO,WAAW,WAAW,CAAC,6BAA6B,KAAK,SAAS,EAAE,GAC7E,OAAO;GAAE,IAAI;GAAO,SAAS;EAA8D;EAE7F,IAAI,OAAO,WAAW,SAAS,CAAC,+BAA+B,KAAK,SAAS,EAAE,GAC7E,OAAO;GAAE,IAAI;GAAO,SAAS;EAAuD;CAExF;CAEA,OAAO,EAAE,IAAI,KAAK;AACpB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ResponseBlock.vue.d.ts","sourceRoot":"","sources":["../../../../src/v2/blocks/response-block/ResponseBlock.vue"],"names":[],"mappings":"AA8RA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAC7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AACvE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAA;AAK7E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kDAAkD,CAAA;AAWxF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAErD,KAAK,WAAW,GAAG;IACf,4BAA4B;IAC5B,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAAA;IACjC,qDAAqD;IACrD,cAAc,EAAE,cAAc,GAAG,IAAI,CAAA;IACrC,oBAAoB;IACpB,MAAM,EAAE,YAAY,CAAA;IACpB,yCAAyC;IACzC,sBAAsB,EAAE,MAAM,CAAA;IAC9B,0BAA0B;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB,6BAA6B;IAC7B,OAAO,EAAE,YAAY,EAAE,CAAA;IACvB,0BAA0B;IAC1B,QAAQ,EAAE,iBAAiB,CAAA;CAC5B,CAAC;AAyBJ,QAAA,MAAM,gBAAgB,yCAA0C,CAAA;AAChE,KAAK,MAAM,GAAG,KAAK,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"ResponseBlock.vue.d.ts","sourceRoot":"","sources":["../../../../src/v2/blocks/response-block/ResponseBlock.vue"],"names":[],"mappings":"AA8RA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAC7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AACvE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAA;AAK7E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kDAAkD,CAAA;AAWxF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAErD,KAAK,WAAW,GAAG;IACf,4BAA4B;IAC5B,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAAA;IACjC,qDAAqD;IACrD,cAAc,EAAE,cAAc,GAAG,IAAI,CAAA;IACrC,oBAAoB;IACpB,MAAM,EAAE,YAAY,CAAA;IACpB,yCAAyC;IACzC,sBAAsB,EAAE,MAAM,CAAA;IAC9B,0BAA0B;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB,6BAA6B;IAC7B,OAAO,EAAE,YAAY,EAAE,CAAA;IACvB,0BAA0B;IAC1B,QAAQ,EAAE,iBAAiB,CAAA;CAC5B,CAAC;AAyBJ,QAAA,MAAM,gBAAgB,yCAA0C,CAAA;AAChE,KAAK,MAAM,GAAG,KAAK,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAA;AA4ZvD,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;oPAGhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -2,7 +2,7 @@ import _plugin_vue_export_helper_default from "../../../_virtual/_plugin-vue_exp
|
|
|
2
2
|
import ResponseBlock_vue_vue_type_script_setup_true_lang_default from "./ResponseBlock.vue.script.js";
|
|
3
3
|
/* empty css */
|
|
4
4
|
//#region src/v2/blocks/response-block/ResponseBlock.vue
|
|
5
|
-
var ResponseBlock_default =
|
|
5
|
+
var ResponseBlock_default = /*#__PURE__*/ _plugin_vue_export_helper_default(ResponseBlock_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-7a7c6611"]]);
|
|
6
6
|
//#endregion
|
|
7
7
|
export { ResponseBlock_default as default };
|
|
8
8
|
|
|
@@ -17,7 +17,7 @@ import { ScalarErrorBoundary } from "@scalar/components/error-boundary";
|
|
|
17
17
|
var _hoisted_1 = { class: "flex h-8 flex-1 items-center" };
|
|
18
18
|
var _hoisted_2 = ["id", "role"];
|
|
19
19
|
var VIRTUALIZATION_THRESHOLD = 2e5;
|
|
20
|
-
var ResponseBlock_vue_vue_type_script_setup_true_lang_default =
|
|
20
|
+
var ResponseBlock_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
21
21
|
__name: "ResponseBlock",
|
|
22
22
|
props: {
|
|
23
23
|
response: {},
|
|
@@ -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/error-boundary'\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
|
+
{"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/error-boundary'\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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"}
|
|
@@ -15,7 +15,7 @@ var _hoisted_2 = {
|
|
|
15
15
|
key: 1,
|
|
16
16
|
class: "text-c-3 bg-b-1 flex min-h-[64px] items-center justify-center border-t px-4 text-sm"
|
|
17
17
|
};
|
|
18
|
-
var Headers_vue_vue_type_script_setup_true_lang_default =
|
|
18
|
+
var Headers_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
19
19
|
__name: "Headers",
|
|
20
20
|
props: { headers: {} },
|
|
21
21
|
setup(__props) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Headers.vue.script.js","names":[],"sources":["../../../../../src/v2/blocks/response-block/components/Headers.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { httpHeaders, type HttpHeader } from '@scalar/helpers/http/http-headers'\nimport {\n DataTable,\n DataTableHeader,\n DataTableRow,\n DataTableText,\n} from '@v2/components/data-table'\n\nimport HelpfulLink from '@/components/HelpfulLink.vue'\nimport { CollapsibleSection } from '@/v2/components/layout'\n\ntype Header = { name: string; value: string }\n\ndefineProps<{\n headers: Header[]\n}>()\n\nconst findHeaderInfo = (name: string): HttpHeader | undefined =>\n httpHeaders[name.toLowerCase() as keyof typeof httpHeaders]\n</script>\n<template>\n <CollapsibleSection\n class=\"overflow-auto\"\n :defaultOpen=\"false\"\n :itemCount=\"headers.length\">\n <template #title><slot name=\"title\" /></template>\n <div\n v-if=\"headers.length\"\n class=\"max-h-[calc(100%-32px)] overflow-y-auto\">\n <DataTable\n :columns=\"['minmax(auto, min-content)', 'minmax(50%, 1fr)']\"\n scroll>\n <DataTableRow class=\"sr-only !block\">\n <DataTableHeader>Header Key</DataTableHeader>\n <DataTableHeader>Header Value</DataTableHeader>\n </DataTableRow>\n <DataTableRow\n v-for=\"item in headers\"\n :key=\"item.name\"\n class=\"group/row text-c-1\">\n <DataTableText\n class=\"bg-b-1 sticky left-0 z-1 max-w-full group-first/row:border-t-0\">\n <template v-if=\"typeof findHeaderInfo(item.name)?.url === 'string'\">\n <HelpfulLink\n class=\"decoration-c-3\"\n :href=\"findHeaderInfo(item.name)!.url\">\n {{ item.name }}\n </HelpfulLink>\n </template>\n <template v-else>\n {{ item.name }}\n </template>\n </DataTableText>\n <DataTableText\n class=\"z-0 group-first/row:border-t-0\"\n :text=\"item.value\" />\n </DataTableRow>\n </DataTable>\n </div>\n <!-- Empty state -->\n <div\n v-else\n class=\"text-c-3 bg-b-1 flex min-h-[64px] items-center justify-center border-t px-4 text-sm\">\n No headers\n </div>\n </CollapsibleSection>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;EAkBA,MAAM,kBAAkB,SACtB,YAAY,KAAK,
|
|
1
|
+
{"version":3,"file":"Headers.vue.script.js","names":[],"sources":["../../../../../src/v2/blocks/response-block/components/Headers.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { httpHeaders, type HttpHeader } from '@scalar/helpers/http/http-headers'\nimport {\n DataTable,\n DataTableHeader,\n DataTableRow,\n DataTableText,\n} from '@v2/components/data-table'\n\nimport HelpfulLink from '@/components/HelpfulLink.vue'\nimport { CollapsibleSection } from '@/v2/components/layout'\n\ntype Header = { name: string; value: string }\n\ndefineProps<{\n headers: Header[]\n}>()\n\nconst findHeaderInfo = (name: string): HttpHeader | undefined =>\n httpHeaders[name.toLowerCase() as keyof typeof httpHeaders]\n</script>\n<template>\n <CollapsibleSection\n class=\"overflow-auto\"\n :defaultOpen=\"false\"\n :itemCount=\"headers.length\">\n <template #title><slot name=\"title\" /></template>\n <div\n v-if=\"headers.length\"\n class=\"max-h-[calc(100%-32px)] overflow-y-auto\">\n <DataTable\n :columns=\"['minmax(auto, min-content)', 'minmax(50%, 1fr)']\"\n scroll>\n <DataTableRow class=\"sr-only !block\">\n <DataTableHeader>Header Key</DataTableHeader>\n <DataTableHeader>Header Value</DataTableHeader>\n </DataTableRow>\n <DataTableRow\n v-for=\"item in headers\"\n :key=\"item.name\"\n class=\"group/row text-c-1\">\n <DataTableText\n class=\"bg-b-1 sticky left-0 z-1 max-w-full group-first/row:border-t-0\">\n <template v-if=\"typeof findHeaderInfo(item.name)?.url === 'string'\">\n <HelpfulLink\n class=\"decoration-c-3\"\n :href=\"findHeaderInfo(item.name)!.url\">\n {{ item.name }}\n </HelpfulLink>\n </template>\n <template v-else>\n {{ item.name }}\n </template>\n </DataTableText>\n <DataTableText\n class=\"z-0 group-first/row:border-t-0\"\n :text=\"item.value\" />\n </DataTableRow>\n </DataTable>\n </div>\n <!-- Empty state -->\n <div\n v-else\n class=\"text-c-3 bg-b-1 flex min-h-[64px] items-center justify-center border-t px-4 text-sm\">\n No headers\n </div>\n </CollapsibleSection>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;EAkBA,MAAM,kBAAkB,SACtB,YAAY,KAAK,YAAY;;uBAG7B,YA4CqB,MAAA,0BAAA,GAAA;IA3CnB,OAAM;IACL,aAAa;IACb,WAAW,QAAA,QAAQ;;IACT,OAAK,cAAsB,CAArB,WAAqB,KAAA,QAAA,OAAA,CAAA,CAAA;2BAiChC,CA/BE,QAAA,QAAQ,UAAA,UAAA,GADhB,mBAgCM,OAhCN,YAgCM,CA7BJ,YA4BY,MAAA,iBAAA,GAAA;KA3BT,SAAS,CAAA,6BAAA,kBAAA;KACV,QAAA;;4BAIe,CAHf,YAGe,MAAA,oBAAA,GAAA,EAHD,OAAM,iBAAgB,GAAA;6BACW,CAA7C,YAA6C,MAAA,uBAAA,GAAA,MAAA;8BAAlB,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CAAA,gBAAV,cAAU,EAAA,CAAA,EAAA,CAAA;;UAC3B,YAA+C,MAAA,uBAAA,GAAA,MAAA;8BAAlB,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CAAA,gBAAZ,gBAAY,EAAA,CAAA,EAAA,CAAA;;;;2BAE/B,mBAoBe,UAAA,MAAA,WAnBE,QAAA,UAAR,SAAI;0BADb,YAoBe,MAAA,oBAAA,GAAA;OAlBZ,KAAK,KAAK;OACX,OAAM;;8BAaU,CAZhB,YAYgB,MAAA,qBAAA,GAAA,EAXd,OAAM,iEAAgE,GAAA;+BAO3D,CAAA,OANY,eAAe,KAAK,IAAI,CAAA,EAAG,QAAG,YAAA,UAAA,GACnD,YAIc,qBAAA;;SAHZ,OAAM;SACL,MAAM,eAAe,KAAK,IAAI,CAAA,CAAG;;gCACnB,CAAA,gBAAA,gBAAZ,KAAK,IAAI,GAAA,CAAA,CAAA,CAAA;;4CAGhB,mBAEW,UAAA,EAAA,KAAA,EAAA,GAAA,CAAA,gBAAA,gBADN,KAAK,IAAI,GAAA,CAAA,CAAA,GAAA,EAAA,EAAA,CAAA;;iBAGhB,YAEuB,MAAA,qBAAA,GAAA;QADrB,OAAM;QACL,MAAM,KAAK;;;;;;0BAKpB,mBAIM,OAJN,YAE8F,cAE9F,EAAA,CAAA"}
|
|
@@ -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 =
|
|
5
|
+
var ResponseBody_default = /*#__PURE__*/ _plugin_vue_export_helper_default(ResponseBody_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-bb31ac6f"]]);
|
|
6
6
|
//#endregion
|
|
7
7
|
export { ResponseBody_default as default };
|
|
8
8
|
|