@scalar/api-client 3.22.0 → 3.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/dist/hooks/use-file-dialog.js +1 -1
- package/dist/hooks/use-file-dialog.js.map +1 -1
- package/dist/style.css +64 -50
- package/dist/v2/blocks/operation-block/helpers/persist-response-cookies.d.ts +3 -3
- package/dist/v2/blocks/operation-block/helpers/persist-response-cookies.d.ts.map +1 -1
- package/dist/v2/blocks/operation-block/helpers/persist-response-cookies.js +4 -4
- package/dist/v2/blocks/operation-block/helpers/persist-response-cookies.js.map +1 -1
- package/dist/v2/blocks/operation-block/helpers/validate-path-parameters.js +1 -1
- package/dist/v2/blocks/operation-block/helpers/validate-path-parameters.js.map +1 -1
- package/dist/v2/blocks/request-block/RequestBlock.vue.d.ts.map +1 -1
- package/dist/v2/blocks/request-block/RequestBlock.vue.js +1 -1
- package/dist/v2/blocks/request-block/RequestBlock.vue.js.map +1 -1
- package/dist/v2/blocks/request-block/RequestBlock.vue.script.js +13 -8
- package/dist/v2/blocks/request-block/RequestBlock.vue.script.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestBody.vue.d.ts.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestBody.vue.js +1 -1
- package/dist/v2/blocks/request-block/components/RequestBody.vue.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestBody.vue.script.js +3 -1
- package/dist/v2/blocks/request-block/components/RequestBody.vue.script.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestBodyForm.vue.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestBodyForm.vue.script.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestParams.vue.d.ts +12 -0
- package/dist/v2/blocks/request-block/components/RequestParams.vue.d.ts.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestParams.vue.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestParams.vue.script.js +132 -32
- package/dist/v2/blocks/request-block/components/RequestParams.vue.script.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestTable.vue.d.ts +3 -1
- package/dist/v2/blocks/request-block/components/RequestTable.vue.d.ts.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestTable.vue.js +1 -1
- package/dist/v2/blocks/request-block/components/RequestTable.vue.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestTable.vue.script.js +13 -2
- package/dist/v2/blocks/request-block/components/RequestTable.vue.script.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestTableRow.vue.d.ts +3 -1
- package/dist/v2/blocks/request-block/components/RequestTableRow.vue.d.ts.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestTableRow.vue.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestTableRow.vue.script.js +6 -2
- package/dist/v2/blocks/request-block/components/RequestTableRow.vue.script.js.map +1 -1
- package/dist/v2/blocks/request-block/helpers/create-parameter-handlers.d.ts.map +1 -1
- package/dist/v2/blocks/request-block/helpers/create-parameter-handlers.js +10 -3
- package/dist/v2/blocks/request-block/helpers/create-parameter-handlers.js.map +1 -1
- package/dist/v2/blocks/request-block/helpers/create-parameter-rows.d.ts.map +1 -1
- package/dist/v2/blocks/request-block/helpers/create-parameter-rows.js +10 -1
- package/dist/v2/blocks/request-block/helpers/create-parameter-rows.js.map +1 -1
- package/dist/v2/blocks/request-block/helpers/get-form-body-rows.js +1 -1
- package/dist/v2/blocks/request-block/helpers/get-form-body-rows.js.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue.d.ts.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue.js.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue.script.js +55 -16
- package/dist/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue.script.js.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthDataTableInput.vue.d.ts +3 -3
- package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthDataTableInput.vue.d.ts.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthDataTableInput.vue.js.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthDataTableInput.vue.script.js +20 -7
- package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthDataTableInput.vue.script.js.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue.d.ts.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue.js.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue.script.js +32 -27
- package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue.script.js.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/helpers/openid-discovery-to-flows.d.ts.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/helpers/openid-discovery-to-flows.js +2 -1
- package/dist/v2/blocks/scalar-auth-selector-block/helpers/openid-discovery-to-flows.js.map +1 -1
- package/dist/v2/components/code-input/PillTooltipHost.vue.d.ts.map +1 -1
- package/dist/v2/components/code-input/PillTooltipHost.vue.js.map +1 -1
- package/dist/v2/components/code-input/PillTooltipHost.vue.script.js +4 -1
- package/dist/v2/components/code-input/PillTooltipHost.vue.script.js.map +1 -1
- package/dist/v2/components/code-input/code-variable-widget.js +1 -1
- package/dist/v2/components/code-input/code-variable-widget.js.map +1 -1
- package/dist/v2/components/data-table/DataTableInput.vue.d.ts +3 -1
- package/dist/v2/components/data-table/DataTableInput.vue.d.ts.map +1 -1
- package/dist/v2/components/data-table/DataTableInput.vue.js +1 -1
- package/dist/v2/components/data-table/DataTableInput.vue.js.map +1 -1
- package/dist/v2/components/data-table/DataTableInput.vue.script.js +46 -15
- package/dist/v2/components/data-table/DataTableInput.vue.script.js.map +1 -1
- package/dist/v2/constants.js +1 -1
- package/dist/v2/features/localization/index.d.ts.map +1 -1
- package/dist/v2/features/localization/index.js +2 -0
- package/dist/v2/features/localization/index.js.map +1 -1
- package/dist/v2/features/localization/locales/ar.d.ts +3 -0
- package/dist/v2/features/localization/locales/ar.d.ts.map +1 -1
- package/dist/v2/features/localization/locales/ar.js +3 -0
- package/dist/v2/features/localization/locales/ar.js.map +1 -1
- package/dist/v2/features/localization/locales/de.d.ts +3 -0
- package/dist/v2/features/localization/locales/de.d.ts.map +1 -1
- package/dist/v2/features/localization/locales/de.js +3 -0
- package/dist/v2/features/localization/locales/de.js.map +1 -1
- package/dist/v2/features/localization/locales/es.d.ts +3 -0
- package/dist/v2/features/localization/locales/es.d.ts.map +1 -1
- package/dist/v2/features/localization/locales/es.js +3 -0
- package/dist/v2/features/localization/locales/es.js.map +1 -1
- package/dist/v2/features/localization/locales/fr.d.ts +3 -0
- package/dist/v2/features/localization/locales/fr.d.ts.map +1 -1
- package/dist/v2/features/localization/locales/fr.js +3 -0
- package/dist/v2/features/localization/locales/fr.js.map +1 -1
- package/dist/v2/features/localization/locales/pt.d.ts +3 -0
- package/dist/v2/features/localization/locales/pt.d.ts.map +1 -1
- package/dist/v2/features/localization/locales/pt.js +3 -0
- package/dist/v2/features/localization/locales/pt.js.map +1 -1
- package/dist/v2/features/localization/locales/ru.d.ts +3 -0
- package/dist/v2/features/localization/locales/ru.d.ts.map +1 -1
- package/dist/v2/features/localization/locales/ru.js +3 -0
- package/dist/v2/features/localization/locales/ru.js.map +1 -1
- package/dist/v2/features/localization/locales/zh-cn.d.ts +3 -0
- package/dist/v2/features/localization/locales/zh-cn.d.ts.map +1 -1
- package/dist/v2/features/localization/locales/zh-cn.js +3 -0
- package/dist/v2/features/localization/locales/zh-cn.js.map +1 -1
- package/dist/v2/features/localization/locales/zh-tw.d.ts +398 -0
- package/dist/v2/features/localization/locales/zh-tw.d.ts.map +1 -0
- package/dist/v2/features/localization/locales/zh-tw.js +360 -0
- package/dist/v2/features/localization/locales/zh-tw.js.map +1 -0
- package/dist/v2/features/localization/translations.d.ts +3 -0
- package/dist/v2/features/localization/translations.d.ts.map +1 -1
- package/dist/v2/features/localization/translations.js +3 -0
- package/dist/v2/features/localization/translations.js.map +1 -1
- package/dist/v2/features/modal/index.d.ts +1 -1
- package/dist/v2/features/modal/index.d.ts.map +1 -1
- package/dist/v2/helpers/handle-hotkeys.d.ts.map +1 -1
- package/dist/v2/helpers/handle-hotkeys.js +4 -1
- package/dist/v2/helpers/handle-hotkeys.js.map +1 -1
- package/dist/vue-styles.css +15 -15
- package/package.json +13 -13
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @scalar/api-client
|
|
2
2
|
|
|
3
|
+
## 3.23.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#10555](https://github.com/scalar/scalar/pull/10555): Show empty optional fields of expanded object query parameters in a searchable Add parameter picker.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- [#10551](https://github.com/scalar/scalar/pull/10551): Show **Reset to default** on authentication fields only when the field has a default that differs from its current value (the document or configured value, or the current page URL for the OAuth2 redirect URL). A cleared OAuth2 access token keeps the action so you can get back to the Authorize form. The show password toggle only appears once a field has a value, and an emptied field goes back to masked.
|
|
12
|
+
- [#10559](https://github.com/scalar/scalar/pull/10559): Clean up Biome warnings in package code and tests. Handle rejected debounced callbacks and await streaming writes.
|
|
13
|
+
- [#10555](https://github.com/scalar/scalar/pull/10555): Keep expanded query parameter checkboxes independent and preserve disabled field values while excluding them from requests.
|
|
14
|
+
- [#10506](https://github.com/scalar/scalar/pull/10506): Organize imports consistently with the checks enforced in CI.
|
|
15
|
+
- [#10534](https://github.com/scalar/scalar/pull/10534): Keep **Authorize via OAuth2** rightmost in the bearer token's "Get a token" row, with the settings gear to its left and **Refresh** in between, so the button never moves when Refresh appears.
|
|
16
|
+
- [#10547](https://github.com/scalar/scalar/pull/10547): Respect Max-Age precedence over Expires when persisting response cookies.
|
|
17
|
+
- [#10508](https://github.com/scalar/scalar/pull/10508): Add built-in Traditional Chinese (Taiwan) translations for `zh-TW`, including case and underscore variants, across API Reference, API Client, and schema blocks.
|
|
18
|
+
|
|
3
19
|
## 3.22.0
|
|
4
20
|
|
|
5
21
|
### Minor Changes
|
|
@@ -14,7 +14,7 @@ function useFileDialog({ multiple, accept, onChange, onError } = {}) {
|
|
|
14
14
|
if (!(event.target instanceof HTMLInputElement)) return;
|
|
15
15
|
const result = event.target;
|
|
16
16
|
files.value = result.files;
|
|
17
|
-
onChange?.(files.value);
|
|
17
|
+
return onChange?.(files.value);
|
|
18
18
|
};
|
|
19
19
|
input.onerror = () => onError?.();
|
|
20
20
|
input.multiple = multiple;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-file-dialog.js","names":[],"sources":["../../src/hooks/use-file-dialog.ts"],"sourcesContent":["import { readonly, ref } from 'vue'\n\ntype UseFileDialogOptions = {\n multiple?: boolean\n /** @default '*' */\n accept?: string\n onChange?: (files: FileList | null) => void | Promise<void>\n onError?: () => void | Promise<void>\n}\n\n/**\n * Simplified interface for opening a file picker dialog\n * Derived from vueuse @see https://vueuse.org/useFileDialog\n */\nexport function useFileDialog({ multiple, accept, onChange, onError }: UseFileDialogOptions = {}) {\n const files = ref<FileList | null>(null)\n\n let input: HTMLInputElement | undefined\n if (typeof document !== 'undefined') {\n input = document.createElement('input')\n input.type = 'file'\n\n input.onchange = (event: Event) => {\n if (!(event.target instanceof HTMLInputElement)) {\n return\n }\n const result = event.target\n files.value = result.files\n onChange?.(files.value)\n }\n\n input.onerror = () => onError?.()\n\n input.multiple = multiple!\n input.accept = accept!\n }\n\n const open = () => {\n if (!input) {\n return onError?.()\n }\n\n input.click()\n }\n\n return {\n files: readonly(files),\n open,\n }\n}\n"],"mappings":";;;;;;AAcA,SAAgB,cAAc,EAAE,UAAU,QAAQ,UAAU,YAAkC,CAAC,GAAG;CAChG,MAAM,QAAQ,IAAqB,IAAI;CAEvC,IAAI;CACJ,IAAI,OAAO,aAAa,aAAa;EACnC,QAAQ,SAAS,cAAc,OAAO;EACtC,MAAM,OAAO;EAEb,MAAM,YAAY,UAAiB;GACjC,IAAI,EAAE,MAAM,kBAAkB,mBAC5B;GAEF,MAAM,SAAS,MAAM;GACrB,MAAM,QAAQ,OAAO;GACrB,WAAW,MAAM,KAAK;
|
|
1
|
+
{"version":3,"file":"use-file-dialog.js","names":[],"sources":["../../src/hooks/use-file-dialog.ts"],"sourcesContent":["import { readonly, ref } from 'vue'\n\ntype UseFileDialogOptions = {\n multiple?: boolean\n /** @default '*' */\n accept?: string\n onChange?: (files: FileList | null) => void | Promise<void>\n onError?: () => void | Promise<void>\n}\n\n/**\n * Simplified interface for opening a file picker dialog\n * Derived from vueuse @see https://vueuse.org/useFileDialog\n */\nexport function useFileDialog({ multiple, accept, onChange, onError }: UseFileDialogOptions = {}) {\n const files = ref<FileList | null>(null)\n\n let input: HTMLInputElement | undefined\n if (typeof document !== 'undefined') {\n input = document.createElement('input')\n input.type = 'file'\n\n input.onchange = (event: Event) => {\n if (!(event.target instanceof HTMLInputElement)) {\n return\n }\n const result = event.target\n files.value = result.files\n return onChange?.(files.value)\n }\n\n input.onerror = () => onError?.()\n\n input.multiple = multiple!\n input.accept = accept!\n }\n\n const open = () => {\n if (!input) {\n return onError?.()\n }\n\n input.click()\n }\n\n return {\n files: readonly(files),\n open,\n }\n}\n"],"mappings":";;;;;;AAcA,SAAgB,cAAc,EAAE,UAAU,QAAQ,UAAU,YAAkC,CAAC,GAAG;CAChG,MAAM,QAAQ,IAAqB,IAAI;CAEvC,IAAI;CACJ,IAAI,OAAO,aAAa,aAAa;EACnC,QAAQ,SAAS,cAAc,OAAO;EACtC,MAAM,OAAO;EAEb,MAAM,YAAY,UAAiB;GACjC,IAAI,EAAE,MAAM,kBAAkB,mBAC5B;GAEF,MAAM,SAAS,MAAM;GACrB,MAAM,QAAQ,OAAO;GACrB,OAAO,WAAW,MAAM,KAAK;EAC/B;EAEA,MAAM,gBAAgB,UAAU;EAEhC,MAAM,WAAW;EACjB,MAAM,SAAS;CACjB;CAEA,MAAM,aAAa;EACjB,IAAI,CAAC,OACH,OAAO,UAAU;EAGnB,MAAM,MAAM;CACd;CAEA,OAAO;EACL,OAAO,SAAS,KAAK;EACrB;CACF;AACF"}
|
package/dist/style.css
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
@supports (((-webkit-hyphens: none)) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color: rgb(from red r g b)))) {
|
|
4
4
|
*, :before, :after, ::backdrop {
|
|
5
5
|
--tw-font-weight: initial;
|
|
6
|
-
--tw-border-style: solid;
|
|
7
6
|
--tw-shadow: 0 0 #0000;
|
|
8
7
|
--tw-shadow-color: initial;
|
|
9
8
|
--tw-shadow-alpha: 100%;
|
|
@@ -40,6 +39,7 @@
|
|
|
40
39
|
--tw-skew-y: initial;
|
|
41
40
|
--tw-space-x-reverse: 0;
|
|
42
41
|
--tw-divide-y-reverse: 0;
|
|
42
|
+
--tw-border-style: solid;
|
|
43
43
|
--tw-gradient-position: initial;
|
|
44
44
|
--tw-gradient-from: #0000;
|
|
45
45
|
--tw-gradient-via: #0000;
|
|
@@ -1734,10 +1734,9 @@
|
|
|
1734
1734
|
|
|
1735
1735
|
:where(body, dialog) > .scalar-tooltip:before {
|
|
1736
1736
|
content: "";
|
|
1737
|
+
border: var(--scalar-border-width) solid var(--scalar-border-color);
|
|
1737
1738
|
z-index: calc(1 * -1);
|
|
1738
1739
|
border-radius: var(--scalar-radius-lg);
|
|
1739
|
-
border-style: var(--tw-border-style);
|
|
1740
|
-
border-width: var(--scalar-border-width);
|
|
1741
1740
|
background-color: var(--scalar-tooltip-background);
|
|
1742
1741
|
--tw-shadow: var(--scalar-shadow-1);
|
|
1743
1742
|
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
|
@@ -1769,12 +1768,6 @@
|
|
|
1769
1768
|
inherits: false
|
|
1770
1769
|
}
|
|
1771
1770
|
|
|
1772
|
-
@property --tw-border-style {
|
|
1773
|
-
syntax: "*";
|
|
1774
|
-
inherits: false;
|
|
1775
|
-
initial-value: solid;
|
|
1776
|
-
}
|
|
1777
|
-
|
|
1778
1771
|
@property --tw-shadow {
|
|
1779
1772
|
syntax: "*";
|
|
1780
1773
|
inherits: false;
|
|
@@ -1920,17 +1913,17 @@
|
|
|
1920
1913
|
border-radius: var(--scalar-radius);
|
|
1921
1914
|
}
|
|
1922
1915
|
|
|
1923
|
-
.request-card[data-v-
|
|
1916
|
+
.request-card[data-v-5374efff] {
|
|
1924
1917
|
color: var(--scalar-color-1);
|
|
1925
1918
|
font-size: var(--scalar-font-size-3);
|
|
1926
1919
|
}
|
|
1927
1920
|
|
|
1928
|
-
.request-method[data-v-
|
|
1921
|
+
.request-method[data-v-5374efff] {
|
|
1929
1922
|
font-family: var(--scalar-font-code);
|
|
1930
1923
|
margin-right: 6px;
|
|
1931
1924
|
}
|
|
1932
1925
|
|
|
1933
|
-
.request-card-footer[data-v-
|
|
1926
|
+
.request-card-footer[data-v-5374efff] {
|
|
1934
1927
|
flex-shrink: 0;
|
|
1935
1928
|
justify-content: flex-end;
|
|
1936
1929
|
padding: 6px;
|
|
@@ -1938,19 +1931,30 @@
|
|
|
1938
1931
|
position: relative;
|
|
1939
1932
|
}
|
|
1940
1933
|
|
|
1941
|
-
.request-card-footer
|
|
1934
|
+
.request-card-footer--wraps[data-v-5374efff] {
|
|
1935
|
+
flex-wrap: wrap;
|
|
1936
|
+
row-gap: 4px;
|
|
1937
|
+
}
|
|
1938
|
+
|
|
1939
|
+
.request-card-footer-start[data-v-5374efff] {
|
|
1940
|
+
flex: 1 0 auto;
|
|
1941
|
+
align-items: center;
|
|
1942
|
+
display: flex;
|
|
1943
|
+
}
|
|
1944
|
+
|
|
1945
|
+
.request-card-footer-addon[data-v-5374efff] {
|
|
1942
1946
|
flex: 1;
|
|
1943
1947
|
align-items: center;
|
|
1944
1948
|
min-width: 0;
|
|
1945
1949
|
display: flex;
|
|
1946
1950
|
}
|
|
1947
1951
|
|
|
1948
|
-
.request-editor-section[data-v-
|
|
1952
|
+
.request-editor-section[data-v-5374efff] {
|
|
1949
1953
|
flex: 1;
|
|
1950
1954
|
display: flex;
|
|
1951
1955
|
}
|
|
1952
1956
|
|
|
1953
|
-
.request-card-simple[data-v-
|
|
1957
|
+
.request-card-simple[data-v-5374efff] {
|
|
1954
1958
|
font-size: var(--scalar-small);
|
|
1955
1959
|
justify-content: space-between;
|
|
1956
1960
|
align-items: center;
|
|
@@ -1958,7 +1962,7 @@
|
|
|
1958
1962
|
display: flex;
|
|
1959
1963
|
}
|
|
1960
1964
|
|
|
1961
|
-
.code-snippet[data-v-
|
|
1965
|
+
.code-snippet[data-v-5374efff] {
|
|
1962
1966
|
flex-direction: column;
|
|
1963
1967
|
width: 100%;
|
|
1964
1968
|
display: flex;
|
|
@@ -2539,7 +2543,7 @@ code.property-detail-value[data-v-8b57daa7] {
|
|
|
2539
2543
|
text-decoration: line-through;
|
|
2540
2544
|
}
|
|
2541
2545
|
|
|
2542
|
-
.property[data-v-
|
|
2546
|
+
.property[data-v-0949fba6] {
|
|
2543
2547
|
color: var(--scalar-color-1);
|
|
2544
2548
|
font-size: var(--scalar-small);
|
|
2545
2549
|
flex-direction: column;
|
|
@@ -2548,61 +2552,61 @@ code.property-detail-value[data-v-8b57daa7] {
|
|
|
2548
2552
|
position: relative;
|
|
2549
2553
|
}
|
|
2550
2554
|
|
|
2551
|
-
.property[data-v-
|
|
2555
|
+
.property[data-v-0949fba6]:has( > .property-rule:first-of-type):not(.property--compact) {
|
|
2552
2556
|
padding-top: 8px;
|
|
2553
2557
|
padding-bottom: 8px;
|
|
2554
2558
|
}
|
|
2555
2559
|
|
|
2556
|
-
.property--deprecated[data-v-
|
|
2560
|
+
.property--deprecated[data-v-0949fba6] {
|
|
2557
2561
|
background: repeating-linear-gradient(-45deg, var(--scalar-background-2) 0, var(--scalar-background-2) 2px, transparent 2px, transparent 5px);
|
|
2558
2562
|
background-size: 100%;
|
|
2559
2563
|
}
|
|
2560
2564
|
|
|
2561
|
-
.property-description[data-v-
|
|
2565
|
+
.property-description[data-v-0949fba6] {
|
|
2562
2566
|
line-height: 1.4;
|
|
2563
2567
|
font-size: var(--scalar-small);
|
|
2564
2568
|
margin-top: 6px;
|
|
2565
2569
|
}
|
|
2566
2570
|
|
|
2567
|
-
.property-description[data-v-
|
|
2571
|
+
.property-description[data-v-0949fba6]:has( + .property-rule) {
|
|
2568
2572
|
margin-bottom: 9px;
|
|
2569
2573
|
}
|
|
2570
2574
|
|
|
2571
|
-
[data-v-
|
|
2575
|
+
[data-v-0949fba6] .property-description * {
|
|
2572
2576
|
color: var(--scalar-color-2) !important;
|
|
2573
2577
|
}
|
|
2574
2578
|
|
|
2575
|
-
.property[data-v-
|
|
2579
|
+
.property[data-v-0949fba6]:not(:last-of-type) {
|
|
2576
2580
|
border-bottom: var(--scalar-border-width) solid var(--scalar-border-color);
|
|
2577
2581
|
}
|
|
2578
2582
|
|
|
2579
|
-
.property-description + .children[data-v-
|
|
2583
|
+
.property-description + .children[data-v-0949fba6], .children + .property-rule[data-v-0949fba6] {
|
|
2580
2584
|
margin-top: 9px;
|
|
2581
2585
|
}
|
|
2582
2586
|
|
|
2583
|
-
.children[data-v-
|
|
2587
|
+
.children[data-v-0949fba6] {
|
|
2584
2588
|
flex-direction: column;
|
|
2585
2589
|
display: flex;
|
|
2586
2590
|
}
|
|
2587
2591
|
|
|
2588
|
-
.children .property--compact.property--level-1[data-v-
|
|
2592
|
+
.children .property--compact.property--level-1[data-v-0949fba6] {
|
|
2589
2593
|
padding: 12px;
|
|
2590
2594
|
}
|
|
2591
2595
|
|
|
2592
|
-
.property-example-value[data-v-
|
|
2596
|
+
.property-example-value[data-v-0949fba6] {
|
|
2593
2597
|
all: unset;
|
|
2594
2598
|
font-family: var(--scalar-font-code);
|
|
2595
2599
|
border-top: var(--scalar-border-width) solid var(--scalar-border-color);
|
|
2596
2600
|
padding: 6px;
|
|
2597
2601
|
}
|
|
2598
2602
|
|
|
2599
|
-
.property-rule[data-v-
|
|
2603
|
+
.property-rule[data-v-0949fba6] {
|
|
2600
2604
|
border-radius: var(--scalar-radius-lg);
|
|
2601
2605
|
flex-direction: column;
|
|
2602
2606
|
display: flex;
|
|
2603
2607
|
}
|
|
2604
2608
|
|
|
2605
|
-
.property-example[data-v-
|
|
2609
|
+
.property-example[data-v-0949fba6] {
|
|
2606
2610
|
background: none;
|
|
2607
2611
|
border: none;
|
|
2608
2612
|
flex-direction: row;
|
|
@@ -2610,23 +2614,23 @@ code.property-detail-value[data-v-8b57daa7] {
|
|
|
2610
2614
|
display: flex;
|
|
2611
2615
|
}
|
|
2612
2616
|
|
|
2613
|
-
.property-example-label[data-v-
|
|
2617
|
+
.property-example-label[data-v-0949fba6], .property-example-value[data-v-0949fba6] {
|
|
2614
2618
|
padding: 3px 0 0;
|
|
2615
2619
|
}
|
|
2616
2620
|
|
|
2617
|
-
.property-example-value[data-v-
|
|
2621
|
+
.property-example-value[data-v-0949fba6] {
|
|
2618
2622
|
background: var(--scalar-background-2);
|
|
2619
2623
|
border-radius: var(--scalar-radius);
|
|
2620
2624
|
border-top: 0;
|
|
2621
2625
|
padding: 3px 4px;
|
|
2622
2626
|
}
|
|
2623
2627
|
|
|
2624
|
-
.property-name[data-v-
|
|
2628
|
+
.property-name[data-v-0949fba6] {
|
|
2625
2629
|
font-family: var(--scalar-font-code);
|
|
2626
2630
|
font-weight: var(--scalar-semibold);
|
|
2627
2631
|
}
|
|
2628
2632
|
|
|
2629
|
-
.property-name-additional-properties[data-v-
|
|
2633
|
+
.property-name-additional-properties[data-v-0949fba6]:before, .property-name-pattern-properties[data-v-0949fba6]:before {
|
|
2630
2634
|
text-transform: uppercase;
|
|
2631
2635
|
font-size: var(--scalar-micro);
|
|
2632
2636
|
border-radius: var(--scalar-radius);
|
|
@@ -2638,11 +2642,11 @@ code.property-detail-value[data-v-8b57daa7] {
|
|
|
2638
2642
|
display: inline-block;
|
|
2639
2643
|
}
|
|
2640
2644
|
|
|
2641
|
-
.property-name-pattern-properties[data-v-
|
|
2645
|
+
.property-name-pattern-properties[data-v-0949fba6]:before {
|
|
2642
2646
|
content: "regex";
|
|
2643
2647
|
}
|
|
2644
2648
|
|
|
2645
|
-
.property-name-additional-properties[data-v-
|
|
2649
|
+
.property-name-additional-properties[data-v-0949fba6], .property-name-pattern-properties[data-v-0949fba6] {
|
|
2646
2650
|
border: 1px dashed var(--scalar-border-color);
|
|
2647
2651
|
color: var(--scalar-color-accent);
|
|
2648
2652
|
border-radius: var(--scalar-radius);
|
|
@@ -3132,6 +3136,10 @@ code.property-detail-value[data-v-8b57daa7] {
|
|
|
3132
3136
|
margin-inline: 4px;
|
|
3133
3137
|
}
|
|
3134
3138
|
|
|
3139
|
+
.scalar-app .mx-2 {
|
|
3140
|
+
margin-inline: 8px;
|
|
3141
|
+
}
|
|
3142
|
+
|
|
3135
3143
|
.scalar-app .mx-px {
|
|
3136
3144
|
margin-inline: 1px;
|
|
3137
3145
|
}
|
|
@@ -6970,6 +6978,12 @@ code.property-detail-value[data-v-8b57daa7] {
|
|
|
6970
6978
|
initial-value: 0;
|
|
6971
6979
|
}
|
|
6972
6980
|
|
|
6981
|
+
@property --tw-border-style {
|
|
6982
|
+
syntax: "*";
|
|
6983
|
+
inherits: false;
|
|
6984
|
+
initial-value: solid;
|
|
6985
|
+
}
|
|
6986
|
+
|
|
6973
6987
|
@property --tw-gradient-position {
|
|
6974
6988
|
syntax: "*";
|
|
6975
6989
|
inherits: false
|
|
@@ -7657,41 +7671,41 @@ to {
|
|
|
7657
7671
|
background: color-mix(in srgb, var(--scalar-background-3), transparent 40%);
|
|
7658
7672
|
}
|
|
7659
7673
|
|
|
7660
|
-
[data-v-
|
|
7674
|
+
[data-v-344240b0] .code-input-lite__editor {
|
|
7661
7675
|
background-color: transparent;
|
|
7662
7676
|
font-family: var(--scalar-font);
|
|
7663
7677
|
font-size: var(--scalar-small);
|
|
7664
7678
|
padding: 5px 8px;
|
|
7665
7679
|
}
|
|
7666
|
-
[data-v-
|
|
7680
|
+
[data-v-344240b0] .scalar-pill:not(:last-of-type) {
|
|
7667
7681
|
margin-right: 0.15em;
|
|
7668
7682
|
}
|
|
7669
|
-
[data-v-
|
|
7683
|
+
[data-v-344240b0] .scalar-pill:not(:first-of-type) {
|
|
7670
7684
|
margin-left: 0.5px;
|
|
7671
7685
|
}
|
|
7672
7686
|
|
|
7673
|
-
[data-v-
|
|
7687
|
+
[data-v-ec7e5b86] .cm-content {
|
|
7674
7688
|
font-size: var(--scalar-small);
|
|
7675
7689
|
}
|
|
7676
7690
|
|
|
7677
|
-
[data-v-
|
|
7691
|
+
[data-v-029a43f5] .code-input-lite__editor {
|
|
7678
7692
|
background-color: transparent;
|
|
7679
7693
|
font-family: var(--scalar-font);
|
|
7680
7694
|
font-size: var(--scalar-small);
|
|
7681
7695
|
padding: 5px 8px;
|
|
7682
7696
|
}
|
|
7683
|
-
[data-v-
|
|
7697
|
+
[data-v-029a43f5] .scalar-pill:not(:last-of-type) {
|
|
7684
7698
|
margin-right: 0.15em;
|
|
7685
7699
|
}
|
|
7686
|
-
[data-v-
|
|
7700
|
+
[data-v-029a43f5] .scalar-pill:not(:first-of-type) {
|
|
7687
7701
|
margin-left: 0.5px;
|
|
7688
7702
|
}
|
|
7689
7703
|
/* Tailwind placeholder is busted */
|
|
7690
|
-
input[data-v-
|
|
7704
|
+
input[data-v-029a43f5]::placeholder {
|
|
7691
7705
|
color: var(--scalar-color-3);
|
|
7692
7706
|
}
|
|
7693
7707
|
/* we want our inputs to look like a password input but not be one */
|
|
7694
|
-
.scalar-password-input[data-v-
|
|
7708
|
+
.scalar-password-input[data-v-029a43f5] {
|
|
7695
7709
|
text-security: disc;
|
|
7696
7710
|
-webkit-text-security: disc;
|
|
7697
7711
|
-moz-text-security: disc;
|
|
@@ -7719,20 +7733,20 @@ input[data-v-ce270af2]::placeholder {
|
|
|
7719
7733
|
scrollbar-width: none;
|
|
7720
7734
|
}
|
|
7721
7735
|
|
|
7722
|
-
.request-section-content[data-v-
|
|
7736
|
+
.request-section-content[data-v-a55ce987] {
|
|
7723
7737
|
--scalar-border-width: 0.5px;
|
|
7724
7738
|
}
|
|
7725
|
-
.request-section-content-filter[data-v-
|
|
7739
|
+
.request-section-content-filter[data-v-a55ce987] {
|
|
7726
7740
|
box-shadow: 0 -10px 0 10px var(--scalar-background-1);
|
|
7727
7741
|
}
|
|
7728
|
-
.request-item:focus-within .request-meta-buttons[data-v-
|
|
7742
|
+
.request-item:focus-within .request-meta-buttons[data-v-a55ce987] {
|
|
7729
7743
|
opacity: 1;
|
|
7730
7744
|
}
|
|
7731
|
-
.group-hover-input[data-v-
|
|
7745
|
+
.group-hover-input[data-v-a55ce987] {
|
|
7732
7746
|
border-width: var(--scalar-border-width);
|
|
7733
7747
|
border-color: transparent;
|
|
7734
7748
|
}
|
|
7735
|
-
.group:hover .group-hover-input[data-v-
|
|
7749
|
+
.group:hover .group-hover-input[data-v-a55ce987] {
|
|
7736
7750
|
background: color-mix(
|
|
7737
7751
|
in srgb,
|
|
7738
7752
|
var(--scalar-background-1),
|
|
@@ -7740,7 +7754,7 @@ input[data-v-ce270af2]::placeholder {
|
|
|
7740
7754
|
);
|
|
7741
7755
|
border-color: var(--scalar-border-color);
|
|
7742
7756
|
}
|
|
7743
|
-
.group-hover-input[data-v-
|
|
7757
|
+
.group-hover-input[data-v-a55ce987]:focus {
|
|
7744
7758
|
background: transparent !important;
|
|
7745
7759
|
border-color: var(--scalar-border-color) !important;
|
|
7746
7760
|
}
|
|
@@ -34,9 +34,9 @@ export declare const getCookieRequestUrl: (payloadUrl: string) => string;
|
|
|
34
34
|
*
|
|
35
35
|
* Cookies are scoped like a browser would scope them — using the `Set-Cookie`
|
|
36
36
|
* `Domain`/`Path` attributes, or falling back to the request host and default
|
|
37
|
-
* path — so they are only replayed on matching requests.
|
|
38
|
-
* `
|
|
39
|
-
*
|
|
37
|
+
* path — so they are only replayed on matching requests. A non-positive
|
|
38
|
+
* `Max-Age`, or a past `Expires` when `Max-Age` is absent, removes the matching
|
|
39
|
+
* cookie. `Max-Age` takes precedence when both attributes are present.
|
|
40
40
|
*
|
|
41
41
|
* @param cookieHeaderKeys - Serialized `Set-Cookie` values from the response
|
|
42
42
|
* @param documentCookies - The current persisted document cookies (order matches the store)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"persist-response-cookies.d.ts","sourceRoot":"","sources":["../../../../../src/v2/blocks/operation-block/helpers/persist-response-cookies.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qEAAqE,CAAA;AAGxG;;;;;GAKG;AACH,KAAK,oBAAoB,GACrB;IACE,IAAI,EAAE,QAAQ,CAAA;IACd,uFAAuF;IACvF,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC,CAAA;IACjE,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,GACD;IACE,IAAI,EAAE,QAAQ,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;IAClB,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAEL;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAAI,YAAY,MAAM,KAAG,MAQxD,CAAA;AAqCD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,wBAAwB,GAAI,yDAKtC;IACD,gBAAgB,EAAE,MAAM,EAAE,CAAA;IAC1B,eAAe,EAAE,aAAa,EAAE,CAAA;IAChC,UAAU,EAAE,MAAM,CAAA;IAClB,GAAG,CAAC,EAAE,MAAM,CAAA;CACb,KAAG,oBAAoB,
|
|
1
|
+
{"version":3,"file":"persist-response-cookies.d.ts","sourceRoot":"","sources":["../../../../../src/v2/blocks/operation-block/helpers/persist-response-cookies.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qEAAqE,CAAA;AAGxG;;;;;GAKG;AACH,KAAK,oBAAoB,GACrB;IACE,IAAI,EAAE,QAAQ,CAAA;IACd,uFAAuF;IACvF,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC,CAAA;IACjE,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,GACD;IACE,IAAI,EAAE,QAAQ,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;IAClB,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAEL;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAAI,YAAY,MAAM,KAAG,MAQxD,CAAA;AAqCD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,wBAAwB,GAAI,yDAKtC;IACD,gBAAgB,EAAE,MAAM,EAAE,CAAA;IAC1B,eAAe,EAAE,aAAa,EAAE,CAAA;IAChC,UAAU,EAAE,MAAM,CAAA;IAClB,GAAG,CAAC,EAAE,MAAM,CAAA;CACb,KAAG,oBAAoB,EAsEvB,CAAA"}
|
|
@@ -55,9 +55,9 @@ var isSameCookie = (a, b) => a.name === b.name && (a.domain ?? "") === (b.domain
|
|
|
55
55
|
*
|
|
56
56
|
* Cookies are scoped like a browser would scope them — using the `Set-Cookie`
|
|
57
57
|
* `Domain`/`Path` attributes, or falling back to the request host and default
|
|
58
|
-
* path — so they are only replayed on matching requests.
|
|
59
|
-
* `
|
|
60
|
-
*
|
|
58
|
+
* path — so they are only replayed on matching requests. A non-positive
|
|
59
|
+
* `Max-Age`, or a past `Expires` when `Max-Age` is absent, removes the matching
|
|
60
|
+
* cookie. `Max-Age` takes precedence when both attributes are present.
|
|
61
61
|
*
|
|
62
62
|
* @param cookieHeaderKeys - Serialized `Set-Cookie` values from the response
|
|
63
63
|
* @param documentCookies - The current persisted document cookies (order matches the store)
|
|
@@ -79,7 +79,7 @@ var getResponseCookieActions = ({ cookieHeaderKeys, documentCookies, requestUrl,
|
|
|
79
79
|
if (!parsed?.name) continue;
|
|
80
80
|
const domain = parsed.domain || hostname;
|
|
81
81
|
const path = parsed.path || defaultPath;
|
|
82
|
-
const expired = parsed.maxAge !== void 0
|
|
82
|
+
const expired = parsed.maxAge !== void 0 ? parsed.maxAge <= 0 : parsed.expires instanceof Date && parsed.expires.getTime() <= now;
|
|
83
83
|
resolved.set(`${parsed.name}\n${domain}\n${path}`, {
|
|
84
84
|
cookie: {
|
|
85
85
|
name: parsed.name,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"persist-response-cookies.js","names":[],"sources":["../../../../../src/v2/blocks/operation-block/helpers/persist-response-cookies.ts"],"sourcesContent":["import type { XScalarCookie } from '@scalar/workspace-store/schemas/extensions/general/x-scalar-cookies'\nimport { parseSetCookie } from 'set-cookie-parser'\n\n/**\n * A single change to apply to the persisted document cookie jar in response to a\n * server's `Set-Cookie` headers. This mirrors how a browser stores server-set\n * cookies so that values like a Django CSRF token survive a page reload and get\n * replayed on the next request.\n */\ntype ResponseCookieAction =\n | {\n type: 'upsert'\n /** The cookie fields to store. Merged over the existing cookie when `index` is set. */\n cookie: Pick<XScalarCookie, 'name' | 'value' | 'domain' | 'path'>\n /** Index of the existing cookie to update, or undefined to add a new one. */\n index?: number\n }\n | {\n type: 'delete'\n cookieName: string\n /** Index of the existing cookie to remove. */\n index: number\n }\n\n/**\n * Resolve the real target URL a request was sent to, so cookies are scoped to\n * the API host rather than the proxy. When a request is proxied, the target URL\n * is carried in the `scalar_url` query parameter; otherwise the URL is used as-is.\n */\nexport const getCookieRequestUrl = (payloadUrl: string): string => {\n try {\n // Fall back to the proxied URL when `scalar_url` is missing or empty, so an\n // empty query value never scopes cookies against a placeholder host.\n return new URL(payloadUrl).searchParams.get('scalar_url') || payloadUrl\n } catch {\n return payloadUrl\n }\n}\n\n/**\n * Compute the default cookie path from a request pathname, following the browser\n * default-path algorithm (RFC 6265, section 5.1.4): the request path up to, but\n * not including, its rightmost slash — or \"/\" when there is nothing before it.\n */\nconst getDefaultPath = (pathname: string): string => {\n if (!pathname.startsWith('/')) {\n return '/'\n }\n\n const lastSlash = pathname.lastIndexOf('/')\n\n return lastSlash <= 0 ? '/' : pathname.slice(0, lastSlash)\n}\n\n/**\n * Derive the host and default path a cookie should be scoped to from the request\n * URL. The URL is parsed defensively: `getCookieRequestUrl` may hand back a value\n * that is not a valid URL (for example a malformed `scalar_url`), and a throw here\n * would otherwise abort persistence after an otherwise successful request.\n */\nconst getRequestScope = (requestUrl: string): { hostname: string; defaultPath: string } => {\n try {\n const { hostname, pathname } = new URL(requestUrl, 'https://example.com')\n\n return { hostname, defaultPath: getDefaultPath(pathname) }\n } catch {\n return { hostname: '', defaultPath: '/' }\n }\n}\n\n/** Two stored cookies share an identity when name, domain, and path all match. */\nconst isSameCookie = (a: Pick<XScalarCookie, 'name' | 'domain' | 'path'>, b: XScalarCookie): boolean =>\n a.name === b.name && (a.domain ?? '') === (b.domain ?? '') && (a.path ?? '') === (b.path ?? '')\n\n/**\n * Translate a response's `Set-Cookie` headers into a list of changes for the\n * document cookie jar.\n *\n * Scalar sends requests through a proxy and reads `Set-Cookie` from a custom\n * header because browsers hide it from `fetch`, so it has to maintain its own\n * cookie jar instead of relying on the browser. This function is that jar's\n * write path: it decides which cookies to add, update, or remove.\n *\n * Cookies are scoped like a browser would scope them — using the `Set-Cookie`\n * `Domain`/`Path` attributes, or falling back to the request host and default\n * path — so they are only replayed on matching requests.
|
|
1
|
+
{"version":3,"file":"persist-response-cookies.js","names":[],"sources":["../../../../../src/v2/blocks/operation-block/helpers/persist-response-cookies.ts"],"sourcesContent":["import type { XScalarCookie } from '@scalar/workspace-store/schemas/extensions/general/x-scalar-cookies'\nimport { parseSetCookie } from 'set-cookie-parser'\n\n/**\n * A single change to apply to the persisted document cookie jar in response to a\n * server's `Set-Cookie` headers. This mirrors how a browser stores server-set\n * cookies so that values like a Django CSRF token survive a page reload and get\n * replayed on the next request.\n */\ntype ResponseCookieAction =\n | {\n type: 'upsert'\n /** The cookie fields to store. Merged over the existing cookie when `index` is set. */\n cookie: Pick<XScalarCookie, 'name' | 'value' | 'domain' | 'path'>\n /** Index of the existing cookie to update, or undefined to add a new one. */\n index?: number\n }\n | {\n type: 'delete'\n cookieName: string\n /** Index of the existing cookie to remove. */\n index: number\n }\n\n/**\n * Resolve the real target URL a request was sent to, so cookies are scoped to\n * the API host rather than the proxy. When a request is proxied, the target URL\n * is carried in the `scalar_url` query parameter; otherwise the URL is used as-is.\n */\nexport const getCookieRequestUrl = (payloadUrl: string): string => {\n try {\n // Fall back to the proxied URL when `scalar_url` is missing or empty, so an\n // empty query value never scopes cookies against a placeholder host.\n return new URL(payloadUrl).searchParams.get('scalar_url') || payloadUrl\n } catch {\n return payloadUrl\n }\n}\n\n/**\n * Compute the default cookie path from a request pathname, following the browser\n * default-path algorithm (RFC 6265, section 5.1.4): the request path up to, but\n * not including, its rightmost slash — or \"/\" when there is nothing before it.\n */\nconst getDefaultPath = (pathname: string): string => {\n if (!pathname.startsWith('/')) {\n return '/'\n }\n\n const lastSlash = pathname.lastIndexOf('/')\n\n return lastSlash <= 0 ? '/' : pathname.slice(0, lastSlash)\n}\n\n/**\n * Derive the host and default path a cookie should be scoped to from the request\n * URL. The URL is parsed defensively: `getCookieRequestUrl` may hand back a value\n * that is not a valid URL (for example a malformed `scalar_url`), and a throw here\n * would otherwise abort persistence after an otherwise successful request.\n */\nconst getRequestScope = (requestUrl: string): { hostname: string; defaultPath: string } => {\n try {\n const { hostname, pathname } = new URL(requestUrl, 'https://example.com')\n\n return { hostname, defaultPath: getDefaultPath(pathname) }\n } catch {\n return { hostname: '', defaultPath: '/' }\n }\n}\n\n/** Two stored cookies share an identity when name, domain, and path all match. */\nconst isSameCookie = (a: Pick<XScalarCookie, 'name' | 'domain' | 'path'>, b: XScalarCookie): boolean =>\n a.name === b.name && (a.domain ?? '') === (b.domain ?? '') && (a.path ?? '') === (b.path ?? '')\n\n/**\n * Translate a response's `Set-Cookie` headers into a list of changes for the\n * document cookie jar.\n *\n * Scalar sends requests through a proxy and reads `Set-Cookie` from a custom\n * header because browsers hide it from `fetch`, so it has to maintain its own\n * cookie jar instead of relying on the browser. This function is that jar's\n * write path: it decides which cookies to add, update, or remove.\n *\n * Cookies are scoped like a browser would scope them — using the `Set-Cookie`\n * `Domain`/`Path` attributes, or falling back to the request host and default\n * path — so they are only replayed on matching requests. A non-positive\n * `Max-Age`, or a past `Expires` when `Max-Age` is absent, removes the matching\n * cookie. `Max-Age` takes precedence when both attributes are present.\n *\n * @param cookieHeaderKeys - Serialized `Set-Cookie` values from the response\n * @param documentCookies - The current persisted document cookies (order matches the store)\n * @param requestUrl - The request URL, used to derive the default domain and path\n * @param now - Current time in ms, injectable for testing\n */\nexport const getResponseCookieActions = ({\n cookieHeaderKeys,\n documentCookies,\n requestUrl,\n now = Date.now(),\n}: {\n cookieHeaderKeys: string[]\n documentCookies: XScalarCookie[]\n requestUrl: string\n now?: number\n}): ResponseCookieAction[] => {\n const { hostname, defaultPath } = getRequestScope(requestUrl)\n\n /**\n * Collapse the response's `Set-Cookie` headers into one final state per cookie\n * identity. A browser applies them in order, so a later header for the same\n * name/domain/path wins — whether it sets a new value or expires the cookie.\n * Resolving this first also keeps a single action per identity, so the same\n * stored cookie never gets a conflicting upsert and delete on the same index.\n */\n const resolved = new Map<\n string,\n { cookie: Pick<XScalarCookie, 'name' | 'value' | 'domain' | 'path'>; expired: boolean }\n >()\n\n for (const header of cookieHeaderKeys) {\n // Each header holds a single Set-Cookie value, so take the first parsed cookie.\n const [parsed] = parseSetCookie(header)\n\n if (!parsed?.name) {\n continue\n }\n\n // Scope the cookie the way a browser would, so it is only replayed on matching requests.\n const domain = parsed.domain || hostname\n const path = parsed.path || defaultPath\n\n // Max-Age takes precedence over Expires (RFC 6265, section 5.3).\n const expired =\n parsed.maxAge !== undefined\n ? parsed.maxAge <= 0\n : parsed.expires instanceof Date && parsed.expires.getTime() <= now\n\n resolved.set(`${parsed.name}\\n${domain}\\n${path}`, {\n cookie: { name: parsed.name, value: parsed.value, domain, path },\n expired,\n })\n }\n\n const upserts: ResponseCookieAction[] = []\n const deletes: ResponseCookieAction[] = []\n\n for (const { cookie, expired } of resolved.values()) {\n const index = documentCookies.findIndex((existing) => isSameCookie(cookie, existing))\n\n if (expired) {\n if (index !== -1) {\n deletes.push({ type: 'delete', cookieName: cookie.name, index })\n }\n continue\n }\n\n upserts.push({\n type: 'upsert',\n cookie,\n ...(index === -1 ? {} : { index }),\n })\n }\n\n /**\n * Apply index-based changes (updates and deletes) before appends, and process\n * deletes from the highest index down, so earlier indices stay valid as the\n * underlying array shrinks.\n */\n const indexed = [...upserts.filter((action) => action.index !== undefined), ...deletes].sort(\n (a, b) => (b.index ?? 0) - (a.index ?? 0),\n )\n const appends = upserts.filter((action) => action.index === undefined)\n\n return [...indexed, ...appends]\n}\n"],"mappings":";;;;;;;AA6BA,IAAa,uBAAuB,eAA+B;CACjE,IAAI;EAGF,OAAO,IAAI,IAAI,UAAU,CAAC,CAAC,aAAa,IAAI,YAAY,KAAK;CAC/D,QAAQ;EACN,OAAO;CACT;AACF;;;;;;AAOA,IAAM,kBAAkB,aAA6B;CACnD,IAAI,CAAC,SAAS,WAAW,GAAG,GAC1B,OAAO;CAGT,MAAM,YAAY,SAAS,YAAY,GAAG;CAE1C,OAAO,aAAa,IAAI,MAAM,SAAS,MAAM,GAAG,SAAS;AAC3D;;;;;;;AAQA,IAAM,mBAAmB,eAAkE;CACzF,IAAI;EACF,MAAM,EAAE,UAAU,aAAa,IAAI,IAAI,YAAY,qBAAqB;EAExE,OAAO;GAAE;GAAU,aAAa,eAAe,QAAQ;EAAE;CAC3D,QAAQ;EACN,OAAO;GAAE,UAAU;GAAI,aAAa;EAAI;CAC1C;AACF;;AAGA,IAAM,gBAAgB,GAAoD,MACxE,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,SAAS,EAAE,UAAU,QAAQ,EAAE,QAAQ,SAAS,EAAE,QAAQ;;;;;;;;;;;;;;;;;;;;;AAsB9F,IAAa,4BAA4B,EACvC,kBACA,iBACA,YACA,MAAM,KAAK,IAAI,QAMa;CAC5B,MAAM,EAAE,UAAU,gBAAgB,gBAAgB,UAAU;;;;;;;;CAS5D,MAAM,2BAAW,IAAI,IAGnB;CAEF,KAAK,MAAM,UAAU,kBAAkB;EAErC,MAAM,CAAC,UAAU,eAAe,MAAM;EAEtC,IAAI,CAAC,QAAQ,MACX;EAIF,MAAM,SAAS,OAAO,UAAU;EAChC,MAAM,OAAO,OAAO,QAAQ;EAG5B,MAAM,UACJ,OAAO,WAAW,KAAA,IACd,OAAO,UAAU,IACjB,OAAO,mBAAmB,QAAQ,OAAO,QAAQ,QAAQ,KAAK;EAEpE,SAAS,IAAI,GAAG,OAAO,KAAK,IAAI,OAAO,IAAI,QAAQ;GACjD,QAAQ;IAAE,MAAM,OAAO;IAAM,OAAO,OAAO;IAAO;IAAQ;GAAK;GAC/D;EACF,CAAC;CACH;CAEA,MAAM,UAAkC,CAAC;CACzC,MAAM,UAAkC,CAAC;CAEzC,KAAK,MAAM,EAAE,QAAQ,aAAa,SAAS,OAAO,GAAG;EACnD,MAAM,QAAQ,gBAAgB,WAAW,aAAa,aAAa,QAAQ,QAAQ,CAAC;EAEpF,IAAI,SAAS;GACX,IAAI,UAAU,IACZ,QAAQ,KAAK;IAAE,MAAM;IAAU,YAAY,OAAO;IAAM;GAAM,CAAC;GAEjE;EACF;EAEA,QAAQ,KAAK;GACX,MAAM;GACN;GACA,GAAI,UAAU,KAAK,CAAC,IAAI,EAAE,MAAM;EAClC,CAAC;CACH;;;;;;CAOA,MAAM,UAAU,CAAC,GAAG,QAAQ,QAAQ,WAAW,OAAO,UAAU,KAAA,CAAS,GAAG,GAAG,OAAO,CAAC,CAAC,MACrF,GAAG,OAAO,EAAE,SAAS,MAAM,EAAE,SAAS,EACzC;CACA,MAAM,UAAU,QAAQ,QAAQ,WAAW,OAAO,UAAU,KAAA,CAAS;CAErE,OAAO,CAAC,GAAG,SAAS,GAAG,OAAO;AAChC"}
|
|
@@ -17,7 +17,7 @@ var validatePathParameters = (parameters = [], exampleKey = "default") => {
|
|
|
17
17
|
const invalidParams = [];
|
|
18
18
|
for (const referencedParam of parameters) {
|
|
19
19
|
const param = getResolvedRef(referencedParam);
|
|
20
|
-
if (
|
|
20
|
+
if (param?.in !== "path") continue;
|
|
21
21
|
const example = getExample(param, exampleKey, void 0);
|
|
22
22
|
if (isParamDisabled(param, example)) continue;
|
|
23
23
|
if (isEmptyParamValue(example?.value)) invalidParams.push(param.name);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate-path-parameters.js","names":[],"sources":["../../../../../src/v2/blocks/operation-block/helpers/validate-path-parameters.ts"],"sourcesContent":["import { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport { getExample, isParamDisabled } from '@scalar/workspace-store/request-example'\nimport type { ParameterObject, ReferenceType } from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document'\n\ntype ValidatePathParametersResult = { ok: true } | { ok: false; invalidParams: string[] }\n\n/** Treats undefined, null, and blank/whitespace strings as empty. */\nconst isEmptyParamValue = (value: unknown): boolean => {\n if (value === undefined || value === null) {\n return true\n }\n if (typeof value === 'string') {\n return value.trim() === ''\n }\n return false\n}\n\n/**\n * Validates that all required path parameters have non-empty values.\n *\n * Path parameters are always required per the OpenAPI specification.\n * Returns the names of any path parameters that are missing values.\n */\nexport const validatePathParameters = (\n parameters: ReferenceType<ParameterObject>[] = [],\n exampleKey: string = 'default',\n): ValidatePathParametersResult => {\n const invalidParams: string[] = []\n\n for (const referencedParam of parameters) {\n const param = getResolvedRef(referencedParam)\n if (
|
|
1
|
+
{"version":3,"file":"validate-path-parameters.js","names":[],"sources":["../../../../../src/v2/blocks/operation-block/helpers/validate-path-parameters.ts"],"sourcesContent":["import { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport { getExample, isParamDisabled } from '@scalar/workspace-store/request-example'\nimport type { ParameterObject, ReferenceType } from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document'\n\ntype ValidatePathParametersResult = { ok: true } | { ok: false; invalidParams: string[] }\n\n/** Treats undefined, null, and blank/whitespace strings as empty. */\nconst isEmptyParamValue = (value: unknown): boolean => {\n if (value === undefined || value === null) {\n return true\n }\n if (typeof value === 'string') {\n return value.trim() === ''\n }\n return false\n}\n\n/**\n * Validates that all required path parameters have non-empty values.\n *\n * Path parameters are always required per the OpenAPI specification.\n * Returns the names of any path parameters that are missing values.\n */\nexport const validatePathParameters = (\n parameters: ReferenceType<ParameterObject>[] = [],\n exampleKey: string = 'default',\n): ValidatePathParametersResult => {\n const invalidParams: string[] = []\n\n for (const referencedParam of parameters) {\n const param = getResolvedRef(referencedParam)\n if (param?.in !== 'path') {\n continue\n }\n\n const example = getExample(param, exampleKey, undefined)\n if (isParamDisabled(param, example)) {\n continue\n }\n\n if (isEmptyParamValue(example?.value)) {\n invalidParams.push(param.name)\n }\n }\n\n return invalidParams.length > 0 ? { ok: false, invalidParams } : { ok: true }\n}\n"],"mappings":";;;;AAOA,IAAM,qBAAqB,UAA4B;CACrD,IAAI,UAAU,KAAA,KAAa,UAAU,MACnC,OAAO;CAET,IAAI,OAAO,UAAU,UACnB,OAAO,MAAM,KAAK,MAAM;CAE1B,OAAO;AACT;;;;;;;AAQA,IAAa,0BACX,aAA+C,CAAC,GAChD,aAAqB,cACY;CACjC,MAAM,gBAA0B,CAAC;CAEjC,KAAK,MAAM,mBAAmB,YAAY;EACxC,MAAM,QAAQ,eAAe,eAAe;EAC5C,IAAI,OAAO,OAAO,QAChB;EAGF,MAAM,UAAU,WAAW,OAAO,YAAY,KAAA,CAAS;EACvD,IAAI,gBAAgB,OAAO,OAAO,GAChC;EAGF,IAAI,kBAAkB,SAAS,KAAK,GAClC,cAAc,KAAK,MAAM,IAAI;CAEjC;CAEA,OAAO,cAAc,SAAS,IAAI;EAAE,IAAI;EAAO;CAAc,IAAI,EAAE,IAAI,KAAK;AAC9E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RequestBlock.vue.d.ts","sourceRoot":"","sources":["../../../../src/v2/blocks/request-block/RequestBlock.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"RequestBlock.vue.d.ts","sourceRoot":"","sources":["../../../../src/v2/blocks/request-block/RequestBlock.vue"],"names":[],"mappings":"AAw2BA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAA;AAKpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AACpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAA;AAC7E,OAAO,KAAK,EAEV,QAAQ,EACR,iBAAiB,EAClB,MAAM,gCAAgC,CAAA;AAIvC,OAAO,EAKL,KAAK,qBAAqB,EAC1B,KAAK,0BAA0B,EAChC,MAAM,yCAAyC,CAAA;AAChD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2EAA2E,CAAA;AACnH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qEAAqE,CAAA;AACxG,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EACf,YAAY,EACb,MAAM,8DAA8D,CAAA;AAerE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8DAA8D,CAAA;AAMjG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAWrD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,QAAQ,CAAA;IAClB,aAAa,EAAE,iBAAiB,EAAE,CAAA;IAClC,WAAW,EAAE,kBAAkB,CAAA;IAC/B,QAAQ,EAAE,iBAAiB,CAAA;IAC3B,UAAU,EAAE,MAAM,CAAA;IAClB,gBAAgB,EAAE,aAAa,EAAE,CAAA;IACjC,eAAe,EAAE,aAAa,EAAE,CAAA;IAChC,oDAAoD;IACpD,YAAY,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,YAAY,CAAA;IACpB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,eAAe,CAAA;IAC1B,qFAAqF;IACrF,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,YAAY,EAAE,CAAA;IACvB,QAAQ,EAAE,MAAM,CAAA;IAChB,oBAAoB,EAAE,eAAe,CAAC,UAAU,CAAC,CAAA;IACjD,eAAe,EAAE,qBAAqB,CAAA;IACtC,+DAA+D;IAC/D,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,+BAA+B,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACxD,cAAc,EAAE,cAAc,CAAC,WAAW,CAAC,CAAC,yBAAyB,CAAC,CAAA;IACtE,gBAAgB,EAAE,gBAAgB,CAAA;IAClC,uBAAuB,EAAE,0BAA0B,EAAE,CAAA;IACrD,MAAM,EAAE,YAAY,GAAG,IAAI,CAAA;IAC3B,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACtC,mHAAmH;IACnH,sBAAsB,CAAC,EAAE,MAAM,GAAG,KAAK,CAAA;IACvC,uDAAuD;IACvD,OAAO,CAAC,EAAE,aAAa,CAAA;CACxB,CAAA;AAigCD,QAAA,MAAM,YAAY,8SAEhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -2,7 +2,7 @@ import _plugin_vue_export_helper_default from "../../../_virtual/_plugin-vue_exp
|
|
|
2
2
|
import RequestBlock_vue_vue_type_script_setup_true_lang_default from "./RequestBlock.vue.script.js";
|
|
3
3
|
/* empty css */
|
|
4
4
|
//#region src/v2/blocks/request-block/RequestBlock.vue
|
|
5
|
-
var RequestBlock_default = /*#__PURE__*/ _plugin_vue_export_helper_default(RequestBlock_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-
|
|
5
|
+
var RequestBlock_default = /*#__PURE__*/ _plugin_vue_export_helper_default(RequestBlock_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-a55ce987"]]);
|
|
6
6
|
//#endregion
|
|
7
7
|
export { RequestBlock_default as default };
|
|
8
8
|
|