@scalar/blocks 0.2.0 → 0.3.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 +26 -0
- package/dist/code-example/components/CodeExample.vue.d.ts +3 -2
- package/dist/code-example/components/CodeExample.vue.d.ts.map +1 -1
- package/dist/code-example/components/CodeExample.vue.js +1 -1
- package/dist/code-example/components/CodeExample.vue.js.map +1 -1
- package/dist/code-example/components/CodeExample.vue.script.js +87 -82
- package/dist/code-example/components/CodeExample.vue.script.js.map +1 -1
- package/dist/code-example/components/HttpMethod.vue.d.ts +1 -2
- package/dist/code-example/components/HttpMethod.vue.d.ts.map +1 -1
- package/dist/code-example/components/HttpMethod.vue.js.map +1 -1
- package/dist/code-example/components/HttpMethod.vue.script.js +15 -11
- package/dist/code-example/components/HttpMethod.vue.script.js.map +1 -1
- package/dist/code-example/helpers/generate-client-options.d.ts +1 -0
- package/dist/code-example/helpers/generate-client-options.d.ts.map +1 -1
- package/dist/code-example/helpers/generate-client-options.js +7 -3
- package/dist/code-example/helpers/generate-client-options.js.map +1 -1
- package/dist/code-example/helpers/generate-code-snippet.d.ts +3 -4
- package/dist/code-example/helpers/generate-code-snippet.d.ts.map +1 -1
- package/dist/code-example/helpers/generate-code-snippet.js +24 -18
- package/dist/code-example/helpers/generate-code-snippet.js.map +1 -1
- package/dist/code-example/helpers/get-clients.d.ts.map +1 -1
- package/dist/code-example/helpers/get-clients.js +4 -2
- package/dist/code-example/helpers/get-clients.js.map +1 -1
- package/dist/code-example/helpers/operation-to-har/operation-to-har.d.ts +1 -2
- package/dist/code-example/helpers/operation-to-har/operation-to-har.d.ts.map +1 -1
- package/dist/code-example/helpers/operation-to-har/operation-to-har.js +22 -14
- package/dist/code-example/helpers/operation-to-har/operation-to-har.js.map +1 -1
- package/dist/code-example/helpers/operation-to-har/process-parameters.d.ts +2 -0
- package/dist/code-example/helpers/operation-to-har/process-parameters.d.ts.map +1 -1
- package/dist/code-example/helpers/operation-to-har/process-parameters.js +163 -95
- package/dist/code-example/helpers/operation-to-har/process-parameters.js.map +1 -1
- package/dist/code-example/mount.d.ts +3 -2
- package/dist/code-example/mount.d.ts.map +1 -1
- package/dist/code-example/mount.js +32 -28
- package/dist/code-example/mount.js.map +1 -1
- package/dist/constants.js +1 -1
- package/dist/style.css +1 -1
- package/dist/vue-styles.css +1 -1
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# @scalar/blocks
|
|
2
2
|
|
|
3
|
+
## 0.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#10310](https://github.com/scalar/scalar/pull/10310): Connect SDK code samples to named request body examples using optional example and contentType fields. Keep the example switcher available for static samples and use the selected request example in API client snippets. Display unavailable linked samples as a localized status message in all supported languages.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- [#10322](https://github.com/scalar/scalar/pull/10322): Use OpenAPI 3.2 dataValue and serializedValue examples for named parameters in the editor, outgoing requests, and code samples. Preserve already serialized values without encoding them twice.
|
|
12
|
+
|
|
13
|
+
Optional parameters with `dataValue` or `serializedValue` examples are now enabled by default, matching legacy `value` examples. Explicitly disabled examples remain disabled.
|
|
14
|
+
|
|
15
|
+
Parameter-level `serializedValue` examples remain editable as raw wire text, including parameter names and percent encoding (for example, `term=hello` rather than `hello`). Media-level cookie examples are percent-encoded when sent, matching generated snippets. Generating snippets no longer modifies the input cookies.
|
|
16
|
+
|
|
17
|
+
- [#10189](https://github.com/scalar/scalar/pull/10189): Support OpenAPI 3.2 `in: querystring` parameters, including content-based serialization, editing the entire query string, schema rendering, and generated request URLs.
|
|
18
|
+
|
|
19
|
+
Non-form whole-query content, including JSON delimiters, is percent-encoded in request URLs and code samples. Use an example with `serializedValue` on the parameter itself for URI-ready query content that must retain its existing encoding.
|
|
20
|
+
|
|
21
|
+
Preserve the encoding of named query values when they coexist with whole-query content in generated code samples, while encoding query authentication values once.
|
|
22
|
+
|
|
23
|
+
Explain why the whole-query editor disables adding named parameters. Existing named parameters follow the whole-query value, preserving duplicate keys for the server to interpret.
|
|
24
|
+
|
|
25
|
+
- [#10186](https://github.com/scalar/scalar/pull/10186): Support OpenAPI 3.2 additionalOperations in operation storage, navigation, documentation, callbacks, and the API client. Preserve custom HTTP method spelling when displaying and sending requests and generating code samples.
|
|
26
|
+
|
|
27
|
+
Traversed operation and webhook methods now use the exported `OperationMethod` type, which accepts custom strings while retaining known-method editor completion. Consumers must handle unknown methods; this open type cannot provide exhaustive checking over the fixed HTTP method set. Unknown method presentation uses `colorClass` and `colorVar`, matching known methods. Preserve uppercase and mixed-case additional operation names consistently.
|
|
28
|
+
|
|
3
29
|
## 0.2.0
|
|
4
30
|
|
|
5
31
|
### Minor Changes
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import type { HttpMethod as HttpMethodType } from '@scalar/helpers/http/http-methods';
|
|
2
1
|
import { type WorkspaceEventBus } from '@scalar/workspace-store/events';
|
|
3
2
|
import type { SecuritySchemeObjectSecret } from '@scalar/workspace-store/request-example';
|
|
4
3
|
import type { XScalarCookie } from '@scalar/workspace-store/schemas/extensions/general/x-scalar-cookies';
|
|
5
4
|
import type { OperationObject, ServerObject } from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document';
|
|
6
5
|
import type { ClientOptionGroup } from '../types';
|
|
7
6
|
export type CodeExampleProps = {
|
|
7
|
+
/** Localized status text shown when the selected example has no linked code sample. */
|
|
8
|
+
codeSampleUnavailable?: string;
|
|
8
9
|
/**
|
|
9
10
|
* Integration type: determines if the code sample is displayed in a client environment
|
|
10
11
|
* or in an API reference environment.
|
|
@@ -79,7 +80,7 @@ export type CodeExampleProps = {
|
|
|
79
80
|
/**
|
|
80
81
|
* HTTP method of the operation
|
|
81
82
|
*/
|
|
82
|
-
method:
|
|
83
|
+
method: string;
|
|
83
84
|
/**
|
|
84
85
|
* Path of the operation
|
|
85
86
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeExample.vue.d.ts","sourceRoot":"","sources":["../../../src/code-example/components/CodeExample.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CodeExample.vue.d.ts","sourceRoot":"","sources":["../../../src/code-example/components/CodeExample.vue"],"names":[],"mappings":"AA2nBA,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAUvE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,yCAAyC,CAAA;AACzF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qEAAqE,CAAA;AACxG,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EACb,MAAM,8DAA8D,CAAA;AAkBrE,OAAO,KAAK,EAEV,iBAAiB,EAElB,MAAM,UAAU,CAAA;AAKjB,MAAM,MAAM,gBAAgB,GAAG;IAC7B,uFAAuF;IACvF,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B;;;OAGG;IACH,WAAW,CAAC,EAAE,QAAQ,GAAG,WAAW,CAAA;IACpC;;OAEG;IACH,aAAa,EAAE,iBAAiB,EAAE,CAAA;IAClC;;;;;;;;OAQG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;;OAEG;IACH,cAAc,CAAC,EAAE,YAAY,GAAG,IAAI,CAAA;IACpC;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA+BG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB;;OAEG;IACH,QAAQ,EAAE,iBAAiB,CAAA;IAC3B;;OAEG;IACH,eAAe,EAAE,0BAA0B,EAAE,CAAA;IAC7C;;OAEG;IACH,MAAM,EAAE,MAAM,CAAA;IACd;;OAEG;IACH,IAAI,EAAE,MAAM,CAAA;IACZ;;OAEG;IACH,SAAS,EAAE,eAAe,CAAA;IAC1B;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,MAAM,CAAA;IAC5B;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;OAEG;IACH,aAAa,CAAC,EAAE,aAAa,EAAE,CAAA;IAC/B;;;OAGG;IACH,+BAA+B,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACzD,CAAA;AAED;;;;;;;;GAQG;wBACkB,OAAO,YAAY;AAAxC,wBAAyC;AAGzC,QAAA,MAAM,YAAY;;;;;YAmCR,MAAM,OAAO;YACb,CAAC,EAAE,WAAW,EAAE,EAAE;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO;EA+qB3D,CAAC;AACL,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
|
|
@@ -2,7 +2,7 @@ import e from "./CodeExample.vue.script.js";
|
|
|
2
2
|
/* empty css */
|
|
3
3
|
import t from "../../_virtual/_plugin-vue_export-helper.js";
|
|
4
4
|
//#region src/code-example/components/CodeExample.vue
|
|
5
|
-
var n = /*#__PURE__*/ t(e, [["__scopeId", "data-v-
|
|
5
|
+
var n = /*#__PURE__*/ t(e, [["__scopeId", "data-v-0f51a301"]]);
|
|
6
6
|
//#endregion
|
|
7
7
|
export { n as default };
|
|
8
8
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeExample.vue.js","names":[],"sources":["../../../src/code-example/components/CodeExample.vue"],"sourcesContent":["<script lang=\"ts\">\nexport type CodeExampleProps = {\n /**\n * Integration type: determines if the code sample is displayed in a client environment\n * or in an API reference environment.\n */\n integration?: 'client' | 'reference'\n /**\n * List of all http clients formatted into option groups for the client selector\n */\n clientOptions: ClientOptionGroup[]\n /**\n * Pre-selected client, this will determine which client is initially selected in the dropdown.\n * Either a built-in client id (e.g. `js/fetch`) or a custom sample id (e.g. `custom/python`).\n *\n * Typed as a plain string: unioning the (large) client-id union with the `custom/...`\n * ids overflows TypeScript's union-complexity limit inside this component's `defineProps`.\n *\n * @defaults to a custom sample if one is available, otherwise shell/curl\n */\n selectedClient?: string\n /**\n * Which server from the spec to use for the code example\n */\n selectedServer?: ServerObject | null\n /**\n * The selected content type from the requestBody.content, this will determine which examples are available\n * as well as the content type of the code example\n *\n * @defaults to the first content type if not provided\n */\n selectedContentType?: string\n /**\n * Example name to use for resolving example values for parameters AND requestBody.\n *\n * This is the document-wide selection: it is honored only when this operation defines an example\n * with the same key, so picking an example on one operation syncs the rest without blanking out\n * operations that do not share that key.\n *\n * @example \"limited\"\n * ```ts\n * parameters: {\n * name: 'foobar',\n * in: 'query',\n * examples: {\n * limited: {\n * dataValue: 10,\n * }\n * }\n * },\n * body: {\n * content: {\n * 'application/json': {\n * examples: {\n * limited: {\n * dataValue: { foo: 'bar' },\n * }\n * }\n * }\n * }\n * }\n *\n * ```\n */\n selectedExample?: string\n /**\n * Event bus\n */\n eventBus: WorkspaceEventBus\n /**\n * The security schemes which are applicable to this operation\n */\n securitySchemes: SecuritySchemeObjectSecret[]\n /**\n * HTTP method of the operation\n */\n method: HttpMethodType\n /**\n * Path of the operation\n */\n path: string\n /**\n * De-referenced OpenAPI Operation object\n */\n operation: OperationObject\n /**\n * If true and there's no example, we will display a small card with the method and path only\n */\n fallback?: boolean\n /**\n * A method to generate the label of the block, should return an html string\n */\n generateLabel?: () => string\n /**\n * If true, render this as a webhook request example\n */\n isWebhook?: boolean\n /**\n * Workspace + document cookies\n */\n globalCookies?: XScalarCookie[]\n /**\n * When the request body schema uses oneOf/anyOf, use these selected variants\n * for the example snippet (e.g. from the schema dropdowns in the API reference).\n */\n requestBodyCompositionSelection?: Record<string, number>\n}\n\n/**\n * Request Example\n *\n * The core component for rendering a request example block,\n * this component does not have much of its own state but operates on props and custom events\n *\n * @event workspace:update:selected-client - Emitted when the selected client changes\n * @event workspace:update:selected-example - Emitted when the selected example changes, so other operations can sync\n */\nexport default {}\n</script>\n\n<script setup lang=\"ts\">\nimport { ScalarButton } from '@scalar/components/button'\nimport {\n ScalarCard,\n ScalarCardFooter,\n ScalarCardHeader,\n ScalarCardSection,\n} from '@scalar/components/card'\nimport { ScalarCodeBlock } from '@scalar/components/code-block'\nimport { ScalarCombobox } from '@scalar/components/combobox'\nimport { ScalarVirtualText } from '@scalar/components/virtual-text'\nimport { freezeElement } from '@scalar/helpers/dom/freeze-element'\nimport type { HttpMethod as HttpMethodType } from '@scalar/helpers/http/http-methods'\nimport { ScalarIconCaretDown } from '@scalar/icons'\nimport { type WorkspaceEventBus } from '@scalar/workspace-store/events'\nimport { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport {\n getOperationExamples,\n resolveOperationExamples,\n} from '@scalar/workspace-store/helpers/operation-examples'\nimport {\n useExampleVisibility,\n useExternalExamples,\n} from '@scalar/workspace-store/helpers/use-external-examples'\nimport type { SecuritySchemeObjectSecret } from '@scalar/workspace-store/request-example'\nimport type { XScalarCookie } from '@scalar/workspace-store/schemas/extensions/general/x-scalar-cookies'\nimport type {\n OperationObject,\n ServerObject,\n} from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document'\nimport {\n computed,\n onBeforeMount,\n ref,\n useId,\n watch,\n watchEffect,\n type ComponentPublicInstance,\n} from 'vue'\n\nimport { filterClientsByQuery } from '../helpers/filter-clients-by-query'\nimport { findClient } from '../helpers/find-client'\nimport { generateCodeSnippet } from '../helpers/generate-code-snippet'\nimport { getClients } from '../helpers/get-clients'\nimport { getCustomCodeSamples } from '../helpers/get-custom-code-samples'\nimport { getSecrets } from '../helpers/get-secrets'\nimport { operationToHar } from '../helpers/operation-to-har/operation-to-har'\nimport type {\n ClientOption,\n ClientOptionGroup,\n CustomClientOption,\n} from '../types'\nimport ExamplePicker from './ExamplePicker.vue'\nimport HttpMethod from './HttpMethod.vue'\n\nconst {\n integration,\n clientOptions,\n selectedClient,\n selectedServer = null,\n selectedContentType,\n selectedExample,\n securitySchemes = [],\n method,\n eventBus,\n path,\n operation,\n isWebhook,\n generateLabel,\n globalCookies,\n requestBodyCompositionSelection,\n} = defineProps<CodeExampleProps>()\n\nconst emit = defineEmits<{\n /**\n * Emitted whenever the example key actually shown for this operation changes.\n *\n * This is the resolved local key (not the raw document-wide selection), so layouts that render\n * the test-request button outside this component can open the client with the same example the\n * snippet displays.\n */\n (e: 'update:exampleKey', value: string): void\n}>()\n\ndefineSlots<{\n header: () => unknown\n footer: ({ exampleName }: { exampleName: string }) => unknown\n}>()\n\n/** Grab the examples for the given content type */\nconst requestBodyExamples = computed(() => {\n const content = getResolvedRef(operation.requestBody)?.content ?? {}\n const contentType = selectedContentType || Object.keys(content)[0]\n if (!contentType) return {}\n\n const examples = content[contentType]?.examples ?? {}\n\n return examples\n})\n\n/**\n * The example key actually shown for this operation.\n *\n * `selectedExample` is the document-wide selection that syncs across operations. We honor it only\n * when this operation actually defines that key, otherwise we keep the local example: a selection\n * on one operation should never blank out an operation that does not share the same example.\n */\nconst localExampleKey = ref('')\n\n/** Resolve the key to display, preferring the document-wide selection when this operation has it */\nconst resolveExampleKey = (preferred: string | undefined): string => {\n const keys = Object.keys(requestBodyExamples.value)\n if (preferred && keys.includes(preferred)) {\n return preferred\n }\n // Keep the current local example when it is still valid, otherwise fall back to the first one\n if (localExampleKey.value && keys.includes(localExampleKey.value)) {\n return localExampleKey.value\n }\n return keys[0] ?? ''\n}\n\n// Set the initial example from the document-wide selection, falling back to the first example\nonBeforeMount(() => {\n localExampleKey.value = resolveExampleKey(selectedExample)\n})\n\n// Follow the document-wide selection when it changes and this operation has that example\nwatch(\n () => selectedExample,\n (preferred) => {\n localExampleKey.value = resolveExampleKey(preferred)\n },\n)\n\n/** Reset the selected example key if the content type changes and the new content type doesn't have the previously selected example */\nwatch(\n () => selectedContentType,\n () => {\n if (\n !Object.keys(requestBodyExamples.value).includes(localExampleKey.value)\n ) {\n // Re-resolve so the new content type still follows the document-wide selection when it has\n // that key, instead of always snapping back to the first example\n localExampleKey.value = resolveExampleKey(selectedExample)\n }\n },\n)\n\n// Keep the parent informed of the resolved key so a test-request button rendered outside this\n// component (e.g. the classic layout header) opens the client with the example the snippet shows\nwatchEffect(() => {\n emit('update:exampleKey', localExampleKey.value)\n})\n\n/** Select an example locally and sync the choice across the document */\nconst selectExample = (key: string) => {\n localExampleKey.value = key\n eventBus.emit('workspace:update:selected-example', key)\n}\n\n/** Grab any custom code samples from the operation */\nconst customCodeSamples = computed(() => getCustomCodeSamples(operation))\n\n/** Merge custom code samples with the client options */\nconst clients = computed(() =>\n getClients(\n customCodeSamples.value.samples,\n clientOptions,\n customCodeSamples.value.label,\n ),\n)\n\n/** Total number of available clients across all option groups */\nconst clientCount = computed(() =>\n clients.value.reduce((total, group) => total + group.options.length, 0),\n)\n\n/** The locally selected client which would include code samples from this operation only */\nconst localSelectedClient = ref<ClientOption | CustomClientOption | undefined>(\n findClient(clients.value, selectedClient),\n)\n\n/**\n * Re-resolve the local client whenever the global selection or the available\n * clients change. Watching `clients` matters when navigating between operations:\n * the stored id stays the same, but the matching option (e.g. a custom sample)\n * differs per operation, so without this the snippet could go stale.\n */\nwatch([() => selectedClient, clients], ([newClient]) => {\n const client = findClient(clients.value, newClient)\n if (client) {\n localSelectedClient.value = client\n }\n})\n\nconst elem = ref<ComponentPublicInstance | null>(null)\nconst visible = useExampleVisibility(elem)\nconst externalExamples = useExternalExamples(\n () =>\n getOperationExamples(operation, localExampleKey.value, selectedContentType),\n () => visible.value,\n)\nconst resolvedOperation = computed(() =>\n resolveOperationExamples(\n operation,\n localExampleKey.value,\n selectedContentType,\n externalExamples.resolve,\n ),\n)\n\n/** Generate HAR data for webhook requests */\nconst webhookHar = computed(() => {\n if (!isWebhook) return null\n\n try {\n return operationToHar({\n operation: resolvedOperation.value,\n method,\n path,\n example: localExampleKey.value,\n requestBodyCompositionSelection,\n // Only required parameters are shown in code examples; optional parameters\n // are omitted unless explicitly enabled via `x-disabled: false`.\n defaultDisabledParameters: true,\n })\n } catch (error) {\n console.error('[webhookHar]', error)\n return null\n }\n})\n\n/** Generate the code snippet for the selected example */\nconst generatedCode = computed<string>(() => {\n if (isWebhook) {\n return webhookHar.value?.postData?.text ?? ''\n }\n\n return generateCodeSnippet({\n // Only required parameters are shown in code examples; optional parameters\n // are omitted unless explicitly enabled via `x-disabled: false`.\n defaultDisabledParameters: true,\n includeDefaultHeaders: integration === 'client',\n clientId: localSelectedClient.value?.id,\n customCodeSamples: customCodeSamples.value.samples,\n operation: resolvedOperation.value,\n method,\n path,\n contentType: selectedContentType,\n server: selectedServer,\n securitySchemes,\n example: localExampleKey.value,\n globalCookies,\n requestBodyCompositionSelection,\n })\n})\n\n/** The language for the code block, used for syntax highlighting */\nconst codeBlockLanguage = computed(() => {\n if (isWebhook) {\n return webhookLanguage.value\n }\n\n return localSelectedClient.value?.lang\n})\n\n/** Determine the language for webhook content based on MIME type */\nconst webhookLanguage = computed<string>(() => {\n if (!webhookHar.value?.postData) return 'json'\n\n const contentType = webhookHar.value.postData.mimeType\n if (contentType?.includes('json')) return 'json'\n if (contentType?.includes('xml')) return 'xml'\n if (contentType?.includes('yaml') || contentType?.includes('yml'))\n return 'yaml'\n if (contentType?.includes('text/plain')) return 'text'\n\n return 'json'\n})\n\n/** Block secrets from being shown in the code block */\nconst secretCredentials = computed(() => getSecrets(securitySchemes))\n\n/** Set custom example, or update the selected HTTP client globally */\nconst selectClient = (option: ClientOption) => {\n // We need to freeze the ui to prevent scrolling as the clients change\n if (elem.value) {\n const unfreeze = freezeElement(elem.value.$el)\n setTimeout(() => {\n unfreeze()\n }, 300)\n }\n // Update to the local example\n localSelectedClient.value = option\n\n // Sync the selection globally so other operations follow along. Custom samples\n // sync too (keyed by language), so picking e.g. the Python SDK example here\n // shows the Python example on every operation that ships one.\n if (option) {\n eventBus.emit('workspace:update:selected-client', option.id)\n }\n}\n\n// Virtualize the code block if it's too large\n// This prevents the entire app from freezing up if there's a massive example\n// We set a lower threshold here as code examples can get quite large\nconst VIRTUALIZATION_THRESHOLD = 20_000\n\nconst shouldVirtualize = computed(\n () => (generatedCode.value.length ?? 0) > VIRTUALIZATION_THRESHOLD,\n)\n\nconst id = useId()\n</script>\n<template>\n <ScalarCard\n v-if=\"generatedCode || externalExamples.pending.value\"\n ref=\"elem\"\n class=\"request-card dark-mode\">\n <!-- Header -->\n <ScalarCardHeader class=\"pr-2.5\">\n <span class=\"sr-only\">Request Example for</span>\n <HttpMethod\n as=\"span\"\n class=\"request-method\"\n :method=\"method\" />\n <span\n v-if=\"generateLabel\"\n v-html=\"generateLabel()\" />\n <slot name=\"header\" />\n <!-- Client picker -->\n <template\n v-if=\"!isWebhook && clientCount\"\n #actions>\n <!-- Multiple clients: render a dropdown to switch between them -->\n <ScalarCombobox\n v-if=\"clientCount > 1\"\n class=\"max-h-80\"\n :filterFn=\"filterClientsByQuery\"\n :modelValue=\"localSelectedClient\"\n :options=\"clients\"\n placement=\"bottom-end\"\n teleport\n @update:modelValue=\"selectClient($event as ClientOption)\">\n <ScalarButton\n class=\"text-c-2 hover:text-c-1 flex h-full w-fit gap-1.5 px-0.5 py-0 text-base font-normal\"\n data-testid=\"client-picker\"\n variant=\"ghost\">\n {{ localSelectedClient?.title }}\n <ScalarIconCaretDown\n class=\"ui-open:rotate-180 mt-px size-3 transition-transform duration-100\"\n weight=\"bold\" />\n </ScalarButton>\n </ScalarCombobox>\n <!-- Single client: just show its label, no need for a dropdown -->\n <span\n v-else\n class=\"text-c-2 flex h-full w-fit items-center px-0.5 py-0 text-base font-normal\"\n data-testid=\"client-picker\">\n {{ localSelectedClient?.title }}\n </span>\n </template>\n </ScalarCardHeader>\n\n <!-- Code snippet -->\n <ScalarCardSection class=\"request-editor-section custom-scroll p-0\">\n <div\n v-if=\"externalExamples.pending.value\"\n class=\"text-c-2 p-4\"\n role=\"status\">\n <template v-if=\"externalExamples.failed.value\">\n Could not load this example.\n <ScalarButton\n size=\"sm\"\n variant=\"ghost\"\n @click=\"externalExamples.retry\">\n Retry\n </ScalarButton>\n </template>\n <template v-else>Loading example…</template>\n </div>\n <div\n v-else\n :id=\"`${id}-example`\"\n class=\"code-snippet\">\n <ScalarCodeBlock\n v-if=\"!shouldVirtualize\"\n class=\"bg-b-2 h-full\"\n :content=\"generatedCode\"\n :hideCredentials=\"secretCredentials\"\n :lang=\"codeBlockLanguage\"\n lineNumbers />\n <ScalarVirtualText\n v-else\n containerClass=\"custom-scroll scalar-code-block border rounded-b flex flex-1 max-h-screen\"\n contentClass=\"language-plaintext whitespace-pre font-code text-base p-2\"\n :lineHeight=\"20\"\n :text=\"generatedCode\" />\n </div>\n </ScalarCardSection>\n\n <!-- Footer -->\n <ScalarCardFooter\n v-if=\"Object.keys(requestBodyExamples).length > 1 || $slots.footer\"\n class=\"request-card-footer bg-b-3\">\n <!-- Example picker -->\n <div\n v-if=\"Object.keys(requestBodyExamples).length > 1\"\n class=\"request-card-footer-addon\">\n <template v-if=\"Object.keys(requestBodyExamples).length\">\n <ExamplePicker\n :examples=\"requestBodyExamples\"\n :modelValue=\"localExampleKey\"\n @update:modelValue=\"selectExample\" />\n </template>\n </div>\n\n <!-- Footer -->\n <slot\n :exampleName=\"localExampleKey\"\n name=\"footer\" />\n </ScalarCardFooter>\n </ScalarCard>\n\n <!-- Fallback card with just method and path in the case of no examples -->\n <ScalarCard\n v-else-if=\"fallback\"\n class=\"request-card dark-mode\">\n <ScalarCardSection class=\"request-card-simple\">\n <div class=\"request-header\">\n <HttpMethod\n as=\"span\"\n class=\"request-method\"\n :method=\"method\" />\n <slot name=\"header\" />\n </div>\n <slot\n :exampleName=\"localExampleKey\"\n name=\"footer\" />\n </ScalarCardSection>\n </ScalarCard>\n</template>\n<style scoped>\n.request-card {\n color: var(--scalar-color-1);\n font-size: var(--scalar-font-size-3);\n}\n.request-method {\n font-family: var(--scalar-font-code);\n text-transform: uppercase;\n margin-right: 6px;\n}\n.request-card-footer {\n display: flex;\n justify-content: flex-end;\n padding: 6px;\n flex-shrink: 0;\n position: relative;\n}\n.request-card-footer-addon {\n display: flex;\n align-items: center;\n\n flex: 1;\n min-width: 0;\n}\n.request-editor-section {\n display: flex;\n flex: 1;\n}\n.request-card-simple {\n display: flex;\n align-items: center;\n justify-content: space-between;\n\n padding: 8px 8px 8px 12px;\n\n font-size: var(--scalar-small);\n}\n.code-snippet {\n display: flex;\n flex-direction: column;\n width: 100%;\n}\n</style>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"CodeExample.vue.js","names":[],"sources":["../../../src/code-example/components/CodeExample.vue"],"sourcesContent":["<script lang=\"ts\">\nexport type CodeExampleProps = {\n /** Localized status text shown when the selected example has no linked code sample. */\n codeSampleUnavailable?: string\n /**\n * Integration type: determines if the code sample is displayed in a client environment\n * or in an API reference environment.\n */\n integration?: 'client' | 'reference'\n /**\n * List of all http clients formatted into option groups for the client selector\n */\n clientOptions: ClientOptionGroup[]\n /**\n * Pre-selected client, this will determine which client is initially selected in the dropdown.\n * Either a built-in client id (e.g. `js/fetch`) or a custom sample id (e.g. `custom/python`).\n *\n * Typed as a plain string: unioning the (large) client-id union with the `custom/...`\n * ids overflows TypeScript's union-complexity limit inside this component's `defineProps`.\n *\n * @defaults to a custom sample if one is available, otherwise shell/curl\n */\n selectedClient?: string\n /**\n * Which server from the spec to use for the code example\n */\n selectedServer?: ServerObject | null\n /**\n * The selected content type from the requestBody.content, this will determine which examples are available\n * as well as the content type of the code example\n *\n * @defaults to the first content type if not provided\n */\n selectedContentType?: string\n /**\n * Example name to use for resolving example values for parameters AND requestBody.\n *\n * This is the document-wide selection: it is honored only when this operation defines an example\n * with the same key, so picking an example on one operation syncs the rest without blanking out\n * operations that do not share that key.\n *\n * @example \"limited\"\n * ```ts\n * parameters: {\n * name: 'foobar',\n * in: 'query',\n * examples: {\n * limited: {\n * dataValue: 10,\n * }\n * }\n * },\n * body: {\n * content: {\n * 'application/json': {\n * examples: {\n * limited: {\n * dataValue: { foo: 'bar' },\n * }\n * }\n * }\n * }\n * }\n *\n * ```\n */\n selectedExample?: string\n /**\n * Event bus\n */\n eventBus: WorkspaceEventBus\n /**\n * The security schemes which are applicable to this operation\n */\n securitySchemes: SecuritySchemeObjectSecret[]\n /**\n * HTTP method of the operation\n */\n method: string\n /**\n * Path of the operation\n */\n path: string\n /**\n * De-referenced OpenAPI Operation object\n */\n operation: OperationObject\n /**\n * If true and there's no example, we will display a small card with the method and path only\n */\n fallback?: boolean\n /**\n * A method to generate the label of the block, should return an html string\n */\n generateLabel?: () => string\n /**\n * If true, render this as a webhook request example\n */\n isWebhook?: boolean\n /**\n * Workspace + document cookies\n */\n globalCookies?: XScalarCookie[]\n /**\n * When the request body schema uses oneOf/anyOf, use these selected variants\n * for the example snippet (e.g. from the schema dropdowns in the API reference).\n */\n requestBodyCompositionSelection?: Record<string, number>\n}\n\n/**\n * Request Example\n *\n * The core component for rendering a request example block,\n * this component does not have much of its own state but operates on props and custom events\n *\n * @event workspace:update:selected-client - Emitted when the selected client changes\n * @event workspace:update:selected-example - Emitted when the selected example changes, so other operations can sync\n */\nexport default {}\n</script>\n\n<script setup lang=\"ts\">\nimport { ScalarButton } from '@scalar/components/button'\nimport {\n ScalarCard,\n ScalarCardFooter,\n ScalarCardHeader,\n ScalarCardSection,\n} from '@scalar/components/card'\nimport { ScalarCodeBlock } from '@scalar/components/code-block'\nimport { ScalarCombobox } from '@scalar/components/combobox'\nimport { ScalarVirtualText } from '@scalar/components/virtual-text'\nimport { freezeElement } from '@scalar/helpers/dom/freeze-element'\nimport { ScalarIconCaretDown } from '@scalar/icons'\nimport { type WorkspaceEventBus } from '@scalar/workspace-store/events'\nimport { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport {\n getOperationExamples,\n resolveOperationExamples,\n} from '@scalar/workspace-store/helpers/operation-examples'\nimport {\n useExampleVisibility,\n useExternalExamples,\n} from '@scalar/workspace-store/helpers/use-external-examples'\nimport type { SecuritySchemeObjectSecret } from '@scalar/workspace-store/request-example'\nimport type { XScalarCookie } from '@scalar/workspace-store/schemas/extensions/general/x-scalar-cookies'\nimport type {\n OperationObject,\n ServerObject,\n} from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document'\nimport {\n computed,\n onBeforeMount,\n ref,\n useId,\n watch,\n watchEffect,\n type ComponentPublicInstance,\n} from 'vue'\n\nimport { filterClientsByQuery } from '../helpers/filter-clients-by-query'\nimport { findClient } from '../helpers/find-client'\nimport { generateCodeSnippet } from '../helpers/generate-code-snippet'\nimport { getClients } from '../helpers/get-clients'\nimport { getCustomCodeSamples } from '../helpers/get-custom-code-samples'\nimport { getSecrets } from '../helpers/get-secrets'\nimport { operationToHar } from '../helpers/operation-to-har/operation-to-har'\nimport type {\n ClientOption,\n ClientOptionGroup,\n CustomClientOption,\n} from '../types'\nimport ExamplePicker from './ExamplePicker.vue'\nimport HttpMethod from './HttpMethod.vue'\n\nconst {\n integration,\n codeSampleUnavailable = 'No code sample available for this example.',\n clientOptions,\n selectedClient,\n selectedServer = null,\n selectedContentType,\n selectedExample,\n securitySchemes = [],\n method,\n eventBus,\n path,\n operation,\n isWebhook,\n generateLabel,\n globalCookies,\n requestBodyCompositionSelection,\n} = defineProps<CodeExampleProps>()\n\nconst emit = defineEmits<{\n /**\n * Emitted whenever the example key actually shown for this operation changes.\n *\n * This is the resolved local key (not the raw document-wide selection), so layouts that render\n * the test-request button outside this component can open the client with the same example the\n * snippet displays.\n */\n (e: 'update:exampleKey', value: string): void\n}>()\n\ndefineSlots<{\n header: () => unknown\n footer: ({ exampleName }: { exampleName: string }) => unknown\n}>()\n\n/** Grab the examples for the given content type */\nconst requestBodyExamples = computed(() => {\n const content = getResolvedRef(operation.requestBody)?.content ?? {}\n const contentType = selectedContentType || Object.keys(content)[0]\n if (!contentType) return {}\n\n const examples = content[contentType]?.examples ?? {}\n\n return examples\n})\n\n/**\n * The example key actually shown for this operation.\n *\n * `selectedExample` is the document-wide selection that syncs across operations. We honor it only\n * when this operation actually defines that key, otherwise we keep the local example: a selection\n * on one operation should never blank out an operation that does not share the same example.\n */\nconst localExampleKey = ref('')\n\n/** Resolve the key to display, preferring the document-wide selection when this operation has it */\nconst resolveExampleKey = (preferred: string | undefined): string => {\n const keys = Object.keys(requestBodyExamples.value)\n if (preferred && keys.includes(preferred)) {\n return preferred\n }\n // Keep the current local example when it is still valid, otherwise fall back to the first one\n if (localExampleKey.value && keys.includes(localExampleKey.value)) {\n return localExampleKey.value\n }\n return keys[0] ?? ''\n}\n\n// Set the initial example from the document-wide selection, falling back to the first example\nonBeforeMount(() => {\n localExampleKey.value = resolveExampleKey(selectedExample)\n})\n\n// Follow the document-wide selection when it changes and this operation has that example\nwatch(\n () => selectedExample,\n (preferred) => {\n localExampleKey.value = resolveExampleKey(preferred)\n },\n)\n\n/** Reset the selected example key if the content type changes and the new content type doesn't have the previously selected example */\nwatch(\n () => selectedContentType,\n () => {\n if (\n !Object.keys(requestBodyExamples.value).includes(localExampleKey.value)\n ) {\n // Re-resolve so the new content type still follows the document-wide selection when it has\n // that key, instead of always snapping back to the first example\n localExampleKey.value = resolveExampleKey(selectedExample)\n }\n },\n)\n\n// Keep the parent informed of the resolved key so a test-request button rendered outside this\n// component (e.g. the classic layout header) opens the client with the example the snippet shows\nwatchEffect(() => {\n emit('update:exampleKey', localExampleKey.value)\n})\n\n/** Select an example locally and sync the choice across the document */\nconst selectExample = (key: string) => {\n localExampleKey.value = key\n eventBus.emit('workspace:update:selected-example', key)\n}\n\n/** Grab any custom code samples from the operation */\nconst customCodeSamples = computed(() => getCustomCodeSamples(operation))\n\n/** Merge custom code samples with the client options */\nconst clients = computed(() =>\n getClients(\n customCodeSamples.value.samples,\n clientOptions,\n customCodeSamples.value.label,\n ),\n)\n\n/** Total number of available clients across all option groups */\nconst clientCount = computed(() =>\n clients.value.reduce((total, group) => total + group.options.length, 0),\n)\n\n/** The locally selected client which would include code samples from this operation only */\nconst localSelectedClient = ref<ClientOption | CustomClientOption | undefined>(\n findClient(clients.value, selectedClient),\n)\n\n/**\n * Re-resolve the local client whenever the global selection or the available\n * clients change. Watching `clients` matters when navigating between operations:\n * the stored id stays the same, but the matching option (e.g. a custom sample)\n * differs per operation, so without this the snippet could go stale.\n */\nwatch([() => selectedClient, clients], ([newClient]) => {\n const client = findClient(clients.value, newClient)\n if (client) {\n localSelectedClient.value = client\n }\n})\n\nconst elem = ref<ComponentPublicInstance | null>(null)\nconst visible = useExampleVisibility(elem)\nconst externalExamples = useExternalExamples(\n () =>\n getOperationExamples(operation, localExampleKey.value, selectedContentType),\n () => visible.value,\n)\nconst resolvedOperation = computed(() =>\n resolveOperationExamples(\n operation,\n localExampleKey.value,\n selectedContentType,\n externalExamples.resolve,\n ),\n)\n\n/** Keep the picker available because it also selects the example opened by Test Request. */\nconst showExamplePicker = computed(\n () => Object.keys(requestBodyExamples.value).length > 1,\n)\n\n/** Generate HAR data for webhook requests */\nconst webhookHar = computed(() => {\n if (!isWebhook) return null\n\n try {\n return operationToHar({\n operation: resolvedOperation.value,\n method,\n path,\n example: localExampleKey.value,\n requestBodyCompositionSelection,\n // Only required parameters are shown in code examples; optional parameters\n // are omitted unless explicitly enabled via `x-disabled: false`.\n defaultDisabledParameters: true,\n })\n } catch (error) {\n console.error('[webhookHar]', error)\n return null\n }\n})\n\n/** Generate the code snippet for the selected example */\nconst generatedCode = computed<string | null>(() => {\n if (isWebhook) {\n return webhookHar.value?.postData?.text ?? ''\n }\n\n return generateCodeSnippet({\n // Only required parameters are shown in code examples; optional parameters\n // are omitted unless explicitly enabled via `x-disabled: false`.\n defaultDisabledParameters: true,\n includeDefaultHeaders: integration === 'client',\n clientId: localSelectedClient.value?.id,\n customCodeSamples: customCodeSamples.value.samples,\n operation: resolvedOperation.value,\n method,\n path,\n contentType: selectedContentType,\n server: selectedServer,\n securitySchemes,\n example: localExampleKey.value,\n globalCookies,\n requestBodyCompositionSelection,\n })\n})\n\n/** The language for the code block, used for syntax highlighting */\nconst codeBlockLanguage = computed(() => {\n if (isWebhook) {\n return webhookLanguage.value\n }\n\n return localSelectedClient.value?.lang\n})\n\n/** Determine the language for webhook content based on MIME type */\nconst webhookLanguage = computed<string>(() => {\n if (!webhookHar.value?.postData) return 'json'\n\n const contentType = webhookHar.value.postData.mimeType\n if (contentType?.includes('json')) return 'json'\n if (contentType?.includes('xml')) return 'xml'\n if (contentType?.includes('yaml') || contentType?.includes('yml'))\n return 'yaml'\n if (contentType?.includes('text/plain')) return 'text'\n\n return 'json'\n})\n\n/** Block secrets from being shown in the code block */\nconst secretCredentials = computed(() => getSecrets(securitySchemes))\n\n/** Set custom example, or update the selected HTTP client globally */\nconst selectClient = (option: ClientOption) => {\n // We need to freeze the ui to prevent scrolling as the clients change\n if (elem.value) {\n const unfreeze = freezeElement(elem.value.$el)\n setTimeout(() => {\n unfreeze()\n }, 300)\n }\n // Update to the local example\n localSelectedClient.value = option\n\n // Sync the selection globally so other operations follow along. Custom samples\n // sync too (keyed by language), so picking e.g. the Python SDK example here\n // shows the Python example on every operation that ships one.\n if (option) {\n eventBus.emit('workspace:update:selected-client', option.id)\n }\n}\n\n// Virtualize the code block if it's too large\n// This prevents the entire app from freezing up if there's a massive example\n// We set a lower threshold here as code examples can get quite large\nconst VIRTUALIZATION_THRESHOLD = 20_000\n\nconst shouldVirtualize = computed(\n () => (generatedCode.value?.length ?? 0) > VIRTUALIZATION_THRESHOLD,\n)\n\nconst id = useId()\n</script>\n<template>\n <ScalarCard\n v-if=\"\n generatedCode === null || generatedCode || externalExamples.pending.value\n \"\n ref=\"elem\"\n class=\"request-card dark-mode\">\n <!-- Header -->\n <ScalarCardHeader class=\"pr-2.5\">\n <span class=\"sr-only\">Request Example for</span>\n <HttpMethod\n as=\"span\"\n class=\"request-method\"\n :method=\"method\" />\n <span\n v-if=\"generateLabel\"\n v-html=\"generateLabel()\" />\n <slot name=\"header\" />\n <!-- Client picker -->\n <template\n v-if=\"!isWebhook && clientCount\"\n #actions>\n <!-- Multiple clients: render a dropdown to switch between them -->\n <ScalarCombobox\n v-if=\"clientCount > 1\"\n class=\"max-h-80\"\n :filterFn=\"filterClientsByQuery\"\n :modelValue=\"localSelectedClient\"\n :options=\"clients\"\n placement=\"bottom-end\"\n teleport\n @update:modelValue=\"selectClient($event as ClientOption)\">\n <ScalarButton\n class=\"text-c-2 hover:text-c-1 flex h-full w-fit gap-1.5 px-0.5 py-0 text-base font-normal\"\n data-testid=\"client-picker\"\n variant=\"ghost\">\n {{ localSelectedClient?.title }}\n <ScalarIconCaretDown\n class=\"ui-open:rotate-180 mt-px size-3 transition-transform duration-100\"\n weight=\"bold\" />\n </ScalarButton>\n </ScalarCombobox>\n <!-- Single client: just show its label, no need for a dropdown -->\n <span\n v-else\n class=\"text-c-2 flex h-full w-fit items-center px-0.5 py-0 text-base font-normal\"\n data-testid=\"client-picker\">\n {{ localSelectedClient?.title }}\n </span>\n </template>\n </ScalarCardHeader>\n\n <!-- Code snippet -->\n <ScalarCardSection class=\"request-editor-section custom-scroll p-0\">\n <div\n v-if=\"externalExamples.pending.value\"\n class=\"text-c-2 p-4\"\n role=\"status\">\n <template v-if=\"externalExamples.failed.value\">\n Could not load this example.\n <ScalarButton\n size=\"sm\"\n variant=\"ghost\"\n @click=\"externalExamples.retry\">\n Retry\n </ScalarButton>\n </template>\n <template v-else>Loading example…</template>\n </div>\n <div\n v-else-if=\"generatedCode === null\"\n class=\"text-c-2 p-4\"\n role=\"status\">\n {{ codeSampleUnavailable }}\n </div>\n <div\n v-else\n :id=\"`${id}-example`\"\n class=\"code-snippet\">\n <ScalarCodeBlock\n v-if=\"!shouldVirtualize\"\n class=\"bg-b-2 h-full\"\n :content=\"generatedCode\"\n :hideCredentials=\"secretCredentials\"\n :lang=\"codeBlockLanguage\"\n lineNumbers />\n <ScalarVirtualText\n v-else\n containerClass=\"custom-scroll scalar-code-block border rounded-b flex flex-1 max-h-screen\"\n contentClass=\"language-plaintext whitespace-pre font-code text-base p-2\"\n :lineHeight=\"20\"\n :text=\"generatedCode\" />\n </div>\n </ScalarCardSection>\n\n <!-- Footer -->\n <ScalarCardFooter\n v-if=\"showExamplePicker || $slots.footer\"\n class=\"request-card-footer bg-b-3\">\n <!-- Example picker -->\n <div\n v-if=\"showExamplePicker\"\n class=\"request-card-footer-addon\">\n <template v-if=\"Object.keys(requestBodyExamples).length\">\n <ExamplePicker\n :examples=\"requestBodyExamples\"\n :modelValue=\"localExampleKey\"\n @update:modelValue=\"selectExample\" />\n </template>\n </div>\n\n <!-- Footer -->\n <slot\n :exampleName=\"localExampleKey\"\n name=\"footer\" />\n </ScalarCardFooter>\n </ScalarCard>\n\n <!-- Fallback card with just method and path in the case of no examples -->\n <ScalarCard\n v-else-if=\"fallback\"\n class=\"request-card dark-mode\">\n <ScalarCardSection class=\"request-card-simple\">\n <div class=\"request-header\">\n <HttpMethod\n as=\"span\"\n class=\"request-method\"\n :method=\"method\" />\n <slot name=\"header\" />\n </div>\n <slot\n :exampleName=\"localExampleKey\"\n name=\"footer\" />\n </ScalarCardSection>\n </ScalarCard>\n</template>\n<style scoped>\n.request-card {\n color: var(--scalar-color-1);\n font-size: var(--scalar-font-size-3);\n}\n.request-method {\n font-family: var(--scalar-font-code);\n margin-right: 6px;\n}\n.request-card-footer {\n display: flex;\n justify-content: flex-end;\n padding: 6px;\n flex-shrink: 0;\n position: relative;\n}\n.request-card-footer-addon {\n display: flex;\n align-items: center;\n\n flex: 1;\n min-width: 0;\n}\n.request-editor-section {\n display: flex;\n flex: 1;\n}\n.request-card-simple {\n display: flex;\n align-items: center;\n justify-content: space-between;\n\n padding: 8px 8px 8px 12px;\n\n font-size: var(--scalar-small);\n}\n.code-snippet {\n display: flex;\n flex-direction: column;\n width: 100%;\n}\n</style>\n"],"mappings":""}
|
|
@@ -7,32 +7,37 @@ import { getClients as r } from "../helpers/get-clients.js";
|
|
|
7
7
|
import { getSecrets as i } from "../helpers/get-secrets.js";
|
|
8
8
|
import ne from "./ExamplePicker.vue.js";
|
|
9
9
|
import a from "./HttpMethod.vue.js";
|
|
10
|
-
import { Fragment as o, computed as s, createBlock as c, createCommentVNode as l, createElementBlock as u, createElementVNode as d, createSlots as re, createTextVNode as f, createVNode as p, defineComponent as m, onBeforeMount as ie, openBlock as h, ref as g, renderSlot as _, toDisplayString as v, unref as y, useId as b, watch as x, watchEffect as
|
|
11
|
-
import { ScalarButton as
|
|
12
|
-
import { ScalarCard as
|
|
13
|
-
import { ScalarCodeBlock as
|
|
14
|
-
import { ScalarCombobox as
|
|
15
|
-
import { ScalarVirtualText as
|
|
16
|
-
import { freezeElement as
|
|
17
|
-
import { ScalarIconCaretDown as
|
|
18
|
-
import { getResolvedRef as
|
|
19
|
-
import { getOperationExamples as
|
|
20
|
-
import { useExampleVisibility as
|
|
10
|
+
import { Fragment as o, computed as s, createBlock as c, createCommentVNode as l, createElementBlock as u, createElementVNode as d, createSlots as re, createTextVNode as f, createVNode as p, defineComponent as m, onBeforeMount as ie, openBlock as h, ref as g, renderSlot as _, toDisplayString as v, unref as y, useId as b, watch as x, watchEffect as ae, withCtx as S } from "vue";
|
|
11
|
+
import { ScalarButton as C } from "@scalar/components/button";
|
|
12
|
+
import { ScalarCard as w, ScalarCardFooter as oe, ScalarCardHeader as se, ScalarCardSection as T } from "@scalar/components/card";
|
|
13
|
+
import { ScalarCodeBlock as ce } from "@scalar/components/code-block";
|
|
14
|
+
import { ScalarCombobox as le } from "@scalar/components/combobox";
|
|
15
|
+
import { ScalarVirtualText as ue } from "@scalar/components/virtual-text";
|
|
16
|
+
import { freezeElement as de } from "@scalar/helpers/dom/freeze-element";
|
|
17
|
+
import { ScalarIconCaretDown as E } from "@scalar/icons";
|
|
18
|
+
import { getResolvedRef as D } from "@scalar/workspace-store/helpers/get-resolved-ref";
|
|
19
|
+
import { getOperationExamples as O, resolveOperationExamples as k } from "@scalar/workspace-store/helpers/operation-examples";
|
|
20
|
+
import { useExampleVisibility as A, useExternalExamples as j } from "@scalar/workspace-store/helpers/use-external-examples";
|
|
21
21
|
//#region src/code-example/components/CodeExample.vue?vue&type=script&setup=true&lang.ts
|
|
22
|
-
var
|
|
22
|
+
var M = ["innerHTML"], N = {
|
|
23
23
|
key: 1,
|
|
24
24
|
class: "text-c-2 flex h-full w-fit items-center px-0.5 py-0 text-base font-normal",
|
|
25
25
|
"data-testid": "client-picker"
|
|
26
|
-
},
|
|
26
|
+
}, P = {
|
|
27
27
|
key: 0,
|
|
28
28
|
class: "text-c-2 p-4",
|
|
29
29
|
role: "status"
|
|
30
|
-
},
|
|
30
|
+
}, F = {
|
|
31
|
+
key: 1,
|
|
32
|
+
class: "text-c-2 p-4",
|
|
33
|
+
role: "status"
|
|
34
|
+
}, I = ["id"], L = {
|
|
31
35
|
key: 0,
|
|
32
36
|
class: "request-card-footer-addon"
|
|
33
|
-
},
|
|
37
|
+
}, R = { class: "request-header" }, z = /*@__PURE__*/ m({
|
|
34
38
|
__name: "CodeExample",
|
|
35
39
|
props: {
|
|
40
|
+
codeSampleUnavailable: { default: "No code sample available for this example." },
|
|
36
41
|
integration: {},
|
|
37
42
|
clientOptions: {},
|
|
38
43
|
selectedClient: {},
|
|
@@ -51,38 +56,38 @@ var P = ["innerHTML"], F = {
|
|
|
51
56
|
requestBodyCompositionSelection: {}
|
|
52
57
|
},
|
|
53
58
|
emits: ["update:exampleKey"],
|
|
54
|
-
setup(m, { emit:
|
|
55
|
-
let
|
|
56
|
-
let e =
|
|
59
|
+
setup(m, { emit: z }) {
|
|
60
|
+
let B = z, V = s(() => {
|
|
61
|
+
let e = D(m.operation.requestBody)?.content ?? {}, t = m.selectedContentType || Object.keys(e)[0];
|
|
57
62
|
return t ? e[t]?.examples ?? {} : {};
|
|
58
|
-
}),
|
|
59
|
-
let t = Object.keys(
|
|
60
|
-
return e && t.includes(e) ? e :
|
|
63
|
+
}), H = g(""), U = (e) => {
|
|
64
|
+
let t = Object.keys(V.value);
|
|
65
|
+
return e && t.includes(e) ? e : H.value && t.includes(H.value) ? H.value : t[0] ?? "";
|
|
61
66
|
};
|
|
62
67
|
ie(() => {
|
|
63
|
-
|
|
68
|
+
H.value = U(m.selectedExample);
|
|
64
69
|
}), x(() => m.selectedExample, (e) => {
|
|
65
|
-
|
|
70
|
+
H.value = U(e);
|
|
66
71
|
}), x(() => m.selectedContentType, () => {
|
|
67
|
-
Object.keys(
|
|
68
|
-
}),
|
|
69
|
-
|
|
72
|
+
Object.keys(V.value).includes(H.value) || (H.value = U(m.selectedExample));
|
|
73
|
+
}), ae(() => {
|
|
74
|
+
B("update:exampleKey", H.value);
|
|
70
75
|
});
|
|
71
|
-
let
|
|
72
|
-
|
|
73
|
-
},
|
|
74
|
-
x([() => m.selectedClient,
|
|
75
|
-
let n = t(
|
|
76
|
-
n && (
|
|
76
|
+
let fe = (e) => {
|
|
77
|
+
H.value = e, m.eventBus.emit("workspace:update:selected-example", e);
|
|
78
|
+
}, W = s(() => te(m.operation)), G = s(() => r(W.value.samples, m.clientOptions, W.value.label)), K = s(() => G.value.reduce((e, t) => e + t.options.length, 0)), q = g(t(G.value, m.selectedClient));
|
|
79
|
+
x([() => m.selectedClient, G], ([e]) => {
|
|
80
|
+
let n = t(G.value, e);
|
|
81
|
+
n && (q.value = n);
|
|
77
82
|
});
|
|
78
|
-
let
|
|
83
|
+
let J = g(null), pe = A(J), Y = j(() => O(m.operation, H.value, m.selectedContentType), () => pe.value), X = s(() => k(m.operation, H.value, m.selectedContentType, Y.resolve)), Z = s(() => Object.keys(V.value).length > 1), Q = s(() => {
|
|
79
84
|
if (!m.isWebhook) return null;
|
|
80
85
|
try {
|
|
81
86
|
return n({
|
|
82
|
-
operation:
|
|
87
|
+
operation: X.value,
|
|
83
88
|
method: m.method,
|
|
84
89
|
path: m.path,
|
|
85
|
-
example:
|
|
90
|
+
example: H.value,
|
|
86
91
|
requestBodyCompositionSelection: m.requestBodyCompositionSelection,
|
|
87
92
|
defaultDisabledParameters: !0
|
|
88
93
|
});
|
|
@@ -92,39 +97,39 @@ var P = ["innerHTML"], F = {
|
|
|
92
97
|
}), $ = s(() => m.isWebhook ? Q.value?.postData?.text ?? "" : ee({
|
|
93
98
|
defaultDisabledParameters: !0,
|
|
94
99
|
includeDefaultHeaders: m.integration === "client",
|
|
95
|
-
clientId:
|
|
96
|
-
customCodeSamples:
|
|
97
|
-
operation:
|
|
100
|
+
clientId: q.value?.id,
|
|
101
|
+
customCodeSamples: W.value.samples,
|
|
102
|
+
operation: X.value,
|
|
98
103
|
method: m.method,
|
|
99
104
|
path: m.path,
|
|
100
105
|
contentType: m.selectedContentType,
|
|
101
106
|
server: m.selectedServer,
|
|
102
107
|
securitySchemes: m.securitySchemes,
|
|
103
|
-
example:
|
|
108
|
+
example: H.value,
|
|
104
109
|
globalCookies: m.globalCookies,
|
|
105
110
|
requestBodyCompositionSelection: m.requestBodyCompositionSelection
|
|
106
|
-
})),
|
|
111
|
+
})), me = s(() => m.isWebhook ? he.value : q.value?.lang), he = s(() => {
|
|
107
112
|
if (!Q.value?.postData) return "json";
|
|
108
113
|
let e = Q.value.postData.mimeType;
|
|
109
114
|
return e?.includes("json") ? "json" : e?.includes("xml") ? "xml" : e?.includes("yaml") || e?.includes("yml") ? "yaml" : e?.includes("text/plain") ? "text" : "json";
|
|
110
|
-
}),
|
|
111
|
-
if (
|
|
112
|
-
let e =
|
|
115
|
+
}), ge = s(() => i(m.securitySchemes)), _e = (e) => {
|
|
116
|
+
if (J.value) {
|
|
117
|
+
let e = de(J.value.$el);
|
|
113
118
|
setTimeout(() => {
|
|
114
119
|
e();
|
|
115
120
|
}, 300);
|
|
116
121
|
}
|
|
117
|
-
|
|
118
|
-
},
|
|
119
|
-
return (t, n) => $.value || y(
|
|
122
|
+
q.value = e, e && m.eventBus.emit("workspace:update:selected-client", e.id);
|
|
123
|
+
}, ve = s(() => ($.value?.length ?? 0) > 2e4), ye = b();
|
|
124
|
+
return (t, n) => $.value === null || $.value || y(Y).pending.value ? (h(), c(y(w), {
|
|
120
125
|
key: 0,
|
|
121
126
|
ref_key: "elem",
|
|
122
|
-
ref:
|
|
127
|
+
ref: J,
|
|
123
128
|
class: "request-card dark-mode"
|
|
124
129
|
}, {
|
|
125
|
-
default:
|
|
126
|
-
p(y(
|
|
127
|
-
default:
|
|
130
|
+
default: S(() => [
|
|
131
|
+
p(y(se), { class: "pr-2.5" }, re({
|
|
132
|
+
default: S(() => [
|
|
128
133
|
n[1] ||= d("span", { class: "sr-only" }, "Request Example for", -1),
|
|
129
134
|
p(a, {
|
|
130
135
|
as: "span",
|
|
@@ -134,28 +139,28 @@ var P = ["innerHTML"], F = {
|
|
|
134
139
|
m.generateLabel ? (h(), u("span", {
|
|
135
140
|
key: 0,
|
|
136
141
|
innerHTML: m.generateLabel()
|
|
137
|
-
}, null, 8,
|
|
142
|
+
}, null, 8, M)) : l("", !0),
|
|
138
143
|
_(t.$slots, "header", {}, void 0, !0)
|
|
139
144
|
]),
|
|
140
145
|
_: 2
|
|
141
|
-
}, [!m.isWebhook &&
|
|
146
|
+
}, [!m.isWebhook && K.value ? {
|
|
142
147
|
name: "actions",
|
|
143
|
-
fn:
|
|
148
|
+
fn: S(() => [K.value > 1 ? (h(), c(y(le), {
|
|
144
149
|
key: 0,
|
|
145
150
|
class: "max-h-80",
|
|
146
151
|
filterFn: y(e),
|
|
147
|
-
modelValue:
|
|
148
|
-
options:
|
|
152
|
+
modelValue: q.value,
|
|
153
|
+
options: G.value,
|
|
149
154
|
placement: "bottom-end",
|
|
150
155
|
teleport: "",
|
|
151
|
-
"onUpdate:modelValue": n[0] ||= (e) =>
|
|
156
|
+
"onUpdate:modelValue": n[0] ||= (e) => _e(e)
|
|
152
157
|
}, {
|
|
153
|
-
default:
|
|
158
|
+
default: S(() => [p(y(C), {
|
|
154
159
|
class: "text-c-2 hover:text-c-1 flex h-full w-fit gap-1.5 px-0.5 py-0 text-base font-normal",
|
|
155
160
|
"data-testid": "client-picker",
|
|
156
161
|
variant: "ghost"
|
|
157
162
|
}, {
|
|
158
|
-
default:
|
|
163
|
+
default: S(() => [f(v(q.value?.title) + " ", 1), p(y(E), {
|
|
159
164
|
class: "ui-open:rotate-180 mt-px size-3 transition-transform duration-100",
|
|
160
165
|
weight: "bold"
|
|
161
166
|
})]),
|
|
@@ -166,65 +171,65 @@ var P = ["innerHTML"], F = {
|
|
|
166
171
|
"filterFn",
|
|
167
172
|
"modelValue",
|
|
168
173
|
"options"
|
|
169
|
-
])) : (h(), u("span",
|
|
174
|
+
])) : (h(), u("span", N, v(q.value?.title), 1))]),
|
|
170
175
|
key: "0"
|
|
171
176
|
} : void 0]), 1024),
|
|
172
|
-
p(y(
|
|
173
|
-
default:
|
|
177
|
+
p(y(T), { class: "request-editor-section custom-scroll p-0" }, {
|
|
178
|
+
default: S(() => [y(Y).pending.value ? (h(), u("div", P, [y(Y).failed.value ? (h(), u(o, { key: 0 }, [n[3] ||= f(" Could not load this example. ", -1), p(y(C), {
|
|
174
179
|
size: "sm",
|
|
175
180
|
variant: "ghost",
|
|
176
|
-
onClick: y(
|
|
181
|
+
onClick: y(Y).retry
|
|
177
182
|
}, {
|
|
178
|
-
default:
|
|
183
|
+
default: S(() => [...n[2] ||= [f(" Retry ", -1)]]),
|
|
179
184
|
_: 1
|
|
180
|
-
}, 8, ["onClick"])], 64)) : (h(), u(o, { key: 1 }, [f("Loading example…")], 64))])) : (h(), u("div", {
|
|
181
|
-
key:
|
|
182
|
-
id: `${y(
|
|
185
|
+
}, 8, ["onClick"])], 64)) : (h(), u(o, { key: 1 }, [f("Loading example…")], 64))])) : $.value === null ? (h(), u("div", F, v(m.codeSampleUnavailable), 1)) : (h(), u("div", {
|
|
186
|
+
key: 2,
|
|
187
|
+
id: `${y(ye)}-example`,
|
|
183
188
|
class: "code-snippet"
|
|
184
|
-
}, [
|
|
189
|
+
}, [ve.value ? (h(), c(y(ue), {
|
|
185
190
|
key: 1,
|
|
186
191
|
containerClass: "custom-scroll scalar-code-block border rounded-b flex flex-1 max-h-screen",
|
|
187
192
|
contentClass: "language-plaintext whitespace-pre font-code text-base p-2",
|
|
188
193
|
lineHeight: 20,
|
|
189
194
|
text: $.value
|
|
190
|
-
}, null, 8, ["text"])) : (h(), c(y(
|
|
195
|
+
}, null, 8, ["text"])) : (h(), c(y(ce), {
|
|
191
196
|
key: 0,
|
|
192
197
|
class: "bg-b-2 h-full",
|
|
193
198
|
content: $.value,
|
|
194
|
-
hideCredentials:
|
|
195
|
-
lang:
|
|
199
|
+
hideCredentials: ge.value,
|
|
200
|
+
lang: me.value,
|
|
196
201
|
lineNumbers: ""
|
|
197
202
|
}, null, 8, [
|
|
198
203
|
"content",
|
|
199
204
|
"hideCredentials",
|
|
200
205
|
"lang"
|
|
201
|
-
]))], 8,
|
|
206
|
+
]))], 8, I))]),
|
|
202
207
|
_: 1
|
|
203
208
|
}),
|
|
204
|
-
|
|
209
|
+
Z.value || t.$slots.footer ? (h(), c(y(oe), {
|
|
205
210
|
key: 0,
|
|
206
211
|
class: "request-card-footer bg-b-3"
|
|
207
212
|
}, {
|
|
208
|
-
default:
|
|
213
|
+
default: S(() => [Z.value ? (h(), u("div", L, [Object.keys(V.value).length ? (h(), c(ne, {
|
|
209
214
|
key: 0,
|
|
210
|
-
examples:
|
|
211
|
-
modelValue:
|
|
212
|
-
"onUpdate:modelValue":
|
|
213
|
-
}, null, 8, ["examples", "modelValue"])) : l("", !0)])) : l("", !0), _(t.$slots, "footer", { exampleName:
|
|
215
|
+
examples: V.value,
|
|
216
|
+
modelValue: H.value,
|
|
217
|
+
"onUpdate:modelValue": fe
|
|
218
|
+
}, null, 8, ["examples", "modelValue"])) : l("", !0)])) : l("", !0), _(t.$slots, "footer", { exampleName: H.value }, void 0, !0)]),
|
|
214
219
|
_: 3
|
|
215
220
|
})) : l("", !0)
|
|
216
221
|
]),
|
|
217
222
|
_: 3
|
|
218
|
-
}, 512)) : m.fallback ? (h(), c(y(
|
|
223
|
+
}, 512)) : m.fallback ? (h(), c(y(w), {
|
|
219
224
|
key: 1,
|
|
220
225
|
class: "request-card dark-mode"
|
|
221
226
|
}, {
|
|
222
|
-
default:
|
|
223
|
-
default:
|
|
227
|
+
default: S(() => [p(y(T), { class: "request-card-simple" }, {
|
|
228
|
+
default: S(() => [d("div", R, [p(a, {
|
|
224
229
|
as: "span",
|
|
225
230
|
class: "request-method",
|
|
226
231
|
method: m.method
|
|
227
|
-
}, null, 8, ["method"]), _(t.$slots, "header", {}, void 0, !0)]), _(t.$slots, "footer", { exampleName:
|
|
232
|
+
}, null, 8, ["method"]), _(t.$slots, "header", {}, void 0, !0)]), _(t.$slots, "footer", { exampleName: H.value }, void 0, !0)]),
|
|
228
233
|
_: 3
|
|
229
234
|
})]),
|
|
230
235
|
_: 3
|
|
@@ -232,6 +237,6 @@ var P = ["innerHTML"], F = {
|
|
|
232
237
|
}
|
|
233
238
|
});
|
|
234
239
|
//#endregion
|
|
235
|
-
export {
|
|
240
|
+
export { z as default };
|
|
236
241
|
|
|
237
242
|
//# sourceMappingURL=CodeExample.vue.script.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeExample.vue.script.js","names":["$slots"],"sources":["../../../src/code-example/components/CodeExample.vue"],"sourcesContent":["<script lang=\"ts\">\nexport type CodeExampleProps = {\n /**\n * Integration type: determines if the code sample is displayed in a client environment\n * or in an API reference environment.\n */\n integration?: 'client' | 'reference'\n /**\n * List of all http clients formatted into option groups for the client selector\n */\n clientOptions: ClientOptionGroup[]\n /**\n * Pre-selected client, this will determine which client is initially selected in the dropdown.\n * Either a built-in client id (e.g. `js/fetch`) or a custom sample id (e.g. `custom/python`).\n *\n * Typed as a plain string: unioning the (large) client-id union with the `custom/...`\n * ids overflows TypeScript's union-complexity limit inside this component's `defineProps`.\n *\n * @defaults to a custom sample if one is available, otherwise shell/curl\n */\n selectedClient?: string\n /**\n * Which server from the spec to use for the code example\n */\n selectedServer?: ServerObject | null\n /**\n * The selected content type from the requestBody.content, this will determine which examples are available\n * as well as the content type of the code example\n *\n * @defaults to the first content type if not provided\n */\n selectedContentType?: string\n /**\n * Example name to use for resolving example values for parameters AND requestBody.\n *\n * This is the document-wide selection: it is honored only when this operation defines an example\n * with the same key, so picking an example on one operation syncs the rest without blanking out\n * operations that do not share that key.\n *\n * @example \"limited\"\n * ```ts\n * parameters: {\n * name: 'foobar',\n * in: 'query',\n * examples: {\n * limited: {\n * dataValue: 10,\n * }\n * }\n * },\n * body: {\n * content: {\n * 'application/json': {\n * examples: {\n * limited: {\n * dataValue: { foo: 'bar' },\n * }\n * }\n * }\n * }\n * }\n *\n * ```\n */\n selectedExample?: string\n /**\n * Event bus\n */\n eventBus: WorkspaceEventBus\n /**\n * The security schemes which are applicable to this operation\n */\n securitySchemes: SecuritySchemeObjectSecret[]\n /**\n * HTTP method of the operation\n */\n method: HttpMethodType\n /**\n * Path of the operation\n */\n path: string\n /**\n * De-referenced OpenAPI Operation object\n */\n operation: OperationObject\n /**\n * If true and there's no example, we will display a small card with the method and path only\n */\n fallback?: boolean\n /**\n * A method to generate the label of the block, should return an html string\n */\n generateLabel?: () => string\n /**\n * If true, render this as a webhook request example\n */\n isWebhook?: boolean\n /**\n * Workspace + document cookies\n */\n globalCookies?: XScalarCookie[]\n /**\n * When the request body schema uses oneOf/anyOf, use these selected variants\n * for the example snippet (e.g. from the schema dropdowns in the API reference).\n */\n requestBodyCompositionSelection?: Record<string, number>\n}\n\n/**\n * Request Example\n *\n * The core component for rendering a request example block,\n * this component does not have much of its own state but operates on props and custom events\n *\n * @event workspace:update:selected-client - Emitted when the selected client changes\n * @event workspace:update:selected-example - Emitted when the selected example changes, so other operations can sync\n */\nexport default {}\n</script>\n\n<script setup lang=\"ts\">\nimport { ScalarButton } from '@scalar/components/button'\nimport {\n ScalarCard,\n ScalarCardFooter,\n ScalarCardHeader,\n ScalarCardSection,\n} from '@scalar/components/card'\nimport { ScalarCodeBlock } from '@scalar/components/code-block'\nimport { ScalarCombobox } from '@scalar/components/combobox'\nimport { ScalarVirtualText } from '@scalar/components/virtual-text'\nimport { freezeElement } from '@scalar/helpers/dom/freeze-element'\nimport type { HttpMethod as HttpMethodType } from '@scalar/helpers/http/http-methods'\nimport { ScalarIconCaretDown } from '@scalar/icons'\nimport { type WorkspaceEventBus } from '@scalar/workspace-store/events'\nimport { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport {\n getOperationExamples,\n resolveOperationExamples,\n} from '@scalar/workspace-store/helpers/operation-examples'\nimport {\n useExampleVisibility,\n useExternalExamples,\n} from '@scalar/workspace-store/helpers/use-external-examples'\nimport type { SecuritySchemeObjectSecret } from '@scalar/workspace-store/request-example'\nimport type { XScalarCookie } from '@scalar/workspace-store/schemas/extensions/general/x-scalar-cookies'\nimport type {\n OperationObject,\n ServerObject,\n} from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document'\nimport {\n computed,\n onBeforeMount,\n ref,\n useId,\n watch,\n watchEffect,\n type ComponentPublicInstance,\n} from 'vue'\n\nimport { filterClientsByQuery } from '../helpers/filter-clients-by-query'\nimport { findClient } from '../helpers/find-client'\nimport { generateCodeSnippet } from '../helpers/generate-code-snippet'\nimport { getClients } from '../helpers/get-clients'\nimport { getCustomCodeSamples } from '../helpers/get-custom-code-samples'\nimport { getSecrets } from '../helpers/get-secrets'\nimport { operationToHar } from '../helpers/operation-to-har/operation-to-har'\nimport type {\n ClientOption,\n ClientOptionGroup,\n CustomClientOption,\n} from '../types'\nimport ExamplePicker from './ExamplePicker.vue'\nimport HttpMethod from './HttpMethod.vue'\n\nconst {\n integration,\n clientOptions,\n selectedClient,\n selectedServer = null,\n selectedContentType,\n selectedExample,\n securitySchemes = [],\n method,\n eventBus,\n path,\n operation,\n isWebhook,\n generateLabel,\n globalCookies,\n requestBodyCompositionSelection,\n} = defineProps<CodeExampleProps>()\n\nconst emit = defineEmits<{\n /**\n * Emitted whenever the example key actually shown for this operation changes.\n *\n * This is the resolved local key (not the raw document-wide selection), so layouts that render\n * the test-request button outside this component can open the client with the same example the\n * snippet displays.\n */\n (e: 'update:exampleKey', value: string): void\n}>()\n\ndefineSlots<{\n header: () => unknown\n footer: ({ exampleName }: { exampleName: string }) => unknown\n}>()\n\n/** Grab the examples for the given content type */\nconst requestBodyExamples = computed(() => {\n const content = getResolvedRef(operation.requestBody)?.content ?? {}\n const contentType = selectedContentType || Object.keys(content)[0]\n if (!contentType) return {}\n\n const examples = content[contentType]?.examples ?? {}\n\n return examples\n})\n\n/**\n * The example key actually shown for this operation.\n *\n * `selectedExample` is the document-wide selection that syncs across operations. We honor it only\n * when this operation actually defines that key, otherwise we keep the local example: a selection\n * on one operation should never blank out an operation that does not share the same example.\n */\nconst localExampleKey = ref('')\n\n/** Resolve the key to display, preferring the document-wide selection when this operation has it */\nconst resolveExampleKey = (preferred: string | undefined): string => {\n const keys = Object.keys(requestBodyExamples.value)\n if (preferred && keys.includes(preferred)) {\n return preferred\n }\n // Keep the current local example when it is still valid, otherwise fall back to the first one\n if (localExampleKey.value && keys.includes(localExampleKey.value)) {\n return localExampleKey.value\n }\n return keys[0] ?? ''\n}\n\n// Set the initial example from the document-wide selection, falling back to the first example\nonBeforeMount(() => {\n localExampleKey.value = resolveExampleKey(selectedExample)\n})\n\n// Follow the document-wide selection when it changes and this operation has that example\nwatch(\n () => selectedExample,\n (preferred) => {\n localExampleKey.value = resolveExampleKey(preferred)\n },\n)\n\n/** Reset the selected example key if the content type changes and the new content type doesn't have the previously selected example */\nwatch(\n () => selectedContentType,\n () => {\n if (\n !Object.keys(requestBodyExamples.value).includes(localExampleKey.value)\n ) {\n // Re-resolve so the new content type still follows the document-wide selection when it has\n // that key, instead of always snapping back to the first example\n localExampleKey.value = resolveExampleKey(selectedExample)\n }\n },\n)\n\n// Keep the parent informed of the resolved key so a test-request button rendered outside this\n// component (e.g. the classic layout header) opens the client with the example the snippet shows\nwatchEffect(() => {\n emit('update:exampleKey', localExampleKey.value)\n})\n\n/** Select an example locally and sync the choice across the document */\nconst selectExample = (key: string) => {\n localExampleKey.value = key\n eventBus.emit('workspace:update:selected-example', key)\n}\n\n/** Grab any custom code samples from the operation */\nconst customCodeSamples = computed(() => getCustomCodeSamples(operation))\n\n/** Merge custom code samples with the client options */\nconst clients = computed(() =>\n getClients(\n customCodeSamples.value.samples,\n clientOptions,\n customCodeSamples.value.label,\n ),\n)\n\n/** Total number of available clients across all option groups */\nconst clientCount = computed(() =>\n clients.value.reduce((total, group) => total + group.options.length, 0),\n)\n\n/** The locally selected client which would include code samples from this operation only */\nconst localSelectedClient = ref<ClientOption | CustomClientOption | undefined>(\n findClient(clients.value, selectedClient),\n)\n\n/**\n * Re-resolve the local client whenever the global selection or the available\n * clients change. Watching `clients` matters when navigating between operations:\n * the stored id stays the same, but the matching option (e.g. a custom sample)\n * differs per operation, so without this the snippet could go stale.\n */\nwatch([() => selectedClient, clients], ([newClient]) => {\n const client = findClient(clients.value, newClient)\n if (client) {\n localSelectedClient.value = client\n }\n})\n\nconst elem = ref<ComponentPublicInstance | null>(null)\nconst visible = useExampleVisibility(elem)\nconst externalExamples = useExternalExamples(\n () =>\n getOperationExamples(operation, localExampleKey.value, selectedContentType),\n () => visible.value,\n)\nconst resolvedOperation = computed(() =>\n resolveOperationExamples(\n operation,\n localExampleKey.value,\n selectedContentType,\n externalExamples.resolve,\n ),\n)\n\n/** Generate HAR data for webhook requests */\nconst webhookHar = computed(() => {\n if (!isWebhook) return null\n\n try {\n return operationToHar({\n operation: resolvedOperation.value,\n method,\n path,\n example: localExampleKey.value,\n requestBodyCompositionSelection,\n // Only required parameters are shown in code examples; optional parameters\n // are omitted unless explicitly enabled via `x-disabled: false`.\n defaultDisabledParameters: true,\n })\n } catch (error) {\n console.error('[webhookHar]', error)\n return null\n }\n})\n\n/** Generate the code snippet for the selected example */\nconst generatedCode = computed<string>(() => {\n if (isWebhook) {\n return webhookHar.value?.postData?.text ?? ''\n }\n\n return generateCodeSnippet({\n // Only required parameters are shown in code examples; optional parameters\n // are omitted unless explicitly enabled via `x-disabled: false`.\n defaultDisabledParameters: true,\n includeDefaultHeaders: integration === 'client',\n clientId: localSelectedClient.value?.id,\n customCodeSamples: customCodeSamples.value.samples,\n operation: resolvedOperation.value,\n method,\n path,\n contentType: selectedContentType,\n server: selectedServer,\n securitySchemes,\n example: localExampleKey.value,\n globalCookies,\n requestBodyCompositionSelection,\n })\n})\n\n/** The language for the code block, used for syntax highlighting */\nconst codeBlockLanguage = computed(() => {\n if (isWebhook) {\n return webhookLanguage.value\n }\n\n return localSelectedClient.value?.lang\n})\n\n/** Determine the language for webhook content based on MIME type */\nconst webhookLanguage = computed<string>(() => {\n if (!webhookHar.value?.postData) return 'json'\n\n const contentType = webhookHar.value.postData.mimeType\n if (contentType?.includes('json')) return 'json'\n if (contentType?.includes('xml')) return 'xml'\n if (contentType?.includes('yaml') || contentType?.includes('yml'))\n return 'yaml'\n if (contentType?.includes('text/plain')) return 'text'\n\n return 'json'\n})\n\n/** Block secrets from being shown in the code block */\nconst secretCredentials = computed(() => getSecrets(securitySchemes))\n\n/** Set custom example, or update the selected HTTP client globally */\nconst selectClient = (option: ClientOption) => {\n // We need to freeze the ui to prevent scrolling as the clients change\n if (elem.value) {\n const unfreeze = freezeElement(elem.value.$el)\n setTimeout(() => {\n unfreeze()\n }, 300)\n }\n // Update to the local example\n localSelectedClient.value = option\n\n // Sync the selection globally so other operations follow along. Custom samples\n // sync too (keyed by language), so picking e.g. the Python SDK example here\n // shows the Python example on every operation that ships one.\n if (option) {\n eventBus.emit('workspace:update:selected-client', option.id)\n }\n}\n\n// Virtualize the code block if it's too large\n// This prevents the entire app from freezing up if there's a massive example\n// We set a lower threshold here as code examples can get quite large\nconst VIRTUALIZATION_THRESHOLD = 20_000\n\nconst shouldVirtualize = computed(\n () => (generatedCode.value.length ?? 0) > VIRTUALIZATION_THRESHOLD,\n)\n\nconst id = useId()\n</script>\n<template>\n <ScalarCard\n v-if=\"generatedCode || externalExamples.pending.value\"\n ref=\"elem\"\n class=\"request-card dark-mode\">\n <!-- Header -->\n <ScalarCardHeader class=\"pr-2.5\">\n <span class=\"sr-only\">Request Example for</span>\n <HttpMethod\n as=\"span\"\n class=\"request-method\"\n :method=\"method\" />\n <span\n v-if=\"generateLabel\"\n v-html=\"generateLabel()\" />\n <slot name=\"header\" />\n <!-- Client picker -->\n <template\n v-if=\"!isWebhook && clientCount\"\n #actions>\n <!-- Multiple clients: render a dropdown to switch between them -->\n <ScalarCombobox\n v-if=\"clientCount > 1\"\n class=\"max-h-80\"\n :filterFn=\"filterClientsByQuery\"\n :modelValue=\"localSelectedClient\"\n :options=\"clients\"\n placement=\"bottom-end\"\n teleport\n @update:modelValue=\"selectClient($event as ClientOption)\">\n <ScalarButton\n class=\"text-c-2 hover:text-c-1 flex h-full w-fit gap-1.5 px-0.5 py-0 text-base font-normal\"\n data-testid=\"client-picker\"\n variant=\"ghost\">\n {{ localSelectedClient?.title }}\n <ScalarIconCaretDown\n class=\"ui-open:rotate-180 mt-px size-3 transition-transform duration-100\"\n weight=\"bold\" />\n </ScalarButton>\n </ScalarCombobox>\n <!-- Single client: just show its label, no need for a dropdown -->\n <span\n v-else\n class=\"text-c-2 flex h-full w-fit items-center px-0.5 py-0 text-base font-normal\"\n data-testid=\"client-picker\">\n {{ localSelectedClient?.title }}\n </span>\n </template>\n </ScalarCardHeader>\n\n <!-- Code snippet -->\n <ScalarCardSection class=\"request-editor-section custom-scroll p-0\">\n <div\n v-if=\"externalExamples.pending.value\"\n class=\"text-c-2 p-4\"\n role=\"status\">\n <template v-if=\"externalExamples.failed.value\">\n Could not load this example.\n <ScalarButton\n size=\"sm\"\n variant=\"ghost\"\n @click=\"externalExamples.retry\">\n Retry\n </ScalarButton>\n </template>\n <template v-else>Loading example…</template>\n </div>\n <div\n v-else\n :id=\"`${id}-example`\"\n class=\"code-snippet\">\n <ScalarCodeBlock\n v-if=\"!shouldVirtualize\"\n class=\"bg-b-2 h-full\"\n :content=\"generatedCode\"\n :hideCredentials=\"secretCredentials\"\n :lang=\"codeBlockLanguage\"\n lineNumbers />\n <ScalarVirtualText\n v-else\n containerClass=\"custom-scroll scalar-code-block border rounded-b flex flex-1 max-h-screen\"\n contentClass=\"language-plaintext whitespace-pre font-code text-base p-2\"\n :lineHeight=\"20\"\n :text=\"generatedCode\" />\n </div>\n </ScalarCardSection>\n\n <!-- Footer -->\n <ScalarCardFooter\n v-if=\"Object.keys(requestBodyExamples).length > 1 || $slots.footer\"\n class=\"request-card-footer bg-b-3\">\n <!-- Example picker -->\n <div\n v-if=\"Object.keys(requestBodyExamples).length > 1\"\n class=\"request-card-footer-addon\">\n <template v-if=\"Object.keys(requestBodyExamples).length\">\n <ExamplePicker\n :examples=\"requestBodyExamples\"\n :modelValue=\"localExampleKey\"\n @update:modelValue=\"selectExample\" />\n </template>\n </div>\n\n <!-- Footer -->\n <slot\n :exampleName=\"localExampleKey\"\n name=\"footer\" />\n </ScalarCardFooter>\n </ScalarCard>\n\n <!-- Fallback card with just method and path in the case of no examples -->\n <ScalarCard\n v-else-if=\"fallback\"\n class=\"request-card dark-mode\">\n <ScalarCardSection class=\"request-card-simple\">\n <div class=\"request-header\">\n <HttpMethod\n as=\"span\"\n class=\"request-method\"\n :method=\"method\" />\n <slot name=\"header\" />\n </div>\n <slot\n :exampleName=\"localExampleKey\"\n name=\"footer\" />\n </ScalarCardSection>\n </ScalarCard>\n</template>\n<style scoped>\n.request-card {\n color: var(--scalar-color-1);\n font-size: var(--scalar-font-size-3);\n}\n.request-method {\n font-family: var(--scalar-font-code);\n text-transform: uppercase;\n margin-right: 6px;\n}\n.request-card-footer {\n display: flex;\n justify-content: flex-end;\n padding: 6px;\n flex-shrink: 0;\n position: relative;\n}\n.request-card-footer-addon {\n display: flex;\n align-items: center;\n\n flex: 1;\n min-width: 0;\n}\n.request-editor-section {\n display: flex;\n flex: 1;\n}\n.request-card-simple {\n display: flex;\n align-items: center;\n justify-content: space-between;\n\n padding: 8px 8px 8px 12px;\n\n font-size: var(--scalar-small);\n}\n.code-snippet {\n display: flex;\n flex-direction: column;\n width: 100%;\n}\n</style>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CodeExample.vue.script.js","names":["$slots"],"sources":["../../../src/code-example/components/CodeExample.vue"],"sourcesContent":["<script lang=\"ts\">\nexport type CodeExampleProps = {\n /** Localized status text shown when the selected example has no linked code sample. */\n codeSampleUnavailable?: string\n /**\n * Integration type: determines if the code sample is displayed in a client environment\n * or in an API reference environment.\n */\n integration?: 'client' | 'reference'\n /**\n * List of all http clients formatted into option groups for the client selector\n */\n clientOptions: ClientOptionGroup[]\n /**\n * Pre-selected client, this will determine which client is initially selected in the dropdown.\n * Either a built-in client id (e.g. `js/fetch`) or a custom sample id (e.g. `custom/python`).\n *\n * Typed as a plain string: unioning the (large) client-id union with the `custom/...`\n * ids overflows TypeScript's union-complexity limit inside this component's `defineProps`.\n *\n * @defaults to a custom sample if one is available, otherwise shell/curl\n */\n selectedClient?: string\n /**\n * Which server from the spec to use for the code example\n */\n selectedServer?: ServerObject | null\n /**\n * The selected content type from the requestBody.content, this will determine which examples are available\n * as well as the content type of the code example\n *\n * @defaults to the first content type if not provided\n */\n selectedContentType?: string\n /**\n * Example name to use for resolving example values for parameters AND requestBody.\n *\n * This is the document-wide selection: it is honored only when this operation defines an example\n * with the same key, so picking an example on one operation syncs the rest without blanking out\n * operations that do not share that key.\n *\n * @example \"limited\"\n * ```ts\n * parameters: {\n * name: 'foobar',\n * in: 'query',\n * examples: {\n * limited: {\n * dataValue: 10,\n * }\n * }\n * },\n * body: {\n * content: {\n * 'application/json': {\n * examples: {\n * limited: {\n * dataValue: { foo: 'bar' },\n * }\n * }\n * }\n * }\n * }\n *\n * ```\n */\n selectedExample?: string\n /**\n * Event bus\n */\n eventBus: WorkspaceEventBus\n /**\n * The security schemes which are applicable to this operation\n */\n securitySchemes: SecuritySchemeObjectSecret[]\n /**\n * HTTP method of the operation\n */\n method: string\n /**\n * Path of the operation\n */\n path: string\n /**\n * De-referenced OpenAPI Operation object\n */\n operation: OperationObject\n /**\n * If true and there's no example, we will display a small card with the method and path only\n */\n fallback?: boolean\n /**\n * A method to generate the label of the block, should return an html string\n */\n generateLabel?: () => string\n /**\n * If true, render this as a webhook request example\n */\n isWebhook?: boolean\n /**\n * Workspace + document cookies\n */\n globalCookies?: XScalarCookie[]\n /**\n * When the request body schema uses oneOf/anyOf, use these selected variants\n * for the example snippet (e.g. from the schema dropdowns in the API reference).\n */\n requestBodyCompositionSelection?: Record<string, number>\n}\n\n/**\n * Request Example\n *\n * The core component for rendering a request example block,\n * this component does not have much of its own state but operates on props and custom events\n *\n * @event workspace:update:selected-client - Emitted when the selected client changes\n * @event workspace:update:selected-example - Emitted when the selected example changes, so other operations can sync\n */\nexport default {}\n</script>\n\n<script setup lang=\"ts\">\nimport { ScalarButton } from '@scalar/components/button'\nimport {\n ScalarCard,\n ScalarCardFooter,\n ScalarCardHeader,\n ScalarCardSection,\n} from '@scalar/components/card'\nimport { ScalarCodeBlock } from '@scalar/components/code-block'\nimport { ScalarCombobox } from '@scalar/components/combobox'\nimport { ScalarVirtualText } from '@scalar/components/virtual-text'\nimport { freezeElement } from '@scalar/helpers/dom/freeze-element'\nimport { ScalarIconCaretDown } from '@scalar/icons'\nimport { type WorkspaceEventBus } from '@scalar/workspace-store/events'\nimport { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport {\n getOperationExamples,\n resolveOperationExamples,\n} from '@scalar/workspace-store/helpers/operation-examples'\nimport {\n useExampleVisibility,\n useExternalExamples,\n} from '@scalar/workspace-store/helpers/use-external-examples'\nimport type { SecuritySchemeObjectSecret } from '@scalar/workspace-store/request-example'\nimport type { XScalarCookie } from '@scalar/workspace-store/schemas/extensions/general/x-scalar-cookies'\nimport type {\n OperationObject,\n ServerObject,\n} from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document'\nimport {\n computed,\n onBeforeMount,\n ref,\n useId,\n watch,\n watchEffect,\n type ComponentPublicInstance,\n} from 'vue'\n\nimport { filterClientsByQuery } from '../helpers/filter-clients-by-query'\nimport { findClient } from '../helpers/find-client'\nimport { generateCodeSnippet } from '../helpers/generate-code-snippet'\nimport { getClients } from '../helpers/get-clients'\nimport { getCustomCodeSamples } from '../helpers/get-custom-code-samples'\nimport { getSecrets } from '../helpers/get-secrets'\nimport { operationToHar } from '../helpers/operation-to-har/operation-to-har'\nimport type {\n ClientOption,\n ClientOptionGroup,\n CustomClientOption,\n} from '../types'\nimport ExamplePicker from './ExamplePicker.vue'\nimport HttpMethod from './HttpMethod.vue'\n\nconst {\n integration,\n codeSampleUnavailable = 'No code sample available for this example.',\n clientOptions,\n selectedClient,\n selectedServer = null,\n selectedContentType,\n selectedExample,\n securitySchemes = [],\n method,\n eventBus,\n path,\n operation,\n isWebhook,\n generateLabel,\n globalCookies,\n requestBodyCompositionSelection,\n} = defineProps<CodeExampleProps>()\n\nconst emit = defineEmits<{\n /**\n * Emitted whenever the example key actually shown for this operation changes.\n *\n * This is the resolved local key (not the raw document-wide selection), so layouts that render\n * the test-request button outside this component can open the client with the same example the\n * snippet displays.\n */\n (e: 'update:exampleKey', value: string): void\n}>()\n\ndefineSlots<{\n header: () => unknown\n footer: ({ exampleName }: { exampleName: string }) => unknown\n}>()\n\n/** Grab the examples for the given content type */\nconst requestBodyExamples = computed(() => {\n const content = getResolvedRef(operation.requestBody)?.content ?? {}\n const contentType = selectedContentType || Object.keys(content)[0]\n if (!contentType) return {}\n\n const examples = content[contentType]?.examples ?? {}\n\n return examples\n})\n\n/**\n * The example key actually shown for this operation.\n *\n * `selectedExample` is the document-wide selection that syncs across operations. We honor it only\n * when this operation actually defines that key, otherwise we keep the local example: a selection\n * on one operation should never blank out an operation that does not share the same example.\n */\nconst localExampleKey = ref('')\n\n/** Resolve the key to display, preferring the document-wide selection when this operation has it */\nconst resolveExampleKey = (preferred: string | undefined): string => {\n const keys = Object.keys(requestBodyExamples.value)\n if (preferred && keys.includes(preferred)) {\n return preferred\n }\n // Keep the current local example when it is still valid, otherwise fall back to the first one\n if (localExampleKey.value && keys.includes(localExampleKey.value)) {\n return localExampleKey.value\n }\n return keys[0] ?? ''\n}\n\n// Set the initial example from the document-wide selection, falling back to the first example\nonBeforeMount(() => {\n localExampleKey.value = resolveExampleKey(selectedExample)\n})\n\n// Follow the document-wide selection when it changes and this operation has that example\nwatch(\n () => selectedExample,\n (preferred) => {\n localExampleKey.value = resolveExampleKey(preferred)\n },\n)\n\n/** Reset the selected example key if the content type changes and the new content type doesn't have the previously selected example */\nwatch(\n () => selectedContentType,\n () => {\n if (\n !Object.keys(requestBodyExamples.value).includes(localExampleKey.value)\n ) {\n // Re-resolve so the new content type still follows the document-wide selection when it has\n // that key, instead of always snapping back to the first example\n localExampleKey.value = resolveExampleKey(selectedExample)\n }\n },\n)\n\n// Keep the parent informed of the resolved key so a test-request button rendered outside this\n// component (e.g. the classic layout header) opens the client with the example the snippet shows\nwatchEffect(() => {\n emit('update:exampleKey', localExampleKey.value)\n})\n\n/** Select an example locally and sync the choice across the document */\nconst selectExample = (key: string) => {\n localExampleKey.value = key\n eventBus.emit('workspace:update:selected-example', key)\n}\n\n/** Grab any custom code samples from the operation */\nconst customCodeSamples = computed(() => getCustomCodeSamples(operation))\n\n/** Merge custom code samples with the client options */\nconst clients = computed(() =>\n getClients(\n customCodeSamples.value.samples,\n clientOptions,\n customCodeSamples.value.label,\n ),\n)\n\n/** Total number of available clients across all option groups */\nconst clientCount = computed(() =>\n clients.value.reduce((total, group) => total + group.options.length, 0),\n)\n\n/** The locally selected client which would include code samples from this operation only */\nconst localSelectedClient = ref<ClientOption | CustomClientOption | undefined>(\n findClient(clients.value, selectedClient),\n)\n\n/**\n * Re-resolve the local client whenever the global selection or the available\n * clients change. Watching `clients` matters when navigating between operations:\n * the stored id stays the same, but the matching option (e.g. a custom sample)\n * differs per operation, so without this the snippet could go stale.\n */\nwatch([() => selectedClient, clients], ([newClient]) => {\n const client = findClient(clients.value, newClient)\n if (client) {\n localSelectedClient.value = client\n }\n})\n\nconst elem = ref<ComponentPublicInstance | null>(null)\nconst visible = useExampleVisibility(elem)\nconst externalExamples = useExternalExamples(\n () =>\n getOperationExamples(operation, localExampleKey.value, selectedContentType),\n () => visible.value,\n)\nconst resolvedOperation = computed(() =>\n resolveOperationExamples(\n operation,\n localExampleKey.value,\n selectedContentType,\n externalExamples.resolve,\n ),\n)\n\n/** Keep the picker available because it also selects the example opened by Test Request. */\nconst showExamplePicker = computed(\n () => Object.keys(requestBodyExamples.value).length > 1,\n)\n\n/** Generate HAR data for webhook requests */\nconst webhookHar = computed(() => {\n if (!isWebhook) return null\n\n try {\n return operationToHar({\n operation: resolvedOperation.value,\n method,\n path,\n example: localExampleKey.value,\n requestBodyCompositionSelection,\n // Only required parameters are shown in code examples; optional parameters\n // are omitted unless explicitly enabled via `x-disabled: false`.\n defaultDisabledParameters: true,\n })\n } catch (error) {\n console.error('[webhookHar]', error)\n return null\n }\n})\n\n/** Generate the code snippet for the selected example */\nconst generatedCode = computed<string | null>(() => {\n if (isWebhook) {\n return webhookHar.value?.postData?.text ?? ''\n }\n\n return generateCodeSnippet({\n // Only required parameters are shown in code examples; optional parameters\n // are omitted unless explicitly enabled via `x-disabled: false`.\n defaultDisabledParameters: true,\n includeDefaultHeaders: integration === 'client',\n clientId: localSelectedClient.value?.id,\n customCodeSamples: customCodeSamples.value.samples,\n operation: resolvedOperation.value,\n method,\n path,\n contentType: selectedContentType,\n server: selectedServer,\n securitySchemes,\n example: localExampleKey.value,\n globalCookies,\n requestBodyCompositionSelection,\n })\n})\n\n/** The language for the code block, used for syntax highlighting */\nconst codeBlockLanguage = computed(() => {\n if (isWebhook) {\n return webhookLanguage.value\n }\n\n return localSelectedClient.value?.lang\n})\n\n/** Determine the language for webhook content based on MIME type */\nconst webhookLanguage = computed<string>(() => {\n if (!webhookHar.value?.postData) return 'json'\n\n const contentType = webhookHar.value.postData.mimeType\n if (contentType?.includes('json')) return 'json'\n if (contentType?.includes('xml')) return 'xml'\n if (contentType?.includes('yaml') || contentType?.includes('yml'))\n return 'yaml'\n if (contentType?.includes('text/plain')) return 'text'\n\n return 'json'\n})\n\n/** Block secrets from being shown in the code block */\nconst secretCredentials = computed(() => getSecrets(securitySchemes))\n\n/** Set custom example, or update the selected HTTP client globally */\nconst selectClient = (option: ClientOption) => {\n // We need to freeze the ui to prevent scrolling as the clients change\n if (elem.value) {\n const unfreeze = freezeElement(elem.value.$el)\n setTimeout(() => {\n unfreeze()\n }, 300)\n }\n // Update to the local example\n localSelectedClient.value = option\n\n // Sync the selection globally so other operations follow along. Custom samples\n // sync too (keyed by language), so picking e.g. the Python SDK example here\n // shows the Python example on every operation that ships one.\n if (option) {\n eventBus.emit('workspace:update:selected-client', option.id)\n }\n}\n\n// Virtualize the code block if it's too large\n// This prevents the entire app from freezing up if there's a massive example\n// We set a lower threshold here as code examples can get quite large\nconst VIRTUALIZATION_THRESHOLD = 20_000\n\nconst shouldVirtualize = computed(\n () => (generatedCode.value?.length ?? 0) > VIRTUALIZATION_THRESHOLD,\n)\n\nconst id = useId()\n</script>\n<template>\n <ScalarCard\n v-if=\"\n generatedCode === null || generatedCode || externalExamples.pending.value\n \"\n ref=\"elem\"\n class=\"request-card dark-mode\">\n <!-- Header -->\n <ScalarCardHeader class=\"pr-2.5\">\n <span class=\"sr-only\">Request Example for</span>\n <HttpMethod\n as=\"span\"\n class=\"request-method\"\n :method=\"method\" />\n <span\n v-if=\"generateLabel\"\n v-html=\"generateLabel()\" />\n <slot name=\"header\" />\n <!-- Client picker -->\n <template\n v-if=\"!isWebhook && clientCount\"\n #actions>\n <!-- Multiple clients: render a dropdown to switch between them -->\n <ScalarCombobox\n v-if=\"clientCount > 1\"\n class=\"max-h-80\"\n :filterFn=\"filterClientsByQuery\"\n :modelValue=\"localSelectedClient\"\n :options=\"clients\"\n placement=\"bottom-end\"\n teleport\n @update:modelValue=\"selectClient($event as ClientOption)\">\n <ScalarButton\n class=\"text-c-2 hover:text-c-1 flex h-full w-fit gap-1.5 px-0.5 py-0 text-base font-normal\"\n data-testid=\"client-picker\"\n variant=\"ghost\">\n {{ localSelectedClient?.title }}\n <ScalarIconCaretDown\n class=\"ui-open:rotate-180 mt-px size-3 transition-transform duration-100\"\n weight=\"bold\" />\n </ScalarButton>\n </ScalarCombobox>\n <!-- Single client: just show its label, no need for a dropdown -->\n <span\n v-else\n class=\"text-c-2 flex h-full w-fit items-center px-0.5 py-0 text-base font-normal\"\n data-testid=\"client-picker\">\n {{ localSelectedClient?.title }}\n </span>\n </template>\n </ScalarCardHeader>\n\n <!-- Code snippet -->\n <ScalarCardSection class=\"request-editor-section custom-scroll p-0\">\n <div\n v-if=\"externalExamples.pending.value\"\n class=\"text-c-2 p-4\"\n role=\"status\">\n <template v-if=\"externalExamples.failed.value\">\n Could not load this example.\n <ScalarButton\n size=\"sm\"\n variant=\"ghost\"\n @click=\"externalExamples.retry\">\n Retry\n </ScalarButton>\n </template>\n <template v-else>Loading example…</template>\n </div>\n <div\n v-else-if=\"generatedCode === null\"\n class=\"text-c-2 p-4\"\n role=\"status\">\n {{ codeSampleUnavailable }}\n </div>\n <div\n v-else\n :id=\"`${id}-example`\"\n class=\"code-snippet\">\n <ScalarCodeBlock\n v-if=\"!shouldVirtualize\"\n class=\"bg-b-2 h-full\"\n :content=\"generatedCode\"\n :hideCredentials=\"secretCredentials\"\n :lang=\"codeBlockLanguage\"\n lineNumbers />\n <ScalarVirtualText\n v-else\n containerClass=\"custom-scroll scalar-code-block border rounded-b flex flex-1 max-h-screen\"\n contentClass=\"language-plaintext whitespace-pre font-code text-base p-2\"\n :lineHeight=\"20\"\n :text=\"generatedCode\" />\n </div>\n </ScalarCardSection>\n\n <!-- Footer -->\n <ScalarCardFooter\n v-if=\"showExamplePicker || $slots.footer\"\n class=\"request-card-footer bg-b-3\">\n <!-- Example picker -->\n <div\n v-if=\"showExamplePicker\"\n class=\"request-card-footer-addon\">\n <template v-if=\"Object.keys(requestBodyExamples).length\">\n <ExamplePicker\n :examples=\"requestBodyExamples\"\n :modelValue=\"localExampleKey\"\n @update:modelValue=\"selectExample\" />\n </template>\n </div>\n\n <!-- Footer -->\n <slot\n :exampleName=\"localExampleKey\"\n name=\"footer\" />\n </ScalarCardFooter>\n </ScalarCard>\n\n <!-- Fallback card with just method and path in the case of no examples -->\n <ScalarCard\n v-else-if=\"fallback\"\n class=\"request-card dark-mode\">\n <ScalarCardSection class=\"request-card-simple\">\n <div class=\"request-header\">\n <HttpMethod\n as=\"span\"\n class=\"request-method\"\n :method=\"method\" />\n <slot name=\"header\" />\n </div>\n <slot\n :exampleName=\"localExampleKey\"\n name=\"footer\" />\n </ScalarCardSection>\n </ScalarCard>\n</template>\n<style scoped>\n.request-card {\n color: var(--scalar-color-1);\n font-size: var(--scalar-font-size-3);\n}\n.request-method {\n font-family: var(--scalar-font-code);\n margin-right: 6px;\n}\n.request-card-footer {\n display: flex;\n justify-content: flex-end;\n padding: 6px;\n flex-shrink: 0;\n position: relative;\n}\n.request-card-footer-addon {\n display: flex;\n align-items: center;\n\n flex: 1;\n min-width: 0;\n}\n.request-editor-section {\n display: flex;\n flex: 1;\n}\n.request-card-simple {\n display: flex;\n align-items: center;\n justify-content: space-between;\n\n padding: 8px 8px 8px 12px;\n\n font-size: var(--scalar-small);\n}\n.code-snippet {\n display: flex;\n flex-direction: column;\n width: 100%;\n}\n</style>\n"],"mappings":"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"}
|