@scalar/api-client 2.38.2 → 2.38.3

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 (128) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/{AddressBar-B4xnl66I.js → AddressBar-CX8xiYoe.js} +4 -4
  3. package/dist/{AddressBar-B4xnl66I.js.map → AddressBar-CX8xiYoe.js.map} +1 -1
  4. package/dist/{App-BVH4lIe8.js → App-BpNPKHmM.js} +4 -4
  5. package/dist/{App-BVH4lIe8.js.map → App-BpNPKHmM.js.map} +1 -1
  6. package/dist/{App-CvClwSlM.js → App-Ckirvnv1.js} +2 -2
  7. package/dist/{App-CvClwSlM.js.map → App-Ckirvnv1.js.map} +1 -1
  8. package/dist/{CodeInput-C-igR77V.js → CodeInput-BN7uw3Bh.js} +2 -2
  9. package/dist/{CodeInput-C-igR77V.js.map → CodeInput-BN7uw3Bh.js.map} +1 -1
  10. package/dist/{Collection-4MT9WmDD.js → Collection-ChAxs3rz.js} +2 -2
  11. package/dist/{Collection-4MT9WmDD.js.map → Collection-ChAxs3rz.js.map} +1 -1
  12. package/dist/{CollectionAuthentication-MHWQpw74.js → CollectionAuthentication-BDpvv8cA.js} +5 -5
  13. package/dist/{CollectionAuthentication-MHWQpw74.js.map → CollectionAuthentication-BDpvv8cA.js.map} +1 -1
  14. package/dist/{CollectionEnvironment-Dw35vIqo.js → CollectionEnvironment-dwisJ-h5.js} +4 -4
  15. package/dist/{CollectionEnvironment-Dw35vIqo.js.map → CollectionEnvironment-dwisJ-h5.js.map} +1 -1
  16. package/dist/{CollectionOverview-TUdDIu5f.js → CollectionOverview-CJ9-Vmei.js} +3 -3
  17. package/dist/{CollectionOverview-TUdDIu5f.js.map → CollectionOverview-CJ9-Vmei.js.map} +1 -1
  18. package/dist/{CollectionServers-BrjTCfDe.js → CollectionServers-BWkIGwz4.js} +5 -5
  19. package/dist/{CollectionServers-BrjTCfDe.js.map → CollectionServers-BWkIGwz4.js.map} +1 -1
  20. package/dist/{CollectionSettings-HVSlp2Gv.js → CollectionSettings-CqUUYOym.js} +2 -2
  21. package/dist/{CollectionSettings-HVSlp2Gv.js.map → CollectionSettings-CqUUYOym.js.map} +1 -1
  22. package/dist/{CommandPalette-CL8k4CoN.js → CommandPalette-BiA0IgO8.js} +2 -2
  23. package/dist/{CommandPalette-CL8k4CoN.js.map → CommandPalette-BiA0IgO8.js.map} +1 -1
  24. package/dist/{Cookies-DbOKTi1f.js → Cookies-CNRSxP8J.js} +8 -8
  25. package/dist/{Cookies-DbOKTi1f.js.map → Cookies-CNRSxP8J.js.map} +1 -1
  26. package/dist/{DataTableInput-yaU5g-kP.js → DataTableInput-SkIUPlrB.js} +2 -2
  27. package/dist/{DataTableInput-yaU5g-kP.js.map → DataTableInput-SkIUPlrB.js.map} +1 -1
  28. package/dist/{Environment-DJatRQIg.js → Environment-D_CbZk0A.js} +5 -5
  29. package/dist/{Environment-DJatRQIg.js.map → Environment-D_CbZk0A.js.map} +1 -1
  30. package/dist/{EnvironmentModal-DBEJ4Kzj.js → EnvironmentModal-CcyqnPc2.js} +2 -2
  31. package/dist/{EnvironmentModal-DBEJ4Kzj.js.map → EnvironmentModal-CcyqnPc2.js.map} +1 -1
  32. package/dist/{Form-CSKzyHGO.js → Form-bA4bV_oA.js} +3 -3
  33. package/dist/{Form-CSKzyHGO.js.map → Form-bA4bV_oA.js.map} +1 -1
  34. package/dist/{ImportCollection-DfX1UQ5u.js → ImportCollection-BIYMxB9Q.js} +2 -2
  35. package/dist/{ImportCollection-DfX1UQ5u.js.map → ImportCollection-BIYMxB9Q.js.map} +1 -1
  36. package/dist/{MainLayout-BEFMl1ud.js → MainLayout-oMIJ5QXF.js} +3 -3
  37. package/dist/{MainLayout-BEFMl1ud.js.map → MainLayout-oMIJ5QXF.js.map} +1 -1
  38. package/dist/{Modal-sQ9vH6MN.js → Modal-DkOa_KK0.js} +2 -2
  39. package/dist/{Modal-sQ9vH6MN.js.map → Modal-DkOa_KK0.js.map} +1 -1
  40. package/dist/{Request-gscRsGQ8.js → Request-BWfYWyBa.js} +10 -10
  41. package/dist/{Request-gscRsGQ8.js.map → Request-BWfYWyBa.js.map} +1 -1
  42. package/dist/{RequestAuth-BzBfIysT.js → RequestAuth-BU6ubH-c.js} +3 -3
  43. package/dist/{RequestAuth-BzBfIysT.js.map → RequestAuth-BU6ubH-c.js.map} +1 -1
  44. package/dist/{RequestRoot-3Bj8JZD-.js → RequestRoot-7xhK5_qr.js} +7 -7
  45. package/dist/{RequestRoot-3Bj8JZD-.js.map → RequestRoot-7xhK5_qr.js.map} +1 -1
  46. package/dist/{RequestSection-HhdJj9hW.js → RequestSection-Bx8UHW-k.js} +4 -4
  47. package/dist/{RequestSection-HhdJj9hW.js.map → RequestSection-Bx8UHW-k.js.map} +1 -1
  48. package/dist/{ResponseSection-DMJ0tw8E.js → ResponseSection-CLrgLMN_.js} +3 -3
  49. package/dist/{ResponseSection-DMJ0tw8E.js.map → ResponseSection-CLrgLMN_.js.map} +1 -1
  50. package/dist/{Server-DnA_BzPS.js → Server-BS4zjUdO.js} +2 -2
  51. package/dist/{Server-DnA_BzPS.js.map → Server-BS4zjUdO.js.map} +1 -1
  52. package/dist/{Settings-CYZzdJPO.js → Settings-BuLKHzRY.js} +2 -2
  53. package/dist/{Settings-CYZzdJPO.js.map → Settings-BuLKHzRY.js.map} +1 -1
  54. package/dist/{Sidebar-C6AdX6-N.js → Sidebar-Xl9_nFXX.js} +2 -2
  55. package/dist/{Sidebar-C6AdX6-N.js.map → Sidebar-Xl9_nFXX.js.map} +1 -1
  56. package/dist/components/AddressBar/index.js +3 -3
  57. package/dist/components/CodeInput/index.js +1 -1
  58. package/dist/components/CommandPalette/index.js +1 -1
  59. package/dist/components/DataTable/index.js +2 -2
  60. package/dist/components/ImportCollection/index.js +1 -1
  61. package/dist/components/Server/index.js +1 -1
  62. package/dist/components/Sidebar/index.js +1 -1
  63. package/dist/components/index.js +4 -4
  64. package/dist/{components-CSxJTn6F.js → components-DfJHvSLM.js} +2 -2
  65. package/dist/{components-CSxJTn6F.js.map → components-DfJHvSLM.js.map} +1 -1
  66. package/dist/get-resolved-url-SybDPV0U.js +85 -0
  67. package/dist/get-resolved-url-SybDPV0U.js.map +1 -0
  68. package/dist/{get-server-url-o3On8CEr.js → get-server-url-UVN-dx79.js} +1 -1
  69. package/dist/{get-server-url-o3On8CEr.js.map → get-server-url-UVN-dx79.js.map} +1 -1
  70. package/dist/index.js +5 -5
  71. package/dist/layouts/App/index.js +3 -3
  72. package/dist/layouts/Modal/index.js +1 -1
  73. package/dist/layouts/Web/index.js +4 -4
  74. package/dist/libs/index.js +1 -1
  75. package/dist/{operation-block-BnMIKAOh.js → operation-block-DE-hoO03.js} +67 -17
  76. package/dist/operation-block-DE-hoO03.js.map +1 -0
  77. package/dist/{operation-code-sample-ZUTueV3v.js → operation-code-sample-xgx4qi2H.js} +22 -10
  78. package/dist/operation-code-sample-xgx4qi2H.js.map +1 -0
  79. package/dist/{request-block-DwsGy64Q.js → request-block-N7dPFyrG.js} +4 -4
  80. package/dist/{request-block-DwsGy64Q.js.map → request-block-N7dPFyrG.js.map} +1 -1
  81. package/dist/{scalar-address-bar-block--Vs6IBU1.js → scalar-address-bar-block-BbysOhkE.js} +2 -2
  82. package/dist/{scalar-address-bar-block--Vs6IBU1.js.map → scalar-address-bar-block-BbysOhkE.js.map} +1 -1
  83. package/dist/{scalar-auth-selector-block-DI3DLag9.js → scalar-auth-selector-block-Bs79QOMA.js} +12 -9
  84. package/dist/scalar-auth-selector-block-Bs79QOMA.js.map +1 -0
  85. package/dist/store/index.js +1 -1
  86. package/dist/{store-DpSUVhjp.js → store-DaPoVtIS.js} +15 -15
  87. package/dist/{store-DpSUVhjp.js.map → store-DaPoVtIS.js.map} +1 -1
  88. package/dist/style.css +1 -1
  89. package/dist/v2/blocks/operation-block/OperationBlock.vue.d.ts.map +1 -1
  90. package/dist/v2/blocks/operation-block/helpers/apply-allow-reserved-to-url.d.ts +6 -0
  91. package/dist/v2/blocks/operation-block/helpers/apply-allow-reserved-to-url.d.ts.map +1 -0
  92. package/dist/v2/blocks/operation-block/helpers/build-request-body.d.ts.map +1 -1
  93. package/dist/v2/blocks/operation-block/helpers/build-request-parameters.d.ts +1 -0
  94. package/dist/v2/blocks/operation-block/helpers/build-request-parameters.d.ts.map +1 -1
  95. package/dist/v2/blocks/operation-block/helpers/build-request.d.ts.map +1 -1
  96. package/dist/v2/blocks/operation-block/helpers/get-resolved-url.d.ts +2 -1
  97. package/dist/v2/blocks/operation-block/helpers/get-resolved-url.d.ts.map +1 -1
  98. package/dist/v2/blocks/operation-block/index.js +11 -11
  99. package/dist/v2/blocks/operation-code-sample/helpers/operation-to-har/process-body.d.ts.map +1 -1
  100. package/dist/v2/blocks/operation-code-sample/index.js +1 -1
  101. package/dist/v2/blocks/request-block/helpers/get-default-headers.d.ts.map +1 -1
  102. package/dist/v2/blocks/request-block/index.js +5 -5
  103. package/dist/v2/blocks/response-block/index.js +2 -2
  104. package/dist/v2/blocks/scalar-address-bar-block/index.js +1 -1
  105. package/dist/v2/blocks/scalar-auth-selector-block/helpers/extract-security-scheme-secrets.d.ts.map +1 -1
  106. package/dist/v2/blocks/scalar-auth-selector-block/helpers/security-scheme.d.ts.map +1 -1
  107. package/dist/v2/blocks/scalar-auth-selector-block/index.js +3 -3
  108. package/dist/v2/constants.d.ts +3 -0
  109. package/dist/v2/constants.d.ts.map +1 -0
  110. package/dist/v2/features/app/components/index.js +4 -4
  111. package/dist/v2/features/app/index.js +14 -14
  112. package/dist/v2/features/app/index.js.map +1 -1
  113. package/dist/v2/features/collection/components/Authentication.vue.d.ts.map +1 -1
  114. package/dist/v2/features/modal/index.js +10 -10
  115. package/dist/v2/features/operation/Operation.vue.d.ts.map +1 -1
  116. package/dist/v2/features/operation/helpers/get-selected-security.d.ts +6 -1
  117. package/dist/v2/features/operation/helpers/get-selected-security.d.ts.map +1 -1
  118. package/dist/v2/features/operation/index.js +10 -10
  119. package/dist/views/Request/RequestSection/RequestAuth/index.js +3 -3
  120. package/dist/views/Request/RequestSection/index.js +4 -4
  121. package/dist/views/Request/ResponseSection/index.js +3 -3
  122. package/dist/views/Request/components/index.js +1 -1
  123. package/package.json +13 -13
  124. package/dist/get-resolved-url-BUCwrBzc.js +0 -30
  125. package/dist/get-resolved-url-BUCwrBzc.js.map +0 -1
  126. package/dist/operation-block-BnMIKAOh.js.map +0 -1
  127. package/dist/operation-code-sample-ZUTueV3v.js.map +0 -1
  128. package/dist/scalar-auth-selector-block-DI3DLag9.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"RequestRoot-3Bj8JZD-.js","names":["$emit","$emit","$emit"],"sources":["../src/components/Sidebar/SidebarToggle.vue","../src/components/Sidebar/SidebarToggle.vue","../src/hooks/useAnalytics.ts","../src/libs/validate-parameters.ts","../src/views/Request/hooks/useOpenApiWatcher.ts","../src/components/EnvironmentSelector/EnvironmentSelector.vue","../src/components/EnvironmentSelector/EnvironmentSelector.vue","../src/components/Search/useSearch.ts","../src/views/Request/handle-drag.ts","../src/components/Sidebar/Actions/EditSidebarListCollection.vue","../src/components/Sidebar/Actions/EditSidebarListCollection.vue","../src/views/Request/RequestSidebarItemMenu.vue","../src/views/Request/RequestSidebarItemMenu.vue","../src/views/Request/RequestSection/helpers/getting-started.ts","../src/views/Request/RequestSidebarItem.vue","../src/views/Request/RequestSidebarItem.vue","../src/views/Request/RequestSidebar.vue","../src/views/Request/RequestSidebar.vue","../src/views/Request/RequestRoot.vue","../src/views/Request/RequestRoot.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { useSidebar } from '@/hooks/useSidebar'\n\nconst { isSidebarOpen, toggleSidebarOpen } = useSidebar()\n</script>\n<template>\n <button\n :aria-pressed=\"isSidebarOpen\"\n class=\"scalar-sidebar-toggle text-c-3 hover:bg-b-2 active:text-c-1 rounded-lg p-2\"\n type=\"button\"\n @click=\"toggleSidebarOpen\">\n <span class=\"sr-only\">{{ isSidebarOpen ? 'Hide' : 'Show' }} sidebar</span>\n <svg\n class=\"size-4\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <clipPath id=\"mask\">\n <path\n clip-rule=\"evenodd\"\n d=\"M9 3.2H4c-1.7 0-3 1.3-3 3v11.5c0 1.7 1.3 3 3 3h5V3.2z\" />\n </clipPath>\n </defs>\n <g clip-path=\"url(#mask)\">\n <path\n class=\"transition-transform duration-300\"\n :class=\"isSidebarOpen ? 'translate-x-0' : '-translate-x-1/2'\"\n d=\"M1 3.2h8v17.5H1z\"\n fill=\"currentColor\" />\n </g>\n <path\n d=\"M20 20.8H4c-1.7 0-3-1.3-3-3V6.2c0-1.7 1.3-3 3-3h16c1.7 0 3 1.3 3 3v11.5c0 1.7-1.3 3-3 3zM9 3.2v17.5\"\n stroke=\"currentColor\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\" />\n </svg>\n </button>\n</template>\n","<script setup lang=\"ts\">\nimport { useSidebar } from '@/hooks/useSidebar'\n\nconst { isSidebarOpen, toggleSidebarOpen } = useSidebar()\n</script>\n<template>\n <button\n :aria-pressed=\"isSidebarOpen\"\n class=\"scalar-sidebar-toggle text-c-3 hover:bg-b-2 active:text-c-1 rounded-lg p-2\"\n type=\"button\"\n @click=\"toggleSidebarOpen\">\n <span class=\"sr-only\">{{ isSidebarOpen ? 'Hide' : 'Show' }} sidebar</span>\n <svg\n class=\"size-4\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <clipPath id=\"mask\">\n <path\n clip-rule=\"evenodd\"\n d=\"M9 3.2H4c-1.7 0-3 1.3-3 3v11.5c0 1.7 1.3 3 3 3h5V3.2z\" />\n </clipPath>\n </defs>\n <g clip-path=\"url(#mask)\">\n <path\n class=\"transition-transform duration-300\"\n :class=\"isSidebarOpen ? 'translate-x-0' : '-translate-x-1/2'\"\n d=\"M1 3.2h8v17.5H1z\"\n fill=\"currentColor\" />\n </g>\n <path\n d=\"M20 20.8H4c-1.7 0-3-1.3-3-3V6.2c0-1.7 1.3-3 3-3h16c1.7 0 3 1.3 3 3v11.5c0 1.7-1.3 3-3 3zM9 3.2v17.5\"\n stroke=\"currentColor\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\" />\n </svg>\n </button>\n</template>\n","import { analytics } from '@/analytics'\nimport { useClientConfig } from '@/hooks/useClientConfig'\nimport { useLayout } from '@/hooks/useLayout'\n\n/** Gets the correct analytics client based on the layout. */\nexport function useAnalytics() {\n const { layout } = useLayout()\n const config = useClientConfig()\n\n if (!config.value.telemetry || layout === 'modal') {\n return\n }\n\n // Return the correct analytics client\n return analytics\n}\n","import type { RequestExample } from '@scalar/oas-utils/entities/spec'\n\nexport type ValidationResult = {\n invalidParams: Set<string>\n hasBlockingErrors: boolean\n}\n\n/**\n * Validate required parameters from an example.\n *\n * Returns both the set of invalid parameter keys and a flag indicating\n * if there are blocking errors (empty required path parameters) that\n * should prevent the request from being sent.\n */\nexport const validateParameters = (example: Partial<RequestExample> | null): ValidationResult => {\n const result = {\n invalidParams: new Set<string>(),\n hasBlockingErrors: false,\n }\n\n if (!example) {\n return result\n }\n\n // Check path parameters separately - these are blocking\n example.parameters?.path?.forEach((param) => {\n if (param.enabled && param.value.trim() === '') {\n result.invalidParams.add(param.key)\n result.hasBlockingErrors = true\n }\n })\n\n // Validate other parameters - these are non-blocking\n const nonBlockingParamTypes = ['query', 'headers', 'cookies'] as const\n nonBlockingParamTypes.forEach((paramType) => {\n example.parameters?.[paramType]?.forEach((param) => {\n if (param.required && param.value === '') {\n result.invalidParams.add(param.key)\n }\n })\n })\n\n return result\n}\n","import { createHash, fetchDocument } from '@scalar/oas-utils/helpers'\nimport { parseSchema } from '@scalar/oas-utils/transforms'\nimport { useToasts } from '@scalar/use-toasts'\nimport { useTimeoutPoll } from '@vueuse/core'\nimport microdiff, { type Difference } from 'microdiff'\nimport { watch } from 'vue'\n\nimport { useWorkspace } from '@/store'\nimport { useActiveEntities } from '@/store/active-entities'\nimport { specDictionary } from '@/store/import-spec'\nimport {\n combineRenameDiffs,\n mutateCollectionDiff,\n mutateRequestDiff,\n mutateSecuritySchemeDiff,\n mutateServerDiff,\n mutateTagDiff,\n} from '@/views/Request/libs/watch-mode'\n\n/** Timeout for the watch mode polling */\nconst POLLING_INTERVAL = 5 * 1000 // 5 seconds\n\n/** Pause for 60 seconds after an error */\nconst ERROR_TIMEOUT = 60 * 1000 // 60 seconds\n\n/**\n * Hook which handles polling the documentUrl for changes then attempts to merge what is new\n *\n * TODO:\n * - check lastModified or similar headers\n * - speed up the polling when there's a change then slowly slow it down\n */\nexport const useOpenApiWatcher = () => {\n const { toast } = useToasts()\n const activeEntities = useActiveEntities()\n const store = useWorkspace()\n\n const { activeCollection, activeWorkspace } = activeEntities\n const { collectionMutators } = store\n\n /** Little toast helper */\n const toastError = (type: string) => toast(`[useOpenApiWatcher] Changes to the ${type} were not applied`, 'error')\n\n // Transforms and applies the diff to our mutators\n const applyDiff = (d: Difference) => {\n // Info/Security\n if (d.path[0] === 'info' || d.path[0] === 'security') {\n const success = mutateCollectionDiff(d, activeEntities, store)\n if (!success) {\n toastError('collection')\n }\n }\n // Components.securitySchemes\n else if (d.path[0] === 'components' && d.path[1] === 'securitySchemes') {\n const success = mutateSecuritySchemeDiff(d, activeEntities, store)\n if (!success) {\n toastError('securitySchemes')\n }\n }\n // Servers\n else if (d.path[0] === 'servers') {\n const success = mutateServerDiff(d, activeEntities, store)\n if (!success) {\n toastError('servers')\n }\n }\n // Tags\n else if (d.path[0] === 'tags') {\n const success = mutateTagDiff(d, activeEntities, store)\n if (!success) {\n toastError('tags')\n }\n }\n // Requests\n else if (d.path[0] === 'paths') {\n const success = mutateRequestDiff(d, activeEntities, store)\n if (!success) {\n toastError('requests')\n }\n }\n }\n\n const { pause, resume } = useTimeoutPoll(async () => {\n const url = activeCollection.value?.documentUrl\n if (!url) {\n return\n }\n\n const old = specDictionary[url]\n\n try {\n // Grab the new spec\n const spec = await fetchDocument(url, activeWorkspace.value?.proxyUrl, undefined, false)\n const hash = createHash(spec)\n\n collectionMutators.edit(activeCollection.value.uid, 'watchModeStatus', 'WATCHING')\n\n // If we have no previous copy then store this one\n if (!old?.hash) {\n const { schema } = await parseSchema(spec)\n\n if (schema) {\n specDictionary[url] = {\n hash,\n schema,\n }\n }\n }\n // If the hashes do not match, start diffin\n else if (old.hash && old.hash !== hash) {\n const { schema } = await parseSchema(spec)\n const diff = microdiff(old.schema, schema)\n\n // Combines add/remove diffs into single rename diffs\n const combined = combineRenameDiffs(diff)\n\n try {\n // Transform and apply the diffs to our mutators\n combined.forEach(applyDiff)\n\n // Update the dict\n specDictionary[url] = {\n hash,\n schema,\n }\n } catch (e) {\n console.error('[useOpenApiWatcher] Error:', e)\n }\n } else {\n console.log('[useOpenApiWatcher] No changes detected yet…')\n }\n } catch (e) {\n console.error('[useOpenApiWatcher] Error:', e)\n console.info('[useOpenApiWatcher] Pausing watcher for 60 seconds')\n\n pause()\n collectionMutators.edit(activeCollection.value.uid, 'watchModeStatus', 'ERROR')\n toast('[useOpenApiWatcher] Unable to fetch the spec file, paused the watcher for 60 seconds', 'error')\n\n setTimeout(() => {\n console.info('[useOpenApiWatcher] Resuming watcher')\n resume()\n }, ERROR_TIMEOUT)\n }\n }, POLLING_INTERVAL)\n\n // Ensure we are only polling when we should watchMode\n watch(\n [() => activeCollection.value?.documentUrl, () => activeCollection.value?.watchMode],\n ([documentUrl, watchMode]) => {\n if (documentUrl && watchMode) {\n console.info(`[useOpenApiWatcher] Watching ${documentUrl} …`)\n resume()\n } else if (activeCollection.value) {\n pause()\n collectionMutators.edit(activeCollection.value.uid, 'watchModeStatus', 'IDLE')\n }\n },\n { immediate: true },\n )\n}\n","<script setup lang=\"ts\">\nimport {\n ScalarButton,\n ScalarDropdown,\n ScalarDropdownDivider,\n ScalarDropdownItem,\n ScalarIcon,\n ScalarListboxCheckbox,\n} from '@scalar/components'\nimport type { Collection } from '@scalar/oas-utils/entities/spec'\nimport { computed, onMounted, watch } from 'vue'\nimport { useRouter } from 'vue-router'\n\nimport { useLayout } from '@/hooks'\nimport { PathId } from '@/routes'\nimport { useWorkspace } from '@/store'\nimport { useActiveEntities } from '@/store/active-entities'\n\nconst { activeCollection, activeWorkspace, activeEnvironment } =\n useActiveEntities()\nconst { collectionMutators } = useWorkspace()\nconst { layout } = useLayout()\n\nconst router = useRouter()\n\nconst updateSelected = (uid: string) => {\n if (activeCollection.value && activeWorkspace.value) {\n collectionMutators.edit(\n activeCollection.value.uid,\n 'x-scalar-active-environment',\n uid,\n )\n\n activeWorkspace.value.activeEnvironmentId = uid\n }\n}\n\nconst redirectToEnvironments = () =>\n router.push({\n name: 'environment.default',\n params: {\n [PathId.Workspace]: activeWorkspace.value?.uid,\n },\n })\n\nconst selectedEnvironment = computed(() => {\n const { value: environment } = activeEnvironment\n const { value: collection } = activeCollection\n return (\n environment?.name ||\n collection?.['x-scalar-active-environment'] ||\n 'No Environment'\n )\n})\n\nconst availableEnvironments = computed(() => {\n const { value: collection } = activeCollection\n const environments = collection?.['x-scalar-environments']\n return environments\n ? Object.entries(environments).map(([key, env]) => ({\n ...env,\n uid: key,\n name: key,\n }))\n : []\n})\n\nconst selectLatestEnvironment = () => {\n const environments = availableEnvironments.value\n if (environments.length > 0) {\n // Get the latest created collection environment\n const latestEnvironment = environments[environments.length - 1]\n\n if (latestEnvironment?.uid) {\n updateSelected(latestEnvironment.uid)\n }\n }\n}\n\n// Select for the collection its latest environment on creation\nwatch(availableEnvironments, (newEnvs, oldEnvs) => {\n if (newEnvs.length > oldEnvs.length) {\n selectLatestEnvironment()\n }\n})\n\nconst setInitialEnvironment = (collection: Collection) => {\n const activeEnv = collection['x-scalar-active-environment']\n if (activeEnv && activeCollection.value && activeWorkspace.value) {\n activeCollection.value['x-scalar-active-environment'] = activeEnv\n activeWorkspace.value.activeEnvironmentId = activeEnv\n } else if (activeWorkspace.value) {\n activeWorkspace.value.activeEnvironmentId = ''\n }\n}\n\nwatch(\n activeCollection,\n (newCollection) => newCollection && setInitialEnvironment(newCollection),\n)\n\nonMounted(() => {\n activeCollection.value && setInitialEnvironment(activeCollection.value)\n})\n</script>\n<template>\n <ScalarDropdown teleport>\n <ScalarButton\n class=\"text-c-1 hover:bg-b-2 line-clamp-1 h-auto w-fit justify-start px-1.5 py-1.5 font-normal\"\n variant=\"ghost\">\n <h2 class=\"m-0 flex items-center gap-1.5 font-medium whitespace-nowrap\">\n {{ selectedEnvironment }}\n </h2>\n </ScalarButton>\n <!-- Workspace list -->\n <template #items>\n <ScalarDropdownItem\n v-for=\"environment in availableEnvironments\"\n :key=\"environment.uid\"\n class=\"group/item flex items-center gap-1.5 overflow-hidden text-ellipsis whitespace-nowrap\"\n @click.stop=\"updateSelected(environment.uid)\">\n <ScalarListboxCheckbox\n :selected=\"\n activeCollection?.['x-scalar-active-environment'] ===\n environment.uid\n \" />\n {{ environment.name }}\n </ScalarDropdownItem>\n <ScalarDropdownItem\n class=\"group/item flex items-center gap-1.5 overflow-hidden text-ellipsis whitespace-nowrap\"\n @click.stop=\"updateSelected('')\">\n <ScalarListboxCheckbox\n :selected=\"\n (activeEnvironment?.uid === '' &&\n activeCollection?.['x-scalar-active-environment'] === '') ||\n activeEnvironment?.name === 'No Environment'\n \" />\n No Environment\n </ScalarDropdownItem>\n <ScalarDropdownDivider />\n <!-- Manage environments -->\n <ScalarDropdownItem\n v-if=\"layout !== 'modal'\"\n class=\"flex items-center gap-1.5\"\n @click=\"redirectToEnvironments\">\n <div class=\"flex h-4 w-4 items-center justify-center\">\n <ScalarIcon\n icon=\"Brackets\"\n size=\"sm\" />\n </div>\n <span class=\"leading-none\">Manage Environments</span>\n </ScalarDropdownItem>\n </template>\n </ScalarDropdown>\n</template>\n","<script setup lang=\"ts\">\nimport {\n ScalarButton,\n ScalarDropdown,\n ScalarDropdownDivider,\n ScalarDropdownItem,\n ScalarIcon,\n ScalarListboxCheckbox,\n} from '@scalar/components'\nimport type { Collection } from '@scalar/oas-utils/entities/spec'\nimport { computed, onMounted, watch } from 'vue'\nimport { useRouter } from 'vue-router'\n\nimport { useLayout } from '@/hooks'\nimport { PathId } from '@/routes'\nimport { useWorkspace } from '@/store'\nimport { useActiveEntities } from '@/store/active-entities'\n\nconst { activeCollection, activeWorkspace, activeEnvironment } =\n useActiveEntities()\nconst { collectionMutators } = useWorkspace()\nconst { layout } = useLayout()\n\nconst router = useRouter()\n\nconst updateSelected = (uid: string) => {\n if (activeCollection.value && activeWorkspace.value) {\n collectionMutators.edit(\n activeCollection.value.uid,\n 'x-scalar-active-environment',\n uid,\n )\n\n activeWorkspace.value.activeEnvironmentId = uid\n }\n}\n\nconst redirectToEnvironments = () =>\n router.push({\n name: 'environment.default',\n params: {\n [PathId.Workspace]: activeWorkspace.value?.uid,\n },\n })\n\nconst selectedEnvironment = computed(() => {\n const { value: environment } = activeEnvironment\n const { value: collection } = activeCollection\n return (\n environment?.name ||\n collection?.['x-scalar-active-environment'] ||\n 'No Environment'\n )\n})\n\nconst availableEnvironments = computed(() => {\n const { value: collection } = activeCollection\n const environments = collection?.['x-scalar-environments']\n return environments\n ? Object.entries(environments).map(([key, env]) => ({\n ...env,\n uid: key,\n name: key,\n }))\n : []\n})\n\nconst selectLatestEnvironment = () => {\n const environments = availableEnvironments.value\n if (environments.length > 0) {\n // Get the latest created collection environment\n const latestEnvironment = environments[environments.length - 1]\n\n if (latestEnvironment?.uid) {\n updateSelected(latestEnvironment.uid)\n }\n }\n}\n\n// Select for the collection its latest environment on creation\nwatch(availableEnvironments, (newEnvs, oldEnvs) => {\n if (newEnvs.length > oldEnvs.length) {\n selectLatestEnvironment()\n }\n})\n\nconst setInitialEnvironment = (collection: Collection) => {\n const activeEnv = collection['x-scalar-active-environment']\n if (activeEnv && activeCollection.value && activeWorkspace.value) {\n activeCollection.value['x-scalar-active-environment'] = activeEnv\n activeWorkspace.value.activeEnvironmentId = activeEnv\n } else if (activeWorkspace.value) {\n activeWorkspace.value.activeEnvironmentId = ''\n }\n}\n\nwatch(\n activeCollection,\n (newCollection) => newCollection && setInitialEnvironment(newCollection),\n)\n\nonMounted(() => {\n activeCollection.value && setInitialEnvironment(activeCollection.value)\n})\n</script>\n<template>\n <ScalarDropdown teleport>\n <ScalarButton\n class=\"text-c-1 hover:bg-b-2 line-clamp-1 h-auto w-fit justify-start px-1.5 py-1.5 font-normal\"\n variant=\"ghost\">\n <h2 class=\"m-0 flex items-center gap-1.5 font-medium whitespace-nowrap\">\n {{ selectedEnvironment }}\n </h2>\n </ScalarButton>\n <!-- Workspace list -->\n <template #items>\n <ScalarDropdownItem\n v-for=\"environment in availableEnvironments\"\n :key=\"environment.uid\"\n class=\"group/item flex items-center gap-1.5 overflow-hidden text-ellipsis whitespace-nowrap\"\n @click.stop=\"updateSelected(environment.uid)\">\n <ScalarListboxCheckbox\n :selected=\"\n activeCollection?.['x-scalar-active-environment'] ===\n environment.uid\n \" />\n {{ environment.name }}\n </ScalarDropdownItem>\n <ScalarDropdownItem\n class=\"group/item flex items-center gap-1.5 overflow-hidden text-ellipsis whitespace-nowrap\"\n @click.stop=\"updateSelected('')\">\n <ScalarListboxCheckbox\n :selected=\"\n (activeEnvironment?.uid === '' &&\n activeCollection?.['x-scalar-active-environment'] === '') ||\n activeEnvironment?.name === 'No Environment'\n \" />\n No Environment\n </ScalarDropdownItem>\n <ScalarDropdownDivider />\n <!-- Manage environments -->\n <ScalarDropdownItem\n v-if=\"layout !== 'modal'\"\n class=\"flex items-center gap-1.5\"\n @click=\"redirectToEnvironments\">\n <div class=\"flex h-4 w-4 items-center justify-center\">\n <ScalarIcon\n icon=\"Brackets\"\n size=\"sm\" />\n </div>\n <span class=\"leading-none\">Manage Environments</span>\n </ScalarDropdownItem>\n </template>\n </ScalarDropdown>\n</template>\n","import type { Request } from '@scalar/oas-utils/entities/spec'\nimport { isDefined, shouldIgnoreEntity } from '@scalar/oas-utils/helpers'\nimport Fuse, { type FuseResult } from 'fuse.js'\nimport { computed, nextTick, ref, watch } from 'vue'\nimport { useRouter } from 'vue-router'\n\nimport { PathId } from '@/routes'\nimport { useWorkspace } from '@/store'\nimport { useActiveEntities } from '@/store/active-entities'\n\n/**\n * Hook for managing search functionality.\n * Provides search state, results, and methods for searching.\n */\nexport function useSearch() {\n const router = useRouter()\n const { activeWorkspace, activeWorkspaceRequests, activeWorkspaceCollections } = useActiveEntities()\n const { requests, tags } = useWorkspace()\n\n type FuseData = {\n title: string\n description: string\n httpVerb: string\n id: string\n path: string\n link: string | undefined\n }\n\n const fuseDataArray = ref<FuseData[]>([])\n const searchResults = ref<FuseResult<FuseData>[]>([])\n const selectedSearchResult = ref<number>(0)\n const searchText = ref<string>('')\n const searchInputRef = ref<HTMLInputElement | null>(null)\n const searchResultRefs = ref<HTMLElement[]>([])\n\n const fuse = new Fuse(fuseDataArray.value, {\n keys: ['title', 'description', 'body'],\n })\n\n const resetSearch = () => {\n searchText.value = ''\n selectedSearchResult.value = 0\n searchResults.value = []\n if (searchInputRef.value instanceof HTMLInputElement) {\n searchInputRef.value.blur()\n }\n }\n\n const populateFuseDataArray = (items: Request[]) => {\n fuseDataArray.value = items\n // TODO: We should probably filter in the store or somewhere else.\n // Check if the request is marked has hidden/internal\n .filter((request) => !shouldIgnoreEntity(request))\n // Check if the request is in a tag that is marked has hidden/internal\n .filter((request) => {\n // Find the collection for the request\n const collection = activeWorkspaceCollections.value?.find((activeWorkspaceCollection) =>\n activeWorkspaceCollection.requests.includes(request.uid),\n )\n\n const hasIgnoredTags = Boolean(\n collection?.tags\n .map((uid) => tags[uid])\n .filter(isDefined)\n .filter((tag) => request.tags?.includes(tag.name))\n .filter((tag) => shouldIgnoreEntity(tag)).length,\n )\n\n return !hasIgnoredTags\n })\n .map((request: Request) => ({\n id: request.uid,\n title: request.summary ?? request.method,\n description: request.description ?? '',\n httpVerb: request.method,\n path: request.path,\n link: router?.resolve({\n name: 'request',\n params: {\n [PathId.Request]: request.uid,\n [PathId.Workspace]: activeWorkspace.value?.uid,\n },\n })?.href,\n }))\n\n fuse.setCollection(fuseDataArray.value)\n }\n\n const fuseSearch = (): void => {\n selectedSearchResult.value = 0\n searchResults.value = fuse.search(searchText.value)\n }\n\n watch(searchText, (newValue) => {\n if (newValue.length) {\n fuseSearch()\n } else {\n searchResults.value = []\n }\n })\n\n const navigateSearchResults = (direction: 'up' | 'down') => {\n const offset = direction === 'up' ? -1 : 1\n const length = searchResultsWithPlaceholderResults.value.length\n\n // Ensures we loop around the array by using the remainder\n selectedSearchResult.value = (selectedSearchResult.value + offset + length) % length\n\n // Scroll the selected item into view\n nextTick(() => {\n const element = searchResultRefs.value[selectedSearchResult.value]\n if (element instanceof HTMLElement) {\n element.scrollIntoView({\n behavior: 'smooth',\n block: 'center',\n })\n }\n })\n }\n\n const selectSearchResult = () => {\n if (selectedSearchResult.value >= 0) {\n const selectedResult = searchResultsWithPlaceholderResults.value[selectedSearchResult.value]\n if (selectedResult) {\n onSearchResultClick(selectedResult)\n }\n }\n }\n\n const validRequests = computed(() => activeWorkspaceRequests.value.map((uid) => requests[uid]).filter(isDefined))\n\n // Populate our fuseDataArray with the request items\n watch(\n activeWorkspaceRequests,\n () => {\n populateFuseDataArray(validRequests.value)\n },\n { immediate: true },\n )\n\n const onSearchResultClick = (entry: FuseResult<FuseData>) => {\n router.push(entry.item.id)\n resetSearch()\n }\n\n const searchResultsWithPlaceholderResults = computed((): FuseResult<FuseData>[] => {\n if (searchText.value.length === 0) {\n return fuseDataArray.value.map((item) => {\n return {\n item: item,\n } as FuseResult<FuseData>\n })\n }\n\n return searchResults.value\n })\n\n return {\n searchText,\n searchResultsWithPlaceholderResults,\n selectedSearchResult,\n onSearchResultClick,\n fuseSearch,\n searchInputRef,\n searchResultRefs,\n navigateSearchResults,\n selectSearchResult,\n populateFuseDataArray,\n }\n}\n","import type { DraggingItem, HoveredItem } from '@scalar/draggable'\nimport type { Collection, Tag } from '@scalar/oas-utils/entities/spec'\n\nimport { useLayout } from '@/hooks'\nimport type { WorkspaceStore } from '@/store'\nimport type { ActiveEntitiesStore } from '@/store/active-entities'\n\n/** Create DnD handlers */\nexport function dragHandlerFactory(\n activeWorkspace: ActiveEntitiesStore['activeWorkspace'],\n { collections, collectionMutators, tags, tagMutators, workspaceMutators }: WorkspaceStore,\n) {\n const { layout } = useLayout()\n\n /** Mutate tag OR collection */\n const mutateTagOrCollection = (parent: Collection | Tag, childUids: string[]) => {\n if (parent.type === 'collection') {\n collectionMutators.edit(parent.uid, 'children', childUids as Collection['children'])\n } else if (parent.type === 'tag') {\n tagMutators.edit(parent.uid, 'children', childUids as Tag['children'])\n }\n }\n\n /** Drag handler that mutates depending on the entity types */\n const handleDragEnd = (draggingItem: DraggingItem, hoveredItem: HoveredItem) => {\n if (!draggingItem || !hoveredItem) {\n return\n }\n\n const { id: draggingUid, parentId: draggingParentUid } = draggingItem\n const { id: hoveredUid, parentId: hoveredParentUid, offset } = hoveredItem\n\n // Parent is the workspace\n if (!draggingParentUid) {\n workspaceMutators.edit(\n activeWorkspace.value?.uid,\n 'collections',\n activeWorkspace.value?.collections.filter((uid) => uid !== draggingUid) ?? [],\n )\n }\n\n // Parent is collection\n else if (collections[draggingParentUid]) {\n collectionMutators.edit(\n draggingParentUid as Collection['uid'],\n 'children',\n collections[draggingParentUid].children.filter((uid) => uid !== draggingUid),\n )\n }\n // Parent is a tag\n else if (tags[draggingParentUid]) {\n tagMutators.edit(\n draggingParentUid as Tag['uid'],\n 'children',\n tags[draggingParentUid].children.filter((uid) => uid !== draggingUid),\n )\n }\n\n // Place it at the end of the list of the hoveredItem\n if (offset === 2) {\n const parent = collections[hoveredUid] || tags[hoveredUid]\n if (parent) {\n mutateTagOrCollection(parent, [...(parent.children ?? []), draggingUid])\n }\n }\n // Special case for collections\n else if (!hoveredParentUid) {\n const newChildUids = [...(activeWorkspace.value?.collections ?? [])]\n const hoveredIndex = newChildUids.findIndex((uid) => hoveredUid === uid) ?? 0\n newChildUids.splice(hoveredIndex + offset, 0, draggingUid as Collection['uid'])\n\n workspaceMutators.edit(activeWorkspace.value?.uid, 'collections', newChildUids)\n }\n // Place it into the list at an index\n else {\n const parent = collections[hoveredParentUid] || tags[hoveredParentUid]\n if (!parent) {\n return\n }\n\n const newChildUids = [...(parent.children ?? [])] as string[]\n const hoveredIndex = newChildUids.findIndex((uid) => hoveredUid === uid) ?? 0\n newChildUids.splice(hoveredIndex + offset, 0, draggingUid)\n\n mutateTagOrCollection(parent, newChildUids)\n }\n }\n\n /** Ensure only collections are allowed at the top level OR resources dropped INTO (offset 2) */\n const isDroppable = (draggingItem: DraggingItem, hoveredItem: HoveredItem) => {\n // Cannot drop in read only mode\n if (layout === 'modal') {\n return false\n }\n // Cannot drop requests/folders into a workspace\n if (!collections[draggingItem.id] && hoveredItem.offset !== 2) {\n return false\n }\n // Collections cannot drop over Drafts\n if (collections[draggingItem.id] && collections[hoveredItem.id]?.info?.title === 'Drafts') {\n return false\n }\n\n return true\n }\n\n return {\n handleDragEnd,\n isDroppable,\n }\n}\n","<script setup lang=\"ts\">\nimport { ScalarButton, ScalarTextInput } from '@scalar/components'\nimport { LibraryIcon } from '@scalar/icons/library'\nimport { ref } from 'vue'\n\nimport IconSelector from '@/components/IconSelector.vue'\nimport SidebarListElementForm from '@/components/Sidebar/Actions/SidebarListElementForm.vue'\n\nconst props = defineProps<{\n name: string\n icon: string\n}>()\n\nconst emit = defineEmits<{\n (e: 'close'): void\n (e: 'edit', newName: string, newIcon: string): void\n}>()\n\nconst newName = ref(props.name)\nconst newIcon = ref(props.icon)\n</script>\n<template>\n <SidebarListElementForm\n @cancel=\"emit('close')\"\n @submit=\"emit('edit', newName, newIcon)\">\n <div class=\"grid grid-cols-[auto_1fr] gap-2\">\n <div class=\"flex aspect-square\">\n <IconSelector\n v-model=\"newIcon\"\n placement=\"bottom-start\">\n <ScalarButton\n class=\"aspect-square h-auto px-0\"\n variant=\"outlined\">\n <LibraryIcon\n class=\"text-c-2 size-4\"\n :src=\"newIcon\" />\n </ScalarButton>\n </IconSelector>\n </div>\n <ScalarTextInput\n v-model=\"newName\"\n autofocus\n class=\"flex-1\" />\n </div>\n </SidebarListElementForm>\n</template>\n","<script setup lang=\"ts\">\nimport { ScalarButton, ScalarTextInput } from '@scalar/components'\nimport { LibraryIcon } from '@scalar/icons/library'\nimport { ref } from 'vue'\n\nimport IconSelector from '@/components/IconSelector.vue'\nimport SidebarListElementForm from '@/components/Sidebar/Actions/SidebarListElementForm.vue'\n\nconst props = defineProps<{\n name: string\n icon: string\n}>()\n\nconst emit = defineEmits<{\n (e: 'close'): void\n (e: 'edit', newName: string, newIcon: string): void\n}>()\n\nconst newName = ref(props.name)\nconst newIcon = ref(props.icon)\n</script>\n<template>\n <SidebarListElementForm\n @cancel=\"emit('close')\"\n @submit=\"emit('edit', newName, newIcon)\">\n <div class=\"grid grid-cols-[auto_1fr] gap-2\">\n <div class=\"flex aspect-square\">\n <IconSelector\n v-model=\"newIcon\"\n placement=\"bottom-start\">\n <ScalarButton\n class=\"aspect-square h-auto px-0\"\n variant=\"outlined\">\n <LibraryIcon\n class=\"text-c-2 size-4\"\n :src=\"newIcon\" />\n </ScalarButton>\n </IconSelector>\n </div>\n <ScalarTextInput\n v-model=\"newName\"\n autofocus\n class=\"flex-1\" />\n </div>\n </SidebarListElementForm>\n</template>\n","<script setup lang=\"ts\">\nimport {\n ScalarDropdownButton,\n ScalarDropdownMenu,\n ScalarFloating,\n ScalarIcon,\n ScalarModal,\n useModal,\n type ScalarDropdown,\n} from '@scalar/components'\nimport type { Collection } from '@scalar/oas-utils/entities/spec'\nimport { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'\nimport { useRouter } from 'vue-router'\n\nimport DeleteSidebarListElement from '@/components/Sidebar/Actions/DeleteSidebarListElement.vue'\nimport EditSidebarListCollection from '@/components/Sidebar/Actions/EditSidebarListCollection.vue'\nimport EditSidebarListElement from '@/components/Sidebar/Actions/EditSidebarListElement.vue'\nimport { PathId } from '@/routes'\nimport { useWorkspace } from '@/store'\nimport { useActiveEntities } from '@/store/active-entities'\nimport { createInitialRequest } from '@/store/requests'\nimport type { SidebarMenuItem } from '@/views/Request/types'\n\nconst props = defineProps<{ menuItem: SidebarMenuItem }>()\n\nconst emit = defineEmits<{\n (e: 'closeMenu'): []\n (e: 'toggleWatchMode', item: SidebarMenuItem['item']): void\n (e: 'clearDrafts'): void\n}>()\n\nconst { replace } = useRouter()\nconst {\n activeRouterParams,\n activeWorkspaceCollections,\n activeWorkspaceRequests,\n} = useActiveEntities()\nconst { events, requestMutators } = useWorkspace()\n\nconst editModal = useModal()\nconst deleteModal = useModal()\nconst clearDraftsModal = useModal()\n\n/** Add example */\nconst handleAddExample = () =>\n events.commandPalette.emit({\n commandName: 'Add Example',\n metaData: {\n itemUid: props.menuItem.item?.entity.uid,\n },\n })\n\nconst handleEdit = (newName: string, newIcon?: string) => {\n props.menuItem.item?.edit(newName, newIcon)\n editModal.hide()\n}\n\n/** Delete with redirect for both requests and requestExamples */\nconst handleItemDelete = () => {\n props.menuItem.item?.delete()\n\n if (!activeWorkspaceRequests.value.length) {\n const { request } = createInitialRequest()\n const draftCollection = activeWorkspaceCollections.value.find(\n (collection: Collection) => collection.info?.title === 'Drafts',\n )\n\n if (draftCollection) {\n requestMutators.add(request, draftCollection.uid)\n\n replace({\n name: 'request',\n params: {\n [PathId.Request]: request.uid,\n },\n })\n }\n }\n\n if (\n activeRouterParams.value[PathId.Request] === props.menuItem.item?.entity.uid\n ) {\n replace({\n name: 'request',\n params: {\n [PathId.Request]: 'default',\n },\n })\n }\n\n if (\n activeRouterParams.value[PathId.Examples] ===\n props.menuItem.item?.entity.uid\n ) {\n replace({\n name: 'request',\n params: {\n [PathId.Request]: 'default',\n },\n })\n }\n\n if (activeWorkspaceCollections.value[0]) {\n const firstRequest = activeWorkspaceCollections.value[0].requests[0]\n replace({\n name: 'request',\n params: {\n [PathId.Request]: firstRequest,\n },\n })\n }\n\n deleteModal.hide()\n}\n\n// Manually focus the popup - not pretty but it works\nconst menuRef = ref<typeof ScalarDropdown | null>(null)\nwatch([() => props.menuItem.open, menuRef], ([open]) => {\n if (open && menuRef.value?.$parent?.$el) {\n menuRef.value.$parent.$el.focus()\n }\n})\n\n// Close menu on click because headless doesn't seem to work\nconst globalClickListener = () => props.menuItem.open && emit('closeMenu')\nonMounted(() => window.addEventListener('click', globalClickListener))\nonBeforeUnmount(() => window.removeEventListener('click', globalClickListener))\n\nconst toggleWatchMode = () => {\n emit('toggleWatchMode', props.menuItem.item)\n}\n\nconst handleClearDrafts = () => {\n emit('clearDrafts')\n clearDraftsModal.hide()\n}\n\nconst isDraftsMenuItem = computed(() => {\n return props.menuItem.item?.title === 'Drafts'\n})\n</script>\n\n<template>\n <ScalarFloating\n v-if=\"menuItem.targetRef && menuItem.open\"\n placement=\"right-start\"\n :target=\"menuItem.targetRef\"\n teleport>\n <template #floating>\n <ScalarDropdownMenu @keydown.escape=\"$emit('closeMenu')\">\n <!-- Add example -->\n <ScalarDropdownButton\n v-if=\"menuItem.item?.entity.type === 'request'\"\n class=\"flex items-center gap-2\"\n @click=\"handleAddExample\">\n <ScalarIcon\n class=\"inline-flex\"\n icon=\"Example\"\n size=\"md\"\n thickness=\"1.5\" />\n <span>Add Example</span>\n </ScalarDropdownButton>\n\n <!-- Rename -->\n <ScalarDropdownButton\n v-if=\"!isDraftsMenuItem\"\n ref=\"menuRef\"\n class=\"flex items-center gap-2\"\n @click=\"editModal.show()\">\n <ScalarIcon\n class=\"inline-flex\"\n icon=\"Edit\"\n size=\"md\"\n thickness=\"1.5\" />\n <span>\n <template v-if=\"menuItem.item?.entity.type === 'collection'\">\n Edit\n </template>\n <template v-else> Rename </template>\n </span>\n </ScalarDropdownButton>\n\n <!-- Duplicate -->\n <!-- <ScalarDropdownButton\n class=\"flex items-center !gap-2\"\n @click=\"handleItemDuplicate\">\n <ScalarIcon\n class=\"inline-flex\"\n thickness=\"1.5\"\n icon=\"Duplicate\"\n size=\"sm\" />\n <span>Duplicate</span>\n </ScalarDropdownButton>\n <ScalarDropdownDivider /> -->\n\n <!-- Watch -->\n <ScalarDropdownButton\n v-if=\"menuItem.item?.documentUrl\"\n ref=\"menuRef\"\n class=\"flex items-center gap-2\"\n @click=\"toggleWatchMode\">\n <ScalarIcon\n class=\"inline-flex\"\n :icon=\"menuItem.item?.watchMode ? 'Unwatch' : 'Watch'\"\n size=\"md\"\n thickness=\"1.5\" />\n <span>\n {{\n menuItem.item?.watchMode\n ? 'Disable Watch Mode'\n : 'Enable Watch Mode'\n }}\n </span>\n </ScalarDropdownButton>\n\n <!-- Delete -->\n <ScalarDropdownButton\n v-if=\"!isDraftsMenuItem\"\n class=\"flex items-center gap-2\"\n @click=\"deleteModal.show()\">\n <ScalarIcon\n class=\"inline-flex\"\n icon=\"Delete\"\n size=\"md\"\n thickness=\"1.5\" />\n <span>Delete</span>\n </ScalarDropdownButton>\n\n <!-- Clear Drafts -->\n <ScalarDropdownButton\n v-if=\"isDraftsMenuItem\"\n class=\"flex items-center gap-2\"\n @click=\"clearDraftsModal.show()\">\n <ScalarIcon\n class=\"inline-flex\"\n icon=\"Delete\"\n size=\"md\"\n thickness=\"1.5\" />\n <span>Clear Drafts</span>\n </ScalarDropdownButton>\n </ScalarDropdownMenu>\n </template>\n </ScalarFloating>\n\n <!-- Modals -->\n <ScalarModal\n :size=\"'xxs'\"\n :state=\"deleteModal\"\n :title=\"`Delete ${menuItem.item?.resourceTitle}`\">\n <DeleteSidebarListElement\n :variableName=\"menuItem.item?.title ?? ''\"\n :warningMessage=\"menuItem.item?.warning\"\n @close=\"deleteModal.hide()\"\n @delete=\"handleItemDelete\" />\n </ScalarModal>\n <ScalarModal\n :size=\"'xxs'\"\n :state=\"editModal\"\n :title=\"`Edit ${menuItem.item?.resourceTitle}`\">\n <EditSidebarListCollection\n v-if=\"menuItem.item?.resourceTitle === 'Collection'\"\n :icon=\"menuItem.item?.icon || 'interface-content-folder'\"\n :name=\"menuItem.item?.title\"\n @close=\"editModal.hide()\"\n @edit=\"handleEdit\" />\n <EditSidebarListElement\n v-else\n :name=\"menuItem.item?.title ?? ''\"\n @close=\"editModal.hide()\"\n @edit=\"handleEdit\" />\n </ScalarModal>\n <ScalarModal\n :size=\"'xxs'\"\n :state=\"clearDraftsModal\"\n :title=\"'Clear Drafts'\">\n <DeleteSidebarListElement\n :variableName=\"'All Drafts'\"\n :warningMessage=\"'This action will clear all drafts. This cannot be undone.'\"\n @close=\"clearDraftsModal.hide()\"\n @delete=\"handleClearDrafts\" />\n </ScalarModal>\n</template>\n<style scoped>\n.ellipsis-position {\n transform: translate3d(calc(-100% - 4.5px), 0, 0);\n}\n</style>\n","<script setup lang=\"ts\">\nimport {\n ScalarDropdownButton,\n ScalarDropdownMenu,\n ScalarFloating,\n ScalarIcon,\n ScalarModal,\n useModal,\n type ScalarDropdown,\n} from '@scalar/components'\nimport type { Collection } from '@scalar/oas-utils/entities/spec'\nimport { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'\nimport { useRouter } from 'vue-router'\n\nimport DeleteSidebarListElement from '@/components/Sidebar/Actions/DeleteSidebarListElement.vue'\nimport EditSidebarListCollection from '@/components/Sidebar/Actions/EditSidebarListCollection.vue'\nimport EditSidebarListElement from '@/components/Sidebar/Actions/EditSidebarListElement.vue'\nimport { PathId } from '@/routes'\nimport { useWorkspace } from '@/store'\nimport { useActiveEntities } from '@/store/active-entities'\nimport { createInitialRequest } from '@/store/requests'\nimport type { SidebarMenuItem } from '@/views/Request/types'\n\nconst props = defineProps<{ menuItem: SidebarMenuItem }>()\n\nconst emit = defineEmits<{\n (e: 'closeMenu'): []\n (e: 'toggleWatchMode', item: SidebarMenuItem['item']): void\n (e: 'clearDrafts'): void\n}>()\n\nconst { replace } = useRouter()\nconst {\n activeRouterParams,\n activeWorkspaceCollections,\n activeWorkspaceRequests,\n} = useActiveEntities()\nconst { events, requestMutators } = useWorkspace()\n\nconst editModal = useModal()\nconst deleteModal = useModal()\nconst clearDraftsModal = useModal()\n\n/** Add example */\nconst handleAddExample = () =>\n events.commandPalette.emit({\n commandName: 'Add Example',\n metaData: {\n itemUid: props.menuItem.item?.entity.uid,\n },\n })\n\nconst handleEdit = (newName: string, newIcon?: string) => {\n props.menuItem.item?.edit(newName, newIcon)\n editModal.hide()\n}\n\n/** Delete with redirect for both requests and requestExamples */\nconst handleItemDelete = () => {\n props.menuItem.item?.delete()\n\n if (!activeWorkspaceRequests.value.length) {\n const { request } = createInitialRequest()\n const draftCollection = activeWorkspaceCollections.value.find(\n (collection: Collection) => collection.info?.title === 'Drafts',\n )\n\n if (draftCollection) {\n requestMutators.add(request, draftCollection.uid)\n\n replace({\n name: 'request',\n params: {\n [PathId.Request]: request.uid,\n },\n })\n }\n }\n\n if (\n activeRouterParams.value[PathId.Request] === props.menuItem.item?.entity.uid\n ) {\n replace({\n name: 'request',\n params: {\n [PathId.Request]: 'default',\n },\n })\n }\n\n if (\n activeRouterParams.value[PathId.Examples] ===\n props.menuItem.item?.entity.uid\n ) {\n replace({\n name: 'request',\n params: {\n [PathId.Request]: 'default',\n },\n })\n }\n\n if (activeWorkspaceCollections.value[0]) {\n const firstRequest = activeWorkspaceCollections.value[0].requests[0]\n replace({\n name: 'request',\n params: {\n [PathId.Request]: firstRequest,\n },\n })\n }\n\n deleteModal.hide()\n}\n\n// Manually focus the popup - not pretty but it works\nconst menuRef = ref<typeof ScalarDropdown | null>(null)\nwatch([() => props.menuItem.open, menuRef], ([open]) => {\n if (open && menuRef.value?.$parent?.$el) {\n menuRef.value.$parent.$el.focus()\n }\n})\n\n// Close menu on click because headless doesn't seem to work\nconst globalClickListener = () => props.menuItem.open && emit('closeMenu')\nonMounted(() => window.addEventListener('click', globalClickListener))\nonBeforeUnmount(() => window.removeEventListener('click', globalClickListener))\n\nconst toggleWatchMode = () => {\n emit('toggleWatchMode', props.menuItem.item)\n}\n\nconst handleClearDrafts = () => {\n emit('clearDrafts')\n clearDraftsModal.hide()\n}\n\nconst isDraftsMenuItem = computed(() => {\n return props.menuItem.item?.title === 'Drafts'\n})\n</script>\n\n<template>\n <ScalarFloating\n v-if=\"menuItem.targetRef && menuItem.open\"\n placement=\"right-start\"\n :target=\"menuItem.targetRef\"\n teleport>\n <template #floating>\n <ScalarDropdownMenu @keydown.escape=\"$emit('closeMenu')\">\n <!-- Add example -->\n <ScalarDropdownButton\n v-if=\"menuItem.item?.entity.type === 'request'\"\n class=\"flex items-center gap-2\"\n @click=\"handleAddExample\">\n <ScalarIcon\n class=\"inline-flex\"\n icon=\"Example\"\n size=\"md\"\n thickness=\"1.5\" />\n <span>Add Example</span>\n </ScalarDropdownButton>\n\n <!-- Rename -->\n <ScalarDropdownButton\n v-if=\"!isDraftsMenuItem\"\n ref=\"menuRef\"\n class=\"flex items-center gap-2\"\n @click=\"editModal.show()\">\n <ScalarIcon\n class=\"inline-flex\"\n icon=\"Edit\"\n size=\"md\"\n thickness=\"1.5\" />\n <span>\n <template v-if=\"menuItem.item?.entity.type === 'collection'\">\n Edit\n </template>\n <template v-else> Rename </template>\n </span>\n </ScalarDropdownButton>\n\n <!-- Duplicate -->\n <!-- <ScalarDropdownButton\n class=\"flex items-center !gap-2\"\n @click=\"handleItemDuplicate\">\n <ScalarIcon\n class=\"inline-flex\"\n thickness=\"1.5\"\n icon=\"Duplicate\"\n size=\"sm\" />\n <span>Duplicate</span>\n </ScalarDropdownButton>\n <ScalarDropdownDivider /> -->\n\n <!-- Watch -->\n <ScalarDropdownButton\n v-if=\"menuItem.item?.documentUrl\"\n ref=\"menuRef\"\n class=\"flex items-center gap-2\"\n @click=\"toggleWatchMode\">\n <ScalarIcon\n class=\"inline-flex\"\n :icon=\"menuItem.item?.watchMode ? 'Unwatch' : 'Watch'\"\n size=\"md\"\n thickness=\"1.5\" />\n <span>\n {{\n menuItem.item?.watchMode\n ? 'Disable Watch Mode'\n : 'Enable Watch Mode'\n }}\n </span>\n </ScalarDropdownButton>\n\n <!-- Delete -->\n <ScalarDropdownButton\n v-if=\"!isDraftsMenuItem\"\n class=\"flex items-center gap-2\"\n @click=\"deleteModal.show()\">\n <ScalarIcon\n class=\"inline-flex\"\n icon=\"Delete\"\n size=\"md\"\n thickness=\"1.5\" />\n <span>Delete</span>\n </ScalarDropdownButton>\n\n <!-- Clear Drafts -->\n <ScalarDropdownButton\n v-if=\"isDraftsMenuItem\"\n class=\"flex items-center gap-2\"\n @click=\"clearDraftsModal.show()\">\n <ScalarIcon\n class=\"inline-flex\"\n icon=\"Delete\"\n size=\"md\"\n thickness=\"1.5\" />\n <span>Clear Drafts</span>\n </ScalarDropdownButton>\n </ScalarDropdownMenu>\n </template>\n </ScalarFloating>\n\n <!-- Modals -->\n <ScalarModal\n :size=\"'xxs'\"\n :state=\"deleteModal\"\n :title=\"`Delete ${menuItem.item?.resourceTitle}`\">\n <DeleteSidebarListElement\n :variableName=\"menuItem.item?.title ?? ''\"\n :warningMessage=\"menuItem.item?.warning\"\n @close=\"deleteModal.hide()\"\n @delete=\"handleItemDelete\" />\n </ScalarModal>\n <ScalarModal\n :size=\"'xxs'\"\n :state=\"editModal\"\n :title=\"`Edit ${menuItem.item?.resourceTitle}`\">\n <EditSidebarListCollection\n v-if=\"menuItem.item?.resourceTitle === 'Collection'\"\n :icon=\"menuItem.item?.icon || 'interface-content-folder'\"\n :name=\"menuItem.item?.title\"\n @close=\"editModal.hide()\"\n @edit=\"handleEdit\" />\n <EditSidebarListElement\n v-else\n :name=\"menuItem.item?.title ?? ''\"\n @close=\"editModal.hide()\"\n @edit=\"handleEdit\" />\n </ScalarModal>\n <ScalarModal\n :size=\"'xxs'\"\n :state=\"clearDraftsModal\"\n :title=\"'Clear Drafts'\">\n <DeleteSidebarListElement\n :variableName=\"'All Drafts'\"\n :warningMessage=\"'This action will clear all drafts. This cannot be undone.'\"\n @close=\"clearDraftsModal.hide()\"\n @delete=\"handleClearDrafts\" />\n </ScalarModal>\n</template>\n<style scoped>\n.ellipsis-position {\n transform: translate3d(calc(-100% - 4.5px), 0, 0);\n}\n</style>\n","import type { Collection, Operation } from '@scalar/oas-utils/entities/spec'\n\n/**\n * Checks if the user gets the getting started state displayed\n */\nexport const isGettingStarted = (\n activeWorkspaceCollections: Collection[],\n activeWorkspaceRequests: Operation['uid'][],\n requests: Record<string, any>,\n) => {\n const draftCollection = activeWorkspaceCollections.find((collection) => collection.info?.title === 'Drafts')\n const hasSingleRequest = activeWorkspaceRequests.length === 1\n\n if (!activeWorkspaceRequests[0]) {\n return false\n }\n const isDraftsRequest = draftCollection?.requests.includes(activeWorkspaceRequests[0])\n\n if (!isDraftsRequest) {\n return false\n }\n const isRenamed = requests[draftCollection?.requests[0] ?? '']?.summary !== 'My First Request'\n\n return hasSingleRequest && isDraftsRequest && !isRenamed\n}\n","<script setup lang=\"ts\">\nimport {\n ScalarButton,\n ScalarIcon,\n ScalarSidebarGroupToggle,\n ScalarTooltip,\n} from '@scalar/components'\nimport {\n Draggable,\n type DraggableProps,\n type DraggingItem,\n type HoveredItem,\n} from '@scalar/draggable'\nimport type { Collection, Request } from '@scalar/oas-utils/entities/spec'\nimport { shouldIgnoreEntity } from '@scalar/oas-utils/helpers'\nimport { computed, nextTick, ref } from 'vue'\nimport { RouterLink, useRouter } from 'vue-router'\n\nimport { HttpMethod } from '@/components/HttpMethod'\nimport { useLayout } from '@/hooks/useLayout'\nimport { useSidebar } from '@/hooks/useSidebar'\nimport { getModifiers } from '@/libs'\nimport { PathId } from '@/routes'\nimport { useWorkspace } from '@/store'\nimport { useActiveEntities } from '@/store/active-entities'\nimport type { SidebarItem, SidebarMenuItem } from '@/views/Request/types'\n\nconst {\n isDraggable = false,\n isDroppable = false,\n parentUids,\n uid,\n menuItem,\n} = defineProps<{\n /**\n * Toggle dragging on and off\n *\n * @default false\n */\n isDraggable?: boolean\n /**\n * Prevents items from being hovered and dropped into\n *\n * @default false\n */\n isDroppable?: DraggableProps['isDroppable']\n /** Both indicate the level and provide a way to traverse upwards */\n parentUids: string[]\n /** uid of a Collection, Tag, Request or RequestExample */\n uid: string\n /** To keep track of the menu being open */\n menuItem: SidebarMenuItem\n}>()\n\nconst emit = defineEmits<{\n onDragEnd: [draggingItem: DraggingItem, hoveredItem: HoveredItem]\n newTab: [name: string, uid: string]\n openMenu: [menuItem: SidebarMenuItem]\n}>()\n\ndefineSlots<{\n leftIcon(): void\n}>()\n\nconst { activeCollection, activeRequest, activeRouterParams, activeWorkspace } =\n useActiveEntities()\nconst {\n collections,\n tags,\n requests,\n requestExamples,\n collectionMutators,\n tagMutators,\n requestMutators,\n requestExampleMutators,\n events,\n} = useWorkspace()\nconst router = useRouter()\nconst { collapsedSidebarFolders, toggleSidebarFolder } = useSidebar()\nconst { layout } = useLayout()\n\n/** Normalize properties across different types for easy consumption */\nconst item = computed<SidebarItem>(() => {\n const collection = collections[uid]\n const tag = tags[uid]\n const request = requests[uid]\n const requestExample = requestExamples[uid]\n\n if (collection) {\n return {\n title: collection.info?.title || 'Untitled Collection',\n entity: collection,\n resourceTitle: 'Collection',\n children: collection.children,\n icon: collection['x-scalar-icon'],\n documentUrl: collection.documentUrl,\n watchMode: collection.watchMode,\n to:\n collection.uid && collection?.info?.title !== 'Drafts'\n ? {\n name: 'collection',\n params: {\n [PathId.Workspace]: activeWorkspace.value?.uid,\n [PathId.Collection]: collection.uid,\n },\n }\n : undefined,\n warning:\n \"This cannot be undone. You're about to delete the collection and all folders and requests inside it.\",\n edit: (name: string, icon?: string) => {\n collectionMutators.edit(collection.uid, 'info.title', name)\n if (icon) {\n collectionMutators.edit(collection.uid, 'x-scalar-icon', icon)\n }\n },\n delete: () => {\n if (activeWorkspace.value) {\n collectionMutators.delete(collection, activeWorkspace.value)\n }\n },\n }\n }\n\n if (tag) {\n return {\n title: tag.name,\n entity: tag,\n resourceTitle: 'Tag',\n children: tag.children,\n warning:\n \"This cannot be undone. You're about to delete the tag and all requests inside it\",\n edit: (name: string) => tagMutators.edit(tag.uid, 'name', name),\n delete: () =>\n parentUids[0] &&\n tagMutators.delete(tag, parentUids[0] as Collection['uid']),\n }\n }\n\n if (request) {\n return {\n title: request.summary ?? request.path,\n to: {\n name: 'request',\n params: {\n workspace: activeWorkspace.value?.uid,\n request: request.uid,\n },\n },\n method: request.method,\n entity: request,\n resourceTitle: 'Request',\n warning: \"This cannot be undone. You're about to delete the request.\",\n children: request.examples.slice(1),\n edit: (name: string) =>\n requestMutators.edit(request.uid, 'summary', name),\n delete: () =>\n parentUids[0] &&\n requestMutators.delete(request, parentUids[0] as Collection['uid']),\n }\n }\n\n if (requestExample?.requestUid) {\n return {\n title: requestExample.name,\n to: {\n name: 'request.examples',\n params: {\n workspace: activeWorkspace.value?.uid,\n request: requestExample.requestUid,\n examples: requestExample.uid,\n },\n },\n method: requests[requestExample.requestUid]?.method,\n entity: requestExample,\n resourceTitle: 'Example',\n warning:\n \"This cannot be undone. You're about to delete the example from the request.\",\n children: [],\n edit: (name: string) =>\n requestExampleMutators.edit(requestExample.uid, 'name', name),\n delete: () => requestExampleMutators.delete(requestExample),\n }\n }\n\n // Catch all item which we should never see\n return {\n title: 'Unknown',\n entity: {\n uid: '',\n type: 'unknown',\n },\n resourceTitle: 'Unknown',\n children: [],\n edit: () => null,\n delete: () => null,\n } satisfies SidebarItem\n})\n\n/** Checks to see if it is a draft collection with the title of Drafts */\nconst isDraftCollection = computed(\n () =>\n item.value.entity.type === 'collection' && item.value.title === 'Drafts',\n)\n\nconst highlightClasses = 'hover:bg-sidebar-b-active indent-padding-left'\n\n/** Due to the nesting, we need a dynamic left offset for hover and active backgrounds */\nconst leftOffset = computed(() => {\n if (!parentUids.length) {\n return '12px'\n }\n if (layout === 'modal') {\n return `${(parentUids.length - 1) * 12}px`\n }\n return `${parentUids.length * 12}px`\n})\nconst paddingOffset = computed(() => {\n if (!parentUids.length) {\n return '0px'\n }\n if (layout === 'modal') {\n return `${(parentUids.length - 1) * 12}px`\n }\n return `${parentUids.length * 12}px`\n})\n\n/**\n * Show folders if they are open,\n * show examples if there are more than one and the request is active\n */\nconst showChildren = computed(\n () =>\n collapsedSidebarFolders[uid] ||\n (activeRequest.value?.uid === uid &&\n (item.value.entity as Request).examples.length > 1),\n)\n\n/** Since we have exact routing, we should check if the default request is active */\nconst isDefaultActive = computed(\n () =>\n typeof router.currentRoute.value.name === 'string' &&\n router.currentRoute.value.name.startsWith('request') &&\n activeRouterParams.value[PathId.Request] === 'default' &&\n activeRequest.value?.uid === uid,\n)\n\n/** The draggable component */\nconst draggableRef = ref<{\n draggingItem: DraggingItem\n hoveredItem: HoveredItem\n} | null>(null)\n\n/** Calculate offsets which change a little depending on whats being dragged and hovered over */\nconst getDraggableOffsets = computed(() => {\n let ceiling = 0.5\n let floor = 0.5\n\n if (!draggableRef.value) {\n return { ceiling, floor }\n }\n const { draggingItem } = draggableRef.value\n\n // If hovered over is collection && dragging is not a collection\n if (\n !collections[draggingItem?.id] &&\n item.value.entity.type === 'collection'\n ) {\n ceiling = 1\n floor = 0\n }\n // Has children but is not a request or a collection\n else if (item.value.entity.type === 'tag') {\n ceiling = 0.8\n floor = 0.2\n }\n\n return { ceiling, floor }\n})\n\n/** Guard to check if an element is able to be dropped on */\nconst _isDroppable = (draggingItem: DraggingItem, hoveredItem: HoveredItem) => {\n // Cannot drop in read only mode\n if (layout === 'modal') {\n return false\n }\n // RequestExamples cannot be dropped on\n if (requestExamples[hoveredItem.id]) {\n return false\n }\n // Collection cannot be dropped into another collection\n if (collections[draggingItem.id]) {\n return false\n }\n\n return true\n}\n\nconst handleNavigation = (event: KeyboardEvent, _item: SidebarItem) => {\n if (event) {\n const modifier = getModifiers(['default'])\n const isModifierPressed = modifier.some((key) => event[key])\n\n if (isModifierPressed) {\n emit('newTab', _item.title || '', _item.entity.uid)\n } else if (_item.to) {\n router.push(_item.to)\n }\n\n nextTick(() => events.focusAddressBar.emit())\n }\n}\n\nfunction addRequest(entityUid: string) {\n const collectionUid = parentUids[0]\n ? collections[parentUids[0]]?.uid || ''\n : entityUid\n\n // If the entity is a tag, add the tag name to the request\n const requestData =\n parentUids[0] && tags[entityUid]?.name\n ? { tags: [tags[entityUid].name] }\n : {}\n\n const newRequest = requestMutators.add(\n requestData,\n collectionUid as Collection['uid'],\n )\n\n if (newRequest) {\n router.push({\n name: 'request',\n params: {\n workspace: activeWorkspace.value?.uid,\n request: newRequest.uid,\n },\n })\n\n // Focus the address bar\n events.hotKeys.emit({\n focusAddressBar: new KeyboardEvent('keydown', { key: 'l' }),\n })\n }\n}\n\nconst watchIconColor = computed(() => {\n const { uid: _uid, watchModeStatus } = activeCollection.value || {}\n\n if (_uid !== item.value.entity.uid) {\n return 'text-c-3'\n }\n if (watchModeStatus === 'WATCHING') {\n return 'text-c-1'\n }\n if (watchModeStatus === 'ERROR') {\n return 'text-red'\n }\n return 'text-c-3'\n})\n\nconst hasDraftRequests = computed(() => {\n return (\n item.value.title === 'Drafts' &&\n layout !== 'modal' &&\n item.value.children.length > 0\n )\n})\n\n/**\n * Check if the item should be shown.\n * This is used to hide items that are marked as hidden/internal.\n */\nconst shouldShowItem = computed(() => {\n const request = requests[uid]\n if (request) {\n return !shouldIgnoreEntity(request)\n }\n\n const tag = tags[uid]\n if (tag) {\n return !shouldIgnoreEntity(tag)\n }\n\n return true\n})\n</script>\n\n<template>\n <li\n v-if=\"shouldShowItem\"\n class=\"relative flex flex-row\"\n :class=\"[\n (layout === 'modal' && parentUids.length > 1) ||\n (layout !== 'modal' && parentUids.length)\n ? 'before:bg-border indent-border-line-offset mb-[.5px] before:pointer-events-none before:absolute before:top-0 before:left-[calc(.75rem_+_.5px)] before:z-1 before:h-[calc(100%_+_.5px)] before:w-[.5px] last:mb-0 last:before:h-full'\n : '',\n ]\">\n <Draggable\n :id=\"item.entity.uid\"\n ref=\"draggableRef\"\n :ceiling=\"getDraggableOffsets.ceiling\"\n class=\"gap-1/2 flex flex-1 flex-col text-base/5\"\n :floor=\"getDraggableOffsets.floor\"\n :isDraggable=\"isDraggable\"\n :isDroppable=\"isDroppable\"\n :parentIds=\"parentUids\"\n @onDragEnd=\"(...args) => $emit('onDragEnd', ...args)\">\n <!-- Request -->\n <RouterLink\n v-if=\"\n (item.entity.type === 'request' ||\n item.entity.type === 'requestExample') &&\n item.to\n \"\n v-slot=\"{ isExactActive }\"\n class=\"group no-underline\"\n :to=\"item.to\"\n @click.prevent=\"\n (event: KeyboardEvent) => handleNavigation(event, item)\n \">\n <div\n class=\"relative flex min-h-8 w-full cursor-pointer flex-row items-start justify-between gap-0.5 rounded py-1.5 pr-2\"\n :class=\"[\n highlightClasses,\n isExactActive || isDefaultActive\n ? 'bg-sidebar-b-active text-sidebar-c-active font-medium transition-none'\n : 'text-sidebar-c-2',\n ]\">\n <span class=\"line-clamp-1 w-full pl-2 break-all\">\n {{ item.title || 'Untitled' }}\n </span>\n <div class=\"flex flex-row items-center gap-1\">\n <!-- Menu -->\n <div class=\"relative\">\n <ScalarButton\n v-if=\"layout !== 'modal'\"\n class=\"hover:bg-b-3 hidden aspect-square h-fit px-0.5 py-0 opacity-0 group-hover:flex group-hover:opacity-100 group-focus-visible:opacity-100 group-has-[:focus-visible]:opacity-100\"\n :class=\"{\n flex:\n menuItem?.item?.entity.uid === item.entity.uid &&\n menuItem.open,\n }\"\n size=\"sm\"\n type=\"button\"\n variant=\"ghost\"\n @click.stop.prevent=\"\n (ev: MouseEvent) =>\n $emit('openMenu', {\n item,\n parentUids,\n targetRef: ev.currentTarget as HTMLButtonElement,\n open: !menuItem.open,\n })\n \">\n <ScalarIcon\n icon=\"Ellipses\"\n size=\"md\" />\n </ScalarButton>\n </div>\n <span class=\"flex items-start\">\n &hairsp;\n <span class=\"sr-only\">HTTP Method:</span>\n <HttpMethod\n v-if=\"item.method\"\n class=\"font-bold\"\n :method=\"item.method\" />\n </span>\n </div>\n </div>\n </RouterLink>\n\n <!-- Collection -->\n <RouterLink\n v-else-if=\"\n (layout !== 'modal' || parentUids.length) &&\n item.entity.type === 'collection' &&\n item.to\n \"\n :aria-expanded=\"Boolean(collapsedSidebarFolders[item.entity.uid])\"\n class=\"hover:bg-b-2 group relative flex w-full flex-row justify-start gap-1.5 rounded p-1.5 no-underline focus-visible:z-10\"\n :class=\"[\n highlightClasses,\n {\n 'bg-sidebar-b-active text-sidebar-c-active transition-none':\n typeof router.currentRoute.value.name === 'string' &&\n router.currentRoute.value.name.startsWith('collection') &&\n router.currentRoute.value.params[PathId.Collection] ===\n item.entity.uid,\n 'text-c-2': item.title === 'Untitled Collection',\n },\n ]\"\n :to=\"item.to\">\n <span\n class=\"flex h-5 max-w-[14px] shrink-0 items-center justify-center\">\n <slot name=\"leftIcon\" />\n &hairsp;\n </span>\n <div class=\"flex flex-1 flex-row justify-between font-medium\">\n <span class=\"line-clamp-1 w-full text-left break-all\">\n {{ item.title }}\n </span>\n <div class=\"relative flex h-fit items-center justify-end gap-0.5\">\n <div\n class=\"items-center gap-px opacity-0 group-hover:flex group-hover:opacity-100 group-focus-visible:opacity-100 group-has-[:focus-visible]:opacity-100\"\n :class=\"{\n flex: menuItem.open,\n hidden:\n !menuItem.open ||\n menuItem.item?.entity.uid !== item.entity.uid,\n }\">\n <ScalarButton\n v-if=\"\n (layout !== 'modal' && !isDraftCollection) ||\n (isDraftCollection && hasDraftRequests)\n \"\n class=\"hover:bg-b-3 hover:text-c-1 aspect-square h-fit px-0.5 py-0 group-focus-visible:opacity-100 group-has-[:focus-visible]:opacity-100\"\n size=\"sm\"\n variant=\"ghost\"\n @click.stop.prevent=\"\n (ev: MouseEvent) =>\n $emit('openMenu', {\n item,\n parentUids,\n targetRef: (ev.currentTarget as HTMLElement)\n ?.parentNode as HTMLButtonElement,\n open: true,\n })\n \">\n <ScalarIcon\n icon=\"Ellipses\"\n size=\"md\" />\n </ScalarButton>\n <ScalarButton\n v-if=\"layout !== 'modal'\"\n class=\"hover:bg-b-3 hover:text-c-1 aspect-square h-fit px-0.5 py-0 group-focus-visible:opacity-100 group-has-[:focus-visible]:opacity-100\"\n size=\"sm\"\n variant=\"ghost\"\n @click.stop.prevent=\"addRequest(item.entity.uid)\">\n <ScalarIcon\n icon=\"Add\"\n size=\"md\"\n thickness=\"2\" />\n </ScalarButton>\n </div>\n <ScalarTooltip\n v-if=\"item.watchMode\"\n :content=\"`Watching: ${item.documentUrl}`\"\n :offset=\"12\"\n placement=\"right\">\n <button\n class=\"flex items-center justify-center\"\n type=\"button\">\n <ScalarIcon\n class=\"ml-0.5 text-sm\"\n :class=\"watchIconColor\"\n icon=\"Watch\"\n size=\"md\"\n thickness=\"2\" />\n </button>\n </ScalarTooltip>\n <span\n class=\"flex cursor-pointer items-center justify-center\"\n @click.stop.prevent=\"toggleSidebarFolder(item.entity.uid)\">\n <ScalarSidebarGroupToggle\n class=\"text-c-3 hover:text-c-1 shrink-0\"\n :open=\"Boolean(collapsedSidebarFolders[item.entity.uid])\" />\n </span>\n </div>\n </div>\n </RouterLink>\n\n <!-- Tag -->\n <button\n v-else-if=\"layout !== 'modal' || parentUids.length\"\n :aria-expanded=\"Boolean(collapsedSidebarFolders[item.entity.uid])\"\n class=\"hover:bg-b-2 group relative flex w-full flex-row justify-start gap-1.5 rounded p-1.5 focus-visible:z-10\"\n :class=\"[highlightClasses]\"\n type=\"button\"\n @click=\"toggleSidebarFolder(item.entity.uid)\">\n <span\n class=\"flex h-5 max-w-[14px] shrink-0 items-center justify-center\">\n <slot name=\"leftIcon\" />\n &hairsp;\n </span>\n <div class=\"flex flex-1 flex-row justify-between\">\n <span class=\"line-clamp-1 w-full text-left font-medium break-all\">\n {{ item.title }}\n </span>\n <div class=\"relative flex h-fit items-center justify-end gap-0.5\">\n <div\n class=\"items-center gap-px opacity-0 group-hover:flex group-hover:opacity-100 group-focus-visible:opacity-100 group-has-[:focus-visible]:opacity-100\"\n :class=\"{\n flex: menuItem.open,\n hidden:\n !menuItem.open ||\n menuItem.item?.entity.uid !== item.entity.uid,\n }\">\n <ScalarButton\n v-if=\"\n (layout !== 'modal' && !isDraftCollection) ||\n (isDraftCollection && hasDraftRequests)\n \"\n class=\"hover:bg-b-3 hover:text-c-1 aspect-square h-fit px-0.5 py-0 group-focus-visible:opacity-100 group-has-[:focus-visible]:opacity-100\"\n size=\"sm\"\n variant=\"ghost\"\n @click.stop.prevent=\"\n (ev: MouseEvent) =>\n $emit('openMenu', {\n item,\n parentUids,\n targetRef: (ev.currentTarget as HTMLElement)\n ?.parentNode as HTMLButtonElement,\n open: true,\n })\n \">\n <ScalarIcon\n icon=\"Ellipses\"\n size=\"md\" />\n </ScalarButton>\n <ScalarButton\n v-if=\"layout !== 'modal'\"\n class=\"hover:bg-b-3 hover:text-c-1 aspect-square h-fit px-0.5 py-0 group-focus-visible:opacity-100 group-has-[:focus-visible]:opacity-100\"\n size=\"sm\"\n variant=\"ghost\"\n @click.stop.prevent=\"addRequest(item.entity.uid)\">\n <ScalarIcon\n icon=\"Add\"\n size=\"md\"\n thickness=\"2\" />\n </ScalarButton>\n </div>\n <ScalarTooltip\n v-if=\"item.watchMode\"\n content=\"Watching: {{ item.documentUrl }}\"\n :offset=\"12\"\n placement=\"right\">\n <button\n class=\"flex items-center justify-center\"\n type=\"button\">\n <ScalarIcon\n class=\"ml-0.5 text-sm\"\n :class=\"watchIconColor\"\n icon=\"Watch\"\n size=\"md\"\n thickness=\"2\" />\n </button>\n </ScalarTooltip>\n <span\n class=\"flex cursor-pointer items-center justify-center\"\n @click.stop.prevent=\"toggleSidebarFolder(item.entity.uid)\">\n <ScalarSidebarGroupToggle\n class=\"text-c-3 hover:text-c-1 shrink-0\"\n :open=\"Boolean(collapsedSidebarFolders[item.entity.uid])\" />\n </span>\n </div>\n </div>\n </button>\n\n <!-- Children -->\n <ul v-if=\"showChildren\">\n <!-- We never want to show the first example -->\n <RequestSidebarItem\n v-for=\"childUid in item.children\"\n :key=\"childUid\"\n :isDraggable=\"!requestExamples[childUid]\"\n :isDroppable=\"_isDroppable\"\n :menuItem=\"menuItem\"\n :parentUids=\"[...parentUids, uid]\"\n :uid=\"childUid\"\n @newTab=\"(name, uid) => $emit('newTab', name, uid)\"\n @onDragEnd=\"(...args) => $emit('onDragEnd', ...args)\"\n @openMenu=\"(item) => $emit('openMenu', item)\" />\n <ScalarButton\n v-if=\"item.children.length === 0\"\n class=\"text-c-1 hover:bg-b-2 flex h-8 w-full justify-start gap-1.5 py-0 text-xs\"\n :class=\"parentUids.length ? 'pl-9' : ''\"\n variant=\"ghost\"\n @click=\"addRequest(item.entity.uid)\">\n <ScalarIcon\n icon=\"Add\"\n size=\"sm\" />\n <span>Add Request</span>\n </ScalarButton>\n </ul>\n </Draggable>\n </li>\n</template>\n<style>\n@import '@scalar/draggable/style.css';\n</style>\n<style scoped>\n.indent-border-line-offset:before {\n left: v-bind(leftOffset);\n}\n.indent-padding-left {\n padding-left: calc(v-bind(paddingOffset) + 6px);\n}\n.sidebar-folderitem :deep(.ellipsis-position) {\n right: 6px;\n transform: none;\n}\n</style>\n","<script setup lang=\"ts\">\nimport {\n ScalarButton,\n ScalarIcon,\n ScalarSidebarGroupToggle,\n ScalarTooltip,\n} from '@scalar/components'\nimport {\n Draggable,\n type DraggableProps,\n type DraggingItem,\n type HoveredItem,\n} from '@scalar/draggable'\nimport type { Collection, Request } from '@scalar/oas-utils/entities/spec'\nimport { shouldIgnoreEntity } from '@scalar/oas-utils/helpers'\nimport { computed, nextTick, ref } from 'vue'\nimport { RouterLink, useRouter } from 'vue-router'\n\nimport { HttpMethod } from '@/components/HttpMethod'\nimport { useLayout } from '@/hooks/useLayout'\nimport { useSidebar } from '@/hooks/useSidebar'\nimport { getModifiers } from '@/libs'\nimport { PathId } from '@/routes'\nimport { useWorkspace } from '@/store'\nimport { useActiveEntities } from '@/store/active-entities'\nimport type { SidebarItem, SidebarMenuItem } from '@/views/Request/types'\n\nconst {\n isDraggable = false,\n isDroppable = false,\n parentUids,\n uid,\n menuItem,\n} = defineProps<{\n /**\n * Toggle dragging on and off\n *\n * @default false\n */\n isDraggable?: boolean\n /**\n * Prevents items from being hovered and dropped into\n *\n * @default false\n */\n isDroppable?: DraggableProps['isDroppable']\n /** Both indicate the level and provide a way to traverse upwards */\n parentUids: string[]\n /** uid of a Collection, Tag, Request or RequestExample */\n uid: string\n /** To keep track of the menu being open */\n menuItem: SidebarMenuItem\n}>()\n\nconst emit = defineEmits<{\n onDragEnd: [draggingItem: DraggingItem, hoveredItem: HoveredItem]\n newTab: [name: string, uid: string]\n openMenu: [menuItem: SidebarMenuItem]\n}>()\n\ndefineSlots<{\n leftIcon(): void\n}>()\n\nconst { activeCollection, activeRequest, activeRouterParams, activeWorkspace } =\n useActiveEntities()\nconst {\n collections,\n tags,\n requests,\n requestExamples,\n collectionMutators,\n tagMutators,\n requestMutators,\n requestExampleMutators,\n events,\n} = useWorkspace()\nconst router = useRouter()\nconst { collapsedSidebarFolders, toggleSidebarFolder } = useSidebar()\nconst { layout } = useLayout()\n\n/** Normalize properties across different types for easy consumption */\nconst item = computed<SidebarItem>(() => {\n const collection = collections[uid]\n const tag = tags[uid]\n const request = requests[uid]\n const requestExample = requestExamples[uid]\n\n if (collection) {\n return {\n title: collection.info?.title || 'Untitled Collection',\n entity: collection,\n resourceTitle: 'Collection',\n children: collection.children,\n icon: collection['x-scalar-icon'],\n documentUrl: collection.documentUrl,\n watchMode: collection.watchMode,\n to:\n collection.uid && collection?.info?.title !== 'Drafts'\n ? {\n name: 'collection',\n params: {\n [PathId.Workspace]: activeWorkspace.value?.uid,\n [PathId.Collection]: collection.uid,\n },\n }\n : undefined,\n warning:\n \"This cannot be undone. You're about to delete the collection and all folders and requests inside it.\",\n edit: (name: string, icon?: string) => {\n collectionMutators.edit(collection.uid, 'info.title', name)\n if (icon) {\n collectionMutators.edit(collection.uid, 'x-scalar-icon', icon)\n }\n },\n delete: () => {\n if (activeWorkspace.value) {\n collectionMutators.delete(collection, activeWorkspace.value)\n }\n },\n }\n }\n\n if (tag) {\n return {\n title: tag.name,\n entity: tag,\n resourceTitle: 'Tag',\n children: tag.children,\n warning:\n \"This cannot be undone. You're about to delete the tag and all requests inside it\",\n edit: (name: string) => tagMutators.edit(tag.uid, 'name', name),\n delete: () =>\n parentUids[0] &&\n tagMutators.delete(tag, parentUids[0] as Collection['uid']),\n }\n }\n\n if (request) {\n return {\n title: request.summary ?? request.path,\n to: {\n name: 'request',\n params: {\n workspace: activeWorkspace.value?.uid,\n request: request.uid,\n },\n },\n method: request.method,\n entity: request,\n resourceTitle: 'Request',\n warning: \"This cannot be undone. You're about to delete the request.\",\n children: request.examples.slice(1),\n edit: (name: string) =>\n requestMutators.edit(request.uid, 'summary', name),\n delete: () =>\n parentUids[0] &&\n requestMutators.delete(request, parentUids[0] as Collection['uid']),\n }\n }\n\n if (requestExample?.requestUid) {\n return {\n title: requestExample.name,\n to: {\n name: 'request.examples',\n params: {\n workspace: activeWorkspace.value?.uid,\n request: requestExample.requestUid,\n examples: requestExample.uid,\n },\n },\n method: requests[requestExample.requestUid]?.method,\n entity: requestExample,\n resourceTitle: 'Example',\n warning:\n \"This cannot be undone. You're about to delete the example from the request.\",\n children: [],\n edit: (name: string) =>\n requestExampleMutators.edit(requestExample.uid, 'name', name),\n delete: () => requestExampleMutators.delete(requestExample),\n }\n }\n\n // Catch all item which we should never see\n return {\n title: 'Unknown',\n entity: {\n uid: '',\n type: 'unknown',\n },\n resourceTitle: 'Unknown',\n children: [],\n edit: () => null,\n delete: () => null,\n } satisfies SidebarItem\n})\n\n/** Checks to see if it is a draft collection with the title of Drafts */\nconst isDraftCollection = computed(\n () =>\n item.value.entity.type === 'collection' && item.value.title === 'Drafts',\n)\n\nconst highlightClasses = 'hover:bg-sidebar-b-active indent-padding-left'\n\n/** Due to the nesting, we need a dynamic left offset for hover and active backgrounds */\nconst leftOffset = computed(() => {\n if (!parentUids.length) {\n return '12px'\n }\n if (layout === 'modal') {\n return `${(parentUids.length - 1) * 12}px`\n }\n return `${parentUids.length * 12}px`\n})\nconst paddingOffset = computed(() => {\n if (!parentUids.length) {\n return '0px'\n }\n if (layout === 'modal') {\n return `${(parentUids.length - 1) * 12}px`\n }\n return `${parentUids.length * 12}px`\n})\n\n/**\n * Show folders if they are open,\n * show examples if there are more than one and the request is active\n */\nconst showChildren = computed(\n () =>\n collapsedSidebarFolders[uid] ||\n (activeRequest.value?.uid === uid &&\n (item.value.entity as Request).examples.length > 1),\n)\n\n/** Since we have exact routing, we should check if the default request is active */\nconst isDefaultActive = computed(\n () =>\n typeof router.currentRoute.value.name === 'string' &&\n router.currentRoute.value.name.startsWith('request') &&\n activeRouterParams.value[PathId.Request] === 'default' &&\n activeRequest.value?.uid === uid,\n)\n\n/** The draggable component */\nconst draggableRef = ref<{\n draggingItem: DraggingItem\n hoveredItem: HoveredItem\n} | null>(null)\n\n/** Calculate offsets which change a little depending on whats being dragged and hovered over */\nconst getDraggableOffsets = computed(() => {\n let ceiling = 0.5\n let floor = 0.5\n\n if (!draggableRef.value) {\n return { ceiling, floor }\n }\n const { draggingItem } = draggableRef.value\n\n // If hovered over is collection && dragging is not a collection\n if (\n !collections[draggingItem?.id] &&\n item.value.entity.type === 'collection'\n ) {\n ceiling = 1\n floor = 0\n }\n // Has children but is not a request or a collection\n else if (item.value.entity.type === 'tag') {\n ceiling = 0.8\n floor = 0.2\n }\n\n return { ceiling, floor }\n})\n\n/** Guard to check if an element is able to be dropped on */\nconst _isDroppable = (draggingItem: DraggingItem, hoveredItem: HoveredItem) => {\n // Cannot drop in read only mode\n if (layout === 'modal') {\n return false\n }\n // RequestExamples cannot be dropped on\n if (requestExamples[hoveredItem.id]) {\n return false\n }\n // Collection cannot be dropped into another collection\n if (collections[draggingItem.id]) {\n return false\n }\n\n return true\n}\n\nconst handleNavigation = (event: KeyboardEvent, _item: SidebarItem) => {\n if (event) {\n const modifier = getModifiers(['default'])\n const isModifierPressed = modifier.some((key) => event[key])\n\n if (isModifierPressed) {\n emit('newTab', _item.title || '', _item.entity.uid)\n } else if (_item.to) {\n router.push(_item.to)\n }\n\n nextTick(() => events.focusAddressBar.emit())\n }\n}\n\nfunction addRequest(entityUid: string) {\n const collectionUid = parentUids[0]\n ? collections[parentUids[0]]?.uid || ''\n : entityUid\n\n // If the entity is a tag, add the tag name to the request\n const requestData =\n parentUids[0] && tags[entityUid]?.name\n ? { tags: [tags[entityUid].name] }\n : {}\n\n const newRequest = requestMutators.add(\n requestData,\n collectionUid as Collection['uid'],\n )\n\n if (newRequest) {\n router.push({\n name: 'request',\n params: {\n workspace: activeWorkspace.value?.uid,\n request: newRequest.uid,\n },\n })\n\n // Focus the address bar\n events.hotKeys.emit({\n focusAddressBar: new KeyboardEvent('keydown', { key: 'l' }),\n })\n }\n}\n\nconst watchIconColor = computed(() => {\n const { uid: _uid, watchModeStatus } = activeCollection.value || {}\n\n if (_uid !== item.value.entity.uid) {\n return 'text-c-3'\n }\n if (watchModeStatus === 'WATCHING') {\n return 'text-c-1'\n }\n if (watchModeStatus === 'ERROR') {\n return 'text-red'\n }\n return 'text-c-3'\n})\n\nconst hasDraftRequests = computed(() => {\n return (\n item.value.title === 'Drafts' &&\n layout !== 'modal' &&\n item.value.children.length > 0\n )\n})\n\n/**\n * Check if the item should be shown.\n * This is used to hide items that are marked as hidden/internal.\n */\nconst shouldShowItem = computed(() => {\n const request = requests[uid]\n if (request) {\n return !shouldIgnoreEntity(request)\n }\n\n const tag = tags[uid]\n if (tag) {\n return !shouldIgnoreEntity(tag)\n }\n\n return true\n})\n</script>\n\n<template>\n <li\n v-if=\"shouldShowItem\"\n class=\"relative flex flex-row\"\n :class=\"[\n (layout === 'modal' && parentUids.length > 1) ||\n (layout !== 'modal' && parentUids.length)\n ? 'before:bg-border indent-border-line-offset mb-[.5px] before:pointer-events-none before:absolute before:top-0 before:left-[calc(.75rem_+_.5px)] before:z-1 before:h-[calc(100%_+_.5px)] before:w-[.5px] last:mb-0 last:before:h-full'\n : '',\n ]\">\n <Draggable\n :id=\"item.entity.uid\"\n ref=\"draggableRef\"\n :ceiling=\"getDraggableOffsets.ceiling\"\n class=\"gap-1/2 flex flex-1 flex-col text-base/5\"\n :floor=\"getDraggableOffsets.floor\"\n :isDraggable=\"isDraggable\"\n :isDroppable=\"isDroppable\"\n :parentIds=\"parentUids\"\n @onDragEnd=\"(...args) => $emit('onDragEnd', ...args)\">\n <!-- Request -->\n <RouterLink\n v-if=\"\n (item.entity.type === 'request' ||\n item.entity.type === 'requestExample') &&\n item.to\n \"\n v-slot=\"{ isExactActive }\"\n class=\"group no-underline\"\n :to=\"item.to\"\n @click.prevent=\"\n (event: KeyboardEvent) => handleNavigation(event, item)\n \">\n <div\n class=\"relative flex min-h-8 w-full cursor-pointer flex-row items-start justify-between gap-0.5 rounded py-1.5 pr-2\"\n :class=\"[\n highlightClasses,\n isExactActive || isDefaultActive\n ? 'bg-sidebar-b-active text-sidebar-c-active font-medium transition-none'\n : 'text-sidebar-c-2',\n ]\">\n <span class=\"line-clamp-1 w-full pl-2 break-all\">\n {{ item.title || 'Untitled' }}\n </span>\n <div class=\"flex flex-row items-center gap-1\">\n <!-- Menu -->\n <div class=\"relative\">\n <ScalarButton\n v-if=\"layout !== 'modal'\"\n class=\"hover:bg-b-3 hidden aspect-square h-fit px-0.5 py-0 opacity-0 group-hover:flex group-hover:opacity-100 group-focus-visible:opacity-100 group-has-[:focus-visible]:opacity-100\"\n :class=\"{\n flex:\n menuItem?.item?.entity.uid === item.entity.uid &&\n menuItem.open,\n }\"\n size=\"sm\"\n type=\"button\"\n variant=\"ghost\"\n @click.stop.prevent=\"\n (ev: MouseEvent) =>\n $emit('openMenu', {\n item,\n parentUids,\n targetRef: ev.currentTarget as HTMLButtonElement,\n open: !menuItem.open,\n })\n \">\n <ScalarIcon\n icon=\"Ellipses\"\n size=\"md\" />\n </ScalarButton>\n </div>\n <span class=\"flex items-start\">\n &hairsp;\n <span class=\"sr-only\">HTTP Method:</span>\n <HttpMethod\n v-if=\"item.method\"\n class=\"font-bold\"\n :method=\"item.method\" />\n </span>\n </div>\n </div>\n </RouterLink>\n\n <!-- Collection -->\n <RouterLink\n v-else-if=\"\n (layout !== 'modal' || parentUids.length) &&\n item.entity.type === 'collection' &&\n item.to\n \"\n :aria-expanded=\"Boolean(collapsedSidebarFolders[item.entity.uid])\"\n class=\"hover:bg-b-2 group relative flex w-full flex-row justify-start gap-1.5 rounded p-1.5 no-underline focus-visible:z-10\"\n :class=\"[\n highlightClasses,\n {\n 'bg-sidebar-b-active text-sidebar-c-active transition-none':\n typeof router.currentRoute.value.name === 'string' &&\n router.currentRoute.value.name.startsWith('collection') &&\n router.currentRoute.value.params[PathId.Collection] ===\n item.entity.uid,\n 'text-c-2': item.title === 'Untitled Collection',\n },\n ]\"\n :to=\"item.to\">\n <span\n class=\"flex h-5 max-w-[14px] shrink-0 items-center justify-center\">\n <slot name=\"leftIcon\" />\n &hairsp;\n </span>\n <div class=\"flex flex-1 flex-row justify-between font-medium\">\n <span class=\"line-clamp-1 w-full text-left break-all\">\n {{ item.title }}\n </span>\n <div class=\"relative flex h-fit items-center justify-end gap-0.5\">\n <div\n class=\"items-center gap-px opacity-0 group-hover:flex group-hover:opacity-100 group-focus-visible:opacity-100 group-has-[:focus-visible]:opacity-100\"\n :class=\"{\n flex: menuItem.open,\n hidden:\n !menuItem.open ||\n menuItem.item?.entity.uid !== item.entity.uid,\n }\">\n <ScalarButton\n v-if=\"\n (layout !== 'modal' && !isDraftCollection) ||\n (isDraftCollection && hasDraftRequests)\n \"\n class=\"hover:bg-b-3 hover:text-c-1 aspect-square h-fit px-0.5 py-0 group-focus-visible:opacity-100 group-has-[:focus-visible]:opacity-100\"\n size=\"sm\"\n variant=\"ghost\"\n @click.stop.prevent=\"\n (ev: MouseEvent) =>\n $emit('openMenu', {\n item,\n parentUids,\n targetRef: (ev.currentTarget as HTMLElement)\n ?.parentNode as HTMLButtonElement,\n open: true,\n })\n \">\n <ScalarIcon\n icon=\"Ellipses\"\n size=\"md\" />\n </ScalarButton>\n <ScalarButton\n v-if=\"layout !== 'modal'\"\n class=\"hover:bg-b-3 hover:text-c-1 aspect-square h-fit px-0.5 py-0 group-focus-visible:opacity-100 group-has-[:focus-visible]:opacity-100\"\n size=\"sm\"\n variant=\"ghost\"\n @click.stop.prevent=\"addRequest(item.entity.uid)\">\n <ScalarIcon\n icon=\"Add\"\n size=\"md\"\n thickness=\"2\" />\n </ScalarButton>\n </div>\n <ScalarTooltip\n v-if=\"item.watchMode\"\n :content=\"`Watching: ${item.documentUrl}`\"\n :offset=\"12\"\n placement=\"right\">\n <button\n class=\"flex items-center justify-center\"\n type=\"button\">\n <ScalarIcon\n class=\"ml-0.5 text-sm\"\n :class=\"watchIconColor\"\n icon=\"Watch\"\n size=\"md\"\n thickness=\"2\" />\n </button>\n </ScalarTooltip>\n <span\n class=\"flex cursor-pointer items-center justify-center\"\n @click.stop.prevent=\"toggleSidebarFolder(item.entity.uid)\">\n <ScalarSidebarGroupToggle\n class=\"text-c-3 hover:text-c-1 shrink-0\"\n :open=\"Boolean(collapsedSidebarFolders[item.entity.uid])\" />\n </span>\n </div>\n </div>\n </RouterLink>\n\n <!-- Tag -->\n <button\n v-else-if=\"layout !== 'modal' || parentUids.length\"\n :aria-expanded=\"Boolean(collapsedSidebarFolders[item.entity.uid])\"\n class=\"hover:bg-b-2 group relative flex w-full flex-row justify-start gap-1.5 rounded p-1.5 focus-visible:z-10\"\n :class=\"[highlightClasses]\"\n type=\"button\"\n @click=\"toggleSidebarFolder(item.entity.uid)\">\n <span\n class=\"flex h-5 max-w-[14px] shrink-0 items-center justify-center\">\n <slot name=\"leftIcon\" />\n &hairsp;\n </span>\n <div class=\"flex flex-1 flex-row justify-between\">\n <span class=\"line-clamp-1 w-full text-left font-medium break-all\">\n {{ item.title }}\n </span>\n <div class=\"relative flex h-fit items-center justify-end gap-0.5\">\n <div\n class=\"items-center gap-px opacity-0 group-hover:flex group-hover:opacity-100 group-focus-visible:opacity-100 group-has-[:focus-visible]:opacity-100\"\n :class=\"{\n flex: menuItem.open,\n hidden:\n !menuItem.open ||\n menuItem.item?.entity.uid !== item.entity.uid,\n }\">\n <ScalarButton\n v-if=\"\n (layout !== 'modal' && !isDraftCollection) ||\n (isDraftCollection && hasDraftRequests)\n \"\n class=\"hover:bg-b-3 hover:text-c-1 aspect-square h-fit px-0.5 py-0 group-focus-visible:opacity-100 group-has-[:focus-visible]:opacity-100\"\n size=\"sm\"\n variant=\"ghost\"\n @click.stop.prevent=\"\n (ev: MouseEvent) =>\n $emit('openMenu', {\n item,\n parentUids,\n targetRef: (ev.currentTarget as HTMLElement)\n ?.parentNode as HTMLButtonElement,\n open: true,\n })\n \">\n <ScalarIcon\n icon=\"Ellipses\"\n size=\"md\" />\n </ScalarButton>\n <ScalarButton\n v-if=\"layout !== 'modal'\"\n class=\"hover:bg-b-3 hover:text-c-1 aspect-square h-fit px-0.5 py-0 group-focus-visible:opacity-100 group-has-[:focus-visible]:opacity-100\"\n size=\"sm\"\n variant=\"ghost\"\n @click.stop.prevent=\"addRequest(item.entity.uid)\">\n <ScalarIcon\n icon=\"Add\"\n size=\"md\"\n thickness=\"2\" />\n </ScalarButton>\n </div>\n <ScalarTooltip\n v-if=\"item.watchMode\"\n content=\"Watching: {{ item.documentUrl }}\"\n :offset=\"12\"\n placement=\"right\">\n <button\n class=\"flex items-center justify-center\"\n type=\"button\">\n <ScalarIcon\n class=\"ml-0.5 text-sm\"\n :class=\"watchIconColor\"\n icon=\"Watch\"\n size=\"md\"\n thickness=\"2\" />\n </button>\n </ScalarTooltip>\n <span\n class=\"flex cursor-pointer items-center justify-center\"\n @click.stop.prevent=\"toggleSidebarFolder(item.entity.uid)\">\n <ScalarSidebarGroupToggle\n class=\"text-c-3 hover:text-c-1 shrink-0\"\n :open=\"Boolean(collapsedSidebarFolders[item.entity.uid])\" />\n </span>\n </div>\n </div>\n </button>\n\n <!-- Children -->\n <ul v-if=\"showChildren\">\n <!-- We never want to show the first example -->\n <RequestSidebarItem\n v-for=\"childUid in item.children\"\n :key=\"childUid\"\n :isDraggable=\"!requestExamples[childUid]\"\n :isDroppable=\"_isDroppable\"\n :menuItem=\"menuItem\"\n :parentUids=\"[...parentUids, uid]\"\n :uid=\"childUid\"\n @newTab=\"(name, uid) => $emit('newTab', name, uid)\"\n @onDragEnd=\"(...args) => $emit('onDragEnd', ...args)\"\n @openMenu=\"(item) => $emit('openMenu', item)\" />\n <ScalarButton\n v-if=\"item.children.length === 0\"\n class=\"text-c-1 hover:bg-b-2 flex h-8 w-full justify-start gap-1.5 py-0 text-xs\"\n :class=\"parentUids.length ? 'pl-9' : ''\"\n variant=\"ghost\"\n @click=\"addRequest(item.entity.uid)\">\n <ScalarIcon\n icon=\"Add\"\n size=\"sm\" />\n <span>Add Request</span>\n </ScalarButton>\n </ul>\n </Draggable>\n </li>\n</template>\n<style>\n@import '@scalar/draggable/style.css';\n</style>\n<style scoped>\n.indent-border-line-offset:before {\n left: v-bind(leftOffset);\n}\n.indent-padding-left {\n padding-left: calc(v-bind(paddingOffset) + 6px);\n}\n.sidebar-folderitem :deep(.ellipsis-position) {\n right: 6px;\n transform: none;\n}\n</style>\n","<script setup lang=\"ts\">\nimport {\n ScalarButton,\n ScalarIcon,\n ScalarSearchResultItem,\n ScalarSearchResultList,\n ScalarSidebarSearchInput,\n} from '@scalar/components'\nimport { LibraryIcon } from '@scalar/icons/library'\nimport type { Collection } from '@scalar/oas-utils/entities/spec'\nimport { useToasts } from '@scalar/use-toasts'\nimport {\n computed,\n onBeforeUnmount,\n onMounted,\n reactive,\n ref,\n useId,\n watch,\n} from 'vue'\nimport { useRouter } from 'vue-router'\n\nimport Rabbit from '@/assets/rabbit.ascii?raw'\nimport RabbitJump from '@/assets/rabbitjump.ascii?raw'\nimport { Sidebar } from '@/components'\nimport EnvironmentSelector from '@/components/EnvironmentSelector/EnvironmentSelector.vue'\nimport HttpMethod from '@/components/HttpMethod/HttpMethod.vue'\nimport ScalarAsciiArt from '@/components/ScalarAsciiArt.vue'\nimport { useSearch } from '@/components/Search/useSearch'\nimport SidebarButton from '@/components/Sidebar/SidebarButton.vue'\nimport { useLayout } from '@/hooks/useLayout'\nimport { useSidebar } from '@/hooks/useSidebar'\nimport type { HotKeyEvent } from '@/libs'\nimport { PathId } from '@/routes'\nimport { useWorkspace } from '@/store'\nimport { useActiveEntities } from '@/store/active-entities'\nimport { createInitialRequest } from '@/store/requests'\nimport { dragHandlerFactory } from '@/views/Request/handle-drag'\nimport RequestSidebarItemMenu from '@/views/Request/RequestSidebarItemMenu.vue'\nimport type { SidebarItem, SidebarMenuItem } from '@/views/Request/types'\n\nimport { WorkspaceDropdown } from './components'\nimport { isGettingStarted } from './RequestSection/helpers/getting-started'\nimport RequestSidebarItem from './RequestSidebarItem.vue'\n\nconst emit = defineEmits<{\n (e: 'newTab', { name, uid }: { name: string; uid: string }): void\n (e: 'clearDrafts'): void\n}>()\n\nconst { isSidebarOpen, setCollapsedSidebarFolder, toggleSidebarOpen } =\n useSidebar()\nconst { layout } = useLayout()\n\nconst workspaceContext = useWorkspace()\nconst {\n activeCollection,\n activeWorkspaceCollections,\n activeRequest,\n activeWorkspaceRequests,\n activeWorkspace,\n} = useActiveEntities()\nconst { findRequestParents, events, requestMutators, requests } =\n workspaceContext\n\nconst { handleDragEnd, isDroppable } = dragHandlerFactory(\n activeWorkspace,\n workspaceContext,\n)\nconst { replace } = useRouter()\nconst openCommandPaletteImport = () => {\n events.commandPalette.emit({\n commandName: 'Import from OpenAPI/Swagger/Postman/cURL',\n })\n}\nconst searchResultsId = useId()\nconst { toast } = useToasts()\n/** The currently selected sidebarMenuItem for the context menu */\nconst menuItem = reactive<SidebarMenuItem>({ open: false })\nconst isSearchVisible = ref(false)\n\n/** Watch to see if activeRequest changes and ensure we open any folders */\nwatch(\n activeRequest,\n (request) => {\n if (!request) {\n return\n }\n\n // Ensure the sidebar folders are open\n findRequestParents(request).forEach((uid: string) =>\n setCollapsedSidebarFolder(uid, true),\n )\n },\n { immediate: true },\n)\n\nconst {\n searchText,\n searchResultsWithPlaceholderResults,\n selectedSearchResult,\n onSearchResultClick,\n fuseSearch,\n searchInputRef,\n searchResultRefs,\n navigateSearchResults,\n selectSearchResult,\n} = useSearch()\n\nconst searchToggleRef = ref<HTMLButtonElement>()\n\n/** Handle hotkey events from the bus */\nconst handleHotKey = (event?: HotKeyEvent) => {\n if (!event) {\n return\n }\n if (event.toggleSidebar) {\n toggleSidebarOpen()\n }\n if (event.focusRequestSearch) {\n searchInputRef.value?.focus()\n }\n}\n\nonMounted(() => events.hotKeys.on(handleHotKey))\n\n/**\n * Need to manually remove listener on unmount due to vueuse memory leak\n *\n * @see https://github.com/vueuse/vueuse/issues/3498#issuecomment-2055546566\n */\nonBeforeUnmount(() => {\n events.hotKeys.off(handleHotKey)\n})\n\nconst handleToggleWatchMode = (item?: SidebarItem) => {\n if (item?.documentUrl) {\n item.watchMode = !item.watchMode\n const currentCollection = activeWorkspaceCollections.value.find(\n (collection: Collection) => collection.uid === item.entity.uid,\n )\n if (currentCollection) {\n currentCollection.watchMode = item.watchMode\n }\n }\n}\n\nwatch(\n () =>\n activeWorkspaceCollections.value.map(\n (collection: Collection) => collection.watchMode,\n ),\n (newWatchModes, oldWatchModes) => {\n newWatchModes.forEach((newWatchMode: boolean, index: number) => {\n if (\n layout !== 'modal' &&\n newWatchMode !== oldWatchModes[index] &&\n activeWorkspaceCollections.value[index]?.info?.title !== 'Drafts' &&\n activeWorkspaceCollections.value[index]\n ) {\n const currentCollection = activeWorkspaceCollections.value[index]\n if (!currentCollection) {\n return\n }\n\n const message = `${currentCollection.info?.title}: Watch Mode ${newWatchMode ? 'enabled' : 'disabled'}`\n toast(message, 'info')\n }\n })\n },\n)\n\n/** Screen reader label for the search input */\nconst srLabel = computed<string>(() => {\n const results = searchResultsWithPlaceholderResults.value\n if (!results.length) {\n return 'No results found'\n }\n\n const result = results[selectedSearchResult.value]?.item\n if (!result) {\n return 'No result selected'\n }\n\n const resultsFoundLabel = searchText.value.length\n ? `${results.length} result${results.length === 1 ? '' : 's'} found, `\n : ''\n\n const selectedResultDescription = `, HTTP Method ${result.httpVerb}, Path ${result.path}`\n\n const selectedResultLabel = `${result.title} ${selectedResultDescription}`\n\n return `${resultsFoundLabel}Selected: ${selectedResultLabel}`\n})\n\nconst handleClearDrafts = () => {\n const draftCollection = activeWorkspaceCollections.value.find(\n (collection: Collection) => collection.info?.title === 'Drafts',\n )\n\n if (draftCollection) {\n draftCollection.requests.forEach((requestUid: string) => {\n if (requests[requestUid]) {\n requestMutators.delete(requests[requestUid], draftCollection.uid)\n }\n })\n }\n\n const hasRequests = activeWorkspaceRequests.value.length\n\n // First request in the first collection\n if (hasRequests) {\n const firstCollection = activeWorkspaceCollections.value[0]\n const firstRequest = firstCollection?.requests[0]\n\n if (firstRequest) {\n replace({\n name: 'request',\n params: {\n [PathId.Request]: firstRequest,\n },\n })\n }\n }\n // Create a new request and go to it\n else {\n const { request } = createInitialRequest()\n\n if (draftCollection) {\n requestMutators.add(request, draftCollection.uid)\n\n replace({\n name: 'request',\n params: {\n [PathId.Request]: request.uid,\n },\n })\n }\n }\n}\n\nwatch(isSearchVisible, (isVisible) => {\n // If we're hiding the search, clear the text\n if (!isVisible) {\n searchText.value = ''\n }\n})\n\nconst showGettingStarted = computed(() =>\n isGettingStarted(\n activeWorkspaceCollections.value,\n activeWorkspaceRequests.value,\n requests,\n ),\n)\n\n/** We ensure in modal mode we only show the current requests collection */\nconst collections = computed(() => {\n if (layout === 'modal' && activeCollection.value) {\n return [activeCollection.value]\n }\n return activeWorkspaceCollections.value\n})\n\n/** Hide the search input if the text is empty */\nfunction handleBlur(e: FocusEvent) {\n // We have to check the blur did not come from the search toggle button\n // otherwise the search will show again form the click event\n if (!searchText.value && e.relatedTarget !== searchToggleRef.value) {\n isSearchVisible.value = false\n }\n}\n</script>\n<template>\n <Sidebar\n v-show=\"isSidebarOpen\"\n :class=\"[isSidebarOpen ? 'sidebar-active-width' : '']\">\n <template\n v-if=\"layout !== 'modal'\"\n #header />\n <template #content>\n <div class=\"bg-b-1 sticky top-0 z-20 flex h-12 items-center px-3\">\n <!-- Holds space for the sidebar toggle -->\n <div\n class=\"size-8\"\n :class=\"{ 'xl:hidden': layout !== 'modal' }\" />\n <WorkspaceDropdown v-if=\"layout !== 'modal'\" />\n <span\n v-if=\"layout !== 'modal'\"\n class=\"text-c-3\">\n /\n </span>\n <EnvironmentSelector v-if=\"layout !== 'modal'\" />\n <button\n ref=\"searchToggleRef\"\n :aria-pressed=\"isSearchVisible\"\n class=\"ml-auto\"\n type=\"button\"\n @click=\"isSearchVisible = !isSearchVisible\">\n <span class=\"sr-only\">\n {{ isSearchVisible ? 'Hide' : 'Show' }} search\n </span>\n <ScalarIcon\n class=\"text-c-3 hover:bg-b-2 max-h-8 max-w-8 rounded-lg p-1.75 text-sm\"\n icon=\"Search\" />\n </button>\n </div>\n <div\n v-if=\"isSearchVisible\"\n class=\"search-button-fade sticky top-12 z-10 px-3 py-2.5 pt-0 focus-within:z-20\"\n role=\"search\">\n <ScalarSidebarSearchInput\n ref=\"searchInputRef\"\n v-model=\"searchText\"\n autofocus\n :aria-controls=\"searchResultsId\"\n :label=\"srLabel\"\n @input=\"fuseSearch\"\n @keydown.down.stop=\"navigateSearchResults('down')\"\n @keydown.enter.stop=\"selectSearchResult()\"\n @keydown.up.stop=\"navigateSearchResults('up')\"\n @blur=\"handleBlur\" />\n </div>\n <div\n class=\"gap-1/2 flex flex-1 flex-col overflow-visible overflow-y-auto px-3 pt-0 pb-3\"\n :class=\"[\n {\n 'pb-14': layout !== 'modal',\n },\n {\n 'h-[calc(100%-273.5px)]': showGettingStarted,\n },\n ]\"\n @dragenter.prevent\n @dragover.prevent>\n <template v-if=\"searchText\">\n <ScalarSearchResultList\n :id=\"searchResultsId\"\n aria-label=\"Search Results\"\n class=\"gap-px\"\n :noResults=\"!searchResultsWithPlaceholderResults.length\">\n <ScalarSearchResultItem\n v-for=\"(entry, index) in searchResultsWithPlaceholderResults\"\n :id=\"`#search-input-${entry.item.id}`\"\n :key=\"entry.refIndex\"\n :ref=\"(el) => (searchResultRefs[index] = el as HTMLElement)\"\n :selected=\"selectedSearchResult === index\"\n class=\"px-2\"\n :href=\"entry.item.link\"\n @click.prevent=\"onSearchResultClick(entry)\"\n @focus=\"selectedSearchResult = index\">\n {{ entry.item.title }}\n <template #addon>\n <span class=\"sr-only\">HTTP Method:</span>\n <HttpMethod\n class=\"font-bold\"\n :method=\"entry.item.httpVerb ?? 'get'\" />\n </template>\n </ScalarSearchResultItem>\n </ScalarSearchResultList>\n </template>\n <nav\n v-else\n class=\"contents\">\n <!-- Collection -->\n <RequestSidebarItem\n v-for=\"collection in collections\"\n :key=\"collection.uid\"\n :isDraggable=\"\n layout !== 'modal' && collection.info?.title !== 'Drafts'\n \"\n :isDroppable=\"isDroppable\"\n :menuItem=\"menuItem\"\n :parentUids=\"[]\"\n :uid=\"collection.uid\"\n @newTab=\"(name, uid) => emit('newTab', { name, uid })\"\n @onDragEnd=\"handleDragEnd\"\n @openMenu=\"(item) => Object.assign(menuItem, item)\">\n <template #leftIcon>\n <ScalarIcon\n v-if=\"collection.info?.title === 'Drafts'\"\n class=\"text-sidebar-c-2\"\n icon=\"Scribble\"\n thickness=\"2.25\" />\n <LibraryIcon\n v-else\n class=\"text-sidebar-c-2 size-3.5 min-w-3.5 stroke-2\"\n :src=\"\n collection['x-scalar-icon'] || 'interface-content-folder'\n \" />\n </template>\n </RequestSidebarItem>\n </nav>\n </div>\n </template>\n <template #button>\n <div\n :class=\"{\n 'empty-sidebar-item': showGettingStarted,\n }\">\n <div\n v-if=\"showGettingStarted\"\n class=\"empty-sidebar-item-content px-2.5 py-2.5\">\n <div class=\"rabbit-ascii relative m-auto mt-2 h-[68px] w-[60px]\">\n <ScalarAsciiArt\n :art=\"Rabbit\"\n class=\"rabbitsit font-bold\" />\n <ScalarAsciiArt\n :art=\"RabbitJump\"\n class=\"rabbitjump absolute top-0 left-0 font-bold\" />\n </div>\n <div class=\"mt-2 mb-2 text-center text-sm text-balance\">\n <b class=\"font-medium\">Let's Get Started</b>\n <p class=\"mt-2\">\n Create request, folder, collection or import from OpenAPI/Postman\n </p>\n </div>\n </div>\n <ScalarButton\n v-if=\"layout !== 'modal'\"\n class=\"mb-1.5 hidden h-fit w-full p-1.5 opacity-0\"\n :class=\"{\n 'flex opacity-100': showGettingStarted,\n }\"\n @click=\"openCommandPaletteImport\">\n Import Collection\n </ScalarButton>\n <SidebarButton\n v-if=\"layout !== 'modal'\"\n :click=\"events.commandPalette.emit\"\n hotkey=\"K\">\n <template #title> Add Item </template>\n </SidebarButton>\n </div>\n </template>\n </Sidebar>\n\n <!-- Menu -->\n <RequestSidebarItemMenu\n v-if=\"layout !== 'modal' && menuItem\"\n :menuItem=\"menuItem\"\n @clearDrafts=\"handleClearDrafts\"\n @closeMenu=\"menuItem.open = false\"\n @toggleWatchMode=\"handleToggleWatchMode\" />\n</template>\n<style scoped>\n.search-button-fade {\n background: linear-gradient(\n var(--scalar-background-1) 32px,\n color-mix(in srgb, var(--scalar-background-1), transparent) 38px,\n transparent\n );\n}\n.empty-sidebar-item-content {\n display: none;\n}\n.empty-sidebar-item .empty-sidebar-item-content {\n display: block;\n}\n.rabbitjump {\n opacity: 0;\n}\n.empty-sidebar-item:hover .rabbitjump {\n opacity: 1;\n animation: rabbitAnimation 0.5s steps(1) infinite;\n}\n.empty-sidebar-item:hover .rabbitsit {\n opacity: 0;\n animation: rabbitAnimation2 0.5s steps(1) infinite;\n}\n.empty-sidebar-item:hover .rabbit-ascii {\n animation: rabbitRun 8s infinite linear;\n}\n@keyframes rabbitRun {\n 0% {\n transform: translate3d(0, 0, 0);\n }\n 25% {\n transform: translate3d(250px, 0, 0);\n }\n 25.01% {\n transform: translate3d(-250px, 0, 0);\n }\n 75% {\n transform: translate3d(250px, 0, 0);\n }\n 75.01% {\n transform: translate3d(-250px, 0, 0);\n }\n 100% {\n transform: translate3d(0, 0, 0);\n }\n}\n@keyframes rabbitAnimation {\n 0%,\n 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0;\n }\n}\n@keyframes rabbitAnimation2 {\n 0%,\n 100% {\n opacity: 0;\n }\n 50% {\n opacity: 1;\n transform: translate3d(0, -8px, 0);\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport {\n ScalarButton,\n ScalarIcon,\n ScalarSearchResultItem,\n ScalarSearchResultList,\n ScalarSidebarSearchInput,\n} from '@scalar/components'\nimport { LibraryIcon } from '@scalar/icons/library'\nimport type { Collection } from '@scalar/oas-utils/entities/spec'\nimport { useToasts } from '@scalar/use-toasts'\nimport {\n computed,\n onBeforeUnmount,\n onMounted,\n reactive,\n ref,\n useId,\n watch,\n} from 'vue'\nimport { useRouter } from 'vue-router'\n\nimport Rabbit from '@/assets/rabbit.ascii?raw'\nimport RabbitJump from '@/assets/rabbitjump.ascii?raw'\nimport { Sidebar } from '@/components'\nimport EnvironmentSelector from '@/components/EnvironmentSelector/EnvironmentSelector.vue'\nimport HttpMethod from '@/components/HttpMethod/HttpMethod.vue'\nimport ScalarAsciiArt from '@/components/ScalarAsciiArt.vue'\nimport { useSearch } from '@/components/Search/useSearch'\nimport SidebarButton from '@/components/Sidebar/SidebarButton.vue'\nimport { useLayout } from '@/hooks/useLayout'\nimport { useSidebar } from '@/hooks/useSidebar'\nimport type { HotKeyEvent } from '@/libs'\nimport { PathId } from '@/routes'\nimport { useWorkspace } from '@/store'\nimport { useActiveEntities } from '@/store/active-entities'\nimport { createInitialRequest } from '@/store/requests'\nimport { dragHandlerFactory } from '@/views/Request/handle-drag'\nimport RequestSidebarItemMenu from '@/views/Request/RequestSidebarItemMenu.vue'\nimport type { SidebarItem, SidebarMenuItem } from '@/views/Request/types'\n\nimport { WorkspaceDropdown } from './components'\nimport { isGettingStarted } from './RequestSection/helpers/getting-started'\nimport RequestSidebarItem from './RequestSidebarItem.vue'\n\nconst emit = defineEmits<{\n (e: 'newTab', { name, uid }: { name: string; uid: string }): void\n (e: 'clearDrafts'): void\n}>()\n\nconst { isSidebarOpen, setCollapsedSidebarFolder, toggleSidebarOpen } =\n useSidebar()\nconst { layout } = useLayout()\n\nconst workspaceContext = useWorkspace()\nconst {\n activeCollection,\n activeWorkspaceCollections,\n activeRequest,\n activeWorkspaceRequests,\n activeWorkspace,\n} = useActiveEntities()\nconst { findRequestParents, events, requestMutators, requests } =\n workspaceContext\n\nconst { handleDragEnd, isDroppable } = dragHandlerFactory(\n activeWorkspace,\n workspaceContext,\n)\nconst { replace } = useRouter()\nconst openCommandPaletteImport = () => {\n events.commandPalette.emit({\n commandName: 'Import from OpenAPI/Swagger/Postman/cURL',\n })\n}\nconst searchResultsId = useId()\nconst { toast } = useToasts()\n/** The currently selected sidebarMenuItem for the context menu */\nconst menuItem = reactive<SidebarMenuItem>({ open: false })\nconst isSearchVisible = ref(false)\n\n/** Watch to see if activeRequest changes and ensure we open any folders */\nwatch(\n activeRequest,\n (request) => {\n if (!request) {\n return\n }\n\n // Ensure the sidebar folders are open\n findRequestParents(request).forEach((uid: string) =>\n setCollapsedSidebarFolder(uid, true),\n )\n },\n { immediate: true },\n)\n\nconst {\n searchText,\n searchResultsWithPlaceholderResults,\n selectedSearchResult,\n onSearchResultClick,\n fuseSearch,\n searchInputRef,\n searchResultRefs,\n navigateSearchResults,\n selectSearchResult,\n} = useSearch()\n\nconst searchToggleRef = ref<HTMLButtonElement>()\n\n/** Handle hotkey events from the bus */\nconst handleHotKey = (event?: HotKeyEvent) => {\n if (!event) {\n return\n }\n if (event.toggleSidebar) {\n toggleSidebarOpen()\n }\n if (event.focusRequestSearch) {\n searchInputRef.value?.focus()\n }\n}\n\nonMounted(() => events.hotKeys.on(handleHotKey))\n\n/**\n * Need to manually remove listener on unmount due to vueuse memory leak\n *\n * @see https://github.com/vueuse/vueuse/issues/3498#issuecomment-2055546566\n */\nonBeforeUnmount(() => {\n events.hotKeys.off(handleHotKey)\n})\n\nconst handleToggleWatchMode = (item?: SidebarItem) => {\n if (item?.documentUrl) {\n item.watchMode = !item.watchMode\n const currentCollection = activeWorkspaceCollections.value.find(\n (collection: Collection) => collection.uid === item.entity.uid,\n )\n if (currentCollection) {\n currentCollection.watchMode = item.watchMode\n }\n }\n}\n\nwatch(\n () =>\n activeWorkspaceCollections.value.map(\n (collection: Collection) => collection.watchMode,\n ),\n (newWatchModes, oldWatchModes) => {\n newWatchModes.forEach((newWatchMode: boolean, index: number) => {\n if (\n layout !== 'modal' &&\n newWatchMode !== oldWatchModes[index] &&\n activeWorkspaceCollections.value[index]?.info?.title !== 'Drafts' &&\n activeWorkspaceCollections.value[index]\n ) {\n const currentCollection = activeWorkspaceCollections.value[index]\n if (!currentCollection) {\n return\n }\n\n const message = `${currentCollection.info?.title}: Watch Mode ${newWatchMode ? 'enabled' : 'disabled'}`\n toast(message, 'info')\n }\n })\n },\n)\n\n/** Screen reader label for the search input */\nconst srLabel = computed<string>(() => {\n const results = searchResultsWithPlaceholderResults.value\n if (!results.length) {\n return 'No results found'\n }\n\n const result = results[selectedSearchResult.value]?.item\n if (!result) {\n return 'No result selected'\n }\n\n const resultsFoundLabel = searchText.value.length\n ? `${results.length} result${results.length === 1 ? '' : 's'} found, `\n : ''\n\n const selectedResultDescription = `, HTTP Method ${result.httpVerb}, Path ${result.path}`\n\n const selectedResultLabel = `${result.title} ${selectedResultDescription}`\n\n return `${resultsFoundLabel}Selected: ${selectedResultLabel}`\n})\n\nconst handleClearDrafts = () => {\n const draftCollection = activeWorkspaceCollections.value.find(\n (collection: Collection) => collection.info?.title === 'Drafts',\n )\n\n if (draftCollection) {\n draftCollection.requests.forEach((requestUid: string) => {\n if (requests[requestUid]) {\n requestMutators.delete(requests[requestUid], draftCollection.uid)\n }\n })\n }\n\n const hasRequests = activeWorkspaceRequests.value.length\n\n // First request in the first collection\n if (hasRequests) {\n const firstCollection = activeWorkspaceCollections.value[0]\n const firstRequest = firstCollection?.requests[0]\n\n if (firstRequest) {\n replace({\n name: 'request',\n params: {\n [PathId.Request]: firstRequest,\n },\n })\n }\n }\n // Create a new request and go to it\n else {\n const { request } = createInitialRequest()\n\n if (draftCollection) {\n requestMutators.add(request, draftCollection.uid)\n\n replace({\n name: 'request',\n params: {\n [PathId.Request]: request.uid,\n },\n })\n }\n }\n}\n\nwatch(isSearchVisible, (isVisible) => {\n // If we're hiding the search, clear the text\n if (!isVisible) {\n searchText.value = ''\n }\n})\n\nconst showGettingStarted = computed(() =>\n isGettingStarted(\n activeWorkspaceCollections.value,\n activeWorkspaceRequests.value,\n requests,\n ),\n)\n\n/** We ensure in modal mode we only show the current requests collection */\nconst collections = computed(() => {\n if (layout === 'modal' && activeCollection.value) {\n return [activeCollection.value]\n }\n return activeWorkspaceCollections.value\n})\n\n/** Hide the search input if the text is empty */\nfunction handleBlur(e: FocusEvent) {\n // We have to check the blur did not come from the search toggle button\n // otherwise the search will show again form the click event\n if (!searchText.value && e.relatedTarget !== searchToggleRef.value) {\n isSearchVisible.value = false\n }\n}\n</script>\n<template>\n <Sidebar\n v-show=\"isSidebarOpen\"\n :class=\"[isSidebarOpen ? 'sidebar-active-width' : '']\">\n <template\n v-if=\"layout !== 'modal'\"\n #header />\n <template #content>\n <div class=\"bg-b-1 sticky top-0 z-20 flex h-12 items-center px-3\">\n <!-- Holds space for the sidebar toggle -->\n <div\n class=\"size-8\"\n :class=\"{ 'xl:hidden': layout !== 'modal' }\" />\n <WorkspaceDropdown v-if=\"layout !== 'modal'\" />\n <span\n v-if=\"layout !== 'modal'\"\n class=\"text-c-3\">\n /\n </span>\n <EnvironmentSelector v-if=\"layout !== 'modal'\" />\n <button\n ref=\"searchToggleRef\"\n :aria-pressed=\"isSearchVisible\"\n class=\"ml-auto\"\n type=\"button\"\n @click=\"isSearchVisible = !isSearchVisible\">\n <span class=\"sr-only\">\n {{ isSearchVisible ? 'Hide' : 'Show' }} search\n </span>\n <ScalarIcon\n class=\"text-c-3 hover:bg-b-2 max-h-8 max-w-8 rounded-lg p-1.75 text-sm\"\n icon=\"Search\" />\n </button>\n </div>\n <div\n v-if=\"isSearchVisible\"\n class=\"search-button-fade sticky top-12 z-10 px-3 py-2.5 pt-0 focus-within:z-20\"\n role=\"search\">\n <ScalarSidebarSearchInput\n ref=\"searchInputRef\"\n v-model=\"searchText\"\n autofocus\n :aria-controls=\"searchResultsId\"\n :label=\"srLabel\"\n @input=\"fuseSearch\"\n @keydown.down.stop=\"navigateSearchResults('down')\"\n @keydown.enter.stop=\"selectSearchResult()\"\n @keydown.up.stop=\"navigateSearchResults('up')\"\n @blur=\"handleBlur\" />\n </div>\n <div\n class=\"gap-1/2 flex flex-1 flex-col overflow-visible overflow-y-auto px-3 pt-0 pb-3\"\n :class=\"[\n {\n 'pb-14': layout !== 'modal',\n },\n {\n 'h-[calc(100%-273.5px)]': showGettingStarted,\n },\n ]\"\n @dragenter.prevent\n @dragover.prevent>\n <template v-if=\"searchText\">\n <ScalarSearchResultList\n :id=\"searchResultsId\"\n aria-label=\"Search Results\"\n class=\"gap-px\"\n :noResults=\"!searchResultsWithPlaceholderResults.length\">\n <ScalarSearchResultItem\n v-for=\"(entry, index) in searchResultsWithPlaceholderResults\"\n :id=\"`#search-input-${entry.item.id}`\"\n :key=\"entry.refIndex\"\n :ref=\"(el) => (searchResultRefs[index] = el as HTMLElement)\"\n :selected=\"selectedSearchResult === index\"\n class=\"px-2\"\n :href=\"entry.item.link\"\n @click.prevent=\"onSearchResultClick(entry)\"\n @focus=\"selectedSearchResult = index\">\n {{ entry.item.title }}\n <template #addon>\n <span class=\"sr-only\">HTTP Method:</span>\n <HttpMethod\n class=\"font-bold\"\n :method=\"entry.item.httpVerb ?? 'get'\" />\n </template>\n </ScalarSearchResultItem>\n </ScalarSearchResultList>\n </template>\n <nav\n v-else\n class=\"contents\">\n <!-- Collection -->\n <RequestSidebarItem\n v-for=\"collection in collections\"\n :key=\"collection.uid\"\n :isDraggable=\"\n layout !== 'modal' && collection.info?.title !== 'Drafts'\n \"\n :isDroppable=\"isDroppable\"\n :menuItem=\"menuItem\"\n :parentUids=\"[]\"\n :uid=\"collection.uid\"\n @newTab=\"(name, uid) => emit('newTab', { name, uid })\"\n @onDragEnd=\"handleDragEnd\"\n @openMenu=\"(item) => Object.assign(menuItem, item)\">\n <template #leftIcon>\n <ScalarIcon\n v-if=\"collection.info?.title === 'Drafts'\"\n class=\"text-sidebar-c-2\"\n icon=\"Scribble\"\n thickness=\"2.25\" />\n <LibraryIcon\n v-else\n class=\"text-sidebar-c-2 size-3.5 min-w-3.5 stroke-2\"\n :src=\"\n collection['x-scalar-icon'] || 'interface-content-folder'\n \" />\n </template>\n </RequestSidebarItem>\n </nav>\n </div>\n </template>\n <template #button>\n <div\n :class=\"{\n 'empty-sidebar-item': showGettingStarted,\n }\">\n <div\n v-if=\"showGettingStarted\"\n class=\"empty-sidebar-item-content px-2.5 py-2.5\">\n <div class=\"rabbit-ascii relative m-auto mt-2 h-[68px] w-[60px]\">\n <ScalarAsciiArt\n :art=\"Rabbit\"\n class=\"rabbitsit font-bold\" />\n <ScalarAsciiArt\n :art=\"RabbitJump\"\n class=\"rabbitjump absolute top-0 left-0 font-bold\" />\n </div>\n <div class=\"mt-2 mb-2 text-center text-sm text-balance\">\n <b class=\"font-medium\">Let's Get Started</b>\n <p class=\"mt-2\">\n Create request, folder, collection or import from OpenAPI/Postman\n </p>\n </div>\n </div>\n <ScalarButton\n v-if=\"layout !== 'modal'\"\n class=\"mb-1.5 hidden h-fit w-full p-1.5 opacity-0\"\n :class=\"{\n 'flex opacity-100': showGettingStarted,\n }\"\n @click=\"openCommandPaletteImport\">\n Import Collection\n </ScalarButton>\n <SidebarButton\n v-if=\"layout !== 'modal'\"\n :click=\"events.commandPalette.emit\"\n hotkey=\"K\">\n <template #title> Add Item </template>\n </SidebarButton>\n </div>\n </template>\n </Sidebar>\n\n <!-- Menu -->\n <RequestSidebarItemMenu\n v-if=\"layout !== 'modal' && menuItem\"\n :menuItem=\"menuItem\"\n @clearDrafts=\"handleClearDrafts\"\n @closeMenu=\"menuItem.open = false\"\n @toggleWatchMode=\"handleToggleWatchMode\" />\n</template>\n<style scoped>\n.search-button-fade {\n background: linear-gradient(\n var(--scalar-background-1) 32px,\n color-mix(in srgb, var(--scalar-background-1), transparent) 38px,\n transparent\n );\n}\n.empty-sidebar-item-content {\n display: none;\n}\n.empty-sidebar-item .empty-sidebar-item-content {\n display: block;\n}\n.rabbitjump {\n opacity: 0;\n}\n.empty-sidebar-item:hover .rabbitjump {\n opacity: 1;\n animation: rabbitAnimation 0.5s steps(1) infinite;\n}\n.empty-sidebar-item:hover .rabbitsit {\n opacity: 0;\n animation: rabbitAnimation2 0.5s steps(1) infinite;\n}\n.empty-sidebar-item:hover .rabbit-ascii {\n animation: rabbitRun 8s infinite linear;\n}\n@keyframes rabbitRun {\n 0% {\n transform: translate3d(0, 0, 0);\n }\n 25% {\n transform: translate3d(250px, 0, 0);\n }\n 25.01% {\n transform: translate3d(-250px, 0, 0);\n }\n 75% {\n transform: translate3d(250px, 0, 0);\n }\n 75.01% {\n transform: translate3d(-250px, 0, 0);\n }\n 100% {\n transform: translate3d(0, 0, 0);\n }\n}\n@keyframes rabbitAnimation {\n 0%,\n 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0;\n }\n}\n@keyframes rabbitAnimation2 {\n 0%,\n 100% {\n opacity: 0;\n }\n 50% {\n opacity: 1;\n transform: translate3d(0, -8px, 0);\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport { isDefined } from '@scalar/helpers/array/is-defined'\nimport { safeJSON } from '@scalar/object-utils/parse'\nimport { useToasts } from '@scalar/use-toasts'\nimport { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'\nimport { RouterView } from 'vue-router'\n\nimport SidebarToggle from '@/components/Sidebar/SidebarToggle.vue'\nimport { useLayout } from '@/hooks'\nimport { useAnalytics } from '@/hooks/useAnalytics'\nimport { useClientConfig } from '@/hooks/useClientConfig'\nimport { useSidebar } from '@/hooks/useSidebar'\nimport { ERRORS } from '@/libs'\nimport { createRequestOperation } from '@/libs/send-request'\nimport type { SendRequestResult } from '@/libs/send-request/create-request-operation'\nimport {\n validateParameters,\n type ValidationResult,\n} from '@/libs/validate-parameters'\nimport { usePluginManager } from '@/plugins'\nimport { useWorkspace } from '@/store'\nimport { useActiveEntities } from '@/store/active-entities'\nimport { useOpenApiWatcher } from '@/views/Request/hooks/useOpenApiWatcher'\n\nimport RequestSidebar from './RequestSidebar.vue'\n\ndefineEmits<(e: 'newTab', item: { name: string; uid: string }) => void>()\nconst workspaceContext = useWorkspace()\nconst { toast } = useToasts()\nconst { layout } = useLayout()\nconst config = useClientConfig()\nconst { isSidebarOpen } = useSidebar()\nconst analytics = useAnalytics()\n\nconst {\n activeCollection,\n activeExample,\n activeEnvironment,\n activeRequest,\n activeWorkspace,\n activeServer,\n} = useActiveEntities()\nconst {\n cookies,\n requestHistory,\n showSidebar,\n securitySchemes,\n modalState,\n events,\n} = workspaceContext\n\nconst pluginManager = usePluginManager()\n\n/** Root element (bound in template via ref=\"_element\") */\nconst _element = ref<HTMLDivElement>()\nvoid _element\n\nconst requestAbortController = ref<AbortController>()\n/** Computed Validation State Update on Example Change */\nconst validation = computed<ValidationResult>(() =>\n validateParameters(activeExample.value ?? null),\n)\nconst requestResult = ref<SendRequestResult | null>(null)\n\n/**\n * Selected scheme UIDs\n *\n * In the modal we use collection.selectedSecuritySchemes and in the\n * standalone client we use request.selectedSecuritySchemeUids\n *\n * These are centralized here so they can be drilled down AND used in send-request\n */\nconst selectedSecuritySchemeUids = computed(\n () =>\n (activeCollection.value?.useCollectionSecurity\n ? activeCollection.value?.selectedSecuritySchemeUids\n : activeRequest.value?.selectedSecuritySchemeUids) ?? [],\n)\n\n/**\n * Execute the request\n * called from the send button as well as keyboard shortcuts\n */\nconst executeRequest = async () => {\n if (!activeRequest.value || !activeExample.value || !activeCollection.value) {\n return\n }\n\n // Block request if there are empty required path parameters\n if (validation.value.hasBlockingErrors) {\n toast('Path parameters must have values.', 'error')\n events.requestStatus.emit('abort')\n return\n }\n\n const environmentValue =\n typeof activeEnvironment.value === 'object'\n ? activeEnvironment.value.value\n : '{}'\n const e = safeJSON.parse(environmentValue)\n if (e.error) {\n console.error('INVALID ENVIRONMENT!')\n }\n const environment =\n e.error || typeof e.data !== 'object' ? {} : (e.data ?? {})\n\n const globalCookies =\n activeWorkspace.value?.cookies.map((c) => cookies[c]).filter(isDefined) ??\n []\n\n const server =\n activeCollection.value?.info?.title === 'Drafts'\n ? undefined\n : activeServer.value\n\n const [error, requestOperation] = createRequestOperation({\n request: activeRequest.value,\n example: activeExample.value,\n selectedSecuritySchemeUids: selectedSecuritySchemeUids.value,\n proxyUrl: activeWorkspace.value?.proxyUrl ?? '',\n environment,\n globalCookies,\n status: events.requestStatus,\n securitySchemes: securitySchemes,\n server,\n pluginManager,\n })\n\n // Call the onRequestSent callback if it exists\n config.value?.onRequestSent?.(activeRequest.value.path ?? '')\n\n // Error from createRequestOperation\n if (error) {\n toast(error.message, 'error')\n return\n }\n\n requestAbortController.value = requestOperation.controller\n const [sendRequestError, result] = await requestOperation.sendRequest()\n\n // Store the result to share it with child components\n requestResult.value = result\n\n // Send error toast\n if (sendRequestError) {\n toast(sendRequestError.message, 'error')\n } else {\n // We need to deep clone the result because it's a ref and updates will break the history\n requestHistory.push(cloneRequestResult(result))\n }\n}\n\n/** Cancel a live request */\nconst cancelRequest = async () =>\n requestAbortController.value?.abort(ERRORS.REQUEST_ABORTED)\n\n/** Subscribed to executeRequest, used for logging / analytics. */\nfunction logRequest() {\n analytics?.capture('client-send-request')\n}\n\n/**\n * Cancel request when closing the modal\n * @see https://github.com/scalar/scalar/issues/7115\n */\nwatch(modalState, ({ open }) => {\n if (!open) {\n void cancelRequest()\n }\n})\n\nonMounted(() => {\n events.executeRequest.on(executeRequest)\n events.executeRequest.on(logRequest)\n events.cancelRequest.on(cancelRequest)\n})\n\nuseOpenApiWatcher()\n\n/**\n * Need to manually remove listener on unmount due to vueuse memory leak\n *\n * @see https://github.com/vueuse/vueuse/issues/3498#issuecomment-2055546566\n */\nonBeforeUnmount(() => {\n events.executeRequest.off(executeRequest)\n events.executeRequest.off(logRequest)\n events.cancelRequest.off(cancelRequest)\n})\n\nconst cloneRequestResult = (result: any) => {\n // Create a structured clone that can handle Blobs, ArrayBuffers, etc.\n try {\n return structuredClone(result)\n } catch {\n // Fallback to a custom cloning approach if structuredClone fails\n // or isn't available in the environment\n const clone = { ...result }\n\n // Handle response data specifically\n if (result.response?.data) {\n // If it's a Blob/File/ArrayBuffer, store a reference\n if (\n result.response.data instanceof Blob ||\n result.response.data instanceof ArrayBuffer\n ) {\n clone.response.data = result.response.data\n } else {\n // For regular objects, do a deep clone\n clone.response.data = JSON.parse(JSON.stringify(result.response.data))\n }\n }\n\n return clone\n }\n}\n</script>\n\n<template>\n <!-- Layout -->\n <div\n ref=\"_element\"\n class=\"bg-b-1 relative z-0 flex h-full flex-1 flex-col overflow-hidden pt-0\"\n :class=\"{\n '!mr-0 !mb-0 !border-0': layout === 'modal',\n }\">\n <SidebarToggle\n v-if=\"showSidebar\"\n v-model=\"isSidebarOpen\"\n class=\"absolute top-2 left-3 z-50\"\n :class=\"[\n { hidden: isSidebarOpen },\n { 'xl:!flex': !isSidebarOpen },\n { '!flex': layout === 'modal' },\n ]\" />\n <div class=\"flex h-full\">\n <!-- Sidebar -->\n <RequestSidebar\n v-if=\"showSidebar\"\n @newTab=\"$emit('newTab', $event)\" />\n\n <!-- Content -->\n <div class=\"flex h-full flex-1 flex-col\">\n <RouterView\n :invalidParams=\"validation.invalidParams\"\n :requestResult=\"requestResult\"\n :selectedSecuritySchemeUids=\"selectedSecuritySchemeUids\" />\n </div>\n </div>\n </div>\n</template>\n\n<style scoped>\n.request-text-color-text {\n color: var(--scalar-color-1);\n background: linear-gradient(\n var(--scalar-background-1),\n var(--scalar-background-3)\n );\n box-shadow: 0 0 0 1px var(--scalar-border-color);\n}\n@media screen and (max-width: 800px) {\n .sidebar-active-hide-layout {\n display: none;\n }\n .sidebar-active-width {\n width: 100%;\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport { isDefined } from '@scalar/helpers/array/is-defined'\nimport { safeJSON } from '@scalar/object-utils/parse'\nimport { useToasts } from '@scalar/use-toasts'\nimport { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'\nimport { RouterView } from 'vue-router'\n\nimport SidebarToggle from '@/components/Sidebar/SidebarToggle.vue'\nimport { useLayout } from '@/hooks'\nimport { useAnalytics } from '@/hooks/useAnalytics'\nimport { useClientConfig } from '@/hooks/useClientConfig'\nimport { useSidebar } from '@/hooks/useSidebar'\nimport { ERRORS } from '@/libs'\nimport { createRequestOperation } from '@/libs/send-request'\nimport type { SendRequestResult } from '@/libs/send-request/create-request-operation'\nimport {\n validateParameters,\n type ValidationResult,\n} from '@/libs/validate-parameters'\nimport { usePluginManager } from '@/plugins'\nimport { useWorkspace } from '@/store'\nimport { useActiveEntities } from '@/store/active-entities'\nimport { useOpenApiWatcher } from '@/views/Request/hooks/useOpenApiWatcher'\n\nimport RequestSidebar from './RequestSidebar.vue'\n\ndefineEmits<(e: 'newTab', item: { name: string; uid: string }) => void>()\nconst workspaceContext = useWorkspace()\nconst { toast } = useToasts()\nconst { layout } = useLayout()\nconst config = useClientConfig()\nconst { isSidebarOpen } = useSidebar()\nconst analytics = useAnalytics()\n\nconst {\n activeCollection,\n activeExample,\n activeEnvironment,\n activeRequest,\n activeWorkspace,\n activeServer,\n} = useActiveEntities()\nconst {\n cookies,\n requestHistory,\n showSidebar,\n securitySchemes,\n modalState,\n events,\n} = workspaceContext\n\nconst pluginManager = usePluginManager()\n\n/** Root element (bound in template via ref=\"_element\") */\nconst _element = ref<HTMLDivElement>()\nvoid _element\n\nconst requestAbortController = ref<AbortController>()\n/** Computed Validation State Update on Example Change */\nconst validation = computed<ValidationResult>(() =>\n validateParameters(activeExample.value ?? null),\n)\nconst requestResult = ref<SendRequestResult | null>(null)\n\n/**\n * Selected scheme UIDs\n *\n * In the modal we use collection.selectedSecuritySchemes and in the\n * standalone client we use request.selectedSecuritySchemeUids\n *\n * These are centralized here so they can be drilled down AND used in send-request\n */\nconst selectedSecuritySchemeUids = computed(\n () =>\n (activeCollection.value?.useCollectionSecurity\n ? activeCollection.value?.selectedSecuritySchemeUids\n : activeRequest.value?.selectedSecuritySchemeUids) ?? [],\n)\n\n/**\n * Execute the request\n * called from the send button as well as keyboard shortcuts\n */\nconst executeRequest = async () => {\n if (!activeRequest.value || !activeExample.value || !activeCollection.value) {\n return\n }\n\n // Block request if there are empty required path parameters\n if (validation.value.hasBlockingErrors) {\n toast('Path parameters must have values.', 'error')\n events.requestStatus.emit('abort')\n return\n }\n\n const environmentValue =\n typeof activeEnvironment.value === 'object'\n ? activeEnvironment.value.value\n : '{}'\n const e = safeJSON.parse(environmentValue)\n if (e.error) {\n console.error('INVALID ENVIRONMENT!')\n }\n const environment =\n e.error || typeof e.data !== 'object' ? {} : (e.data ?? {})\n\n const globalCookies =\n activeWorkspace.value?.cookies.map((c) => cookies[c]).filter(isDefined) ??\n []\n\n const server =\n activeCollection.value?.info?.title === 'Drafts'\n ? undefined\n : activeServer.value\n\n const [error, requestOperation] = createRequestOperation({\n request: activeRequest.value,\n example: activeExample.value,\n selectedSecuritySchemeUids: selectedSecuritySchemeUids.value,\n proxyUrl: activeWorkspace.value?.proxyUrl ?? '',\n environment,\n globalCookies,\n status: events.requestStatus,\n securitySchemes: securitySchemes,\n server,\n pluginManager,\n })\n\n // Call the onRequestSent callback if it exists\n config.value?.onRequestSent?.(activeRequest.value.path ?? '')\n\n // Error from createRequestOperation\n if (error) {\n toast(error.message, 'error')\n return\n }\n\n requestAbortController.value = requestOperation.controller\n const [sendRequestError, result] = await requestOperation.sendRequest()\n\n // Store the result to share it with child components\n requestResult.value = result\n\n // Send error toast\n if (sendRequestError) {\n toast(sendRequestError.message, 'error')\n } else {\n // We need to deep clone the result because it's a ref and updates will break the history\n requestHistory.push(cloneRequestResult(result))\n }\n}\n\n/** Cancel a live request */\nconst cancelRequest = async () =>\n requestAbortController.value?.abort(ERRORS.REQUEST_ABORTED)\n\n/** Subscribed to executeRequest, used for logging / analytics. */\nfunction logRequest() {\n analytics?.capture('client-send-request')\n}\n\n/**\n * Cancel request when closing the modal\n * @see https://github.com/scalar/scalar/issues/7115\n */\nwatch(modalState, ({ open }) => {\n if (!open) {\n void cancelRequest()\n }\n})\n\nonMounted(() => {\n events.executeRequest.on(executeRequest)\n events.executeRequest.on(logRequest)\n events.cancelRequest.on(cancelRequest)\n})\n\nuseOpenApiWatcher()\n\n/**\n * Need to manually remove listener on unmount due to vueuse memory leak\n *\n * @see https://github.com/vueuse/vueuse/issues/3498#issuecomment-2055546566\n */\nonBeforeUnmount(() => {\n events.executeRequest.off(executeRequest)\n events.executeRequest.off(logRequest)\n events.cancelRequest.off(cancelRequest)\n})\n\nconst cloneRequestResult = (result: any) => {\n // Create a structured clone that can handle Blobs, ArrayBuffers, etc.\n try {\n return structuredClone(result)\n } catch {\n // Fallback to a custom cloning approach if structuredClone fails\n // or isn't available in the environment\n const clone = { ...result }\n\n // Handle response data specifically\n if (result.response?.data) {\n // If it's a Blob/File/ArrayBuffer, store a reference\n if (\n result.response.data instanceof Blob ||\n result.response.data instanceof ArrayBuffer\n ) {\n clone.response.data = result.response.data\n } else {\n // For regular objects, do a deep clone\n clone.response.data = JSON.parse(JSON.stringify(result.response.data))\n }\n }\n\n return clone\n }\n}\n</script>\n\n<template>\n <!-- Layout -->\n <div\n ref=\"_element\"\n class=\"bg-b-1 relative z-0 flex h-full flex-1 flex-col overflow-hidden pt-0\"\n :class=\"{\n '!mr-0 !mb-0 !border-0': layout === 'modal',\n }\">\n <SidebarToggle\n v-if=\"showSidebar\"\n v-model=\"isSidebarOpen\"\n class=\"absolute top-2 left-3 z-50\"\n :class=\"[\n { hidden: isSidebarOpen },\n { 'xl:!flex': !isSidebarOpen },\n { '!flex': layout === 'modal' },\n ]\" />\n <div class=\"flex h-full\">\n <!-- Sidebar -->\n <RequestSidebar\n v-if=\"showSidebar\"\n @newTab=\"$emit('newTab', $event)\" />\n\n <!-- Content -->\n <div class=\"flex h-full flex-1 flex-col\">\n <RouterView\n :invalidParams=\"validation.invalidParams\"\n :requestResult=\"requestResult\"\n :selectedSecuritySchemeUids=\"selectedSecuritySchemeUids\" />\n </div>\n </div>\n </div>\n</template>\n\n<style scoped>\n.request-text-color-text {\n color: var(--scalar-color-1);\n background: linear-gradient(\n var(--scalar-background-1),\n var(--scalar-background-3)\n );\n box-shadow: 0 0 0 1px var(--scalar-border-color);\n}\n@media screen and (max-width: 800px) {\n .sidebar-active-hide-layout {\n display: none;\n }\n .sidebar-active-width {\n width: 100%;\n }\n}\n</style>\n"],"mappings":"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"}
1
+ {"version":3,"file":"RequestRoot-7xhK5_qr.js","names":["$emit","$emit","$emit"],"sources":["../src/components/Sidebar/SidebarToggle.vue","../src/components/Sidebar/SidebarToggle.vue","../src/hooks/useAnalytics.ts","../src/libs/validate-parameters.ts","../src/views/Request/hooks/useOpenApiWatcher.ts","../src/components/EnvironmentSelector/EnvironmentSelector.vue","../src/components/EnvironmentSelector/EnvironmentSelector.vue","../src/components/Search/useSearch.ts","../src/views/Request/handle-drag.ts","../src/components/Sidebar/Actions/EditSidebarListCollection.vue","../src/components/Sidebar/Actions/EditSidebarListCollection.vue","../src/views/Request/RequestSidebarItemMenu.vue","../src/views/Request/RequestSidebarItemMenu.vue","../src/views/Request/RequestSection/helpers/getting-started.ts","../src/views/Request/RequestSidebarItem.vue","../src/views/Request/RequestSidebarItem.vue","../src/views/Request/RequestSidebar.vue","../src/views/Request/RequestSidebar.vue","../src/views/Request/RequestRoot.vue","../src/views/Request/RequestRoot.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { useSidebar } from '@/hooks/useSidebar'\n\nconst { isSidebarOpen, toggleSidebarOpen } = useSidebar()\n</script>\n<template>\n <button\n :aria-pressed=\"isSidebarOpen\"\n class=\"scalar-sidebar-toggle text-c-3 hover:bg-b-2 active:text-c-1 rounded-lg p-2\"\n type=\"button\"\n @click=\"toggleSidebarOpen\">\n <span class=\"sr-only\">{{ isSidebarOpen ? 'Hide' : 'Show' }} sidebar</span>\n <svg\n class=\"size-4\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <clipPath id=\"mask\">\n <path\n clip-rule=\"evenodd\"\n d=\"M9 3.2H4c-1.7 0-3 1.3-3 3v11.5c0 1.7 1.3 3 3 3h5V3.2z\" />\n </clipPath>\n </defs>\n <g clip-path=\"url(#mask)\">\n <path\n class=\"transition-transform duration-300\"\n :class=\"isSidebarOpen ? 'translate-x-0' : '-translate-x-1/2'\"\n d=\"M1 3.2h8v17.5H1z\"\n fill=\"currentColor\" />\n </g>\n <path\n d=\"M20 20.8H4c-1.7 0-3-1.3-3-3V6.2c0-1.7 1.3-3 3-3h16c1.7 0 3 1.3 3 3v11.5c0 1.7-1.3 3-3 3zM9 3.2v17.5\"\n stroke=\"currentColor\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\" />\n </svg>\n </button>\n</template>\n","<script setup lang=\"ts\">\nimport { useSidebar } from '@/hooks/useSidebar'\n\nconst { isSidebarOpen, toggleSidebarOpen } = useSidebar()\n</script>\n<template>\n <button\n :aria-pressed=\"isSidebarOpen\"\n class=\"scalar-sidebar-toggle text-c-3 hover:bg-b-2 active:text-c-1 rounded-lg p-2\"\n type=\"button\"\n @click=\"toggleSidebarOpen\">\n <span class=\"sr-only\">{{ isSidebarOpen ? 'Hide' : 'Show' }} sidebar</span>\n <svg\n class=\"size-4\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <clipPath id=\"mask\">\n <path\n clip-rule=\"evenodd\"\n d=\"M9 3.2H4c-1.7 0-3 1.3-3 3v11.5c0 1.7 1.3 3 3 3h5V3.2z\" />\n </clipPath>\n </defs>\n <g clip-path=\"url(#mask)\">\n <path\n class=\"transition-transform duration-300\"\n :class=\"isSidebarOpen ? 'translate-x-0' : '-translate-x-1/2'\"\n d=\"M1 3.2h8v17.5H1z\"\n fill=\"currentColor\" />\n </g>\n <path\n d=\"M20 20.8H4c-1.7 0-3-1.3-3-3V6.2c0-1.7 1.3-3 3-3h16c1.7 0 3 1.3 3 3v11.5c0 1.7-1.3 3-3 3zM9 3.2v17.5\"\n stroke=\"currentColor\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\" />\n </svg>\n </button>\n</template>\n","import { analytics } from '@/analytics'\nimport { useClientConfig } from '@/hooks/useClientConfig'\nimport { useLayout } from '@/hooks/useLayout'\n\n/** Gets the correct analytics client based on the layout. */\nexport function useAnalytics() {\n const { layout } = useLayout()\n const config = useClientConfig()\n\n if (!config.value.telemetry || layout === 'modal') {\n return\n }\n\n // Return the correct analytics client\n return analytics\n}\n","import type { RequestExample } from '@scalar/oas-utils/entities/spec'\n\nexport type ValidationResult = {\n invalidParams: Set<string>\n hasBlockingErrors: boolean\n}\n\n/**\n * Validate required parameters from an example.\n *\n * Returns both the set of invalid parameter keys and a flag indicating\n * if there are blocking errors (empty required path parameters) that\n * should prevent the request from being sent.\n */\nexport const validateParameters = (example: Partial<RequestExample> | null): ValidationResult => {\n const result = {\n invalidParams: new Set<string>(),\n hasBlockingErrors: false,\n }\n\n if (!example) {\n return result\n }\n\n // Check path parameters separately - these are blocking\n example.parameters?.path?.forEach((param) => {\n if (param.enabled && param.value.trim() === '') {\n result.invalidParams.add(param.key)\n result.hasBlockingErrors = true\n }\n })\n\n // Validate other parameters - these are non-blocking\n const nonBlockingParamTypes = ['query', 'headers', 'cookies'] as const\n nonBlockingParamTypes.forEach((paramType) => {\n example.parameters?.[paramType]?.forEach((param) => {\n if (param.required && param.value === '') {\n result.invalidParams.add(param.key)\n }\n })\n })\n\n return result\n}\n","import { createHash, fetchDocument } from '@scalar/oas-utils/helpers'\nimport { parseSchema } from '@scalar/oas-utils/transforms'\nimport { useToasts } from '@scalar/use-toasts'\nimport { useTimeoutPoll } from '@vueuse/core'\nimport microdiff, { type Difference } from 'microdiff'\nimport { watch } from 'vue'\n\nimport { useWorkspace } from '@/store'\nimport { useActiveEntities } from '@/store/active-entities'\nimport { specDictionary } from '@/store/import-spec'\nimport {\n combineRenameDiffs,\n mutateCollectionDiff,\n mutateRequestDiff,\n mutateSecuritySchemeDiff,\n mutateServerDiff,\n mutateTagDiff,\n} from '@/views/Request/libs/watch-mode'\n\n/** Timeout for the watch mode polling */\nconst POLLING_INTERVAL = 5 * 1000 // 5 seconds\n\n/** Pause for 60 seconds after an error */\nconst ERROR_TIMEOUT = 60 * 1000 // 60 seconds\n\n/**\n * Hook which handles polling the documentUrl for changes then attempts to merge what is new\n *\n * TODO:\n * - check lastModified or similar headers\n * - speed up the polling when there's a change then slowly slow it down\n */\nexport const useOpenApiWatcher = () => {\n const { toast } = useToasts()\n const activeEntities = useActiveEntities()\n const store = useWorkspace()\n\n const { activeCollection, activeWorkspace } = activeEntities\n const { collectionMutators } = store\n\n /** Little toast helper */\n const toastError = (type: string) => toast(`[useOpenApiWatcher] Changes to the ${type} were not applied`, 'error')\n\n // Transforms and applies the diff to our mutators\n const applyDiff = (d: Difference) => {\n // Info/Security\n if (d.path[0] === 'info' || d.path[0] === 'security') {\n const success = mutateCollectionDiff(d, activeEntities, store)\n if (!success) {\n toastError('collection')\n }\n }\n // Components.securitySchemes\n else if (d.path[0] === 'components' && d.path[1] === 'securitySchemes') {\n const success = mutateSecuritySchemeDiff(d, activeEntities, store)\n if (!success) {\n toastError('securitySchemes')\n }\n }\n // Servers\n else if (d.path[0] === 'servers') {\n const success = mutateServerDiff(d, activeEntities, store)\n if (!success) {\n toastError('servers')\n }\n }\n // Tags\n else if (d.path[0] === 'tags') {\n const success = mutateTagDiff(d, activeEntities, store)\n if (!success) {\n toastError('tags')\n }\n }\n // Requests\n else if (d.path[0] === 'paths') {\n const success = mutateRequestDiff(d, activeEntities, store)\n if (!success) {\n toastError('requests')\n }\n }\n }\n\n const { pause, resume } = useTimeoutPoll(async () => {\n const url = activeCollection.value?.documentUrl\n if (!url) {\n return\n }\n\n const old = specDictionary[url]\n\n try {\n // Grab the new spec\n const spec = await fetchDocument(url, activeWorkspace.value?.proxyUrl, undefined, false)\n const hash = createHash(spec)\n\n collectionMutators.edit(activeCollection.value.uid, 'watchModeStatus', 'WATCHING')\n\n // If we have no previous copy then store this one\n if (!old?.hash) {\n const { schema } = await parseSchema(spec)\n\n if (schema) {\n specDictionary[url] = {\n hash,\n schema,\n }\n }\n }\n // If the hashes do not match, start diffin\n else if (old.hash && old.hash !== hash) {\n const { schema } = await parseSchema(spec)\n const diff = microdiff(old.schema, schema)\n\n // Combines add/remove diffs into single rename diffs\n const combined = combineRenameDiffs(diff)\n\n try {\n // Transform and apply the diffs to our mutators\n combined.forEach(applyDiff)\n\n // Update the dict\n specDictionary[url] = {\n hash,\n schema,\n }\n } catch (e) {\n console.error('[useOpenApiWatcher] Error:', e)\n }\n } else {\n console.log('[useOpenApiWatcher] No changes detected yet…')\n }\n } catch (e) {\n console.error('[useOpenApiWatcher] Error:', e)\n console.info('[useOpenApiWatcher] Pausing watcher for 60 seconds')\n\n pause()\n collectionMutators.edit(activeCollection.value.uid, 'watchModeStatus', 'ERROR')\n toast('[useOpenApiWatcher] Unable to fetch the spec file, paused the watcher for 60 seconds', 'error')\n\n setTimeout(() => {\n console.info('[useOpenApiWatcher] Resuming watcher')\n resume()\n }, ERROR_TIMEOUT)\n }\n }, POLLING_INTERVAL)\n\n // Ensure we are only polling when we should watchMode\n watch(\n [() => activeCollection.value?.documentUrl, () => activeCollection.value?.watchMode],\n ([documentUrl, watchMode]) => {\n if (documentUrl && watchMode) {\n console.info(`[useOpenApiWatcher] Watching ${documentUrl} …`)\n resume()\n } else if (activeCollection.value) {\n pause()\n collectionMutators.edit(activeCollection.value.uid, 'watchModeStatus', 'IDLE')\n }\n },\n { immediate: true },\n )\n}\n","<script setup lang=\"ts\">\nimport {\n ScalarButton,\n ScalarDropdown,\n ScalarDropdownDivider,\n ScalarDropdownItem,\n ScalarIcon,\n ScalarListboxCheckbox,\n} from '@scalar/components'\nimport type { Collection } from '@scalar/oas-utils/entities/spec'\nimport { computed, onMounted, watch } from 'vue'\nimport { useRouter } from 'vue-router'\n\nimport { useLayout } from '@/hooks'\nimport { PathId } from '@/routes'\nimport { useWorkspace } from '@/store'\nimport { useActiveEntities } from '@/store/active-entities'\n\nconst { activeCollection, activeWorkspace, activeEnvironment } =\n useActiveEntities()\nconst { collectionMutators } = useWorkspace()\nconst { layout } = useLayout()\n\nconst router = useRouter()\n\nconst updateSelected = (uid: string) => {\n if (activeCollection.value && activeWorkspace.value) {\n collectionMutators.edit(\n activeCollection.value.uid,\n 'x-scalar-active-environment',\n uid,\n )\n\n activeWorkspace.value.activeEnvironmentId = uid\n }\n}\n\nconst redirectToEnvironments = () =>\n router.push({\n name: 'environment.default',\n params: {\n [PathId.Workspace]: activeWorkspace.value?.uid,\n },\n })\n\nconst selectedEnvironment = computed(() => {\n const { value: environment } = activeEnvironment\n const { value: collection } = activeCollection\n return (\n environment?.name ||\n collection?.['x-scalar-active-environment'] ||\n 'No Environment'\n )\n})\n\nconst availableEnvironments = computed(() => {\n const { value: collection } = activeCollection\n const environments = collection?.['x-scalar-environments']\n return environments\n ? Object.entries(environments).map(([key, env]) => ({\n ...env,\n uid: key,\n name: key,\n }))\n : []\n})\n\nconst selectLatestEnvironment = () => {\n const environments = availableEnvironments.value\n if (environments.length > 0) {\n // Get the latest created collection environment\n const latestEnvironment = environments[environments.length - 1]\n\n if (latestEnvironment?.uid) {\n updateSelected(latestEnvironment.uid)\n }\n }\n}\n\n// Select for the collection its latest environment on creation\nwatch(availableEnvironments, (newEnvs, oldEnvs) => {\n if (newEnvs.length > oldEnvs.length) {\n selectLatestEnvironment()\n }\n})\n\nconst setInitialEnvironment = (collection: Collection) => {\n const activeEnv = collection['x-scalar-active-environment']\n if (activeEnv && activeCollection.value && activeWorkspace.value) {\n activeCollection.value['x-scalar-active-environment'] = activeEnv\n activeWorkspace.value.activeEnvironmentId = activeEnv\n } else if (activeWorkspace.value) {\n activeWorkspace.value.activeEnvironmentId = ''\n }\n}\n\nwatch(\n activeCollection,\n (newCollection) => newCollection && setInitialEnvironment(newCollection),\n)\n\nonMounted(() => {\n activeCollection.value && setInitialEnvironment(activeCollection.value)\n})\n</script>\n<template>\n <ScalarDropdown teleport>\n <ScalarButton\n class=\"text-c-1 hover:bg-b-2 line-clamp-1 h-auto w-fit justify-start px-1.5 py-1.5 font-normal\"\n variant=\"ghost\">\n <h2 class=\"m-0 flex items-center gap-1.5 font-medium whitespace-nowrap\">\n {{ selectedEnvironment }}\n </h2>\n </ScalarButton>\n <!-- Workspace list -->\n <template #items>\n <ScalarDropdownItem\n v-for=\"environment in availableEnvironments\"\n :key=\"environment.uid\"\n class=\"group/item flex items-center gap-1.5 overflow-hidden text-ellipsis whitespace-nowrap\"\n @click.stop=\"updateSelected(environment.uid)\">\n <ScalarListboxCheckbox\n :selected=\"\n activeCollection?.['x-scalar-active-environment'] ===\n environment.uid\n \" />\n {{ environment.name }}\n </ScalarDropdownItem>\n <ScalarDropdownItem\n class=\"group/item flex items-center gap-1.5 overflow-hidden text-ellipsis whitespace-nowrap\"\n @click.stop=\"updateSelected('')\">\n <ScalarListboxCheckbox\n :selected=\"\n (activeEnvironment?.uid === '' &&\n activeCollection?.['x-scalar-active-environment'] === '') ||\n activeEnvironment?.name === 'No Environment'\n \" />\n No Environment\n </ScalarDropdownItem>\n <ScalarDropdownDivider />\n <!-- Manage environments -->\n <ScalarDropdownItem\n v-if=\"layout !== 'modal'\"\n class=\"flex items-center gap-1.5\"\n @click=\"redirectToEnvironments\">\n <div class=\"flex h-4 w-4 items-center justify-center\">\n <ScalarIcon\n icon=\"Brackets\"\n size=\"sm\" />\n </div>\n <span class=\"leading-none\">Manage Environments</span>\n </ScalarDropdownItem>\n </template>\n </ScalarDropdown>\n</template>\n","<script setup lang=\"ts\">\nimport {\n ScalarButton,\n ScalarDropdown,\n ScalarDropdownDivider,\n ScalarDropdownItem,\n ScalarIcon,\n ScalarListboxCheckbox,\n} from '@scalar/components'\nimport type { Collection } from '@scalar/oas-utils/entities/spec'\nimport { computed, onMounted, watch } from 'vue'\nimport { useRouter } from 'vue-router'\n\nimport { useLayout } from '@/hooks'\nimport { PathId } from '@/routes'\nimport { useWorkspace } from '@/store'\nimport { useActiveEntities } from '@/store/active-entities'\n\nconst { activeCollection, activeWorkspace, activeEnvironment } =\n useActiveEntities()\nconst { collectionMutators } = useWorkspace()\nconst { layout } = useLayout()\n\nconst router = useRouter()\n\nconst updateSelected = (uid: string) => {\n if (activeCollection.value && activeWorkspace.value) {\n collectionMutators.edit(\n activeCollection.value.uid,\n 'x-scalar-active-environment',\n uid,\n )\n\n activeWorkspace.value.activeEnvironmentId = uid\n }\n}\n\nconst redirectToEnvironments = () =>\n router.push({\n name: 'environment.default',\n params: {\n [PathId.Workspace]: activeWorkspace.value?.uid,\n },\n })\n\nconst selectedEnvironment = computed(() => {\n const { value: environment } = activeEnvironment\n const { value: collection } = activeCollection\n return (\n environment?.name ||\n collection?.['x-scalar-active-environment'] ||\n 'No Environment'\n )\n})\n\nconst availableEnvironments = computed(() => {\n const { value: collection } = activeCollection\n const environments = collection?.['x-scalar-environments']\n return environments\n ? Object.entries(environments).map(([key, env]) => ({\n ...env,\n uid: key,\n name: key,\n }))\n : []\n})\n\nconst selectLatestEnvironment = () => {\n const environments = availableEnvironments.value\n if (environments.length > 0) {\n // Get the latest created collection environment\n const latestEnvironment = environments[environments.length - 1]\n\n if (latestEnvironment?.uid) {\n updateSelected(latestEnvironment.uid)\n }\n }\n}\n\n// Select for the collection its latest environment on creation\nwatch(availableEnvironments, (newEnvs, oldEnvs) => {\n if (newEnvs.length > oldEnvs.length) {\n selectLatestEnvironment()\n }\n})\n\nconst setInitialEnvironment = (collection: Collection) => {\n const activeEnv = collection['x-scalar-active-environment']\n if (activeEnv && activeCollection.value && activeWorkspace.value) {\n activeCollection.value['x-scalar-active-environment'] = activeEnv\n activeWorkspace.value.activeEnvironmentId = activeEnv\n } else if (activeWorkspace.value) {\n activeWorkspace.value.activeEnvironmentId = ''\n }\n}\n\nwatch(\n activeCollection,\n (newCollection) => newCollection && setInitialEnvironment(newCollection),\n)\n\nonMounted(() => {\n activeCollection.value && setInitialEnvironment(activeCollection.value)\n})\n</script>\n<template>\n <ScalarDropdown teleport>\n <ScalarButton\n class=\"text-c-1 hover:bg-b-2 line-clamp-1 h-auto w-fit justify-start px-1.5 py-1.5 font-normal\"\n variant=\"ghost\">\n <h2 class=\"m-0 flex items-center gap-1.5 font-medium whitespace-nowrap\">\n {{ selectedEnvironment }}\n </h2>\n </ScalarButton>\n <!-- Workspace list -->\n <template #items>\n <ScalarDropdownItem\n v-for=\"environment in availableEnvironments\"\n :key=\"environment.uid\"\n class=\"group/item flex items-center gap-1.5 overflow-hidden text-ellipsis whitespace-nowrap\"\n @click.stop=\"updateSelected(environment.uid)\">\n <ScalarListboxCheckbox\n :selected=\"\n activeCollection?.['x-scalar-active-environment'] ===\n environment.uid\n \" />\n {{ environment.name }}\n </ScalarDropdownItem>\n <ScalarDropdownItem\n class=\"group/item flex items-center gap-1.5 overflow-hidden text-ellipsis whitespace-nowrap\"\n @click.stop=\"updateSelected('')\">\n <ScalarListboxCheckbox\n :selected=\"\n (activeEnvironment?.uid === '' &&\n activeCollection?.['x-scalar-active-environment'] === '') ||\n activeEnvironment?.name === 'No Environment'\n \" />\n No Environment\n </ScalarDropdownItem>\n <ScalarDropdownDivider />\n <!-- Manage environments -->\n <ScalarDropdownItem\n v-if=\"layout !== 'modal'\"\n class=\"flex items-center gap-1.5\"\n @click=\"redirectToEnvironments\">\n <div class=\"flex h-4 w-4 items-center justify-center\">\n <ScalarIcon\n icon=\"Brackets\"\n size=\"sm\" />\n </div>\n <span class=\"leading-none\">Manage Environments</span>\n </ScalarDropdownItem>\n </template>\n </ScalarDropdown>\n</template>\n","import type { Request } from '@scalar/oas-utils/entities/spec'\nimport { isDefined, shouldIgnoreEntity } from '@scalar/oas-utils/helpers'\nimport Fuse, { type FuseResult } from 'fuse.js'\nimport { computed, nextTick, ref, watch } from 'vue'\nimport { useRouter } from 'vue-router'\n\nimport { PathId } from '@/routes'\nimport { useWorkspace } from '@/store'\nimport { useActiveEntities } from '@/store/active-entities'\n\n/**\n * Hook for managing search functionality.\n * Provides search state, results, and methods for searching.\n */\nexport function useSearch() {\n const router = useRouter()\n const { activeWorkspace, activeWorkspaceRequests, activeWorkspaceCollections } = useActiveEntities()\n const { requests, tags } = useWorkspace()\n\n type FuseData = {\n title: string\n description: string\n httpVerb: string\n id: string\n path: string\n link: string | undefined\n }\n\n const fuseDataArray = ref<FuseData[]>([])\n const searchResults = ref<FuseResult<FuseData>[]>([])\n const selectedSearchResult = ref<number>(0)\n const searchText = ref<string>('')\n const searchInputRef = ref<HTMLInputElement | null>(null)\n const searchResultRefs = ref<HTMLElement[]>([])\n\n const fuse = new Fuse(fuseDataArray.value, {\n keys: ['title', 'description', 'body'],\n })\n\n const resetSearch = () => {\n searchText.value = ''\n selectedSearchResult.value = 0\n searchResults.value = []\n if (searchInputRef.value instanceof HTMLInputElement) {\n searchInputRef.value.blur()\n }\n }\n\n const populateFuseDataArray = (items: Request[]) => {\n fuseDataArray.value = items\n // TODO: We should probably filter in the store or somewhere else.\n // Check if the request is marked has hidden/internal\n .filter((request) => !shouldIgnoreEntity(request))\n // Check if the request is in a tag that is marked has hidden/internal\n .filter((request) => {\n // Find the collection for the request\n const collection = activeWorkspaceCollections.value?.find((activeWorkspaceCollection) =>\n activeWorkspaceCollection.requests.includes(request.uid),\n )\n\n const hasIgnoredTags = Boolean(\n collection?.tags\n .map((uid) => tags[uid])\n .filter(isDefined)\n .filter((tag) => request.tags?.includes(tag.name))\n .filter((tag) => shouldIgnoreEntity(tag)).length,\n )\n\n return !hasIgnoredTags\n })\n .map((request: Request) => ({\n id: request.uid,\n title: request.summary ?? request.method,\n description: request.description ?? '',\n httpVerb: request.method,\n path: request.path,\n link: router?.resolve({\n name: 'request',\n params: {\n [PathId.Request]: request.uid,\n [PathId.Workspace]: activeWorkspace.value?.uid,\n },\n })?.href,\n }))\n\n fuse.setCollection(fuseDataArray.value)\n }\n\n const fuseSearch = (): void => {\n selectedSearchResult.value = 0\n searchResults.value = fuse.search(searchText.value)\n }\n\n watch(searchText, (newValue) => {\n if (newValue.length) {\n fuseSearch()\n } else {\n searchResults.value = []\n }\n })\n\n const navigateSearchResults = (direction: 'up' | 'down') => {\n const offset = direction === 'up' ? -1 : 1\n const length = searchResultsWithPlaceholderResults.value.length\n\n // Ensures we loop around the array by using the remainder\n selectedSearchResult.value = (selectedSearchResult.value + offset + length) % length\n\n // Scroll the selected item into view\n nextTick(() => {\n const element = searchResultRefs.value[selectedSearchResult.value]\n if (element instanceof HTMLElement) {\n element.scrollIntoView({\n behavior: 'smooth',\n block: 'center',\n })\n }\n })\n }\n\n const selectSearchResult = () => {\n if (selectedSearchResult.value >= 0) {\n const selectedResult = searchResultsWithPlaceholderResults.value[selectedSearchResult.value]\n if (selectedResult) {\n onSearchResultClick(selectedResult)\n }\n }\n }\n\n const validRequests = computed(() => activeWorkspaceRequests.value.map((uid) => requests[uid]).filter(isDefined))\n\n // Populate our fuseDataArray with the request items\n watch(\n activeWorkspaceRequests,\n () => {\n populateFuseDataArray(validRequests.value)\n },\n { immediate: true },\n )\n\n const onSearchResultClick = (entry: FuseResult<FuseData>) => {\n router.push(entry.item.id)\n resetSearch()\n }\n\n const searchResultsWithPlaceholderResults = computed((): FuseResult<FuseData>[] => {\n if (searchText.value.length === 0) {\n return fuseDataArray.value.map((item) => {\n return {\n item: item,\n } as FuseResult<FuseData>\n })\n }\n\n return searchResults.value\n })\n\n return {\n searchText,\n searchResultsWithPlaceholderResults,\n selectedSearchResult,\n onSearchResultClick,\n fuseSearch,\n searchInputRef,\n searchResultRefs,\n navigateSearchResults,\n selectSearchResult,\n populateFuseDataArray,\n }\n}\n","import type { DraggingItem, HoveredItem } from '@scalar/draggable'\nimport type { Collection, Tag } from '@scalar/oas-utils/entities/spec'\n\nimport { useLayout } from '@/hooks'\nimport type { WorkspaceStore } from '@/store'\nimport type { ActiveEntitiesStore } from '@/store/active-entities'\n\n/** Create DnD handlers */\nexport function dragHandlerFactory(\n activeWorkspace: ActiveEntitiesStore['activeWorkspace'],\n { collections, collectionMutators, tags, tagMutators, workspaceMutators }: WorkspaceStore,\n) {\n const { layout } = useLayout()\n\n /** Mutate tag OR collection */\n const mutateTagOrCollection = (parent: Collection | Tag, childUids: string[]) => {\n if (parent.type === 'collection') {\n collectionMutators.edit(parent.uid, 'children', childUids as Collection['children'])\n } else if (parent.type === 'tag') {\n tagMutators.edit(parent.uid, 'children', childUids as Tag['children'])\n }\n }\n\n /** Drag handler that mutates depending on the entity types */\n const handleDragEnd = (draggingItem: DraggingItem, hoveredItem: HoveredItem) => {\n if (!draggingItem || !hoveredItem) {\n return\n }\n\n const { id: draggingUid, parentId: draggingParentUid } = draggingItem\n const { id: hoveredUid, parentId: hoveredParentUid, offset } = hoveredItem\n\n // Parent is the workspace\n if (!draggingParentUid) {\n workspaceMutators.edit(\n activeWorkspace.value?.uid,\n 'collections',\n activeWorkspace.value?.collections.filter((uid) => uid !== draggingUid) ?? [],\n )\n }\n\n // Parent is collection\n else if (collections[draggingParentUid]) {\n collectionMutators.edit(\n draggingParentUid as Collection['uid'],\n 'children',\n collections[draggingParentUid].children.filter((uid) => uid !== draggingUid),\n )\n }\n // Parent is a tag\n else if (tags[draggingParentUid]) {\n tagMutators.edit(\n draggingParentUid as Tag['uid'],\n 'children',\n tags[draggingParentUid].children.filter((uid) => uid !== draggingUid),\n )\n }\n\n // Place it at the end of the list of the hoveredItem\n if (offset === 2) {\n const parent = collections[hoveredUid] || tags[hoveredUid]\n if (parent) {\n mutateTagOrCollection(parent, [...(parent.children ?? []), draggingUid])\n }\n }\n // Special case for collections\n else if (!hoveredParentUid) {\n const newChildUids = [...(activeWorkspace.value?.collections ?? [])]\n const hoveredIndex = newChildUids.findIndex((uid) => hoveredUid === uid) ?? 0\n newChildUids.splice(hoveredIndex + offset, 0, draggingUid as Collection['uid'])\n\n workspaceMutators.edit(activeWorkspace.value?.uid, 'collections', newChildUids)\n }\n // Place it into the list at an index\n else {\n const parent = collections[hoveredParentUid] || tags[hoveredParentUid]\n if (!parent) {\n return\n }\n\n const newChildUids = [...(parent.children ?? [])] as string[]\n const hoveredIndex = newChildUids.findIndex((uid) => hoveredUid === uid) ?? 0\n newChildUids.splice(hoveredIndex + offset, 0, draggingUid)\n\n mutateTagOrCollection(parent, newChildUids)\n }\n }\n\n /** Ensure only collections are allowed at the top level OR resources dropped INTO (offset 2) */\n const isDroppable = (draggingItem: DraggingItem, hoveredItem: HoveredItem) => {\n // Cannot drop in read only mode\n if (layout === 'modal') {\n return false\n }\n // Cannot drop requests/folders into a workspace\n if (!collections[draggingItem.id] && hoveredItem.offset !== 2) {\n return false\n }\n // Collections cannot drop over Drafts\n if (collections[draggingItem.id] && collections[hoveredItem.id]?.info?.title === 'Drafts') {\n return false\n }\n\n return true\n }\n\n return {\n handleDragEnd,\n isDroppable,\n }\n}\n","<script setup lang=\"ts\">\nimport { ScalarButton, ScalarTextInput } from '@scalar/components'\nimport { LibraryIcon } from '@scalar/icons/library'\nimport { ref } from 'vue'\n\nimport IconSelector from '@/components/IconSelector.vue'\nimport SidebarListElementForm from '@/components/Sidebar/Actions/SidebarListElementForm.vue'\n\nconst props = defineProps<{\n name: string\n icon: string\n}>()\n\nconst emit = defineEmits<{\n (e: 'close'): void\n (e: 'edit', newName: string, newIcon: string): void\n}>()\n\nconst newName = ref(props.name)\nconst newIcon = ref(props.icon)\n</script>\n<template>\n <SidebarListElementForm\n @cancel=\"emit('close')\"\n @submit=\"emit('edit', newName, newIcon)\">\n <div class=\"grid grid-cols-[auto_1fr] gap-2\">\n <div class=\"flex aspect-square\">\n <IconSelector\n v-model=\"newIcon\"\n placement=\"bottom-start\">\n <ScalarButton\n class=\"aspect-square h-auto px-0\"\n variant=\"outlined\">\n <LibraryIcon\n class=\"text-c-2 size-4\"\n :src=\"newIcon\" />\n </ScalarButton>\n </IconSelector>\n </div>\n <ScalarTextInput\n v-model=\"newName\"\n autofocus\n class=\"flex-1\" />\n </div>\n </SidebarListElementForm>\n</template>\n","<script setup lang=\"ts\">\nimport { ScalarButton, ScalarTextInput } from '@scalar/components'\nimport { LibraryIcon } from '@scalar/icons/library'\nimport { ref } from 'vue'\n\nimport IconSelector from '@/components/IconSelector.vue'\nimport SidebarListElementForm from '@/components/Sidebar/Actions/SidebarListElementForm.vue'\n\nconst props = defineProps<{\n name: string\n icon: string\n}>()\n\nconst emit = defineEmits<{\n (e: 'close'): void\n (e: 'edit', newName: string, newIcon: string): void\n}>()\n\nconst newName = ref(props.name)\nconst newIcon = ref(props.icon)\n</script>\n<template>\n <SidebarListElementForm\n @cancel=\"emit('close')\"\n @submit=\"emit('edit', newName, newIcon)\">\n <div class=\"grid grid-cols-[auto_1fr] gap-2\">\n <div class=\"flex aspect-square\">\n <IconSelector\n v-model=\"newIcon\"\n placement=\"bottom-start\">\n <ScalarButton\n class=\"aspect-square h-auto px-0\"\n variant=\"outlined\">\n <LibraryIcon\n class=\"text-c-2 size-4\"\n :src=\"newIcon\" />\n </ScalarButton>\n </IconSelector>\n </div>\n <ScalarTextInput\n v-model=\"newName\"\n autofocus\n class=\"flex-1\" />\n </div>\n </SidebarListElementForm>\n</template>\n","<script setup lang=\"ts\">\nimport {\n ScalarDropdownButton,\n ScalarDropdownMenu,\n ScalarFloating,\n ScalarIcon,\n ScalarModal,\n useModal,\n type ScalarDropdown,\n} from '@scalar/components'\nimport type { Collection } from '@scalar/oas-utils/entities/spec'\nimport { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'\nimport { useRouter } from 'vue-router'\n\nimport DeleteSidebarListElement from '@/components/Sidebar/Actions/DeleteSidebarListElement.vue'\nimport EditSidebarListCollection from '@/components/Sidebar/Actions/EditSidebarListCollection.vue'\nimport EditSidebarListElement from '@/components/Sidebar/Actions/EditSidebarListElement.vue'\nimport { PathId } from '@/routes'\nimport { useWorkspace } from '@/store'\nimport { useActiveEntities } from '@/store/active-entities'\nimport { createInitialRequest } from '@/store/requests'\nimport type { SidebarMenuItem } from '@/views/Request/types'\n\nconst props = defineProps<{ menuItem: SidebarMenuItem }>()\n\nconst emit = defineEmits<{\n (e: 'closeMenu'): []\n (e: 'toggleWatchMode', item: SidebarMenuItem['item']): void\n (e: 'clearDrafts'): void\n}>()\n\nconst { replace } = useRouter()\nconst {\n activeRouterParams,\n activeWorkspaceCollections,\n activeWorkspaceRequests,\n} = useActiveEntities()\nconst { events, requestMutators } = useWorkspace()\n\nconst editModal = useModal()\nconst deleteModal = useModal()\nconst clearDraftsModal = useModal()\n\n/** Add example */\nconst handleAddExample = () =>\n events.commandPalette.emit({\n commandName: 'Add Example',\n metaData: {\n itemUid: props.menuItem.item?.entity.uid,\n },\n })\n\nconst handleEdit = (newName: string, newIcon?: string) => {\n props.menuItem.item?.edit(newName, newIcon)\n editModal.hide()\n}\n\n/** Delete with redirect for both requests and requestExamples */\nconst handleItemDelete = () => {\n props.menuItem.item?.delete()\n\n if (!activeWorkspaceRequests.value.length) {\n const { request } = createInitialRequest()\n const draftCollection = activeWorkspaceCollections.value.find(\n (collection: Collection) => collection.info?.title === 'Drafts',\n )\n\n if (draftCollection) {\n requestMutators.add(request, draftCollection.uid)\n\n replace({\n name: 'request',\n params: {\n [PathId.Request]: request.uid,\n },\n })\n }\n }\n\n if (\n activeRouterParams.value[PathId.Request] === props.menuItem.item?.entity.uid\n ) {\n replace({\n name: 'request',\n params: {\n [PathId.Request]: 'default',\n },\n })\n }\n\n if (\n activeRouterParams.value[PathId.Examples] ===\n props.menuItem.item?.entity.uid\n ) {\n replace({\n name: 'request',\n params: {\n [PathId.Request]: 'default',\n },\n })\n }\n\n if (activeWorkspaceCollections.value[0]) {\n const firstRequest = activeWorkspaceCollections.value[0].requests[0]\n replace({\n name: 'request',\n params: {\n [PathId.Request]: firstRequest,\n },\n })\n }\n\n deleteModal.hide()\n}\n\n// Manually focus the popup - not pretty but it works\nconst menuRef = ref<typeof ScalarDropdown | null>(null)\nwatch([() => props.menuItem.open, menuRef], ([open]) => {\n if (open && menuRef.value?.$parent?.$el) {\n menuRef.value.$parent.$el.focus()\n }\n})\n\n// Close menu on click because headless doesn't seem to work\nconst globalClickListener = () => props.menuItem.open && emit('closeMenu')\nonMounted(() => window.addEventListener('click', globalClickListener))\nonBeforeUnmount(() => window.removeEventListener('click', globalClickListener))\n\nconst toggleWatchMode = () => {\n emit('toggleWatchMode', props.menuItem.item)\n}\n\nconst handleClearDrafts = () => {\n emit('clearDrafts')\n clearDraftsModal.hide()\n}\n\nconst isDraftsMenuItem = computed(() => {\n return props.menuItem.item?.title === 'Drafts'\n})\n</script>\n\n<template>\n <ScalarFloating\n v-if=\"menuItem.targetRef && menuItem.open\"\n placement=\"right-start\"\n :target=\"menuItem.targetRef\"\n teleport>\n <template #floating>\n <ScalarDropdownMenu @keydown.escape=\"$emit('closeMenu')\">\n <!-- Add example -->\n <ScalarDropdownButton\n v-if=\"menuItem.item?.entity.type === 'request'\"\n class=\"flex items-center gap-2\"\n @click=\"handleAddExample\">\n <ScalarIcon\n class=\"inline-flex\"\n icon=\"Example\"\n size=\"md\"\n thickness=\"1.5\" />\n <span>Add Example</span>\n </ScalarDropdownButton>\n\n <!-- Rename -->\n <ScalarDropdownButton\n v-if=\"!isDraftsMenuItem\"\n ref=\"menuRef\"\n class=\"flex items-center gap-2\"\n @click=\"editModal.show()\">\n <ScalarIcon\n class=\"inline-flex\"\n icon=\"Edit\"\n size=\"md\"\n thickness=\"1.5\" />\n <span>\n <template v-if=\"menuItem.item?.entity.type === 'collection'\">\n Edit\n </template>\n <template v-else> Rename </template>\n </span>\n </ScalarDropdownButton>\n\n <!-- Duplicate -->\n <!-- <ScalarDropdownButton\n class=\"flex items-center !gap-2\"\n @click=\"handleItemDuplicate\">\n <ScalarIcon\n class=\"inline-flex\"\n thickness=\"1.5\"\n icon=\"Duplicate\"\n size=\"sm\" />\n <span>Duplicate</span>\n </ScalarDropdownButton>\n <ScalarDropdownDivider /> -->\n\n <!-- Watch -->\n <ScalarDropdownButton\n v-if=\"menuItem.item?.documentUrl\"\n ref=\"menuRef\"\n class=\"flex items-center gap-2\"\n @click=\"toggleWatchMode\">\n <ScalarIcon\n class=\"inline-flex\"\n :icon=\"menuItem.item?.watchMode ? 'Unwatch' : 'Watch'\"\n size=\"md\"\n thickness=\"1.5\" />\n <span>\n {{\n menuItem.item?.watchMode\n ? 'Disable Watch Mode'\n : 'Enable Watch Mode'\n }}\n </span>\n </ScalarDropdownButton>\n\n <!-- Delete -->\n <ScalarDropdownButton\n v-if=\"!isDraftsMenuItem\"\n class=\"flex items-center gap-2\"\n @click=\"deleteModal.show()\">\n <ScalarIcon\n class=\"inline-flex\"\n icon=\"Delete\"\n size=\"md\"\n thickness=\"1.5\" />\n <span>Delete</span>\n </ScalarDropdownButton>\n\n <!-- Clear Drafts -->\n <ScalarDropdownButton\n v-if=\"isDraftsMenuItem\"\n class=\"flex items-center gap-2\"\n @click=\"clearDraftsModal.show()\">\n <ScalarIcon\n class=\"inline-flex\"\n icon=\"Delete\"\n size=\"md\"\n thickness=\"1.5\" />\n <span>Clear Drafts</span>\n </ScalarDropdownButton>\n </ScalarDropdownMenu>\n </template>\n </ScalarFloating>\n\n <!-- Modals -->\n <ScalarModal\n :size=\"'xxs'\"\n :state=\"deleteModal\"\n :title=\"`Delete ${menuItem.item?.resourceTitle}`\">\n <DeleteSidebarListElement\n :variableName=\"menuItem.item?.title ?? ''\"\n :warningMessage=\"menuItem.item?.warning\"\n @close=\"deleteModal.hide()\"\n @delete=\"handleItemDelete\" />\n </ScalarModal>\n <ScalarModal\n :size=\"'xxs'\"\n :state=\"editModal\"\n :title=\"`Edit ${menuItem.item?.resourceTitle}`\">\n <EditSidebarListCollection\n v-if=\"menuItem.item?.resourceTitle === 'Collection'\"\n :icon=\"menuItem.item?.icon || 'interface-content-folder'\"\n :name=\"menuItem.item?.title\"\n @close=\"editModal.hide()\"\n @edit=\"handleEdit\" />\n <EditSidebarListElement\n v-else\n :name=\"menuItem.item?.title ?? ''\"\n @close=\"editModal.hide()\"\n @edit=\"handleEdit\" />\n </ScalarModal>\n <ScalarModal\n :size=\"'xxs'\"\n :state=\"clearDraftsModal\"\n :title=\"'Clear Drafts'\">\n <DeleteSidebarListElement\n :variableName=\"'All Drafts'\"\n :warningMessage=\"'This action will clear all drafts. This cannot be undone.'\"\n @close=\"clearDraftsModal.hide()\"\n @delete=\"handleClearDrafts\" />\n </ScalarModal>\n</template>\n<style scoped>\n.ellipsis-position {\n transform: translate3d(calc(-100% - 4.5px), 0, 0);\n}\n</style>\n","<script setup lang=\"ts\">\nimport {\n ScalarDropdownButton,\n ScalarDropdownMenu,\n ScalarFloating,\n ScalarIcon,\n ScalarModal,\n useModal,\n type ScalarDropdown,\n} from '@scalar/components'\nimport type { Collection } from '@scalar/oas-utils/entities/spec'\nimport { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'\nimport { useRouter } from 'vue-router'\n\nimport DeleteSidebarListElement from '@/components/Sidebar/Actions/DeleteSidebarListElement.vue'\nimport EditSidebarListCollection from '@/components/Sidebar/Actions/EditSidebarListCollection.vue'\nimport EditSidebarListElement from '@/components/Sidebar/Actions/EditSidebarListElement.vue'\nimport { PathId } from '@/routes'\nimport { useWorkspace } from '@/store'\nimport { useActiveEntities } from '@/store/active-entities'\nimport { createInitialRequest } from '@/store/requests'\nimport type { SidebarMenuItem } from '@/views/Request/types'\n\nconst props = defineProps<{ menuItem: SidebarMenuItem }>()\n\nconst emit = defineEmits<{\n (e: 'closeMenu'): []\n (e: 'toggleWatchMode', item: SidebarMenuItem['item']): void\n (e: 'clearDrafts'): void\n}>()\n\nconst { replace } = useRouter()\nconst {\n activeRouterParams,\n activeWorkspaceCollections,\n activeWorkspaceRequests,\n} = useActiveEntities()\nconst { events, requestMutators } = useWorkspace()\n\nconst editModal = useModal()\nconst deleteModal = useModal()\nconst clearDraftsModal = useModal()\n\n/** Add example */\nconst handleAddExample = () =>\n events.commandPalette.emit({\n commandName: 'Add Example',\n metaData: {\n itemUid: props.menuItem.item?.entity.uid,\n },\n })\n\nconst handleEdit = (newName: string, newIcon?: string) => {\n props.menuItem.item?.edit(newName, newIcon)\n editModal.hide()\n}\n\n/** Delete with redirect for both requests and requestExamples */\nconst handleItemDelete = () => {\n props.menuItem.item?.delete()\n\n if (!activeWorkspaceRequests.value.length) {\n const { request } = createInitialRequest()\n const draftCollection = activeWorkspaceCollections.value.find(\n (collection: Collection) => collection.info?.title === 'Drafts',\n )\n\n if (draftCollection) {\n requestMutators.add(request, draftCollection.uid)\n\n replace({\n name: 'request',\n params: {\n [PathId.Request]: request.uid,\n },\n })\n }\n }\n\n if (\n activeRouterParams.value[PathId.Request] === props.menuItem.item?.entity.uid\n ) {\n replace({\n name: 'request',\n params: {\n [PathId.Request]: 'default',\n },\n })\n }\n\n if (\n activeRouterParams.value[PathId.Examples] ===\n props.menuItem.item?.entity.uid\n ) {\n replace({\n name: 'request',\n params: {\n [PathId.Request]: 'default',\n },\n })\n }\n\n if (activeWorkspaceCollections.value[0]) {\n const firstRequest = activeWorkspaceCollections.value[0].requests[0]\n replace({\n name: 'request',\n params: {\n [PathId.Request]: firstRequest,\n },\n })\n }\n\n deleteModal.hide()\n}\n\n// Manually focus the popup - not pretty but it works\nconst menuRef = ref<typeof ScalarDropdown | null>(null)\nwatch([() => props.menuItem.open, menuRef], ([open]) => {\n if (open && menuRef.value?.$parent?.$el) {\n menuRef.value.$parent.$el.focus()\n }\n})\n\n// Close menu on click because headless doesn't seem to work\nconst globalClickListener = () => props.menuItem.open && emit('closeMenu')\nonMounted(() => window.addEventListener('click', globalClickListener))\nonBeforeUnmount(() => window.removeEventListener('click', globalClickListener))\n\nconst toggleWatchMode = () => {\n emit('toggleWatchMode', props.menuItem.item)\n}\n\nconst handleClearDrafts = () => {\n emit('clearDrafts')\n clearDraftsModal.hide()\n}\n\nconst isDraftsMenuItem = computed(() => {\n return props.menuItem.item?.title === 'Drafts'\n})\n</script>\n\n<template>\n <ScalarFloating\n v-if=\"menuItem.targetRef && menuItem.open\"\n placement=\"right-start\"\n :target=\"menuItem.targetRef\"\n teleport>\n <template #floating>\n <ScalarDropdownMenu @keydown.escape=\"$emit('closeMenu')\">\n <!-- Add example -->\n <ScalarDropdownButton\n v-if=\"menuItem.item?.entity.type === 'request'\"\n class=\"flex items-center gap-2\"\n @click=\"handleAddExample\">\n <ScalarIcon\n class=\"inline-flex\"\n icon=\"Example\"\n size=\"md\"\n thickness=\"1.5\" />\n <span>Add Example</span>\n </ScalarDropdownButton>\n\n <!-- Rename -->\n <ScalarDropdownButton\n v-if=\"!isDraftsMenuItem\"\n ref=\"menuRef\"\n class=\"flex items-center gap-2\"\n @click=\"editModal.show()\">\n <ScalarIcon\n class=\"inline-flex\"\n icon=\"Edit\"\n size=\"md\"\n thickness=\"1.5\" />\n <span>\n <template v-if=\"menuItem.item?.entity.type === 'collection'\">\n Edit\n </template>\n <template v-else> Rename </template>\n </span>\n </ScalarDropdownButton>\n\n <!-- Duplicate -->\n <!-- <ScalarDropdownButton\n class=\"flex items-center !gap-2\"\n @click=\"handleItemDuplicate\">\n <ScalarIcon\n class=\"inline-flex\"\n thickness=\"1.5\"\n icon=\"Duplicate\"\n size=\"sm\" />\n <span>Duplicate</span>\n </ScalarDropdownButton>\n <ScalarDropdownDivider /> -->\n\n <!-- Watch -->\n <ScalarDropdownButton\n v-if=\"menuItem.item?.documentUrl\"\n ref=\"menuRef\"\n class=\"flex items-center gap-2\"\n @click=\"toggleWatchMode\">\n <ScalarIcon\n class=\"inline-flex\"\n :icon=\"menuItem.item?.watchMode ? 'Unwatch' : 'Watch'\"\n size=\"md\"\n thickness=\"1.5\" />\n <span>\n {{\n menuItem.item?.watchMode\n ? 'Disable Watch Mode'\n : 'Enable Watch Mode'\n }}\n </span>\n </ScalarDropdownButton>\n\n <!-- Delete -->\n <ScalarDropdownButton\n v-if=\"!isDraftsMenuItem\"\n class=\"flex items-center gap-2\"\n @click=\"deleteModal.show()\">\n <ScalarIcon\n class=\"inline-flex\"\n icon=\"Delete\"\n size=\"md\"\n thickness=\"1.5\" />\n <span>Delete</span>\n </ScalarDropdownButton>\n\n <!-- Clear Drafts -->\n <ScalarDropdownButton\n v-if=\"isDraftsMenuItem\"\n class=\"flex items-center gap-2\"\n @click=\"clearDraftsModal.show()\">\n <ScalarIcon\n class=\"inline-flex\"\n icon=\"Delete\"\n size=\"md\"\n thickness=\"1.5\" />\n <span>Clear Drafts</span>\n </ScalarDropdownButton>\n </ScalarDropdownMenu>\n </template>\n </ScalarFloating>\n\n <!-- Modals -->\n <ScalarModal\n :size=\"'xxs'\"\n :state=\"deleteModal\"\n :title=\"`Delete ${menuItem.item?.resourceTitle}`\">\n <DeleteSidebarListElement\n :variableName=\"menuItem.item?.title ?? ''\"\n :warningMessage=\"menuItem.item?.warning\"\n @close=\"deleteModal.hide()\"\n @delete=\"handleItemDelete\" />\n </ScalarModal>\n <ScalarModal\n :size=\"'xxs'\"\n :state=\"editModal\"\n :title=\"`Edit ${menuItem.item?.resourceTitle}`\">\n <EditSidebarListCollection\n v-if=\"menuItem.item?.resourceTitle === 'Collection'\"\n :icon=\"menuItem.item?.icon || 'interface-content-folder'\"\n :name=\"menuItem.item?.title\"\n @close=\"editModal.hide()\"\n @edit=\"handleEdit\" />\n <EditSidebarListElement\n v-else\n :name=\"menuItem.item?.title ?? ''\"\n @close=\"editModal.hide()\"\n @edit=\"handleEdit\" />\n </ScalarModal>\n <ScalarModal\n :size=\"'xxs'\"\n :state=\"clearDraftsModal\"\n :title=\"'Clear Drafts'\">\n <DeleteSidebarListElement\n :variableName=\"'All Drafts'\"\n :warningMessage=\"'This action will clear all drafts. This cannot be undone.'\"\n @close=\"clearDraftsModal.hide()\"\n @delete=\"handleClearDrafts\" />\n </ScalarModal>\n</template>\n<style scoped>\n.ellipsis-position {\n transform: translate3d(calc(-100% - 4.5px), 0, 0);\n}\n</style>\n","import type { Collection, Operation } from '@scalar/oas-utils/entities/spec'\n\n/**\n * Checks if the user gets the getting started state displayed\n */\nexport const isGettingStarted = (\n activeWorkspaceCollections: Collection[],\n activeWorkspaceRequests: Operation['uid'][],\n requests: Record<string, any>,\n) => {\n const draftCollection = activeWorkspaceCollections.find((collection) => collection.info?.title === 'Drafts')\n const hasSingleRequest = activeWorkspaceRequests.length === 1\n\n if (!activeWorkspaceRequests[0]) {\n return false\n }\n const isDraftsRequest = draftCollection?.requests.includes(activeWorkspaceRequests[0])\n\n if (!isDraftsRequest) {\n return false\n }\n const isRenamed = requests[draftCollection?.requests[0] ?? '']?.summary !== 'My First Request'\n\n return hasSingleRequest && isDraftsRequest && !isRenamed\n}\n","<script setup lang=\"ts\">\nimport {\n ScalarButton,\n ScalarIcon,\n ScalarSidebarGroupToggle,\n ScalarTooltip,\n} from '@scalar/components'\nimport {\n Draggable,\n type DraggableProps,\n type DraggingItem,\n type HoveredItem,\n} from '@scalar/draggable'\nimport type { Collection, Request } from '@scalar/oas-utils/entities/spec'\nimport { shouldIgnoreEntity } from '@scalar/oas-utils/helpers'\nimport { computed, nextTick, ref } from 'vue'\nimport { RouterLink, useRouter } from 'vue-router'\n\nimport { HttpMethod } from '@/components/HttpMethod'\nimport { useLayout } from '@/hooks/useLayout'\nimport { useSidebar } from '@/hooks/useSidebar'\nimport { getModifiers } from '@/libs'\nimport { PathId } from '@/routes'\nimport { useWorkspace } from '@/store'\nimport { useActiveEntities } from '@/store/active-entities'\nimport type { SidebarItem, SidebarMenuItem } from '@/views/Request/types'\n\nconst {\n isDraggable = false,\n isDroppable = false,\n parentUids,\n uid,\n menuItem,\n} = defineProps<{\n /**\n * Toggle dragging on and off\n *\n * @default false\n */\n isDraggable?: boolean\n /**\n * Prevents items from being hovered and dropped into\n *\n * @default false\n */\n isDroppable?: DraggableProps['isDroppable']\n /** Both indicate the level and provide a way to traverse upwards */\n parentUids: string[]\n /** uid of a Collection, Tag, Request or RequestExample */\n uid: string\n /** To keep track of the menu being open */\n menuItem: SidebarMenuItem\n}>()\n\nconst emit = defineEmits<{\n onDragEnd: [draggingItem: DraggingItem, hoveredItem: HoveredItem]\n newTab: [name: string, uid: string]\n openMenu: [menuItem: SidebarMenuItem]\n}>()\n\ndefineSlots<{\n leftIcon(): void\n}>()\n\nconst { activeCollection, activeRequest, activeRouterParams, activeWorkspace } =\n useActiveEntities()\nconst {\n collections,\n tags,\n requests,\n requestExamples,\n collectionMutators,\n tagMutators,\n requestMutators,\n requestExampleMutators,\n events,\n} = useWorkspace()\nconst router = useRouter()\nconst { collapsedSidebarFolders, toggleSidebarFolder } = useSidebar()\nconst { layout } = useLayout()\n\n/** Normalize properties across different types for easy consumption */\nconst item = computed<SidebarItem>(() => {\n const collection = collections[uid]\n const tag = tags[uid]\n const request = requests[uid]\n const requestExample = requestExamples[uid]\n\n if (collection) {\n return {\n title: collection.info?.title || 'Untitled Collection',\n entity: collection,\n resourceTitle: 'Collection',\n children: collection.children,\n icon: collection['x-scalar-icon'],\n documentUrl: collection.documentUrl,\n watchMode: collection.watchMode,\n to:\n collection.uid && collection?.info?.title !== 'Drafts'\n ? {\n name: 'collection',\n params: {\n [PathId.Workspace]: activeWorkspace.value?.uid,\n [PathId.Collection]: collection.uid,\n },\n }\n : undefined,\n warning:\n \"This cannot be undone. You're about to delete the collection and all folders and requests inside it.\",\n edit: (name: string, icon?: string) => {\n collectionMutators.edit(collection.uid, 'info.title', name)\n if (icon) {\n collectionMutators.edit(collection.uid, 'x-scalar-icon', icon)\n }\n },\n delete: () => {\n if (activeWorkspace.value) {\n collectionMutators.delete(collection, activeWorkspace.value)\n }\n },\n }\n }\n\n if (tag) {\n return {\n title: tag.name,\n entity: tag,\n resourceTitle: 'Tag',\n children: tag.children,\n warning:\n \"This cannot be undone. You're about to delete the tag and all requests inside it\",\n edit: (name: string) => tagMutators.edit(tag.uid, 'name', name),\n delete: () =>\n parentUids[0] &&\n tagMutators.delete(tag, parentUids[0] as Collection['uid']),\n }\n }\n\n if (request) {\n return {\n title: request.summary ?? request.path,\n to: {\n name: 'request',\n params: {\n workspace: activeWorkspace.value?.uid,\n request: request.uid,\n },\n },\n method: request.method,\n entity: request,\n resourceTitle: 'Request',\n warning: \"This cannot be undone. You're about to delete the request.\",\n children: request.examples.slice(1),\n edit: (name: string) =>\n requestMutators.edit(request.uid, 'summary', name),\n delete: () =>\n parentUids[0] &&\n requestMutators.delete(request, parentUids[0] as Collection['uid']),\n }\n }\n\n if (requestExample?.requestUid) {\n return {\n title: requestExample.name,\n to: {\n name: 'request.examples',\n params: {\n workspace: activeWorkspace.value?.uid,\n request: requestExample.requestUid,\n examples: requestExample.uid,\n },\n },\n method: requests[requestExample.requestUid]?.method,\n entity: requestExample,\n resourceTitle: 'Example',\n warning:\n \"This cannot be undone. You're about to delete the example from the request.\",\n children: [],\n edit: (name: string) =>\n requestExampleMutators.edit(requestExample.uid, 'name', name),\n delete: () => requestExampleMutators.delete(requestExample),\n }\n }\n\n // Catch all item which we should never see\n return {\n title: 'Unknown',\n entity: {\n uid: '',\n type: 'unknown',\n },\n resourceTitle: 'Unknown',\n children: [],\n edit: () => null,\n delete: () => null,\n } satisfies SidebarItem\n})\n\n/** Checks to see if it is a draft collection with the title of Drafts */\nconst isDraftCollection = computed(\n () =>\n item.value.entity.type === 'collection' && item.value.title === 'Drafts',\n)\n\nconst highlightClasses = 'hover:bg-sidebar-b-active indent-padding-left'\n\n/** Due to the nesting, we need a dynamic left offset for hover and active backgrounds */\nconst leftOffset = computed(() => {\n if (!parentUids.length) {\n return '12px'\n }\n if (layout === 'modal') {\n return `${(parentUids.length - 1) * 12}px`\n }\n return `${parentUids.length * 12}px`\n})\nconst paddingOffset = computed(() => {\n if (!parentUids.length) {\n return '0px'\n }\n if (layout === 'modal') {\n return `${(parentUids.length - 1) * 12}px`\n }\n return `${parentUids.length * 12}px`\n})\n\n/**\n * Show folders if they are open,\n * show examples if there are more than one and the request is active\n */\nconst showChildren = computed(\n () =>\n collapsedSidebarFolders[uid] ||\n (activeRequest.value?.uid === uid &&\n (item.value.entity as Request).examples.length > 1),\n)\n\n/** Since we have exact routing, we should check if the default request is active */\nconst isDefaultActive = computed(\n () =>\n typeof router.currentRoute.value.name === 'string' &&\n router.currentRoute.value.name.startsWith('request') &&\n activeRouterParams.value[PathId.Request] === 'default' &&\n activeRequest.value?.uid === uid,\n)\n\n/** The draggable component */\nconst draggableRef = ref<{\n draggingItem: DraggingItem\n hoveredItem: HoveredItem\n} | null>(null)\n\n/** Calculate offsets which change a little depending on whats being dragged and hovered over */\nconst getDraggableOffsets = computed(() => {\n let ceiling = 0.5\n let floor = 0.5\n\n if (!draggableRef.value) {\n return { ceiling, floor }\n }\n const { draggingItem } = draggableRef.value\n\n // If hovered over is collection && dragging is not a collection\n if (\n !collections[draggingItem?.id] &&\n item.value.entity.type === 'collection'\n ) {\n ceiling = 1\n floor = 0\n }\n // Has children but is not a request or a collection\n else if (item.value.entity.type === 'tag') {\n ceiling = 0.8\n floor = 0.2\n }\n\n return { ceiling, floor }\n})\n\n/** Guard to check if an element is able to be dropped on */\nconst _isDroppable = (draggingItem: DraggingItem, hoveredItem: HoveredItem) => {\n // Cannot drop in read only mode\n if (layout === 'modal') {\n return false\n }\n // RequestExamples cannot be dropped on\n if (requestExamples[hoveredItem.id]) {\n return false\n }\n // Collection cannot be dropped into another collection\n if (collections[draggingItem.id]) {\n return false\n }\n\n return true\n}\n\nconst handleNavigation = (event: KeyboardEvent, _item: SidebarItem) => {\n if (event) {\n const modifier = getModifiers(['default'])\n const isModifierPressed = modifier.some((key) => event[key])\n\n if (isModifierPressed) {\n emit('newTab', _item.title || '', _item.entity.uid)\n } else if (_item.to) {\n router.push(_item.to)\n }\n\n nextTick(() => events.focusAddressBar.emit())\n }\n}\n\nfunction addRequest(entityUid: string) {\n const collectionUid = parentUids[0]\n ? collections[parentUids[0]]?.uid || ''\n : entityUid\n\n // If the entity is a tag, add the tag name to the request\n const requestData =\n parentUids[0] && tags[entityUid]?.name\n ? { tags: [tags[entityUid].name] }\n : {}\n\n const newRequest = requestMutators.add(\n requestData,\n collectionUid as Collection['uid'],\n )\n\n if (newRequest) {\n router.push({\n name: 'request',\n params: {\n workspace: activeWorkspace.value?.uid,\n request: newRequest.uid,\n },\n })\n\n // Focus the address bar\n events.hotKeys.emit({\n focusAddressBar: new KeyboardEvent('keydown', { key: 'l' }),\n })\n }\n}\n\nconst watchIconColor = computed(() => {\n const { uid: _uid, watchModeStatus } = activeCollection.value || {}\n\n if (_uid !== item.value.entity.uid) {\n return 'text-c-3'\n }\n if (watchModeStatus === 'WATCHING') {\n return 'text-c-1'\n }\n if (watchModeStatus === 'ERROR') {\n return 'text-red'\n }\n return 'text-c-3'\n})\n\nconst hasDraftRequests = computed(() => {\n return (\n item.value.title === 'Drafts' &&\n layout !== 'modal' &&\n item.value.children.length > 0\n )\n})\n\n/**\n * Check if the item should be shown.\n * This is used to hide items that are marked as hidden/internal.\n */\nconst shouldShowItem = computed(() => {\n const request = requests[uid]\n if (request) {\n return !shouldIgnoreEntity(request)\n }\n\n const tag = tags[uid]\n if (tag) {\n return !shouldIgnoreEntity(tag)\n }\n\n return true\n})\n</script>\n\n<template>\n <li\n v-if=\"shouldShowItem\"\n class=\"relative flex flex-row\"\n :class=\"[\n (layout === 'modal' && parentUids.length > 1) ||\n (layout !== 'modal' && parentUids.length)\n ? 'before:bg-border indent-border-line-offset mb-[.5px] before:pointer-events-none before:absolute before:top-0 before:left-[calc(.75rem_+_.5px)] before:z-1 before:h-[calc(100%_+_.5px)] before:w-[.5px] last:mb-0 last:before:h-full'\n : '',\n ]\">\n <Draggable\n :id=\"item.entity.uid\"\n ref=\"draggableRef\"\n :ceiling=\"getDraggableOffsets.ceiling\"\n class=\"gap-1/2 flex flex-1 flex-col text-base/5\"\n :floor=\"getDraggableOffsets.floor\"\n :isDraggable=\"isDraggable\"\n :isDroppable=\"isDroppable\"\n :parentIds=\"parentUids\"\n @onDragEnd=\"(...args) => $emit('onDragEnd', ...args)\">\n <!-- Request -->\n <RouterLink\n v-if=\"\n (item.entity.type === 'request' ||\n item.entity.type === 'requestExample') &&\n item.to\n \"\n v-slot=\"{ isExactActive }\"\n class=\"group no-underline\"\n :to=\"item.to\"\n @click.prevent=\"\n (event: KeyboardEvent) => handleNavigation(event, item)\n \">\n <div\n class=\"relative flex min-h-8 w-full cursor-pointer flex-row items-start justify-between gap-0.5 rounded py-1.5 pr-2\"\n :class=\"[\n highlightClasses,\n isExactActive || isDefaultActive\n ? 'bg-sidebar-b-active text-sidebar-c-active font-medium transition-none'\n : 'text-sidebar-c-2',\n ]\">\n <span class=\"line-clamp-1 w-full pl-2 break-all\">\n {{ item.title || 'Untitled' }}\n </span>\n <div class=\"flex flex-row items-center gap-1\">\n <!-- Menu -->\n <div class=\"relative\">\n <ScalarButton\n v-if=\"layout !== 'modal'\"\n class=\"hover:bg-b-3 hidden aspect-square h-fit px-0.5 py-0 opacity-0 group-hover:flex group-hover:opacity-100 group-focus-visible:opacity-100 group-has-[:focus-visible]:opacity-100\"\n :class=\"{\n flex:\n menuItem?.item?.entity.uid === item.entity.uid &&\n menuItem.open,\n }\"\n size=\"sm\"\n type=\"button\"\n variant=\"ghost\"\n @click.stop.prevent=\"\n (ev: MouseEvent) =>\n $emit('openMenu', {\n item,\n parentUids,\n targetRef: ev.currentTarget as HTMLButtonElement,\n open: !menuItem.open,\n })\n \">\n <ScalarIcon\n icon=\"Ellipses\"\n size=\"md\" />\n </ScalarButton>\n </div>\n <span class=\"flex items-start\">\n &hairsp;\n <span class=\"sr-only\">HTTP Method:</span>\n <HttpMethod\n v-if=\"item.method\"\n class=\"font-bold\"\n :method=\"item.method\" />\n </span>\n </div>\n </div>\n </RouterLink>\n\n <!-- Collection -->\n <RouterLink\n v-else-if=\"\n (layout !== 'modal' || parentUids.length) &&\n item.entity.type === 'collection' &&\n item.to\n \"\n :aria-expanded=\"Boolean(collapsedSidebarFolders[item.entity.uid])\"\n class=\"hover:bg-b-2 group relative flex w-full flex-row justify-start gap-1.5 rounded p-1.5 no-underline focus-visible:z-10\"\n :class=\"[\n highlightClasses,\n {\n 'bg-sidebar-b-active text-sidebar-c-active transition-none':\n typeof router.currentRoute.value.name === 'string' &&\n router.currentRoute.value.name.startsWith('collection') &&\n router.currentRoute.value.params[PathId.Collection] ===\n item.entity.uid,\n 'text-c-2': item.title === 'Untitled Collection',\n },\n ]\"\n :to=\"item.to\">\n <span\n class=\"flex h-5 max-w-[14px] shrink-0 items-center justify-center\">\n <slot name=\"leftIcon\" />\n &hairsp;\n </span>\n <div class=\"flex flex-1 flex-row justify-between font-medium\">\n <span class=\"line-clamp-1 w-full text-left break-all\">\n {{ item.title }}\n </span>\n <div class=\"relative flex h-fit items-center justify-end gap-0.5\">\n <div\n class=\"items-center gap-px opacity-0 group-hover:flex group-hover:opacity-100 group-focus-visible:opacity-100 group-has-[:focus-visible]:opacity-100\"\n :class=\"{\n flex: menuItem.open,\n hidden:\n !menuItem.open ||\n menuItem.item?.entity.uid !== item.entity.uid,\n }\">\n <ScalarButton\n v-if=\"\n (layout !== 'modal' && !isDraftCollection) ||\n (isDraftCollection && hasDraftRequests)\n \"\n class=\"hover:bg-b-3 hover:text-c-1 aspect-square h-fit px-0.5 py-0 group-focus-visible:opacity-100 group-has-[:focus-visible]:opacity-100\"\n size=\"sm\"\n variant=\"ghost\"\n @click.stop.prevent=\"\n (ev: MouseEvent) =>\n $emit('openMenu', {\n item,\n parentUids,\n targetRef: (ev.currentTarget as HTMLElement)\n ?.parentNode as HTMLButtonElement,\n open: true,\n })\n \">\n <ScalarIcon\n icon=\"Ellipses\"\n size=\"md\" />\n </ScalarButton>\n <ScalarButton\n v-if=\"layout !== 'modal'\"\n class=\"hover:bg-b-3 hover:text-c-1 aspect-square h-fit px-0.5 py-0 group-focus-visible:opacity-100 group-has-[:focus-visible]:opacity-100\"\n size=\"sm\"\n variant=\"ghost\"\n @click.stop.prevent=\"addRequest(item.entity.uid)\">\n <ScalarIcon\n icon=\"Add\"\n size=\"md\"\n thickness=\"2\" />\n </ScalarButton>\n </div>\n <ScalarTooltip\n v-if=\"item.watchMode\"\n :content=\"`Watching: ${item.documentUrl}`\"\n :offset=\"12\"\n placement=\"right\">\n <button\n class=\"flex items-center justify-center\"\n type=\"button\">\n <ScalarIcon\n class=\"ml-0.5 text-sm\"\n :class=\"watchIconColor\"\n icon=\"Watch\"\n size=\"md\"\n thickness=\"2\" />\n </button>\n </ScalarTooltip>\n <span\n class=\"flex cursor-pointer items-center justify-center\"\n @click.stop.prevent=\"toggleSidebarFolder(item.entity.uid)\">\n <ScalarSidebarGroupToggle\n class=\"text-c-3 hover:text-c-1 shrink-0\"\n :open=\"Boolean(collapsedSidebarFolders[item.entity.uid])\" />\n </span>\n </div>\n </div>\n </RouterLink>\n\n <!-- Tag -->\n <button\n v-else-if=\"layout !== 'modal' || parentUids.length\"\n :aria-expanded=\"Boolean(collapsedSidebarFolders[item.entity.uid])\"\n class=\"hover:bg-b-2 group relative flex w-full flex-row justify-start gap-1.5 rounded p-1.5 focus-visible:z-10\"\n :class=\"[highlightClasses]\"\n type=\"button\"\n @click=\"toggleSidebarFolder(item.entity.uid)\">\n <span\n class=\"flex h-5 max-w-[14px] shrink-0 items-center justify-center\">\n <slot name=\"leftIcon\" />\n &hairsp;\n </span>\n <div class=\"flex flex-1 flex-row justify-between\">\n <span class=\"line-clamp-1 w-full text-left font-medium break-all\">\n {{ item.title }}\n </span>\n <div class=\"relative flex h-fit items-center justify-end gap-0.5\">\n <div\n class=\"items-center gap-px opacity-0 group-hover:flex group-hover:opacity-100 group-focus-visible:opacity-100 group-has-[:focus-visible]:opacity-100\"\n :class=\"{\n flex: menuItem.open,\n hidden:\n !menuItem.open ||\n menuItem.item?.entity.uid !== item.entity.uid,\n }\">\n <ScalarButton\n v-if=\"\n (layout !== 'modal' && !isDraftCollection) ||\n (isDraftCollection && hasDraftRequests)\n \"\n class=\"hover:bg-b-3 hover:text-c-1 aspect-square h-fit px-0.5 py-0 group-focus-visible:opacity-100 group-has-[:focus-visible]:opacity-100\"\n size=\"sm\"\n variant=\"ghost\"\n @click.stop.prevent=\"\n (ev: MouseEvent) =>\n $emit('openMenu', {\n item,\n parentUids,\n targetRef: (ev.currentTarget as HTMLElement)\n ?.parentNode as HTMLButtonElement,\n open: true,\n })\n \">\n <ScalarIcon\n icon=\"Ellipses\"\n size=\"md\" />\n </ScalarButton>\n <ScalarButton\n v-if=\"layout !== 'modal'\"\n class=\"hover:bg-b-3 hover:text-c-1 aspect-square h-fit px-0.5 py-0 group-focus-visible:opacity-100 group-has-[:focus-visible]:opacity-100\"\n size=\"sm\"\n variant=\"ghost\"\n @click.stop.prevent=\"addRequest(item.entity.uid)\">\n <ScalarIcon\n icon=\"Add\"\n size=\"md\"\n thickness=\"2\" />\n </ScalarButton>\n </div>\n <ScalarTooltip\n v-if=\"item.watchMode\"\n content=\"Watching: {{ item.documentUrl }}\"\n :offset=\"12\"\n placement=\"right\">\n <button\n class=\"flex items-center justify-center\"\n type=\"button\">\n <ScalarIcon\n class=\"ml-0.5 text-sm\"\n :class=\"watchIconColor\"\n icon=\"Watch\"\n size=\"md\"\n thickness=\"2\" />\n </button>\n </ScalarTooltip>\n <span\n class=\"flex cursor-pointer items-center justify-center\"\n @click.stop.prevent=\"toggleSidebarFolder(item.entity.uid)\">\n <ScalarSidebarGroupToggle\n class=\"text-c-3 hover:text-c-1 shrink-0\"\n :open=\"Boolean(collapsedSidebarFolders[item.entity.uid])\" />\n </span>\n </div>\n </div>\n </button>\n\n <!-- Children -->\n <ul v-if=\"showChildren\">\n <!-- We never want to show the first example -->\n <RequestSidebarItem\n v-for=\"childUid in item.children\"\n :key=\"childUid\"\n :isDraggable=\"!requestExamples[childUid]\"\n :isDroppable=\"_isDroppable\"\n :menuItem=\"menuItem\"\n :parentUids=\"[...parentUids, uid]\"\n :uid=\"childUid\"\n @newTab=\"(name, uid) => $emit('newTab', name, uid)\"\n @onDragEnd=\"(...args) => $emit('onDragEnd', ...args)\"\n @openMenu=\"(item) => $emit('openMenu', item)\" />\n <ScalarButton\n v-if=\"item.children.length === 0\"\n class=\"text-c-1 hover:bg-b-2 flex h-8 w-full justify-start gap-1.5 py-0 text-xs\"\n :class=\"parentUids.length ? 'pl-9' : ''\"\n variant=\"ghost\"\n @click=\"addRequest(item.entity.uid)\">\n <ScalarIcon\n icon=\"Add\"\n size=\"sm\" />\n <span>Add Request</span>\n </ScalarButton>\n </ul>\n </Draggable>\n </li>\n</template>\n<style>\n@import '@scalar/draggable/style.css';\n</style>\n<style scoped>\n.indent-border-line-offset:before {\n left: v-bind(leftOffset);\n}\n.indent-padding-left {\n padding-left: calc(v-bind(paddingOffset) + 6px);\n}\n.sidebar-folderitem :deep(.ellipsis-position) {\n right: 6px;\n transform: none;\n}\n</style>\n","<script setup lang=\"ts\">\nimport {\n ScalarButton,\n ScalarIcon,\n ScalarSidebarGroupToggle,\n ScalarTooltip,\n} from '@scalar/components'\nimport {\n Draggable,\n type DraggableProps,\n type DraggingItem,\n type HoveredItem,\n} from '@scalar/draggable'\nimport type { Collection, Request } from '@scalar/oas-utils/entities/spec'\nimport { shouldIgnoreEntity } from '@scalar/oas-utils/helpers'\nimport { computed, nextTick, ref } from 'vue'\nimport { RouterLink, useRouter } from 'vue-router'\n\nimport { HttpMethod } from '@/components/HttpMethod'\nimport { useLayout } from '@/hooks/useLayout'\nimport { useSidebar } from '@/hooks/useSidebar'\nimport { getModifiers } from '@/libs'\nimport { PathId } from '@/routes'\nimport { useWorkspace } from '@/store'\nimport { useActiveEntities } from '@/store/active-entities'\nimport type { SidebarItem, SidebarMenuItem } from '@/views/Request/types'\n\nconst {\n isDraggable = false,\n isDroppable = false,\n parentUids,\n uid,\n menuItem,\n} = defineProps<{\n /**\n * Toggle dragging on and off\n *\n * @default false\n */\n isDraggable?: boolean\n /**\n * Prevents items from being hovered and dropped into\n *\n * @default false\n */\n isDroppable?: DraggableProps['isDroppable']\n /** Both indicate the level and provide a way to traverse upwards */\n parentUids: string[]\n /** uid of a Collection, Tag, Request or RequestExample */\n uid: string\n /** To keep track of the menu being open */\n menuItem: SidebarMenuItem\n}>()\n\nconst emit = defineEmits<{\n onDragEnd: [draggingItem: DraggingItem, hoveredItem: HoveredItem]\n newTab: [name: string, uid: string]\n openMenu: [menuItem: SidebarMenuItem]\n}>()\n\ndefineSlots<{\n leftIcon(): void\n}>()\n\nconst { activeCollection, activeRequest, activeRouterParams, activeWorkspace } =\n useActiveEntities()\nconst {\n collections,\n tags,\n requests,\n requestExamples,\n collectionMutators,\n tagMutators,\n requestMutators,\n requestExampleMutators,\n events,\n} = useWorkspace()\nconst router = useRouter()\nconst { collapsedSidebarFolders, toggleSidebarFolder } = useSidebar()\nconst { layout } = useLayout()\n\n/** Normalize properties across different types for easy consumption */\nconst item = computed<SidebarItem>(() => {\n const collection = collections[uid]\n const tag = tags[uid]\n const request = requests[uid]\n const requestExample = requestExamples[uid]\n\n if (collection) {\n return {\n title: collection.info?.title || 'Untitled Collection',\n entity: collection,\n resourceTitle: 'Collection',\n children: collection.children,\n icon: collection['x-scalar-icon'],\n documentUrl: collection.documentUrl,\n watchMode: collection.watchMode,\n to:\n collection.uid && collection?.info?.title !== 'Drafts'\n ? {\n name: 'collection',\n params: {\n [PathId.Workspace]: activeWorkspace.value?.uid,\n [PathId.Collection]: collection.uid,\n },\n }\n : undefined,\n warning:\n \"This cannot be undone. You're about to delete the collection and all folders and requests inside it.\",\n edit: (name: string, icon?: string) => {\n collectionMutators.edit(collection.uid, 'info.title', name)\n if (icon) {\n collectionMutators.edit(collection.uid, 'x-scalar-icon', icon)\n }\n },\n delete: () => {\n if (activeWorkspace.value) {\n collectionMutators.delete(collection, activeWorkspace.value)\n }\n },\n }\n }\n\n if (tag) {\n return {\n title: tag.name,\n entity: tag,\n resourceTitle: 'Tag',\n children: tag.children,\n warning:\n \"This cannot be undone. You're about to delete the tag and all requests inside it\",\n edit: (name: string) => tagMutators.edit(tag.uid, 'name', name),\n delete: () =>\n parentUids[0] &&\n tagMutators.delete(tag, parentUids[0] as Collection['uid']),\n }\n }\n\n if (request) {\n return {\n title: request.summary ?? request.path,\n to: {\n name: 'request',\n params: {\n workspace: activeWorkspace.value?.uid,\n request: request.uid,\n },\n },\n method: request.method,\n entity: request,\n resourceTitle: 'Request',\n warning: \"This cannot be undone. You're about to delete the request.\",\n children: request.examples.slice(1),\n edit: (name: string) =>\n requestMutators.edit(request.uid, 'summary', name),\n delete: () =>\n parentUids[0] &&\n requestMutators.delete(request, parentUids[0] as Collection['uid']),\n }\n }\n\n if (requestExample?.requestUid) {\n return {\n title: requestExample.name,\n to: {\n name: 'request.examples',\n params: {\n workspace: activeWorkspace.value?.uid,\n request: requestExample.requestUid,\n examples: requestExample.uid,\n },\n },\n method: requests[requestExample.requestUid]?.method,\n entity: requestExample,\n resourceTitle: 'Example',\n warning:\n \"This cannot be undone. You're about to delete the example from the request.\",\n children: [],\n edit: (name: string) =>\n requestExampleMutators.edit(requestExample.uid, 'name', name),\n delete: () => requestExampleMutators.delete(requestExample),\n }\n }\n\n // Catch all item which we should never see\n return {\n title: 'Unknown',\n entity: {\n uid: '',\n type: 'unknown',\n },\n resourceTitle: 'Unknown',\n children: [],\n edit: () => null,\n delete: () => null,\n } satisfies SidebarItem\n})\n\n/** Checks to see if it is a draft collection with the title of Drafts */\nconst isDraftCollection = computed(\n () =>\n item.value.entity.type === 'collection' && item.value.title === 'Drafts',\n)\n\nconst highlightClasses = 'hover:bg-sidebar-b-active indent-padding-left'\n\n/** Due to the nesting, we need a dynamic left offset for hover and active backgrounds */\nconst leftOffset = computed(() => {\n if (!parentUids.length) {\n return '12px'\n }\n if (layout === 'modal') {\n return `${(parentUids.length - 1) * 12}px`\n }\n return `${parentUids.length * 12}px`\n})\nconst paddingOffset = computed(() => {\n if (!parentUids.length) {\n return '0px'\n }\n if (layout === 'modal') {\n return `${(parentUids.length - 1) * 12}px`\n }\n return `${parentUids.length * 12}px`\n})\n\n/**\n * Show folders if they are open,\n * show examples if there are more than one and the request is active\n */\nconst showChildren = computed(\n () =>\n collapsedSidebarFolders[uid] ||\n (activeRequest.value?.uid === uid &&\n (item.value.entity as Request).examples.length > 1),\n)\n\n/** Since we have exact routing, we should check if the default request is active */\nconst isDefaultActive = computed(\n () =>\n typeof router.currentRoute.value.name === 'string' &&\n router.currentRoute.value.name.startsWith('request') &&\n activeRouterParams.value[PathId.Request] === 'default' &&\n activeRequest.value?.uid === uid,\n)\n\n/** The draggable component */\nconst draggableRef = ref<{\n draggingItem: DraggingItem\n hoveredItem: HoveredItem\n} | null>(null)\n\n/** Calculate offsets which change a little depending on whats being dragged and hovered over */\nconst getDraggableOffsets = computed(() => {\n let ceiling = 0.5\n let floor = 0.5\n\n if (!draggableRef.value) {\n return { ceiling, floor }\n }\n const { draggingItem } = draggableRef.value\n\n // If hovered over is collection && dragging is not a collection\n if (\n !collections[draggingItem?.id] &&\n item.value.entity.type === 'collection'\n ) {\n ceiling = 1\n floor = 0\n }\n // Has children but is not a request or a collection\n else if (item.value.entity.type === 'tag') {\n ceiling = 0.8\n floor = 0.2\n }\n\n return { ceiling, floor }\n})\n\n/** Guard to check if an element is able to be dropped on */\nconst _isDroppable = (draggingItem: DraggingItem, hoveredItem: HoveredItem) => {\n // Cannot drop in read only mode\n if (layout === 'modal') {\n return false\n }\n // RequestExamples cannot be dropped on\n if (requestExamples[hoveredItem.id]) {\n return false\n }\n // Collection cannot be dropped into another collection\n if (collections[draggingItem.id]) {\n return false\n }\n\n return true\n}\n\nconst handleNavigation = (event: KeyboardEvent, _item: SidebarItem) => {\n if (event) {\n const modifier = getModifiers(['default'])\n const isModifierPressed = modifier.some((key) => event[key])\n\n if (isModifierPressed) {\n emit('newTab', _item.title || '', _item.entity.uid)\n } else if (_item.to) {\n router.push(_item.to)\n }\n\n nextTick(() => events.focusAddressBar.emit())\n }\n}\n\nfunction addRequest(entityUid: string) {\n const collectionUid = parentUids[0]\n ? collections[parentUids[0]]?.uid || ''\n : entityUid\n\n // If the entity is a tag, add the tag name to the request\n const requestData =\n parentUids[0] && tags[entityUid]?.name\n ? { tags: [tags[entityUid].name] }\n : {}\n\n const newRequest = requestMutators.add(\n requestData,\n collectionUid as Collection['uid'],\n )\n\n if (newRequest) {\n router.push({\n name: 'request',\n params: {\n workspace: activeWorkspace.value?.uid,\n request: newRequest.uid,\n },\n })\n\n // Focus the address bar\n events.hotKeys.emit({\n focusAddressBar: new KeyboardEvent('keydown', { key: 'l' }),\n })\n }\n}\n\nconst watchIconColor = computed(() => {\n const { uid: _uid, watchModeStatus } = activeCollection.value || {}\n\n if (_uid !== item.value.entity.uid) {\n return 'text-c-3'\n }\n if (watchModeStatus === 'WATCHING') {\n return 'text-c-1'\n }\n if (watchModeStatus === 'ERROR') {\n return 'text-red'\n }\n return 'text-c-3'\n})\n\nconst hasDraftRequests = computed(() => {\n return (\n item.value.title === 'Drafts' &&\n layout !== 'modal' &&\n item.value.children.length > 0\n )\n})\n\n/**\n * Check if the item should be shown.\n * This is used to hide items that are marked as hidden/internal.\n */\nconst shouldShowItem = computed(() => {\n const request = requests[uid]\n if (request) {\n return !shouldIgnoreEntity(request)\n }\n\n const tag = tags[uid]\n if (tag) {\n return !shouldIgnoreEntity(tag)\n }\n\n return true\n})\n</script>\n\n<template>\n <li\n v-if=\"shouldShowItem\"\n class=\"relative flex flex-row\"\n :class=\"[\n (layout === 'modal' && parentUids.length > 1) ||\n (layout !== 'modal' && parentUids.length)\n ? 'before:bg-border indent-border-line-offset mb-[.5px] before:pointer-events-none before:absolute before:top-0 before:left-[calc(.75rem_+_.5px)] before:z-1 before:h-[calc(100%_+_.5px)] before:w-[.5px] last:mb-0 last:before:h-full'\n : '',\n ]\">\n <Draggable\n :id=\"item.entity.uid\"\n ref=\"draggableRef\"\n :ceiling=\"getDraggableOffsets.ceiling\"\n class=\"gap-1/2 flex flex-1 flex-col text-base/5\"\n :floor=\"getDraggableOffsets.floor\"\n :isDraggable=\"isDraggable\"\n :isDroppable=\"isDroppable\"\n :parentIds=\"parentUids\"\n @onDragEnd=\"(...args) => $emit('onDragEnd', ...args)\">\n <!-- Request -->\n <RouterLink\n v-if=\"\n (item.entity.type === 'request' ||\n item.entity.type === 'requestExample') &&\n item.to\n \"\n v-slot=\"{ isExactActive }\"\n class=\"group no-underline\"\n :to=\"item.to\"\n @click.prevent=\"\n (event: KeyboardEvent) => handleNavigation(event, item)\n \">\n <div\n class=\"relative flex min-h-8 w-full cursor-pointer flex-row items-start justify-between gap-0.5 rounded py-1.5 pr-2\"\n :class=\"[\n highlightClasses,\n isExactActive || isDefaultActive\n ? 'bg-sidebar-b-active text-sidebar-c-active font-medium transition-none'\n : 'text-sidebar-c-2',\n ]\">\n <span class=\"line-clamp-1 w-full pl-2 break-all\">\n {{ item.title || 'Untitled' }}\n </span>\n <div class=\"flex flex-row items-center gap-1\">\n <!-- Menu -->\n <div class=\"relative\">\n <ScalarButton\n v-if=\"layout !== 'modal'\"\n class=\"hover:bg-b-3 hidden aspect-square h-fit px-0.5 py-0 opacity-0 group-hover:flex group-hover:opacity-100 group-focus-visible:opacity-100 group-has-[:focus-visible]:opacity-100\"\n :class=\"{\n flex:\n menuItem?.item?.entity.uid === item.entity.uid &&\n menuItem.open,\n }\"\n size=\"sm\"\n type=\"button\"\n variant=\"ghost\"\n @click.stop.prevent=\"\n (ev: MouseEvent) =>\n $emit('openMenu', {\n item,\n parentUids,\n targetRef: ev.currentTarget as HTMLButtonElement,\n open: !menuItem.open,\n })\n \">\n <ScalarIcon\n icon=\"Ellipses\"\n size=\"md\" />\n </ScalarButton>\n </div>\n <span class=\"flex items-start\">\n &hairsp;\n <span class=\"sr-only\">HTTP Method:</span>\n <HttpMethod\n v-if=\"item.method\"\n class=\"font-bold\"\n :method=\"item.method\" />\n </span>\n </div>\n </div>\n </RouterLink>\n\n <!-- Collection -->\n <RouterLink\n v-else-if=\"\n (layout !== 'modal' || parentUids.length) &&\n item.entity.type === 'collection' &&\n item.to\n \"\n :aria-expanded=\"Boolean(collapsedSidebarFolders[item.entity.uid])\"\n class=\"hover:bg-b-2 group relative flex w-full flex-row justify-start gap-1.5 rounded p-1.5 no-underline focus-visible:z-10\"\n :class=\"[\n highlightClasses,\n {\n 'bg-sidebar-b-active text-sidebar-c-active transition-none':\n typeof router.currentRoute.value.name === 'string' &&\n router.currentRoute.value.name.startsWith('collection') &&\n router.currentRoute.value.params[PathId.Collection] ===\n item.entity.uid,\n 'text-c-2': item.title === 'Untitled Collection',\n },\n ]\"\n :to=\"item.to\">\n <span\n class=\"flex h-5 max-w-[14px] shrink-0 items-center justify-center\">\n <slot name=\"leftIcon\" />\n &hairsp;\n </span>\n <div class=\"flex flex-1 flex-row justify-between font-medium\">\n <span class=\"line-clamp-1 w-full text-left break-all\">\n {{ item.title }}\n </span>\n <div class=\"relative flex h-fit items-center justify-end gap-0.5\">\n <div\n class=\"items-center gap-px opacity-0 group-hover:flex group-hover:opacity-100 group-focus-visible:opacity-100 group-has-[:focus-visible]:opacity-100\"\n :class=\"{\n flex: menuItem.open,\n hidden:\n !menuItem.open ||\n menuItem.item?.entity.uid !== item.entity.uid,\n }\">\n <ScalarButton\n v-if=\"\n (layout !== 'modal' && !isDraftCollection) ||\n (isDraftCollection && hasDraftRequests)\n \"\n class=\"hover:bg-b-3 hover:text-c-1 aspect-square h-fit px-0.5 py-0 group-focus-visible:opacity-100 group-has-[:focus-visible]:opacity-100\"\n size=\"sm\"\n variant=\"ghost\"\n @click.stop.prevent=\"\n (ev: MouseEvent) =>\n $emit('openMenu', {\n item,\n parentUids,\n targetRef: (ev.currentTarget as HTMLElement)\n ?.parentNode as HTMLButtonElement,\n open: true,\n })\n \">\n <ScalarIcon\n icon=\"Ellipses\"\n size=\"md\" />\n </ScalarButton>\n <ScalarButton\n v-if=\"layout !== 'modal'\"\n class=\"hover:bg-b-3 hover:text-c-1 aspect-square h-fit px-0.5 py-0 group-focus-visible:opacity-100 group-has-[:focus-visible]:opacity-100\"\n size=\"sm\"\n variant=\"ghost\"\n @click.stop.prevent=\"addRequest(item.entity.uid)\">\n <ScalarIcon\n icon=\"Add\"\n size=\"md\"\n thickness=\"2\" />\n </ScalarButton>\n </div>\n <ScalarTooltip\n v-if=\"item.watchMode\"\n :content=\"`Watching: ${item.documentUrl}`\"\n :offset=\"12\"\n placement=\"right\">\n <button\n class=\"flex items-center justify-center\"\n type=\"button\">\n <ScalarIcon\n class=\"ml-0.5 text-sm\"\n :class=\"watchIconColor\"\n icon=\"Watch\"\n size=\"md\"\n thickness=\"2\" />\n </button>\n </ScalarTooltip>\n <span\n class=\"flex cursor-pointer items-center justify-center\"\n @click.stop.prevent=\"toggleSidebarFolder(item.entity.uid)\">\n <ScalarSidebarGroupToggle\n class=\"text-c-3 hover:text-c-1 shrink-0\"\n :open=\"Boolean(collapsedSidebarFolders[item.entity.uid])\" />\n </span>\n </div>\n </div>\n </RouterLink>\n\n <!-- Tag -->\n <button\n v-else-if=\"layout !== 'modal' || parentUids.length\"\n :aria-expanded=\"Boolean(collapsedSidebarFolders[item.entity.uid])\"\n class=\"hover:bg-b-2 group relative flex w-full flex-row justify-start gap-1.5 rounded p-1.5 focus-visible:z-10\"\n :class=\"[highlightClasses]\"\n type=\"button\"\n @click=\"toggleSidebarFolder(item.entity.uid)\">\n <span\n class=\"flex h-5 max-w-[14px] shrink-0 items-center justify-center\">\n <slot name=\"leftIcon\" />\n &hairsp;\n </span>\n <div class=\"flex flex-1 flex-row justify-between\">\n <span class=\"line-clamp-1 w-full text-left font-medium break-all\">\n {{ item.title }}\n </span>\n <div class=\"relative flex h-fit items-center justify-end gap-0.5\">\n <div\n class=\"items-center gap-px opacity-0 group-hover:flex group-hover:opacity-100 group-focus-visible:opacity-100 group-has-[:focus-visible]:opacity-100\"\n :class=\"{\n flex: menuItem.open,\n hidden:\n !menuItem.open ||\n menuItem.item?.entity.uid !== item.entity.uid,\n }\">\n <ScalarButton\n v-if=\"\n (layout !== 'modal' && !isDraftCollection) ||\n (isDraftCollection && hasDraftRequests)\n \"\n class=\"hover:bg-b-3 hover:text-c-1 aspect-square h-fit px-0.5 py-0 group-focus-visible:opacity-100 group-has-[:focus-visible]:opacity-100\"\n size=\"sm\"\n variant=\"ghost\"\n @click.stop.prevent=\"\n (ev: MouseEvent) =>\n $emit('openMenu', {\n item,\n parentUids,\n targetRef: (ev.currentTarget as HTMLElement)\n ?.parentNode as HTMLButtonElement,\n open: true,\n })\n \">\n <ScalarIcon\n icon=\"Ellipses\"\n size=\"md\" />\n </ScalarButton>\n <ScalarButton\n v-if=\"layout !== 'modal'\"\n class=\"hover:bg-b-3 hover:text-c-1 aspect-square h-fit px-0.5 py-0 group-focus-visible:opacity-100 group-has-[:focus-visible]:opacity-100\"\n size=\"sm\"\n variant=\"ghost\"\n @click.stop.prevent=\"addRequest(item.entity.uid)\">\n <ScalarIcon\n icon=\"Add\"\n size=\"md\"\n thickness=\"2\" />\n </ScalarButton>\n </div>\n <ScalarTooltip\n v-if=\"item.watchMode\"\n content=\"Watching: {{ item.documentUrl }}\"\n :offset=\"12\"\n placement=\"right\">\n <button\n class=\"flex items-center justify-center\"\n type=\"button\">\n <ScalarIcon\n class=\"ml-0.5 text-sm\"\n :class=\"watchIconColor\"\n icon=\"Watch\"\n size=\"md\"\n thickness=\"2\" />\n </button>\n </ScalarTooltip>\n <span\n class=\"flex cursor-pointer items-center justify-center\"\n @click.stop.prevent=\"toggleSidebarFolder(item.entity.uid)\">\n <ScalarSidebarGroupToggle\n class=\"text-c-3 hover:text-c-1 shrink-0\"\n :open=\"Boolean(collapsedSidebarFolders[item.entity.uid])\" />\n </span>\n </div>\n </div>\n </button>\n\n <!-- Children -->\n <ul v-if=\"showChildren\">\n <!-- We never want to show the first example -->\n <RequestSidebarItem\n v-for=\"childUid in item.children\"\n :key=\"childUid\"\n :isDraggable=\"!requestExamples[childUid]\"\n :isDroppable=\"_isDroppable\"\n :menuItem=\"menuItem\"\n :parentUids=\"[...parentUids, uid]\"\n :uid=\"childUid\"\n @newTab=\"(name, uid) => $emit('newTab', name, uid)\"\n @onDragEnd=\"(...args) => $emit('onDragEnd', ...args)\"\n @openMenu=\"(item) => $emit('openMenu', item)\" />\n <ScalarButton\n v-if=\"item.children.length === 0\"\n class=\"text-c-1 hover:bg-b-2 flex h-8 w-full justify-start gap-1.5 py-0 text-xs\"\n :class=\"parentUids.length ? 'pl-9' : ''\"\n variant=\"ghost\"\n @click=\"addRequest(item.entity.uid)\">\n <ScalarIcon\n icon=\"Add\"\n size=\"sm\" />\n <span>Add Request</span>\n </ScalarButton>\n </ul>\n </Draggable>\n </li>\n</template>\n<style>\n@import '@scalar/draggable/style.css';\n</style>\n<style scoped>\n.indent-border-line-offset:before {\n left: v-bind(leftOffset);\n}\n.indent-padding-left {\n padding-left: calc(v-bind(paddingOffset) + 6px);\n}\n.sidebar-folderitem :deep(.ellipsis-position) {\n right: 6px;\n transform: none;\n}\n</style>\n","<script setup lang=\"ts\">\nimport {\n ScalarButton,\n ScalarIcon,\n ScalarSearchResultItem,\n ScalarSearchResultList,\n ScalarSidebarSearchInput,\n} from '@scalar/components'\nimport { LibraryIcon } from '@scalar/icons/library'\nimport type { Collection } from '@scalar/oas-utils/entities/spec'\nimport { useToasts } from '@scalar/use-toasts'\nimport {\n computed,\n onBeforeUnmount,\n onMounted,\n reactive,\n ref,\n useId,\n watch,\n} from 'vue'\nimport { useRouter } from 'vue-router'\n\nimport Rabbit from '@/assets/rabbit.ascii?raw'\nimport RabbitJump from '@/assets/rabbitjump.ascii?raw'\nimport { Sidebar } from '@/components'\nimport EnvironmentSelector from '@/components/EnvironmentSelector/EnvironmentSelector.vue'\nimport HttpMethod from '@/components/HttpMethod/HttpMethod.vue'\nimport ScalarAsciiArt from '@/components/ScalarAsciiArt.vue'\nimport { useSearch } from '@/components/Search/useSearch'\nimport SidebarButton from '@/components/Sidebar/SidebarButton.vue'\nimport { useLayout } from '@/hooks/useLayout'\nimport { useSidebar } from '@/hooks/useSidebar'\nimport type { HotKeyEvent } from '@/libs'\nimport { PathId } from '@/routes'\nimport { useWorkspace } from '@/store'\nimport { useActiveEntities } from '@/store/active-entities'\nimport { createInitialRequest } from '@/store/requests'\nimport { dragHandlerFactory } from '@/views/Request/handle-drag'\nimport RequestSidebarItemMenu from '@/views/Request/RequestSidebarItemMenu.vue'\nimport type { SidebarItem, SidebarMenuItem } from '@/views/Request/types'\n\nimport { WorkspaceDropdown } from './components'\nimport { isGettingStarted } from './RequestSection/helpers/getting-started'\nimport RequestSidebarItem from './RequestSidebarItem.vue'\n\nconst emit = defineEmits<{\n (e: 'newTab', { name, uid }: { name: string; uid: string }): void\n (e: 'clearDrafts'): void\n}>()\n\nconst { isSidebarOpen, setCollapsedSidebarFolder, toggleSidebarOpen } =\n useSidebar()\nconst { layout } = useLayout()\n\nconst workspaceContext = useWorkspace()\nconst {\n activeCollection,\n activeWorkspaceCollections,\n activeRequest,\n activeWorkspaceRequests,\n activeWorkspace,\n} = useActiveEntities()\nconst { findRequestParents, events, requestMutators, requests } =\n workspaceContext\n\nconst { handleDragEnd, isDroppable } = dragHandlerFactory(\n activeWorkspace,\n workspaceContext,\n)\nconst { replace } = useRouter()\nconst openCommandPaletteImport = () => {\n events.commandPalette.emit({\n commandName: 'Import from OpenAPI/Swagger/Postman/cURL',\n })\n}\nconst searchResultsId = useId()\nconst { toast } = useToasts()\n/** The currently selected sidebarMenuItem for the context menu */\nconst menuItem = reactive<SidebarMenuItem>({ open: false })\nconst isSearchVisible = ref(false)\n\n/** Watch to see if activeRequest changes and ensure we open any folders */\nwatch(\n activeRequest,\n (request) => {\n if (!request) {\n return\n }\n\n // Ensure the sidebar folders are open\n findRequestParents(request).forEach((uid: string) =>\n setCollapsedSidebarFolder(uid, true),\n )\n },\n { immediate: true },\n)\n\nconst {\n searchText,\n searchResultsWithPlaceholderResults,\n selectedSearchResult,\n onSearchResultClick,\n fuseSearch,\n searchInputRef,\n searchResultRefs,\n navigateSearchResults,\n selectSearchResult,\n} = useSearch()\n\nconst searchToggleRef = ref<HTMLButtonElement>()\n\n/** Handle hotkey events from the bus */\nconst handleHotKey = (event?: HotKeyEvent) => {\n if (!event) {\n return\n }\n if (event.toggleSidebar) {\n toggleSidebarOpen()\n }\n if (event.focusRequestSearch) {\n searchInputRef.value?.focus()\n }\n}\n\nonMounted(() => events.hotKeys.on(handleHotKey))\n\n/**\n * Need to manually remove listener on unmount due to vueuse memory leak\n *\n * @see https://github.com/vueuse/vueuse/issues/3498#issuecomment-2055546566\n */\nonBeforeUnmount(() => {\n events.hotKeys.off(handleHotKey)\n})\n\nconst handleToggleWatchMode = (item?: SidebarItem) => {\n if (item?.documentUrl) {\n item.watchMode = !item.watchMode\n const currentCollection = activeWorkspaceCollections.value.find(\n (collection: Collection) => collection.uid === item.entity.uid,\n )\n if (currentCollection) {\n currentCollection.watchMode = item.watchMode\n }\n }\n}\n\nwatch(\n () =>\n activeWorkspaceCollections.value.map(\n (collection: Collection) => collection.watchMode,\n ),\n (newWatchModes, oldWatchModes) => {\n newWatchModes.forEach((newWatchMode: boolean, index: number) => {\n if (\n layout !== 'modal' &&\n newWatchMode !== oldWatchModes[index] &&\n activeWorkspaceCollections.value[index]?.info?.title !== 'Drafts' &&\n activeWorkspaceCollections.value[index]\n ) {\n const currentCollection = activeWorkspaceCollections.value[index]\n if (!currentCollection) {\n return\n }\n\n const message = `${currentCollection.info?.title}: Watch Mode ${newWatchMode ? 'enabled' : 'disabled'}`\n toast(message, 'info')\n }\n })\n },\n)\n\n/** Screen reader label for the search input */\nconst srLabel = computed<string>(() => {\n const results = searchResultsWithPlaceholderResults.value\n if (!results.length) {\n return 'No results found'\n }\n\n const result = results[selectedSearchResult.value]?.item\n if (!result) {\n return 'No result selected'\n }\n\n const resultsFoundLabel = searchText.value.length\n ? `${results.length} result${results.length === 1 ? '' : 's'} found, `\n : ''\n\n const selectedResultDescription = `, HTTP Method ${result.httpVerb}, Path ${result.path}`\n\n const selectedResultLabel = `${result.title} ${selectedResultDescription}`\n\n return `${resultsFoundLabel}Selected: ${selectedResultLabel}`\n})\n\nconst handleClearDrafts = () => {\n const draftCollection = activeWorkspaceCollections.value.find(\n (collection: Collection) => collection.info?.title === 'Drafts',\n )\n\n if (draftCollection) {\n draftCollection.requests.forEach((requestUid: string) => {\n if (requests[requestUid]) {\n requestMutators.delete(requests[requestUid], draftCollection.uid)\n }\n })\n }\n\n const hasRequests = activeWorkspaceRequests.value.length\n\n // First request in the first collection\n if (hasRequests) {\n const firstCollection = activeWorkspaceCollections.value[0]\n const firstRequest = firstCollection?.requests[0]\n\n if (firstRequest) {\n replace({\n name: 'request',\n params: {\n [PathId.Request]: firstRequest,\n },\n })\n }\n }\n // Create a new request and go to it\n else {\n const { request } = createInitialRequest()\n\n if (draftCollection) {\n requestMutators.add(request, draftCollection.uid)\n\n replace({\n name: 'request',\n params: {\n [PathId.Request]: request.uid,\n },\n })\n }\n }\n}\n\nwatch(isSearchVisible, (isVisible) => {\n // If we're hiding the search, clear the text\n if (!isVisible) {\n searchText.value = ''\n }\n})\n\nconst showGettingStarted = computed(() =>\n isGettingStarted(\n activeWorkspaceCollections.value,\n activeWorkspaceRequests.value,\n requests,\n ),\n)\n\n/** We ensure in modal mode we only show the current requests collection */\nconst collections = computed(() => {\n if (layout === 'modal' && activeCollection.value) {\n return [activeCollection.value]\n }\n return activeWorkspaceCollections.value\n})\n\n/** Hide the search input if the text is empty */\nfunction handleBlur(e: FocusEvent) {\n // We have to check the blur did not come from the search toggle button\n // otherwise the search will show again form the click event\n if (!searchText.value && e.relatedTarget !== searchToggleRef.value) {\n isSearchVisible.value = false\n }\n}\n</script>\n<template>\n <Sidebar\n v-show=\"isSidebarOpen\"\n :class=\"[isSidebarOpen ? 'sidebar-active-width' : '']\">\n <template\n v-if=\"layout !== 'modal'\"\n #header />\n <template #content>\n <div class=\"bg-b-1 sticky top-0 z-20 flex h-12 items-center px-3\">\n <!-- Holds space for the sidebar toggle -->\n <div\n class=\"size-8\"\n :class=\"{ 'xl:hidden': layout !== 'modal' }\" />\n <WorkspaceDropdown v-if=\"layout !== 'modal'\" />\n <span\n v-if=\"layout !== 'modal'\"\n class=\"text-c-3\">\n /\n </span>\n <EnvironmentSelector v-if=\"layout !== 'modal'\" />\n <button\n ref=\"searchToggleRef\"\n :aria-pressed=\"isSearchVisible\"\n class=\"ml-auto\"\n type=\"button\"\n @click=\"isSearchVisible = !isSearchVisible\">\n <span class=\"sr-only\">\n {{ isSearchVisible ? 'Hide' : 'Show' }} search\n </span>\n <ScalarIcon\n class=\"text-c-3 hover:bg-b-2 max-h-8 max-w-8 rounded-lg p-1.75 text-sm\"\n icon=\"Search\" />\n </button>\n </div>\n <div\n v-if=\"isSearchVisible\"\n class=\"search-button-fade sticky top-12 z-10 px-3 py-2.5 pt-0 focus-within:z-20\"\n role=\"search\">\n <ScalarSidebarSearchInput\n ref=\"searchInputRef\"\n v-model=\"searchText\"\n autofocus\n :aria-controls=\"searchResultsId\"\n :label=\"srLabel\"\n @input=\"fuseSearch\"\n @keydown.down.stop=\"navigateSearchResults('down')\"\n @keydown.enter.stop=\"selectSearchResult()\"\n @keydown.up.stop=\"navigateSearchResults('up')\"\n @blur=\"handleBlur\" />\n </div>\n <div\n class=\"gap-1/2 flex flex-1 flex-col overflow-visible overflow-y-auto px-3 pt-0 pb-3\"\n :class=\"[\n {\n 'pb-14': layout !== 'modal',\n },\n {\n 'h-[calc(100%-273.5px)]': showGettingStarted,\n },\n ]\"\n @dragenter.prevent\n @dragover.prevent>\n <template v-if=\"searchText\">\n <ScalarSearchResultList\n :id=\"searchResultsId\"\n aria-label=\"Search Results\"\n class=\"gap-px\"\n :noResults=\"!searchResultsWithPlaceholderResults.length\">\n <ScalarSearchResultItem\n v-for=\"(entry, index) in searchResultsWithPlaceholderResults\"\n :id=\"`#search-input-${entry.item.id}`\"\n :key=\"entry.refIndex\"\n :ref=\"(el) => (searchResultRefs[index] = el as HTMLElement)\"\n :selected=\"selectedSearchResult === index\"\n class=\"px-2\"\n :href=\"entry.item.link\"\n @click.prevent=\"onSearchResultClick(entry)\"\n @focus=\"selectedSearchResult = index\">\n {{ entry.item.title }}\n <template #addon>\n <span class=\"sr-only\">HTTP Method:</span>\n <HttpMethod\n class=\"font-bold\"\n :method=\"entry.item.httpVerb ?? 'get'\" />\n </template>\n </ScalarSearchResultItem>\n </ScalarSearchResultList>\n </template>\n <nav\n v-else\n class=\"contents\">\n <!-- Collection -->\n <RequestSidebarItem\n v-for=\"collection in collections\"\n :key=\"collection.uid\"\n :isDraggable=\"\n layout !== 'modal' && collection.info?.title !== 'Drafts'\n \"\n :isDroppable=\"isDroppable\"\n :menuItem=\"menuItem\"\n :parentUids=\"[]\"\n :uid=\"collection.uid\"\n @newTab=\"(name, uid) => emit('newTab', { name, uid })\"\n @onDragEnd=\"handleDragEnd\"\n @openMenu=\"(item) => Object.assign(menuItem, item)\">\n <template #leftIcon>\n <ScalarIcon\n v-if=\"collection.info?.title === 'Drafts'\"\n class=\"text-sidebar-c-2\"\n icon=\"Scribble\"\n thickness=\"2.25\" />\n <LibraryIcon\n v-else\n class=\"text-sidebar-c-2 size-3.5 min-w-3.5 stroke-2\"\n :src=\"\n collection['x-scalar-icon'] || 'interface-content-folder'\n \" />\n </template>\n </RequestSidebarItem>\n </nav>\n </div>\n </template>\n <template #button>\n <div\n :class=\"{\n 'empty-sidebar-item': showGettingStarted,\n }\">\n <div\n v-if=\"showGettingStarted\"\n class=\"empty-sidebar-item-content px-2.5 py-2.5\">\n <div class=\"rabbit-ascii relative m-auto mt-2 h-[68px] w-[60px]\">\n <ScalarAsciiArt\n :art=\"Rabbit\"\n class=\"rabbitsit font-bold\" />\n <ScalarAsciiArt\n :art=\"RabbitJump\"\n class=\"rabbitjump absolute top-0 left-0 font-bold\" />\n </div>\n <div class=\"mt-2 mb-2 text-center text-sm text-balance\">\n <b class=\"font-medium\">Let's Get Started</b>\n <p class=\"mt-2\">\n Create request, folder, collection or import from OpenAPI/Postman\n </p>\n </div>\n </div>\n <ScalarButton\n v-if=\"layout !== 'modal'\"\n class=\"mb-1.5 hidden h-fit w-full p-1.5 opacity-0\"\n :class=\"{\n 'flex opacity-100': showGettingStarted,\n }\"\n @click=\"openCommandPaletteImport\">\n Import Collection\n </ScalarButton>\n <SidebarButton\n v-if=\"layout !== 'modal'\"\n :click=\"events.commandPalette.emit\"\n hotkey=\"K\">\n <template #title> Add Item </template>\n </SidebarButton>\n </div>\n </template>\n </Sidebar>\n\n <!-- Menu -->\n <RequestSidebarItemMenu\n v-if=\"layout !== 'modal' && menuItem\"\n :menuItem=\"menuItem\"\n @clearDrafts=\"handleClearDrafts\"\n @closeMenu=\"menuItem.open = false\"\n @toggleWatchMode=\"handleToggleWatchMode\" />\n</template>\n<style scoped>\n.search-button-fade {\n background: linear-gradient(\n var(--scalar-background-1) 32px,\n color-mix(in srgb, var(--scalar-background-1), transparent) 38px,\n transparent\n );\n}\n.empty-sidebar-item-content {\n display: none;\n}\n.empty-sidebar-item .empty-sidebar-item-content {\n display: block;\n}\n.rabbitjump {\n opacity: 0;\n}\n.empty-sidebar-item:hover .rabbitjump {\n opacity: 1;\n animation: rabbitAnimation 0.5s steps(1) infinite;\n}\n.empty-sidebar-item:hover .rabbitsit {\n opacity: 0;\n animation: rabbitAnimation2 0.5s steps(1) infinite;\n}\n.empty-sidebar-item:hover .rabbit-ascii {\n animation: rabbitRun 8s infinite linear;\n}\n@keyframes rabbitRun {\n 0% {\n transform: translate3d(0, 0, 0);\n }\n 25% {\n transform: translate3d(250px, 0, 0);\n }\n 25.01% {\n transform: translate3d(-250px, 0, 0);\n }\n 75% {\n transform: translate3d(250px, 0, 0);\n }\n 75.01% {\n transform: translate3d(-250px, 0, 0);\n }\n 100% {\n transform: translate3d(0, 0, 0);\n }\n}\n@keyframes rabbitAnimation {\n 0%,\n 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0;\n }\n}\n@keyframes rabbitAnimation2 {\n 0%,\n 100% {\n opacity: 0;\n }\n 50% {\n opacity: 1;\n transform: translate3d(0, -8px, 0);\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport {\n ScalarButton,\n ScalarIcon,\n ScalarSearchResultItem,\n ScalarSearchResultList,\n ScalarSidebarSearchInput,\n} from '@scalar/components'\nimport { LibraryIcon } from '@scalar/icons/library'\nimport type { Collection } from '@scalar/oas-utils/entities/spec'\nimport { useToasts } from '@scalar/use-toasts'\nimport {\n computed,\n onBeforeUnmount,\n onMounted,\n reactive,\n ref,\n useId,\n watch,\n} from 'vue'\nimport { useRouter } from 'vue-router'\n\nimport Rabbit from '@/assets/rabbit.ascii?raw'\nimport RabbitJump from '@/assets/rabbitjump.ascii?raw'\nimport { Sidebar } from '@/components'\nimport EnvironmentSelector from '@/components/EnvironmentSelector/EnvironmentSelector.vue'\nimport HttpMethod from '@/components/HttpMethod/HttpMethod.vue'\nimport ScalarAsciiArt from '@/components/ScalarAsciiArt.vue'\nimport { useSearch } from '@/components/Search/useSearch'\nimport SidebarButton from '@/components/Sidebar/SidebarButton.vue'\nimport { useLayout } from '@/hooks/useLayout'\nimport { useSidebar } from '@/hooks/useSidebar'\nimport type { HotKeyEvent } from '@/libs'\nimport { PathId } from '@/routes'\nimport { useWorkspace } from '@/store'\nimport { useActiveEntities } from '@/store/active-entities'\nimport { createInitialRequest } from '@/store/requests'\nimport { dragHandlerFactory } from '@/views/Request/handle-drag'\nimport RequestSidebarItemMenu from '@/views/Request/RequestSidebarItemMenu.vue'\nimport type { SidebarItem, SidebarMenuItem } from '@/views/Request/types'\n\nimport { WorkspaceDropdown } from './components'\nimport { isGettingStarted } from './RequestSection/helpers/getting-started'\nimport RequestSidebarItem from './RequestSidebarItem.vue'\n\nconst emit = defineEmits<{\n (e: 'newTab', { name, uid }: { name: string; uid: string }): void\n (e: 'clearDrafts'): void\n}>()\n\nconst { isSidebarOpen, setCollapsedSidebarFolder, toggleSidebarOpen } =\n useSidebar()\nconst { layout } = useLayout()\n\nconst workspaceContext = useWorkspace()\nconst {\n activeCollection,\n activeWorkspaceCollections,\n activeRequest,\n activeWorkspaceRequests,\n activeWorkspace,\n} = useActiveEntities()\nconst { findRequestParents, events, requestMutators, requests } =\n workspaceContext\n\nconst { handleDragEnd, isDroppable } = dragHandlerFactory(\n activeWorkspace,\n workspaceContext,\n)\nconst { replace } = useRouter()\nconst openCommandPaletteImport = () => {\n events.commandPalette.emit({\n commandName: 'Import from OpenAPI/Swagger/Postman/cURL',\n })\n}\nconst searchResultsId = useId()\nconst { toast } = useToasts()\n/** The currently selected sidebarMenuItem for the context menu */\nconst menuItem = reactive<SidebarMenuItem>({ open: false })\nconst isSearchVisible = ref(false)\n\n/** Watch to see if activeRequest changes and ensure we open any folders */\nwatch(\n activeRequest,\n (request) => {\n if (!request) {\n return\n }\n\n // Ensure the sidebar folders are open\n findRequestParents(request).forEach((uid: string) =>\n setCollapsedSidebarFolder(uid, true),\n )\n },\n { immediate: true },\n)\n\nconst {\n searchText,\n searchResultsWithPlaceholderResults,\n selectedSearchResult,\n onSearchResultClick,\n fuseSearch,\n searchInputRef,\n searchResultRefs,\n navigateSearchResults,\n selectSearchResult,\n} = useSearch()\n\nconst searchToggleRef = ref<HTMLButtonElement>()\n\n/** Handle hotkey events from the bus */\nconst handleHotKey = (event?: HotKeyEvent) => {\n if (!event) {\n return\n }\n if (event.toggleSidebar) {\n toggleSidebarOpen()\n }\n if (event.focusRequestSearch) {\n searchInputRef.value?.focus()\n }\n}\n\nonMounted(() => events.hotKeys.on(handleHotKey))\n\n/**\n * Need to manually remove listener on unmount due to vueuse memory leak\n *\n * @see https://github.com/vueuse/vueuse/issues/3498#issuecomment-2055546566\n */\nonBeforeUnmount(() => {\n events.hotKeys.off(handleHotKey)\n})\n\nconst handleToggleWatchMode = (item?: SidebarItem) => {\n if (item?.documentUrl) {\n item.watchMode = !item.watchMode\n const currentCollection = activeWorkspaceCollections.value.find(\n (collection: Collection) => collection.uid === item.entity.uid,\n )\n if (currentCollection) {\n currentCollection.watchMode = item.watchMode\n }\n }\n}\n\nwatch(\n () =>\n activeWorkspaceCollections.value.map(\n (collection: Collection) => collection.watchMode,\n ),\n (newWatchModes, oldWatchModes) => {\n newWatchModes.forEach((newWatchMode: boolean, index: number) => {\n if (\n layout !== 'modal' &&\n newWatchMode !== oldWatchModes[index] &&\n activeWorkspaceCollections.value[index]?.info?.title !== 'Drafts' &&\n activeWorkspaceCollections.value[index]\n ) {\n const currentCollection = activeWorkspaceCollections.value[index]\n if (!currentCollection) {\n return\n }\n\n const message = `${currentCollection.info?.title}: Watch Mode ${newWatchMode ? 'enabled' : 'disabled'}`\n toast(message, 'info')\n }\n })\n },\n)\n\n/** Screen reader label for the search input */\nconst srLabel = computed<string>(() => {\n const results = searchResultsWithPlaceholderResults.value\n if (!results.length) {\n return 'No results found'\n }\n\n const result = results[selectedSearchResult.value]?.item\n if (!result) {\n return 'No result selected'\n }\n\n const resultsFoundLabel = searchText.value.length\n ? `${results.length} result${results.length === 1 ? '' : 's'} found, `\n : ''\n\n const selectedResultDescription = `, HTTP Method ${result.httpVerb}, Path ${result.path}`\n\n const selectedResultLabel = `${result.title} ${selectedResultDescription}`\n\n return `${resultsFoundLabel}Selected: ${selectedResultLabel}`\n})\n\nconst handleClearDrafts = () => {\n const draftCollection = activeWorkspaceCollections.value.find(\n (collection: Collection) => collection.info?.title === 'Drafts',\n )\n\n if (draftCollection) {\n draftCollection.requests.forEach((requestUid: string) => {\n if (requests[requestUid]) {\n requestMutators.delete(requests[requestUid], draftCollection.uid)\n }\n })\n }\n\n const hasRequests = activeWorkspaceRequests.value.length\n\n // First request in the first collection\n if (hasRequests) {\n const firstCollection = activeWorkspaceCollections.value[0]\n const firstRequest = firstCollection?.requests[0]\n\n if (firstRequest) {\n replace({\n name: 'request',\n params: {\n [PathId.Request]: firstRequest,\n },\n })\n }\n }\n // Create a new request and go to it\n else {\n const { request } = createInitialRequest()\n\n if (draftCollection) {\n requestMutators.add(request, draftCollection.uid)\n\n replace({\n name: 'request',\n params: {\n [PathId.Request]: request.uid,\n },\n })\n }\n }\n}\n\nwatch(isSearchVisible, (isVisible) => {\n // If we're hiding the search, clear the text\n if (!isVisible) {\n searchText.value = ''\n }\n})\n\nconst showGettingStarted = computed(() =>\n isGettingStarted(\n activeWorkspaceCollections.value,\n activeWorkspaceRequests.value,\n requests,\n ),\n)\n\n/** We ensure in modal mode we only show the current requests collection */\nconst collections = computed(() => {\n if (layout === 'modal' && activeCollection.value) {\n return [activeCollection.value]\n }\n return activeWorkspaceCollections.value\n})\n\n/** Hide the search input if the text is empty */\nfunction handleBlur(e: FocusEvent) {\n // We have to check the blur did not come from the search toggle button\n // otherwise the search will show again form the click event\n if (!searchText.value && e.relatedTarget !== searchToggleRef.value) {\n isSearchVisible.value = false\n }\n}\n</script>\n<template>\n <Sidebar\n v-show=\"isSidebarOpen\"\n :class=\"[isSidebarOpen ? 'sidebar-active-width' : '']\">\n <template\n v-if=\"layout !== 'modal'\"\n #header />\n <template #content>\n <div class=\"bg-b-1 sticky top-0 z-20 flex h-12 items-center px-3\">\n <!-- Holds space for the sidebar toggle -->\n <div\n class=\"size-8\"\n :class=\"{ 'xl:hidden': layout !== 'modal' }\" />\n <WorkspaceDropdown v-if=\"layout !== 'modal'\" />\n <span\n v-if=\"layout !== 'modal'\"\n class=\"text-c-3\">\n /\n </span>\n <EnvironmentSelector v-if=\"layout !== 'modal'\" />\n <button\n ref=\"searchToggleRef\"\n :aria-pressed=\"isSearchVisible\"\n class=\"ml-auto\"\n type=\"button\"\n @click=\"isSearchVisible = !isSearchVisible\">\n <span class=\"sr-only\">\n {{ isSearchVisible ? 'Hide' : 'Show' }} search\n </span>\n <ScalarIcon\n class=\"text-c-3 hover:bg-b-2 max-h-8 max-w-8 rounded-lg p-1.75 text-sm\"\n icon=\"Search\" />\n </button>\n </div>\n <div\n v-if=\"isSearchVisible\"\n class=\"search-button-fade sticky top-12 z-10 px-3 py-2.5 pt-0 focus-within:z-20\"\n role=\"search\">\n <ScalarSidebarSearchInput\n ref=\"searchInputRef\"\n v-model=\"searchText\"\n autofocus\n :aria-controls=\"searchResultsId\"\n :label=\"srLabel\"\n @input=\"fuseSearch\"\n @keydown.down.stop=\"navigateSearchResults('down')\"\n @keydown.enter.stop=\"selectSearchResult()\"\n @keydown.up.stop=\"navigateSearchResults('up')\"\n @blur=\"handleBlur\" />\n </div>\n <div\n class=\"gap-1/2 flex flex-1 flex-col overflow-visible overflow-y-auto px-3 pt-0 pb-3\"\n :class=\"[\n {\n 'pb-14': layout !== 'modal',\n },\n {\n 'h-[calc(100%-273.5px)]': showGettingStarted,\n },\n ]\"\n @dragenter.prevent\n @dragover.prevent>\n <template v-if=\"searchText\">\n <ScalarSearchResultList\n :id=\"searchResultsId\"\n aria-label=\"Search Results\"\n class=\"gap-px\"\n :noResults=\"!searchResultsWithPlaceholderResults.length\">\n <ScalarSearchResultItem\n v-for=\"(entry, index) in searchResultsWithPlaceholderResults\"\n :id=\"`#search-input-${entry.item.id}`\"\n :key=\"entry.refIndex\"\n :ref=\"(el) => (searchResultRefs[index] = el as HTMLElement)\"\n :selected=\"selectedSearchResult === index\"\n class=\"px-2\"\n :href=\"entry.item.link\"\n @click.prevent=\"onSearchResultClick(entry)\"\n @focus=\"selectedSearchResult = index\">\n {{ entry.item.title }}\n <template #addon>\n <span class=\"sr-only\">HTTP Method:</span>\n <HttpMethod\n class=\"font-bold\"\n :method=\"entry.item.httpVerb ?? 'get'\" />\n </template>\n </ScalarSearchResultItem>\n </ScalarSearchResultList>\n </template>\n <nav\n v-else\n class=\"contents\">\n <!-- Collection -->\n <RequestSidebarItem\n v-for=\"collection in collections\"\n :key=\"collection.uid\"\n :isDraggable=\"\n layout !== 'modal' && collection.info?.title !== 'Drafts'\n \"\n :isDroppable=\"isDroppable\"\n :menuItem=\"menuItem\"\n :parentUids=\"[]\"\n :uid=\"collection.uid\"\n @newTab=\"(name, uid) => emit('newTab', { name, uid })\"\n @onDragEnd=\"handleDragEnd\"\n @openMenu=\"(item) => Object.assign(menuItem, item)\">\n <template #leftIcon>\n <ScalarIcon\n v-if=\"collection.info?.title === 'Drafts'\"\n class=\"text-sidebar-c-2\"\n icon=\"Scribble\"\n thickness=\"2.25\" />\n <LibraryIcon\n v-else\n class=\"text-sidebar-c-2 size-3.5 min-w-3.5 stroke-2\"\n :src=\"\n collection['x-scalar-icon'] || 'interface-content-folder'\n \" />\n </template>\n </RequestSidebarItem>\n </nav>\n </div>\n </template>\n <template #button>\n <div\n :class=\"{\n 'empty-sidebar-item': showGettingStarted,\n }\">\n <div\n v-if=\"showGettingStarted\"\n class=\"empty-sidebar-item-content px-2.5 py-2.5\">\n <div class=\"rabbit-ascii relative m-auto mt-2 h-[68px] w-[60px]\">\n <ScalarAsciiArt\n :art=\"Rabbit\"\n class=\"rabbitsit font-bold\" />\n <ScalarAsciiArt\n :art=\"RabbitJump\"\n class=\"rabbitjump absolute top-0 left-0 font-bold\" />\n </div>\n <div class=\"mt-2 mb-2 text-center text-sm text-balance\">\n <b class=\"font-medium\">Let's Get Started</b>\n <p class=\"mt-2\">\n Create request, folder, collection or import from OpenAPI/Postman\n </p>\n </div>\n </div>\n <ScalarButton\n v-if=\"layout !== 'modal'\"\n class=\"mb-1.5 hidden h-fit w-full p-1.5 opacity-0\"\n :class=\"{\n 'flex opacity-100': showGettingStarted,\n }\"\n @click=\"openCommandPaletteImport\">\n Import Collection\n </ScalarButton>\n <SidebarButton\n v-if=\"layout !== 'modal'\"\n :click=\"events.commandPalette.emit\"\n hotkey=\"K\">\n <template #title> Add Item </template>\n </SidebarButton>\n </div>\n </template>\n </Sidebar>\n\n <!-- Menu -->\n <RequestSidebarItemMenu\n v-if=\"layout !== 'modal' && menuItem\"\n :menuItem=\"menuItem\"\n @clearDrafts=\"handleClearDrafts\"\n @closeMenu=\"menuItem.open = false\"\n @toggleWatchMode=\"handleToggleWatchMode\" />\n</template>\n<style scoped>\n.search-button-fade {\n background: linear-gradient(\n var(--scalar-background-1) 32px,\n color-mix(in srgb, var(--scalar-background-1), transparent) 38px,\n transparent\n );\n}\n.empty-sidebar-item-content {\n display: none;\n}\n.empty-sidebar-item .empty-sidebar-item-content {\n display: block;\n}\n.rabbitjump {\n opacity: 0;\n}\n.empty-sidebar-item:hover .rabbitjump {\n opacity: 1;\n animation: rabbitAnimation 0.5s steps(1) infinite;\n}\n.empty-sidebar-item:hover .rabbitsit {\n opacity: 0;\n animation: rabbitAnimation2 0.5s steps(1) infinite;\n}\n.empty-sidebar-item:hover .rabbit-ascii {\n animation: rabbitRun 8s infinite linear;\n}\n@keyframes rabbitRun {\n 0% {\n transform: translate3d(0, 0, 0);\n }\n 25% {\n transform: translate3d(250px, 0, 0);\n }\n 25.01% {\n transform: translate3d(-250px, 0, 0);\n }\n 75% {\n transform: translate3d(250px, 0, 0);\n }\n 75.01% {\n transform: translate3d(-250px, 0, 0);\n }\n 100% {\n transform: translate3d(0, 0, 0);\n }\n}\n@keyframes rabbitAnimation {\n 0%,\n 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0;\n }\n}\n@keyframes rabbitAnimation2 {\n 0%,\n 100% {\n opacity: 0;\n }\n 50% {\n opacity: 1;\n transform: translate3d(0, -8px, 0);\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport { isDefined } from '@scalar/helpers/array/is-defined'\nimport { safeJSON } from '@scalar/object-utils/parse'\nimport { useToasts } from '@scalar/use-toasts'\nimport { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'\nimport { RouterView } from 'vue-router'\n\nimport SidebarToggle from '@/components/Sidebar/SidebarToggle.vue'\nimport { useLayout } from '@/hooks'\nimport { useAnalytics } from '@/hooks/useAnalytics'\nimport { useClientConfig } from '@/hooks/useClientConfig'\nimport { useSidebar } from '@/hooks/useSidebar'\nimport { ERRORS } from '@/libs'\nimport { createRequestOperation } from '@/libs/send-request'\nimport type { SendRequestResult } from '@/libs/send-request/create-request-operation'\nimport {\n validateParameters,\n type ValidationResult,\n} from '@/libs/validate-parameters'\nimport { usePluginManager } from '@/plugins'\nimport { useWorkspace } from '@/store'\nimport { useActiveEntities } from '@/store/active-entities'\nimport { useOpenApiWatcher } from '@/views/Request/hooks/useOpenApiWatcher'\n\nimport RequestSidebar from './RequestSidebar.vue'\n\ndefineEmits<(e: 'newTab', item: { name: string; uid: string }) => void>()\nconst workspaceContext = useWorkspace()\nconst { toast } = useToasts()\nconst { layout } = useLayout()\nconst config = useClientConfig()\nconst { isSidebarOpen } = useSidebar()\nconst analytics = useAnalytics()\n\nconst {\n activeCollection,\n activeExample,\n activeEnvironment,\n activeRequest,\n activeWorkspace,\n activeServer,\n} = useActiveEntities()\nconst {\n cookies,\n requestHistory,\n showSidebar,\n securitySchemes,\n modalState,\n events,\n} = workspaceContext\n\nconst pluginManager = usePluginManager()\n\n/** Root element (bound in template via ref=\"_element\") */\nconst _element = ref<HTMLDivElement>()\nvoid _element\n\nconst requestAbortController = ref<AbortController>()\n/** Computed Validation State Update on Example Change */\nconst validation = computed<ValidationResult>(() =>\n validateParameters(activeExample.value ?? null),\n)\nconst requestResult = ref<SendRequestResult | null>(null)\n\n/**\n * Selected scheme UIDs\n *\n * In the modal we use collection.selectedSecuritySchemes and in the\n * standalone client we use request.selectedSecuritySchemeUids\n *\n * These are centralized here so they can be drilled down AND used in send-request\n */\nconst selectedSecuritySchemeUids = computed(\n () =>\n (activeCollection.value?.useCollectionSecurity\n ? activeCollection.value?.selectedSecuritySchemeUids\n : activeRequest.value?.selectedSecuritySchemeUids) ?? [],\n)\n\n/**\n * Execute the request\n * called from the send button as well as keyboard shortcuts\n */\nconst executeRequest = async () => {\n if (!activeRequest.value || !activeExample.value || !activeCollection.value) {\n return\n }\n\n // Block request if there are empty required path parameters\n if (validation.value.hasBlockingErrors) {\n toast('Path parameters must have values.', 'error')\n events.requestStatus.emit('abort')\n return\n }\n\n const environmentValue =\n typeof activeEnvironment.value === 'object'\n ? activeEnvironment.value.value\n : '{}'\n const e = safeJSON.parse(environmentValue)\n if (e.error) {\n console.error('INVALID ENVIRONMENT!')\n }\n const environment =\n e.error || typeof e.data !== 'object' ? {} : (e.data ?? {})\n\n const globalCookies =\n activeWorkspace.value?.cookies.map((c) => cookies[c]).filter(isDefined) ??\n []\n\n const server =\n activeCollection.value?.info?.title === 'Drafts'\n ? undefined\n : activeServer.value\n\n const [error, requestOperation] = createRequestOperation({\n request: activeRequest.value,\n example: activeExample.value,\n selectedSecuritySchemeUids: selectedSecuritySchemeUids.value,\n proxyUrl: activeWorkspace.value?.proxyUrl ?? '',\n environment,\n globalCookies,\n status: events.requestStatus,\n securitySchemes: securitySchemes,\n server,\n pluginManager,\n })\n\n // Call the onRequestSent callback if it exists\n config.value?.onRequestSent?.(activeRequest.value.path ?? '')\n\n // Error from createRequestOperation\n if (error) {\n toast(error.message, 'error')\n return\n }\n\n requestAbortController.value = requestOperation.controller\n const [sendRequestError, result] = await requestOperation.sendRequest()\n\n // Store the result to share it with child components\n requestResult.value = result\n\n // Send error toast\n if (sendRequestError) {\n toast(sendRequestError.message, 'error')\n } else {\n // We need to deep clone the result because it's a ref and updates will break the history\n requestHistory.push(cloneRequestResult(result))\n }\n}\n\n/** Cancel a live request */\nconst cancelRequest = async () =>\n requestAbortController.value?.abort(ERRORS.REQUEST_ABORTED)\n\n/** Subscribed to executeRequest, used for logging / analytics. */\nfunction logRequest() {\n analytics?.capture('client-send-request')\n}\n\n/**\n * Cancel request when closing the modal\n * @see https://github.com/scalar/scalar/issues/7115\n */\nwatch(modalState, ({ open }) => {\n if (!open) {\n void cancelRequest()\n }\n})\n\nonMounted(() => {\n events.executeRequest.on(executeRequest)\n events.executeRequest.on(logRequest)\n events.cancelRequest.on(cancelRequest)\n})\n\nuseOpenApiWatcher()\n\n/**\n * Need to manually remove listener on unmount due to vueuse memory leak\n *\n * @see https://github.com/vueuse/vueuse/issues/3498#issuecomment-2055546566\n */\nonBeforeUnmount(() => {\n events.executeRequest.off(executeRequest)\n events.executeRequest.off(logRequest)\n events.cancelRequest.off(cancelRequest)\n})\n\nconst cloneRequestResult = (result: any) => {\n // Create a structured clone that can handle Blobs, ArrayBuffers, etc.\n try {\n return structuredClone(result)\n } catch {\n // Fallback to a custom cloning approach if structuredClone fails\n // or isn't available in the environment\n const clone = { ...result }\n\n // Handle response data specifically\n if (result.response?.data) {\n // If it's a Blob/File/ArrayBuffer, store a reference\n if (\n result.response.data instanceof Blob ||\n result.response.data instanceof ArrayBuffer\n ) {\n clone.response.data = result.response.data\n } else {\n // For regular objects, do a deep clone\n clone.response.data = JSON.parse(JSON.stringify(result.response.data))\n }\n }\n\n return clone\n }\n}\n</script>\n\n<template>\n <!-- Layout -->\n <div\n ref=\"_element\"\n class=\"bg-b-1 relative z-0 flex h-full flex-1 flex-col overflow-hidden pt-0\"\n :class=\"{\n '!mr-0 !mb-0 !border-0': layout === 'modal',\n }\">\n <SidebarToggle\n v-if=\"showSidebar\"\n v-model=\"isSidebarOpen\"\n class=\"absolute top-2 left-3 z-50\"\n :class=\"[\n { hidden: isSidebarOpen },\n { 'xl:!flex': !isSidebarOpen },\n { '!flex': layout === 'modal' },\n ]\" />\n <div class=\"flex h-full\">\n <!-- Sidebar -->\n <RequestSidebar\n v-if=\"showSidebar\"\n @newTab=\"$emit('newTab', $event)\" />\n\n <!-- Content -->\n <div class=\"flex h-full flex-1 flex-col\">\n <RouterView\n :invalidParams=\"validation.invalidParams\"\n :requestResult=\"requestResult\"\n :selectedSecuritySchemeUids=\"selectedSecuritySchemeUids\" />\n </div>\n </div>\n </div>\n</template>\n\n<style scoped>\n.request-text-color-text {\n color: var(--scalar-color-1);\n background: linear-gradient(\n var(--scalar-background-1),\n var(--scalar-background-3)\n );\n box-shadow: 0 0 0 1px var(--scalar-border-color);\n}\n@media screen and (max-width: 800px) {\n .sidebar-active-hide-layout {\n display: none;\n }\n .sidebar-active-width {\n width: 100%;\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport { isDefined } from '@scalar/helpers/array/is-defined'\nimport { safeJSON } from '@scalar/object-utils/parse'\nimport { useToasts } from '@scalar/use-toasts'\nimport { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'\nimport { RouterView } from 'vue-router'\n\nimport SidebarToggle from '@/components/Sidebar/SidebarToggle.vue'\nimport { useLayout } from '@/hooks'\nimport { useAnalytics } from '@/hooks/useAnalytics'\nimport { useClientConfig } from '@/hooks/useClientConfig'\nimport { useSidebar } from '@/hooks/useSidebar'\nimport { ERRORS } from '@/libs'\nimport { createRequestOperation } from '@/libs/send-request'\nimport type { SendRequestResult } from '@/libs/send-request/create-request-operation'\nimport {\n validateParameters,\n type ValidationResult,\n} from '@/libs/validate-parameters'\nimport { usePluginManager } from '@/plugins'\nimport { useWorkspace } from '@/store'\nimport { useActiveEntities } from '@/store/active-entities'\nimport { useOpenApiWatcher } from '@/views/Request/hooks/useOpenApiWatcher'\n\nimport RequestSidebar from './RequestSidebar.vue'\n\ndefineEmits<(e: 'newTab', item: { name: string; uid: string }) => void>()\nconst workspaceContext = useWorkspace()\nconst { toast } = useToasts()\nconst { layout } = useLayout()\nconst config = useClientConfig()\nconst { isSidebarOpen } = useSidebar()\nconst analytics = useAnalytics()\n\nconst {\n activeCollection,\n activeExample,\n activeEnvironment,\n activeRequest,\n activeWorkspace,\n activeServer,\n} = useActiveEntities()\nconst {\n cookies,\n requestHistory,\n showSidebar,\n securitySchemes,\n modalState,\n events,\n} = workspaceContext\n\nconst pluginManager = usePluginManager()\n\n/** Root element (bound in template via ref=\"_element\") */\nconst _element = ref<HTMLDivElement>()\nvoid _element\n\nconst requestAbortController = ref<AbortController>()\n/** Computed Validation State Update on Example Change */\nconst validation = computed<ValidationResult>(() =>\n validateParameters(activeExample.value ?? null),\n)\nconst requestResult = ref<SendRequestResult | null>(null)\n\n/**\n * Selected scheme UIDs\n *\n * In the modal we use collection.selectedSecuritySchemes and in the\n * standalone client we use request.selectedSecuritySchemeUids\n *\n * These are centralized here so they can be drilled down AND used in send-request\n */\nconst selectedSecuritySchemeUids = computed(\n () =>\n (activeCollection.value?.useCollectionSecurity\n ? activeCollection.value?.selectedSecuritySchemeUids\n : activeRequest.value?.selectedSecuritySchemeUids) ?? [],\n)\n\n/**\n * Execute the request\n * called from the send button as well as keyboard shortcuts\n */\nconst executeRequest = async () => {\n if (!activeRequest.value || !activeExample.value || !activeCollection.value) {\n return\n }\n\n // Block request if there are empty required path parameters\n if (validation.value.hasBlockingErrors) {\n toast('Path parameters must have values.', 'error')\n events.requestStatus.emit('abort')\n return\n }\n\n const environmentValue =\n typeof activeEnvironment.value === 'object'\n ? activeEnvironment.value.value\n : '{}'\n const e = safeJSON.parse(environmentValue)\n if (e.error) {\n console.error('INVALID ENVIRONMENT!')\n }\n const environment =\n e.error || typeof e.data !== 'object' ? {} : (e.data ?? {})\n\n const globalCookies =\n activeWorkspace.value?.cookies.map((c) => cookies[c]).filter(isDefined) ??\n []\n\n const server =\n activeCollection.value?.info?.title === 'Drafts'\n ? undefined\n : activeServer.value\n\n const [error, requestOperation] = createRequestOperation({\n request: activeRequest.value,\n example: activeExample.value,\n selectedSecuritySchemeUids: selectedSecuritySchemeUids.value,\n proxyUrl: activeWorkspace.value?.proxyUrl ?? '',\n environment,\n globalCookies,\n status: events.requestStatus,\n securitySchemes: securitySchemes,\n server,\n pluginManager,\n })\n\n // Call the onRequestSent callback if it exists\n config.value?.onRequestSent?.(activeRequest.value.path ?? '')\n\n // Error from createRequestOperation\n if (error) {\n toast(error.message, 'error')\n return\n }\n\n requestAbortController.value = requestOperation.controller\n const [sendRequestError, result] = await requestOperation.sendRequest()\n\n // Store the result to share it with child components\n requestResult.value = result\n\n // Send error toast\n if (sendRequestError) {\n toast(sendRequestError.message, 'error')\n } else {\n // We need to deep clone the result because it's a ref and updates will break the history\n requestHistory.push(cloneRequestResult(result))\n }\n}\n\n/** Cancel a live request */\nconst cancelRequest = async () =>\n requestAbortController.value?.abort(ERRORS.REQUEST_ABORTED)\n\n/** Subscribed to executeRequest, used for logging / analytics. */\nfunction logRequest() {\n analytics?.capture('client-send-request')\n}\n\n/**\n * Cancel request when closing the modal\n * @see https://github.com/scalar/scalar/issues/7115\n */\nwatch(modalState, ({ open }) => {\n if (!open) {\n void cancelRequest()\n }\n})\n\nonMounted(() => {\n events.executeRequest.on(executeRequest)\n events.executeRequest.on(logRequest)\n events.cancelRequest.on(cancelRequest)\n})\n\nuseOpenApiWatcher()\n\n/**\n * Need to manually remove listener on unmount due to vueuse memory leak\n *\n * @see https://github.com/vueuse/vueuse/issues/3498#issuecomment-2055546566\n */\nonBeforeUnmount(() => {\n events.executeRequest.off(executeRequest)\n events.executeRequest.off(logRequest)\n events.cancelRequest.off(cancelRequest)\n})\n\nconst cloneRequestResult = (result: any) => {\n // Create a structured clone that can handle Blobs, ArrayBuffers, etc.\n try {\n return structuredClone(result)\n } catch {\n // Fallback to a custom cloning approach if structuredClone fails\n // or isn't available in the environment\n const clone = { ...result }\n\n // Handle response data specifically\n if (result.response?.data) {\n // If it's a Blob/File/ArrayBuffer, store a reference\n if (\n result.response.data instanceof Blob ||\n result.response.data instanceof ArrayBuffer\n ) {\n clone.response.data = result.response.data\n } else {\n // For regular objects, do a deep clone\n clone.response.data = JSON.parse(JSON.stringify(result.response.data))\n }\n }\n\n return clone\n }\n}\n</script>\n\n<template>\n <!-- Layout -->\n <div\n ref=\"_element\"\n class=\"bg-b-1 relative z-0 flex h-full flex-1 flex-col overflow-hidden pt-0\"\n :class=\"{\n '!mr-0 !mb-0 !border-0': layout === 'modal',\n }\">\n <SidebarToggle\n v-if=\"showSidebar\"\n v-model=\"isSidebarOpen\"\n class=\"absolute top-2 left-3 z-50\"\n :class=\"[\n { hidden: isSidebarOpen },\n { 'xl:!flex': !isSidebarOpen },\n { '!flex': layout === 'modal' },\n ]\" />\n <div class=\"flex h-full\">\n <!-- Sidebar -->\n <RequestSidebar\n v-if=\"showSidebar\"\n @newTab=\"$emit('newTab', $event)\" />\n\n <!-- Content -->\n <div class=\"flex h-full flex-1 flex-col\">\n <RouterView\n :invalidParams=\"validation.invalidParams\"\n :requestResult=\"requestResult\"\n :selectedSecuritySchemeUids=\"selectedSecuritySchemeUids\" />\n </div>\n </div>\n </div>\n</template>\n\n<style scoped>\n.request-text-color-text {\n color: var(--scalar-color-1);\n background: linear-gradient(\n var(--scalar-background-1),\n var(--scalar-background-3)\n );\n box-shadow: 0 0 0 1px var(--scalar-border-color);\n}\n@media screen and (max-width: 800px) {\n .sidebar-active-hide-layout {\n display: none;\n }\n .sidebar-active-width {\n width: 100%;\n }\n}\n</style>\n"],"mappings":"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"}