@scalar/api-client 3.23.0 → 3.23.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.
Files changed (73) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/components/ScalarAsciiArt/ScalarAsciiArt.vue.js +1 -1
  3. package/dist/components/ScalarAsciiArt/ScalarAsciiArt.vue.js.map +1 -1
  4. package/dist/components/ScalarAsciiArt/ScalarAsciiArt.vue.script.js +2 -2
  5. package/dist/components/ScalarAsciiArt/ScalarAsciiArt.vue.script.js.map +1 -1
  6. package/dist/style.css +162 -122
  7. package/dist/v2/blocks/operation-block/OperationBlock.vue.js.map +1 -1
  8. package/dist/v2/blocks/operation-block/OperationBlock.vue.script.js.map +1 -1
  9. package/dist/v2/blocks/operation-block/components/Header.vue.d.ts.map +1 -1
  10. package/dist/v2/blocks/operation-block/components/Header.vue.js +1 -1
  11. package/dist/v2/blocks/operation-block/components/Header.vue.js.map +1 -1
  12. package/dist/v2/blocks/operation-block/components/Header.vue.script.js.map +1 -1
  13. package/dist/v2/blocks/request-block/RequestBlock.vue.d.ts.map +1 -1
  14. package/dist/v2/blocks/request-block/RequestBlock.vue.js +1 -1
  15. package/dist/v2/blocks/request-block/RequestBlock.vue.js.map +1 -1
  16. package/dist/v2/blocks/request-block/RequestBlock.vue.script.js.map +1 -1
  17. package/dist/v2/blocks/request-block/components/RequestParams.vue.d.ts.map +1 -1
  18. package/dist/v2/blocks/request-block/components/RequestParams.vue.js.map +1 -1
  19. package/dist/v2/blocks/request-block/components/RequestParams.vue.script.js.map +1 -1
  20. package/dist/v2/blocks/request-block/components/RequestTable.vue.d.ts.map +1 -1
  21. package/dist/v2/blocks/request-block/components/RequestTable.vue.js +1 -1
  22. package/dist/v2/blocks/request-block/components/RequestTable.vue.js.map +1 -1
  23. package/dist/v2/blocks/request-block/components/RequestTable.vue.script.js.map +1 -1
  24. package/dist/v2/blocks/response-block/components/ResponseBodyRaw.vue.js +1 -1
  25. package/dist/v2/blocks/response-block/components/ResponseBodyRaw.vue.js.map +1 -1
  26. package/dist/v2/blocks/response-block/components/ResponseBodyRaw.vue.script.js +4 -4
  27. package/dist/v2/blocks/response-block/components/ResponseBodyRaw.vue.script.js.map +1 -1
  28. package/dist/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue.d.ts.map +1 -1
  29. package/dist/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue.js.map +1 -1
  30. package/dist/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue.script.js +2 -4
  31. package/dist/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue.script.js.map +1 -1
  32. package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue.d.ts.map +1 -1
  33. package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue.js.map +1 -1
  34. package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue.script.js +1 -0
  35. package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue.script.js.map +1 -1
  36. package/dist/v2/blocks/scalar-auth-selector-block/helpers/fetch-oauth2-metadata.d.ts.map +1 -1
  37. package/dist/v2/blocks/scalar-auth-selector-block/helpers/fetch-oauth2-metadata.js +1 -1
  38. package/dist/v2/blocks/scalar-auth-selector-block/helpers/fetch-oauth2-metadata.js.map +1 -1
  39. package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth-device-authorization.d.ts.map +1 -1
  40. package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth-device-authorization.js +1 -1
  41. package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth-device-authorization.js.map +1 -1
  42. package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth.d.ts.map +1 -1
  43. package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth.js +2 -0
  44. package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth.js.map +1 -1
  45. package/dist/v2/components/code-input/CodeInput.vue.js +1 -1
  46. package/dist/v2/components/code-input/CodeInput.vue.js.map +1 -1
  47. package/dist/v2/components/code-input/CodeInput.vue.script.js +4 -4
  48. package/dist/v2/components/code-input/CodeInput.vue.script.js.map +1 -1
  49. package/dist/v2/components/code-input/CodeInputLite.vue.d.ts.map +1 -1
  50. package/dist/v2/components/code-input/CodeInputLite.vue.js +1 -1
  51. package/dist/v2/components/code-input/CodeInputLite.vue.js.map +1 -1
  52. package/dist/v2/components/code-input/CodeInputLite.vue.script.js.map +1 -1
  53. package/dist/v2/constants.js +1 -1
  54. package/dist/v2/features/modal/Modal.vue.d.ts.map +1 -1
  55. package/dist/v2/features/modal/Modal.vue.js.map +1 -1
  56. package/dist/v2/features/modal/Modal.vue.script.js +1 -0
  57. package/dist/v2/features/modal/Modal.vue.script.js.map +1 -1
  58. package/dist/v2/features/modal/modal-events.d.ts +3 -1
  59. package/dist/v2/features/modal/modal-events.d.ts.map +1 -1
  60. package/dist/v2/features/modal/modal-events.js +2 -1
  61. package/dist/v2/features/modal/modal-events.js.map +1 -1
  62. package/dist/v2/workspace-events.d.ts +4 -1
  63. package/dist/v2/workspace-events.d.ts.map +1 -1
  64. package/dist/v2/workspace-events.js +2 -2
  65. package/dist/v2/workspace-events.js.map +1 -1
  66. package/dist/vue-styles.css +45 -45
  67. package/package.json +13 -13
  68. package/dist/v2/blocks/scalar-auth-selector-block/helpers/extract-security-scheme-secrets.d.ts +0 -10
  69. package/dist/v2/blocks/scalar-auth-selector-block/helpers/extract-security-scheme-secrets.d.ts.map +0 -1
  70. package/dist/v2/blocks/scalar-auth-selector-block/helpers/is-allowed-oauth-url.d.ts +0 -3
  71. package/dist/v2/blocks/scalar-auth-selector-block/helpers/is-allowed-oauth-url.d.ts.map +0 -1
  72. package/dist/v2/blocks/scalar-auth-selector-block/helpers/is-allowed-oauth-url.js +0 -8
  73. package/dist/v2/blocks/scalar-auth-selector-block/helpers/is-allowed-oauth-url.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"RequestTable.vue.script.js","names":[],"sources":["../../../../../src/v2/blocks/request-block/components/RequestTable.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport { computed, type ComponentPublicInstance } from 'vue'\n\nimport RequestTableRow, {\n type TableRow,\n type TableRowUpsertPayload,\n} from '@/v2/blocks/request-block/components/RequestTableRow.vue'\nimport {\n DataTable,\n DataTableHeader,\n DataTableRow,\n} from '@/v2/components/data-table'\nimport { useLocalization } from '@/v2/features/localization'\n\nconst {\n data,\n hasCheckboxDisabled,\n deferKeyUpdates,\n showUploadButton,\n showAddRowPlaceholder = true,\n environment,\n} = defineProps<{\n data: TableRow[]\n /** Save key edits on blur so changing a body name does not replace the focused row. */\n deferKeyUpdates?: boolean\n /** Hide the enabled column */\n hasCheckboxDisabled?: boolean\n invalidParams?: Set<string>\n label?: string\n showUploadButton?: boolean\n showAddRowPlaceholder?: boolean\n environment: XScalarEnvironment\n}>()\n\n/**\n * Make this component more generic that can be used also for the operation body\n */\nconst emit = defineEmits<{\n (e: 'upsertRow', index: number, payload: TableRowUpsertPayload): void\n (e: 'deleteRow', index: number): void\n\n /**\n * File upload events\n *\n * Each row has its own upload button, so we need to know which row to update\n * when the file is selected.\n */\n (e: 'uploadFile', index: number): void\n (e: 'removeFile', index: number): void\n (e: 'navigate', route: NonNullable<TableRow['globalRoute']>): void\n /** Select a value for a grouped global cookie preset at the given row index. */\n (e: 'selectPreset', index: number, value: string): void\n}>()\n\nconst { translate } = useLocalization()\n\nconst columns = computed(() => {\n if (showUploadButton) {\n return ['36px', '', '', 'minmax(0, 1fr)']\n }\n return ['36px', '', '']\n})\n\n/** Add the last empty row (for ui purposes only) */\nconst displayData = computed(() => {\n if (!showAddRowPlaceholder) {\n return data\n }\n\n const last = data.at(-1)\n\n if (last?.name !== '' || last.value !== '') {\n return [...data, { name: '', value: '', isDisabled: true }]\n }\n\n return data\n})\n\n/**\n * Stable identity key for each row so Vue never reuses a RequestTableRow instance for a different\n * parameter or the appended placeholder row. Parameter rows are keyed by their parameter identity —\n * the name plus the value path for expanded object parameters. The parts are combined through\n * JSON.stringify so the name/path boundary is unambiguous (for example `ab` + `['c']` never\n * collides with `a` + `['bc']`). Form rows use the name and its occurrence so repeated\n * multipart fields remain distinct while unrelated rows can move without losing their identity.\n */\nconst getRowKey = (row: TableRow, index: number): string => {\n // Body edits retain their row when blur commits a rename after focus moves into the value.\n if (deferKeyUpdates) {\n return `body:${index}`\n }\n if (row.originalParameter) {\n return JSON.stringify([\n row.originalParameter.name,\n ...(row.sourceParameterValuePath ?? []),\n ])\n }\n\n const occurrence = displayData.value\n .slice(0, index)\n .filter(\n (other) => !other.originalParameter && other.name === row.name,\n ).length\n return `row:${JSON.stringify([row.name, occurrence])}`\n}\n\n/** Keep an edited row mounted when saving it changes its parameter identity. */\ntype DisplayRow = {\n data: TableRow\n identity: string\n key: symbol\n}\n\nconst pendingUpdates = new Map<symbol, TableRowUpsertPayload>()\nconst rowRefs = new Map<symbol, InstanceType<typeof RequestTableRow>>()\n\nconst setRowRef = (\n key: symbol,\n element: Element | ComponentPublicInstance | null,\n): void => {\n if (element) {\n rowRefs.set(key, element as InstanceType<typeof RequestTableRow>)\n } else {\n rowRefs.delete(key)\n }\n}\n\nconst matchesPendingUpdate = (key: symbol, row: TableRow): boolean => {\n const update = pendingUpdates.get(key)\n return update?.name === row.name && update.value === row.value\n}\n\n// A saved parameter inherits the editor's key. The next placeholder gets a fresh key,\n// so it cannot retain the previous placeholder's text or focused input.\nconst keyedRows = computed<DisplayRow[]>((previous = []) => {\n const available = new Set(previous)\n // Reserve identities still present in the store before transferring an edited key.\n // The appended placeholder is excluded so a newly saved row can inherit its editor.\n const savedIdentities = new Set(data.map(getRowKey))\n const rows = displayData.value.map((row, index) => {\n const identity = getRowKey(row, index)\n const existing = [...available].find((entry) => entry.identity === identity)\n const pending = [...available].find(\n (entry) =>\n !savedIdentities.has(entry.identity) &&\n !entry.data.sourceParameterValuePath &&\n matchesPendingUpdate(entry.key, row),\n )\n const match = existing ?? pending\n\n if (match) {\n available.delete(match)\n if (matchesPendingUpdate(match.key, row)) {\n pendingUpdates.delete(match.key)\n }\n }\n\n return { data: row, identity, key: match?.key ?? Symbol() }\n })\n\n for (const removed of available) {\n pendingUpdates.delete(removed.key)\n }\n\n return rows\n})\n\nconst handleUpsertRow = (\n row: DisplayRow,\n index: number,\n payload: TableRowUpsertPayload,\n): void => {\n // The store may debounce the save. Transfer this key only when the saved row arrives.\n pendingUpdates.set(row.key, payload)\n emit('upsertRow', index, payload)\n}\n\ndefineExpose({\n focusValue: (index: number): void => {\n const row = keyedRows.value[index]\n if (row) rowRefs.get(row.key)?.focusValue()\n },\n})\n</script>\n<template>\n <DataTable\n class=\"group/table flex-1\"\n :columns=\"columns\">\n <DataTableRow class=\"sr-only !block\">\n <DataTableHeader>\n {{ label }}\n {{ translate('apiClient.requestTable.enabled') }}\n </DataTableHeader>\n <DataTableHeader>\n {{ label }}\n {{ translate('apiClient.requestTable.key') }}\n </DataTableHeader>\n <DataTableHeader>\n {{ label }}\n {{ translate('apiClient.requestTable.value') }}\n </DataTableHeader>\n </DataTableRow>\n\n <RequestTableRow\n v-for=\"(row, index) in keyedRows\"\n :key=\"row.key\"\n :ref=\"(el) => setRowRef(row.key, el)\"\n :data=\"row.data\"\n :deferKeyUpdates=\"deferKeyUpdates\"\n :environment=\"environment\"\n :hasCheckboxDisabled=\"hasCheckboxDisabled\"\n :invalidParams=\"invalidParams\"\n :label=\"label\"\n :showUploadButton=\"showUploadButton\"\n @deleteRow=\"emit('deleteRow', index)\"\n @navigate=\"(route) => emit('navigate', route)\"\n @removeFile=\"emit('removeFile', index)\"\n @selectPreset=\"(value) => emit('selectPreset', index, value)\"\n @uploadFile=\"emit('uploadFile', index)\"\n @upsertRow=\"(payload) => handleUpsertRow(row, index, payload)\" />\n </DataTable>\n</template>\n<style scoped>\n:deep(.code-input-lite__editor) {\n background-color: transparent;\n font-family: var(--scalar-font);\n font-size: var(--scalar-small);\n padding: 5px 8px;\n}\n:deep(.scalar-pill:not(:last-of-type)) {\n margin-right: 0.15em;\n}\n:deep(.scalar-pill:not(:first-of-type)) {\n margin-left: 0.5px;\n}\n</style>\n"],"mappings":"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"}
1
+ {"version":3,"file":"RequestTable.vue.script.js","names":[],"sources":["../../../../../src/v2/blocks/request-block/components/RequestTable.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport { computed, type ComponentPublicInstance } from 'vue'\n\nimport RequestTableRow, {\n type TableRow,\n type TableRowUpsertPayload,\n} from '@/v2/blocks/request-block/components/RequestTableRow.vue'\nimport {\n DataTable,\n DataTableHeader,\n DataTableRow,\n} from '@/v2/components/data-table'\nimport { useLocalization } from '@/v2/features/localization'\n\nconst {\n data,\n hasCheckboxDisabled,\n deferKeyUpdates,\n showUploadButton,\n showAddRowPlaceholder = true,\n environment,\n} = defineProps<{\n data: TableRow[]\n /** Save key edits on blur so changing a body name does not replace the focused row. */\n deferKeyUpdates?: boolean\n /** Hide the enabled column */\n hasCheckboxDisabled?: boolean\n invalidParams?: Set<string>\n label?: string\n showUploadButton?: boolean\n showAddRowPlaceholder?: boolean\n environment: XScalarEnvironment\n}>()\n\n/**\n * Make this component more generic that can be used also for the operation body\n */\nconst emit = defineEmits<{\n (e: 'upsertRow', index: number, payload: TableRowUpsertPayload): void\n (e: 'deleteRow', index: number): void\n\n /**\n * File upload events\n *\n * Each row has its own upload button, so we need to know which row to update\n * when the file is selected.\n */\n (e: 'uploadFile', index: number): void\n (e: 'removeFile', index: number): void\n (e: 'navigate', route: NonNullable<TableRow['globalRoute']>): void\n /** Select a value for a grouped global cookie preset at the given row index. */\n (e: 'selectPreset', index: number, value: string): void\n}>()\n\nconst { translate } = useLocalization()\n\nconst columns = computed(() => {\n if (showUploadButton) {\n return ['36px', '', '', 'minmax(0, 1fr)']\n }\n return ['36px', '', '']\n})\n\n/** Add the last empty row (for ui purposes only) */\nconst displayData = computed(() => {\n if (!showAddRowPlaceholder) {\n return data\n }\n\n const last = data.at(-1)\n\n if (last?.name !== '' || last.value !== '') {\n return [...data, { name: '', value: '', isDisabled: true }]\n }\n\n return data\n})\n\n/**\n * Stable identity key for each row so Vue never reuses a RequestTableRow instance for a different\n * parameter or the appended placeholder row. Parameter rows are keyed by their parameter identity —\n * the name plus the value path for expanded object parameters. The parts are combined through\n * JSON.stringify so the name/path boundary is unambiguous (for example `ab` + `['c']` never\n * collides with `a` + `['bc']`). Form rows use the name and its occurrence so repeated\n * multipart fields remain distinct while unrelated rows can move without losing their identity.\n */\nconst getRowKey = (row: TableRow, index: number): string => {\n // Body edits retain their row when blur commits a rename after focus moves into the value.\n if (deferKeyUpdates) {\n return `body:${index}`\n }\n if (row.originalParameter) {\n return JSON.stringify([\n row.originalParameter.name,\n ...(row.sourceParameterValuePath ?? []),\n ])\n }\n\n const occurrence = displayData.value\n .slice(0, index)\n .filter(\n (other) => !other.originalParameter && other.name === row.name,\n ).length\n return `row:${JSON.stringify([row.name, occurrence])}`\n}\n\n/** Keep an edited row mounted when saving it changes its parameter identity. */\ntype DisplayRow = {\n data: TableRow\n identity: string\n key: symbol\n}\n\nconst pendingUpdates = new Map<symbol, TableRowUpsertPayload>()\nconst rowRefs = new Map<symbol, InstanceType<typeof RequestTableRow>>()\n\nconst setRowRef = (\n key: symbol,\n element: Element | ComponentPublicInstance | null,\n): void => {\n if (element) {\n rowRefs.set(key, element as InstanceType<typeof RequestTableRow>)\n } else {\n rowRefs.delete(key)\n }\n}\n\nconst matchesPendingUpdate = (key: symbol, row: TableRow): boolean => {\n const update = pendingUpdates.get(key)\n return update?.name === row.name && update.value === row.value\n}\n\n// A saved parameter inherits the editor's key. The next placeholder gets a fresh key,\n// so it cannot retain the previous placeholder's text or focused input.\nconst keyedRows = computed<DisplayRow[]>((previous = []) => {\n const available = new Set(previous)\n // Reserve identities still present in the store before transferring an edited key.\n // The appended placeholder is excluded so a newly saved row can inherit its editor.\n const savedIdentities = new Set(data.map(getRowKey))\n const rows = displayData.value.map((row, index) => {\n const identity = getRowKey(row, index)\n const existing = [...available].find((entry) => entry.identity === identity)\n const pending = [...available].find(\n (entry) =>\n !savedIdentities.has(entry.identity) &&\n !entry.data.sourceParameterValuePath &&\n matchesPendingUpdate(entry.key, row),\n )\n const match = existing ?? pending\n\n if (match) {\n available.delete(match)\n if (matchesPendingUpdate(match.key, row)) {\n pendingUpdates.delete(match.key)\n }\n }\n\n return { data: row, identity, key: match?.key ?? Symbol() }\n })\n\n for (const removed of available) {\n pendingUpdates.delete(removed.key)\n }\n\n return rows\n})\n\nconst handleUpsertRow = (\n row: DisplayRow,\n index: number,\n payload: TableRowUpsertPayload,\n): void => {\n // The store may debounce the save. Transfer this key only when the saved row arrives.\n pendingUpdates.set(row.key, payload)\n emit('upsertRow', index, payload)\n}\n\ndefineExpose({\n focusValue: (index: number): void => {\n const row = keyedRows.value[index]\n if (row) {\n rowRefs.get(row.key)?.focusValue()\n }\n },\n})\n</script>\n<template>\n <DataTable\n class=\"group/table flex-1\"\n :columns=\"columns\">\n <DataTableRow class=\"sr-only !block\">\n <DataTableHeader>\n {{ label }}\n {{ translate('apiClient.requestTable.enabled') }}\n </DataTableHeader>\n <DataTableHeader>\n {{ label }}\n {{ translate('apiClient.requestTable.key') }}\n </DataTableHeader>\n <DataTableHeader>\n {{ label }}\n {{ translate('apiClient.requestTable.value') }}\n </DataTableHeader>\n </DataTableRow>\n\n <RequestTableRow\n v-for=\"(row, index) in keyedRows\"\n :key=\"row.key\"\n :ref=\"(el) => setRowRef(row.key, el)\"\n :data=\"row.data\"\n :deferKeyUpdates=\"deferKeyUpdates\"\n :environment=\"environment\"\n :hasCheckboxDisabled=\"hasCheckboxDisabled\"\n :invalidParams=\"invalidParams\"\n :label=\"label\"\n :showUploadButton=\"showUploadButton\"\n @deleteRow=\"emit('deleteRow', index)\"\n @navigate=\"(route) => emit('navigate', route)\"\n @removeFile=\"emit('removeFile', index)\"\n @selectPreset=\"(value) => emit('selectPreset', index, value)\"\n @uploadFile=\"emit('uploadFile', index)\"\n @upsertRow=\"(payload) => handleUpsertRow(row, index, payload)\" />\n </DataTable>\n</template>\n<style scoped>\n:deep(.code-input-lite__editor) {\n background-color: transparent;\n font-family: var(--scalar-font);\n font-size: var(--scalar-small);\n padding: 5px 8px;\n}\n:deep(.scalar-pill:not(:last-of-type)) {\n margin-right: 0.15em;\n}\n:deep(.scalar-pill:not(:first-of-type)) {\n margin-left: 0.5px;\n}\n</style>\n"],"mappings":"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"}
@@ -2,7 +2,7 @@ import _plugin_vue_export_helper_default from "../../../../_virtual/_plugin-vue_
2
2
  import ResponseBodyRaw_vue_vue_type_script_setup_true_lang_default from "./ResponseBodyRaw.vue.script.js";
3
3
  /* empty css */
4
4
  //#region src/v2/blocks/response-block/components/ResponseBodyRaw.vue
5
- var ResponseBodyRaw_default = /*#__PURE__*/ _plugin_vue_export_helper_default(ResponseBodyRaw_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-6e055eb2"]]);
5
+ var ResponseBodyRaw_default = /*#__PURE__*/ _plugin_vue_export_helper_default(ResponseBodyRaw_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-973d48ca"]]);
6
6
  //#endregion
7
7
  export { ResponseBodyRaw_default as default };
8
8
 
@@ -1 +1 @@
1
- {"version":3,"file":"ResponseBodyRaw.vue.js","names":[],"sources":["../../../../../src/v2/blocks/response-block/components/ResponseBodyRaw.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { ScalarCodeBlockCopy } from '@scalar/components/code-block'\nimport { ScalarIconButton } from '@scalar/components/icon-button'\nimport { ScalarIconArrowElbowDownLeft } from '@scalar/icons'\nimport {\n EditorView,\n useCodeMirror,\n type CodeMirrorLanguage,\n} from '@scalar/use-codemirror'\nimport { computed, ref, toRef, useId } from 'vue'\n\nimport { prettifyJsoncString } from '@/v2/blocks/response-block/helpers/prettify-jsonc-string'\n\nconst props = defineProps<{\n content: unknown\n language: CodeMirrorLanguage | undefined\n /** When true, JSON/JSONC strings are pretty-printed for the Preview tab (wire bytes stay unchanged in Raw). */\n prettyPrintJson?: boolean\n}>()\n\nconst codeMirrorRef = ref<HTMLDivElement | null>(null)\n/** Base id for the code block */\nconst id = useId()\n\nconst isLineWrapping = ref(false)\n\nconst displayContent = computed((): string => {\n const { content, language, prettyPrintJson = false } = props\n if (typeof content !== 'string') {\n if (content == null) {\n return ''\n }\n return String(content)\n }\n if (prettyPrintJson && language === 'json') {\n return prettifyJsoncString(content)\n }\n return content\n})\n\nconst extensions = computed(() =>\n isLineWrapping.value ? [EditorView.lineWrapping] : [],\n)\n\nconst { codeMirror } = useCodeMirror({\n codeMirrorRef,\n readOnly: true,\n lineNumbers: true,\n content: toRef(displayContent),\n language: toRef(() => props.language),\n forceFoldGutter: true,\n extensions,\n})\n\n// Function to get current content\nconst getCurrentContent = () => {\n return codeMirror.value?.state.doc.toString() || ''\n}\n\nconst toggleLineWrapping = (): void => {\n isLineWrapping.value = !isLineWrapping.value\n}\n</script>\n<template>\n <div\n class=\"scalar-code-block group/code-block relative grid min-h-0 overflow-hidden p-px outline-none has-focus-visible:outline\"\n data-testid=\"response-body-raw\">\n <div\n class=\"custom-scroll relative pr-1\"\n tabindex=\"0\">\n <!-- CodeMirror container -->\n <div ref=\"codeMirrorRef\" />\n </div>\n <!-- Action buttons -->\n <div\n v-if=\"getCurrentContent()\"\n class=\"absolute top-2 right-2 flex items-center gap-1.5 opacity-0 transition-opacity duration-150 group-hover/code-block:opacity-100 group-has-focus-visible/code-block:opacity-100\">\n <ScalarIconButton\n class=\"bg-b-2 text-c-2 hover:text-c-1 absolute right-18\"\n :icon=\"ScalarIconArrowElbowDownLeft\"\n :aria-pressed=\"isLineWrapping\"\n :aria-label=\"isLineWrapping ? 'Disable line wrap' : 'Wrap lines'\"\n :label=\"isLineWrapping ? 'Disable line wrap' : 'Wrap lines'\"\n size=\"sm\"\n tooltip\n variant=\"ghost\"\n @click=\"toggleLineWrapping\" />\n <ScalarCodeBlockCopy\n :aria-controls=\"id\"\n :content=\"getCurrentContent()\" />\n </div>\n </div>\n</template>\n<style scoped>\n:deep(.cm-editor) {\n background-color: transparent;\n font-size: var(--scalar-small);\n outline: none;\n}\n\n:deep(.cm-gutters) {\n background-color: var(--scalar-background-1);\n border-radius: var(--scalar-radius) 0 0 var(--scalar-radius);\n}\n\n:deep(.cm-scroller) {\n overflow: auto;\n min-width: 100%;\n}\n\n:deep(.cm-lineWrapping .cm-line) {\n word-break: break-all;\n}\n</style>\n"],"mappings":""}
1
+ {"version":3,"file":"ResponseBodyRaw.vue.js","names":[],"sources":["../../../../../src/v2/blocks/response-block/components/ResponseBodyRaw.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { ScalarCodeBlockCopy } from '@scalar/components/code-block'\nimport { ScalarIconButton } from '@scalar/components/icon-button'\nimport { ScalarIconArrowElbowDownLeft } from '@scalar/icons'\nimport {\n EditorView,\n useCodeMirror,\n type CodeMirrorLanguage,\n} from '@scalar/use-codemirror'\nimport { computed, ref, toRef, useId } from 'vue'\n\nimport { prettifyJsoncString } from '@/v2/blocks/response-block/helpers/prettify-jsonc-string'\n\nconst props = defineProps<{\n content: unknown\n language: CodeMirrorLanguage | undefined\n /** When true, JSON/JSONC strings are pretty-printed for the Preview tab (wire bytes stay unchanged in Raw). */\n prettyPrintJson?: boolean\n}>()\n\nconst codeMirrorRef = ref<HTMLDivElement | null>(null)\n/** Base id for the code block */\nconst id = useId()\n\nconst isLineWrapping = ref(false)\n\nconst displayContent = computed((): string => {\n const { content, language, prettyPrintJson = false } = props\n if (typeof content !== 'string') {\n if (content == null) {\n return ''\n }\n return String(content)\n }\n if (prettyPrintJson && language === 'json') {\n return prettifyJsoncString(content)\n }\n return content\n})\n\nconst extensions = computed(() =>\n isLineWrapping.value ? [EditorView.lineWrapping] : [],\n)\n\nconst { codeMirror } = useCodeMirror({\n codeMirrorRef,\n readOnly: true,\n lineNumbers: true,\n content: toRef(displayContent),\n language: toRef(() => props.language),\n forceFoldGutter: true,\n extensions,\n})\n\n// Function to get current content\nconst getCurrentContent = () => {\n return codeMirror.value?.state.doc.toString() || ''\n}\n\nconst toggleLineWrapping = (): void => {\n isLineWrapping.value = !isLineWrapping.value\n}\n</script>\n<template>\n <div\n class=\"scalar-code-block group/code-block relative grid min-h-0 overflow-hidden p-px outline-none has-focus-visible:outline\"\n data-testid=\"response-body-raw\">\n <div\n class=\"custom-scroll relative pr-1\"\n tabindex=\"0\">\n <!-- CodeMirror container -->\n <div ref=\"codeMirrorRef\" />\n </div>\n <!-- Action buttons -->\n <div\n v-if=\"getCurrentContent()\"\n class=\"absolute top-2 right-2 flex items-center gap-1.5 opacity-0 transition-opacity duration-150 group-hover/code-block:opacity-100 group-has-focus-visible/code-block:opacity-100\">\n <ScalarIconButton\n :aria-label=\"isLineWrapping ? 'Disable line wrap' : 'Wrap lines'\"\n :aria-pressed=\"isLineWrapping\"\n class=\"bg-b-2 text-c-2 hover:text-c-1 absolute right-18\"\n :icon=\"ScalarIconArrowElbowDownLeft\"\n :label=\"isLineWrapping ? 'Disable line wrap' : 'Wrap lines'\"\n size=\"sm\"\n tooltip\n variant=\"ghost\"\n @click=\"toggleLineWrapping\" />\n <ScalarCodeBlockCopy\n :aria-controls=\"id\"\n :content=\"getCurrentContent()\" />\n </div>\n </div>\n</template>\n<style scoped>\n:deep(.cm-editor) {\n background-color: transparent;\n font-size: var(--scalar-small);\n outline: none;\n}\n\n:deep(.cm-gutters) {\n background-color: var(--scalar-background-1);\n border-radius: var(--scalar-radius) 0 0 var(--scalar-radius);\n}\n\n:deep(.cm-scroller) {\n overflow: auto;\n min-width: 100%;\n}\n\n:deep(.cm-lineWrapping .cm-line) {\n word-break: break-all;\n}\n</style>\n"],"mappings":""}
@@ -60,19 +60,19 @@ var ResponseBodyRaw_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/
60
60
  ref_key: "codeMirrorRef",
61
61
  ref: codeMirrorRef
62
62
  }, null, 512)]), getCurrentContent() ? (openBlock(), createElementBlock("div", _hoisted_3, [createVNode(unref(ScalarIconButton), {
63
+ "aria-label": isLineWrapping.value ? "Disable line wrap" : "Wrap lines",
64
+ "aria-pressed": isLineWrapping.value,
63
65
  class: "bg-b-2 text-c-2 hover:text-c-1 absolute right-18",
64
66
  icon: unref(ScalarIconArrowElbowDownLeft),
65
- "aria-pressed": isLineWrapping.value,
66
- "aria-label": isLineWrapping.value ? "Disable line wrap" : "Wrap lines",
67
67
  label: isLineWrapping.value ? "Disable line wrap" : "Wrap lines",
68
68
  size: "sm",
69
69
  tooltip: "",
70
70
  variant: "ghost",
71
71
  onClick: toggleLineWrapping
72
72
  }, null, 8, [
73
- "icon",
74
- "aria-pressed",
75
73
  "aria-label",
74
+ "aria-pressed",
75
+ "icon",
76
76
  "label"
77
77
  ]), createVNode(unref(ScalarCodeBlockCopy), {
78
78
  "aria-controls": unref(id),
@@ -1 +1 @@
1
- {"version":3,"file":"ResponseBodyRaw.vue.script.js","names":[],"sources":["../../../../../src/v2/blocks/response-block/components/ResponseBodyRaw.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { ScalarCodeBlockCopy } from '@scalar/components/code-block'\nimport { ScalarIconButton } from '@scalar/components/icon-button'\nimport { ScalarIconArrowElbowDownLeft } from '@scalar/icons'\nimport {\n EditorView,\n useCodeMirror,\n type CodeMirrorLanguage,\n} from '@scalar/use-codemirror'\nimport { computed, ref, toRef, useId } from 'vue'\n\nimport { prettifyJsoncString } from '@/v2/blocks/response-block/helpers/prettify-jsonc-string'\n\nconst props = defineProps<{\n content: unknown\n language: CodeMirrorLanguage | undefined\n /** When true, JSON/JSONC strings are pretty-printed for the Preview tab (wire bytes stay unchanged in Raw). */\n prettyPrintJson?: boolean\n}>()\n\nconst codeMirrorRef = ref<HTMLDivElement | null>(null)\n/** Base id for the code block */\nconst id = useId()\n\nconst isLineWrapping = ref(false)\n\nconst displayContent = computed((): string => {\n const { content, language, prettyPrintJson = false } = props\n if (typeof content !== 'string') {\n if (content == null) {\n return ''\n }\n return String(content)\n }\n if (prettyPrintJson && language === 'json') {\n return prettifyJsoncString(content)\n }\n return content\n})\n\nconst extensions = computed(() =>\n isLineWrapping.value ? [EditorView.lineWrapping] : [],\n)\n\nconst { codeMirror } = useCodeMirror({\n codeMirrorRef,\n readOnly: true,\n lineNumbers: true,\n content: toRef(displayContent),\n language: toRef(() => props.language),\n forceFoldGutter: true,\n extensions,\n})\n\n// Function to get current content\nconst getCurrentContent = () => {\n return codeMirror.value?.state.doc.toString() || ''\n}\n\nconst toggleLineWrapping = (): void => {\n isLineWrapping.value = !isLineWrapping.value\n}\n</script>\n<template>\n <div\n class=\"scalar-code-block group/code-block relative grid min-h-0 overflow-hidden p-px outline-none has-focus-visible:outline\"\n data-testid=\"response-body-raw\">\n <div\n class=\"custom-scroll relative pr-1\"\n tabindex=\"0\">\n <!-- CodeMirror container -->\n <div ref=\"codeMirrorRef\" />\n </div>\n <!-- Action buttons -->\n <div\n v-if=\"getCurrentContent()\"\n class=\"absolute top-2 right-2 flex items-center gap-1.5 opacity-0 transition-opacity duration-150 group-hover/code-block:opacity-100 group-has-focus-visible/code-block:opacity-100\">\n <ScalarIconButton\n class=\"bg-b-2 text-c-2 hover:text-c-1 absolute right-18\"\n :icon=\"ScalarIconArrowElbowDownLeft\"\n :aria-pressed=\"isLineWrapping\"\n :aria-label=\"isLineWrapping ? 'Disable line wrap' : 'Wrap lines'\"\n :label=\"isLineWrapping ? 'Disable line wrap' : 'Wrap lines'\"\n size=\"sm\"\n tooltip\n variant=\"ghost\"\n @click=\"toggleLineWrapping\" />\n <ScalarCodeBlockCopy\n :aria-controls=\"id\"\n :content=\"getCurrentContent()\" />\n </div>\n </div>\n</template>\n<style scoped>\n:deep(.cm-editor) {\n background-color: transparent;\n font-size: var(--scalar-small);\n outline: none;\n}\n\n:deep(.cm-gutters) {\n background-color: var(--scalar-background-1);\n border-radius: var(--scalar-radius) 0 0 var(--scalar-radius);\n}\n\n:deep(.cm-scroller) {\n overflow: auto;\n min-width: 100%;\n}\n\n:deep(.cm-lineWrapping .cm-line) {\n word-break: break-all;\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;EAaA,MAAM,QAAQ;EAOd,MAAM,gBAAgB,IAA2B,IAAI;;EAErD,MAAM,KAAK,MAAM;EAEjB,MAAM,iBAAiB,IAAI,KAAK;EAEhC,MAAM,iBAAiB,eAAuB;GAC5C,MAAM,EAAE,SAAS,UAAU,kBAAkB,UAAU;GACvD,IAAI,OAAO,YAAY,UAAU;IAC/B,IAAI,WAAW,MACb,OAAO;IAET,OAAO,OAAO,OAAO;GACvB;GACA,IAAI,mBAAmB,aAAa,QAClC,OAAO,oBAAoB,OAAO;GAEpC,OAAO;EACT,CAAC;EAED,MAAM,aAAa,eACjB,eAAe,QAAQ,CAAC,WAAW,YAAY,IAAI,CAAC,CACtD;EAEA,MAAM,EAAE,eAAe,cAAc;GACnC;GACA,UAAU;GACV,aAAa;GACb,SAAS,MAAM,cAAc;GAC7B,UAAU,YAAY,MAAM,QAAQ;GACpC,iBAAiB;GACjB;EACF,CAAC;EAGD,MAAM,0BAA0B;GAC9B,OAAO,WAAW,OAAO,MAAM,IAAI,SAAS,KAAK;EACnD;EAEA,MAAM,2BAAiC;GACrC,eAAe,QAAQ,CAAC,eAAe;EACzC;;uBAGE,mBA2BM,OA3BN,YA2BM,CAxBJ,mBAKM,OALN,YAKM,CADJ,mBAA2B,OAAA;aAAlB;IAAJ,KAAI;oBAIH,kBAAiB,KAAA,UAAA,GADzB,mBAgBM,OAhBN,YAgBM,CAbJ,YASgC,MAAA,gBAAA,GAAA;IAR9B,OAAM;IACL,MAAM,MAAA,4BAAA;IACN,gBAAc,eAAA;IACd,cAAY,eAAA,QAAc,sBAAA;IAC1B,OAAO,eAAA,QAAc,sBAAA;IACtB,MAAK;IACL,SAAA;IACA,SAAQ;IACP,SAAO;;;;;;OACV,YAEmC,MAAA,mBAAA,GAAA;IADhC,iBAAe,MAAA,EAAA;IACf,SAAS,kBAAiB"}
1
+ {"version":3,"file":"ResponseBodyRaw.vue.script.js","names":[],"sources":["../../../../../src/v2/blocks/response-block/components/ResponseBodyRaw.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { ScalarCodeBlockCopy } from '@scalar/components/code-block'\nimport { ScalarIconButton } from '@scalar/components/icon-button'\nimport { ScalarIconArrowElbowDownLeft } from '@scalar/icons'\nimport {\n EditorView,\n useCodeMirror,\n type CodeMirrorLanguage,\n} from '@scalar/use-codemirror'\nimport { computed, ref, toRef, useId } from 'vue'\n\nimport { prettifyJsoncString } from '@/v2/blocks/response-block/helpers/prettify-jsonc-string'\n\nconst props = defineProps<{\n content: unknown\n language: CodeMirrorLanguage | undefined\n /** When true, JSON/JSONC strings are pretty-printed for the Preview tab (wire bytes stay unchanged in Raw). */\n prettyPrintJson?: boolean\n}>()\n\nconst codeMirrorRef = ref<HTMLDivElement | null>(null)\n/** Base id for the code block */\nconst id = useId()\n\nconst isLineWrapping = ref(false)\n\nconst displayContent = computed((): string => {\n const { content, language, prettyPrintJson = false } = props\n if (typeof content !== 'string') {\n if (content == null) {\n return ''\n }\n return String(content)\n }\n if (prettyPrintJson && language === 'json') {\n return prettifyJsoncString(content)\n }\n return content\n})\n\nconst extensions = computed(() =>\n isLineWrapping.value ? [EditorView.lineWrapping] : [],\n)\n\nconst { codeMirror } = useCodeMirror({\n codeMirrorRef,\n readOnly: true,\n lineNumbers: true,\n content: toRef(displayContent),\n language: toRef(() => props.language),\n forceFoldGutter: true,\n extensions,\n})\n\n// Function to get current content\nconst getCurrentContent = () => {\n return codeMirror.value?.state.doc.toString() || ''\n}\n\nconst toggleLineWrapping = (): void => {\n isLineWrapping.value = !isLineWrapping.value\n}\n</script>\n<template>\n <div\n class=\"scalar-code-block group/code-block relative grid min-h-0 overflow-hidden p-px outline-none has-focus-visible:outline\"\n data-testid=\"response-body-raw\">\n <div\n class=\"custom-scroll relative pr-1\"\n tabindex=\"0\">\n <!-- CodeMirror container -->\n <div ref=\"codeMirrorRef\" />\n </div>\n <!-- Action buttons -->\n <div\n v-if=\"getCurrentContent()\"\n class=\"absolute top-2 right-2 flex items-center gap-1.5 opacity-0 transition-opacity duration-150 group-hover/code-block:opacity-100 group-has-focus-visible/code-block:opacity-100\">\n <ScalarIconButton\n :aria-label=\"isLineWrapping ? 'Disable line wrap' : 'Wrap lines'\"\n :aria-pressed=\"isLineWrapping\"\n class=\"bg-b-2 text-c-2 hover:text-c-1 absolute right-18\"\n :icon=\"ScalarIconArrowElbowDownLeft\"\n :label=\"isLineWrapping ? 'Disable line wrap' : 'Wrap lines'\"\n size=\"sm\"\n tooltip\n variant=\"ghost\"\n @click=\"toggleLineWrapping\" />\n <ScalarCodeBlockCopy\n :aria-controls=\"id\"\n :content=\"getCurrentContent()\" />\n </div>\n </div>\n</template>\n<style scoped>\n:deep(.cm-editor) {\n background-color: transparent;\n font-size: var(--scalar-small);\n outline: none;\n}\n\n:deep(.cm-gutters) {\n background-color: var(--scalar-background-1);\n border-radius: var(--scalar-radius) 0 0 var(--scalar-radius);\n}\n\n:deep(.cm-scroller) {\n overflow: auto;\n min-width: 100%;\n}\n\n:deep(.cm-lineWrapping .cm-line) {\n word-break: break-all;\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;EAaA,MAAM,QAAQ;EAOd,MAAM,gBAAgB,IAA2B,IAAI;;EAErD,MAAM,KAAK,MAAM;EAEjB,MAAM,iBAAiB,IAAI,KAAK;EAEhC,MAAM,iBAAiB,eAAuB;GAC5C,MAAM,EAAE,SAAS,UAAU,kBAAkB,UAAU;GACvD,IAAI,OAAO,YAAY,UAAU;IAC/B,IAAI,WAAW,MACb,OAAO;IAET,OAAO,OAAO,OAAO;GACvB;GACA,IAAI,mBAAmB,aAAa,QAClC,OAAO,oBAAoB,OAAO;GAEpC,OAAO;EACT,CAAC;EAED,MAAM,aAAa,eACjB,eAAe,QAAQ,CAAC,WAAW,YAAY,IAAI,CAAC,CACtD;EAEA,MAAM,EAAE,eAAe,cAAc;GACnC;GACA,UAAU;GACV,aAAa;GACb,SAAS,MAAM,cAAc;GAC7B,UAAU,YAAY,MAAM,QAAQ;GACpC,iBAAiB;GACjB;EACF,CAAC;EAGD,MAAM,0BAA0B;GAC9B,OAAO,WAAW,OAAO,MAAM,IAAI,SAAS,KAAK;EACnD;EAEA,MAAM,2BAAiC;GACrC,eAAe,QAAQ,CAAC,eAAe;EACzC;;uBAGE,mBA2BM,OA3BN,YA2BM,CAxBJ,mBAKM,OALN,YAKM,CADJ,mBAA2B,OAAA;aAAlB;IAAJ,KAAI;oBAIH,kBAAiB,KAAA,UAAA,GADzB,mBAgBM,OAhBN,YAgBM,CAbJ,YASgC,MAAA,gBAAA,GAAA;IAR7B,cAAY,eAAA,QAAc,sBAAA;IAC1B,gBAAc,eAAA;IACf,OAAM;IACL,MAAM,MAAA,4BAAA;IACN,OAAO,eAAA,QAAc,sBAAA;IACtB,MAAK;IACL,SAAA;IACA,SAAQ;IACP,SAAO;;;;;;OACV,YAEmC,MAAA,mBAAA,GAAA;IADhC,iBAAe,MAAA,EAAA;IACf,SAAS,kBAAiB"}
@@ -1 +1 @@
1
- {"version":3,"file":"OAuth2.vue.d.ts","sourceRoot":"","sources":["../../../../../src/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue"],"names":[],"mappings":"AAmxBA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AAIzE,OAAO,KAAK,EAEV,iBAAiB,EAClB,MAAM,gCAAgC,CAAA;AAMvC,OAAO,EAKL,KAAK,sBAAsB,EAC3B,KAAK,0BAA0B,EAChC,MAAM,yCAAyC,CAAA;AAChD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2EAA2E,CAAA;AAEnH,OAAO,KAAK,EAEV,YAAY,EACb,MAAM,8DAA8D,CAAA;AAIrE,OAAO,EAGL,KAAK,qBAAqB,EAC3B,MAAM,sDAAsD,CAAA;AAS7D,uDAAuD;AACvD,MAAM,MAAM,aAAa,GAAG,IAAI,CAC9B,sBAAsB,EACtB,mBAAmB,CACpB,GAAG;IACF,2GAA2G;IAC3G,WAAW,CAAC,EAAE,OAAO,KAAK,CAAA;IAC1B,0FAA0F;IAC1F,qBAAqB,CAAC,EAAE,qBAAqB,CAAA;CAC9C,CAAA;wBACoB,OAAO,YAAY;AAAxC,wBAAyC;AACzC,QAAA,MAAM,YAAY;IAEhB,wCAAwC;iBAC3B,kBAAkB;IAC/B,kBAAkB;WACX,sBAAsB;IAC7B,6BAA6B;UACvB,MAAM,sBAAsB;IAClC,sBAAsB;oBACN,MAAM,EAAE;IACxB,sBAAsB;YACd,0BAA0B;IAClC,mCAAmC;YAC3B,YAAY,GAAG,IAAI;IAC3B,gBAAgB;cACN,MAAM;IAChB,kCAAkC;UAC5B,MAAM;IACZ,2CAA2C;cACjC,iBAAiB;IAC3B,uDAAuD;cAC7C,aAAa;IACvB;;;;OAIG;kBACW,OAAO;;;iBAmBC,MAAM,EAAE;gBAAU,MAAM;mBAAa,OAAO;;;;;;;;;;;;;;;;IA5ClE,wCAAwC;iBAC3B,kBAAkB;IAC/B,kBAAkB;WACX,sBAAsB;IAC7B,6BAA6B;UACvB,MAAM,sBAAsB;IAClC,sBAAsB;oBACN,MAAM,EAAE;IACxB,sBAAsB;YACd,0BAA0B;IAClC,mCAAmC;YAC3B,YAAY,GAAG,IAAI;IAC3B,gBAAgB;cACN,MAAM;IAChB,kCAAkC;UAC5B,MAAM;IACZ,2CAA2C;cACjC,iBAAiB;IAC3B,uDAAuD;cAC7C,aAAa;IACvB;;;;OAIG;kBACW,OAAO;;;iBAmBC,MAAM,EAAE;gBAAU,MAAM;mBAAa,OAAO;;;;;;;;;;;;;;;kFAg8ChE,CAAC"}
1
+ {"version":3,"file":"OAuth2.vue.d.ts","sourceRoot":"","sources":["../../../../../src/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue"],"names":[],"mappings":"AAwwBA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AAIzE,OAAO,KAAK,EAEV,iBAAiB,EAClB,MAAM,gCAAgC,CAAA;AAMvC,OAAO,EAKL,KAAK,sBAAsB,EAC3B,KAAK,0BAA0B,EAChC,MAAM,yCAAyC,CAAA;AAChD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2EAA2E,CAAA;AAEnH,OAAO,KAAK,EAEV,YAAY,EACb,MAAM,8DAA8D,CAAA;AAIrE,OAAO,EAGL,KAAK,qBAAqB,EAC3B,MAAM,sDAAsD,CAAA;AAS7D,uDAAuD;AACvD,MAAM,MAAM,aAAa,GAAG,IAAI,CAC9B,sBAAsB,EACtB,mBAAmB,CACpB,GAAG;IACF,2GAA2G;IAC3G,WAAW,CAAC,EAAE,OAAO,KAAK,CAAA;IAC1B,0FAA0F;IAC1F,qBAAqB,CAAC,EAAE,qBAAqB,CAAA;CAC9C,CAAA;wBACoB,OAAO,YAAY;AAAxC,wBAAyC;AACzC,QAAA,MAAM,YAAY;IAEhB,wCAAwC;iBAC3B,kBAAkB;IAC/B,kBAAkB;WACX,sBAAsB;IAC7B,6BAA6B;UACvB,MAAM,sBAAsB;IAClC,sBAAsB;oBACN,MAAM,EAAE;IACxB,sBAAsB;YACd,0BAA0B;IAClC,mCAAmC;YAC3B,YAAY,GAAG,IAAI;IAC3B,gBAAgB;cACN,MAAM;IAChB,kCAAkC;UAC5B,MAAM;IACZ,2CAA2C;cACjC,iBAAiB;IAC3B,uDAAuD;cAC7C,aAAa;IACvB;;;;OAIG;kBACW,OAAO;;;iBAmBC,MAAM,EAAE;gBAAU,MAAM;mBAAa,OAAO;;;;;;;;;;;;;;;;IA5ClE,wCAAwC;iBAC3B,kBAAkB;IAC/B,kBAAkB;WACX,sBAAsB;IAC7B,6BAA6B;UACvB,MAAM,sBAAsB;IAClC,sBAAsB;oBACN,MAAM,EAAE;IACxB,sBAAsB;YACd,0BAA0B;IAClC,mCAAmC;YAC3B,YAAY,GAAG,IAAI;IAC3B,gBAAgB;cACN,MAAM;IAChB,kCAAkC;UAC5B,MAAM;IACZ,2CAA2C;cACjC,iBAAiB;IAC3B,uDAAuD;cAC7C,aAAa;IACvB;;;;OAIG;kBACW,OAAO;;;iBAmBC,MAAM,EAAE;gBAAU,MAAM;mBAAa,OAAO;;;;;;;;;;;;;;;kFA65ChE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"OAuth2.vue.js","names":[],"sources":["../../../../../src/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue"],"sourcesContent":["<script lang=\"ts\">\n/** Any config options required for the OAuth2 flow */\nexport type OAuth2Options = Pick<\n ApiClientConfiguration,\n 'oauth2RedirectUri'\n> & {\n /** Optional fetch override (IPC-backed on desktop) used for token exchange, refresh, and OIDC discovery */\n customFetch?: typeof fetch\n /** Optional redirect capture (loopback-backed on desktop) for interactive OAuth2 flows */\n captureOAuth2Callback?: CaptureOAuth2Callback\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { ScalarButton } from '@scalar/components/button'\nimport { useLoadingState } from '@scalar/components/loading'\nimport type { ApiClientConfiguration } from '@scalar/types/api-reference'\nimport { pkceOptions } from '@scalar/types/entities'\nimport { useToasts } from '@scalar/use-toasts'\nimport type { SecretsOAuthFlows } from '@scalar/workspace-store/entities/auth'\nimport type {\n ApiReferenceEvents,\n WorkspaceEventBus,\n} from '@scalar/workspace-store/events'\nimport {\n canResetSecretField,\n isSecretFieldCleared,\n type AuthSecretField,\n} from '@scalar/workspace-store/helpers/auth-secret-fields'\nimport {\n getEnvironmentVariables,\n type OAuthFlowAuthorizationCodeSecret,\n type OAuthFlowClientCredentialsSecret,\n type OAuthFlowPasswordSecret,\n type OAuthFlowsObjectSecret,\n type SecuritySchemeObjectSecret,\n} from '@scalar/workspace-store/request-example'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport type { XScalarCredentialsLocation } from '@scalar/workspace-store/schemas/extensions/security/x-scalar-credentials-location'\nimport type {\n OAuthFlow,\n ServerObject,\n} from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document'\nimport { computed, onBeforeUnmount, ref, watch } from 'vue'\n\nimport OAuthScopesInput from '@/v2/blocks/scalar-auth-selector-block/components/OAuthScopesInput.vue'\nimport {\n authorizeOauth2,\n refreshOauth2Token,\n type CaptureOAuth2Callback,\n} from '@/v2/blocks/scalar-auth-selector-block/helpers/oauth'\nimport { resolveDefaultOAuth2RedirectUri } from '@/v2/blocks/scalar-auth-selector-block/helpers/resolve-default-oauth2-redirect-url'\nimport { DataTableRow } from '@/v2/components/data-table'\nimport { useLocalization } from '@/v2/features/localization'\n\nimport type { DeviceAuthorizationPrompt } from '../helpers/oauth-device-authorization'\nimport RequestAuthDataTableInput from './RequestAuthDataTableInput.vue'\n\nconst {\n environment,\n flows,\n type,\n scheme,\n selectedScopes: selectedScopesProp,\n server,\n proxyUrl,\n eventBus,\n name,\n options = {},\n} = defineProps<{\n /** Current environment configuration */\n environment: XScalarEnvironment\n /** OAuth flows */\n flows: OAuthFlowsObjectSecret\n /** Type of the OAuth flow */\n type: keyof OAuthFlowsObjectSecret\n /** Selected scopes */\n selectedScopes: string[]\n /** Security scheme */\n scheme: SecuritySchemeObjectSecret\n /** Current server configuration */\n server: ServerObject | null\n /** Proxy URL */\n proxyUrl: string\n /** Name of the security scheme */\n name: string\n /** Event bus for authentication updates */\n eventBus: WorkspaceEventBus\n /** Any config options required for the OAuth2 flow */\n options?: OAuth2Options\n /**\n * Hides the Authorize / Refresh / Clear actions. Used when the form is embedded as a\n * configuration-only view (e.g. behind a gear icon), so the host component owns the\n * authorize action and the tokens are routed to the scheme it chooses.\n */\n hideActions?: boolean\n}>()\n\nconst emits = defineEmits<{\n (\n e: 'update:selectedScopes',\n payload: { scopes?: string[]; scope?: string; selected?: boolean },\n ): void\n (\n e: 'upsert:scope',\n payload: Omit<ApiReferenceEvents['auth:upsert:scopes'], 'name'>,\n ): void\n (\n e: 'delete:scope',\n payload: Omit<ApiReferenceEvents['auth:delete:scopes'], 'name'>,\n ): void\n}>()\n\nconst devicePrompt = ref<DeviceAuthorizationPrompt | null>(null)\nlet deviceController: AbortController | undefined\nconst cancelDeviceAuthorization = (): void => {\n deviceController?.abort()\n devicePrompt.value = null\n}\nonBeforeUnmount(cancelDeviceAuthorization)\nwatch(() => [type, name, flows], cancelDeviceAuthorization)\n\nconst { translate } = useLocalization()\n\nconst loader = useLoadingState()\nconst { toast } = useToasts()\n\n/** The current OAuth flow based on the selected type */\nconst flow = computed(() => flows[type]!)\ntype NonImplicitFlow =\n | OAuthFlowPasswordSecret\n | OAuthFlowClientCredentialsSecret\n | OAuthFlowAuthorizationCodeSecret\n\n/** We filter selected scopes to only include scopes that are defined on this flow (own keys only). */\nconst selectedScopes = computed(() => {\n const definedScopes = flow.value.scopes\n if (!definedScopes) {\n return []\n }\n return selectedScopesProp.filter((scope) =>\n Object.hasOwn(definedScopes, scope),\n )\n})\n\n/**\n * Show the client secret whenever the flow supports one. PKCE and a client\n * secret are independent, so confidential clients can use both together\n * (see RFC 9700 Section 2.1.1).\n */\nconst showClientSecret = computed(\n () => 'x-scalar-secret-client-secret' in flow.value,\n)\n\nconst clientSecretValue = computed((): string => {\n const f = flow.value as { 'x-scalar-secret-client-secret'?: string }\n return f['x-scalar-secret-client-secret'] ?? ''\n})\n\n/** Updates the security scheme base */\nconst handleOauth2Update = (\n payload: Partial<OAuthFlow & XScalarCredentialsLocation> & {\n deviceAuthorizationUrl?: string\n },\n): void => {\n // OpenIdConnect uses the secrets update for all\n if (scheme.type === 'openIdConnect') {\n return handleOauth2SecretsUpdate(payload)\n }\n\n // Only OAuth2 schemes carry flows on the document; this component is never\n // rendered for the other scheme types.\n if (scheme.type !== 'oauth2') {\n return\n }\n\n eventBus.emit('auth:update:security-scheme', {\n payload: {\n type: scheme.type,\n flows: {\n [type]: payload,\n },\n },\n name,\n })\n}\n\n/** Updates the flow secrets */\nconst handleOauth2SecretsUpdate = (\n payload: Omit<Partial<SecretsOAuthFlows[keyof SecretsOAuthFlows]>, 'type'>,\n): void => {\n // This component only renders for oauth2/openIdConnect. Other scheme types (e.g. mutualTLS)\n // carry no flow secrets, so there is nothing to persist and no matching secrets payload type.\n if (scheme.type !== 'oauth2' && scheme.type !== 'openIdConnect') {\n return\n }\n\n eventBus.emit('auth:update:security-scheme-secrets', {\n payload: {\n type: scheme.type,\n [type]: payload,\n },\n name,\n })\n}\n\n/** Reset only this field; redirect URI may need its browser default prefilled again. */\nconst handleResetSecret = (field: AuthSecretField): void => {\n if (field === 'x-scalar-secret-redirect-uri') {\n hasHandledRedirectPrefill.value = false\n }\n eventBus.emit('auth:reset:security-scheme-secret', {\n name,\n flow: type,\n field,\n })\n}\n\n/**\n * Reset needs a default to restore, otherwise it would only clear the field like the clear\n * action does. A cleared access token is the exception: the token view stays open while it is\n * cleared, and Reset is the only way back to the Authorize form.\n */\nconst canReset = (\n field: AuthSecretField,\n value: string | undefined,\n): boolean => {\n if (\n field === 'x-scalar-secret-token' &&\n isSecretFieldCleared(flow.value, field)\n ) {\n return true\n }\n // Without a stored default, resetting the redirect URI re-runs the browser prefill below,\n // unless the desktop loopback capture computes it at authorize time instead.\n const fallback =\n field === 'x-scalar-secret-redirect-uri' && !options.captureOAuth2Callback\n ? resolveDefaultOAuth2RedirectUri(options)\n : ''\n return canResetSecretField(flow.value, field, value, fallback)\n}\n\n/** Fixed-choice fields must never write an empty string into the document. */\nconst handlePkceUpdate = (value: string): void => {\n if (value === 'SHA-256' || value === 'plain' || value === 'no') {\n handleOauth2Update({ 'x-usePkce': value })\n }\n}\n\n/** Clears the flow secrets */\nconst clearOauth2Secrets = (): void => {\n if (loader.isLoading) {\n return\n }\n eventBus.emit('auth:clear:security-scheme-secrets', {\n name,\n })\n}\n\n/** Clears stored access and refresh tokens (authorized state) */\nconst handleClearAccessTokens = (): void => {\n if (loader.isLoading) {\n return\n }\n handleOauth2SecretsUpdate({\n 'x-scalar-secret-token': '',\n 'x-scalar-secret-refresh-token': '',\n })\n}\n\n/** Track redirect URI prefill per flow instance to support document switching */\nconst prefilledFlowIdentity = ref<string | null>(null)\nconst hasHandledRedirectPrefill = ref(false)\n\nconst resolveFlowIdentity = (\n currentFlow: OAuthFlowsObjectSecret[keyof OAuthFlowsObjectSecret] | undefined,\n): string =>\n JSON.stringify({\n type,\n authorizationUrl:\n currentFlow && 'authorizationUrl' in currentFlow\n ? currentFlow.authorizationUrl\n : '',\n tokenUrl:\n currentFlow && 'tokenUrl' in currentFlow ? currentFlow.tokenUrl : '',\n refreshUrl: currentFlow?.refreshUrl ?? '',\n scopes: Object.keys(currentFlow?.scopes ?? {}),\n })\n\n/** Default the redirect-uri to the current origin if we have access to window */\nwatch(\n () => flow.value,\n (currentFlow) => {\n if (!currentFlow || !('x-scalar-secret-redirect-uri' in currentFlow)) {\n return\n }\n\n const flowIdentity = resolveFlowIdentity(currentFlow)\n if (prefilledFlowIdentity.value !== flowIdentity) {\n prefilledFlowIdentity.value = flowIdentity\n hasHandledRedirectPrefill.value = false\n }\n\n if (hasHandledRedirectPrefill.value) {\n return\n }\n\n const newRedirectUri = (currentFlow as OAuthFlowAuthorizationCodeSecret)[\n 'x-scalar-secret-redirect-uri'\n ]\n const defaultRedirectUri = resolveDefaultOAuth2RedirectUri(options)\n\n hasHandledRedirectPrefill.value = true\n\n // The desktop loopback path computes the redirect URI at authorize time (an\n // ephemeral 127.0.0.1 port), so persisting a default into the document would\n // only bake in a stale, unused value. Leave it empty and show a hint instead.\n if (\n isSecretFieldCleared(currentFlow, 'x-scalar-secret-redirect-uri') ||\n newRedirectUri ||\n !defaultRedirectUri ||\n options.captureOAuth2Callback\n ) {\n return\n }\n\n handleOauth2SecretsUpdate({\n 'x-scalar-secret-redirect-uri': defaultRedirectUri,\n })\n },\n { immediate: true },\n)\n\n/**\n * Authorizes the user using the specified OAuth flow.\n * Opens the appropriate OAuth dialog and/or performs the token exchange.\n */\nconst handleAuthorize = async (): Promise<void> => {\n if (loader.isLoading) {\n return\n }\n\n loader.start()\n const controller = new AbortController()\n deviceController = controller\n\n const [error, tokens] = await authorizeOauth2(\n flows,\n type,\n selectedScopes.value,\n server,\n proxyUrl,\n getEnvironmentVariables(environment),\n options.customFetch,\n options.captureOAuth2Callback,\n {\n signal: controller.signal,\n onPrompt: (prompt) => {\n devicePrompt.value = prompt\n },\n },\n )\n devicePrompt.value = null\n\n await loader.clear()\n if (controller.signal.aborted) {\n return\n }\n\n if (tokens?.accessToken) {\n handleOauth2SecretsUpdate({\n 'x-scalar-secret-token': tokens.accessToken,\n ...(tokens.refreshToken\n ? { 'x-scalar-secret-refresh-token': tokens.refreshToken }\n : {}),\n })\n } else {\n console.error(error)\n toast(\n error?.message ?? translate('apiClient.oauth2.failedToauthorize'),\n 'error',\n )\n }\n}\n\n/** Refreshing requires a token issued by the provider, not just a compatible flow. */\nconst canRefreshToken = computed<boolean>(\n (): boolean =>\n type !== 'implicit' && Boolean(flow.value['x-scalar-secret-refresh-token']),\n)\n\n/**\n * Refresh URL placeholder, shows tokenUrl as hint if refreshUrl is not specified.\n * This helps users understand that tokenUrl will be used as fallback.\n */\nconst refreshUrlPlaceholder = computed(() => {\n if ('tokenUrl' in flow.value && flow.value.tokenUrl) {\n return flow.value.tokenUrl\n }\n return 'https://galaxy.scalar.com/oauth/refresh'\n})\n\n/**\n * Uses the stored refresh token to obtain a new access token\n * via grant_type=refresh_token.\n */\nconst handleRefresh = async (): Promise<void> => {\n // The explicit flow check narrows the type for refreshOauth2Token; the computed boolean cannot.\n if (loader.isLoading || type === 'implicit' || !canRefreshToken.value) {\n return\n }\n\n loader.start()\n\n const [error, tokens] = await refreshOauth2Token(\n flows,\n type,\n proxyUrl,\n server,\n getEnvironmentVariables(environment),\n options.customFetch,\n )\n\n await loader.clear()\n\n if (tokens?.accessToken) {\n handleOauth2SecretsUpdate({\n 'x-scalar-secret-token': tokens.accessToken,\n ...(tokens.refreshToken\n ? { 'x-scalar-secret-refresh-token': tokens.refreshToken }\n : {}),\n })\n } else {\n console.error(error)\n toast(\n error?.message ?? translate('apiClient.oauth2.failedToRefreshToken'),\n 'error',\n )\n }\n}\n\n/** Updates the secret location */\nconst handleSecretLocationUpdate = (value: string): void => {\n if (value !== 'body' && value !== 'header') return\n const credentialsLocation = value\n\n if (scheme.type !== 'openIdConnect') {\n handleOauth2Update({\n 'x-scalar-credentials-location': credentialsLocation,\n })\n }\n\n handleOauth2SecretsUpdate({\n 'x-scalar-credentials-location': credentialsLocation,\n })\n}\n</script>\n\n<template>\n <!-- Access Token Display: Shows when user is already authorized -->\n <template\n v-if=\"\n Boolean(flow['x-scalar-secret-token']) ||\n isSecretFieldCleared(flow, 'x-scalar-secret-token')\n \">\n <DataTableRow>\n <RequestAuthDataTableInput\n :canReset=\"\n canReset('x-scalar-secret-token', flow['x-scalar-secret-token'])\n \"\n class=\"border-r-transparent\"\n :environment\n :modelValue=\"flow['x-scalar-secret-token']\"\n placeholder=\"QUxMIFlPVVIgQkFTRSBBUkUgQkVMT05HIFRPIFVT\"\n type=\"password\"\n @reset=\"handleResetSecret('x-scalar-secret-token')\"\n @update:modelValue=\"\n (v) => handleOauth2SecretsUpdate({ 'x-scalar-secret-token': v })\n \">\n {{ translate('apiClient.oauth2.accessToken') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <DataTableRow v-if=\"canRefreshToken\">\n <RequestAuthDataTableInput\n class=\"border-r-transparent\"\n :environment\n :modelValue=\"flow.refreshUrl ?? ''\"\n :placeholder=\"refreshUrlPlaceholder\"\n @update:modelValue=\"(v) => handleOauth2Update({ refreshUrl: v })\">\n {{ translate('apiClient.oauth2.refreshUrl') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <DataTableRow\n v-if=\"!hideActions\"\n class=\"min-w-full\">\n <div class=\"flex h-8 items-center justify-end gap-2 border-t\">\n <ScalarButton\n v-if=\"canRefreshToken\"\n class=\"p-0 px-2 py-0.5\"\n :loader\n size=\"sm\"\n variant=\"outlined\"\n @click=\"handleRefresh\">\n {{ translate('apiClient.oauth2.refresh') }}\n </ScalarButton>\n <ScalarButton\n class=\"mr-1 p-0 px-2 py-0.5\"\n :disabled=\"loader.isLoading\"\n size=\"sm\"\n variant=\"outlined\"\n @click=\"handleClearAccessTokens\">\n {{ translate('apiClient.oauth2.clearTokens') }}\n </ScalarButton>\n </div>\n </DataTableRow>\n </template>\n\n <!-- Authorization Form: Shows when user needs to authorize -->\n <template v-else>\n <DataTableRow v-if=\"'deviceAuthorizationUrl' in flow\">\n <RequestAuthDataTableInput\n :environment\n :modelValue=\"flow.deviceAuthorizationUrl\"\n @update:modelValue=\"\n (v) => handleOauth2Update({ deviceAuthorizationUrl: v })\n \">\n {{ translate('apiClient.oauth2.deviceAuthorizationUrl') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n <DataTableRow v-if=\"devicePrompt\">\n <div class=\"w-full p-2\">\n <div\n class=\"bg-b-2 flex flex-col gap-3 rounded-lg border p-3 text-sm\"\n role=\"status\">\n <p class=\"text-c-2 text-xs leading-normal\">\n {{ translate('apiClient.oauth2.deviceVerificationPrompt') }}\n </p>\n <strong\n class=\"bg-b-1 font-code w-fit max-w-full rounded border px-3 py-2 text-base font-medium tracking-widest break-all select-all\">\n {{ devicePrompt.userCode }}\n </strong>\n <a\n class=\"text-c-accent w-fit max-w-full text-xs break-all underline underline-offset-2\"\n :href=\"\n devicePrompt.verificationUriComplete ||\n devicePrompt.verificationUri\n \"\n rel=\"noopener noreferrer\"\n target=\"_blank\">\n {{ devicePrompt.verificationUri }}\n </a>\n <div class=\"flex items-center justify-between gap-3\">\n <p class=\"text-c-2 text-xs\">\n {{ translate('apiClient.oauth2.waitingForAuthorization') }}\n </p>\n <ScalarButton\n size=\"xs\"\n variant=\"outlined\"\n @click=\"cancelDeviceAuthorization\">\n {{ translate('apiClient.oauth2.cancelDeviceAuthorization') }}\n </ScalarButton>\n </div>\n </div>\n </div>\n </DataTableRow>\n <DataTableRow>\n <RequestAuthDataTableInput\n v-if=\"'authorizationUrl' in flow\"\n :canReset=\"\n canReset(\n 'x-scalar-secret-auth-url',\n flow['x-scalar-secret-auth-url'] ?? '',\n )\n \"\n containerClass=\"border-r-0\"\n :environment\n :modelValue=\"flow['x-scalar-secret-auth-url'] ?? ''\"\n placeholder=\"https://galaxy.scalar.com/authorize\"\n @reset=\"handleResetSecret('x-scalar-secret-auth-url')\"\n @update:modelValue=\"\n (v) => {\n handleOauth2SecretsUpdate({ 'x-scalar-secret-auth-url': v })\n if (v) handleOauth2Update({ authorizationUrl: v })\n }\n \">\n {{ translate('apiClient.oauth2.authUrl') }}\n </RequestAuthDataTableInput>\n\n <RequestAuthDataTableInput\n v-if=\"'tokenUrl' in flow\"\n :canReset=\"\n canReset(\n 'x-scalar-secret-token-url',\n flow['x-scalar-secret-token-url'] ?? '',\n )\n \"\n :environment\n :modelValue=\"flow['x-scalar-secret-token-url'] ?? ''\"\n placeholder=\"https://galaxy.scalar.com/token\"\n @reset=\"handleResetSecret('x-scalar-secret-token-url')\"\n @update:modelValue=\"\n (v) => {\n handleOauth2SecretsUpdate({ 'x-scalar-secret-token-url': v })\n if (v) handleOauth2Update({ tokenUrl: v })\n }\n \">\n {{ translate('apiClient.oauth2.tokenUrl') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <DataTableRow v-if=\"'x-scalar-secret-redirect-uri' in flow\">\n <RequestAuthDataTableInput\n :canReset=\"\n canReset(\n 'x-scalar-secret-redirect-uri',\n flow['x-scalar-secret-redirect-uri'],\n )\n \"\n :environment\n :modelValue=\"flow['x-scalar-secret-redirect-uri']\"\n :placeholder=\"\n options.captureOAuth2Callback\n ? `${resolveDefaultOAuth2RedirectUri(options) || 'http://127.0.0.1'} (handled automatically)`\n : translate('apiClient.oauth2.optionalRedirectUrl')\n \"\n @reset=\"handleResetSecret('x-scalar-secret-redirect-uri')\"\n @update:modelValue=\"\n (v) => {\n hasHandledRedirectPrefill = true\n handleOauth2SecretsUpdate({ 'x-scalar-secret-redirect-uri': v })\n }\n \">\n {{ translate('apiClient.oauth2.redirectUrl') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <template\n v-if=\"\n 'x-scalar-secret-username' in flow && 'x-scalar-secret-password' in flow\n \">\n <DataTableRow>\n <RequestAuthDataTableInput\n :canReset=\"\n canReset(\n 'x-scalar-secret-username',\n flow['x-scalar-secret-username'],\n )\n \"\n class=\"text-c-2\"\n :environment\n :modelValue=\"flow['x-scalar-secret-username']\"\n placeholder=\"janedoe\"\n @reset=\"handleResetSecret('x-scalar-secret-username')\"\n @update:modelValue=\"\n (v) => handleOauth2SecretsUpdate({ 'x-scalar-secret-username': v })\n \">\n {{ translate('apiClient.oauth2.username') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <DataTableRow>\n <RequestAuthDataTableInput\n :canReset=\"\n canReset(\n 'x-scalar-secret-password',\n flow['x-scalar-secret-password'],\n )\n \"\n :environment\n :modelValue=\"flow['x-scalar-secret-password']\"\n placeholder=\"********\"\n type=\"password\"\n @reset=\"handleResetSecret('x-scalar-secret-password')\"\n @update:modelValue=\"\n (v) => handleOauth2SecretsUpdate({ 'x-scalar-secret-password': v })\n \">\n {{ translate('apiClient.oauth2.password') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n </template>\n\n <DataTableRow>\n <RequestAuthDataTableInput\n :canReset=\"\n canReset(\n 'x-scalar-secret-client-id',\n flow['x-scalar-secret-client-id'],\n )\n \"\n :environment\n :modelValue=\"flow['x-scalar-secret-client-id']\"\n placeholder=\"12345\"\n @reset=\"handleResetSecret('x-scalar-secret-client-id')\"\n @update:modelValue=\"\n (v) => handleOauth2SecretsUpdate({ 'x-scalar-secret-client-id': v })\n \">\n {{ translate('apiClient.oauth2.clientID') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <DataTableRow v-if=\"showClientSecret\">\n <RequestAuthDataTableInput\n :canReset=\"canReset('x-scalar-secret-client-secret', clientSecretValue)\"\n :environment\n :modelValue=\"clientSecretValue\"\n placeholder=\"XYZ123\"\n type=\"password\"\n @reset=\"handleResetSecret('x-scalar-secret-client-secret')\"\n @update:modelValue=\"\n (v) =>\n handleOauth2SecretsUpdate({ 'x-scalar-secret-client-secret': v })\n \">\n {{ translate('apiClient.oauth2.clientSecret') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <DataTableRow v-if=\"'x-usePkce' in flow\">\n <RequestAuthDataTableInput\n :enum=\"pkceOptions\"\n :environment\n :modelValue=\"flow['x-usePkce']\"\n readOnly\n @update:modelValue=\"handlePkceUpdate\">\n {{ translate('apiClient.oauth2.usePKCE') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <!-- Credentials Location -->\n <DataTableRow v-if=\"type !== 'implicit'\">\n <RequestAuthDataTableInput\n :enum=\"['header', 'body']\"\n :environment\n :modelValue=\"\n (flow as NonImplicitFlow)['x-scalar-credentials-location'] || 'header'\n \"\n placeholder=\"header\"\n readOnly\n @update:modelValue=\"(v) => handleSecretLocationUpdate(v)\">\n {{ translate('apiClient.oauth2.credentialsLocation') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <!-- Scopes -->\n <DataTableRow>\n <OAuthScopesInput\n :flow\n :flowType=\"type\"\n :selectedScopes\n @delete:scope=\"(v) => emits('delete:scope', v)\"\n @update:selectedScopes=\"(v) => emits('update:selectedScopes', v)\"\n @upsert:scope=\"(v) => emits('upsert:scope', v)\" />\n </DataTableRow>\n\n <DataTableRow\n v-if=\"!hideActions\"\n class=\"min-w-full\">\n <div class=\"flex h-8 w-full items-center justify-end border-t\">\n <!-- Allow clearing the oauth section and going back to discovery -->\n <ScalarButton\n v-if=\"scheme.type === 'openIdConnect'\"\n class=\"mr-1 p-0 px-2 py-0.5\"\n :disabled=\"loader.isLoading\"\n size=\"sm\"\n variant=\"outlined\"\n @click=\"clearOauth2Secrets\">\n {{ translate('apiClient.oauth2.resetDiscovery') }}\n </ScalarButton>\n\n <ScalarButton\n class=\"mr-0.75 p-0 px-2 py-0.5\"\n :loader\n size=\"sm\"\n variant=\"outlined\"\n @click=\"handleAuthorize\">\n {{ translate('apiClient.oauth2.authorize') }}\n </ScalarButton>\n </div>\n </DataTableRow>\n </template>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"OAuth2.vue.js","names":[],"sources":["../../../../../src/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue"],"sourcesContent":["<script lang=\"ts\">\n/** Any config options required for the OAuth2 flow */\nexport type OAuth2Options = Pick<\n ApiClientConfiguration,\n 'oauth2RedirectUri'\n> & {\n /** Optional fetch override (IPC-backed on desktop) used for token exchange, refresh, and OIDC discovery */\n customFetch?: typeof fetch\n /** Optional redirect capture (loopback-backed on desktop) for interactive OAuth2 flows */\n captureOAuth2Callback?: CaptureOAuth2Callback\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { ScalarButton } from '@scalar/components/button'\nimport { useLoadingState } from '@scalar/components/loading'\nimport type { ApiClientConfiguration } from '@scalar/types/api-reference'\nimport { pkceOptions } from '@scalar/types/entities'\nimport { useToasts } from '@scalar/use-toasts'\nimport type { SecretsOAuthFlows } from '@scalar/workspace-store/entities/auth'\nimport type {\n ApiReferenceEvents,\n WorkspaceEventBus,\n} from '@scalar/workspace-store/events'\nimport {\n canResetSecretField,\n isSecretFieldCleared,\n type AuthSecretField,\n} from '@scalar/workspace-store/helpers/auth-secret-fields'\nimport {\n getEnvironmentVariables,\n type OAuthFlowAuthorizationCodeSecret,\n type OAuthFlowClientCredentialsSecret,\n type OAuthFlowPasswordSecret,\n type OAuthFlowsObjectSecret,\n type SecuritySchemeObjectSecret,\n} from '@scalar/workspace-store/request-example'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport type { XScalarCredentialsLocation } from '@scalar/workspace-store/schemas/extensions/security/x-scalar-credentials-location'\nimport type {\n OAuthFlow,\n ServerObject,\n} from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document'\nimport { computed, onBeforeUnmount, ref, watch } from 'vue'\n\nimport OAuthScopesInput from '@/v2/blocks/scalar-auth-selector-block/components/OAuthScopesInput.vue'\nimport {\n authorizeOauth2,\n refreshOauth2Token,\n type CaptureOAuth2Callback,\n} from '@/v2/blocks/scalar-auth-selector-block/helpers/oauth'\nimport { resolveDefaultOAuth2RedirectUri } from '@/v2/blocks/scalar-auth-selector-block/helpers/resolve-default-oauth2-redirect-url'\nimport { DataTableRow } from '@/v2/components/data-table'\nimport { useLocalization } from '@/v2/features/localization'\n\nimport type { DeviceAuthorizationPrompt } from '../helpers/oauth-device-authorization'\nimport RequestAuthDataTableInput from './RequestAuthDataTableInput.vue'\n\nconst {\n environment,\n flows,\n type,\n scheme,\n selectedScopes: selectedScopesProp,\n server,\n proxyUrl,\n eventBus,\n name,\n options = {},\n} = defineProps<{\n /** Current environment configuration */\n environment: XScalarEnvironment\n /** OAuth flows */\n flows: OAuthFlowsObjectSecret\n /** Type of the OAuth flow */\n type: keyof OAuthFlowsObjectSecret\n /** Selected scopes */\n selectedScopes: string[]\n /** Security scheme */\n scheme: SecuritySchemeObjectSecret\n /** Current server configuration */\n server: ServerObject | null\n /** Proxy URL */\n proxyUrl: string\n /** Name of the security scheme */\n name: string\n /** Event bus for authentication updates */\n eventBus: WorkspaceEventBus\n /** Any config options required for the OAuth2 flow */\n options?: OAuth2Options\n /**\n * Hides the Authorize / Refresh / Clear actions. Used when the form is embedded as a\n * configuration-only view (e.g. behind a gear icon), so the host component owns the\n * authorize action and the tokens are routed to the scheme it chooses.\n */\n hideActions?: boolean\n}>()\n\nconst emits = defineEmits<{\n (\n e: 'update:selectedScopes',\n payload: { scopes?: string[]; scope?: string; selected?: boolean },\n ): void\n (\n e: 'upsert:scope',\n payload: Omit<ApiReferenceEvents['auth:upsert:scopes'], 'name'>,\n ): void\n (\n e: 'delete:scope',\n payload: Omit<ApiReferenceEvents['auth:delete:scopes'], 'name'>,\n ): void\n}>()\n\nconst devicePrompt = ref<DeviceAuthorizationPrompt | null>(null)\nlet deviceController: AbortController | undefined\nconst cancelDeviceAuthorization = (): void => {\n deviceController?.abort()\n devicePrompt.value = null\n}\nonBeforeUnmount(cancelDeviceAuthorization)\nwatch(() => [type, name, flows], cancelDeviceAuthorization)\n\nconst { translate } = useLocalization()\n\nconst loader = useLoadingState()\nconst { toast } = useToasts()\n\n/** The current OAuth flow based on the selected type */\nconst flow = computed(() => flows[type]!)\ntype NonImplicitFlow =\n | OAuthFlowPasswordSecret\n | OAuthFlowClientCredentialsSecret\n | OAuthFlowAuthorizationCodeSecret\n\n/** We filter selected scopes to only include scopes that are defined on this flow (own keys only). */\nconst selectedScopes = computed(() => {\n const definedScopes = flow.value.scopes\n if (!definedScopes) {\n return []\n }\n return selectedScopesProp.filter((scope) =>\n Object.hasOwn(definedScopes, scope),\n )\n})\n\n/**\n * Show the client secret whenever the flow supports one. PKCE and a client\n * secret are independent, so confidential clients can use both together\n * (see RFC 9700 Section 2.1.1).\n */\nconst showClientSecret = computed(\n () => 'x-scalar-secret-client-secret' in flow.value,\n)\n\nconst clientSecretValue = computed((): string => {\n const f = flow.value as { 'x-scalar-secret-client-secret'?: string }\n return f['x-scalar-secret-client-secret'] ?? ''\n})\n\n/** Updates the security scheme base */\nconst handleOauth2Update = (\n payload: Partial<OAuthFlow & XScalarCredentialsLocation> & {\n deviceAuthorizationUrl?: string\n },\n): void => {\n // OpenIdConnect uses the secrets update for all\n if (scheme.type === 'openIdConnect') {\n return handleOauth2SecretsUpdate(payload)\n }\n\n // Only OAuth2 schemes carry flows on the document; this component is never\n // rendered for the other scheme types.\n if (scheme.type !== 'oauth2') {\n return\n }\n\n eventBus.emit('auth:update:security-scheme', {\n payload: {\n type: scheme.type,\n flows: {\n [type]: payload,\n },\n },\n name,\n })\n}\n\n/** Updates the flow secrets */\nconst handleOauth2SecretsUpdate = (\n payload: Omit<Partial<SecretsOAuthFlows[keyof SecretsOAuthFlows]>, 'type'>,\n): void => {\n // This component only renders for oauth2/openIdConnect. Other scheme types (e.g. mutualTLS)\n // carry no flow secrets, so there is nothing to persist and no matching secrets payload type.\n if (scheme.type !== 'oauth2' && scheme.type !== 'openIdConnect') {\n return\n }\n\n eventBus.emit('auth:update:security-scheme-secrets', {\n payload: {\n type: scheme.type,\n [type]: payload,\n },\n name,\n })\n}\n\n/** Reset only this field; redirect URI may need its browser default prefilled again. */\nconst handleResetSecret = (field: AuthSecretField): void => {\n if (field === 'x-scalar-secret-redirect-uri') {\n hasHandledRedirectPrefill.value = false\n }\n eventBus.emit('auth:reset:security-scheme-secret', {\n name,\n flow: type,\n field,\n })\n}\n\n/**\n * Reset needs a default to restore, otherwise it would only clear the field like the clear\n * action does.\n */\nconst canReset = (\n field: AuthSecretField,\n value: string | undefined,\n): boolean => {\n // Without a stored default, resetting the redirect URI re-runs the browser prefill below,\n // unless the desktop loopback capture computes it at authorize time instead.\n const fallback =\n field === 'x-scalar-secret-redirect-uri' && !options.captureOAuth2Callback\n ? resolveDefaultOAuth2RedirectUri(options)\n : ''\n return canResetSecretField(flow.value, field, value, fallback)\n}\n\n/** Fixed-choice fields must never write an empty string into the document. */\nconst handlePkceUpdate = (value: string): void => {\n if (value === 'SHA-256' || value === 'plain' || value === 'no') {\n handleOauth2Update({ 'x-usePkce': value })\n }\n}\n\n/** Clears the flow secrets */\nconst clearOauth2Secrets = (): void => {\n if (loader.isLoading) {\n return\n }\n eventBus.emit('auth:clear:security-scheme-secrets', {\n name,\n })\n}\n\n/** Clears stored access and refresh tokens (authorized state) */\nconst handleClearAccessTokens = (): void => {\n if (loader.isLoading) {\n return\n }\n handleOauth2SecretsUpdate({\n 'x-scalar-secret-token': '',\n 'x-scalar-secret-refresh-token': '',\n })\n}\n\n/** Track redirect URI prefill per flow instance to support document switching */\nconst prefilledFlowIdentity = ref<string | null>(null)\nconst hasHandledRedirectPrefill = ref(false)\n\nconst resolveFlowIdentity = (\n currentFlow: OAuthFlowsObjectSecret[keyof OAuthFlowsObjectSecret] | undefined,\n): string =>\n JSON.stringify({\n type,\n authorizationUrl:\n currentFlow && 'authorizationUrl' in currentFlow\n ? currentFlow.authorizationUrl\n : '',\n tokenUrl:\n currentFlow && 'tokenUrl' in currentFlow ? currentFlow.tokenUrl : '',\n refreshUrl: currentFlow?.refreshUrl ?? '',\n scopes: Object.keys(currentFlow?.scopes ?? {}),\n })\n\n/** Default the redirect-uri to the current origin if we have access to window */\nwatch(\n () => flow.value,\n (currentFlow) => {\n if (!currentFlow || !('x-scalar-secret-redirect-uri' in currentFlow)) {\n return\n }\n\n const flowIdentity = resolveFlowIdentity(currentFlow)\n if (prefilledFlowIdentity.value !== flowIdentity) {\n prefilledFlowIdentity.value = flowIdentity\n hasHandledRedirectPrefill.value = false\n }\n\n if (hasHandledRedirectPrefill.value) {\n return\n }\n\n const newRedirectUri = (currentFlow as OAuthFlowAuthorizationCodeSecret)[\n 'x-scalar-secret-redirect-uri'\n ]\n const defaultRedirectUri = resolveDefaultOAuth2RedirectUri(options)\n\n hasHandledRedirectPrefill.value = true\n\n // The desktop loopback path computes the redirect URI at authorize time (an\n // ephemeral 127.0.0.1 port), so persisting a default into the document would\n // only bake in a stale, unused value. Leave it empty and show a hint instead.\n if (\n isSecretFieldCleared(currentFlow, 'x-scalar-secret-redirect-uri') ||\n newRedirectUri ||\n !defaultRedirectUri ||\n options.captureOAuth2Callback\n ) {\n return\n }\n\n handleOauth2SecretsUpdate({\n 'x-scalar-secret-redirect-uri': defaultRedirectUri,\n })\n },\n { immediate: true },\n)\n\n/**\n * Authorizes the user using the specified OAuth flow.\n * Opens the appropriate OAuth dialog and/or performs the token exchange.\n */\nconst handleAuthorize = async (): Promise<void> => {\n if (loader.isLoading) {\n return\n }\n\n loader.start()\n const controller = new AbortController()\n deviceController = controller\n\n const [error, tokens] = await authorizeOauth2(\n flows,\n type,\n selectedScopes.value,\n server,\n proxyUrl,\n getEnvironmentVariables(environment),\n options.customFetch,\n options.captureOAuth2Callback,\n {\n signal: controller.signal,\n onPrompt: (prompt) => {\n devicePrompt.value = prompt\n },\n },\n )\n devicePrompt.value = null\n\n await loader.clear()\n if (controller.signal.aborted) {\n return\n }\n\n if (tokens?.accessToken) {\n handleOauth2SecretsUpdate({\n 'x-scalar-secret-token': tokens.accessToken,\n ...(tokens.refreshToken\n ? { 'x-scalar-secret-refresh-token': tokens.refreshToken }\n : {}),\n })\n } else {\n console.error(error)\n toast(\n error?.message ?? translate('apiClient.oauth2.failedToauthorize'),\n 'error',\n )\n }\n}\n\n/** Refreshing requires a token issued by the provider, not just a compatible flow. */\nconst canRefreshToken = computed<boolean>(\n (): boolean =>\n type !== 'implicit' && Boolean(flow.value['x-scalar-secret-refresh-token']),\n)\n\n/**\n * Refresh URL placeholder, shows tokenUrl as hint if refreshUrl is not specified.\n * This helps users understand that tokenUrl will be used as fallback.\n */\nconst refreshUrlPlaceholder = computed(() => {\n if ('tokenUrl' in flow.value && flow.value.tokenUrl) {\n return flow.value.tokenUrl\n }\n return 'https://galaxy.scalar.com/oauth/refresh'\n})\n\n/**\n * Uses the stored refresh token to obtain a new access token\n * via grant_type=refresh_token.\n */\nconst handleRefresh = async (): Promise<void> => {\n // The explicit flow check narrows the type for refreshOauth2Token; the computed boolean cannot.\n if (loader.isLoading || type === 'implicit' || !canRefreshToken.value) {\n return\n }\n\n loader.start()\n\n const [error, tokens] = await refreshOauth2Token(\n flows,\n type,\n proxyUrl,\n server,\n getEnvironmentVariables(environment),\n options.customFetch,\n )\n\n await loader.clear()\n\n if (tokens?.accessToken) {\n handleOauth2SecretsUpdate({\n 'x-scalar-secret-token': tokens.accessToken,\n ...(tokens.refreshToken\n ? { 'x-scalar-secret-refresh-token': tokens.refreshToken }\n : {}),\n })\n } else {\n console.error(error)\n toast(\n error?.message ?? translate('apiClient.oauth2.failedToRefreshToken'),\n 'error',\n )\n }\n}\n\n/** Updates the secret location */\nconst handleSecretLocationUpdate = (value: string): void => {\n if (value !== 'body' && value !== 'header') return\n const credentialsLocation = value\n\n if (scheme.type !== 'openIdConnect') {\n handleOauth2Update({\n 'x-scalar-credentials-location': credentialsLocation,\n })\n }\n\n handleOauth2SecretsUpdate({\n 'x-scalar-credentials-location': credentialsLocation,\n })\n}\n</script>\n\n<template>\n <!-- Access Token Display: Shows when user is already authorized -->\n <template v-if=\"flow['x-scalar-secret-token']\">\n <DataTableRow>\n <RequestAuthDataTableInput\n :canReset=\"\n canReset('x-scalar-secret-token', flow['x-scalar-secret-token'])\n \"\n class=\"border-r-transparent\"\n :environment\n :modelValue=\"flow['x-scalar-secret-token']\"\n placeholder=\"QUxMIFlPVVIgQkFTRSBBUkUgQkVMT05HIFRPIFVT\"\n type=\"password\"\n @reset=\"handleResetSecret('x-scalar-secret-token')\"\n @update:modelValue=\"\n (v) => handleOauth2SecretsUpdate({ 'x-scalar-secret-token': v })\n \">\n {{ translate('apiClient.oauth2.accessToken') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <DataTableRow v-if=\"canRefreshToken\">\n <RequestAuthDataTableInput\n class=\"border-r-transparent\"\n :environment\n :modelValue=\"flow.refreshUrl ?? ''\"\n :placeholder=\"refreshUrlPlaceholder\"\n @update:modelValue=\"(v) => handleOauth2Update({ refreshUrl: v })\">\n {{ translate('apiClient.oauth2.refreshUrl') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <DataTableRow\n v-if=\"!hideActions\"\n class=\"min-w-full\">\n <div class=\"flex h-8 items-center justify-end gap-2 border-t\">\n <ScalarButton\n v-if=\"canRefreshToken\"\n class=\"p-0 px-2 py-0.5\"\n :loader\n size=\"sm\"\n variant=\"outlined\"\n @click=\"handleRefresh\">\n {{ translate('apiClient.oauth2.refresh') }}\n </ScalarButton>\n <ScalarButton\n class=\"mr-1 p-0 px-2 py-0.5\"\n :disabled=\"loader.isLoading\"\n size=\"sm\"\n variant=\"outlined\"\n @click=\"handleClearAccessTokens\">\n {{ translate('apiClient.oauth2.clearTokens') }}\n </ScalarButton>\n </div>\n </DataTableRow>\n </template>\n\n <!-- Authorization Form: Shows when user needs to authorize -->\n <template v-else>\n <DataTableRow v-if=\"'deviceAuthorizationUrl' in flow\">\n <RequestAuthDataTableInput\n :environment\n :modelValue=\"flow.deviceAuthorizationUrl\"\n @update:modelValue=\"\n (v) => handleOauth2Update({ deviceAuthorizationUrl: v })\n \">\n {{ translate('apiClient.oauth2.deviceAuthorizationUrl') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n <DataTableRow v-if=\"devicePrompt\">\n <div class=\"w-full p-2\">\n <div\n class=\"bg-b-2 flex flex-col gap-3 rounded-lg border p-3 text-sm\"\n role=\"status\">\n <p class=\"text-c-2 text-xs leading-normal\">\n {{ translate('apiClient.oauth2.deviceVerificationPrompt') }}\n </p>\n <strong\n class=\"bg-b-1 font-code w-fit max-w-full rounded border px-3 py-2 text-base font-medium tracking-widest break-all select-all\">\n {{ devicePrompt.userCode }}\n </strong>\n <a\n class=\"text-c-accent w-fit max-w-full text-xs break-all underline underline-offset-2\"\n :href=\"\n devicePrompt.verificationUriComplete ||\n devicePrompt.verificationUri\n \"\n rel=\"noopener noreferrer\"\n target=\"_blank\">\n {{ devicePrompt.verificationUri }}\n </a>\n <div class=\"flex items-center justify-between gap-3\">\n <p class=\"text-c-2 text-xs\">\n {{ translate('apiClient.oauth2.waitingForAuthorization') }}\n </p>\n <ScalarButton\n size=\"xs\"\n variant=\"outlined\"\n @click=\"cancelDeviceAuthorization\">\n {{ translate('apiClient.oauth2.cancelDeviceAuthorization') }}\n </ScalarButton>\n </div>\n </div>\n </div>\n </DataTableRow>\n <DataTableRow>\n <RequestAuthDataTableInput\n v-if=\"'authorizationUrl' in flow\"\n :canReset=\"\n canReset(\n 'x-scalar-secret-auth-url',\n flow['x-scalar-secret-auth-url'] ?? '',\n )\n \"\n containerClass=\"border-r-0\"\n :environment\n :modelValue=\"flow['x-scalar-secret-auth-url'] ?? ''\"\n placeholder=\"https://galaxy.scalar.com/authorize\"\n @reset=\"handleResetSecret('x-scalar-secret-auth-url')\"\n @update:modelValue=\"\n (v) => {\n handleOauth2SecretsUpdate({ 'x-scalar-secret-auth-url': v })\n if (v) handleOauth2Update({ authorizationUrl: v })\n }\n \">\n {{ translate('apiClient.oauth2.authUrl') }}\n </RequestAuthDataTableInput>\n\n <RequestAuthDataTableInput\n v-if=\"'tokenUrl' in flow\"\n :canReset=\"\n canReset(\n 'x-scalar-secret-token-url',\n flow['x-scalar-secret-token-url'] ?? '',\n )\n \"\n :environment\n :modelValue=\"flow['x-scalar-secret-token-url'] ?? ''\"\n placeholder=\"https://galaxy.scalar.com/token\"\n @reset=\"handleResetSecret('x-scalar-secret-token-url')\"\n @update:modelValue=\"\n (v) => {\n handleOauth2SecretsUpdate({ 'x-scalar-secret-token-url': v })\n if (v) handleOauth2Update({ tokenUrl: v })\n }\n \">\n {{ translate('apiClient.oauth2.tokenUrl') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <DataTableRow v-if=\"'x-scalar-secret-redirect-uri' in flow\">\n <RequestAuthDataTableInput\n :canReset=\"\n canReset(\n 'x-scalar-secret-redirect-uri',\n flow['x-scalar-secret-redirect-uri'],\n )\n \"\n :environment\n :modelValue=\"flow['x-scalar-secret-redirect-uri']\"\n :placeholder=\"\n options.captureOAuth2Callback\n ? `${resolveDefaultOAuth2RedirectUri(options) || 'http://127.0.0.1'} (handled automatically)`\n : translate('apiClient.oauth2.optionalRedirectUrl')\n \"\n @reset=\"handleResetSecret('x-scalar-secret-redirect-uri')\"\n @update:modelValue=\"\n (v) => {\n hasHandledRedirectPrefill = true\n handleOauth2SecretsUpdate({ 'x-scalar-secret-redirect-uri': v })\n }\n \">\n {{ translate('apiClient.oauth2.redirectUrl') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <template\n v-if=\"\n 'x-scalar-secret-username' in flow && 'x-scalar-secret-password' in flow\n \">\n <DataTableRow>\n <RequestAuthDataTableInput\n :canReset=\"\n canReset(\n 'x-scalar-secret-username',\n flow['x-scalar-secret-username'],\n )\n \"\n class=\"text-c-2\"\n :environment\n :modelValue=\"flow['x-scalar-secret-username']\"\n placeholder=\"janedoe\"\n @reset=\"handleResetSecret('x-scalar-secret-username')\"\n @update:modelValue=\"\n (v) => handleOauth2SecretsUpdate({ 'x-scalar-secret-username': v })\n \">\n {{ translate('apiClient.oauth2.username') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <DataTableRow>\n <RequestAuthDataTableInput\n :canReset=\"\n canReset(\n 'x-scalar-secret-password',\n flow['x-scalar-secret-password'],\n )\n \"\n :environment\n :modelValue=\"flow['x-scalar-secret-password']\"\n placeholder=\"********\"\n type=\"password\"\n @reset=\"handleResetSecret('x-scalar-secret-password')\"\n @update:modelValue=\"\n (v) => handleOauth2SecretsUpdate({ 'x-scalar-secret-password': v })\n \">\n {{ translate('apiClient.oauth2.password') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n </template>\n\n <DataTableRow>\n <RequestAuthDataTableInput\n :canReset=\"\n canReset(\n 'x-scalar-secret-client-id',\n flow['x-scalar-secret-client-id'],\n )\n \"\n :environment\n :modelValue=\"flow['x-scalar-secret-client-id']\"\n placeholder=\"12345\"\n @reset=\"handleResetSecret('x-scalar-secret-client-id')\"\n @update:modelValue=\"\n (v) => handleOauth2SecretsUpdate({ 'x-scalar-secret-client-id': v })\n \">\n {{ translate('apiClient.oauth2.clientID') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <DataTableRow v-if=\"showClientSecret\">\n <RequestAuthDataTableInput\n :canReset=\"canReset('x-scalar-secret-client-secret', clientSecretValue)\"\n :environment\n :modelValue=\"clientSecretValue\"\n placeholder=\"XYZ123\"\n type=\"password\"\n @reset=\"handleResetSecret('x-scalar-secret-client-secret')\"\n @update:modelValue=\"\n (v) =>\n handleOauth2SecretsUpdate({ 'x-scalar-secret-client-secret': v })\n \">\n {{ translate('apiClient.oauth2.clientSecret') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <DataTableRow v-if=\"'x-usePkce' in flow\">\n <RequestAuthDataTableInput\n :enum=\"pkceOptions\"\n :environment\n :modelValue=\"flow['x-usePkce']\"\n readOnly\n @update:modelValue=\"handlePkceUpdate\">\n {{ translate('apiClient.oauth2.usePKCE') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <!-- Credentials Location -->\n <DataTableRow v-if=\"type !== 'implicit'\">\n <RequestAuthDataTableInput\n :enum=\"['header', 'body']\"\n :environment\n :modelValue=\"\n (flow as NonImplicitFlow)['x-scalar-credentials-location'] || 'header'\n \"\n placeholder=\"header\"\n readOnly\n @update:modelValue=\"(v) => handleSecretLocationUpdate(v)\">\n {{ translate('apiClient.oauth2.credentialsLocation') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <!-- Scopes -->\n <DataTableRow>\n <OAuthScopesInput\n :flow\n :flowType=\"type\"\n :selectedScopes\n @delete:scope=\"(v) => emits('delete:scope', v)\"\n @update:selectedScopes=\"(v) => emits('update:selectedScopes', v)\"\n @upsert:scope=\"(v) => emits('upsert:scope', v)\" />\n </DataTableRow>\n\n <DataTableRow\n v-if=\"!hideActions\"\n class=\"min-w-full\">\n <div class=\"flex h-8 w-full items-center justify-end border-t\">\n <!-- Allow clearing the oauth section and going back to discovery -->\n <ScalarButton\n v-if=\"scheme.type === 'openIdConnect'\"\n class=\"mr-1 p-0 px-2 py-0.5\"\n :disabled=\"loader.isLoading\"\n size=\"sm\"\n variant=\"outlined\"\n @click=\"clearOauth2Secrets\">\n {{ translate('apiClient.oauth2.resetDiscovery') }}\n </ScalarButton>\n\n <ScalarButton\n class=\"mr-0.75 p-0 px-2 py-0.5\"\n :loader\n size=\"sm\"\n variant=\"outlined\"\n @click=\"handleAuthorize\">\n {{ translate('apiClient.oauth2.authorize') }}\n </ScalarButton>\n </div>\n </DataTableRow>\n </template>\n</template>\n"],"mappings":""}
@@ -111,11 +111,9 @@ var OAuth2_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCom
111
111
  };
112
112
  /**
113
113
  * Reset needs a default to restore, otherwise it would only clear the field like the clear
114
- * action does. A cleared access token is the exception: the token view stays open while it is
115
- * cleared, and Reset is the only way back to the Authorize form.
114
+ * action does.
116
115
  */
117
116
  const canReset = (field, value) => {
118
- if (field === "x-scalar-secret-token" && isSecretFieldCleared(flow.value, field)) return true;
119
117
  const fallback = field === "x-scalar-secret-redirect-uri" && !__props.options.captureOAuth2Callback ? resolveDefaultOAuth2RedirectUri(__props.options) : "";
120
118
  return canResetSecretField(flow.value, field, value, fallback);
121
119
  };
@@ -224,7 +222,7 @@ var OAuth2_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCom
224
222
  handleOauth2SecretsUpdate({ "x-scalar-credentials-location": credentialsLocation });
225
223
  };
226
224
  return (_ctx, _cache) => {
227
- return Boolean(flow.value["x-scalar-secret-token"]) || unref(isSecretFieldCleared)(flow.value, "x-scalar-secret-token") ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
225
+ return flow.value["x-scalar-secret-token"] ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
228
226
  createVNode(unref(DataTableRow_default), null, {
229
227
  default: withCtx(() => [createVNode(RequestAuthDataTableInput_default, {
230
228
  canReset: canReset("x-scalar-secret-token", flow.value["x-scalar-secret-token"]),
@@ -1 +1 @@
1
- {"version":3,"file":"OAuth2.vue.script.js","names":[],"sources":["../../../../../src/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue"],"sourcesContent":["<script lang=\"ts\">\n/** Any config options required for the OAuth2 flow */\nexport type OAuth2Options = Pick<\n ApiClientConfiguration,\n 'oauth2RedirectUri'\n> & {\n /** Optional fetch override (IPC-backed on desktop) used for token exchange, refresh, and OIDC discovery */\n customFetch?: typeof fetch\n /** Optional redirect capture (loopback-backed on desktop) for interactive OAuth2 flows */\n captureOAuth2Callback?: CaptureOAuth2Callback\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { ScalarButton } from '@scalar/components/button'\nimport { useLoadingState } from '@scalar/components/loading'\nimport type { ApiClientConfiguration } from '@scalar/types/api-reference'\nimport { pkceOptions } from '@scalar/types/entities'\nimport { useToasts } from '@scalar/use-toasts'\nimport type { SecretsOAuthFlows } from '@scalar/workspace-store/entities/auth'\nimport type {\n ApiReferenceEvents,\n WorkspaceEventBus,\n} from '@scalar/workspace-store/events'\nimport {\n canResetSecretField,\n isSecretFieldCleared,\n type AuthSecretField,\n} from '@scalar/workspace-store/helpers/auth-secret-fields'\nimport {\n getEnvironmentVariables,\n type OAuthFlowAuthorizationCodeSecret,\n type OAuthFlowClientCredentialsSecret,\n type OAuthFlowPasswordSecret,\n type OAuthFlowsObjectSecret,\n type SecuritySchemeObjectSecret,\n} from '@scalar/workspace-store/request-example'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport type { XScalarCredentialsLocation } from '@scalar/workspace-store/schemas/extensions/security/x-scalar-credentials-location'\nimport type {\n OAuthFlow,\n ServerObject,\n} from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document'\nimport { computed, onBeforeUnmount, ref, watch } from 'vue'\n\nimport OAuthScopesInput from '@/v2/blocks/scalar-auth-selector-block/components/OAuthScopesInput.vue'\nimport {\n authorizeOauth2,\n refreshOauth2Token,\n type CaptureOAuth2Callback,\n} from '@/v2/blocks/scalar-auth-selector-block/helpers/oauth'\nimport { resolveDefaultOAuth2RedirectUri } from '@/v2/blocks/scalar-auth-selector-block/helpers/resolve-default-oauth2-redirect-url'\nimport { DataTableRow } from '@/v2/components/data-table'\nimport { useLocalization } from '@/v2/features/localization'\n\nimport type { DeviceAuthorizationPrompt } from '../helpers/oauth-device-authorization'\nimport RequestAuthDataTableInput from './RequestAuthDataTableInput.vue'\n\nconst {\n environment,\n flows,\n type,\n scheme,\n selectedScopes: selectedScopesProp,\n server,\n proxyUrl,\n eventBus,\n name,\n options = {},\n} = defineProps<{\n /** Current environment configuration */\n environment: XScalarEnvironment\n /** OAuth flows */\n flows: OAuthFlowsObjectSecret\n /** Type of the OAuth flow */\n type: keyof OAuthFlowsObjectSecret\n /** Selected scopes */\n selectedScopes: string[]\n /** Security scheme */\n scheme: SecuritySchemeObjectSecret\n /** Current server configuration */\n server: ServerObject | null\n /** Proxy URL */\n proxyUrl: string\n /** Name of the security scheme */\n name: string\n /** Event bus for authentication updates */\n eventBus: WorkspaceEventBus\n /** Any config options required for the OAuth2 flow */\n options?: OAuth2Options\n /**\n * Hides the Authorize / Refresh / Clear actions. Used when the form is embedded as a\n * configuration-only view (e.g. behind a gear icon), so the host component owns the\n * authorize action and the tokens are routed to the scheme it chooses.\n */\n hideActions?: boolean\n}>()\n\nconst emits = defineEmits<{\n (\n e: 'update:selectedScopes',\n payload: { scopes?: string[]; scope?: string; selected?: boolean },\n ): void\n (\n e: 'upsert:scope',\n payload: Omit<ApiReferenceEvents['auth:upsert:scopes'], 'name'>,\n ): void\n (\n e: 'delete:scope',\n payload: Omit<ApiReferenceEvents['auth:delete:scopes'], 'name'>,\n ): void\n}>()\n\nconst devicePrompt = ref<DeviceAuthorizationPrompt | null>(null)\nlet deviceController: AbortController | undefined\nconst cancelDeviceAuthorization = (): void => {\n deviceController?.abort()\n devicePrompt.value = null\n}\nonBeforeUnmount(cancelDeviceAuthorization)\nwatch(() => [type, name, flows], cancelDeviceAuthorization)\n\nconst { translate } = useLocalization()\n\nconst loader = useLoadingState()\nconst { toast } = useToasts()\n\n/** The current OAuth flow based on the selected type */\nconst flow = computed(() => flows[type]!)\ntype NonImplicitFlow =\n | OAuthFlowPasswordSecret\n | OAuthFlowClientCredentialsSecret\n | OAuthFlowAuthorizationCodeSecret\n\n/** We filter selected scopes to only include scopes that are defined on this flow (own keys only). */\nconst selectedScopes = computed(() => {\n const definedScopes = flow.value.scopes\n if (!definedScopes) {\n return []\n }\n return selectedScopesProp.filter((scope) =>\n Object.hasOwn(definedScopes, scope),\n )\n})\n\n/**\n * Show the client secret whenever the flow supports one. PKCE and a client\n * secret are independent, so confidential clients can use both together\n * (see RFC 9700 Section 2.1.1).\n */\nconst showClientSecret = computed(\n () => 'x-scalar-secret-client-secret' in flow.value,\n)\n\nconst clientSecretValue = computed((): string => {\n const f = flow.value as { 'x-scalar-secret-client-secret'?: string }\n return f['x-scalar-secret-client-secret'] ?? ''\n})\n\n/** Updates the security scheme base */\nconst handleOauth2Update = (\n payload: Partial<OAuthFlow & XScalarCredentialsLocation> & {\n deviceAuthorizationUrl?: string\n },\n): void => {\n // OpenIdConnect uses the secrets update for all\n if (scheme.type === 'openIdConnect') {\n return handleOauth2SecretsUpdate(payload)\n }\n\n // Only OAuth2 schemes carry flows on the document; this component is never\n // rendered for the other scheme types.\n if (scheme.type !== 'oauth2') {\n return\n }\n\n eventBus.emit('auth:update:security-scheme', {\n payload: {\n type: scheme.type,\n flows: {\n [type]: payload,\n },\n },\n name,\n })\n}\n\n/** Updates the flow secrets */\nconst handleOauth2SecretsUpdate = (\n payload: Omit<Partial<SecretsOAuthFlows[keyof SecretsOAuthFlows]>, 'type'>,\n): void => {\n // This component only renders for oauth2/openIdConnect. Other scheme types (e.g. mutualTLS)\n // carry no flow secrets, so there is nothing to persist and no matching secrets payload type.\n if (scheme.type !== 'oauth2' && scheme.type !== 'openIdConnect') {\n return\n }\n\n eventBus.emit('auth:update:security-scheme-secrets', {\n payload: {\n type: scheme.type,\n [type]: payload,\n },\n name,\n })\n}\n\n/** Reset only this field; redirect URI may need its browser default prefilled again. */\nconst handleResetSecret = (field: AuthSecretField): void => {\n if (field === 'x-scalar-secret-redirect-uri') {\n hasHandledRedirectPrefill.value = false\n }\n eventBus.emit('auth:reset:security-scheme-secret', {\n name,\n flow: type,\n field,\n })\n}\n\n/**\n * Reset needs a default to restore, otherwise it would only clear the field like the clear\n * action does. A cleared access token is the exception: the token view stays open while it is\n * cleared, and Reset is the only way back to the Authorize form.\n */\nconst canReset = (\n field: AuthSecretField,\n value: string | undefined,\n): boolean => {\n if (\n field === 'x-scalar-secret-token' &&\n isSecretFieldCleared(flow.value, field)\n ) {\n return true\n }\n // Without a stored default, resetting the redirect URI re-runs the browser prefill below,\n // unless the desktop loopback capture computes it at authorize time instead.\n const fallback =\n field === 'x-scalar-secret-redirect-uri' && !options.captureOAuth2Callback\n ? resolveDefaultOAuth2RedirectUri(options)\n : ''\n return canResetSecretField(flow.value, field, value, fallback)\n}\n\n/** Fixed-choice fields must never write an empty string into the document. */\nconst handlePkceUpdate = (value: string): void => {\n if (value === 'SHA-256' || value === 'plain' || value === 'no') {\n handleOauth2Update({ 'x-usePkce': value })\n }\n}\n\n/** Clears the flow secrets */\nconst clearOauth2Secrets = (): void => {\n if (loader.isLoading) {\n return\n }\n eventBus.emit('auth:clear:security-scheme-secrets', {\n name,\n })\n}\n\n/** Clears stored access and refresh tokens (authorized state) */\nconst handleClearAccessTokens = (): void => {\n if (loader.isLoading) {\n return\n }\n handleOauth2SecretsUpdate({\n 'x-scalar-secret-token': '',\n 'x-scalar-secret-refresh-token': '',\n })\n}\n\n/** Track redirect URI prefill per flow instance to support document switching */\nconst prefilledFlowIdentity = ref<string | null>(null)\nconst hasHandledRedirectPrefill = ref(false)\n\nconst resolveFlowIdentity = (\n currentFlow: OAuthFlowsObjectSecret[keyof OAuthFlowsObjectSecret] | undefined,\n): string =>\n JSON.stringify({\n type,\n authorizationUrl:\n currentFlow && 'authorizationUrl' in currentFlow\n ? currentFlow.authorizationUrl\n : '',\n tokenUrl:\n currentFlow && 'tokenUrl' in currentFlow ? currentFlow.tokenUrl : '',\n refreshUrl: currentFlow?.refreshUrl ?? '',\n scopes: Object.keys(currentFlow?.scopes ?? {}),\n })\n\n/** Default the redirect-uri to the current origin if we have access to window */\nwatch(\n () => flow.value,\n (currentFlow) => {\n if (!currentFlow || !('x-scalar-secret-redirect-uri' in currentFlow)) {\n return\n }\n\n const flowIdentity = resolveFlowIdentity(currentFlow)\n if (prefilledFlowIdentity.value !== flowIdentity) {\n prefilledFlowIdentity.value = flowIdentity\n hasHandledRedirectPrefill.value = false\n }\n\n if (hasHandledRedirectPrefill.value) {\n return\n }\n\n const newRedirectUri = (currentFlow as OAuthFlowAuthorizationCodeSecret)[\n 'x-scalar-secret-redirect-uri'\n ]\n const defaultRedirectUri = resolveDefaultOAuth2RedirectUri(options)\n\n hasHandledRedirectPrefill.value = true\n\n // The desktop loopback path computes the redirect URI at authorize time (an\n // ephemeral 127.0.0.1 port), so persisting a default into the document would\n // only bake in a stale, unused value. Leave it empty and show a hint instead.\n if (\n isSecretFieldCleared(currentFlow, 'x-scalar-secret-redirect-uri') ||\n newRedirectUri ||\n !defaultRedirectUri ||\n options.captureOAuth2Callback\n ) {\n return\n }\n\n handleOauth2SecretsUpdate({\n 'x-scalar-secret-redirect-uri': defaultRedirectUri,\n })\n },\n { immediate: true },\n)\n\n/**\n * Authorizes the user using the specified OAuth flow.\n * Opens the appropriate OAuth dialog and/or performs the token exchange.\n */\nconst handleAuthorize = async (): Promise<void> => {\n if (loader.isLoading) {\n return\n }\n\n loader.start()\n const controller = new AbortController()\n deviceController = controller\n\n const [error, tokens] = await authorizeOauth2(\n flows,\n type,\n selectedScopes.value,\n server,\n proxyUrl,\n getEnvironmentVariables(environment),\n options.customFetch,\n options.captureOAuth2Callback,\n {\n signal: controller.signal,\n onPrompt: (prompt) => {\n devicePrompt.value = prompt\n },\n },\n )\n devicePrompt.value = null\n\n await loader.clear()\n if (controller.signal.aborted) {\n return\n }\n\n if (tokens?.accessToken) {\n handleOauth2SecretsUpdate({\n 'x-scalar-secret-token': tokens.accessToken,\n ...(tokens.refreshToken\n ? { 'x-scalar-secret-refresh-token': tokens.refreshToken }\n : {}),\n })\n } else {\n console.error(error)\n toast(\n error?.message ?? translate('apiClient.oauth2.failedToauthorize'),\n 'error',\n )\n }\n}\n\n/** Refreshing requires a token issued by the provider, not just a compatible flow. */\nconst canRefreshToken = computed<boolean>(\n (): boolean =>\n type !== 'implicit' && Boolean(flow.value['x-scalar-secret-refresh-token']),\n)\n\n/**\n * Refresh URL placeholder, shows tokenUrl as hint if refreshUrl is not specified.\n * This helps users understand that tokenUrl will be used as fallback.\n */\nconst refreshUrlPlaceholder = computed(() => {\n if ('tokenUrl' in flow.value && flow.value.tokenUrl) {\n return flow.value.tokenUrl\n }\n return 'https://galaxy.scalar.com/oauth/refresh'\n})\n\n/**\n * Uses the stored refresh token to obtain a new access token\n * via grant_type=refresh_token.\n */\nconst handleRefresh = async (): Promise<void> => {\n // The explicit flow check narrows the type for refreshOauth2Token; the computed boolean cannot.\n if (loader.isLoading || type === 'implicit' || !canRefreshToken.value) {\n return\n }\n\n loader.start()\n\n const [error, tokens] = await refreshOauth2Token(\n flows,\n type,\n proxyUrl,\n server,\n getEnvironmentVariables(environment),\n options.customFetch,\n )\n\n await loader.clear()\n\n if (tokens?.accessToken) {\n handleOauth2SecretsUpdate({\n 'x-scalar-secret-token': tokens.accessToken,\n ...(tokens.refreshToken\n ? { 'x-scalar-secret-refresh-token': tokens.refreshToken }\n : {}),\n })\n } else {\n console.error(error)\n toast(\n error?.message ?? translate('apiClient.oauth2.failedToRefreshToken'),\n 'error',\n )\n }\n}\n\n/** Updates the secret location */\nconst handleSecretLocationUpdate = (value: string): void => {\n if (value !== 'body' && value !== 'header') return\n const credentialsLocation = value\n\n if (scheme.type !== 'openIdConnect') {\n handleOauth2Update({\n 'x-scalar-credentials-location': credentialsLocation,\n })\n }\n\n handleOauth2SecretsUpdate({\n 'x-scalar-credentials-location': credentialsLocation,\n })\n}\n</script>\n\n<template>\n <!-- Access Token Display: Shows when user is already authorized -->\n <template\n v-if=\"\n Boolean(flow['x-scalar-secret-token']) ||\n isSecretFieldCleared(flow, 'x-scalar-secret-token')\n \">\n <DataTableRow>\n <RequestAuthDataTableInput\n :canReset=\"\n canReset('x-scalar-secret-token', flow['x-scalar-secret-token'])\n \"\n class=\"border-r-transparent\"\n :environment\n :modelValue=\"flow['x-scalar-secret-token']\"\n placeholder=\"QUxMIFlPVVIgQkFTRSBBUkUgQkVMT05HIFRPIFVT\"\n type=\"password\"\n @reset=\"handleResetSecret('x-scalar-secret-token')\"\n @update:modelValue=\"\n (v) => handleOauth2SecretsUpdate({ 'x-scalar-secret-token': v })\n \">\n {{ translate('apiClient.oauth2.accessToken') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <DataTableRow v-if=\"canRefreshToken\">\n <RequestAuthDataTableInput\n class=\"border-r-transparent\"\n :environment\n :modelValue=\"flow.refreshUrl ?? ''\"\n :placeholder=\"refreshUrlPlaceholder\"\n @update:modelValue=\"(v) => handleOauth2Update({ refreshUrl: v })\">\n {{ translate('apiClient.oauth2.refreshUrl') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <DataTableRow\n v-if=\"!hideActions\"\n class=\"min-w-full\">\n <div class=\"flex h-8 items-center justify-end gap-2 border-t\">\n <ScalarButton\n v-if=\"canRefreshToken\"\n class=\"p-0 px-2 py-0.5\"\n :loader\n size=\"sm\"\n variant=\"outlined\"\n @click=\"handleRefresh\">\n {{ translate('apiClient.oauth2.refresh') }}\n </ScalarButton>\n <ScalarButton\n class=\"mr-1 p-0 px-2 py-0.5\"\n :disabled=\"loader.isLoading\"\n size=\"sm\"\n variant=\"outlined\"\n @click=\"handleClearAccessTokens\">\n {{ translate('apiClient.oauth2.clearTokens') }}\n </ScalarButton>\n </div>\n </DataTableRow>\n </template>\n\n <!-- Authorization Form: Shows when user needs to authorize -->\n <template v-else>\n <DataTableRow v-if=\"'deviceAuthorizationUrl' in flow\">\n <RequestAuthDataTableInput\n :environment\n :modelValue=\"flow.deviceAuthorizationUrl\"\n @update:modelValue=\"\n (v) => handleOauth2Update({ deviceAuthorizationUrl: v })\n \">\n {{ translate('apiClient.oauth2.deviceAuthorizationUrl') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n <DataTableRow v-if=\"devicePrompt\">\n <div class=\"w-full p-2\">\n <div\n class=\"bg-b-2 flex flex-col gap-3 rounded-lg border p-3 text-sm\"\n role=\"status\">\n <p class=\"text-c-2 text-xs leading-normal\">\n {{ translate('apiClient.oauth2.deviceVerificationPrompt') }}\n </p>\n <strong\n class=\"bg-b-1 font-code w-fit max-w-full rounded border px-3 py-2 text-base font-medium tracking-widest break-all select-all\">\n {{ devicePrompt.userCode }}\n </strong>\n <a\n class=\"text-c-accent w-fit max-w-full text-xs break-all underline underline-offset-2\"\n :href=\"\n devicePrompt.verificationUriComplete ||\n devicePrompt.verificationUri\n \"\n rel=\"noopener noreferrer\"\n target=\"_blank\">\n {{ devicePrompt.verificationUri }}\n </a>\n <div class=\"flex items-center justify-between gap-3\">\n <p class=\"text-c-2 text-xs\">\n {{ translate('apiClient.oauth2.waitingForAuthorization') }}\n </p>\n <ScalarButton\n size=\"xs\"\n variant=\"outlined\"\n @click=\"cancelDeviceAuthorization\">\n {{ translate('apiClient.oauth2.cancelDeviceAuthorization') }}\n </ScalarButton>\n </div>\n </div>\n </div>\n </DataTableRow>\n <DataTableRow>\n <RequestAuthDataTableInput\n v-if=\"'authorizationUrl' in flow\"\n :canReset=\"\n canReset(\n 'x-scalar-secret-auth-url',\n flow['x-scalar-secret-auth-url'] ?? '',\n )\n \"\n containerClass=\"border-r-0\"\n :environment\n :modelValue=\"flow['x-scalar-secret-auth-url'] ?? ''\"\n placeholder=\"https://galaxy.scalar.com/authorize\"\n @reset=\"handleResetSecret('x-scalar-secret-auth-url')\"\n @update:modelValue=\"\n (v) => {\n handleOauth2SecretsUpdate({ 'x-scalar-secret-auth-url': v })\n if (v) handleOauth2Update({ authorizationUrl: v })\n }\n \">\n {{ translate('apiClient.oauth2.authUrl') }}\n </RequestAuthDataTableInput>\n\n <RequestAuthDataTableInput\n v-if=\"'tokenUrl' in flow\"\n :canReset=\"\n canReset(\n 'x-scalar-secret-token-url',\n flow['x-scalar-secret-token-url'] ?? '',\n )\n \"\n :environment\n :modelValue=\"flow['x-scalar-secret-token-url'] ?? ''\"\n placeholder=\"https://galaxy.scalar.com/token\"\n @reset=\"handleResetSecret('x-scalar-secret-token-url')\"\n @update:modelValue=\"\n (v) => {\n handleOauth2SecretsUpdate({ 'x-scalar-secret-token-url': v })\n if (v) handleOauth2Update({ tokenUrl: v })\n }\n \">\n {{ translate('apiClient.oauth2.tokenUrl') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <DataTableRow v-if=\"'x-scalar-secret-redirect-uri' in flow\">\n <RequestAuthDataTableInput\n :canReset=\"\n canReset(\n 'x-scalar-secret-redirect-uri',\n flow['x-scalar-secret-redirect-uri'],\n )\n \"\n :environment\n :modelValue=\"flow['x-scalar-secret-redirect-uri']\"\n :placeholder=\"\n options.captureOAuth2Callback\n ? `${resolveDefaultOAuth2RedirectUri(options) || 'http://127.0.0.1'} (handled automatically)`\n : translate('apiClient.oauth2.optionalRedirectUrl')\n \"\n @reset=\"handleResetSecret('x-scalar-secret-redirect-uri')\"\n @update:modelValue=\"\n (v) => {\n hasHandledRedirectPrefill = true\n handleOauth2SecretsUpdate({ 'x-scalar-secret-redirect-uri': v })\n }\n \">\n {{ translate('apiClient.oauth2.redirectUrl') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <template\n v-if=\"\n 'x-scalar-secret-username' in flow && 'x-scalar-secret-password' in flow\n \">\n <DataTableRow>\n <RequestAuthDataTableInput\n :canReset=\"\n canReset(\n 'x-scalar-secret-username',\n flow['x-scalar-secret-username'],\n )\n \"\n class=\"text-c-2\"\n :environment\n :modelValue=\"flow['x-scalar-secret-username']\"\n placeholder=\"janedoe\"\n @reset=\"handleResetSecret('x-scalar-secret-username')\"\n @update:modelValue=\"\n (v) => handleOauth2SecretsUpdate({ 'x-scalar-secret-username': v })\n \">\n {{ translate('apiClient.oauth2.username') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <DataTableRow>\n <RequestAuthDataTableInput\n :canReset=\"\n canReset(\n 'x-scalar-secret-password',\n flow['x-scalar-secret-password'],\n )\n \"\n :environment\n :modelValue=\"flow['x-scalar-secret-password']\"\n placeholder=\"********\"\n type=\"password\"\n @reset=\"handleResetSecret('x-scalar-secret-password')\"\n @update:modelValue=\"\n (v) => handleOauth2SecretsUpdate({ 'x-scalar-secret-password': v })\n \">\n {{ translate('apiClient.oauth2.password') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n </template>\n\n <DataTableRow>\n <RequestAuthDataTableInput\n :canReset=\"\n canReset(\n 'x-scalar-secret-client-id',\n flow['x-scalar-secret-client-id'],\n )\n \"\n :environment\n :modelValue=\"flow['x-scalar-secret-client-id']\"\n placeholder=\"12345\"\n @reset=\"handleResetSecret('x-scalar-secret-client-id')\"\n @update:modelValue=\"\n (v) => handleOauth2SecretsUpdate({ 'x-scalar-secret-client-id': v })\n \">\n {{ translate('apiClient.oauth2.clientID') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <DataTableRow v-if=\"showClientSecret\">\n <RequestAuthDataTableInput\n :canReset=\"canReset('x-scalar-secret-client-secret', clientSecretValue)\"\n :environment\n :modelValue=\"clientSecretValue\"\n placeholder=\"XYZ123\"\n type=\"password\"\n @reset=\"handleResetSecret('x-scalar-secret-client-secret')\"\n @update:modelValue=\"\n (v) =>\n handleOauth2SecretsUpdate({ 'x-scalar-secret-client-secret': v })\n \">\n {{ translate('apiClient.oauth2.clientSecret') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <DataTableRow v-if=\"'x-usePkce' in flow\">\n <RequestAuthDataTableInput\n :enum=\"pkceOptions\"\n :environment\n :modelValue=\"flow['x-usePkce']\"\n readOnly\n @update:modelValue=\"handlePkceUpdate\">\n {{ translate('apiClient.oauth2.usePKCE') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <!-- Credentials Location -->\n <DataTableRow v-if=\"type !== 'implicit'\">\n <RequestAuthDataTableInput\n :enum=\"['header', 'body']\"\n :environment\n :modelValue=\"\n (flow as NonImplicitFlow)['x-scalar-credentials-location'] || 'header'\n \"\n placeholder=\"header\"\n readOnly\n @update:modelValue=\"(v) => handleSecretLocationUpdate(v)\">\n {{ translate('apiClient.oauth2.credentialsLocation') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <!-- Scopes -->\n <DataTableRow>\n <OAuthScopesInput\n :flow\n :flowType=\"type\"\n :selectedScopes\n @delete:scope=\"(v) => emits('delete:scope', v)\"\n @update:selectedScopes=\"(v) => emits('update:selectedScopes', v)\"\n @upsert:scope=\"(v) => emits('upsert:scope', v)\" />\n </DataTableRow>\n\n <DataTableRow\n v-if=\"!hideActions\"\n class=\"min-w-full\">\n <div class=\"flex h-8 w-full items-center justify-end border-t\">\n <!-- Allow clearing the oauth section and going back to discovery -->\n <ScalarButton\n v-if=\"scheme.type === 'openIdConnect'\"\n class=\"mr-1 p-0 px-2 py-0.5\"\n :disabled=\"loader.isLoading\"\n size=\"sm\"\n variant=\"outlined\"\n @click=\"clearOauth2Secrets\">\n {{ translate('apiClient.oauth2.resetDiscovery') }}\n </ScalarButton>\n\n <ScalarButton\n class=\"mr-0.75 p-0 px-2 py-0.5\"\n :loader\n size=\"sm\"\n variant=\"outlined\"\n @click=\"handleAuthorize\">\n {{ translate('apiClient.oauth2.authorize') }}\n </ScalarButton>\n </div>\n </DataTableRow>\n </template>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"OAuth2.vue.script.js","names":[],"sources":["../../../../../src/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue"],"sourcesContent":["<script lang=\"ts\">\n/** Any config options required for the OAuth2 flow */\nexport type OAuth2Options = Pick<\n ApiClientConfiguration,\n 'oauth2RedirectUri'\n> & {\n /** Optional fetch override (IPC-backed on desktop) used for token exchange, refresh, and OIDC discovery */\n customFetch?: typeof fetch\n /** Optional redirect capture (loopback-backed on desktop) for interactive OAuth2 flows */\n captureOAuth2Callback?: CaptureOAuth2Callback\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { ScalarButton } from '@scalar/components/button'\nimport { useLoadingState } from '@scalar/components/loading'\nimport type { ApiClientConfiguration } from '@scalar/types/api-reference'\nimport { pkceOptions } from '@scalar/types/entities'\nimport { useToasts } from '@scalar/use-toasts'\nimport type { SecretsOAuthFlows } from '@scalar/workspace-store/entities/auth'\nimport type {\n ApiReferenceEvents,\n WorkspaceEventBus,\n} from '@scalar/workspace-store/events'\nimport {\n canResetSecretField,\n isSecretFieldCleared,\n type AuthSecretField,\n} from '@scalar/workspace-store/helpers/auth-secret-fields'\nimport {\n getEnvironmentVariables,\n type OAuthFlowAuthorizationCodeSecret,\n type OAuthFlowClientCredentialsSecret,\n type OAuthFlowPasswordSecret,\n type OAuthFlowsObjectSecret,\n type SecuritySchemeObjectSecret,\n} from '@scalar/workspace-store/request-example'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport type { XScalarCredentialsLocation } from '@scalar/workspace-store/schemas/extensions/security/x-scalar-credentials-location'\nimport type {\n OAuthFlow,\n ServerObject,\n} from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document'\nimport { computed, onBeforeUnmount, ref, watch } from 'vue'\n\nimport OAuthScopesInput from '@/v2/blocks/scalar-auth-selector-block/components/OAuthScopesInput.vue'\nimport {\n authorizeOauth2,\n refreshOauth2Token,\n type CaptureOAuth2Callback,\n} from '@/v2/blocks/scalar-auth-selector-block/helpers/oauth'\nimport { resolveDefaultOAuth2RedirectUri } from '@/v2/blocks/scalar-auth-selector-block/helpers/resolve-default-oauth2-redirect-url'\nimport { DataTableRow } from '@/v2/components/data-table'\nimport { useLocalization } from '@/v2/features/localization'\n\nimport type { DeviceAuthorizationPrompt } from '../helpers/oauth-device-authorization'\nimport RequestAuthDataTableInput from './RequestAuthDataTableInput.vue'\n\nconst {\n environment,\n flows,\n type,\n scheme,\n selectedScopes: selectedScopesProp,\n server,\n proxyUrl,\n eventBus,\n name,\n options = {},\n} = defineProps<{\n /** Current environment configuration */\n environment: XScalarEnvironment\n /** OAuth flows */\n flows: OAuthFlowsObjectSecret\n /** Type of the OAuth flow */\n type: keyof OAuthFlowsObjectSecret\n /** Selected scopes */\n selectedScopes: string[]\n /** Security scheme */\n scheme: SecuritySchemeObjectSecret\n /** Current server configuration */\n server: ServerObject | null\n /** Proxy URL */\n proxyUrl: string\n /** Name of the security scheme */\n name: string\n /** Event bus for authentication updates */\n eventBus: WorkspaceEventBus\n /** Any config options required for the OAuth2 flow */\n options?: OAuth2Options\n /**\n * Hides the Authorize / Refresh / Clear actions. Used when the form is embedded as a\n * configuration-only view (e.g. behind a gear icon), so the host component owns the\n * authorize action and the tokens are routed to the scheme it chooses.\n */\n hideActions?: boolean\n}>()\n\nconst emits = defineEmits<{\n (\n e: 'update:selectedScopes',\n payload: { scopes?: string[]; scope?: string; selected?: boolean },\n ): void\n (\n e: 'upsert:scope',\n payload: Omit<ApiReferenceEvents['auth:upsert:scopes'], 'name'>,\n ): void\n (\n e: 'delete:scope',\n payload: Omit<ApiReferenceEvents['auth:delete:scopes'], 'name'>,\n ): void\n}>()\n\nconst devicePrompt = ref<DeviceAuthorizationPrompt | null>(null)\nlet deviceController: AbortController | undefined\nconst cancelDeviceAuthorization = (): void => {\n deviceController?.abort()\n devicePrompt.value = null\n}\nonBeforeUnmount(cancelDeviceAuthorization)\nwatch(() => [type, name, flows], cancelDeviceAuthorization)\n\nconst { translate } = useLocalization()\n\nconst loader = useLoadingState()\nconst { toast } = useToasts()\n\n/** The current OAuth flow based on the selected type */\nconst flow = computed(() => flows[type]!)\ntype NonImplicitFlow =\n | OAuthFlowPasswordSecret\n | OAuthFlowClientCredentialsSecret\n | OAuthFlowAuthorizationCodeSecret\n\n/** We filter selected scopes to only include scopes that are defined on this flow (own keys only). */\nconst selectedScopes = computed(() => {\n const definedScopes = flow.value.scopes\n if (!definedScopes) {\n return []\n }\n return selectedScopesProp.filter((scope) =>\n Object.hasOwn(definedScopes, scope),\n )\n})\n\n/**\n * Show the client secret whenever the flow supports one. PKCE and a client\n * secret are independent, so confidential clients can use both together\n * (see RFC 9700 Section 2.1.1).\n */\nconst showClientSecret = computed(\n () => 'x-scalar-secret-client-secret' in flow.value,\n)\n\nconst clientSecretValue = computed((): string => {\n const f = flow.value as { 'x-scalar-secret-client-secret'?: string }\n return f['x-scalar-secret-client-secret'] ?? ''\n})\n\n/** Updates the security scheme base */\nconst handleOauth2Update = (\n payload: Partial<OAuthFlow & XScalarCredentialsLocation> & {\n deviceAuthorizationUrl?: string\n },\n): void => {\n // OpenIdConnect uses the secrets update for all\n if (scheme.type === 'openIdConnect') {\n return handleOauth2SecretsUpdate(payload)\n }\n\n // Only OAuth2 schemes carry flows on the document; this component is never\n // rendered for the other scheme types.\n if (scheme.type !== 'oauth2') {\n return\n }\n\n eventBus.emit('auth:update:security-scheme', {\n payload: {\n type: scheme.type,\n flows: {\n [type]: payload,\n },\n },\n name,\n })\n}\n\n/** Updates the flow secrets */\nconst handleOauth2SecretsUpdate = (\n payload: Omit<Partial<SecretsOAuthFlows[keyof SecretsOAuthFlows]>, 'type'>,\n): void => {\n // This component only renders for oauth2/openIdConnect. Other scheme types (e.g. mutualTLS)\n // carry no flow secrets, so there is nothing to persist and no matching secrets payload type.\n if (scheme.type !== 'oauth2' && scheme.type !== 'openIdConnect') {\n return\n }\n\n eventBus.emit('auth:update:security-scheme-secrets', {\n payload: {\n type: scheme.type,\n [type]: payload,\n },\n name,\n })\n}\n\n/** Reset only this field; redirect URI may need its browser default prefilled again. */\nconst handleResetSecret = (field: AuthSecretField): void => {\n if (field === 'x-scalar-secret-redirect-uri') {\n hasHandledRedirectPrefill.value = false\n }\n eventBus.emit('auth:reset:security-scheme-secret', {\n name,\n flow: type,\n field,\n })\n}\n\n/**\n * Reset needs a default to restore, otherwise it would only clear the field like the clear\n * action does.\n */\nconst canReset = (\n field: AuthSecretField,\n value: string | undefined,\n): boolean => {\n // Without a stored default, resetting the redirect URI re-runs the browser prefill below,\n // unless the desktop loopback capture computes it at authorize time instead.\n const fallback =\n field === 'x-scalar-secret-redirect-uri' && !options.captureOAuth2Callback\n ? resolveDefaultOAuth2RedirectUri(options)\n : ''\n return canResetSecretField(flow.value, field, value, fallback)\n}\n\n/** Fixed-choice fields must never write an empty string into the document. */\nconst handlePkceUpdate = (value: string): void => {\n if (value === 'SHA-256' || value === 'plain' || value === 'no') {\n handleOauth2Update({ 'x-usePkce': value })\n }\n}\n\n/** Clears the flow secrets */\nconst clearOauth2Secrets = (): void => {\n if (loader.isLoading) {\n return\n }\n eventBus.emit('auth:clear:security-scheme-secrets', {\n name,\n })\n}\n\n/** Clears stored access and refresh tokens (authorized state) */\nconst handleClearAccessTokens = (): void => {\n if (loader.isLoading) {\n return\n }\n handleOauth2SecretsUpdate({\n 'x-scalar-secret-token': '',\n 'x-scalar-secret-refresh-token': '',\n })\n}\n\n/** Track redirect URI prefill per flow instance to support document switching */\nconst prefilledFlowIdentity = ref<string | null>(null)\nconst hasHandledRedirectPrefill = ref(false)\n\nconst resolveFlowIdentity = (\n currentFlow: OAuthFlowsObjectSecret[keyof OAuthFlowsObjectSecret] | undefined,\n): string =>\n JSON.stringify({\n type,\n authorizationUrl:\n currentFlow && 'authorizationUrl' in currentFlow\n ? currentFlow.authorizationUrl\n : '',\n tokenUrl:\n currentFlow && 'tokenUrl' in currentFlow ? currentFlow.tokenUrl : '',\n refreshUrl: currentFlow?.refreshUrl ?? '',\n scopes: Object.keys(currentFlow?.scopes ?? {}),\n })\n\n/** Default the redirect-uri to the current origin if we have access to window */\nwatch(\n () => flow.value,\n (currentFlow) => {\n if (!currentFlow || !('x-scalar-secret-redirect-uri' in currentFlow)) {\n return\n }\n\n const flowIdentity = resolveFlowIdentity(currentFlow)\n if (prefilledFlowIdentity.value !== flowIdentity) {\n prefilledFlowIdentity.value = flowIdentity\n hasHandledRedirectPrefill.value = false\n }\n\n if (hasHandledRedirectPrefill.value) {\n return\n }\n\n const newRedirectUri = (currentFlow as OAuthFlowAuthorizationCodeSecret)[\n 'x-scalar-secret-redirect-uri'\n ]\n const defaultRedirectUri = resolveDefaultOAuth2RedirectUri(options)\n\n hasHandledRedirectPrefill.value = true\n\n // The desktop loopback path computes the redirect URI at authorize time (an\n // ephemeral 127.0.0.1 port), so persisting a default into the document would\n // only bake in a stale, unused value. Leave it empty and show a hint instead.\n if (\n isSecretFieldCleared(currentFlow, 'x-scalar-secret-redirect-uri') ||\n newRedirectUri ||\n !defaultRedirectUri ||\n options.captureOAuth2Callback\n ) {\n return\n }\n\n handleOauth2SecretsUpdate({\n 'x-scalar-secret-redirect-uri': defaultRedirectUri,\n })\n },\n { immediate: true },\n)\n\n/**\n * Authorizes the user using the specified OAuth flow.\n * Opens the appropriate OAuth dialog and/or performs the token exchange.\n */\nconst handleAuthorize = async (): Promise<void> => {\n if (loader.isLoading) {\n return\n }\n\n loader.start()\n const controller = new AbortController()\n deviceController = controller\n\n const [error, tokens] = await authorizeOauth2(\n flows,\n type,\n selectedScopes.value,\n server,\n proxyUrl,\n getEnvironmentVariables(environment),\n options.customFetch,\n options.captureOAuth2Callback,\n {\n signal: controller.signal,\n onPrompt: (prompt) => {\n devicePrompt.value = prompt\n },\n },\n )\n devicePrompt.value = null\n\n await loader.clear()\n if (controller.signal.aborted) {\n return\n }\n\n if (tokens?.accessToken) {\n handleOauth2SecretsUpdate({\n 'x-scalar-secret-token': tokens.accessToken,\n ...(tokens.refreshToken\n ? { 'x-scalar-secret-refresh-token': tokens.refreshToken }\n : {}),\n })\n } else {\n console.error(error)\n toast(\n error?.message ?? translate('apiClient.oauth2.failedToauthorize'),\n 'error',\n )\n }\n}\n\n/** Refreshing requires a token issued by the provider, not just a compatible flow. */\nconst canRefreshToken = computed<boolean>(\n (): boolean =>\n type !== 'implicit' && Boolean(flow.value['x-scalar-secret-refresh-token']),\n)\n\n/**\n * Refresh URL placeholder, shows tokenUrl as hint if refreshUrl is not specified.\n * This helps users understand that tokenUrl will be used as fallback.\n */\nconst refreshUrlPlaceholder = computed(() => {\n if ('tokenUrl' in flow.value && flow.value.tokenUrl) {\n return flow.value.tokenUrl\n }\n return 'https://galaxy.scalar.com/oauth/refresh'\n})\n\n/**\n * Uses the stored refresh token to obtain a new access token\n * via grant_type=refresh_token.\n */\nconst handleRefresh = async (): Promise<void> => {\n // The explicit flow check narrows the type for refreshOauth2Token; the computed boolean cannot.\n if (loader.isLoading || type === 'implicit' || !canRefreshToken.value) {\n return\n }\n\n loader.start()\n\n const [error, tokens] = await refreshOauth2Token(\n flows,\n type,\n proxyUrl,\n server,\n getEnvironmentVariables(environment),\n options.customFetch,\n )\n\n await loader.clear()\n\n if (tokens?.accessToken) {\n handleOauth2SecretsUpdate({\n 'x-scalar-secret-token': tokens.accessToken,\n ...(tokens.refreshToken\n ? { 'x-scalar-secret-refresh-token': tokens.refreshToken }\n : {}),\n })\n } else {\n console.error(error)\n toast(\n error?.message ?? translate('apiClient.oauth2.failedToRefreshToken'),\n 'error',\n )\n }\n}\n\n/** Updates the secret location */\nconst handleSecretLocationUpdate = (value: string): void => {\n if (value !== 'body' && value !== 'header') return\n const credentialsLocation = value\n\n if (scheme.type !== 'openIdConnect') {\n handleOauth2Update({\n 'x-scalar-credentials-location': credentialsLocation,\n })\n }\n\n handleOauth2SecretsUpdate({\n 'x-scalar-credentials-location': credentialsLocation,\n })\n}\n</script>\n\n<template>\n <!-- Access Token Display: Shows when user is already authorized -->\n <template v-if=\"flow['x-scalar-secret-token']\">\n <DataTableRow>\n <RequestAuthDataTableInput\n :canReset=\"\n canReset('x-scalar-secret-token', flow['x-scalar-secret-token'])\n \"\n class=\"border-r-transparent\"\n :environment\n :modelValue=\"flow['x-scalar-secret-token']\"\n placeholder=\"QUxMIFlPVVIgQkFTRSBBUkUgQkVMT05HIFRPIFVT\"\n type=\"password\"\n @reset=\"handleResetSecret('x-scalar-secret-token')\"\n @update:modelValue=\"\n (v) => handleOauth2SecretsUpdate({ 'x-scalar-secret-token': v })\n \">\n {{ translate('apiClient.oauth2.accessToken') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <DataTableRow v-if=\"canRefreshToken\">\n <RequestAuthDataTableInput\n class=\"border-r-transparent\"\n :environment\n :modelValue=\"flow.refreshUrl ?? ''\"\n :placeholder=\"refreshUrlPlaceholder\"\n @update:modelValue=\"(v) => handleOauth2Update({ refreshUrl: v })\">\n {{ translate('apiClient.oauth2.refreshUrl') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <DataTableRow\n v-if=\"!hideActions\"\n class=\"min-w-full\">\n <div class=\"flex h-8 items-center justify-end gap-2 border-t\">\n <ScalarButton\n v-if=\"canRefreshToken\"\n class=\"p-0 px-2 py-0.5\"\n :loader\n size=\"sm\"\n variant=\"outlined\"\n @click=\"handleRefresh\">\n {{ translate('apiClient.oauth2.refresh') }}\n </ScalarButton>\n <ScalarButton\n class=\"mr-1 p-0 px-2 py-0.5\"\n :disabled=\"loader.isLoading\"\n size=\"sm\"\n variant=\"outlined\"\n @click=\"handleClearAccessTokens\">\n {{ translate('apiClient.oauth2.clearTokens') }}\n </ScalarButton>\n </div>\n </DataTableRow>\n </template>\n\n <!-- Authorization Form: Shows when user needs to authorize -->\n <template v-else>\n <DataTableRow v-if=\"'deviceAuthorizationUrl' in flow\">\n <RequestAuthDataTableInput\n :environment\n :modelValue=\"flow.deviceAuthorizationUrl\"\n @update:modelValue=\"\n (v) => handleOauth2Update({ deviceAuthorizationUrl: v })\n \">\n {{ translate('apiClient.oauth2.deviceAuthorizationUrl') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n <DataTableRow v-if=\"devicePrompt\">\n <div class=\"w-full p-2\">\n <div\n class=\"bg-b-2 flex flex-col gap-3 rounded-lg border p-3 text-sm\"\n role=\"status\">\n <p class=\"text-c-2 text-xs leading-normal\">\n {{ translate('apiClient.oauth2.deviceVerificationPrompt') }}\n </p>\n <strong\n class=\"bg-b-1 font-code w-fit max-w-full rounded border px-3 py-2 text-base font-medium tracking-widest break-all select-all\">\n {{ devicePrompt.userCode }}\n </strong>\n <a\n class=\"text-c-accent w-fit max-w-full text-xs break-all underline underline-offset-2\"\n :href=\"\n devicePrompt.verificationUriComplete ||\n devicePrompt.verificationUri\n \"\n rel=\"noopener noreferrer\"\n target=\"_blank\">\n {{ devicePrompt.verificationUri }}\n </a>\n <div class=\"flex items-center justify-between gap-3\">\n <p class=\"text-c-2 text-xs\">\n {{ translate('apiClient.oauth2.waitingForAuthorization') }}\n </p>\n <ScalarButton\n size=\"xs\"\n variant=\"outlined\"\n @click=\"cancelDeviceAuthorization\">\n {{ translate('apiClient.oauth2.cancelDeviceAuthorization') }}\n </ScalarButton>\n </div>\n </div>\n </div>\n </DataTableRow>\n <DataTableRow>\n <RequestAuthDataTableInput\n v-if=\"'authorizationUrl' in flow\"\n :canReset=\"\n canReset(\n 'x-scalar-secret-auth-url',\n flow['x-scalar-secret-auth-url'] ?? '',\n )\n \"\n containerClass=\"border-r-0\"\n :environment\n :modelValue=\"flow['x-scalar-secret-auth-url'] ?? ''\"\n placeholder=\"https://galaxy.scalar.com/authorize\"\n @reset=\"handleResetSecret('x-scalar-secret-auth-url')\"\n @update:modelValue=\"\n (v) => {\n handleOauth2SecretsUpdate({ 'x-scalar-secret-auth-url': v })\n if (v) handleOauth2Update({ authorizationUrl: v })\n }\n \">\n {{ translate('apiClient.oauth2.authUrl') }}\n </RequestAuthDataTableInput>\n\n <RequestAuthDataTableInput\n v-if=\"'tokenUrl' in flow\"\n :canReset=\"\n canReset(\n 'x-scalar-secret-token-url',\n flow['x-scalar-secret-token-url'] ?? '',\n )\n \"\n :environment\n :modelValue=\"flow['x-scalar-secret-token-url'] ?? ''\"\n placeholder=\"https://galaxy.scalar.com/token\"\n @reset=\"handleResetSecret('x-scalar-secret-token-url')\"\n @update:modelValue=\"\n (v) => {\n handleOauth2SecretsUpdate({ 'x-scalar-secret-token-url': v })\n if (v) handleOauth2Update({ tokenUrl: v })\n }\n \">\n {{ translate('apiClient.oauth2.tokenUrl') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <DataTableRow v-if=\"'x-scalar-secret-redirect-uri' in flow\">\n <RequestAuthDataTableInput\n :canReset=\"\n canReset(\n 'x-scalar-secret-redirect-uri',\n flow['x-scalar-secret-redirect-uri'],\n )\n \"\n :environment\n :modelValue=\"flow['x-scalar-secret-redirect-uri']\"\n :placeholder=\"\n options.captureOAuth2Callback\n ? `${resolveDefaultOAuth2RedirectUri(options) || 'http://127.0.0.1'} (handled automatically)`\n : translate('apiClient.oauth2.optionalRedirectUrl')\n \"\n @reset=\"handleResetSecret('x-scalar-secret-redirect-uri')\"\n @update:modelValue=\"\n (v) => {\n hasHandledRedirectPrefill = true\n handleOauth2SecretsUpdate({ 'x-scalar-secret-redirect-uri': v })\n }\n \">\n {{ translate('apiClient.oauth2.redirectUrl') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <template\n v-if=\"\n 'x-scalar-secret-username' in flow && 'x-scalar-secret-password' in flow\n \">\n <DataTableRow>\n <RequestAuthDataTableInput\n :canReset=\"\n canReset(\n 'x-scalar-secret-username',\n flow['x-scalar-secret-username'],\n )\n \"\n class=\"text-c-2\"\n :environment\n :modelValue=\"flow['x-scalar-secret-username']\"\n placeholder=\"janedoe\"\n @reset=\"handleResetSecret('x-scalar-secret-username')\"\n @update:modelValue=\"\n (v) => handleOauth2SecretsUpdate({ 'x-scalar-secret-username': v })\n \">\n {{ translate('apiClient.oauth2.username') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <DataTableRow>\n <RequestAuthDataTableInput\n :canReset=\"\n canReset(\n 'x-scalar-secret-password',\n flow['x-scalar-secret-password'],\n )\n \"\n :environment\n :modelValue=\"flow['x-scalar-secret-password']\"\n placeholder=\"********\"\n type=\"password\"\n @reset=\"handleResetSecret('x-scalar-secret-password')\"\n @update:modelValue=\"\n (v) => handleOauth2SecretsUpdate({ 'x-scalar-secret-password': v })\n \">\n {{ translate('apiClient.oauth2.password') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n </template>\n\n <DataTableRow>\n <RequestAuthDataTableInput\n :canReset=\"\n canReset(\n 'x-scalar-secret-client-id',\n flow['x-scalar-secret-client-id'],\n )\n \"\n :environment\n :modelValue=\"flow['x-scalar-secret-client-id']\"\n placeholder=\"12345\"\n @reset=\"handleResetSecret('x-scalar-secret-client-id')\"\n @update:modelValue=\"\n (v) => handleOauth2SecretsUpdate({ 'x-scalar-secret-client-id': v })\n \">\n {{ translate('apiClient.oauth2.clientID') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <DataTableRow v-if=\"showClientSecret\">\n <RequestAuthDataTableInput\n :canReset=\"canReset('x-scalar-secret-client-secret', clientSecretValue)\"\n :environment\n :modelValue=\"clientSecretValue\"\n placeholder=\"XYZ123\"\n type=\"password\"\n @reset=\"handleResetSecret('x-scalar-secret-client-secret')\"\n @update:modelValue=\"\n (v) =>\n handleOauth2SecretsUpdate({ 'x-scalar-secret-client-secret': v })\n \">\n {{ translate('apiClient.oauth2.clientSecret') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <DataTableRow v-if=\"'x-usePkce' in flow\">\n <RequestAuthDataTableInput\n :enum=\"pkceOptions\"\n :environment\n :modelValue=\"flow['x-usePkce']\"\n readOnly\n @update:modelValue=\"handlePkceUpdate\">\n {{ translate('apiClient.oauth2.usePKCE') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <!-- Credentials Location -->\n <DataTableRow v-if=\"type !== 'implicit'\">\n <RequestAuthDataTableInput\n :enum=\"['header', 'body']\"\n :environment\n :modelValue=\"\n (flow as NonImplicitFlow)['x-scalar-credentials-location'] || 'header'\n \"\n placeholder=\"header\"\n readOnly\n @update:modelValue=\"(v) => handleSecretLocationUpdate(v)\">\n {{ translate('apiClient.oauth2.credentialsLocation') }}\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <!-- Scopes -->\n <DataTableRow>\n <OAuthScopesInput\n :flow\n :flowType=\"type\"\n :selectedScopes\n @delete:scope=\"(v) => emits('delete:scope', v)\"\n @update:selectedScopes=\"(v) => emits('update:selectedScopes', v)\"\n @upsert:scope=\"(v) => emits('upsert:scope', v)\" />\n </DataTableRow>\n\n <DataTableRow\n v-if=\"!hideActions\"\n class=\"min-w-full\">\n <div class=\"flex h-8 w-full items-center justify-end border-t\">\n <!-- Allow clearing the oauth section and going back to discovery -->\n <ScalarButton\n v-if=\"scheme.type === 'openIdConnect'\"\n class=\"mr-1 p-0 px-2 py-0.5\"\n :disabled=\"loader.isLoading\"\n size=\"sm\"\n variant=\"outlined\"\n @click=\"clearOauth2Secrets\">\n {{ translate('apiClient.oauth2.resetDiscovery') }}\n </ScalarButton>\n\n <ScalarButton\n class=\"mr-0.75 p-0 px-2 py-0.5\"\n :loader\n size=\"sm\"\n variant=\"outlined\"\n @click=\"handleAuthorize\">\n {{ translate('apiClient.oauth2.authorize') }}\n </ScalarButton>\n </div>\n </DataTableRow>\n </template>\n</template>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"RequestAuthTab.vue.d.ts","sourceRoot":"","sources":["../../../../../src/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue"],"names":[],"mappings":"AA0wBA,OAAO,KAAK,EAEV,iBAAiB,EAClB,MAAM,gCAAgC,CAAA;AAGvC,OAAO,EAEL,KAAK,qBAAqB,EAG3B,MAAM,yCAAyC,CAAA;AAChD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2EAA2E,CAAA;AAEnH,OAAO,KAAK,EAEV,yBAAyB,EACzB,YAAY,EACb,MAAM,8DAA8D,CAAA;AAiBrE,OAAe,EAAE,KAAK,aAAa,EAAE,MAAM,cAAc,CAAA;AAKzD,KAAK,WAAW,GAAG;IACjB,wCAAwC;IACxC,WAAW,EAAE,kBAAkB,CAAA;IAC/B,yFAAyF;IACzF,QAAQ,EAAE,OAAO,CAAA;IACjB,gBAAgB;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,+BAA+B;IAC/B,uBAAuB,EAAE,yBAAyB,CAAA;IAClD,oGAAoG;IACpG,eAAe,EAAE,qBAAqB,CAAA;IACtC,mCAAmC;IACnC,MAAM,EAAE,YAAY,GAAG,IAAI,CAAA;IAC3B,2CAA2C;IAC3C,QAAQ,EAAE,iBAAiB,CAAA;IAC3B,uDAAuD;IACvD,OAAO,CAAC,EAAE,aAAa,CAAA;IACvB,yFAAyF;IACzF,YAAY,CAAC,EAAE,SAAS,GAAG,UAAU,CAAA;CACtC,CAAC;AA84CF,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kFAGhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
1
+ {"version":3,"file":"RequestAuthTab.vue.d.ts","sourceRoot":"","sources":["../../../../../src/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue"],"names":[],"mappings":"AA2wBA,OAAO,KAAK,EAEV,iBAAiB,EAClB,MAAM,gCAAgC,CAAA;AAGvC,OAAO,EAEL,KAAK,qBAAqB,EAG3B,MAAM,yCAAyC,CAAA;AAChD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2EAA2E,CAAA;AAEnH,OAAO,KAAK,EAEV,yBAAyB,EACzB,YAAY,EACb,MAAM,8DAA8D,CAAA;AAiBrE,OAAe,EAAE,KAAK,aAAa,EAAE,MAAM,cAAc,CAAA;AAKzD,KAAK,WAAW,GAAG;IACjB,wCAAwC;IACxC,WAAW,EAAE,kBAAkB,CAAA;IAC/B,yFAAyF;IACzF,QAAQ,EAAE,OAAO,CAAA;IACjB,gBAAgB;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,+BAA+B;IAC/B,uBAAuB,EAAE,yBAAyB,CAAA;IAClD,oGAAoG;IACpG,eAAe,EAAE,qBAAqB,CAAA;IACtC,mCAAmC;IACnC,MAAM,EAAE,YAAY,GAAG,IAAI,CAAA;IAC3B,2CAA2C;IAC3C,QAAQ,EAAE,iBAAiB,CAAA;IAC3B,uDAAuD;IACvD,OAAO,CAAC,EAAE,aAAa,CAAA;IACvB,yFAAyF;IACzF,YAAY,CAAC,EAAE,SAAS,GAAG,UAAU,CAAA;CACtC,CAAC;AA+4CF,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kFAGhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}