@scalar/api-client 2.39.0 → 2.39.2
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 +15 -0
- package/dist/hooks/useClientConfig.d.ts +18 -0
- package/dist/hooks/useClientConfig.d.ts.map +1 -1
- package/dist/style.css +23 -28
- package/dist/v2/blocks/operation-block/OperationBlock.vue.d.ts +2 -0
- package/dist/v2/blocks/operation-block/OperationBlock.vue.d.ts.map +1 -1
- package/dist/v2/blocks/operation-block/OperationBlock.vue.js.map +1 -1
- package/dist/v2/blocks/operation-block/OperationBlock.vue.script.js +6 -2
- package/dist/v2/blocks/operation-block/OperationBlock.vue.script.js.map +1 -1
- package/dist/v2/blocks/operation-block/helpers/build-request-body.d.ts +3 -1
- package/dist/v2/blocks/operation-block/helpers/build-request-body.d.ts.map +1 -1
- package/dist/v2/blocks/operation-block/helpers/build-request-body.js +2 -2
- package/dist/v2/blocks/operation-block/helpers/build-request-body.js.map +1 -1
- package/dist/v2/blocks/operation-block/helpers/build-request.d.ts +3 -1
- package/dist/v2/blocks/operation-block/helpers/build-request.d.ts.map +1 -1
- package/dist/v2/blocks/operation-block/helpers/build-request.js +2 -2
- package/dist/v2/blocks/operation-block/helpers/build-request.js.map +1 -1
- package/dist/v2/blocks/operation-code-sample/components/OperationCodeSample.vue.d.ts +5 -0
- package/dist/v2/blocks/operation-code-sample/components/OperationCodeSample.vue.d.ts.map +1 -1
- package/dist/v2/blocks/operation-code-sample/components/OperationCodeSample.vue.js +1 -1
- package/dist/v2/blocks/operation-code-sample/components/OperationCodeSample.vue.js.map +1 -1
- package/dist/v2/blocks/operation-code-sample/components/OperationCodeSample.vue.script.js +6 -3
- package/dist/v2/blocks/operation-code-sample/components/OperationCodeSample.vue.script.js.map +1 -1
- package/dist/v2/blocks/operation-code-sample/helpers/generate-code-snippet.d.ts +3 -1
- package/dist/v2/blocks/operation-code-sample/helpers/generate-code-snippet.d.ts.map +1 -1
- package/dist/v2/blocks/operation-code-sample/helpers/generate-code-snippet.js +3 -2
- package/dist/v2/blocks/operation-code-sample/helpers/generate-code-snippet.js.map +1 -1
- package/dist/v2/blocks/operation-code-sample/helpers/get-example-from-schema.d.ts +5 -1
- package/dist/v2/blocks/operation-code-sample/helpers/get-example-from-schema.d.ts.map +1 -1
- package/dist/v2/blocks/operation-code-sample/helpers/get-example-from-schema.js +51 -25
- package/dist/v2/blocks/operation-code-sample/helpers/get-example-from-schema.js.map +1 -1
- package/dist/v2/blocks/operation-code-sample/helpers/operation-to-har/operation-to-har.d.ts +6 -1
- package/dist/v2/blocks/operation-code-sample/helpers/operation-to-har/operation-to-har.d.ts.map +1 -1
- package/dist/v2/blocks/operation-code-sample/helpers/operation-to-har/operation-to-har.js +3 -2
- package/dist/v2/blocks/operation-code-sample/helpers/operation-to-har/operation-to-har.js.map +1 -1
- package/dist/v2/blocks/operation-code-sample/helpers/operation-to-har/process-body.d.ts +2 -2
- package/dist/v2/blocks/operation-code-sample/helpers/operation-to-har/process-body.d.ts.map +1 -1
- package/dist/v2/blocks/operation-code-sample/helpers/operation-to-har/process-body.js +5 -3
- package/dist/v2/blocks/operation-code-sample/helpers/operation-to-har/process-body.js.map +1 -1
- package/dist/v2/blocks/request-block/RequestBlock.vue.d.ts +1 -0
- package/dist/v2/blocks/request-block/RequestBlock.vue.d.ts.map +1 -1
- package/dist/v2/blocks/request-block/RequestBlock.vue.js +1 -1
- package/dist/v2/blocks/request-block/RequestBlock.vue.js.map +1 -1
- package/dist/v2/blocks/request-block/RequestBlock.vue.script.js +4 -1
- package/dist/v2/blocks/request-block/RequestBlock.vue.script.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestBody.vue.d.ts +2 -0
- package/dist/v2/blocks/request-block/components/RequestBody.vue.d.ts.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestBody.vue.js +1 -1
- package/dist/v2/blocks/request-block/components/RequestBody.vue.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestBody.vue.script.js +3 -2
- package/dist/v2/blocks/request-block/components/RequestBody.vue.script.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestCodeSnippet.vue.script.js +2 -1
- package/dist/v2/blocks/request-block/components/RequestCodeSnippet.vue.script.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestTableTooltip.vue.d.ts.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestTableTooltip.vue.js +1 -3
- package/dist/v2/blocks/request-block/components/RequestTableTooltip.vue.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestTableTooltip.vue.script.js +2 -3
- package/dist/v2/blocks/request-block/components/RequestTableTooltip.vue.script.js.map +1 -1
- package/dist/v2/blocks/request-block/helpers/get-form-body-rows.d.ts.map +1 -1
- package/dist/v2/blocks/request-block/helpers/get-form-body-rows.js +6 -1
- package/dist/v2/blocks/request-block/helpers/get-form-body-rows.js.map +1 -1
- package/dist/v2/blocks/request-block/helpers/get-request-body-example.d.ts +1 -1
- package/dist/v2/blocks/request-block/helpers/get-request-body-example.d.ts.map +1 -1
- package/dist/v2/blocks/request-block/helpers/get-request-body-example.js +6 -2
- package/dist/v2/blocks/request-block/helpers/get-request-body-example.js.map +1 -1
- package/dist/v2/constants.js +1 -1
- package/dist/v2/features/app/helpers/routes.d.ts +2 -0
- package/dist/v2/features/app/helpers/routes.d.ts.map +1 -1
- package/dist/v2/features/collection/DocumentCollection.vue.d.ts.map +1 -1
- package/dist/v2/features/collection/DocumentCollection.vue.js.map +1 -1
- package/dist/v2/features/collection/DocumentCollection.vue.script.js +71 -48
- package/dist/v2/features/collection/DocumentCollection.vue.script.js.map +1 -1
- package/dist/v2/features/modal/Modal.vue.d.ts +3 -1
- package/dist/v2/features/modal/Modal.vue.d.ts.map +1 -1
- package/dist/v2/features/modal/Modal.vue.js.map +1 -1
- package/dist/v2/features/modal/Modal.vue.script.js +4 -0
- package/dist/v2/features/modal/Modal.vue.script.js.map +1 -1
- package/dist/v2/features/modal/helpers/create-api-client-modal.d.ts.map +1 -1
- package/dist/v2/features/modal/helpers/create-api-client-modal.js +3 -0
- package/dist/v2/features/modal/helpers/create-api-client-modal.js.map +1 -1
- package/dist/v2/features/modal/modal-events.d.ts +2 -1
- package/dist/v2/features/modal/modal-events.d.ts.map +1 -1
- package/dist/v2/features/modal/modal-events.js +3 -1
- package/dist/v2/features/modal/modal-events.js.map +1 -1
- package/dist/v2/features/operation/Operation.vue.d.ts +4 -0
- package/dist/v2/features/operation/Operation.vue.d.ts.map +1 -1
- package/dist/v2/features/operation/Operation.vue.js.map +1 -1
- package/dist/v2/features/operation/Operation.vue.script.js +4 -1
- package/dist/v2/features/operation/Operation.vue.script.js.map +1 -1
- package/dist/v2/helpers/download-document.d.ts +2 -0
- package/dist/v2/helpers/download-document.d.ts.map +1 -0
- package/dist/v2/helpers/download-document.js +42 -0
- package/dist/v2/helpers/download-document.js.map +1 -0
- package/dist/v2/posthog.d.ts.map +1 -1
- package/dist/v2/posthog.js +1 -0
- package/dist/v2/posthog.js.map +1 -1
- package/dist/views/Request/ResponseSection/ResponseEmpty.vue.script.js +1 -1
- package/package.json +13 -13
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @scalar/api-client
|
|
2
2
|
|
|
3
|
+
## 2.39.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#8599](https://github.com/scalar/scalar/pull/8599): fix(api-client): truncate long table tooltip content
|
|
8
|
+
- [#8590](https://github.com/scalar/scalar/pull/8590): Group analytic events by api-client product
|
|
9
|
+
- [#8601](https://github.com/scalar/scalar/pull/8601): fix: stringify nested form body example values for table rows
|
|
10
|
+
|
|
11
|
+
## 2.39.1
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- [#8577](https://github.com/scalar/scalar/pull/8577): feat: support document download
|
|
16
|
+
- [#8473](https://github.com/scalar/scalar/pull/8473): fix: request body code samples when switching anyOf or oneOf schemas
|
|
17
|
+
|
|
3
18
|
## 2.39.0
|
|
4
19
|
|
|
5
20
|
### Minor Changes
|
|
@@ -11,6 +11,12 @@ export declare const useClientConfig: () => Ref<{
|
|
|
11
11
|
theme: "default" | "alternate" | "moon" | "purple" | "solarized" | "bluePlanet" | "deepSpace" | "saturn" | "kepler" | "elysiajs" | "fastify" | "mars" | "laserwave" | "none";
|
|
12
12
|
persistAuth: boolean;
|
|
13
13
|
telemetry: boolean;
|
|
14
|
+
externalUrls: {
|
|
15
|
+
dashboardUrl: string;
|
|
16
|
+
registryUrl: string;
|
|
17
|
+
proxyUrl: string;
|
|
18
|
+
apiBaseUrl: string;
|
|
19
|
+
};
|
|
14
20
|
authentication?: any;
|
|
15
21
|
baseServerURL?: string | undefined;
|
|
16
22
|
proxyUrl?: string | undefined;
|
|
@@ -65,6 +71,12 @@ export declare const useClientConfig: () => Ref<{
|
|
|
65
71
|
theme: "default" | "alternate" | "moon" | "purple" | "solarized" | "bluePlanet" | "deepSpace" | "saturn" | "kepler" | "elysiajs" | "fastify" | "mars" | "laserwave" | "none";
|
|
66
72
|
persistAuth: boolean;
|
|
67
73
|
telemetry: boolean;
|
|
74
|
+
externalUrls: {
|
|
75
|
+
dashboardUrl: string;
|
|
76
|
+
registryUrl: string;
|
|
77
|
+
proxyUrl: string;
|
|
78
|
+
apiBaseUrl: string;
|
|
79
|
+
};
|
|
68
80
|
authentication?: any;
|
|
69
81
|
baseServerURL?: string | undefined;
|
|
70
82
|
proxyUrl?: string | undefined;
|
|
@@ -119,6 +131,12 @@ export declare const useClientConfig: () => Ref<{
|
|
|
119
131
|
theme: "default" | "alternate" | "moon" | "purple" | "solarized" | "bluePlanet" | "deepSpace" | "saturn" | "kepler" | "elysiajs" | "fastify" | "mars" | "laserwave" | "none";
|
|
120
132
|
persistAuth: boolean;
|
|
121
133
|
telemetry: boolean;
|
|
134
|
+
externalUrls: {
|
|
135
|
+
dashboardUrl: string;
|
|
136
|
+
registryUrl: string;
|
|
137
|
+
proxyUrl: string;
|
|
138
|
+
apiBaseUrl: string;
|
|
139
|
+
};
|
|
122
140
|
authentication?: any;
|
|
123
141
|
baseServerURL?: string | undefined;
|
|
124
142
|
proxyUrl?: string | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useClientConfig.d.ts","sourceRoot":"","sources":["../../src/hooks/useClientConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,sBAAsB,EAAgC,MAAM,6BAA6B,CAAA;AACvG,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,GAAG,EAAe,MAAM,KAAK,CAAA;AAE9D,eAAO,MAAM,2BAA2B,EAAe,YAAY,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC,CAAA;AAEhG,0DAA0D;AAC1D,eAAO,MAAM,eAAe
|
|
1
|
+
{"version":3,"file":"useClientConfig.d.ts","sourceRoot":"","sources":["../../src/hooks/useClientConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,sBAAsB,EAAgC,MAAM,6BAA6B,CAAA;AACvG,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,GAAG,EAAe,MAAM,KAAK,CAAA;AAE9D,eAAO,MAAM,2BAA2B,EAAe,YAAY,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC,CAAA;AAEhG,0DAA0D;AAC1D,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAAyF,CAAA"}
|
package/dist/style.css
CHANGED
|
@@ -5666,10 +5666,6 @@ input[data-v-c1a50a6e]::placeholder {
|
|
|
5666
5666
|
max-width: 14px;
|
|
5667
5667
|
}
|
|
5668
5668
|
|
|
5669
|
-
.scalar-app .max-w-\[16rem\] {
|
|
5670
|
-
max-width: 16rem;
|
|
5671
|
-
}
|
|
5672
|
-
|
|
5673
5669
|
.scalar-app .max-w-\[37px\] {
|
|
5674
5670
|
max-width: 37px;
|
|
5675
5671
|
}
|
|
@@ -7383,6 +7379,10 @@ input[data-v-c1a50a6e]::placeholder {
|
|
|
7383
7379
|
height: 32px;
|
|
7384
7380
|
}
|
|
7385
7381
|
|
|
7382
|
+
:is(.scalar-app .\*\:max-w-64 > *) {
|
|
7383
|
+
max-width: 256px;
|
|
7384
|
+
}
|
|
7385
|
+
|
|
7386
7386
|
:is(.scalar-app .\*\:cursor-pointer > *) {
|
|
7387
7387
|
cursor: pointer;
|
|
7388
7388
|
}
|
|
@@ -7661,6 +7661,11 @@ input[data-v-c1a50a6e]::placeholder {
|
|
|
7661
7661
|
background-color: var(--scalar-border-color);
|
|
7662
7662
|
}
|
|
7663
7663
|
|
|
7664
|
+
:is(.scalar-app .\*\:not-first\:before\:content-\[\'_·_\'\] > *):not(:first-child):before {
|
|
7665
|
+
--tw-content: " · ";
|
|
7666
|
+
content: var(--tw-content);
|
|
7667
|
+
}
|
|
7668
|
+
|
|
7664
7669
|
.scalar-app .after\:content-\[\'\:\'\]:after {
|
|
7665
7670
|
--tw-content: ":";
|
|
7666
7671
|
content: var(--tw-content);
|
|
@@ -8857,16 +8862,6 @@ input[data-v-c1a50a6e]::placeholder {
|
|
|
8857
8862
|
display: none;
|
|
8858
8863
|
}
|
|
8859
8864
|
|
|
8860
|
-
.schema > span[data-v-f2ab7aa3]:not(:first-child)::before {
|
|
8861
|
-
content: '·';
|
|
8862
|
-
display: block;
|
|
8863
|
-
margin: 0 0.5ch;
|
|
8864
|
-
}
|
|
8865
|
-
.schema > span[data-v-f2ab7aa3] {
|
|
8866
|
-
display: flex;
|
|
8867
|
-
white-space: nowrap;
|
|
8868
|
-
}
|
|
8869
|
-
|
|
8870
8865
|
[data-v-36811e28] .cm-editor {
|
|
8871
8866
|
padding: 0;
|
|
8872
8867
|
}
|
|
@@ -8901,7 +8896,7 @@ input[data-v-c1a50a6e]::placeholder {
|
|
|
8901
8896
|
);
|
|
8902
8897
|
}
|
|
8903
8898
|
|
|
8904
|
-
[data-v-
|
|
8899
|
+
[data-v-2f50e5b7] .cm-content {
|
|
8905
8900
|
font-size: var(--scalar-small);
|
|
8906
8901
|
}
|
|
8907
8902
|
|
|
@@ -8963,20 +8958,20 @@ input[data-v-3157c3c7]::placeholder {
|
|
|
8963
8958
|
-moz-text-security: disc;
|
|
8964
8959
|
}
|
|
8965
8960
|
|
|
8966
|
-
.request-section-content[data-v-
|
|
8961
|
+
.request-section-content[data-v-e0c182d2] {
|
|
8967
8962
|
--scalar-border-width: 0.5px;
|
|
8968
8963
|
}
|
|
8969
|
-
.request-section-content-filter[data-v-
|
|
8964
|
+
.request-section-content-filter[data-v-e0c182d2] {
|
|
8970
8965
|
box-shadow: 0 -10px 0 10px var(--scalar-background-1);
|
|
8971
8966
|
}
|
|
8972
|
-
.request-item:focus-within .request-meta-buttons[data-v-
|
|
8967
|
+
.request-item:focus-within .request-meta-buttons[data-v-e0c182d2] {
|
|
8973
8968
|
opacity: 1;
|
|
8974
8969
|
}
|
|
8975
|
-
.group-hover-input[data-v-
|
|
8970
|
+
.group-hover-input[data-v-e0c182d2] {
|
|
8976
8971
|
border-width: var(--scalar-border-width);
|
|
8977
8972
|
border-color: transparent;
|
|
8978
8973
|
}
|
|
8979
|
-
.group:hover .group-hover-input[data-v-
|
|
8974
|
+
.group:hover .group-hover-input[data-v-e0c182d2] {
|
|
8980
8975
|
background: color-mix(
|
|
8981
8976
|
in srgb,
|
|
8982
8977
|
var(--scalar-background-1),
|
|
@@ -8984,7 +8979,7 @@ input[data-v-3157c3c7]::placeholder {
|
|
|
8984
8979
|
);
|
|
8985
8980
|
border-color: var(--scalar-border-color);
|
|
8986
8981
|
}
|
|
8987
|
-
.group-hover-input[data-v-
|
|
8982
|
+
.group-hover-input[data-v-e0c182d2]:focus {
|
|
8988
8983
|
background: transparent !important;
|
|
8989
8984
|
border-color: var(--scalar-border-color) !important;
|
|
8990
8985
|
}
|
|
@@ -9112,33 +9107,33 @@ to {
|
|
|
9112
9107
|
}
|
|
9113
9108
|
}
|
|
9114
9109
|
|
|
9115
|
-
.request-card[data-v-
|
|
9110
|
+
.request-card[data-v-f52db2cc] {
|
|
9116
9111
|
font-size: var(--scalar-font-size-3);
|
|
9117
9112
|
}
|
|
9118
|
-
.request-method[data-v-
|
|
9113
|
+
.request-method[data-v-f52db2cc] {
|
|
9119
9114
|
font-family: var(--scalar-font-code);
|
|
9120
9115
|
text-transform: uppercase;
|
|
9121
9116
|
margin-right: 6px;
|
|
9122
9117
|
}
|
|
9123
|
-
.request-card-footer[data-v-
|
|
9118
|
+
.request-card-footer[data-v-f52db2cc] {
|
|
9124
9119
|
display: flex;
|
|
9125
9120
|
justify-content: flex-end;
|
|
9126
9121
|
padding: 6px;
|
|
9127
9122
|
flex-shrink: 0;
|
|
9128
9123
|
position: relative;
|
|
9129
9124
|
}
|
|
9130
|
-
.request-card-footer-addon[data-v-
|
|
9125
|
+
.request-card-footer-addon[data-v-f52db2cc] {
|
|
9131
9126
|
display: flex;
|
|
9132
9127
|
align-items: center;
|
|
9133
9128
|
|
|
9134
9129
|
flex: 1;
|
|
9135
9130
|
min-width: 0;
|
|
9136
9131
|
}
|
|
9137
|
-
.request-editor-section[data-v-
|
|
9132
|
+
.request-editor-section[data-v-f52db2cc] {
|
|
9138
9133
|
display: flex;
|
|
9139
9134
|
flex: 1;
|
|
9140
9135
|
}
|
|
9141
|
-
.request-card-simple[data-v-
|
|
9136
|
+
.request-card-simple[data-v-f52db2cc] {
|
|
9142
9137
|
display: flex;
|
|
9143
9138
|
align-items: center;
|
|
9144
9139
|
justify-content: space-between;
|
|
@@ -9147,7 +9142,7 @@ to {
|
|
|
9147
9142
|
|
|
9148
9143
|
font-size: var(--scalar-small);
|
|
9149
9144
|
}
|
|
9150
|
-
.code-snippet[data-v-
|
|
9145
|
+
.code-snippet[data-v-f52db2cc] {
|
|
9151
9146
|
display: flex;
|
|
9152
9147
|
flex-direction: column;
|
|
9153
9148
|
width: 100%;
|
|
@@ -83,6 +83,8 @@ export type OperationBlockProps = {
|
|
|
83
83
|
environment: XScalarEnvironment;
|
|
84
84
|
/** The proxy URL for sending requests */
|
|
85
85
|
proxyUrl: string;
|
|
86
|
+
/** Selected anyOf/oneOf request-body variants keyed by schema path */
|
|
87
|
+
requestBodyCompositionSelection?: Record<string, number>;
|
|
86
88
|
};
|
|
87
89
|
declare const __VLS_export: import("vue").DefineComponent<OperationBlockProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<OperationBlockProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
88
90
|
//# sourceMappingURL=OperationBlock.vue.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OperationBlock.vue.d.ts","sourceRoot":"","sources":["../../../../src/v2/blocks/operation-block/OperationBlock.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"OperationBlock.vue.d.ts","sourceRoot":"","sources":["../../../../src/v2/blocks/operation-block/OperationBlock.vue"],"names":[],"mappings":"AA6bA,OAAO,KAAK,EAAE,UAAU,IAAI,cAAc,EAAE,MAAM,mCAAmC,CAAA;AAErF,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAC7D,OAAO,EAEL,KAAK,gBAAgB,EACtB,MAAM,wBAAwB,CAAA;AAE/B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AACpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAA;AAC7E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iDAAiD,CAAA;AACnF,OAAO,KAAK,EACV,QAAQ,EACR,UAAU,EACV,iBAAiB,EAClB,MAAM,gCAAgC,CAAA;AACvC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2EAA2E,CAAA;AACnH,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EACb,MAAM,8DAA8D,CAAA;AACrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uDAAuD,CAAA;AAK5F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAe3C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4CAA4C,CAAA;AAGtF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,+DAA+D,CAAA;AAS1G;;;;;;;;;;;;GAYG;wBACkB,OAAO,YAAY;AAAxC,wBAAyC;AAMzC,MAAM,MAAM,mBAAmB,GAAG;IAChC,gBAAgB;IAChB,QAAQ,EAAE,iBAAiB,CAAA;IAC3B,gCAAgC;IAChC,gBAAgB,EAAE,eAAe,CAAC,UAAU,CAAC,CAAA;IAC7C,iCAAiC;IACjC,wBAAwB,EAAE,gBAAgB,GAAG,SAAS,CAAA;IACtD,0BAA0B;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB,iCAAiC;IACjC,aAAa,EAAE,oBAAoB,EAAE,CAAA;IACrC,2BAA2B;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,6BAA6B;IAC7B,MAAM,EAAE,cAAc,CAAA;IACtB,mBAAmB;IACnB,WAAW,EAAE,gBAAgB,CAAA;IAC7B,oCAAoC;IACpC,OAAO,CAAC,EAAE,YAAY,EAAE,CAAA;IACxB,oBAAoB;IACpB,MAAM,EAAE,YAAY,CAAA;IACpB,gCAAgC;IAChC,MAAM,EAAE,YAAY,GAAG,IAAI,CAAA;IAC3B,gCAAgC;IAChC,cAAc,EAAE,cAAc,CAAC,WAAW,CAAC,CAAC,yBAAyB,CAAC,CAAA;IACtE,mDAAmD;IACnD,OAAO,EAAE,YAAY,EAAE,CAAA;IACvB,sCAAsC;IACtC,UAAU,EAAE,UAAU,CAAA;IACtB,4CAA4C;IAC5C,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,0BAA0B;IAC1B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,mEAAmE;IACnE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,oBAAoB;IACpB,MAAM,CAAC,EAAE,SAAS,GAAG,eAAe,CAAA;IACpC,uBAAuB;IACvB,SAAS,EAAE,eAAe,CAAA;IAC1B,kCAAkC;IAClC,yBAAyB,EAAE,gBAAgB,GAAG,SAAS,CAAA;IACvD,+DAA+D;IAC/D,UAAU,EAAE,MAAM,CAAA;IAClB,2CAA2C;IAC3C,QAAQ,EAAE,QAAQ,CAAA;IAClB,wCAAwC;IACxC,eAAe,EAAE,qBAAqB,CAAA;IACtC,qBAAqB;IACrB,OAAO,EAAE,YAAY,EAAE,CAAA;IACvB,uBAAuB;IACvB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB,qCAAqC;IACrC,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,8CAA8C;IAC9C,WAAW,EAAE,kBAAkB,CAAA;IAC/B,yCAAyC;IACzC,QAAQ,EAAE,MAAM,CAAA;IAChB,sEAAsE;IACtE,+BAA+B,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACzD,CAAA;AACD,QAAA,MAAM,YAAY,kTA8bd,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OperationBlock.vue.js","names":[],"sources":["../../../../src/v2/blocks/operation-block/OperationBlock.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * OperationBlock\n *\n * Orchestrates the operation view by wiring together the Header, OperationBlock,\n * and ResponseBlock. Forwards user interactions to the workspace event bus and\n * passes through configuration such as auth, servers, plugins, and environment.\n * This component keeps the Operation page lean by centralizing event emission\n * and prop wiring between the blocks.\n *\n * Notable behavior:\n * - Uses operation['x-scalar-method'] and operation['x-scalar-path'] to provide\n * draft overrides for the UI when present.\n */\nexport default {\n name: 'OperationBlock',\n}\n\nexport type OperationBlockProps = {\n /** Event bus */\n eventBus: WorkspaceEventBus\n /** Document defined security */\n documentSecurity: OpenApiDocument['security']\n /** Document selected security */\n documentSelectedSecurity: SelectedSecurity | undefined\n /** Application version */\n appVersion: string\n /** Workspace/document cookies */\n globalCookies: ExtendedScalarCookie[]\n /** Current request path */\n path: string\n /** Current request method */\n method: HttpMethodType\n /** HTTP clients */\n httpClients: AvailableClients\n /** The history for the operation */\n history?: HistoryEntry[]\n /** Client layout */\n layout: ClientLayout\n /** Currently selected server */\n server: ServerObject | null\n /** Currently selected client */\n selectedClient: WorkspaceStore['workspace']['x-scalar-default-client']\n /** Server list available for operation/document */\n servers: ServerObject[]\n /** Meta information for the server */\n serverMeta: ServerMeta\n /** Hides the client button on the header */\n hideClientButton?: boolean\n /** Client integration */\n integration?: string | null\n /** Openapi document url for `modal` mode to open the client app */\n documentUrl?: string\n /** Client source */\n source?: 'gitbook' | 'api-reference'\n /** Operation object */\n operation: OperationObject\n /** Operation selected security */\n operationSelectedSecurity: SelectedSecurity | undefined\n /** Currently selected example key for the current operation */\n exampleKey: string\n /** Meta information for the auth update */\n authMeta: AuthMeta\n /** Document defined security schemes */\n securitySchemes: MergedSecuritySchemes\n /** Client plugins */\n plugins: ClientPlugin[]\n /** Environment list */\n environments?: string[]\n /** Currently selected environment */\n activeEnvironment?: string\n /** For environment variables in the inputs */\n environment: XScalarEnvironment\n /** The proxy URL for sending requests */\n proxyUrl: string\n}\n</script>\n<script setup lang=\"ts\">\nimport type { HttpMethod as HttpMethodType } from '@scalar/helpers/http/http-methods'\nimport type { ResponseInstance } from '@scalar/oas-utils/entities/spec'\nimport { type ClientPlugin } from '@scalar/oas-utils/helpers'\nimport {\n AVAILABLE_CLIENTS,\n type AvailableClients,\n} from '@scalar/types/snippetz'\nimport { useToasts } from '@scalar/use-toasts'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\nimport type { SelectedSecurity } from '@scalar/workspace-store/entities/auth'\nimport type { HistoryEntry } from '@scalar/workspace-store/entities/history/schema'\nimport type {\n AuthMeta,\n ServerMeta,\n WorkspaceEventBus,\n} from '@scalar/workspace-store/events'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport type {\n OpenApiDocument,\n ServerObject,\n} from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport type { OperationObject } from '@scalar/workspace-store/schemas/v3.1/strict/operation'\nimport { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'\n\nimport ViewLayout from '@/components/ViewLayout/ViewLayout.vue'\nimport ViewLayoutContent from '@/components/ViewLayout/ViewLayoutContent.vue'\nimport type { ClientLayout } from '@/hooks'\nimport { ERRORS } from '@/libs/errors'\nimport { buildRequest } from '@/v2/blocks/operation-block/helpers/build-request'\nimport { getSecuritySchemes } from '@/v2/blocks/operation-block/helpers/build-request-security'\nimport { harToFetchRequest } from '@/v2/blocks/operation-block/helpers/har-to-fetch-request'\nimport { harToFetchResponse } from '@/v2/blocks/operation-block/helpers/har-to-fetch-response'\nimport {\n getOperationExampleKey,\n isStreamingResponse,\n responseCache,\n} from '@/v2/blocks/operation-block/helpers/response-cache'\nimport { sendRequest } from '@/v2/blocks/operation-block/helpers/send-request'\nimport { validatePathParameters } from '@/v2/blocks/operation-block/helpers/validate-path-parameters'\nimport { generateClientOptions } from '@/v2/blocks/operation-code-sample'\nimport { RequestBlock } from '@/v2/blocks/request-block'\nimport type { ExtendedScalarCookie } from '@/v2/blocks/request-block/RequestBlock.vue'\nimport { ResponseBlock } from '@/v2/blocks/response-block'\nimport { type History } from '@/v2/blocks/scalar-address-bar-block'\nimport type { MergedSecuritySchemes } from '@/v2/blocks/scalar-auth-selector-block/helpers/merge-security'\nimport {\n getSecurityRequirements,\n getSelectedSecurity,\n} from '@/v2/features/operation'\n\nimport Header from './components/Header.vue'\n\nconst {\n authMeta,\n environment,\n documentSecurity,\n documentSelectedSecurity,\n eventBus,\n exampleKey,\n globalCookies = [],\n hideClientButton,\n httpClients = AVAILABLE_CLIENTS,\n history = [],\n method,\n operation,\n operationSelectedSecurity,\n path,\n plugins = [],\n proxyUrl,\n securitySchemes,\n selectedClient,\n server,\n environments,\n activeEnvironment,\n serverMeta,\n} = defineProps<OperationBlockProps>()\n\n/** Hoist up client generation so it doesn't get re-generated on every operation */\nconst clientOptions = computed(() => generateClientOptions(httpClients))\n\n/** Compute what the security requirements should be for an operation */\nconst securityRequirements = computed(() =>\n getSecurityRequirements(documentSecurity, operation.security),\n)\n\n/** The selected security for the operation or document */\nconst selectedSecurity = computed(() =>\n getSelectedSecurity(\n documentSelectedSecurity,\n operationSelectedSecurity,\n securityRequirements.value,\n securitySchemes,\n ),\n)\n\n/** The above selected requirements in scheme form */\nconst selectedSecuritySchemes = computed(() =>\n getSecuritySchemes(securitySchemes, selectedSecurity.value.selectedSchemes),\n)\n\nconst { toast } = useToasts()\n\n// Refs\nconst abortController = ref<AbortController | null>(null)\nconst response = ref<ResponseInstance | null>(null)\nconst request = ref<Request | null>(null)\n\n/** Cancel the request */\nconst cancelRequest = () => abortController.value?.abort(ERRORS.REQUEST_ABORTED)\n\n/** Execute the current operation example */\nconst handleExecute = async () => {\n const pathValidation = validatePathParameters(\n operation.parameters ?? [],\n exampleKey,\n )\n if (pathValidation.ok === false) {\n toast('Path parameters must have values.', 'error')\n return\n }\n\n const [error, result] = buildRequest({\n environment,\n exampleKey,\n globalCookies,\n method,\n operation,\n path,\n selectedSecuritySchemes: selectedSecuritySchemes.value,\n server,\n proxyUrl,\n })\n\n // Toast the error\n if (error) {\n toast(error.message, 'error')\n return\n }\n\n // Store the abort controller for cancellation\n abortController.value = result.controller\n\n // Stop any previous streaming response\n if (response.value && 'reader' in response.value) {\n response.value.reader.cancel()\n }\n\n // Execute the hooks\n eventBus.emit('hooks:on:request:sent', {\n meta: {\n method,\n path,\n exampleKey,\n },\n })\n\n /** Execute the request */\n const [sendError, sendResult] = await sendRequest({\n isUsingProxy: result.isUsingProxy,\n operation,\n plugins,\n request: result.request,\n })\n\n // Execute the hooks\n eventBus.emit('hooks:on:request:complete', {\n payload: sendResult\n ? {\n response: sendResult.originalResponse,\n request: sendResult.request.clone(),\n duration: sendResult.response.duration,\n timestamp: sendResult.timestamp,\n }\n : undefined,\n meta: {\n method,\n path,\n exampleKey,\n },\n })\n\n // Toast the execute error\n if (sendError) {\n toast(sendError.message, 'error')\n return\n }\n\n // Store the response\n response.value = sendResult.response\n request.value = sendResult.request\n\n // Cache non-streaming responses so they can be restored when navigating back\n if (!isStreamingResponse(sendResult.response)) {\n responseCache.set(getOperationExampleKey(method, path, exampleKey), {\n response: sendResult.response,\n request: sendResult.request,\n })\n }\n}\n\nonMounted(() => {\n eventBus.on('operation:send:request:hotkey', handleExecute)\n eventBus.on('operation:cancel:request', cancelRequest)\n})\nonBeforeUnmount(() => {\n eventBus.off('operation:send:request:hotkey', handleExecute)\n eventBus.off('operation:cancel:request', cancelRequest)\n})\n\nconst operationHistory = computed<History[]>(() =>\n history\n .map((entry) => ({\n method: entry.request.method as HttpMethodType,\n path: entry.request.url,\n duration: entry.time,\n status: entry.response.status,\n }))\n .reverse(),\n)\n\nconst handleSelectHistoryItem = ({ index }: { index: number }) => {\n const transformedIndex = (history.length ?? 0) - index - 1\n const historyItem = history[transformedIndex]\n if (!historyItem) {\n return\n }\n\n const navigate = () =>\n eventBus.emit('ui:navigate', {\n page: 'example',\n method,\n path,\n exampleName: 'draft',\n callback: (status) => {\n // Do not replace the response if the navigation was not successful\n if (status !== 'success') {\n return\n }\n // Reconstruct the response\n const fetchResponse = harToFetchResponse({\n harResponse: historyItem.response,\n url: historyItem.request.url,\n method,\n path,\n duration: historyItem.time,\n })\n\n // Reconstruct the request\n const fetchRequest = harToFetchRequest({\n harRequest: historyItem.request,\n })\n\n // Update the response and request\n response.value = fetchResponse\n request.value = fetchRequest\n },\n })\n\n eventBus.emit('operation:reload:history', {\n meta: {\n path,\n method,\n },\n index: transformedIndex,\n callback: navigate,\n })\n}\n\n/**\n * When the path, method, or example key changes: save current response to\n * cache (so it can be restored when navigating back), then restore from cache\n * for the new operation or clear if no cached response. Response is only\n * cleared on page refresh or when making a new request for that operation.\n */\nwatch(\n [() => path, () => method, () => exampleKey],\n ([newPath, newMethod, newExampleKey]) => {\n const newKey = getOperationExampleKey(newMethod, newPath, newExampleKey)\n const cached = responseCache.get(newKey)\n if (cached) {\n response.value = cached.response\n request.value = cached.request\n } else {\n response.value = null\n request.value = null\n }\n\n // Cancel any in-flight request\n cancelRequest()\n },\n { immediate: true },\n)\n\nonBeforeUnmount(() => {\n // We cancel the request if the component is unmounted\n cancelRequest()\n})\n</script>\n<template>\n <div class=\"bg-b-1 flex h-full flex-col\">\n <div\n class=\"lg:min-h-header flex w-full flex-wrap items-center justify-center p-2 lg:p-0\">\n <!-- Address Bar -->\n <Header\n :activeEnvironment\n :documentUrl\n :environment\n :environments\n :eventBus\n :hideClientButton\n :history=\"operationHistory\"\n :integration\n :layout\n :method\n :path\n :server\n :serverMeta\n :servers\n :source\n @execute=\"handleExecute\"\n @select:history:item=\"handleSelectHistoryItem\" />\n </div>\n\n <ViewLayout class=\"border-t\">\n <ViewLayoutContent class=\"flex-1\">\n <!-- Request Section -->\n <RequestBlock\n :authMeta\n :clientOptions\n :environment\n :eventBus\n :exampleKey\n :globalCookies\n :layout\n :method\n :operation\n :path\n :plugins\n :proxyUrl\n :securityRequirements\n :securitySchemes\n :selectedClient\n :selectedSecurity\n :selectedSecuritySchemes\n :server />\n\n <!-- Response Section -->\n <ResponseBlock\n :appVersion\n :eventBus\n :layout\n :plugins\n :request\n :response\n :totalPerformedRequests=\"operationHistory.length\" />\n </ViewLayoutContent>\n </ViewLayout>\n </div>\n</template>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"OperationBlock.vue.js","names":[],"sources":["../../../../src/v2/blocks/operation-block/OperationBlock.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * OperationBlock\n *\n * Orchestrates the operation view by wiring together the Header, OperationBlock,\n * and ResponseBlock. Forwards user interactions to the workspace event bus and\n * passes through configuration such as auth, servers, plugins, and environment.\n * This component keeps the Operation page lean by centralizing event emission\n * and prop wiring between the blocks.\n *\n * Notable behavior:\n * - Uses operation['x-scalar-method'] and operation['x-scalar-path'] to provide\n * draft overrides for the UI when present.\n */\nexport default {\n name: 'OperationBlock',\n}\n\nexport type OperationBlockProps = {\n /** Event bus */\n eventBus: WorkspaceEventBus\n /** Document defined security */\n documentSecurity: OpenApiDocument['security']\n /** Document selected security */\n documentSelectedSecurity: SelectedSecurity | undefined\n /** Application version */\n appVersion: string\n /** Workspace/document cookies */\n globalCookies: ExtendedScalarCookie[]\n /** Current request path */\n path: string\n /** Current request method */\n method: HttpMethodType\n /** HTTP clients */\n httpClients: AvailableClients\n /** The history for the operation */\n history?: HistoryEntry[]\n /** Client layout */\n layout: ClientLayout\n /** Currently selected server */\n server: ServerObject | null\n /** Currently selected client */\n selectedClient: WorkspaceStore['workspace']['x-scalar-default-client']\n /** Server list available for operation/document */\n servers: ServerObject[]\n /** Meta information for the server */\n serverMeta: ServerMeta\n /** Hides the client button on the header */\n hideClientButton?: boolean\n /** Client integration */\n integration?: string | null\n /** Openapi document url for `modal` mode to open the client app */\n documentUrl?: string\n /** Client source */\n source?: 'gitbook' | 'api-reference'\n /** Operation object */\n operation: OperationObject\n /** Operation selected security */\n operationSelectedSecurity: SelectedSecurity | undefined\n /** Currently selected example key for the current operation */\n exampleKey: string\n /** Meta information for the auth update */\n authMeta: AuthMeta\n /** Document defined security schemes */\n securitySchemes: MergedSecuritySchemes\n /** Client plugins */\n plugins: ClientPlugin[]\n /** Environment list */\n environments?: string[]\n /** Currently selected environment */\n activeEnvironment?: string\n /** For environment variables in the inputs */\n environment: XScalarEnvironment\n /** The proxy URL for sending requests */\n proxyUrl: string\n /** Selected anyOf/oneOf request-body variants keyed by schema path */\n requestBodyCompositionSelection?: Record<string, number>\n}\n</script>\n<script setup lang=\"ts\">\nimport type { HttpMethod as HttpMethodType } from '@scalar/helpers/http/http-methods'\nimport type { ResponseInstance } from '@scalar/oas-utils/entities/spec'\nimport { type ClientPlugin } from '@scalar/oas-utils/helpers'\nimport {\n AVAILABLE_CLIENTS,\n type AvailableClients,\n} from '@scalar/types/snippetz'\nimport { useToasts } from '@scalar/use-toasts'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\nimport type { SelectedSecurity } from '@scalar/workspace-store/entities/auth'\nimport type { HistoryEntry } from '@scalar/workspace-store/entities/history/schema'\nimport type {\n AuthMeta,\n ServerMeta,\n WorkspaceEventBus,\n} from '@scalar/workspace-store/events'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport type {\n OpenApiDocument,\n ServerObject,\n} from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport type { OperationObject } from '@scalar/workspace-store/schemas/v3.1/strict/operation'\nimport { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'\n\nimport ViewLayout from '@/components/ViewLayout/ViewLayout.vue'\nimport ViewLayoutContent from '@/components/ViewLayout/ViewLayoutContent.vue'\nimport type { ClientLayout } from '@/hooks'\nimport { ERRORS } from '@/libs/errors'\nimport { buildRequest } from '@/v2/blocks/operation-block/helpers/build-request'\nimport { getSecuritySchemes } from '@/v2/blocks/operation-block/helpers/build-request-security'\nimport { harToFetchRequest } from '@/v2/blocks/operation-block/helpers/har-to-fetch-request'\nimport { harToFetchResponse } from '@/v2/blocks/operation-block/helpers/har-to-fetch-response'\nimport {\n getOperationExampleKey,\n isStreamingResponse,\n responseCache,\n} from '@/v2/blocks/operation-block/helpers/response-cache'\nimport { sendRequest } from '@/v2/blocks/operation-block/helpers/send-request'\nimport { validatePathParameters } from '@/v2/blocks/operation-block/helpers/validate-path-parameters'\nimport { generateClientOptions } from '@/v2/blocks/operation-code-sample'\nimport { RequestBlock } from '@/v2/blocks/request-block'\nimport type { ExtendedScalarCookie } from '@/v2/blocks/request-block/RequestBlock.vue'\nimport { ResponseBlock } from '@/v2/blocks/response-block'\nimport { type History } from '@/v2/blocks/scalar-address-bar-block'\nimport type { MergedSecuritySchemes } from '@/v2/blocks/scalar-auth-selector-block/helpers/merge-security'\nimport {\n getSecurityRequirements,\n getSelectedSecurity,\n} from '@/v2/features/operation'\n\nimport Header from './components/Header.vue'\n\nconst {\n authMeta,\n environment,\n documentSecurity,\n documentSelectedSecurity,\n eventBus,\n exampleKey,\n globalCookies = [],\n hideClientButton,\n httpClients = AVAILABLE_CLIENTS,\n history = [],\n method,\n operation,\n operationSelectedSecurity,\n path,\n plugins = [],\n proxyUrl,\n requestBodyCompositionSelection,\n securitySchemes,\n selectedClient,\n server,\n environments,\n activeEnvironment,\n serverMeta,\n} = defineProps<OperationBlockProps>()\n\n/** Hoist up client generation so it doesn't get re-generated on every operation */\nconst clientOptions = computed(() => generateClientOptions(httpClients))\n\n/** Compute what the security requirements should be for an operation */\nconst securityRequirements = computed(() =>\n getSecurityRequirements(documentSecurity, operation.security),\n)\n\n/** The selected security for the operation or document */\nconst selectedSecurity = computed(() =>\n getSelectedSecurity(\n documentSelectedSecurity,\n operationSelectedSecurity,\n securityRequirements.value,\n securitySchemes,\n ),\n)\n\n/** The above selected requirements in scheme form */\nconst selectedSecuritySchemes = computed(() =>\n getSecuritySchemes(securitySchemes, selectedSecurity.value.selectedSchemes),\n)\n\nconst { toast } = useToasts()\n\n// Refs\nconst abortController = ref<AbortController | null>(null)\nconst response = ref<ResponseInstance | null>(null)\nconst request = ref<Request | null>(null)\n\n/** Cancel the request */\nconst cancelRequest = () => abortController.value?.abort(ERRORS.REQUEST_ABORTED)\n\n/** Execute the current operation example */\nconst handleExecute = async () => {\n const pathValidation = validatePathParameters(\n operation.parameters ?? [],\n exampleKey,\n )\n if (pathValidation.ok === false) {\n toast('Path parameters must have values.', 'error')\n return\n }\n\n const [error, result] = buildRequest({\n environment,\n exampleKey,\n globalCookies,\n method,\n operation,\n path,\n selectedSecuritySchemes: selectedSecuritySchemes.value,\n server,\n proxyUrl,\n requestBodyCompositionSelection,\n })\n\n // Toast the error\n if (error) {\n toast(error.message, 'error')\n return\n }\n\n // Store the abort controller for cancellation\n abortController.value = result.controller\n\n // Stop any previous streaming response\n if (response.value && 'reader' in response.value) {\n response.value.reader.cancel()\n }\n\n // Execute the hooks\n eventBus.emit('hooks:on:request:sent', {\n meta: {\n method,\n path,\n exampleKey,\n },\n })\n\n /** Execute the request */\n const [sendError, sendResult] = await sendRequest({\n isUsingProxy: result.isUsingProxy,\n operation,\n plugins,\n request: result.request,\n })\n\n // Execute the hooks\n eventBus.emit('hooks:on:request:complete', {\n payload: sendResult\n ? {\n response: sendResult.originalResponse,\n request: sendResult.request.clone(),\n duration: sendResult.response.duration,\n timestamp: sendResult.timestamp,\n }\n : undefined,\n meta: {\n method,\n path,\n exampleKey,\n },\n })\n\n // Toast the execute error\n if (sendError) {\n toast(sendError.message, 'error')\n return\n }\n\n // Store the response\n response.value = sendResult.response\n request.value = sendResult.request\n\n // Cache non-streaming responses so they can be restored when navigating back\n if (!isStreamingResponse(sendResult.response)) {\n responseCache.set(getOperationExampleKey(method, path, exampleKey), {\n response: sendResult.response,\n request: sendResult.request,\n })\n }\n}\n\nonMounted(() => {\n eventBus.on('operation:send:request:hotkey', handleExecute)\n eventBus.on('operation:cancel:request', cancelRequest)\n})\nonBeforeUnmount(() => {\n eventBus.off('operation:send:request:hotkey', handleExecute)\n eventBus.off('operation:cancel:request', cancelRequest)\n})\n\nconst operationHistory = computed<History[]>(() =>\n history\n .map((entry) => ({\n method: entry.request.method as HttpMethodType,\n path: entry.request.url,\n duration: entry.time,\n status: entry.response.status,\n }))\n .reverse(),\n)\n\nconst handleSelectHistoryItem = ({ index }: { index: number }) => {\n const transformedIndex = (history.length ?? 0) - index - 1\n const historyItem = history[transformedIndex]\n if (!historyItem) {\n return\n }\n\n const navigate = () =>\n eventBus.emit('ui:navigate', {\n page: 'example',\n method,\n path,\n exampleName: 'draft',\n callback: (status) => {\n // Do not replace the response if the navigation was not successful\n if (status !== 'success') {\n return\n }\n // Reconstruct the response\n const fetchResponse = harToFetchResponse({\n harResponse: historyItem.response,\n url: historyItem.request.url,\n method,\n path,\n duration: historyItem.time,\n })\n\n // Reconstruct the request\n const fetchRequest = harToFetchRequest({\n harRequest: historyItem.request,\n })\n\n // Update the response and request\n response.value = fetchResponse\n request.value = fetchRequest\n },\n })\n\n eventBus.emit('operation:reload:history', {\n meta: {\n path,\n method,\n },\n index: transformedIndex,\n callback: navigate,\n })\n}\n\n/**\n * When the path, method, or example key changes: save current response to\n * cache (so it can be restored when navigating back), then restore from cache\n * for the new operation or clear if no cached response. Response is only\n * cleared on page refresh or when making a new request for that operation.\n */\nwatch(\n [() => path, () => method, () => exampleKey],\n ([newPath, newMethod, newExampleKey]) => {\n const newKey = getOperationExampleKey(newMethod, newPath, newExampleKey)\n const cached = responseCache.get(newKey)\n if (cached) {\n response.value = cached.response\n request.value = cached.request\n } else {\n response.value = null\n request.value = null\n }\n\n // Cancel any in-flight request\n cancelRequest()\n },\n { immediate: true },\n)\n\nonBeforeUnmount(() => {\n // We cancel the request if the component is unmounted\n cancelRequest()\n})\n</script>\n<template>\n <div class=\"bg-b-1 flex h-full flex-col\">\n <div\n class=\"lg:min-h-header flex w-full flex-wrap items-center justify-center p-2 lg:p-0\">\n <!-- Address Bar -->\n <Header\n :activeEnvironment\n :documentUrl\n :environment\n :environments\n :eventBus\n :hideClientButton\n :history=\"operationHistory\"\n :integration\n :layout\n :method\n :path\n :server\n :serverMeta\n :servers\n :source\n @execute=\"handleExecute\"\n @select:history:item=\"handleSelectHistoryItem\" />\n </div>\n\n <ViewLayout class=\"border-t\">\n <ViewLayoutContent class=\"flex-1\">\n <!-- Request Section -->\n <RequestBlock\n :authMeta\n :clientOptions\n :environment\n :eventBus\n :exampleKey\n :globalCookies\n :layout\n :method\n :operation\n :path\n :plugins\n :proxyUrl\n :requestBodyCompositionSelection\n :securityRequirements\n :securitySchemes\n :selectedClient\n :selectedSecurity\n :selectedSecuritySchemes\n :server />\n\n <!-- Response Section -->\n <ResponseBlock\n :appVersion\n :eventBus\n :layout\n :plugins\n :request\n :response\n :totalPerformedRequests=\"operationHistory.length\" />\n </ViewLayoutContent>\n </ViewLayout>\n </div>\n</template>\n"],"mappings":""}
|
|
@@ -50,7 +50,8 @@ var OperationBlock_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
|
|
|
50
50
|
environments: {},
|
|
51
51
|
activeEnvironment: {},
|
|
52
52
|
environment: {},
|
|
53
|
-
proxyUrl: {}
|
|
53
|
+
proxyUrl: {},
|
|
54
|
+
requestBodyCompositionSelection: {}
|
|
54
55
|
},
|
|
55
56
|
setup(__props) {
|
|
56
57
|
/** Hoist up client generation so it doesn't get re-generated on every operation */
|
|
@@ -82,7 +83,8 @@ var OperationBlock_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
|
|
|
82
83
|
path: __props.path,
|
|
83
84
|
selectedSecuritySchemes: selectedSecuritySchemes.value,
|
|
84
85
|
server: __props.server,
|
|
85
|
-
proxyUrl: __props.proxyUrl
|
|
86
|
+
proxyUrl: __props.proxyUrl,
|
|
87
|
+
requestBodyCompositionSelection: __props.requestBodyCompositionSelection
|
|
86
88
|
});
|
|
87
89
|
if (error) {
|
|
88
90
|
toast(error.message, "error");
|
|
@@ -247,6 +249,7 @@ var OperationBlock_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
|
|
|
247
249
|
path: __props.path,
|
|
248
250
|
plugins: __props.plugins,
|
|
249
251
|
proxyUrl: __props.proxyUrl,
|
|
252
|
+
requestBodyCompositionSelection: __props.requestBodyCompositionSelection,
|
|
250
253
|
securityRequirements: securityRequirements.value,
|
|
251
254
|
securitySchemes: __props.securitySchemes,
|
|
252
255
|
selectedClient: __props.selectedClient,
|
|
@@ -266,6 +269,7 @@ var OperationBlock_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
|
|
|
266
269
|
"path",
|
|
267
270
|
"plugins",
|
|
268
271
|
"proxyUrl",
|
|
272
|
+
"requestBodyCompositionSelection",
|
|
269
273
|
"securityRequirements",
|
|
270
274
|
"securitySchemes",
|
|
271
275
|
"selectedClient",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OperationBlock.vue.script.js","names":[],"sources":["../../../../src/v2/blocks/operation-block/OperationBlock.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * OperationBlock\n *\n * Orchestrates the operation view by wiring together the Header, OperationBlock,\n * and ResponseBlock. Forwards user interactions to the workspace event bus and\n * passes through configuration such as auth, servers, plugins, and environment.\n * This component keeps the Operation page lean by centralizing event emission\n * and prop wiring between the blocks.\n *\n * Notable behavior:\n * - Uses operation['x-scalar-method'] and operation['x-scalar-path'] to provide\n * draft overrides for the UI when present.\n */\nexport default {\n name: 'OperationBlock',\n}\n\nexport type OperationBlockProps = {\n /** Event bus */\n eventBus: WorkspaceEventBus\n /** Document defined security */\n documentSecurity: OpenApiDocument['security']\n /** Document selected security */\n documentSelectedSecurity: SelectedSecurity | undefined\n /** Application version */\n appVersion: string\n /** Workspace/document cookies */\n globalCookies: ExtendedScalarCookie[]\n /** Current request path */\n path: string\n /** Current request method */\n method: HttpMethodType\n /** HTTP clients */\n httpClients: AvailableClients\n /** The history for the operation */\n history?: HistoryEntry[]\n /** Client layout */\n layout: ClientLayout\n /** Currently selected server */\n server: ServerObject | null\n /** Currently selected client */\n selectedClient: WorkspaceStore['workspace']['x-scalar-default-client']\n /** Server list available for operation/document */\n servers: ServerObject[]\n /** Meta information for the server */\n serverMeta: ServerMeta\n /** Hides the client button on the header */\n hideClientButton?: boolean\n /** Client integration */\n integration?: string | null\n /** Openapi document url for `modal` mode to open the client app */\n documentUrl?: string\n /** Client source */\n source?: 'gitbook' | 'api-reference'\n /** Operation object */\n operation: OperationObject\n /** Operation selected security */\n operationSelectedSecurity: SelectedSecurity | undefined\n /** Currently selected example key for the current operation */\n exampleKey: string\n /** Meta information for the auth update */\n authMeta: AuthMeta\n /** Document defined security schemes */\n securitySchemes: MergedSecuritySchemes\n /** Client plugins */\n plugins: ClientPlugin[]\n /** Environment list */\n environments?: string[]\n /** Currently selected environment */\n activeEnvironment?: string\n /** For environment variables in the inputs */\n environment: XScalarEnvironment\n /** The proxy URL for sending requests */\n proxyUrl: string\n}\n</script>\n<script setup lang=\"ts\">\nimport type { HttpMethod as HttpMethodType } from '@scalar/helpers/http/http-methods'\nimport type { ResponseInstance } from '@scalar/oas-utils/entities/spec'\nimport { type ClientPlugin } from '@scalar/oas-utils/helpers'\nimport {\n AVAILABLE_CLIENTS,\n type AvailableClients,\n} from '@scalar/types/snippetz'\nimport { useToasts } from '@scalar/use-toasts'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\nimport type { SelectedSecurity } from '@scalar/workspace-store/entities/auth'\nimport type { HistoryEntry } from '@scalar/workspace-store/entities/history/schema'\nimport type {\n AuthMeta,\n ServerMeta,\n WorkspaceEventBus,\n} from '@scalar/workspace-store/events'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport type {\n OpenApiDocument,\n ServerObject,\n} from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport type { OperationObject } from '@scalar/workspace-store/schemas/v3.1/strict/operation'\nimport { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'\n\nimport ViewLayout from '@/components/ViewLayout/ViewLayout.vue'\nimport ViewLayoutContent from '@/components/ViewLayout/ViewLayoutContent.vue'\nimport type { ClientLayout } from '@/hooks'\nimport { ERRORS } from '@/libs/errors'\nimport { buildRequest } from '@/v2/blocks/operation-block/helpers/build-request'\nimport { getSecuritySchemes } from '@/v2/blocks/operation-block/helpers/build-request-security'\nimport { harToFetchRequest } from '@/v2/blocks/operation-block/helpers/har-to-fetch-request'\nimport { harToFetchResponse } from '@/v2/blocks/operation-block/helpers/har-to-fetch-response'\nimport {\n getOperationExampleKey,\n isStreamingResponse,\n responseCache,\n} from '@/v2/blocks/operation-block/helpers/response-cache'\nimport { sendRequest } from '@/v2/blocks/operation-block/helpers/send-request'\nimport { validatePathParameters } from '@/v2/blocks/operation-block/helpers/validate-path-parameters'\nimport { generateClientOptions } from '@/v2/blocks/operation-code-sample'\nimport { RequestBlock } from '@/v2/blocks/request-block'\nimport type { ExtendedScalarCookie } from '@/v2/blocks/request-block/RequestBlock.vue'\nimport { ResponseBlock } from '@/v2/blocks/response-block'\nimport { type History } from '@/v2/blocks/scalar-address-bar-block'\nimport type { MergedSecuritySchemes } from '@/v2/blocks/scalar-auth-selector-block/helpers/merge-security'\nimport {\n getSecurityRequirements,\n getSelectedSecurity,\n} from '@/v2/features/operation'\n\nimport Header from './components/Header.vue'\n\nconst {\n authMeta,\n environment,\n documentSecurity,\n documentSelectedSecurity,\n eventBus,\n exampleKey,\n globalCookies = [],\n hideClientButton,\n httpClients = AVAILABLE_CLIENTS,\n history = [],\n method,\n operation,\n operationSelectedSecurity,\n path,\n plugins = [],\n proxyUrl,\n securitySchemes,\n selectedClient,\n server,\n environments,\n activeEnvironment,\n serverMeta,\n} = defineProps<OperationBlockProps>()\n\n/** Hoist up client generation so it doesn't get re-generated on every operation */\nconst clientOptions = computed(() => generateClientOptions(httpClients))\n\n/** Compute what the security requirements should be for an operation */\nconst securityRequirements = computed(() =>\n getSecurityRequirements(documentSecurity, operation.security),\n)\n\n/** The selected security for the operation or document */\nconst selectedSecurity = computed(() =>\n getSelectedSecurity(\n documentSelectedSecurity,\n operationSelectedSecurity,\n securityRequirements.value,\n securitySchemes,\n ),\n)\n\n/** The above selected requirements in scheme form */\nconst selectedSecuritySchemes = computed(() =>\n getSecuritySchemes(securitySchemes, selectedSecurity.value.selectedSchemes),\n)\n\nconst { toast } = useToasts()\n\n// Refs\nconst abortController = ref<AbortController | null>(null)\nconst response = ref<ResponseInstance | null>(null)\nconst request = ref<Request | null>(null)\n\n/** Cancel the request */\nconst cancelRequest = () => abortController.value?.abort(ERRORS.REQUEST_ABORTED)\n\n/** Execute the current operation example */\nconst handleExecute = async () => {\n const pathValidation = validatePathParameters(\n operation.parameters ?? [],\n exampleKey,\n )\n if (pathValidation.ok === false) {\n toast('Path parameters must have values.', 'error')\n return\n }\n\n const [error, result] = buildRequest({\n environment,\n exampleKey,\n globalCookies,\n method,\n operation,\n path,\n selectedSecuritySchemes: selectedSecuritySchemes.value,\n server,\n proxyUrl,\n })\n\n // Toast the error\n if (error) {\n toast(error.message, 'error')\n return\n }\n\n // Store the abort controller for cancellation\n abortController.value = result.controller\n\n // Stop any previous streaming response\n if (response.value && 'reader' in response.value) {\n response.value.reader.cancel()\n }\n\n // Execute the hooks\n eventBus.emit('hooks:on:request:sent', {\n meta: {\n method,\n path,\n exampleKey,\n },\n })\n\n /** Execute the request */\n const [sendError, sendResult] = await sendRequest({\n isUsingProxy: result.isUsingProxy,\n operation,\n plugins,\n request: result.request,\n })\n\n // Execute the hooks\n eventBus.emit('hooks:on:request:complete', {\n payload: sendResult\n ? {\n response: sendResult.originalResponse,\n request: sendResult.request.clone(),\n duration: sendResult.response.duration,\n timestamp: sendResult.timestamp,\n }\n : undefined,\n meta: {\n method,\n path,\n exampleKey,\n },\n })\n\n // Toast the execute error\n if (sendError) {\n toast(sendError.message, 'error')\n return\n }\n\n // Store the response\n response.value = sendResult.response\n request.value = sendResult.request\n\n // Cache non-streaming responses so they can be restored when navigating back\n if (!isStreamingResponse(sendResult.response)) {\n responseCache.set(getOperationExampleKey(method, path, exampleKey), {\n response: sendResult.response,\n request: sendResult.request,\n })\n }\n}\n\nonMounted(() => {\n eventBus.on('operation:send:request:hotkey', handleExecute)\n eventBus.on('operation:cancel:request', cancelRequest)\n})\nonBeforeUnmount(() => {\n eventBus.off('operation:send:request:hotkey', handleExecute)\n eventBus.off('operation:cancel:request', cancelRequest)\n})\n\nconst operationHistory = computed<History[]>(() =>\n history\n .map((entry) => ({\n method: entry.request.method as HttpMethodType,\n path: entry.request.url,\n duration: entry.time,\n status: entry.response.status,\n }))\n .reverse(),\n)\n\nconst handleSelectHistoryItem = ({ index }: { index: number }) => {\n const transformedIndex = (history.length ?? 0) - index - 1\n const historyItem = history[transformedIndex]\n if (!historyItem) {\n return\n }\n\n const navigate = () =>\n eventBus.emit('ui:navigate', {\n page: 'example',\n method,\n path,\n exampleName: 'draft',\n callback: (status) => {\n // Do not replace the response if the navigation was not successful\n if (status !== 'success') {\n return\n }\n // Reconstruct the response\n const fetchResponse = harToFetchResponse({\n harResponse: historyItem.response,\n url: historyItem.request.url,\n method,\n path,\n duration: historyItem.time,\n })\n\n // Reconstruct the request\n const fetchRequest = harToFetchRequest({\n harRequest: historyItem.request,\n })\n\n // Update the response and request\n response.value = fetchResponse\n request.value = fetchRequest\n },\n })\n\n eventBus.emit('operation:reload:history', {\n meta: {\n path,\n method,\n },\n index: transformedIndex,\n callback: navigate,\n })\n}\n\n/**\n * When the path, method, or example key changes: save current response to\n * cache (so it can be restored when navigating back), then restore from cache\n * for the new operation or clear if no cached response. Response is only\n * cleared on page refresh or when making a new request for that operation.\n */\nwatch(\n [() => path, () => method, () => exampleKey],\n ([newPath, newMethod, newExampleKey]) => {\n const newKey = getOperationExampleKey(newMethod, newPath, newExampleKey)\n const cached = responseCache.get(newKey)\n if (cached) {\n response.value = cached.response\n request.value = cached.request\n } else {\n response.value = null\n request.value = null\n }\n\n // Cancel any in-flight request\n cancelRequest()\n },\n { immediate: true },\n)\n\nonBeforeUnmount(() => {\n // We cancel the request if the component is unmounted\n cancelRequest()\n})\n</script>\n<template>\n <div class=\"bg-b-1 flex h-full flex-col\">\n <div\n class=\"lg:min-h-header flex w-full flex-wrap items-center justify-center p-2 lg:p-0\">\n <!-- Address Bar -->\n <Header\n :activeEnvironment\n :documentUrl\n :environment\n :environments\n :eventBus\n :hideClientButton\n :history=\"operationHistory\"\n :integration\n :layout\n :method\n :path\n :server\n :serverMeta\n :servers\n :source\n @execute=\"handleExecute\"\n @select:history:item=\"handleSelectHistoryItem\" />\n </div>\n\n <ViewLayout class=\"border-t\">\n <ViewLayoutContent class=\"flex-1\">\n <!-- Request Section -->\n <RequestBlock\n :authMeta\n :clientOptions\n :environment\n :eventBus\n :exampleKey\n :globalCookies\n :layout\n :method\n :operation\n :path\n :plugins\n :proxyUrl\n :securityRequirements\n :securitySchemes\n :selectedClient\n :selectedSecurity\n :selectedSecuritySchemes\n :server />\n\n <!-- Response Section -->\n <ResponseBlock\n :appVersion\n :eventBus\n :layout\n :plugins\n :request\n :response\n :totalPerformedRequests=\"operationHistory.length\" />\n </ViewLayoutContent>\n </ViewLayout>\n </div>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"OperationBlock.vue.script.js","names":[],"sources":["../../../../src/v2/blocks/operation-block/OperationBlock.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * OperationBlock\n *\n * Orchestrates the operation view by wiring together the Header, OperationBlock,\n * and ResponseBlock. Forwards user interactions to the workspace event bus and\n * passes through configuration such as auth, servers, plugins, and environment.\n * This component keeps the Operation page lean by centralizing event emission\n * and prop wiring between the blocks.\n *\n * Notable behavior:\n * - Uses operation['x-scalar-method'] and operation['x-scalar-path'] to provide\n * draft overrides for the UI when present.\n */\nexport default {\n name: 'OperationBlock',\n}\n\nexport type OperationBlockProps = {\n /** Event bus */\n eventBus: WorkspaceEventBus\n /** Document defined security */\n documentSecurity: OpenApiDocument['security']\n /** Document selected security */\n documentSelectedSecurity: SelectedSecurity | undefined\n /** Application version */\n appVersion: string\n /** Workspace/document cookies */\n globalCookies: ExtendedScalarCookie[]\n /** Current request path */\n path: string\n /** Current request method */\n method: HttpMethodType\n /** HTTP clients */\n httpClients: AvailableClients\n /** The history for the operation */\n history?: HistoryEntry[]\n /** Client layout */\n layout: ClientLayout\n /** Currently selected server */\n server: ServerObject | null\n /** Currently selected client */\n selectedClient: WorkspaceStore['workspace']['x-scalar-default-client']\n /** Server list available for operation/document */\n servers: ServerObject[]\n /** Meta information for the server */\n serverMeta: ServerMeta\n /** Hides the client button on the header */\n hideClientButton?: boolean\n /** Client integration */\n integration?: string | null\n /** Openapi document url for `modal` mode to open the client app */\n documentUrl?: string\n /** Client source */\n source?: 'gitbook' | 'api-reference'\n /** Operation object */\n operation: OperationObject\n /** Operation selected security */\n operationSelectedSecurity: SelectedSecurity | undefined\n /** Currently selected example key for the current operation */\n exampleKey: string\n /** Meta information for the auth update */\n authMeta: AuthMeta\n /** Document defined security schemes */\n securitySchemes: MergedSecuritySchemes\n /** Client plugins */\n plugins: ClientPlugin[]\n /** Environment list */\n environments?: string[]\n /** Currently selected environment */\n activeEnvironment?: string\n /** For environment variables in the inputs */\n environment: XScalarEnvironment\n /** The proxy URL for sending requests */\n proxyUrl: string\n /** Selected anyOf/oneOf request-body variants keyed by schema path */\n requestBodyCompositionSelection?: Record<string, number>\n}\n</script>\n<script setup lang=\"ts\">\nimport type { HttpMethod as HttpMethodType } from '@scalar/helpers/http/http-methods'\nimport type { ResponseInstance } from '@scalar/oas-utils/entities/spec'\nimport { type ClientPlugin } from '@scalar/oas-utils/helpers'\nimport {\n AVAILABLE_CLIENTS,\n type AvailableClients,\n} from '@scalar/types/snippetz'\nimport { useToasts } from '@scalar/use-toasts'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\nimport type { SelectedSecurity } from '@scalar/workspace-store/entities/auth'\nimport type { HistoryEntry } from '@scalar/workspace-store/entities/history/schema'\nimport type {\n AuthMeta,\n ServerMeta,\n WorkspaceEventBus,\n} from '@scalar/workspace-store/events'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport type {\n OpenApiDocument,\n ServerObject,\n} from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport type { OperationObject } from '@scalar/workspace-store/schemas/v3.1/strict/operation'\nimport { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'\n\nimport ViewLayout from '@/components/ViewLayout/ViewLayout.vue'\nimport ViewLayoutContent from '@/components/ViewLayout/ViewLayoutContent.vue'\nimport type { ClientLayout } from '@/hooks'\nimport { ERRORS } from '@/libs/errors'\nimport { buildRequest } from '@/v2/blocks/operation-block/helpers/build-request'\nimport { getSecuritySchemes } from '@/v2/blocks/operation-block/helpers/build-request-security'\nimport { harToFetchRequest } from '@/v2/blocks/operation-block/helpers/har-to-fetch-request'\nimport { harToFetchResponse } from '@/v2/blocks/operation-block/helpers/har-to-fetch-response'\nimport {\n getOperationExampleKey,\n isStreamingResponse,\n responseCache,\n} from '@/v2/blocks/operation-block/helpers/response-cache'\nimport { sendRequest } from '@/v2/blocks/operation-block/helpers/send-request'\nimport { validatePathParameters } from '@/v2/blocks/operation-block/helpers/validate-path-parameters'\nimport { generateClientOptions } from '@/v2/blocks/operation-code-sample'\nimport { RequestBlock } from '@/v2/blocks/request-block'\nimport type { ExtendedScalarCookie } from '@/v2/blocks/request-block/RequestBlock.vue'\nimport { ResponseBlock } from '@/v2/blocks/response-block'\nimport { type History } from '@/v2/blocks/scalar-address-bar-block'\nimport type { MergedSecuritySchemes } from '@/v2/blocks/scalar-auth-selector-block/helpers/merge-security'\nimport {\n getSecurityRequirements,\n getSelectedSecurity,\n} from '@/v2/features/operation'\n\nimport Header from './components/Header.vue'\n\nconst {\n authMeta,\n environment,\n documentSecurity,\n documentSelectedSecurity,\n eventBus,\n exampleKey,\n globalCookies = [],\n hideClientButton,\n httpClients = AVAILABLE_CLIENTS,\n history = [],\n method,\n operation,\n operationSelectedSecurity,\n path,\n plugins = [],\n proxyUrl,\n requestBodyCompositionSelection,\n securitySchemes,\n selectedClient,\n server,\n environments,\n activeEnvironment,\n serverMeta,\n} = defineProps<OperationBlockProps>()\n\n/** Hoist up client generation so it doesn't get re-generated on every operation */\nconst clientOptions = computed(() => generateClientOptions(httpClients))\n\n/** Compute what the security requirements should be for an operation */\nconst securityRequirements = computed(() =>\n getSecurityRequirements(documentSecurity, operation.security),\n)\n\n/** The selected security for the operation or document */\nconst selectedSecurity = computed(() =>\n getSelectedSecurity(\n documentSelectedSecurity,\n operationSelectedSecurity,\n securityRequirements.value,\n securitySchemes,\n ),\n)\n\n/** The above selected requirements in scheme form */\nconst selectedSecuritySchemes = computed(() =>\n getSecuritySchemes(securitySchemes, selectedSecurity.value.selectedSchemes),\n)\n\nconst { toast } = useToasts()\n\n// Refs\nconst abortController = ref<AbortController | null>(null)\nconst response = ref<ResponseInstance | null>(null)\nconst request = ref<Request | null>(null)\n\n/** Cancel the request */\nconst cancelRequest = () => abortController.value?.abort(ERRORS.REQUEST_ABORTED)\n\n/** Execute the current operation example */\nconst handleExecute = async () => {\n const pathValidation = validatePathParameters(\n operation.parameters ?? [],\n exampleKey,\n )\n if (pathValidation.ok === false) {\n toast('Path parameters must have values.', 'error')\n return\n }\n\n const [error, result] = buildRequest({\n environment,\n exampleKey,\n globalCookies,\n method,\n operation,\n path,\n selectedSecuritySchemes: selectedSecuritySchemes.value,\n server,\n proxyUrl,\n requestBodyCompositionSelection,\n })\n\n // Toast the error\n if (error) {\n toast(error.message, 'error')\n return\n }\n\n // Store the abort controller for cancellation\n abortController.value = result.controller\n\n // Stop any previous streaming response\n if (response.value && 'reader' in response.value) {\n response.value.reader.cancel()\n }\n\n // Execute the hooks\n eventBus.emit('hooks:on:request:sent', {\n meta: {\n method,\n path,\n exampleKey,\n },\n })\n\n /** Execute the request */\n const [sendError, sendResult] = await sendRequest({\n isUsingProxy: result.isUsingProxy,\n operation,\n plugins,\n request: result.request,\n })\n\n // Execute the hooks\n eventBus.emit('hooks:on:request:complete', {\n payload: sendResult\n ? {\n response: sendResult.originalResponse,\n request: sendResult.request.clone(),\n duration: sendResult.response.duration,\n timestamp: sendResult.timestamp,\n }\n : undefined,\n meta: {\n method,\n path,\n exampleKey,\n },\n })\n\n // Toast the execute error\n if (sendError) {\n toast(sendError.message, 'error')\n return\n }\n\n // Store the response\n response.value = sendResult.response\n request.value = sendResult.request\n\n // Cache non-streaming responses so they can be restored when navigating back\n if (!isStreamingResponse(sendResult.response)) {\n responseCache.set(getOperationExampleKey(method, path, exampleKey), {\n response: sendResult.response,\n request: sendResult.request,\n })\n }\n}\n\nonMounted(() => {\n eventBus.on('operation:send:request:hotkey', handleExecute)\n eventBus.on('operation:cancel:request', cancelRequest)\n})\nonBeforeUnmount(() => {\n eventBus.off('operation:send:request:hotkey', handleExecute)\n eventBus.off('operation:cancel:request', cancelRequest)\n})\n\nconst operationHistory = computed<History[]>(() =>\n history\n .map((entry) => ({\n method: entry.request.method as HttpMethodType,\n path: entry.request.url,\n duration: entry.time,\n status: entry.response.status,\n }))\n .reverse(),\n)\n\nconst handleSelectHistoryItem = ({ index }: { index: number }) => {\n const transformedIndex = (history.length ?? 0) - index - 1\n const historyItem = history[transformedIndex]\n if (!historyItem) {\n return\n }\n\n const navigate = () =>\n eventBus.emit('ui:navigate', {\n page: 'example',\n method,\n path,\n exampleName: 'draft',\n callback: (status) => {\n // Do not replace the response if the navigation was not successful\n if (status !== 'success') {\n return\n }\n // Reconstruct the response\n const fetchResponse = harToFetchResponse({\n harResponse: historyItem.response,\n url: historyItem.request.url,\n method,\n path,\n duration: historyItem.time,\n })\n\n // Reconstruct the request\n const fetchRequest = harToFetchRequest({\n harRequest: historyItem.request,\n })\n\n // Update the response and request\n response.value = fetchResponse\n request.value = fetchRequest\n },\n })\n\n eventBus.emit('operation:reload:history', {\n meta: {\n path,\n method,\n },\n index: transformedIndex,\n callback: navigate,\n })\n}\n\n/**\n * When the path, method, or example key changes: save current response to\n * cache (so it can be restored when navigating back), then restore from cache\n * for the new operation or clear if no cached response. Response is only\n * cleared on page refresh or when making a new request for that operation.\n */\nwatch(\n [() => path, () => method, () => exampleKey],\n ([newPath, newMethod, newExampleKey]) => {\n const newKey = getOperationExampleKey(newMethod, newPath, newExampleKey)\n const cached = responseCache.get(newKey)\n if (cached) {\n response.value = cached.response\n request.value = cached.request\n } else {\n response.value = null\n request.value = null\n }\n\n // Cancel any in-flight request\n cancelRequest()\n },\n { immediate: true },\n)\n\nonBeforeUnmount(() => {\n // We cancel the request if the component is unmounted\n cancelRequest()\n})\n</script>\n<template>\n <div class=\"bg-b-1 flex h-full flex-col\">\n <div\n class=\"lg:min-h-header flex w-full flex-wrap items-center justify-center p-2 lg:p-0\">\n <!-- Address Bar -->\n <Header\n :activeEnvironment\n :documentUrl\n :environment\n :environments\n :eventBus\n :hideClientButton\n :history=\"operationHistory\"\n :integration\n :layout\n :method\n :path\n :server\n :serverMeta\n :servers\n :source\n @execute=\"handleExecute\"\n @select:history:item=\"handleSelectHistoryItem\" />\n </div>\n\n <ViewLayout class=\"border-t\">\n <ViewLayoutContent class=\"flex-1\">\n <!-- Request Section -->\n <RequestBlock\n :authMeta\n :clientOptions\n :environment\n :eventBus\n :exampleKey\n :globalCookies\n :layout\n :method\n :operation\n :path\n :plugins\n :proxyUrl\n :requestBodyCompositionSelection\n :securityRequirements\n :securitySchemes\n :selectedClient\n :selectedSecurity\n :selectedSecuritySchemes\n :server />\n\n <!-- Response Section -->\n <ResponseBlock\n :appVersion\n :eventBus\n :layout\n :plugins\n :request\n :response\n :totalPerformedRequests=\"operationHistory.length\" />\n </ViewLayoutContent>\n </ViewLayout>\n </div>\n</template>\n"],"mappings":"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"}
|
|
@@ -6,5 +6,7 @@ export declare const buildRequestBody: (requestBody: RequestBodyObject | undefin
|
|
|
6
6
|
/** Environment variables flattened into a key-value object */
|
|
7
7
|
env?: Record<string, string>,
|
|
8
8
|
/** The key of the current example */
|
|
9
|
-
exampleKey?: string
|
|
9
|
+
exampleKey?: string,
|
|
10
|
+
/** Selected anyOf/oneOf request-body variants keyed by schema path */
|
|
11
|
+
requestBodyCompositionSelection?: Record<string, number>) => BodyInit | null;
|
|
10
12
|
//# sourceMappingURL=build-request-body.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-request-body.d.ts","sourceRoot":"","sources":["../../../../../src/v2/blocks/operation-block/helpers/build-request-body.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0DAA0D,CAAA;AAyBjG;;GAEG;AACH,eAAO,MAAM,gBAAgB,GAC3B,aAAa,iBAAiB,GAAG,SAAS;AAC1C,8DAA8D;AAC9D,MAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM;AAChC,qCAAqC;AACrC,mBAAsB,
|
|
1
|
+
{"version":3,"file":"build-request-body.d.ts","sourceRoot":"","sources":["../../../../../src/v2/blocks/operation-block/helpers/build-request-body.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0DAA0D,CAAA;AAyBjG;;GAEG;AACH,eAAO,MAAM,gBAAgB,GAC3B,aAAa,iBAAiB,GAAG,SAAS;AAC1C,8DAA8D;AAC9D,MAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM;AAChC,qCAAqC;AACrC,mBAAsB;AACtB,sEAAsE;AACtE,kCAAkC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KACvD,QAAQ,GAAG,IAyGb,CAAA"}
|
|
@@ -11,13 +11,13 @@ var serializeMultipartValue = (value, env) => {
|
|
|
11
11
|
/**
|
|
12
12
|
* Create the fetch request body
|
|
13
13
|
*/
|
|
14
|
-
var buildRequestBody = (requestBody, env = {}, exampleKey = "default") => {
|
|
14
|
+
var buildRequestBody = (requestBody, env = {}, exampleKey = "default", requestBodyCompositionSelection) => {
|
|
15
15
|
if (!requestBody) return null;
|
|
16
16
|
/** Selected content type for the body from the dropdown, stored as x-scalar-selected-content-type */
|
|
17
17
|
const bodyContentType = getSelectedBodyContentType(requestBody, exampleKey);
|
|
18
18
|
if (!bodyContentType) return null;
|
|
19
19
|
/** An example value or generated example from the schema */
|
|
20
|
-
const example = getExampleFromBody(requestBody, bodyContentType, exampleKey);
|
|
20
|
+
const example = getExampleFromBody(requestBody, bodyContentType, exampleKey, requestBodyCompositionSelection);
|
|
21
21
|
if (!example) return null;
|
|
22
22
|
if ((bodyContentType === "multipart/form-data" || bodyContentType === "application/x-www-form-urlencoded") && Array.isArray(example.value)) {
|
|
23
23
|
const exampleValue = example.value.filter((item) => !item.isDisabled);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-request-body.js","names":[],"sources":["../../../../../src/v2/blocks/operation-block/helpers/build-request-body.ts"],"sourcesContent":["import { replaceEnvVariables } from '@scalar/helpers/regex/replace-variables'\nimport { unpackProxyObject } from '@scalar/workspace-store/helpers/unpack-proxy'\nimport type { RequestBodyObject } from '@scalar/workspace-store/schemas/v3.1/strict/request-body'\n\nimport { getSelectedBodyContentType } from '@/v2/blocks/operation-block/helpers/get-selected-body-content-type'\nimport { getExampleFromBody } from '@/v2/blocks/request-block/helpers/get-request-body-example'\n\nconst getMultipartEncodingContentType = (\n requestBody: RequestBodyObject,\n bodyContentType: string,\n fieldName: string,\n replacedFieldName: string,\n) =>\n requestBody.content[bodyContentType]?.encoding?.[fieldName]?.contentType ??\n requestBody.content[bodyContentType]?.encoding?.[replacedFieldName]?.contentType\n\nconst serializeMultipartValue = (value: unknown, env: Record<string, string>) => {\n if (typeof value === 'string') {\n return replaceEnvVariables(value, env)\n }\n\n const serializedValue =\n typeof value === 'object' && value !== null ? JSON.stringify(unpackProxyObject(value)) : String(value)\n\n return replaceEnvVariables(serializedValue, env)\n}\n\n/**\n * Create the fetch request body\n */\nexport const buildRequestBody = (\n requestBody: RequestBodyObject | undefined,\n /** Environment variables flattened into a key-value object */\n env: Record<string, string> = {},\n /** The key of the current example */\n exampleKey = 'default',\n): BodyInit | null => {\n if (!requestBody) {\n return null\n }\n\n /** Selected content type for the body from the dropdown, stored as x-scalar-selected-content-type */\n const bodyContentType = getSelectedBodyContentType(requestBody, exampleKey)\n if (!bodyContentType) {\n return null\n }\n\n /** An example value or generated example from the schema */\n const example = getExampleFromBody(requestBody, bodyContentType, exampleKey)\n if (!example) {\n return null\n }\n\n // Form data - array format (from UI editor)\n if (\n (bodyContentType === 'multipart/form-data' || bodyContentType === 'application/x-www-form-urlencoded') &&\n Array.isArray(example.value)\n ) {\n const exampleValue = example.value.filter((item) => !item.isDisabled) as { name: string; value: unknown }[]\n const form = bodyContentType === 'multipart/form-data' ? new FormData() : new URLSearchParams()\n\n // Loop over all entries and add them to the form\n exampleValue.forEach(({ name, value }) => {\n if (!name) {\n return\n }\n const replacedName = replaceEnvVariables(name, env)\n const partContentType =\n form instanceof FormData\n ? getMultipartEncodingContentType(requestBody, bodyContentType, name, replacedName)\n : undefined\n\n // Handle file uploads\n if (value instanceof File && form instanceof FormData) {\n /**\n * We need to unwrap the proxies to get the file name due to the\n * \"this\" context in the proxy causing an illegal invocation error\n */\n const unwrappedValue = unpackProxyObject(value)\n const encodedValue =\n partContentType && partContentType !== unwrappedValue.type\n ? new File([unwrappedValue], unwrappedValue.name, {\n type: partContentType,\n lastModified: unwrappedValue.lastModified,\n })\n : unwrappedValue\n\n form.append(replacedName, encodedValue, encodedValue.name)\n }\n // Text and structured inputs\n else if (value !== undefined && value !== null) {\n const serializedValue = serializeMultipartValue(value, env)\n\n if (form instanceof FormData && partContentType) {\n form.append(replacedName, new Blob([serializedValue], { type: partContentType }))\n } else {\n form.append(replacedName, serializedValue)\n }\n }\n })\n\n return form\n }\n\n // Form data - object format (from schema examples)\n // When the example value is a plain object and content type is form-urlencoded,\n // convert to URLSearchParams instead of JSON stringifying\n if (\n bodyContentType === 'application/x-www-form-urlencoded' &&\n example.value !== null &&\n typeof example.value === 'object' &&\n !Array.isArray(example.value)\n ) {\n const form = new URLSearchParams()\n\n // Convert object properties to form fields\n for (const [key, value] of Object.entries(example.value)) {\n if (key && value !== undefined && value !== null) {\n const replacedKey = replaceEnvVariables(key, env)\n const stringValue = typeof value === 'string' ? value : String(value)\n form.append(replacedKey, replaceEnvVariables(stringValue, env))\n }\n }\n\n return form\n }\n\n const exampleValue =\n example.value !== null && typeof example.value === 'object' ? unpackProxyObject(example.value) : example.value\n\n if (exampleValue instanceof File) {\n return exampleValue\n }\n\n // Ensure we stringify the example value if it is an object\n if (typeof exampleValue === 'object') {\n return replaceEnvVariables(JSON.stringify(exampleValue), env)\n }\n\n // Return binary or string values\n return typeof exampleValue === 'string' ? replaceEnvVariables(exampleValue, env) : exampleValue\n}\n"],"mappings":";;;;;AAOA,IAAM,mCACJ,aACA,iBACA,WACA,sBAEA,YAAY,QAAQ,kBAAkB,WAAW,YAAY,eAC7D,YAAY,QAAQ,kBAAkB,WAAW,oBAAoB;AAEvE,IAAM,2BAA2B,OAAgB,QAAgC;AAC/E,KAAI,OAAO,UAAU,SACnB,QAAO,oBAAoB,OAAO,IAAI;AAMxC,QAAO,oBAFL,OAAO,UAAU,YAAY,UAAU,OAAO,KAAK,UAAU,kBAAkB,MAAM,CAAC,GAAG,OAAO,MAAM,EAE5D,IAAI;;;;;AAMlD,IAAa,oBACX,aAEA,MAA8B,EAAE,EAEhC,aAAa,
|
|
1
|
+
{"version":3,"file":"build-request-body.js","names":[],"sources":["../../../../../src/v2/blocks/operation-block/helpers/build-request-body.ts"],"sourcesContent":["import { replaceEnvVariables } from '@scalar/helpers/regex/replace-variables'\nimport { unpackProxyObject } from '@scalar/workspace-store/helpers/unpack-proxy'\nimport type { RequestBodyObject } from '@scalar/workspace-store/schemas/v3.1/strict/request-body'\n\nimport { getSelectedBodyContentType } from '@/v2/blocks/operation-block/helpers/get-selected-body-content-type'\nimport { getExampleFromBody } from '@/v2/blocks/request-block/helpers/get-request-body-example'\n\nconst getMultipartEncodingContentType = (\n requestBody: RequestBodyObject,\n bodyContentType: string,\n fieldName: string,\n replacedFieldName: string,\n) =>\n requestBody.content[bodyContentType]?.encoding?.[fieldName]?.contentType ??\n requestBody.content[bodyContentType]?.encoding?.[replacedFieldName]?.contentType\n\nconst serializeMultipartValue = (value: unknown, env: Record<string, string>) => {\n if (typeof value === 'string') {\n return replaceEnvVariables(value, env)\n }\n\n const serializedValue =\n typeof value === 'object' && value !== null ? JSON.stringify(unpackProxyObject(value)) : String(value)\n\n return replaceEnvVariables(serializedValue, env)\n}\n\n/**\n * Create the fetch request body\n */\nexport const buildRequestBody = (\n requestBody: RequestBodyObject | undefined,\n /** Environment variables flattened into a key-value object */\n env: Record<string, string> = {},\n /** The key of the current example */\n exampleKey = 'default',\n /** Selected anyOf/oneOf request-body variants keyed by schema path */\n requestBodyCompositionSelection?: Record<string, number>,\n): BodyInit | null => {\n if (!requestBody) {\n return null\n }\n\n /** Selected content type for the body from the dropdown, stored as x-scalar-selected-content-type */\n const bodyContentType = getSelectedBodyContentType(requestBody, exampleKey)\n if (!bodyContentType) {\n return null\n }\n\n /** An example value or generated example from the schema */\n const example = getExampleFromBody(requestBody, bodyContentType, exampleKey, requestBodyCompositionSelection)\n if (!example) {\n return null\n }\n\n // Form data - array format (from UI editor)\n if (\n (bodyContentType === 'multipart/form-data' || bodyContentType === 'application/x-www-form-urlencoded') &&\n Array.isArray(example.value)\n ) {\n const exampleValue = example.value.filter((item) => !item.isDisabled) as { name: string; value: unknown }[]\n const form = bodyContentType === 'multipart/form-data' ? new FormData() : new URLSearchParams()\n\n // Loop over all entries and add them to the form\n exampleValue.forEach(({ name, value }) => {\n if (!name) {\n return\n }\n const replacedName = replaceEnvVariables(name, env)\n const partContentType =\n form instanceof FormData\n ? getMultipartEncodingContentType(requestBody, bodyContentType, name, replacedName)\n : undefined\n\n // Handle file uploads\n if (value instanceof File && form instanceof FormData) {\n /**\n * We need to unwrap the proxies to get the file name due to the\n * \"this\" context in the proxy causing an illegal invocation error\n */\n const unwrappedValue = unpackProxyObject(value)\n const encodedValue =\n partContentType && partContentType !== unwrappedValue.type\n ? new File([unwrappedValue], unwrappedValue.name, {\n type: partContentType,\n lastModified: unwrappedValue.lastModified,\n })\n : unwrappedValue\n\n form.append(replacedName, encodedValue, encodedValue.name)\n }\n // Text and structured inputs\n else if (value !== undefined && value !== null) {\n const serializedValue = serializeMultipartValue(value, env)\n\n if (form instanceof FormData && partContentType) {\n form.append(replacedName, new Blob([serializedValue], { type: partContentType }))\n } else {\n form.append(replacedName, serializedValue)\n }\n }\n })\n\n return form\n }\n\n // Form data - object format (from schema examples)\n // When the example value is a plain object and content type is form-urlencoded,\n // convert to URLSearchParams instead of JSON stringifying\n if (\n bodyContentType === 'application/x-www-form-urlencoded' &&\n example.value !== null &&\n typeof example.value === 'object' &&\n !Array.isArray(example.value)\n ) {\n const form = new URLSearchParams()\n\n // Convert object properties to form fields\n for (const [key, value] of Object.entries(example.value)) {\n if (key && value !== undefined && value !== null) {\n const replacedKey = replaceEnvVariables(key, env)\n const stringValue = typeof value === 'string' ? value : String(value)\n form.append(replacedKey, replaceEnvVariables(stringValue, env))\n }\n }\n\n return form\n }\n\n const exampleValue =\n example.value !== null && typeof example.value === 'object' ? unpackProxyObject(example.value) : example.value\n\n if (exampleValue instanceof File) {\n return exampleValue\n }\n\n // Ensure we stringify the example value if it is an object\n if (typeof exampleValue === 'object') {\n return replaceEnvVariables(JSON.stringify(exampleValue), env)\n }\n\n // Return binary or string values\n return typeof exampleValue === 'string' ? replaceEnvVariables(exampleValue, env) : exampleValue\n}\n"],"mappings":";;;;;AAOA,IAAM,mCACJ,aACA,iBACA,WACA,sBAEA,YAAY,QAAQ,kBAAkB,WAAW,YAAY,eAC7D,YAAY,QAAQ,kBAAkB,WAAW,oBAAoB;AAEvE,IAAM,2BAA2B,OAAgB,QAAgC;AAC/E,KAAI,OAAO,UAAU,SACnB,QAAO,oBAAoB,OAAO,IAAI;AAMxC,QAAO,oBAFL,OAAO,UAAU,YAAY,UAAU,OAAO,KAAK,UAAU,kBAAkB,MAAM,CAAC,GAAG,OAAO,MAAM,EAE5D,IAAI;;;;;AAMlD,IAAa,oBACX,aAEA,MAA8B,EAAE,EAEhC,aAAa,WAEb,oCACoB;AACpB,KAAI,CAAC,YACH,QAAO;;CAIT,MAAM,kBAAkB,2BAA2B,aAAa,WAAW;AAC3E,KAAI,CAAC,gBACH,QAAO;;CAIT,MAAM,UAAU,mBAAmB,aAAa,iBAAiB,YAAY,gCAAgC;AAC7G,KAAI,CAAC,QACH,QAAO;AAIT,MACG,oBAAoB,yBAAyB,oBAAoB,wCAClE,MAAM,QAAQ,QAAQ,MAAM,EAC5B;EACA,MAAM,eAAe,QAAQ,MAAM,QAAQ,SAAS,CAAC,KAAK,WAAW;EACrE,MAAM,OAAO,oBAAoB,wBAAwB,IAAI,UAAU,GAAG,IAAI,iBAAiB;AAG/F,eAAa,SAAS,EAAE,MAAM,YAAY;AACxC,OAAI,CAAC,KACH;GAEF,MAAM,eAAe,oBAAoB,MAAM,IAAI;GACnD,MAAM,kBACJ,gBAAgB,WACZ,gCAAgC,aAAa,iBAAiB,MAAM,aAAa,GACjF,KAAA;AAGN,OAAI,iBAAiB,QAAQ,gBAAgB,UAAU;;;;;IAKrD,MAAM,iBAAiB,kBAAkB,MAAM;IAC/C,MAAM,eACJ,mBAAmB,oBAAoB,eAAe,OAClD,IAAI,KAAK,CAAC,eAAe,EAAE,eAAe,MAAM;KAC9C,MAAM;KACN,cAAc,eAAe;KAC9B,CAAC,GACF;AAEN,SAAK,OAAO,cAAc,cAAc,aAAa,KAAK;cAGnD,UAAU,KAAA,KAAa,UAAU,MAAM;IAC9C,MAAM,kBAAkB,wBAAwB,OAAO,IAAI;AAE3D,QAAI,gBAAgB,YAAY,gBAC9B,MAAK,OAAO,cAAc,IAAI,KAAK,CAAC,gBAAgB,EAAE,EAAE,MAAM,iBAAiB,CAAC,CAAC;QAEjF,MAAK,OAAO,cAAc,gBAAgB;;IAG9C;AAEF,SAAO;;AAMT,KACE,oBAAoB,uCACpB,QAAQ,UAAU,QAClB,OAAO,QAAQ,UAAU,YACzB,CAAC,MAAM,QAAQ,QAAQ,MAAM,EAC7B;EACA,MAAM,OAAO,IAAI,iBAAiB;AAGlC,OAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,QAAQ,MAAM,CACtD,KAAI,OAAO,UAAU,KAAA,KAAa,UAAU,MAAM;GAChD,MAAM,cAAc,oBAAoB,KAAK,IAAI;GACjD,MAAM,cAAc,OAAO,UAAU,WAAW,QAAQ,OAAO,MAAM;AACrE,QAAK,OAAO,aAAa,oBAAoB,aAAa,IAAI,CAAC;;AAInE,SAAO;;CAGT,MAAM,eACJ,QAAQ,UAAU,QAAQ,OAAO,QAAQ,UAAU,WAAW,kBAAkB,QAAQ,MAAM,GAAG,QAAQ;AAE3G,KAAI,wBAAwB,KAC1B,QAAO;AAIT,KAAI,OAAO,iBAAiB,SAC1B,QAAO,oBAAoB,KAAK,UAAU,aAAa,EAAE,IAAI;AAI/D,QAAO,OAAO,iBAAiB,WAAW,oBAAoB,cAAc,IAAI,GAAG"}
|
|
@@ -17,7 +17,7 @@ import type { SecuritySchemeObjectSecret } from '../../../../v2/blocks/scalar-au
|
|
|
17
17
|
*
|
|
18
18
|
* @returns A tuple containing either an error or the request object with an abort controller
|
|
19
19
|
*/
|
|
20
|
-
export declare const buildRequest: ({ environment, exampleKey, globalCookies, method, operation, path, proxyUrl, server, selectedSecuritySchemes, }: {
|
|
20
|
+
export declare const buildRequest: ({ environment, exampleKey, globalCookies, method, operation, path, proxyUrl, requestBodyCompositionSelection, server, selectedSecuritySchemes, }: {
|
|
21
21
|
/** For environment variables in the inputs */
|
|
22
22
|
environment: XScalarEnvironment;
|
|
23
23
|
/** The key of the current example */
|
|
@@ -32,6 +32,8 @@ export declare const buildRequest: ({ environment, exampleKey, globalCookies, me
|
|
|
32
32
|
path: string;
|
|
33
33
|
/** The proxy URL for cookie domain determination */
|
|
34
34
|
proxyUrl: string;
|
|
35
|
+
/** Selected anyOf/oneOf request-body variants keyed by schema path */
|
|
36
|
+
requestBodyCompositionSelection?: Record<string, number>;
|
|
35
37
|
/** The server object */
|
|
36
38
|
server: ServerObject | null;
|
|
37
39
|
/** The selected security schemes for the current operation */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-request.d.ts","sourceRoot":"","sources":["../../../../../src/v2/blocks/operation-block/helpers/build-request.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAA;AAGnE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2EAA2E,CAAA;AACnH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qEAAqE,CAAA;AACxG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8DAA8D,CAAA;AAChG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uDAAuD,CAAA;AAG5F,OAAO,EAAU,KAAK,aAAa,EAAkB,MAAM,eAAe,CAAA;AAI1E,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,6DAA6D,CAAA;AAO7G;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,YAAY,GAAI,
|
|
1
|
+
{"version":3,"file":"build-request.d.ts","sourceRoot":"","sources":["../../../../../src/v2/blocks/operation-block/helpers/build-request.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAA;AAGnE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2EAA2E,CAAA;AACnH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qEAAqE,CAAA;AACxG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8DAA8D,CAAA;AAChG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uDAAuD,CAAA;AAG5F,OAAO,EAAU,KAAK,aAAa,EAAkB,MAAM,eAAe,CAAA;AAI1E,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,6DAA6D,CAAA;AAO7G;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,YAAY,GAAI,kJAW1B;IACD,8CAA8C;IAC9C,WAAW,EAAE,kBAAkB,CAAA;IAC/B,qCAAqC;IACrC,UAAU,EAAE,MAAM,CAAA;IAClB,mCAAmC;IACnC,aAAa,EAAE,aAAa,EAAE,CAAA;IAC9B,uCAAuC;IACvC,MAAM,EAAE,UAAU,CAAA;IAClB,2BAA2B;IAC3B,SAAS,EAAE,eAAe,CAAA;IAC1B,gCAAgC;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,oDAAoD;IACpD,QAAQ,EAAE,MAAM,CAAA;IAChB,sEAAsE;IACtE,+BAA+B,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACxD,wBAAwB;IACxB,MAAM,EAAE,YAAY,GAAG,IAAI,CAAA;IAC3B,8DAA8D;IAC9D,uBAAuB,EAAE,0BAA0B,EAAE,CAAA;CACtD,KAAG,aAAa,CAAC;IAChB,UAAU,EAAE,eAAe,CAAA;IAC3B,OAAO,EAAE,OAAO,CAAA;IAChB,YAAY,EAAE,OAAO,CAAA;CACtB,CA6GA,CAAA"}
|
|
@@ -23,7 +23,7 @@ import { canMethodHaveBody } from "@scalar/helpers/http/can-method-have-body";
|
|
|
23
23
|
*
|
|
24
24
|
* @returns A tuple containing either an error or the request object with an abort controller
|
|
25
25
|
*/
|
|
26
|
-
var buildRequest = ({ environment, exampleKey = "default", globalCookies, method, operation, path, proxyUrl, server, selectedSecuritySchemes }) => {
|
|
26
|
+
var buildRequest = ({ environment, exampleKey = "default", globalCookies, method, operation, path, proxyUrl, requestBodyCompositionSelection, server, selectedSecuritySchemes }) => {
|
|
27
27
|
try {
|
|
28
28
|
const requestBody = getResolvedRef(operation.requestBody);
|
|
29
29
|
/** Flatten the environment variables array into a key-value object */
|
|
@@ -46,7 +46,7 @@ var buildRequest = ({ environment, exampleKey = "default", globalCookies, method
|
|
|
46
46
|
...security.headers
|
|
47
47
|
});
|
|
48
48
|
const urlParams = new URLSearchParams([...params.urlParams, ...security.urlParams]);
|
|
49
|
-
const body = canMethodHaveBody(method) ? buildRequestBody(requestBody, env, exampleKey) : null;
|
|
49
|
+
const body = canMethodHaveBody(method) ? buildRequestBody(requestBody, env, exampleKey, requestBodyCompositionSelection) : null;
|
|
50
50
|
if (body && (body instanceof FormData || body instanceof URLSearchParams)) headers.delete("Content-Type");
|
|
51
51
|
/** Combine the server url, path and url params into a single url */
|
|
52
52
|
const url = getResolvedUrl({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-request.js","names":[],"sources":["../../../../../src/v2/blocks/operation-block/helpers/build-request.ts"],"sourcesContent":["import { canMethodHaveBody } from '@scalar/helpers/http/can-method-have-body'\nimport type { HttpMethod } from '@scalar/helpers/http/http-methods'\nimport { redirectToProxy, shouldUseProxy } from '@scalar/helpers/url/redirect-to-proxy'\nimport { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport type { XScalarCookie } from '@scalar/workspace-store/schemas/extensions/general/x-scalar-cookies'\nimport type { ServerObject } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport type { OperationObject } from '@scalar/workspace-store/schemas/v3.1/strict/operation'\n\nimport { isElectron } from '@/libs/electron'\nimport { ERRORS, type ErrorResponse, normalizeError } from '@/libs/errors'\nimport { getEnvironmentVariables } from '@/v2/blocks/operation-block/helpers/get-environment-variables'\nimport { getResolvedUrl } from '@/v2/blocks/operation-block/helpers/get-resolved-url'\nimport { getDefaultHeaders } from '@/v2/blocks/request-block/helpers/get-default-headers'\nimport type { SecuritySchemeObjectSecret } from '@/v2/blocks/scalar-auth-selector-block/helpers/secret-types'\n\nimport { buildRequestBody } from './build-request-body'\nimport { buildRequestCookieHeader } from './build-request-cookie-header'\nimport { buildRequestParameters } from './build-request-parameters'\nimport { buildRequestSecurity } from './build-request-security'\n\n/**\n * Builds a fully configured Request object ready for execution.\n *\n * This function processes an OpenAPI operation and constructs a fetch-compatible\n * Request by resolving environment variables, applying security schemes, building\n * headers and cookies, handling proxy redirection, and preparing the request body.\n *\n * The function handles special cases like Electron environments and proxy usage\n * where custom cookie headers are required.\n *\n * @returns A tuple containing either an error or the request object with an abort controller\n */\nexport const buildRequest = ({\n environment,\n exampleKey = 'default',\n globalCookies,\n method,\n operation,\n path,\n proxyUrl,\n server,\n selectedSecuritySchemes,\n}: {\n /** For environment variables in the inputs */\n environment: XScalarEnvironment\n /** The key of the current example */\n exampleKey: string\n /** Workspace + document cookies */\n globalCookies: XScalarCookie[]\n /** The HTTP method of the operation */\n method: HttpMethod\n /** The operation object */\n operation: OperationObject\n /** The path of the operation */\n path: string\n /** The proxy URL for cookie domain determination */\n proxyUrl: string\n /** The server object */\n server: ServerObject | null\n /** The selected security schemes for the current operation */\n selectedSecuritySchemes: SecuritySchemeObjectSecret[]\n}): ErrorResponse<{\n controller: AbortController\n request: Request\n isUsingProxy: boolean\n}> => {\n try {\n const requestBody = getResolvedRef(operation.requestBody)\n\n /** Flatten the environment variables array into a key-value object */\n const env = getEnvironmentVariables(environment)\n /** Build out the request parameters */\n const params = buildRequestParameters(operation.parameters ?? [], env, exampleKey)\n const security = buildRequestSecurity(selectedSecuritySchemes, env)\n\n // Combine the headers, cookies and url params\n const defaultHeaders = getDefaultHeaders({ method, operation, exampleKey, hideDisabledHeaders: true })\n .filter((header) => !header.isOverridden)\n .reduce(\n (acc, header) => {\n acc[header.name] = header.defaultValue\n return acc\n },\n {} as Record<string, string>,\n )\n const headers = new Headers({ ...defaultHeaders, ...params.headers, ...security.headers })\n const urlParams = new URLSearchParams([...params.urlParams, ...security.urlParams])\n\n // If the method can have a body, build the request body, otherwise set it to null\n const body = canMethodHaveBody(method)
|
|
1
|
+
{"version":3,"file":"build-request.js","names":[],"sources":["../../../../../src/v2/blocks/operation-block/helpers/build-request.ts"],"sourcesContent":["import { canMethodHaveBody } from '@scalar/helpers/http/can-method-have-body'\nimport type { HttpMethod } from '@scalar/helpers/http/http-methods'\nimport { redirectToProxy, shouldUseProxy } from '@scalar/helpers/url/redirect-to-proxy'\nimport { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport type { XScalarCookie } from '@scalar/workspace-store/schemas/extensions/general/x-scalar-cookies'\nimport type { ServerObject } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport type { OperationObject } from '@scalar/workspace-store/schemas/v3.1/strict/operation'\n\nimport { isElectron } from '@/libs/electron'\nimport { ERRORS, type ErrorResponse, normalizeError } from '@/libs/errors'\nimport { getEnvironmentVariables } from '@/v2/blocks/operation-block/helpers/get-environment-variables'\nimport { getResolvedUrl } from '@/v2/blocks/operation-block/helpers/get-resolved-url'\nimport { getDefaultHeaders } from '@/v2/blocks/request-block/helpers/get-default-headers'\nimport type { SecuritySchemeObjectSecret } from '@/v2/blocks/scalar-auth-selector-block/helpers/secret-types'\n\nimport { buildRequestBody } from './build-request-body'\nimport { buildRequestCookieHeader } from './build-request-cookie-header'\nimport { buildRequestParameters } from './build-request-parameters'\nimport { buildRequestSecurity } from './build-request-security'\n\n/**\n * Builds a fully configured Request object ready for execution.\n *\n * This function processes an OpenAPI operation and constructs a fetch-compatible\n * Request by resolving environment variables, applying security schemes, building\n * headers and cookies, handling proxy redirection, and preparing the request body.\n *\n * The function handles special cases like Electron environments and proxy usage\n * where custom cookie headers are required.\n *\n * @returns A tuple containing either an error or the request object with an abort controller\n */\nexport const buildRequest = ({\n environment,\n exampleKey = 'default',\n globalCookies,\n method,\n operation,\n path,\n proxyUrl,\n requestBodyCompositionSelection,\n server,\n selectedSecuritySchemes,\n}: {\n /** For environment variables in the inputs */\n environment: XScalarEnvironment\n /** The key of the current example */\n exampleKey: string\n /** Workspace + document cookies */\n globalCookies: XScalarCookie[]\n /** The HTTP method of the operation */\n method: HttpMethod\n /** The operation object */\n operation: OperationObject\n /** The path of the operation */\n path: string\n /** The proxy URL for cookie domain determination */\n proxyUrl: string\n /** Selected anyOf/oneOf request-body variants keyed by schema path */\n requestBodyCompositionSelection?: Record<string, number>\n /** The server object */\n server: ServerObject | null\n /** The selected security schemes for the current operation */\n selectedSecuritySchemes: SecuritySchemeObjectSecret[]\n}): ErrorResponse<{\n controller: AbortController\n request: Request\n isUsingProxy: boolean\n}> => {\n try {\n const requestBody = getResolvedRef(operation.requestBody)\n\n /** Flatten the environment variables array into a key-value object */\n const env = getEnvironmentVariables(environment)\n /** Build out the request parameters */\n const params = buildRequestParameters(operation.parameters ?? [], env, exampleKey)\n const security = buildRequestSecurity(selectedSecuritySchemes, env)\n\n // Combine the headers, cookies and url params\n const defaultHeaders = getDefaultHeaders({ method, operation, exampleKey, hideDisabledHeaders: true })\n .filter((header) => !header.isOverridden)\n .reduce(\n (acc, header) => {\n acc[header.name] = header.defaultValue\n return acc\n },\n {} as Record<string, string>,\n )\n const headers = new Headers({ ...defaultHeaders, ...params.headers, ...security.headers })\n const urlParams = new URLSearchParams([...params.urlParams, ...security.urlParams])\n\n // If the method can have a body, build the request body, otherwise set it to null\n const body = canMethodHaveBody(method)\n ? buildRequestBody(requestBody, env, exampleKey, requestBodyCompositionSelection)\n : null\n\n if (body && (body instanceof FormData || body instanceof URLSearchParams)) {\n // Delete the Content-Type header so the browser will set it automatically based on the request body\n headers.delete('Content-Type')\n }\n\n /** Combine the server url, path and url params into a single url */\n const url = getResolvedUrl({\n environment,\n server,\n path,\n pathVariables: params.pathVariables,\n allowReservedQueryParameters: params.allowReservedQueryParameters,\n urlParams,\n })\n\n // Throw for no server or path\n if (!url) {\n throw ERRORS.URL_EMPTY\n }\n\n const isUsingProxy = shouldUseProxy(proxyUrl, url)\n const proxiedUrl = redirectToProxy(proxyUrl, url)\n\n // If we are running in Electron, we need to add a custom header\n // that's then forwarded as a `User-Agent` header.\n const userAgentHeader = headers.get('User-Agent')\n if (isElectron() && userAgentHeader) {\n headers.set('X-Scalar-User-Agent', userAgentHeader)\n }\n\n /** Build out the cookies header */\n const cookiesHeader = buildRequestCookieHeader({\n paramCookies: [...params.cookies, ...security.cookies],\n globalCookies,\n env,\n originalCookieHeader: headers.get('Cookie'),\n url,\n useCustomCookieHeader: isElectron() || isUsingProxy,\n disabledGlobalCookies: operation['x-scalar-disable-parameters']?.['global-cookies']?.[exampleKey] ?? {},\n })\n\n if (cookiesHeader) {\n headers.set(cookiesHeader.name, cookiesHeader.value)\n }\n\n /** Controller to allow aborting the request */\n const controller = new AbortController()\n const acceptHeader = headers.get('Accept')\n const isSseAcceptHeader = acceptHeader?.toLowerCase().includes('text/event-stream') ?? false\n const requestCacheMode: RequestCache = isSseAcceptHeader ? 'no-store' : 'default'\n\n if (isSseAcceptHeader) {\n headers.set('Cache-Control', 'no-cache')\n headers.set('Pragma', 'no-cache')\n }\n\n /** Build the js request object */\n const request = new Request(proxiedUrl, {\n /**\n * Ensure that all methods are uppercased (though only needed for patch)\n *\n * @see https://github.com/whatwg/fetch/issues/50\n */\n method: method.toUpperCase(),\n headers,\n signal: controller.signal,\n body,\n cache: requestCacheMode,\n })\n\n return [\n null,\n {\n controller,\n isUsingProxy,\n request,\n },\n ]\n } catch (error) {\n return [normalizeError(error, ERRORS.BUILDING_REQUEST_FAILED), null]\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAiCA,IAAa,gBAAgB,EAC3B,aACA,aAAa,WACb,eACA,QACA,WACA,MACA,UACA,iCACA,QACA,8BA0BI;AACJ,KAAI;EACF,MAAM,cAAc,eAAe,UAAU,YAAY;;EAGzD,MAAM,MAAM,wBAAwB,YAAY;;EAEhD,MAAM,SAAS,uBAAuB,UAAU,cAAc,EAAE,EAAE,KAAK,WAAW;EAClF,MAAM,WAAW,qBAAqB,yBAAyB,IAAI;EAGnE,MAAM,iBAAiB,kBAAkB;GAAE;GAAQ;GAAW;GAAY,qBAAqB;GAAM,CAAC,CACnG,QAAQ,WAAW,CAAC,OAAO,aAAa,CACxC,QACE,KAAK,WAAW;AACf,OAAI,OAAO,QAAQ,OAAO;AAC1B,UAAO;KAET,EAAE,CACH;EACH,MAAM,UAAU,IAAI,QAAQ;GAAE,GAAG;GAAgB,GAAG,OAAO;GAAS,GAAG,SAAS;GAAS,CAAC;EAC1F,MAAM,YAAY,IAAI,gBAAgB,CAAC,GAAG,OAAO,WAAW,GAAG,SAAS,UAAU,CAAC;EAGnF,MAAM,OAAO,kBAAkB,OAAO,GAClC,iBAAiB,aAAa,KAAK,YAAY,gCAAgC,GAC/E;AAEJ,MAAI,SAAS,gBAAgB,YAAY,gBAAgB,iBAEvD,SAAQ,OAAO,eAAe;;EAIhC,MAAM,MAAM,eAAe;GACzB;GACA;GACA;GACA,eAAe,OAAO;GACtB,8BAA8B,OAAO;GACrC;GACD,CAAC;AAGF,MAAI,CAAC,IACH,OAAM,OAAO;EAGf,MAAM,eAAe,eAAe,UAAU,IAAI;EAClD,MAAM,aAAa,gBAAgB,UAAU,IAAI;EAIjD,MAAM,kBAAkB,QAAQ,IAAI,aAAa;AACjD,MAAI,YAAY,IAAI,gBAClB,SAAQ,IAAI,uBAAuB,gBAAgB;;EAIrD,MAAM,gBAAgB,yBAAyB;GAC7C,cAAc,CAAC,GAAG,OAAO,SAAS,GAAG,SAAS,QAAQ;GACtD;GACA;GACA,sBAAsB,QAAQ,IAAI,SAAS;GAC3C;GACA,uBAAuB,YAAY,IAAI;GACvC,uBAAuB,UAAU,iCAAiC,oBAAoB,eAAe,EAAE;GACxG,CAAC;AAEF,MAAI,cACF,SAAQ,IAAI,cAAc,MAAM,cAAc,MAAM;;EAItD,MAAM,aAAa,IAAI,iBAAiB;EAExC,MAAM,oBADe,QAAQ,IAAI,SAAS,EACF,aAAa,CAAC,SAAS,oBAAoB,IAAI;EACvF,MAAM,mBAAiC,oBAAoB,aAAa;AAExE,MAAI,mBAAmB;AACrB,WAAQ,IAAI,iBAAiB,WAAW;AACxC,WAAQ,IAAI,UAAU,WAAW;;AAiBnC,SAAO,CACL,MACA;GACE;GACA;GACA,SAlBY,IAAI,QAAQ,YAAY;IAMtC,QAAQ,OAAO,aAAa;IAC5B;IACA,QAAQ,WAAW;IACnB;IACA,OAAO;IACR,CAAC;GAQC,CACF;UACM,OAAO;AACd,SAAO,CAAC,eAAe,OAAO,OAAO,wBAAwB,EAAE,KAAK"}
|
|
@@ -97,6 +97,11 @@ export type OperationCodeSampleProps = {
|
|
|
97
97
|
* Workspace + document cookies
|
|
98
98
|
*/
|
|
99
99
|
globalCookies?: XScalarCookie[];
|
|
100
|
+
/**
|
|
101
|
+
* When the request body schema uses oneOf/anyOf, use these selected variants
|
|
102
|
+
* for the example snippet (e.g. from the schema dropdowns in the API reference).
|
|
103
|
+
*/
|
|
104
|
+
requestBodyCompositionSelection?: Record<string, number>;
|
|
100
105
|
};
|
|
101
106
|
/**
|
|
102
107
|
* Request Example
|