@scalar/api-client 3.1.0 → 3.2.1

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 (157) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/components/HttpMethod/HttpMethod.vue.d.ts +2 -2
  3. package/dist/components/Sidebar/Actions/SidebarListElementForm.vue.d.ts +2 -2
  4. package/dist/style.css +95 -71
  5. package/dist/v2/blocks/operation-block/OperationBlock.vue.d.ts.map +1 -1
  6. package/dist/v2/blocks/operation-block/OperationBlock.vue.js.map +1 -1
  7. package/dist/v2/blocks/operation-block/OperationBlock.vue.script.js +2 -1
  8. package/dist/v2/blocks/operation-block/OperationBlock.vue.script.js.map +1 -1
  9. package/dist/v2/blocks/operation-block/helpers/send-request.d.ts +5 -1
  10. package/dist/v2/blocks/operation-block/helpers/send-request.d.ts.map +1 -1
  11. package/dist/v2/blocks/operation-block/helpers/send-request.js +2 -2
  12. package/dist/v2/blocks/operation-block/helpers/send-request.js.map +1 -1
  13. package/dist/v2/blocks/operation-code-sample/components/OperationCodeSample.vue.d.ts.map +1 -1
  14. package/dist/v2/blocks/operation-code-sample/components/OperationCodeSample.vue.js +1 -1
  15. package/dist/v2/blocks/operation-code-sample/components/OperationCodeSample.vue.js.map +1 -1
  16. package/dist/v2/blocks/operation-code-sample/components/OperationCodeSample.vue.script.js +4 -0
  17. package/dist/v2/blocks/operation-code-sample/components/OperationCodeSample.vue.script.js.map +1 -1
  18. package/dist/v2/blocks/request-block/RequestBlock.vue.script.js.map +1 -1
  19. package/dist/v2/blocks/request-block/components/RequestBody.vue.d.ts.map +1 -1
  20. package/dist/v2/blocks/request-block/components/RequestBody.vue.js +1 -1
  21. package/dist/v2/blocks/request-block/components/RequestBody.vue.js.map +1 -1
  22. package/dist/v2/blocks/request-block/components/RequestBody.vue.script.js +1 -0
  23. package/dist/v2/blocks/request-block/components/RequestBody.vue.script.js.map +1 -1
  24. package/dist/v2/blocks/request-block/components/RequestTableRow.vue.d.ts.map +1 -1
  25. package/dist/v2/blocks/request-block/components/RequestTableRow.vue.js.map +1 -1
  26. package/dist/v2/blocks/request-block/components/RequestTableRow.vue.script.js +1 -0
  27. package/dist/v2/blocks/request-block/components/RequestTableRow.vue.script.js.map +1 -1
  28. package/dist/v2/blocks/scalar-address-bar-block/components/AddressBar.vue.d.ts +1 -1
  29. package/dist/v2/blocks/scalar-address-bar-block/components/EnvironmentSelector.vue.js.map +1 -1
  30. package/dist/v2/blocks/scalar-address-bar-block/components/EnvironmentSelector.vue.script.js +3 -3
  31. package/dist/v2/blocks/scalar-address-bar-block/components/EnvironmentSelector.vue.script.js.map +1 -1
  32. package/dist/v2/blocks/scalar-auth-selector-block/components/AuthSelector.vue.script.js.map +1 -1
  33. package/dist/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue.d.ts.map +1 -1
  34. package/dist/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue.js.map +1 -1
  35. package/dist/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue.script.js +131 -48
  36. package/dist/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue.script.js.map +1 -1
  37. package/dist/v2/blocks/scalar-auth-selector-block/components/OAuthScopesAddModal.vue.d.ts +2 -2
  38. package/dist/v2/blocks/scalar-auth-selector-block/components/OAuthScopesAddModal.vue.d.ts.map +1 -1
  39. package/dist/v2/blocks/scalar-auth-selector-block/helpers/extract-security-scheme-secrets.d.ts.map +1 -1
  40. package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth.d.ts +16 -0
  41. package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth.d.ts.map +1 -1
  42. package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth.js +43 -1
  43. package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth.js.map +1 -1
  44. package/dist/v2/components/code-input/CodeInput.vue.d.ts +6 -2
  45. package/dist/v2/components/code-input/CodeInput.vue.d.ts.map +1 -1
  46. package/dist/v2/components/code-input/CodeInput.vue.js +1 -1
  47. package/dist/v2/components/code-input/CodeInput.vue.js.map +1 -1
  48. package/dist/v2/components/code-input/CodeInput.vue.script.js +9 -4
  49. package/dist/v2/components/code-input/CodeInput.vue.script.js.map +1 -1
  50. package/dist/v2/components/data-table/DataTableInput.vue.d.ts +3 -0
  51. package/dist/v2/components/data-table/DataTableInput.vue.d.ts.map +1 -1
  52. package/dist/v2/components/data-table/DataTableInput.vue.js +1 -1
  53. package/dist/v2/components/data-table/DataTableInput.vue.js.map +1 -1
  54. package/dist/v2/components/data-table/DataTableInput.vue.script.js +7 -1
  55. package/dist/v2/components/data-table/DataTableInput.vue.script.js.map +1 -1
  56. package/dist/v2/components/forms/ConfirmationForm.vue.d.ts +2 -2
  57. package/dist/v2/components/sidebar/Sidebar.vue.d.ts.map +1 -1
  58. package/dist/v2/components/sidebar/Sidebar.vue.js.map +1 -1
  59. package/dist/v2/components/sidebar/Sidebar.vue.script.js +16 -8
  60. package/dist/v2/components/sidebar/Sidebar.vue.script.js.map +1 -1
  61. package/dist/v2/components/sidebar/SidebarToggle.vue.js.map +1 -1
  62. package/dist/v2/components/sidebar/SidebarToggle.vue.script.js +1 -1
  63. package/dist/v2/components/sidebar/SidebarToggle.vue.script.js.map +1 -1
  64. package/dist/v2/constants.js +1 -1
  65. package/dist/v2/features/app/App.vue.d.ts.map +1 -1
  66. package/dist/v2/features/app/App.vue.js.map +1 -1
  67. package/dist/v2/features/app/App.vue.script.js +13 -13
  68. package/dist/v2/features/app/App.vue.script.js.map +1 -1
  69. package/dist/v2/features/app/app-state.d.ts +6 -1
  70. package/dist/v2/features/app/app-state.d.ts.map +1 -1
  71. package/dist/v2/features/app/app-state.js +5 -3
  72. package/dist/v2/features/app/app-state.js.map +1 -1
  73. package/dist/v2/features/app/components/AppSidebar.vue.js +1 -1
  74. package/dist/v2/features/app/components/AppSidebar.vue.js.map +1 -1
  75. package/dist/v2/features/app/components/AppSidebar.vue.script.js +1 -1
  76. package/dist/v2/features/app/components/AppSidebar.vue.script.js.map +1 -1
  77. package/dist/v2/features/app/components/DesktopTab.vue.d.ts +2 -2
  78. package/dist/v2/features/app/helpers/create-api-client-app.d.ts +9 -1
  79. package/dist/v2/features/app/helpers/create-api-client-app.d.ts.map +1 -1
  80. package/dist/v2/features/app/helpers/create-api-client-app.js +3 -2
  81. package/dist/v2/features/app/helpers/create-api-client-app.js.map +1 -1
  82. package/dist/v2/features/app/helpers/routes.d.ts +4 -2
  83. package/dist/v2/features/app/helpers/routes.d.ts.map +1 -1
  84. package/dist/v2/features/app/helpers/routes.js.map +1 -1
  85. package/dist/v2/features/collection/DocumentCollection.vue.script.js +2 -1
  86. package/dist/v2/features/collection/DocumentCollection.vue.script.js.map +1 -1
  87. package/dist/v2/features/collection/OperationCollection.vue.script.js +2 -1
  88. package/dist/v2/features/collection/OperationCollection.vue.script.js.map +1 -1
  89. package/dist/v2/features/collection/WorkspaceCollection.vue.script.js +2 -1
  90. package/dist/v2/features/collection/WorkspaceCollection.vue.script.js.map +1 -1
  91. package/dist/v2/features/collection/components/Authentication.vue.d.ts.map +1 -1
  92. package/dist/v2/features/collection/components/Authentication.vue.js +1 -1
  93. package/dist/v2/features/collection/components/Authentication.vue.js.map +1 -1
  94. package/dist/v2/features/collection/components/Authentication.vue.script.js +10 -1
  95. package/dist/v2/features/collection/components/Authentication.vue.script.js.map +1 -1
  96. package/dist/v2/features/collection/components/Cookies.vue.script.js +1 -0
  97. package/dist/v2/features/collection/components/Cookies.vue.script.js.map +1 -1
  98. package/dist/v2/features/collection/components/Editor/Editor.vue.script.js +1 -0
  99. package/dist/v2/features/collection/components/Editor/Editor.vue.script.js.map +1 -1
  100. package/dist/v2/features/collection/components/Environment.vue.script.js +1 -0
  101. package/dist/v2/features/collection/components/Environment.vue.script.js.map +1 -1
  102. package/dist/v2/features/collection/components/Form.vue.d.ts +2 -0
  103. package/dist/v2/features/collection/components/Form.vue.d.ts.map +1 -1
  104. package/dist/v2/features/collection/components/Form.vue.js.map +1 -1
  105. package/dist/v2/features/collection/components/Form.vue.script.js +4 -1
  106. package/dist/v2/features/collection/components/Form.vue.script.js.map +1 -1
  107. package/dist/v2/features/collection/components/LabelInput.vue.d.ts +1 -1
  108. package/dist/v2/features/collection/components/Overview.vue.script.js +1 -0
  109. package/dist/v2/features/collection/components/Overview.vue.script.js.map +1 -1
  110. package/dist/v2/features/collection/components/Runner/components/Runner.vue.d.ts.map +1 -1
  111. package/dist/v2/features/collection/components/Runner/components/Runner.vue.js.map +1 -1
  112. package/dist/v2/features/collection/components/Runner/components/Runner.vue.script.js +4 -2
  113. package/dist/v2/features/collection/components/Runner/components/Runner.vue.script.js.map +1 -1
  114. package/dist/v2/features/collection/components/Runner/components/RunnerTree.vue.d.ts +2 -2
  115. package/dist/v2/features/collection/components/Runner/hooks/use-runner-execution.d.ts +4 -2
  116. package/dist/v2/features/collection/components/Runner/hooks/use-runner-execution.d.ts.map +1 -1
  117. package/dist/v2/features/collection/components/Runner/hooks/use-runner-execution.js +3 -2
  118. package/dist/v2/features/collection/components/Runner/hooks/use-runner-execution.js.map +1 -1
  119. package/dist/v2/features/collection/components/Scripts.vue.script.js +1 -0
  120. package/dist/v2/features/collection/components/Scripts.vue.script.js.map +1 -1
  121. package/dist/v2/features/collection/components/Servers.vue.d.ts.map +1 -1
  122. package/dist/v2/features/collection/components/Servers.vue.js.map +1 -1
  123. package/dist/v2/features/collection/components/Servers.vue.script.js +3 -1
  124. package/dist/v2/features/collection/components/Servers.vue.script.js.map +1 -1
  125. package/dist/v2/features/collection/components/Settings.vue.script.js +1 -0
  126. package/dist/v2/features/collection/components/Settings.vue.script.js.map +1 -1
  127. package/dist/v2/features/command-palette/components/CommandActionForm.vue.d.ts +2 -2
  128. package/dist/v2/features/environments/components/EnvironmentDeleteModal.vue.d.ts +2 -2
  129. package/dist/v2/features/environments/components/EnvironmentVariablesDropdown.vue.d.ts +1 -1
  130. package/dist/v2/features/environments/components/EnvironmentVariablesDropdown.vue.d.ts.map +1 -1
  131. package/dist/v2/features/environments/components/EnvironmentVariablesDropdown.vue.js.map +1 -1
  132. package/dist/v2/features/environments/components/EnvironmentVariablesDropdown.vue.script.js +2 -2
  133. package/dist/v2/features/environments/components/EnvironmentVariablesDropdown.vue.script.js.map +1 -1
  134. package/dist/v2/features/global-cookies/components/CookiesTable.vue.d.ts.map +1 -1
  135. package/dist/v2/features/global-cookies/components/CookiesTable.vue.js +1 -1
  136. package/dist/v2/features/global-cookies/components/CookiesTable.vue.js.map +1 -1
  137. package/dist/v2/features/global-cookies/components/CookiesTable.vue.script.js +2 -0
  138. package/dist/v2/features/global-cookies/components/CookiesTable.vue.script.js.map +1 -1
  139. package/dist/v2/features/modal/Modal.vue.d.ts +7 -6
  140. package/dist/v2/features/modal/Modal.vue.d.ts.map +1 -1
  141. package/dist/v2/features/modal/Modal.vue.js.map +1 -1
  142. package/dist/v2/features/modal/Modal.vue.script.js +2 -2
  143. package/dist/v2/features/modal/Modal.vue.script.js.map +1 -1
  144. package/dist/v2/features/modal/helpers/create-api-client-modal.d.ts +5 -5
  145. package/dist/v2/features/modal/helpers/create-api-client-modal.d.ts.map +1 -1
  146. package/dist/v2/features/modal/helpers/create-api-client-modal.js.map +1 -1
  147. package/dist/v2/features/modal/helpers/types.d.ts +1 -7
  148. package/dist/v2/features/modal/helpers/types.d.ts.map +1 -1
  149. package/dist/v2/features/modal/index.d.ts +1 -1
  150. package/dist/v2/features/modal/index.d.ts.map +1 -1
  151. package/dist/v2/features/operation/Operation.vue.d.ts +0 -5
  152. package/dist/v2/features/operation/Operation.vue.d.ts.map +1 -1
  153. package/dist/v2/features/operation/Operation.vue.js.map +1 -1
  154. package/dist/v2/features/operation/Operation.vue.script.js.map +1 -1
  155. package/dist/v2/types/options.d.ts +15 -0
  156. package/dist/v2/types/options.d.ts.map +1 -0
  157. package/package.json +13 -13
@@ -1 +1 @@
1
- {"version":3,"file":"use-runner-execution.js","names":[],"sources":["../../../../../../../src/v2/features/collection/components/Runner/hooks/use-runner-execution.ts"],"sourcesContent":["import { useLoadingState } from '@scalar/components'\nimport { isElectron } from '@scalar/helpers/general/is-electron'\nimport { executePostResponseScript, executePreRequestScript, getScript } from '@scalar/pre-post-request-scripts'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\nimport {\n type BuildRequestExampleContext,\n buildRequest,\n createVariablesStoreForRequest,\n getEnvironmentVariables,\n getRequestExampleContext,\n requestFactory,\n} from '@scalar/workspace-store/request-example'\nimport type { OpenApiDocument } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport { type ComputedRef, type Ref, computed, ref } from 'vue'\n\nimport { type ResponseInstance, sendRequest } from '@/v2/blocks/operation-block/helpers/send-request'\nimport { APP_VERSION } from '@/v2/constants'\nimport { tryCatch } from '@/v2/helpers/safe-run'\n\nimport type { SelectedItem } from './use-runner-selection'\n\nexport type TestResult = {\n title: string\n passed: boolean\n duration: number\n error?: string\n status: 'pending' | 'passed' | 'failed'\n}\n\nexport type RunResult = {\n item: SelectedItem\n result: ResponseInstance | null\n error: Error | null\n testResults: TestResult[]\n}\n\nexport type RunSummary = {\n total: number\n passed: number\n failed: number\n skipped: number\n duration: number | null\n allPassed: boolean\n}\n\ntype UseRunnerExecutionOptions = {\n /** Workspace store */\n workspaceStore: WorkspaceStore\n /** Document */\n document: OpenApiDocument | null\n /** Document name */\n documentName: string\n /** Whether the layout is web */\n isWeb: boolean\n /** Ordered list of selected items to run */\n selectedOrder: ComputedRef<SelectedItem[]>\n}\n\ntype UseRunnerExecutionReturn = {\n /** Whether a run is currently in progress */\n isRunning: Ref<boolean>\n /** Whether a run has completed */\n hasRunCompleted: Ref<boolean>\n /** Current index being run (1-based) */\n currentRunIndex: Ref<number | null>\n /** Loading state for the run button */\n runLoader: ReturnType<typeof useLoadingState>\n /** Results from the run */\n runResults: Ref<RunResult[]>\n /** Summary of the run results */\n runSummary: ComputedRef<RunSummary | null>\n /** Start running the selected items */\n run: () => Promise<void>\n /** Clear results and run again */\n rerun: () => void\n /** Clear all results */\n clearResults: () => void\n /** Get the result at a specific index */\n getResultAtIndex: (index: number) => RunResult | null\n /** Check if a result passed */\n isResultPassed: (result: RunResult | null) => boolean\n /** Check if a result was skipped */\n isResultSkipped: (index: number) => boolean\n /** Get failed tests from a result */\n getFailedTests: (result: RunResult | null) => TestResult[]\n}\n\n/**\n * Composable for managing runner execution state and logic.\n */\nexport function useRunnerExecution({\n workspaceStore,\n document,\n documentName,\n isWeb,\n selectedOrder,\n}: UseRunnerExecutionOptions): UseRunnerExecutionReturn {\n const isRunning = ref(false)\n const hasRunCompleted = ref(false)\n const currentRunIndex = ref<number | null>(null)\n const runLoader = useLoadingState()\n const runResults = ref<RunResult[]>([])\n const runStartTime = ref<number | null>(null)\n const runEndTime = ref<number | null>(null)\n\n const runSummary = computed<RunSummary | null>(() => {\n if (runResults.value.length === 0 && !hasRunCompleted.value) {\n return null\n }\n const ran = runResults.value.length\n const total = selectedOrder.value.length\n const passed = runResults.value.filter((r) => !r.error && r.testResults.every((t) => t.passed)).length\n const failed = ran - passed\n const skipped = total - ran\n const duration = runStartTime.value && runEndTime.value ? runEndTime.value - runStartTime.value : null\n const allPassed = failed === 0 && skipped === 0\n return { total, passed, failed, skipped, duration, allPassed }\n })\n\n const clearResults = () => {\n runResults.value = []\n hasRunCompleted.value = false\n runStartTime.value = null\n runEndTime.value = null\n }\n\n const rerun = () => {\n clearResults()\n void run()\n }\n\n const getResultAtIndex = (index: number): RunResult | null => {\n return runResults.value[index] ?? null\n }\n\n const isResultPassed = (result: RunResult | null): boolean => {\n if (!result) {\n return false\n }\n if (result.error) {\n return false\n }\n if (result.testResults.some((t) => !t.passed)) {\n return false\n }\n return true\n }\n\n const isResultSkipped = (index: number): boolean => {\n return hasRunCompleted.value && getResultAtIndex(index) === null\n }\n\n const getFailedTests = (result: RunResult | null): TestResult[] => {\n if (!result) {\n return []\n }\n return result.testResults.filter((t) => !t.passed)\n }\n\n const getContext = (item: SelectedItem) => {\n const contextResult = getRequestExampleContext(\n workspaceStore,\n documentName,\n { path: item.path, method: item.method, exampleName: item.exampleKey },\n {\n fallbackDocument: document,\n isElectron: isElectron(),\n layout: isWeb ? 'web' : 'other',\n appVersion: APP_VERSION,\n },\n )\n\n return contextResult\n }\n\n const getRequestFactory = (ctx: BuildRequestExampleContext, item: SelectedItem) => {\n const globalCookies = [...ctx.cookies.workspace, ...ctx.cookies.document]\n return requestFactory({\n defaultHeaders: ctx.headers.default,\n environment: ctx.environment.environment,\n exampleName: item.exampleKey,\n globalCookies,\n method: item.method,\n operation: ctx.operation,\n path: item.path,\n proxyUrl: ctx.proxy.url ?? '',\n server: ctx.servers.selected,\n selectedSecuritySchemes: ctx.security.selectedSchemes,\n isElectron: isElectron(),\n })\n }\n\n const run = async () => {\n if (isRunning.value || !document || selectedOrder.value.length === 0) {\n return\n }\n\n isRunning.value = true\n hasRunCompleted.value = false\n runLoader.start()\n runResults.value = []\n currentRunIndex.value = 0\n runStartTime.value = performance.now()\n runEndTime.value = null\n\n const variablesStore = createVariablesStoreForRequest()\n\n // Run each item in the selected order\n for (let i = 0; i < selectedOrder.value.length; i++) {\n currentRunIndex.value = i + 1\n const item = selectedOrder.value[i]!\n\n // Create a run result for the current item\n const runResult: RunResult = {\n item,\n result: null,\n error: null,\n testResults: [],\n }\n\n try {\n const contextResult = getContext(item)\n\n if (!contextResult.ok) {\n runResult.error = new Error(contextResult.error)\n runResults.value = [...runResults.value, runResult]\n continue\n }\n\n const { request: requestBuilder } = getRequestFactory(contextResult.data, item)\n\n const preRequestScript = getScript(document['x-pre-request'], contextResult.data.operation['x-pre-request'])\n await executePreRequestScript(preRequestScript, {\n requestBuilder,\n variablesStore,\n onTestResultsUpdate: (newResults) => {\n runResult.testResults = [...newResults]\n },\n })\n\n const envVariables = {\n ...getEnvironmentVariables(contextResult.data.environment.environment),\n ...variablesStore.getVariables(),\n }\n\n const requestResult = await tryCatch(() => {\n return buildRequest(requestBuilder, { envVariables })\n })\n\n if (!requestResult.ok) {\n runResult.error = new Error(requestResult.error)\n runResults.value = [...runResults.value, runResult]\n continue\n }\n\n const [sendError, sendResult] = await sendRequest({\n isUsingProxy: requestResult.data.isUsingProxy,\n requestPayload: requestResult.data.requestPayload,\n })\n\n if (sendError) {\n runResult.error = sendError\n runResults.value = [...runResults.value, runResult]\n continue\n }\n\n runResult.result = sendResult.response\n\n const postResponseScript = getScript(\n document['x-post-response'],\n contextResult.data.operation['x-post-response'],\n )\n\n const preRequestResults = [...runResult.testResults]\n await executePostResponseScript(postResponseScript, {\n requestBuilder,\n response: sendResult.originalResponse.clone(),\n variablesStore,\n onTestResultsUpdate: (postResponseResults) => {\n runResult.testResults = [...preRequestResults, ...postResponseResults]\n },\n })\n\n runResults.value = [...runResults.value, runResult]\n\n const hasTestFailure = runResult.testResults.some((t) => !t.passed)\n if (hasTestFailure) {\n break\n }\n } catch (error) {\n runResult.error = error instanceof Error ? error : new Error(String(error))\n runResults.value = [...runResults.value, runResult]\n break\n }\n }\n\n isRunning.value = false\n hasRunCompleted.value = true\n runEndTime.value = performance.now()\n void runLoader.clear()\n currentRunIndex.value = null\n }\n\n return {\n isRunning,\n hasRunCompleted,\n currentRunIndex,\n runLoader,\n runResults,\n runSummary,\n run,\n rerun,\n clearResults,\n getResultAtIndex,\n isResultPassed,\n isResultSkipped,\n getFailedTests,\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"use-runner-execution.js","names":[],"sources":["../../../../../../../src/v2/features/collection/components/Runner/hooks/use-runner-execution.ts"],"sourcesContent":["import { useLoadingState } from '@scalar/components'\nimport { isElectron } from '@scalar/helpers/general/is-electron'\nimport { executePostResponseScript, executePreRequestScript, getScript } from '@scalar/pre-post-request-scripts'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\nimport {\n type BuildRequestExampleContext,\n buildRequest,\n createVariablesStoreForRequest,\n getEnvironmentVariables,\n getRequestExampleContext,\n requestFactory,\n} from '@scalar/workspace-store/request-example'\nimport type { OpenApiDocument } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport { type ComputedRef, type Ref, computed, ref } from 'vue'\n\nimport { type CustomFetch, type ResponseInstance, sendRequest } from '@/v2/blocks/operation-block/helpers/send-request'\nimport { APP_VERSION } from '@/v2/constants'\nimport { tryCatch } from '@/v2/helpers/safe-run'\n\nimport type { SelectedItem } from './use-runner-selection'\n\nexport type TestResult = {\n title: string\n passed: boolean\n duration: number\n error?: string\n status: 'pending' | 'passed' | 'failed'\n}\n\nexport type RunResult = {\n item: SelectedItem\n result: ResponseInstance | null\n error: Error | null\n testResults: TestResult[]\n}\n\nexport type RunSummary = {\n total: number\n passed: number\n failed: number\n skipped: number\n duration: number | null\n allPassed: boolean\n}\n\ntype UseRunnerExecutionOptions = {\n /** Workspace store */\n workspaceStore: WorkspaceStore\n /** Document */\n document: OpenApiDocument | null\n /** Document name */\n documentName: string\n /** Whether the layout is web */\n isWeb: boolean\n /** Ordered list of selected items to run */\n selectedOrder: ComputedRef<SelectedItem[]>\n /** Optional custom fetch implementation, overrides the global fetch for request execution */\n customFetch?: CustomFetch\n}\n\ntype UseRunnerExecutionReturn = {\n /** Whether a run is currently in progress */\n isRunning: Ref<boolean>\n /** Whether a run has completed */\n hasRunCompleted: Ref<boolean>\n /** Current index being run (1-based) */\n currentRunIndex: Ref<number | null>\n /** Loading state for the run button */\n runLoader: ReturnType<typeof useLoadingState>\n /** Results from the run */\n runResults: Ref<RunResult[]>\n /** Summary of the run results */\n runSummary: ComputedRef<RunSummary | null>\n /** Start running the selected items */\n run: () => Promise<void>\n /** Clear results and run again */\n rerun: () => void\n /** Clear all results */\n clearResults: () => void\n /** Get the result at a specific index */\n getResultAtIndex: (index: number) => RunResult | null\n /** Check if a result passed */\n isResultPassed: (result: RunResult | null) => boolean\n /** Check if a result was skipped */\n isResultSkipped: (index: number) => boolean\n /** Get failed tests from a result */\n getFailedTests: (result: RunResult | null) => TestResult[]\n}\n\n/**\n * Composable for managing runner execution state and logic.\n */\nexport function useRunnerExecution({\n workspaceStore,\n document,\n documentName,\n isWeb,\n selectedOrder,\n customFetch,\n}: UseRunnerExecutionOptions): UseRunnerExecutionReturn {\n const isRunning = ref(false)\n const hasRunCompleted = ref(false)\n const currentRunIndex = ref<number | null>(null)\n const runLoader = useLoadingState()\n const runResults = ref<RunResult[]>([])\n const runStartTime = ref<number | null>(null)\n const runEndTime = ref<number | null>(null)\n\n const runSummary = computed<RunSummary | null>(() => {\n if (runResults.value.length === 0 && !hasRunCompleted.value) {\n return null\n }\n const ran = runResults.value.length\n const total = selectedOrder.value.length\n const passed = runResults.value.filter((r) => !r.error && r.testResults.every((t) => t.passed)).length\n const failed = ran - passed\n const skipped = total - ran\n const duration = runStartTime.value && runEndTime.value ? runEndTime.value - runStartTime.value : null\n const allPassed = failed === 0 && skipped === 0\n return { total, passed, failed, skipped, duration, allPassed }\n })\n\n const clearResults = () => {\n runResults.value = []\n hasRunCompleted.value = false\n runStartTime.value = null\n runEndTime.value = null\n }\n\n const rerun = () => {\n clearResults()\n void run()\n }\n\n const getResultAtIndex = (index: number): RunResult | null => {\n return runResults.value[index] ?? null\n }\n\n const isResultPassed = (result: RunResult | null): boolean => {\n if (!result) {\n return false\n }\n if (result.error) {\n return false\n }\n if (result.testResults.some((t) => !t.passed)) {\n return false\n }\n return true\n }\n\n const isResultSkipped = (index: number): boolean => {\n return hasRunCompleted.value && getResultAtIndex(index) === null\n }\n\n const getFailedTests = (result: RunResult | null): TestResult[] => {\n if (!result) {\n return []\n }\n return result.testResults.filter((t) => !t.passed)\n }\n\n const getContext = (item: SelectedItem) => {\n const contextResult = getRequestExampleContext(\n workspaceStore,\n documentName,\n { path: item.path, method: item.method, exampleName: item.exampleKey },\n {\n fallbackDocument: document,\n isElectron: isElectron(),\n layout: isWeb ? 'web' : 'other',\n appVersion: APP_VERSION,\n },\n )\n\n return contextResult\n }\n\n const getRequestFactory = (ctx: BuildRequestExampleContext, item: SelectedItem) => {\n const globalCookies = [...ctx.cookies.workspace, ...ctx.cookies.document]\n return requestFactory({\n defaultHeaders: ctx.headers.default,\n environment: ctx.environment.environment,\n exampleName: item.exampleKey,\n globalCookies,\n method: item.method,\n operation: ctx.operation,\n path: item.path,\n proxyUrl: ctx.proxy.url ?? '',\n server: ctx.servers.selected,\n selectedSecuritySchemes: ctx.security.selectedSchemes,\n isElectron: isElectron(),\n })\n }\n\n const run = async () => {\n if (isRunning.value || !document || selectedOrder.value.length === 0) {\n return\n }\n\n isRunning.value = true\n hasRunCompleted.value = false\n runLoader.start()\n runResults.value = []\n currentRunIndex.value = 0\n runStartTime.value = performance.now()\n runEndTime.value = null\n\n const variablesStore = createVariablesStoreForRequest()\n\n // Run each item in the selected order\n for (let i = 0; i < selectedOrder.value.length; i++) {\n currentRunIndex.value = i + 1\n const item = selectedOrder.value[i]!\n\n // Create a run result for the current item\n const runResult: RunResult = {\n item,\n result: null,\n error: null,\n testResults: [],\n }\n\n try {\n const contextResult = getContext(item)\n\n if (!contextResult.ok) {\n runResult.error = new Error(contextResult.error)\n runResults.value = [...runResults.value, runResult]\n continue\n }\n\n const { request: requestBuilder } = getRequestFactory(contextResult.data, item)\n\n const preRequestScript = getScript(document['x-pre-request'], contextResult.data.operation['x-pre-request'])\n await executePreRequestScript(preRequestScript, {\n requestBuilder,\n variablesStore,\n onTestResultsUpdate: (newResults) => {\n runResult.testResults = [...newResults]\n },\n })\n\n const envVariables = {\n ...getEnvironmentVariables(contextResult.data.environment.environment),\n ...variablesStore.getVariables(),\n }\n\n const requestResult = await tryCatch(() => {\n return buildRequest(requestBuilder, { envVariables })\n })\n\n if (!requestResult.ok) {\n runResult.error = new Error(requestResult.error)\n runResults.value = [...runResults.value, runResult]\n continue\n }\n\n const [sendError, sendResult] = await sendRequest({\n isUsingProxy: requestResult.data.isUsingProxy,\n requestPayload: requestResult.data.requestPayload,\n customFetch,\n })\n\n if (sendError) {\n runResult.error = sendError\n runResults.value = [...runResults.value, runResult]\n continue\n }\n\n runResult.result = sendResult.response\n\n const postResponseScript = getScript(\n document['x-post-response'],\n contextResult.data.operation['x-post-response'],\n )\n\n const preRequestResults = [...runResult.testResults]\n await executePostResponseScript(postResponseScript, {\n requestBuilder,\n response: sendResult.originalResponse.clone(),\n variablesStore,\n onTestResultsUpdate: (postResponseResults) => {\n runResult.testResults = [...preRequestResults, ...postResponseResults]\n },\n })\n\n runResults.value = [...runResults.value, runResult]\n\n const hasTestFailure = runResult.testResults.some((t) => !t.passed)\n if (hasTestFailure) {\n break\n }\n } catch (error) {\n runResult.error = error instanceof Error ? error : new Error(String(error))\n runResults.value = [...runResults.value, runResult]\n break\n }\n }\n\n isRunning.value = false\n hasRunCompleted.value = true\n runEndTime.value = performance.now()\n void runLoader.clear()\n currentRunIndex.value = null\n }\n\n return {\n isRunning,\n hasRunCompleted,\n currentRunIndex,\n runLoader,\n runResults,\n runSummary,\n run,\n rerun,\n clearResults,\n getResultAtIndex,\n isResultPassed,\n isResultSkipped,\n getFailedTests,\n }\n}\n"],"mappings":"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"}
@@ -22,6 +22,7 @@ var Scripts_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ define
22
22
  fetchRegistryDocument: { type: Function },
23
23
  telemetry: { type: Boolean },
24
24
  onUpdateTelemetry: { type: Function },
25
+ options: {},
25
26
  collectionType: {}
26
27
  },
27
28
  setup(__props) {
@@ -1 +1 @@
1
- {"version":3,"file":"Scripts.vue.script.js","names":[],"sources":["../../../../../src/v2/features/collection/components/Scripts.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { CollectionProps } from '@/v2/features/app/helpers/routes'\nimport DocumentScriptsEditors from '@/v2/features/collection/components/DocumentScriptsEditors.vue'\nimport Section from '@/v2/features/settings/components/Section.vue'\n\nconst { document, eventBus, collectionType } = defineProps<CollectionProps>()\n\nconst handleUpdateExtension = (payload: Record<string, unknown>) => {\n eventBus.emit('document:update:extension', payload)\n}\n</script>\n\n<template>\n <Section v-if=\"collectionType === 'document'\">\n <template #title>Pre-request &amp; Post-response Scripts</template>\n <template #description>\n Scripts at the document level run for every request in this document.\n Operation-level scripts (in the request editor) run in addition to these.\n </template>\n <DocumentScriptsEditors\n :document=\"document\"\n @update:extension=\"handleUpdateExtension\" />\n </Section>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;EAOA,MAAM,yBAAyB,YAAqC;AAClE,WAAA,SAAS,KAAK,6BAA6B,QAAO;;;UAKnC,QAAA,mBAAc,cAAA,WAAA,EAA7B,YASU,iBAAA,EAAA,KAAA,GAAA,EAAA;IARG,OAAK,cAAwC,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CAAA,gBAAvC,uCAAuC,GAAA,CAAA,EAAA,CAAA;IAC7C,aAAW,cAGtB,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CAAA,gBAHuB,qJAGvB,GAAA,CAAA,EAAA,CAAA;2BAG8C,CAF9C,YAE8C,gCAAA;KAD3C,UAAU,QAAA;KACV,sBAAkB"}
1
+ {"version":3,"file":"Scripts.vue.script.js","names":[],"sources":["../../../../../src/v2/features/collection/components/Scripts.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { CollectionProps } from '@/v2/features/app/helpers/routes'\nimport DocumentScriptsEditors from '@/v2/features/collection/components/DocumentScriptsEditors.vue'\nimport Section from '@/v2/features/settings/components/Section.vue'\n\nconst { document, eventBus, collectionType } = defineProps<CollectionProps>()\n\nconst handleUpdateExtension = (payload: Record<string, unknown>) => {\n eventBus.emit('document:update:extension', payload)\n}\n</script>\n\n<template>\n <Section v-if=\"collectionType === 'document'\">\n <template #title>Pre-request &amp; Post-response Scripts</template>\n <template #description>\n Scripts at the document level run for every request in this document.\n Operation-level scripts (in the request editor) run in addition to these.\n </template>\n <DocumentScriptsEditors\n :document=\"document\"\n @update:extension=\"handleUpdateExtension\" />\n </Section>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;EAOA,MAAM,yBAAyB,YAAqC;AAClE,WAAA,SAAS,KAAK,6BAA6B,QAAO;;;UAKnC,QAAA,mBAAc,cAAA,WAAA,EAA7B,YASU,iBAAA,EAAA,KAAA,GAAA,EAAA;IARG,OAAK,cAAwC,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CAAA,gBAAvC,uCAAuC,GAAA,CAAA,EAAA,CAAA;IAC7C,aAAW,cAGtB,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CAAA,gBAHuB,qJAGvB,GAAA,CAAA,EAAA,CAAA;2BAG8C,CAF9C,YAE8C,gCAAA;KAD3C,UAAU,QAAA;KACV,sBAAkB"}
@@ -1 +1 @@
1
- {"version":3,"file":"Servers.vue.d.ts","sourceRoot":"","sources":["../../../../../src/v2/features/collection/components/Servers.vue"],"names":[],"mappings":"AAg0BA,QAAA,MAAM,YAAY;;;;;;;;;;;;kGAEhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
1
+ {"version":3,"file":"Servers.vue.d.ts","sourceRoot":"","sources":["../../../../../src/v2/features/collection/components/Servers.vue"],"names":[],"mappings":"AAm0BA,QAAA,MAAM,YAAY;;;;;;;;;;;;kGAEhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Servers.vue.js","names":[],"sources":["../../../../../src/v2/features/collection/components/Servers.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n ScalarButton,\n ScalarMarkdown,\n ScalarModal,\n ScalarToggle,\n useModal,\n} from '@scalar/components'\nimport { debounce } from '@scalar/helpers/general/debounce'\nimport { isHttpMethod } from '@scalar/helpers/http/is-http-method'\nimport { ScalarIconPlus, ScalarIconTrash } from '@scalar/icons'\nimport type { ServerMeta } from '@scalar/workspace-store/events'\nimport { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport type { ServerObject } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport { computed, ref, watchEffect } from 'vue'\n\nimport { ServerVariablesForm } from '@/components/Server'\nimport DeleteSidebarListElement from '@/components/Sidebar/Actions/DeleteSidebarListElement.vue'\nimport type { CollectionProps } from '@/v2/features/app/helpers/routes'\nimport Section from '@/v2/features/settings/components/Section.vue'\n\nimport Form from './Form.vue'\n\nconst { document, eventBus, collectionType, path, method } =\n defineProps<CollectionProps>()\n\nconst deleteModal = useModal()\nconst selectedServerIndex = ref<number>(-1)\n\nconst isOperation = computed(() => collectionType === 'operation')\n\nconst operation = computed(() => {\n if (!isOperation.value) {\n return null\n }\n // Operation not found\n if (!path || !isHttpMethod(method)) {\n return null\n }\n // Operation found, return the servers\n return getResolvedRef(document?.paths?.[path]?.[method])\n})\n\nconst useOperationServers = ref(false)\nwatchEffect(() => {\n useOperationServers.value = operation.value?.servers !== undefined\n})\n\n/** Grab the servers for the collection */\nconst servers = computed(() => {\n if (collectionType === 'operation' && operation.value) {\n return operation.value.servers ?? []\n }\n return document?.servers ?? []\n})\n\n/** Grab whichever server we are working on */\nconst selectedServer = computed(() => servers.value[selectedServerIndex.value])\n\n/** Meta for server events: document-level or operation-level based on collection type */\nconst serverMeta = computed<ServerMeta>(() => {\n if (collectionType === 'operation' && path && isHttpMethod(method)) {\n return { type: 'operation', path, method }\n }\n return { type: 'document' }\n})\n\n// Form field configuration\nconst FORM_OPTIONS = [\n {\n label: 'URL',\n key: 'url',\n placeholder: 'https://void.scalar.com',\n },\n {\n label: 'Description',\n key: 'description',\n placeholder: 'Production',\n lineWrapping: true,\n },\n]\n\n/** Opens the delete confirmation modal for a server */\nconst openDeleteModal = (index: number) => {\n selectedServerIndex.value = index\n deleteModal.show()\n}\n\n/** Closes the delete modal and resets the selected server */\nconst resetState = () => {\n deleteModal.hide()\n selectedServerIndex.value = -1\n}\n\n/** Handles server deletion */\nconst handleDeleteServer = () => {\n if (selectedServerIndex.value < 0) {\n return\n }\n\n eventBus.emit('server:delete:server', {\n index: selectedServerIndex.value,\n meta: serverMeta.value,\n })\n resetState()\n}\n\n/** Debounced execute function for server updates, keyed so we only debounce by server + key */\nconst { execute } = debounce({ delay: 328, maxWait: 1000 })\n\n/** Handles server property updates with debouncing */\nconst handleServerUpdate = (\n index: number,\n key: string,\n value: string | number,\n) =>\n execute(`${index}-${key}-${serverMeta.value.type}`, () =>\n eventBus.emit('server:update:server', {\n index,\n server: { [key]: value },\n meta: serverMeta.value,\n }),\n )\n\n/** Handles server variable updates with debouncing */\nconst handleVariableUpdate = (index: number, key: string, value: string) =>\n execute(`${index}-${key}-${serverMeta.value.type}`, () =>\n eventBus.emit('server:update:variables', {\n index,\n key,\n value,\n meta: serverMeta.value,\n }),\n )\n\n/** Handles adding a new server */\nconst handleAddServer = () =>\n eventBus.emit('server:add:server', { meta: serverMeta.value })\n\n/**\n * Gets the display name for a server\n */\nconst getServerDisplayName = (server?: ServerObject, index = 0): string =>\n server?.description || `Server ${index + 1}`\n\n/** Handles toggling the operation servers */\nconst handleToggleOperationServers = (value: boolean) => {\n // Only toggle for operation collections\n if (serverMeta.value.type !== 'operation') {\n return\n }\n\n // update the operation servers\n useOperationServers.value = value\n\n if (value) {\n // Initialize the servers with an empty array so we will infer the servers from the operation\n return eventBus.emit('server:initialize:servers', {\n meta: serverMeta.value,\n })\n }\n return eventBus.emit('server:clear:servers', { meta: serverMeta.value })\n}\n</script>\n\n<template>\n <Section>\n <template #title>Servers</template>\n <template #description>\n <template v-if=\"isOperation\">\n <span class=\"block\">\n Override servers for this operation with the toggle.\n </span>\n <span class=\"mt-1 block\">\n <strong>On</strong> — Servers below apply only to this operation.\n </span>\n <span class=\"mt-1 block\">\n <strong>Off</strong> — Removes operation servers; this operation uses\n document or path servers from the OpenAPI spec.\n </span>\n <span class=\"text-c-3 mt-1 block\">\n Use <code class=\"font-code text-c-2\">{variables}</code> for dynamic\n URL parts.\n </span>\n </template>\n <template v-else>\n Add different base URLs for your API. Use\n <code class=\"font-code text-c-2\">{variables}</code> for dynamic parts.\n </template>\n </template>\n <!-- Operation Servers Toggle to use the operation servers instead of the document servers -->\n <template\n v-if=\"isOperation\"\n #actions>\n <div class=\"flex h-8 items-center\">\n <ScalarToggle\n class=\"w-4\"\n :modelValue=\"useOperationServers\"\n @update:modelValue=\"handleToggleOperationServers\" />\n </div>\n </template>\n\n <div :class=\"isOperation && !useOperationServers && 'cursor-not-allowed'\">\n <div\n class=\"flex flex-col gap-4\"\n :class=\"\n isOperation &&\n !useOperationServers &&\n 'pointer-events-none cursor-not-allowed opacity-50 mix-blend-luminosity'\n \">\n <!-- Server List -->\n <div class=\"flex flex-col gap-4\">\n <div\n v-for=\"(server, index) in servers\"\n :key=\"index\"\n class=\"rounded-lg border\">\n <!-- Server Header -->\n <div\n class=\"bg-b-2 flex items-center justify-between rounded-t-lg px-3 py-1 text-sm\">\n <ScalarMarkdown\n v-if=\"server.description\"\n class=\"self-center\"\n :value=\"server.description\" />\n <span\n v-else\n class=\"self-center\">\n {{ getServerDisplayName(server, index) }}\n </span>\n <ScalarButton\n class=\"hover:bg-b-3 hover:text-c-1 h-fit p-1.25\"\n data-testid=\"delete-server-button\"\n variant=\"ghost\"\n @click=\"openDeleteModal(index)\">\n <ScalarIconTrash class=\"size-3.5\" />\n </ScalarButton>\n </div>\n\n <!-- Server Variables Form -->\n <div\n class=\"divide-0 flex w-full flex-col divide-y rounded-b-lg text-sm\">\n <Form\n :data=\"server\"\n :environment=\"environment\"\n :onUpdate=\"\n (key, value) => handleServerUpdate(index, key, value)\n \"\n :options=\"FORM_OPTIONS\" />\n <ServerVariablesForm\n v-if=\"server.variables\"\n :variables=\"server.variables\"\n @update:variable=\"\n (name, value) => handleVariableUpdate(index, name, value)\n \" />\n </div>\n </div>\n </div>\n\n <!-- Add Server Button -->\n <div\n class=\"text-c-3 flex h-full items-center justify-center rounded-lg border p-4\">\n <ScalarButton\n class=\"hover:bg-b-2 hover:text-c-1 flex items-center gap-2\"\n size=\"sm\"\n variant=\"ghost\"\n @click=\"handleAddServer\">\n <ScalarIconPlus />\n <span>Add Server</span>\n </ScalarButton>\n </div>\n </div>\n </div>\n </Section>\n\n <!-- Delete Confirmation Modal -->\n <ScalarModal\n size=\"xxs\"\n :state=\"deleteModal\"\n :title=\"`Delete ${getServerDisplayName(selectedServer, selectedServerIndex)}`\">\n <DeleteSidebarListElement\n variableName=\"Server\"\n warningMessage=\"Are you sure you want to delete this server? This action cannot be undone.\"\n @close=\"resetState\"\n @delete=\"handleDeleteServer\" />\n </ScalarModal>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"Servers.vue.js","names":[],"sources":["../../../../../src/v2/features/collection/components/Servers.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n ScalarButton,\n ScalarMarkdown,\n ScalarModal,\n ScalarToggle,\n useModal,\n} from '@scalar/components'\nimport { debounce } from '@scalar/helpers/general/debounce'\nimport { isHttpMethod } from '@scalar/helpers/http/is-http-method'\nimport { ScalarIconPlus, ScalarIconTrash } from '@scalar/icons'\nimport type { ServerMeta } from '@scalar/workspace-store/events'\nimport { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport type { ServerObject } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport { computed, ref, watchEffect } from 'vue'\n\nimport { ServerVariablesForm } from '@/components/Server'\nimport DeleteSidebarListElement from '@/components/Sidebar/Actions/DeleteSidebarListElement.vue'\nimport type { CollectionProps } from '@/v2/features/app/helpers/routes'\nimport Section from '@/v2/features/settings/components/Section.vue'\n\nimport Form from './Form.vue'\n\nconst { document, eventBus, collectionType, path, method } =\n defineProps<CollectionProps>()\n\nconst deleteModal = useModal()\nconst selectedServerIndex = ref<number>(-1)\n\nconst isOperation = computed(() => collectionType === 'operation')\n\nconst operation = computed(() => {\n if (!isOperation.value) {\n return null\n }\n // Operation not found\n if (!path || !isHttpMethod(method)) {\n return null\n }\n // Operation found, return the servers\n return getResolvedRef(document?.paths?.[path]?.[method])\n})\n\nconst useOperationServers = ref(false)\nwatchEffect(() => {\n useOperationServers.value = operation.value?.servers !== undefined\n})\n\n/** Grab the servers for the collection */\nconst servers = computed(() => {\n if (collectionType === 'operation' && operation.value) {\n return operation.value.servers ?? []\n }\n return document?.servers ?? []\n})\n\n/** Grab whichever server we are working on */\nconst selectedServer = computed(() => servers.value[selectedServerIndex.value])\n\n/** Meta for server events: document-level or operation-level based on collection type */\nconst serverMeta = computed<ServerMeta>(() => {\n if (collectionType === 'operation' && path && isHttpMethod(method)) {\n return { type: 'operation', path, method }\n }\n return { type: 'document' }\n})\n\n// Form field configuration\nconst FORM_OPTIONS = [\n {\n label: 'URL',\n key: 'url',\n placeholder: 'https://void.scalar.com',\n },\n {\n label: 'Description',\n key: 'description',\n placeholder: 'Production',\n lineWrapping: true,\n },\n]\n\n/** Opens the delete confirmation modal for a server */\nconst openDeleteModal = (index: number) => {\n selectedServerIndex.value = index\n deleteModal.show()\n}\n\n/** Closes the delete modal and resets the selected server */\nconst resetState = () => {\n deleteModal.hide()\n selectedServerIndex.value = -1\n}\n\n/** Handles server deletion */\nconst handleDeleteServer = () => {\n if (selectedServerIndex.value < 0) {\n return\n }\n\n eventBus.emit('server:delete:server', {\n index: selectedServerIndex.value,\n meta: serverMeta.value,\n })\n resetState()\n}\n\n/** Debounced execute function for server updates, keyed so we only debounce by server + key */\nconst { execute } = debounce({ delay: 328, maxWait: 1000 })\n\n/** Handles server property updates with debouncing */\nconst handleServerUpdate = (\n index: number,\n key: string,\n value: string | number,\n) =>\n execute(`${index}-${key}-${serverMeta.value.type}`, () =>\n eventBus.emit('server:update:server', {\n index,\n server: { [key]: value },\n meta: serverMeta.value,\n }),\n )\n\n/** Handles server variable updates with debouncing */\nconst handleVariableUpdate = (index: number, key: string, value: string) =>\n execute(`${index}-${key}-${serverMeta.value.type}`, () =>\n eventBus.emit('server:update:variables', {\n index,\n key,\n value,\n meta: serverMeta.value,\n }),\n )\n\n/** Handles adding a new server */\nconst handleAddServer = () =>\n eventBus.emit('server:add:server', { meta: serverMeta.value })\n\n/**\n * Gets the display name for a server\n */\nconst getServerDisplayName = (server?: ServerObject, index = 0): string =>\n server?.description || `Server ${index + 1}`\n\n/** Handles toggling the operation servers */\nconst handleToggleOperationServers = (value: boolean) => {\n // Only toggle for operation collections\n if (serverMeta.value.type !== 'operation') {\n return\n }\n\n // update the operation servers\n useOperationServers.value = value\n\n if (value) {\n // Initialize the servers with an empty array so we will infer the servers from the operation\n return eventBus.emit('server:initialize:servers', {\n meta: serverMeta.value,\n })\n }\n return eventBus.emit('server:clear:servers', { meta: serverMeta.value })\n}\n</script>\n\n<template>\n <Section>\n <template #title>Servers</template>\n <template #description>\n <template v-if=\"isOperation\">\n <span class=\"block\">\n Override servers for this operation with the toggle.\n </span>\n <span class=\"mt-1 block\">\n <strong>On</strong> — Servers below apply only to this operation.\n </span>\n <span class=\"mt-1 block\">\n <strong>Off</strong> — Removes operation servers; this operation uses\n document or path servers from the OpenAPI spec.\n </span>\n <span class=\"text-c-3 mt-1 block\">\n Use <code class=\"font-code text-c-2\">{variables}</code> for dynamic\n URL parts.\n </span>\n </template>\n <template v-else>\n Add different base URLs for your API. Use\n <code class=\"font-code text-c-2\">{variables}</code> for dynamic parts.\n </template>\n </template>\n <!-- Operation Servers Toggle to use the operation servers instead of the document servers -->\n <template\n v-if=\"isOperation\"\n #actions>\n <div class=\"flex h-8 items-center\">\n <ScalarToggle\n class=\"w-4\"\n :modelValue=\"useOperationServers\"\n @update:modelValue=\"handleToggleOperationServers\" />\n </div>\n </template>\n\n <div :class=\"isOperation && !useOperationServers && 'cursor-not-allowed'\">\n <div\n class=\"flex flex-col gap-4\"\n :class=\"\n isOperation &&\n !useOperationServers &&\n 'pointer-events-none cursor-not-allowed opacity-50 mix-blend-luminosity'\n \">\n <!-- Server List -->\n <div class=\"flex flex-col gap-4\">\n <div\n v-for=\"(server, index) in servers\"\n :key=\"index\"\n class=\"rounded-lg border\">\n <!-- Server Header -->\n <div\n class=\"bg-b-2 flex items-center justify-between rounded-t-lg px-3 py-1 text-sm\">\n <ScalarMarkdown\n v-if=\"server.description\"\n class=\"self-center\"\n :value=\"server.description\" />\n <span\n v-else\n class=\"self-center\">\n {{ getServerDisplayName(server, index) }}\n </span>\n <ScalarButton\n class=\"hover:bg-b-3 hover:text-c-1 h-fit p-1.25\"\n data-testid=\"delete-server-button\"\n variant=\"ghost\"\n @click=\"openDeleteModal(index)\">\n <ScalarIconTrash class=\"size-3.5\" />\n </ScalarButton>\n </div>\n\n <!-- Server Variables Form -->\n <div\n class=\"divide-0 flex w-full flex-col divide-y rounded-b-lg text-sm\">\n <Form\n :data=\"server\"\n :environment=\"environment\"\n :onUpdate=\"\n (key, value) => handleServerUpdate(index, key, value)\n \"\n :options=\"FORM_OPTIONS\"\n :withFakeData=\"false\" />\n <ServerVariablesForm\n v-if=\"server.variables\"\n :variables=\"server.variables\"\n @update:variable=\"\n (name, value) => handleVariableUpdate(index, name, value)\n \" />\n </div>\n </div>\n </div>\n\n <!-- Add Server Button -->\n <div\n class=\"text-c-3 flex h-full items-center justify-center rounded-lg border p-4\">\n <ScalarButton\n class=\"hover:bg-b-2 hover:text-c-1 flex items-center gap-2\"\n size=\"sm\"\n variant=\"ghost\"\n @click=\"handleAddServer\">\n <ScalarIconPlus />\n <span>Add Server</span>\n </ScalarButton>\n </div>\n </div>\n </div>\n </Section>\n\n <!-- Delete Confirmation Modal -->\n <ScalarModal\n size=\"xxs\"\n :state=\"deleteModal\"\n :title=\"`Delete ${getServerDisplayName(selectedServer, selectedServerIndex)}`\">\n <DeleteSidebarListElement\n variableName=\"Server\"\n warningMessage=\"Are you sure you want to delete this server? This action cannot be undone.\"\n @close=\"resetState\"\n @delete=\"handleDeleteServer\" />\n </ScalarModal>\n</template>\n"],"mappings":""}
@@ -38,6 +38,7 @@ var Servers_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ define
38
38
  fetchRegistryDocument: { type: Function },
39
39
  telemetry: { type: Boolean },
40
40
  onUpdateTelemetry: { type: Function },
41
+ options: {},
41
42
  collectionType: {}
42
43
  },
43
44
  setup(__props) {
@@ -166,7 +167,8 @@ var Servers_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ define
166
167
  data: server,
167
168
  environment: __props.environment,
168
169
  onUpdate: (key, value) => handleServerUpdate(index, key, value),
169
- options: FORM_OPTIONS
170
+ options: FORM_OPTIONS,
171
+ withFakeData: false
170
172
  }, null, 8, [
171
173
  "data",
172
174
  "environment",
@@ -1 +1 @@
1
- {"version":3,"file":"Servers.vue.script.js","names":[],"sources":["../../../../../src/v2/features/collection/components/Servers.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n ScalarButton,\n ScalarMarkdown,\n ScalarModal,\n ScalarToggle,\n useModal,\n} from '@scalar/components'\nimport { debounce } from '@scalar/helpers/general/debounce'\nimport { isHttpMethod } from '@scalar/helpers/http/is-http-method'\nimport { ScalarIconPlus, ScalarIconTrash } from '@scalar/icons'\nimport type { ServerMeta } from '@scalar/workspace-store/events'\nimport { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport type { ServerObject } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport { computed, ref, watchEffect } from 'vue'\n\nimport { ServerVariablesForm } from '@/components/Server'\nimport DeleteSidebarListElement from '@/components/Sidebar/Actions/DeleteSidebarListElement.vue'\nimport type { CollectionProps } from '@/v2/features/app/helpers/routes'\nimport Section from '@/v2/features/settings/components/Section.vue'\n\nimport Form from './Form.vue'\n\nconst { document, eventBus, collectionType, path, method } =\n defineProps<CollectionProps>()\n\nconst deleteModal = useModal()\nconst selectedServerIndex = ref<number>(-1)\n\nconst isOperation = computed(() => collectionType === 'operation')\n\nconst operation = computed(() => {\n if (!isOperation.value) {\n return null\n }\n // Operation not found\n if (!path || !isHttpMethod(method)) {\n return null\n }\n // Operation found, return the servers\n return getResolvedRef(document?.paths?.[path]?.[method])\n})\n\nconst useOperationServers = ref(false)\nwatchEffect(() => {\n useOperationServers.value = operation.value?.servers !== undefined\n})\n\n/** Grab the servers for the collection */\nconst servers = computed(() => {\n if (collectionType === 'operation' && operation.value) {\n return operation.value.servers ?? []\n }\n return document?.servers ?? []\n})\n\n/** Grab whichever server we are working on */\nconst selectedServer = computed(() => servers.value[selectedServerIndex.value])\n\n/** Meta for server events: document-level or operation-level based on collection type */\nconst serverMeta = computed<ServerMeta>(() => {\n if (collectionType === 'operation' && path && isHttpMethod(method)) {\n return { type: 'operation', path, method }\n }\n return { type: 'document' }\n})\n\n// Form field configuration\nconst FORM_OPTIONS = [\n {\n label: 'URL',\n key: 'url',\n placeholder: 'https://void.scalar.com',\n },\n {\n label: 'Description',\n key: 'description',\n placeholder: 'Production',\n lineWrapping: true,\n },\n]\n\n/** Opens the delete confirmation modal for a server */\nconst openDeleteModal = (index: number) => {\n selectedServerIndex.value = index\n deleteModal.show()\n}\n\n/** Closes the delete modal and resets the selected server */\nconst resetState = () => {\n deleteModal.hide()\n selectedServerIndex.value = -1\n}\n\n/** Handles server deletion */\nconst handleDeleteServer = () => {\n if (selectedServerIndex.value < 0) {\n return\n }\n\n eventBus.emit('server:delete:server', {\n index: selectedServerIndex.value,\n meta: serverMeta.value,\n })\n resetState()\n}\n\n/** Debounced execute function for server updates, keyed so we only debounce by server + key */\nconst { execute } = debounce({ delay: 328, maxWait: 1000 })\n\n/** Handles server property updates with debouncing */\nconst handleServerUpdate = (\n index: number,\n key: string,\n value: string | number,\n) =>\n execute(`${index}-${key}-${serverMeta.value.type}`, () =>\n eventBus.emit('server:update:server', {\n index,\n server: { [key]: value },\n meta: serverMeta.value,\n }),\n )\n\n/** Handles server variable updates with debouncing */\nconst handleVariableUpdate = (index: number, key: string, value: string) =>\n execute(`${index}-${key}-${serverMeta.value.type}`, () =>\n eventBus.emit('server:update:variables', {\n index,\n key,\n value,\n meta: serverMeta.value,\n }),\n )\n\n/** Handles adding a new server */\nconst handleAddServer = () =>\n eventBus.emit('server:add:server', { meta: serverMeta.value })\n\n/**\n * Gets the display name for a server\n */\nconst getServerDisplayName = (server?: ServerObject, index = 0): string =>\n server?.description || `Server ${index + 1}`\n\n/** Handles toggling the operation servers */\nconst handleToggleOperationServers = (value: boolean) => {\n // Only toggle for operation collections\n if (serverMeta.value.type !== 'operation') {\n return\n }\n\n // update the operation servers\n useOperationServers.value = value\n\n if (value) {\n // Initialize the servers with an empty array so we will infer the servers from the operation\n return eventBus.emit('server:initialize:servers', {\n meta: serverMeta.value,\n })\n }\n return eventBus.emit('server:clear:servers', { meta: serverMeta.value })\n}\n</script>\n\n<template>\n <Section>\n <template #title>Servers</template>\n <template #description>\n <template v-if=\"isOperation\">\n <span class=\"block\">\n Override servers for this operation with the toggle.\n </span>\n <span class=\"mt-1 block\">\n <strong>On</strong> — Servers below apply only to this operation.\n </span>\n <span class=\"mt-1 block\">\n <strong>Off</strong> — Removes operation servers; this operation uses\n document or path servers from the OpenAPI spec.\n </span>\n <span class=\"text-c-3 mt-1 block\">\n Use <code class=\"font-code text-c-2\">{variables}</code> for dynamic\n URL parts.\n </span>\n </template>\n <template v-else>\n Add different base URLs for your API. Use\n <code class=\"font-code text-c-2\">{variables}</code> for dynamic parts.\n </template>\n </template>\n <!-- Operation Servers Toggle to use the operation servers instead of the document servers -->\n <template\n v-if=\"isOperation\"\n #actions>\n <div class=\"flex h-8 items-center\">\n <ScalarToggle\n class=\"w-4\"\n :modelValue=\"useOperationServers\"\n @update:modelValue=\"handleToggleOperationServers\" />\n </div>\n </template>\n\n <div :class=\"isOperation && !useOperationServers && 'cursor-not-allowed'\">\n <div\n class=\"flex flex-col gap-4\"\n :class=\"\n isOperation &&\n !useOperationServers &&\n 'pointer-events-none cursor-not-allowed opacity-50 mix-blend-luminosity'\n \">\n <!-- Server List -->\n <div class=\"flex flex-col gap-4\">\n <div\n v-for=\"(server, index) in servers\"\n :key=\"index\"\n class=\"rounded-lg border\">\n <!-- Server Header -->\n <div\n class=\"bg-b-2 flex items-center justify-between rounded-t-lg px-3 py-1 text-sm\">\n <ScalarMarkdown\n v-if=\"server.description\"\n class=\"self-center\"\n :value=\"server.description\" />\n <span\n v-else\n class=\"self-center\">\n {{ getServerDisplayName(server, index) }}\n </span>\n <ScalarButton\n class=\"hover:bg-b-3 hover:text-c-1 h-fit p-1.25\"\n data-testid=\"delete-server-button\"\n variant=\"ghost\"\n @click=\"openDeleteModal(index)\">\n <ScalarIconTrash class=\"size-3.5\" />\n </ScalarButton>\n </div>\n\n <!-- Server Variables Form -->\n <div\n class=\"divide-0 flex w-full flex-col divide-y rounded-b-lg text-sm\">\n <Form\n :data=\"server\"\n :environment=\"environment\"\n :onUpdate=\"\n (key, value) => handleServerUpdate(index, key, value)\n \"\n :options=\"FORM_OPTIONS\" />\n <ServerVariablesForm\n v-if=\"server.variables\"\n :variables=\"server.variables\"\n @update:variable=\"\n (name, value) => handleVariableUpdate(index, name, value)\n \" />\n </div>\n </div>\n </div>\n\n <!-- Add Server Button -->\n <div\n class=\"text-c-3 flex h-full items-center justify-center rounded-lg border p-4\">\n <ScalarButton\n class=\"hover:bg-b-2 hover:text-c-1 flex items-center gap-2\"\n size=\"sm\"\n variant=\"ghost\"\n @click=\"handleAddServer\">\n <ScalarIconPlus />\n <span>Add Server</span>\n </ScalarButton>\n </div>\n </div>\n </div>\n </Section>\n\n <!-- Delete Confirmation Modal -->\n <ScalarModal\n size=\"xxs\"\n :state=\"deleteModal\"\n :title=\"`Delete ${getServerDisplayName(selectedServer, selectedServerIndex)}`\">\n <DeleteSidebarListElement\n variableName=\"Server\"\n warningMessage=\"Are you sure you want to delete this server? This action cannot be undone.\"\n @close=\"resetState\"\n @delete=\"handleDeleteServer\" />\n </ScalarModal>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"Servers.vue.script.js","names":[],"sources":["../../../../../src/v2/features/collection/components/Servers.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n ScalarButton,\n ScalarMarkdown,\n ScalarModal,\n ScalarToggle,\n useModal,\n} from '@scalar/components'\nimport { debounce } from '@scalar/helpers/general/debounce'\nimport { isHttpMethod } from '@scalar/helpers/http/is-http-method'\nimport { ScalarIconPlus, ScalarIconTrash } from '@scalar/icons'\nimport type { ServerMeta } from '@scalar/workspace-store/events'\nimport { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport type { ServerObject } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport { computed, ref, watchEffect } from 'vue'\n\nimport { ServerVariablesForm } from '@/components/Server'\nimport DeleteSidebarListElement from '@/components/Sidebar/Actions/DeleteSidebarListElement.vue'\nimport type { CollectionProps } from '@/v2/features/app/helpers/routes'\nimport Section from '@/v2/features/settings/components/Section.vue'\n\nimport Form from './Form.vue'\n\nconst { document, eventBus, collectionType, path, method } =\n defineProps<CollectionProps>()\n\nconst deleteModal = useModal()\nconst selectedServerIndex = ref<number>(-1)\n\nconst isOperation = computed(() => collectionType === 'operation')\n\nconst operation = computed(() => {\n if (!isOperation.value) {\n return null\n }\n // Operation not found\n if (!path || !isHttpMethod(method)) {\n return null\n }\n // Operation found, return the servers\n return getResolvedRef(document?.paths?.[path]?.[method])\n})\n\nconst useOperationServers = ref(false)\nwatchEffect(() => {\n useOperationServers.value = operation.value?.servers !== undefined\n})\n\n/** Grab the servers for the collection */\nconst servers = computed(() => {\n if (collectionType === 'operation' && operation.value) {\n return operation.value.servers ?? []\n }\n return document?.servers ?? []\n})\n\n/** Grab whichever server we are working on */\nconst selectedServer = computed(() => servers.value[selectedServerIndex.value])\n\n/** Meta for server events: document-level or operation-level based on collection type */\nconst serverMeta = computed<ServerMeta>(() => {\n if (collectionType === 'operation' && path && isHttpMethod(method)) {\n return { type: 'operation', path, method }\n }\n return { type: 'document' }\n})\n\n// Form field configuration\nconst FORM_OPTIONS = [\n {\n label: 'URL',\n key: 'url',\n placeholder: 'https://void.scalar.com',\n },\n {\n label: 'Description',\n key: 'description',\n placeholder: 'Production',\n lineWrapping: true,\n },\n]\n\n/** Opens the delete confirmation modal for a server */\nconst openDeleteModal = (index: number) => {\n selectedServerIndex.value = index\n deleteModal.show()\n}\n\n/** Closes the delete modal and resets the selected server */\nconst resetState = () => {\n deleteModal.hide()\n selectedServerIndex.value = -1\n}\n\n/** Handles server deletion */\nconst handleDeleteServer = () => {\n if (selectedServerIndex.value < 0) {\n return\n }\n\n eventBus.emit('server:delete:server', {\n index: selectedServerIndex.value,\n meta: serverMeta.value,\n })\n resetState()\n}\n\n/** Debounced execute function for server updates, keyed so we only debounce by server + key */\nconst { execute } = debounce({ delay: 328, maxWait: 1000 })\n\n/** Handles server property updates with debouncing */\nconst handleServerUpdate = (\n index: number,\n key: string,\n value: string | number,\n) =>\n execute(`${index}-${key}-${serverMeta.value.type}`, () =>\n eventBus.emit('server:update:server', {\n index,\n server: { [key]: value },\n meta: serverMeta.value,\n }),\n )\n\n/** Handles server variable updates with debouncing */\nconst handleVariableUpdate = (index: number, key: string, value: string) =>\n execute(`${index}-${key}-${serverMeta.value.type}`, () =>\n eventBus.emit('server:update:variables', {\n index,\n key,\n value,\n meta: serverMeta.value,\n }),\n )\n\n/** Handles adding a new server */\nconst handleAddServer = () =>\n eventBus.emit('server:add:server', { meta: serverMeta.value })\n\n/**\n * Gets the display name for a server\n */\nconst getServerDisplayName = (server?: ServerObject, index = 0): string =>\n server?.description || `Server ${index + 1}`\n\n/** Handles toggling the operation servers */\nconst handleToggleOperationServers = (value: boolean) => {\n // Only toggle for operation collections\n if (serverMeta.value.type !== 'operation') {\n return\n }\n\n // update the operation servers\n useOperationServers.value = value\n\n if (value) {\n // Initialize the servers with an empty array so we will infer the servers from the operation\n return eventBus.emit('server:initialize:servers', {\n meta: serverMeta.value,\n })\n }\n return eventBus.emit('server:clear:servers', { meta: serverMeta.value })\n}\n</script>\n\n<template>\n <Section>\n <template #title>Servers</template>\n <template #description>\n <template v-if=\"isOperation\">\n <span class=\"block\">\n Override servers for this operation with the toggle.\n </span>\n <span class=\"mt-1 block\">\n <strong>On</strong> — Servers below apply only to this operation.\n </span>\n <span class=\"mt-1 block\">\n <strong>Off</strong> — Removes operation servers; this operation uses\n document or path servers from the OpenAPI spec.\n </span>\n <span class=\"text-c-3 mt-1 block\">\n Use <code class=\"font-code text-c-2\">{variables}</code> for dynamic\n URL parts.\n </span>\n </template>\n <template v-else>\n Add different base URLs for your API. Use\n <code class=\"font-code text-c-2\">{variables}</code> for dynamic parts.\n </template>\n </template>\n <!-- Operation Servers Toggle to use the operation servers instead of the document servers -->\n <template\n v-if=\"isOperation\"\n #actions>\n <div class=\"flex h-8 items-center\">\n <ScalarToggle\n class=\"w-4\"\n :modelValue=\"useOperationServers\"\n @update:modelValue=\"handleToggleOperationServers\" />\n </div>\n </template>\n\n <div :class=\"isOperation && !useOperationServers && 'cursor-not-allowed'\">\n <div\n class=\"flex flex-col gap-4\"\n :class=\"\n isOperation &&\n !useOperationServers &&\n 'pointer-events-none cursor-not-allowed opacity-50 mix-blend-luminosity'\n \">\n <!-- Server List -->\n <div class=\"flex flex-col gap-4\">\n <div\n v-for=\"(server, index) in servers\"\n :key=\"index\"\n class=\"rounded-lg border\">\n <!-- Server Header -->\n <div\n class=\"bg-b-2 flex items-center justify-between rounded-t-lg px-3 py-1 text-sm\">\n <ScalarMarkdown\n v-if=\"server.description\"\n class=\"self-center\"\n :value=\"server.description\" />\n <span\n v-else\n class=\"self-center\">\n {{ getServerDisplayName(server, index) }}\n </span>\n <ScalarButton\n class=\"hover:bg-b-3 hover:text-c-1 h-fit p-1.25\"\n data-testid=\"delete-server-button\"\n variant=\"ghost\"\n @click=\"openDeleteModal(index)\">\n <ScalarIconTrash class=\"size-3.5\" />\n </ScalarButton>\n </div>\n\n <!-- Server Variables Form -->\n <div\n class=\"divide-0 flex w-full flex-col divide-y rounded-b-lg text-sm\">\n <Form\n :data=\"server\"\n :environment=\"environment\"\n :onUpdate=\"\n (key, value) => handleServerUpdate(index, key, value)\n \"\n :options=\"FORM_OPTIONS\"\n :withFakeData=\"false\" />\n <ServerVariablesForm\n v-if=\"server.variables\"\n :variables=\"server.variables\"\n @update:variable=\"\n (name, value) => handleVariableUpdate(index, name, value)\n \" />\n </div>\n </div>\n </div>\n\n <!-- Add Server Button -->\n <div\n class=\"text-c-3 flex h-full items-center justify-center rounded-lg border p-4\">\n <ScalarButton\n class=\"hover:bg-b-2 hover:text-c-1 flex items-center gap-2\"\n size=\"sm\"\n variant=\"ghost\"\n @click=\"handleAddServer\">\n <ScalarIconPlus />\n <span>Add Server</span>\n </ScalarButton>\n </div>\n </div>\n </div>\n </Section>\n\n <!-- Delete Confirmation Modal -->\n <ScalarModal\n size=\"xxs\"\n :state=\"deleteModal\"\n :title=\"`Delete ${getServerDisplayName(selectedServer, selectedServerIndex)}`\">\n <DeleteSidebarListElement\n variableName=\"Server\"\n warningMessage=\"Are you sure you want to delete this server? This action cannot be undone.\"\n @close=\"resetState\"\n @delete=\"handleDeleteServer\" />\n </ScalarModal>\n</template>\n"],"mappings":"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"}
@@ -23,6 +23,7 @@ var Settings_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defin
23
23
  fetchRegistryDocument: { type: Function },
24
24
  telemetry: { type: Boolean },
25
25
  onUpdateTelemetry: { type: Function },
26
+ options: {},
26
27
  collectionType: {}
27
28
  },
28
29
  setup(__props) {
@@ -1 +1 @@
1
- {"version":3,"file":"Settings.vue.script.js","names":[],"sources":["../../../../../src/v2/features/collection/components/Settings.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { getActiveProxyUrl } from '@scalar/workspace-store/request-example'\nimport type { ColorMode } from '@scalar/workspace-store/schemas/workspace'\n\nimport type { CollectionProps } from '@/v2/features/app/helpers/routes'\nimport { CollectionSettings, DocumentSettings } from '@/v2/features/settings'\n\nconst {\n eventBus,\n documentSlug,\n document,\n workspaceStore,\n collectionType,\n layout,\n telemetry,\n onUpdateTelemetry,\n} = defineProps<CollectionProps>()\n\nconst handleUpdateWatchMode = (watchMode: boolean) => {\n eventBus.emit('document:update:watch-mode', watchMode)\n}\n\nconst handleUpdateThemeSlug = (themeSlug?: string) => {\n eventBus.emit('workspace:update:theme', themeSlug)\n}\nconst handleUpdateActiveProxy = (proxy: string | null) => {\n eventBus.emit('workspace:update:active-proxy', proxy)\n}\n\nconst handleUpdateColorMode = (colorMode: ColorMode) => {\n eventBus.emit('workspace:update:color-mode', colorMode)\n}\n</script>\n<template>\n <DocumentSettings\n v-if=\"collectionType === 'document'\"\n :documentUrl=\"document?.['x-scalar-original-source-url']\"\n :isDraftDocument=\"documentSlug === 'drafts'\"\n :title=\"document?.info.title ?? ''\"\n :watchMode=\"document?.['x-scalar-watch-mode']\"\n @delete:document=\"\n eventBus.emit('document:delete:document', { name: documentSlug })\n \"\n @update:watchMode=\"handleUpdateWatchMode\" />\n <CollectionSettings\n v-else\n :activeProxyUrl=\"\n getActiveProxyUrl(\n workspaceStore.workspace['x-scalar-active-proxy'],\n layout === 'web' ? 'web' : 'other',\n )\n \"\n :activeThemeSlug=\"workspaceStore.workspace['x-scalar-theme'] ?? 'none'\"\n :colorMode=\"workspaceStore.workspace['x-scalar-color-mode'] ?? 'system'\"\n :customThemes=\"customThemes\"\n :telemetry=\"telemetry\"\n @update:colorMode=\"handleUpdateColorMode\"\n @update:proxyUrl=\"handleUpdateActiveProxy\"\n @update:telemetry=\"(value) => onUpdateTelemetry?.(value)\"\n @update:themeSlug=\"handleUpdateThemeSlug\" />\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkBA,MAAM,yBAAyB,cAAuB;AACpD,WAAA,SAAS,KAAK,8BAA8B,UAAS;;EAGvD,MAAM,yBAAyB,cAAuB;AACpD,WAAA,SAAS,KAAK,0BAA0B,UAAS;;EAEnD,MAAM,2BAA2B,UAAyB;AACxD,WAAA,SAAS,KAAK,iCAAiC,MAAK;;EAGtD,MAAM,yBAAyB,cAAyB;AACtD,WAAA,SAAS,KAAK,+BAA+B,UAAS;;;UAK9C,QAAA,mBAAc,cAAA,WAAA,EADtB,YAS8C,MAAA,yBAAA,EAAA;;IAP3C,aAAa,QAAA,WAAQ;IACrB,iBAAiB,QAAA,iBAAY;IAC7B,OAAO,QAAA,UAAU,KAAK,SAAK;IAC3B,WAAW,QAAA,WAAQ;IACnB,qBAAe,OAAA,OAAA,OAAA,MAAA,WAAS,QAAA,SAAS,KAAI,4BAAA,EAAA,MAAqC,QAAA,cAAY,CAAA;IAGtF,sBAAkB;;;;;;uBACrB,YAe8C,MAAA,2BAAA,EAAA;;IAb3C,gBAAuB,MAAA,kBAAiB,CAAU,QAAA,eAAe,UAAS,0BAAmC,QAAA,WAAM,QAAA,QAAA,QAAA;IAMnH,iBAAiB,QAAA,eAAe,UAAS,qBAAA;IACzC,WAAW,QAAA,eAAe,UAAS,0BAAA;IACnC,cAAc,QAAA;IACd,WAAW,QAAA;IACX,sBAAkB;IAClB,qBAAiB;IACjB,sBAAgB,OAAA,OAAA,OAAA,MAAG,UAAU,QAAA,oBAAoB,MAAK;IACtD,sBAAkB"}
1
+ {"version":3,"file":"Settings.vue.script.js","names":[],"sources":["../../../../../src/v2/features/collection/components/Settings.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { getActiveProxyUrl } from '@scalar/workspace-store/request-example'\nimport type { ColorMode } from '@scalar/workspace-store/schemas/workspace'\n\nimport type { CollectionProps } from '@/v2/features/app/helpers/routes'\nimport { CollectionSettings, DocumentSettings } from '@/v2/features/settings'\n\nconst {\n eventBus,\n documentSlug,\n document,\n workspaceStore,\n collectionType,\n layout,\n telemetry,\n onUpdateTelemetry,\n} = defineProps<CollectionProps>()\n\nconst handleUpdateWatchMode = (watchMode: boolean) => {\n eventBus.emit('document:update:watch-mode', watchMode)\n}\n\nconst handleUpdateThemeSlug = (themeSlug?: string) => {\n eventBus.emit('workspace:update:theme', themeSlug)\n}\nconst handleUpdateActiveProxy = (proxy: string | null) => {\n eventBus.emit('workspace:update:active-proxy', proxy)\n}\n\nconst handleUpdateColorMode = (colorMode: ColorMode) => {\n eventBus.emit('workspace:update:color-mode', colorMode)\n}\n</script>\n<template>\n <DocumentSettings\n v-if=\"collectionType === 'document'\"\n :documentUrl=\"document?.['x-scalar-original-source-url']\"\n :isDraftDocument=\"documentSlug === 'drafts'\"\n :title=\"document?.info.title ?? ''\"\n :watchMode=\"document?.['x-scalar-watch-mode']\"\n @delete:document=\"\n eventBus.emit('document:delete:document', { name: documentSlug })\n \"\n @update:watchMode=\"handleUpdateWatchMode\" />\n <CollectionSettings\n v-else\n :activeProxyUrl=\"\n getActiveProxyUrl(\n workspaceStore.workspace['x-scalar-active-proxy'],\n layout === 'web' ? 'web' : 'other',\n )\n \"\n :activeThemeSlug=\"workspaceStore.workspace['x-scalar-theme'] ?? 'none'\"\n :colorMode=\"workspaceStore.workspace['x-scalar-color-mode'] ?? 'system'\"\n :customThemes=\"customThemes\"\n :telemetry=\"telemetry\"\n @update:colorMode=\"handleUpdateColorMode\"\n @update:proxyUrl=\"handleUpdateActiveProxy\"\n @update:telemetry=\"(value) => onUpdateTelemetry?.(value)\"\n @update:themeSlug=\"handleUpdateThemeSlug\" />\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkBA,MAAM,yBAAyB,cAAuB;AACpD,WAAA,SAAS,KAAK,8BAA8B,UAAS;;EAGvD,MAAM,yBAAyB,cAAuB;AACpD,WAAA,SAAS,KAAK,0BAA0B,UAAS;;EAEnD,MAAM,2BAA2B,UAAyB;AACxD,WAAA,SAAS,KAAK,iCAAiC,MAAK;;EAGtD,MAAM,yBAAyB,cAAyB;AACtD,WAAA,SAAS,KAAK,+BAA+B,UAAS;;;UAK9C,QAAA,mBAAc,cAAA,WAAA,EADtB,YAS8C,MAAA,yBAAA,EAAA;;IAP3C,aAAa,QAAA,WAAQ;IACrB,iBAAiB,QAAA,iBAAY;IAC7B,OAAO,QAAA,UAAU,KAAK,SAAK;IAC3B,WAAW,QAAA,WAAQ;IACnB,qBAAe,OAAA,OAAA,OAAA,MAAA,WAAS,QAAA,SAAS,KAAI,4BAAA,EAAA,MAAqC,QAAA,cAAY,CAAA;IAGtF,sBAAkB;;;;;;uBACrB,YAe8C,MAAA,2BAAA,EAAA;;IAb3C,gBAAuB,MAAA,kBAAiB,CAAU,QAAA,eAAe,UAAS,0BAAmC,QAAA,WAAM,QAAA,QAAA,QAAA;IAMnH,iBAAiB,QAAA,eAAe,UAAS,qBAAA;IACzC,WAAW,QAAA,eAAe,UAAS,0BAAA;IACnC,cAAc,QAAA;IACd,WAAW,QAAA;IACX,sBAAkB;IAClB,qBAAiB;IACjB,sBAAgB,OAAA,OAAA,OAAA,MAAG,UAAU,QAAA,oBAAoB,MAAK;IACtD,sBAAkB"}
@@ -34,8 +34,8 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
34
34
  /** Whether the form and submit button are disabled */
35
35
  disabled?: boolean;
36
36
  }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
37
- submit: () => any;
38
37
  cancel: () => any;
38
+ submit: () => any;
39
39
  back: (e: KeyboardEvent) => any;
40
40
  }, string, import("vue").PublicProps, Readonly<{
41
41
  /** Loading state from useLoadingState composable to show spinner on submit button */
@@ -43,8 +43,8 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
43
43
  /** Whether the form and submit button are disabled */
44
44
  disabled?: boolean;
45
45
  }> & Readonly<{
46
- onSubmit?: (() => any) | undefined;
47
46
  onCancel?: (() => any) | undefined;
47
+ onSubmit?: (() => any) | undefined;
48
48
  onBack?: ((e: KeyboardEvent) => any) | undefined;
49
49
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, {
50
50
  /** Main content area for form inputs */
@@ -4,11 +4,11 @@ type __VLS_Props = {
4
4
  name: string | null;
5
5
  };
6
6
  declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
7
- submit: () => any;
8
7
  cancel: () => any;
8
+ submit: () => any;
9
9
  }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
10
- onSubmit?: (() => any) | undefined;
11
10
  onCancel?: (() => any) | undefined;
11
+ onSubmit?: (() => any) | undefined;
12
12
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
13
13
  declare const _default: typeof __VLS_export;
14
14
  export default _default;
@@ -1,7 +1,7 @@
1
1
  import type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments';
2
2
  type __VLS_Props = {
3
3
  query: string;
4
- environment: XScalarEnvironment;
4
+ environment?: XScalarEnvironment;
5
5
  dropdownPosition?: {
6
6
  left: number;
7
7
  top: number;
@@ -1 +1 @@
1
- {"version":3,"file":"EnvironmentVariablesDropdown.vue.d.ts","sourceRoot":"","sources":["../../../../../src/v2/features/environments/components/EnvironmentVariablesDropdown.vue"],"names":[],"mappings":"AA6PA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2EAA2E,CAAA;AASnH,KAAK,WAAW,GAAG;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,kBAAkB,CAAA;IAC/B,gBAAgB,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;IAChD,iFAAiF;IACjF,oBAAoB,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAC9D,CAAC;AAqYF,QAAA,MAAM,YAAY;gCAnQiB,IAAI,GAAG,MAAM;;;;;;;;kFAuQ9C,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
1
+ {"version":3,"file":"EnvironmentVariablesDropdown.vue.d.ts","sourceRoot":"","sources":["../../../../../src/v2/features/environments/components/EnvironmentVariablesDropdown.vue"],"names":[],"mappings":"AA6PA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2EAA2E,CAAA;AASnH,KAAK,WAAW,GAAG;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,kBAAkB,CAAA;IAChC,gBAAgB,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;IAChD,iFAAiF;IACjF,oBAAoB,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAC9D,CAAC;AAqYF,QAAA,MAAM,YAAY;gCAnQiB,IAAI,GAAG,MAAM;;;;;;;;kFAuQ9C,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
@@ -1 +1 @@
1
- {"version":3,"file":"EnvironmentVariablesDropdown.vue.js","names":[],"sources":["../../../../../src/v2/features/environments/components/EnvironmentVariablesDropdown.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ScalarButton, ScalarTeleport } from '@scalar/components'\nimport { ScalarIconPlus } from '@scalar/icons'\nimport { POPULAR_CONTEXT_FUNCTION_KEYS } from '@scalar/workspace-store/request-example'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport { onClickOutside } from '@vueuse/core'\nimport Fuse from 'fuse.js'\nimport { computed, onMounted, ref, type CSSProperties } from 'vue'\n\ntype DropdownRow =\n | { kind: 'env'; key: string; secondary: string }\n | { kind: 'context'; key: string; secondary: string }\n\nconst {\n query,\n environment,\n dropdownPosition,\n contextFunctionItems = [],\n} = defineProps<{\n query: string\n environment: XScalarEnvironment\n dropdownPosition?: { left: number; top: number }\n /** Runtime placeholders such as `{{$guid}}`, shown with environment variables */\n contextFunctionItems?: { key: string; description: string }[]\n}>()\n\nconst emit = defineEmits<{\n (e: 'select', variable: string): void\n (e: 'redirect'): void\n}>()\n\nconst isOpen = ref(true)\nconst dropdownRef = ref<HTMLElement | null>(null)\nconst selectedVariableIndex = ref(0)\n\nconst redirectToEnvironment = () => {\n emit('redirect')\n isOpen.value = false\n}\n\n/** Normalize the variables to have a name and value */\nconst normalizedVariables = computed(() =>\n environment.variables.map((v) => ({\n key: v.name,\n value: typeof v.value === 'string' ? v.value : v.value.default,\n })),\n)\n\nconst contextRows = computed((): DropdownRow[] =>\n contextFunctionItems.map((item) => ({\n kind: 'context',\n key: item.key,\n secondary: item.description,\n })),\n)\n\nconst envRows = computed((): DropdownRow[] =>\n normalizedVariables.value\n .filter(({ key, value }) => key !== '' || value !== '')\n .map(({ key, value }) => ({\n kind: 'env' as const,\n key,\n secondary: value,\n })),\n)\n\ntype FuseRow = DropdownRow & { fuseText: string }\n\nconst envFuseSource = computed((): FuseRow[] =>\n envRows.value.map((row) => ({\n ...row,\n fuseText: `${row.key} ${row.secondary}`,\n })),\n)\n\nconst contextFuseSource = computed((): FuseRow[] =>\n contextRows.value.map((row) => ({\n ...row,\n fuseText: `${row.key} ${row.secondary}`,\n })),\n)\n\nconst fuseEnv = computed(\n () =>\n new Fuse(envFuseSource.value, {\n keys: ['fuseText'],\n threshold: 0.35,\n }),\n)\n\nconst fuseContext = computed(\n () =>\n new Fuse(contextFuseSource.value, {\n keys: ['fuseText'],\n threshold: 0.35,\n }),\n)\n\nconst popularContextRows = computed((): DropdownRow[] => {\n const byKey = new Map(contextFunctionItems.map((c) => [c.key, c]))\n return POPULAR_CONTEXT_FUNCTION_KEYS.flatMap((key) => {\n const item = byKey.get(key)\n return item\n ? [\n {\n kind: 'context' as const,\n key: item.key,\n secondary: item.description,\n },\n ]\n : []\n })\n})\n\nconst DROPDOWN_LIMIT = 12\n\nconst filteredVariables = computed((): DropdownRow[] => {\n if (!query.trim()) {\n const envSlice = envRows.value.slice(-4)\n return [...envSlice, ...popularContextRows.value]\n }\n\n const q = query.trim()\n const envMatches = fuseEnv.value\n .search(q, { limit: DROPDOWN_LIMIT })\n .map((res) => {\n const { kind, key, secondary } = res.item\n return { kind, key, secondary }\n })\n\n const remaining = DROPDOWN_LIMIT - envMatches.length\n const contextMatches =\n remaining > 0\n ? fuseContext.value.search(q, { limit: remaining }).map((res) => {\n const { kind, key, secondary } = res.item\n return { kind, key, secondary }\n })\n : []\n\n return [...envMatches, ...contextMatches]\n})\n\nconst selectVariable = (variableKey: string): void => {\n emit('select', variableKey)\n}\n\nconst handleArrowKey = (direction: 'up' | 'down') => {\n const offset = direction === 'up' ? -1 : 1\n const length = filteredVariables.value.length\n\n if (length === 0) {\n return\n }\n\n selectedVariableIndex.value =\n (selectedVariableIndex.value + offset + length) % length\n}\n\nconst handleSelect = () => {\n if (selectedVariableIndex.value >= 0) {\n const selectedVariable =\n filteredVariables.value[selectedVariableIndex.value]\n if (selectedVariable) {\n selectVariable(selectedVariable.key)\n }\n }\n}\n\ndefineExpose({\n handleArrowKey,\n handleSelect,\n})\n\nonMounted(() => {\n // Reset selected index to the first item when dropdown opens\n selectedVariableIndex.value = 0\n})\n\nconst dropdownStyle = computed<CSSProperties>(() => {\n return {\n left: (dropdownPosition?.left ?? 0) + 'px',\n // Add a 5px offset from the editor\n top: (dropdownPosition?.top ?? 0) + 5 + 'px',\n }\n})\n\nonClickOutside(\n dropdownRef,\n () => {\n isOpen.value = false\n },\n { ignore: [dropdownRef] },\n)\n</script>\n<template>\n <ScalarTeleport\n v-if=\"isOpen\"\n class=\"scalar-client\">\n <div\n ref=\"dropdownRef\"\n class=\"custom-scroll z-context fixed top-0 left-0 flex max-h-[60svh] w-56 flex-col rounded border p-0.75\"\n :style=\"dropdownStyle\">\n <ul\n v-if=\"filteredVariables.length\"\n class=\"gap-1/2 flex flex-col\">\n <template\n v-for=\"(item, index) in filteredVariables\"\n :key=\"`${item.kind}-${item.key}`\">\n <li\n class=\"font-code text-xxs hover:bg-b-2 flex h-8 cursor-pointer items-center justify-between gap-1.5 rounded p-1.5 transition-colors duration-150\"\n :class=\"{ 'bg-b-2': index === selectedVariableIndex }\"\n @click=\"selectVariable(item.key)\">\n <div class=\"flex items-center gap-2 whitespace-nowrap\">\n <span\n v-if=\"item.kind === 'env'\"\n class=\"h-2.25 w-2.25 min-w-2.25 rounded-full\"\n :style=\"{\n backgroundColor: environment.color,\n }\" />\n <span\n v-else\n class=\"text-c-3 bg-b-3 flex h-4.5 min-w-4.5 items-center justify-center rounded px-0.5 font-sans text-[9px] font-semibold\">\n fn\n </span>\n {{ item.key }}\n </div>\n <span\n class=\"max-w-[9rem] overflow-hidden text-right text-ellipsis whitespace-nowrap\">\n {{ item.secondary }}\n </span>\n </li>\n </template>\n </ul>\n <ScalarButton\n v-else\n class=\"font-code text-xxs bg-b-inherit hover:bg-b-2 flex h-8 w-full justify-start gap-2 px-1.5 transition-colors duration-150\"\n variant=\"outlined\"\n @click=\"redirectToEnvironment\">\n <ScalarIconPlus class=\"size-3\" />\n Add Variable\n </ScalarButton>\n <!-- Backdrop for the dropdown -->\n <div\n class=\"bg-b-1 brightness-lifted absolute inset-0 -z-1 rounded shadow-lg\" />\n </div>\n </ScalarTeleport>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"EnvironmentVariablesDropdown.vue.js","names":[],"sources":["../../../../../src/v2/features/environments/components/EnvironmentVariablesDropdown.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ScalarButton, ScalarTeleport } from '@scalar/components'\nimport { ScalarIconPlus } from '@scalar/icons'\nimport { POPULAR_CONTEXT_FUNCTION_KEYS } from '@scalar/workspace-store/request-example'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport { onClickOutside } from '@vueuse/core'\nimport Fuse from 'fuse.js'\nimport { computed, onMounted, ref, type CSSProperties } from 'vue'\n\ntype DropdownRow =\n | { kind: 'env'; key: string; secondary: string }\n | { kind: 'context'; key: string; secondary: string }\n\nconst {\n query,\n environment,\n dropdownPosition,\n contextFunctionItems = [],\n} = defineProps<{\n query: string\n environment?: XScalarEnvironment\n dropdownPosition?: { left: number; top: number }\n /** Runtime placeholders such as `{{$guid}}`, shown with environment variables */\n contextFunctionItems?: { key: string; description: string }[]\n}>()\n\nconst emit = defineEmits<{\n (e: 'select', variable: string): void\n (e: 'redirect'): void\n}>()\n\nconst isOpen = ref(true)\nconst dropdownRef = ref<HTMLElement | null>(null)\nconst selectedVariableIndex = ref(0)\n\nconst redirectToEnvironment = () => {\n emit('redirect')\n isOpen.value = false\n}\n\n/** Normalize the variables to have a name and value */\nconst normalizedVariables = computed(() =>\n (environment?.variables ?? []).map((v) => ({\n key: v.name,\n value: typeof v.value === 'string' ? v.value : v.value.default,\n })),\n)\n\nconst contextRows = computed((): DropdownRow[] =>\n contextFunctionItems.map((item) => ({\n kind: 'context',\n key: item.key,\n secondary: item.description,\n })),\n)\n\nconst envRows = computed((): DropdownRow[] =>\n normalizedVariables.value\n .filter(({ key, value }) => key !== '' || value !== '')\n .map(({ key, value }) => ({\n kind: 'env' as const,\n key,\n secondary: value,\n })),\n)\n\ntype FuseRow = DropdownRow & { fuseText: string }\n\nconst envFuseSource = computed((): FuseRow[] =>\n envRows.value.map((row) => ({\n ...row,\n fuseText: `${row.key} ${row.secondary}`,\n })),\n)\n\nconst contextFuseSource = computed((): FuseRow[] =>\n contextRows.value.map((row) => ({\n ...row,\n fuseText: `${row.key} ${row.secondary}`,\n })),\n)\n\nconst fuseEnv = computed(\n () =>\n new Fuse(envFuseSource.value, {\n keys: ['fuseText'],\n threshold: 0.35,\n }),\n)\n\nconst fuseContext = computed(\n () =>\n new Fuse(contextFuseSource.value, {\n keys: ['fuseText'],\n threshold: 0.35,\n }),\n)\n\nconst popularContextRows = computed((): DropdownRow[] => {\n const byKey = new Map(contextFunctionItems.map((c) => [c.key, c]))\n return POPULAR_CONTEXT_FUNCTION_KEYS.flatMap((key) => {\n const item = byKey.get(key)\n return item\n ? [\n {\n kind: 'context' as const,\n key: item.key,\n secondary: item.description,\n },\n ]\n : []\n })\n})\n\nconst DROPDOWN_LIMIT = 12\n\nconst filteredVariables = computed((): DropdownRow[] => {\n if (!query.trim()) {\n const envSlice = envRows.value.slice(-4)\n return [...envSlice, ...popularContextRows.value]\n }\n\n const q = query.trim()\n const envMatches = fuseEnv.value\n .search(q, { limit: DROPDOWN_LIMIT })\n .map((res) => {\n const { kind, key, secondary } = res.item\n return { kind, key, secondary }\n })\n\n const remaining = DROPDOWN_LIMIT - envMatches.length\n const contextMatches =\n remaining > 0\n ? fuseContext.value.search(q, { limit: remaining }).map((res) => {\n const { kind, key, secondary } = res.item\n return { kind, key, secondary }\n })\n : []\n\n return [...envMatches, ...contextMatches]\n})\n\nconst selectVariable = (variableKey: string): void => {\n emit('select', variableKey)\n}\n\nconst handleArrowKey = (direction: 'up' | 'down') => {\n const offset = direction === 'up' ? -1 : 1\n const length = filteredVariables.value.length\n\n if (length === 0) {\n return\n }\n\n selectedVariableIndex.value =\n (selectedVariableIndex.value + offset + length) % length\n}\n\nconst handleSelect = () => {\n if (selectedVariableIndex.value >= 0) {\n const selectedVariable =\n filteredVariables.value[selectedVariableIndex.value]\n if (selectedVariable) {\n selectVariable(selectedVariable.key)\n }\n }\n}\n\ndefineExpose({\n handleArrowKey,\n handleSelect,\n})\n\nonMounted(() => {\n // Reset selected index to the first item when dropdown opens\n selectedVariableIndex.value = 0\n})\n\nconst dropdownStyle = computed<CSSProperties>(() => {\n return {\n left: (dropdownPosition?.left ?? 0) + 'px',\n // Add a 5px offset from the editor\n top: (dropdownPosition?.top ?? 0) + 5 + 'px',\n }\n})\n\nonClickOutside(\n dropdownRef,\n () => {\n isOpen.value = false\n },\n { ignore: [dropdownRef] },\n)\n</script>\n<template>\n <ScalarTeleport\n v-if=\"isOpen\"\n class=\"scalar-client\">\n <div\n ref=\"dropdownRef\"\n class=\"custom-scroll z-context fixed top-0 left-0 flex max-h-[60svh] w-56 flex-col rounded border p-0.75\"\n :style=\"dropdownStyle\">\n <ul\n v-if=\"filteredVariables.length\"\n class=\"gap-1/2 flex flex-col\">\n <template\n v-for=\"(item, index) in filteredVariables\"\n :key=\"`${item.kind}-${item.key}`\">\n <li\n class=\"font-code text-xxs hover:bg-b-2 flex h-8 cursor-pointer items-center justify-between gap-1.5 rounded p-1.5 transition-colors duration-150\"\n :class=\"{ 'bg-b-2': index === selectedVariableIndex }\"\n @click=\"selectVariable(item.key)\">\n <div class=\"flex items-center gap-2 whitespace-nowrap\">\n <span\n v-if=\"item.kind === 'env'\"\n class=\"h-2.25 w-2.25 min-w-2.25 rounded-full\"\n :style=\"{\n backgroundColor: environment?.color,\n }\" />\n <span\n v-else\n class=\"text-c-3 bg-b-3 flex h-4.5 min-w-4.5 items-center justify-center rounded px-0.5 font-sans text-[9px] font-semibold\">\n fn\n </span>\n {{ item.key }}\n </div>\n <span\n class=\"max-w-[9rem] overflow-hidden text-right text-ellipsis whitespace-nowrap\">\n {{ item.secondary }}\n </span>\n </li>\n </template>\n </ul>\n <ScalarButton\n v-else\n class=\"font-code text-xxs bg-b-inherit hover:bg-b-2 flex h-8 w-full justify-start gap-2 px-1.5 transition-colors duration-150\"\n variant=\"outlined\"\n @click=\"redirectToEnvironment\">\n <ScalarIconPlus class=\"size-3\" />\n Add Variable\n </ScalarButton>\n <!-- Backdrop for the dropdown -->\n <div\n class=\"bg-b-1 brightness-lifted absolute inset-0 -z-1 rounded shadow-lg\" />\n </div>\n </ScalarTeleport>\n</template>\n"],"mappings":""}
@@ -36,7 +36,7 @@ var EnvironmentVariablesDropdown_vue_vue_type_script_setup_true_lang_default = /
36
36
  isOpen.value = false;
37
37
  };
38
38
  /** Normalize the variables to have a name and value */
39
- const normalizedVariables = computed(() => __props.environment.variables.map((v) => ({
39
+ const normalizedVariables = computed(() => (__props.environment?.variables ?? []).map((v) => ({
40
40
  key: v.name,
41
41
  value: typeof v.value === "string" ? v.value : v.value.default
42
42
  })));
@@ -148,7 +148,7 @@ var EnvironmentVariablesDropdown_vue_vue_type_script_setup_true_lang_default = /
148
148
  }, [createElementVNode("div", _hoisted_3, [item.kind === "env" ? (openBlock(), createElementBlock("span", {
149
149
  key: 0,
150
150
  class: "h-2.25 w-2.25 min-w-2.25 rounded-full",
151
- style: normalizeStyle({ backgroundColor: __props.environment.color })
151
+ style: normalizeStyle({ backgroundColor: __props.environment?.color })
152
152
  }, null, 4)) : (openBlock(), createElementBlock("span", _hoisted_4, " fn ")), createTextVNode(" " + toDisplayString(item.key), 1)]), createElementVNode("span", _hoisted_5, toDisplayString(item.secondary), 1)], 10, _hoisted_2);
153
153
  }), 128))])) : (openBlock(), createBlock(unref(ScalarButton), {
154
154
  key: 1,
@@ -1 +1 @@
1
- {"version":3,"file":"EnvironmentVariablesDropdown.vue.script.js","names":[],"sources":["../../../../../src/v2/features/environments/components/EnvironmentVariablesDropdown.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ScalarButton, ScalarTeleport } from '@scalar/components'\nimport { ScalarIconPlus } from '@scalar/icons'\nimport { POPULAR_CONTEXT_FUNCTION_KEYS } from '@scalar/workspace-store/request-example'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport { onClickOutside } from '@vueuse/core'\nimport Fuse from 'fuse.js'\nimport { computed, onMounted, ref, type CSSProperties } from 'vue'\n\ntype DropdownRow =\n | { kind: 'env'; key: string; secondary: string }\n | { kind: 'context'; key: string; secondary: string }\n\nconst {\n query,\n environment,\n dropdownPosition,\n contextFunctionItems = [],\n} = defineProps<{\n query: string\n environment: XScalarEnvironment\n dropdownPosition?: { left: number; top: number }\n /** Runtime placeholders such as `{{$guid}}`, shown with environment variables */\n contextFunctionItems?: { key: string; description: string }[]\n}>()\n\nconst emit = defineEmits<{\n (e: 'select', variable: string): void\n (e: 'redirect'): void\n}>()\n\nconst isOpen = ref(true)\nconst dropdownRef = ref<HTMLElement | null>(null)\nconst selectedVariableIndex = ref(0)\n\nconst redirectToEnvironment = () => {\n emit('redirect')\n isOpen.value = false\n}\n\n/** Normalize the variables to have a name and value */\nconst normalizedVariables = computed(() =>\n environment.variables.map((v) => ({\n key: v.name,\n value: typeof v.value === 'string' ? v.value : v.value.default,\n })),\n)\n\nconst contextRows = computed((): DropdownRow[] =>\n contextFunctionItems.map((item) => ({\n kind: 'context',\n key: item.key,\n secondary: item.description,\n })),\n)\n\nconst envRows = computed((): DropdownRow[] =>\n normalizedVariables.value\n .filter(({ key, value }) => key !== '' || value !== '')\n .map(({ key, value }) => ({\n kind: 'env' as const,\n key,\n secondary: value,\n })),\n)\n\ntype FuseRow = DropdownRow & { fuseText: string }\n\nconst envFuseSource = computed((): FuseRow[] =>\n envRows.value.map((row) => ({\n ...row,\n fuseText: `${row.key} ${row.secondary}`,\n })),\n)\n\nconst contextFuseSource = computed((): FuseRow[] =>\n contextRows.value.map((row) => ({\n ...row,\n fuseText: `${row.key} ${row.secondary}`,\n })),\n)\n\nconst fuseEnv = computed(\n () =>\n new Fuse(envFuseSource.value, {\n keys: ['fuseText'],\n threshold: 0.35,\n }),\n)\n\nconst fuseContext = computed(\n () =>\n new Fuse(contextFuseSource.value, {\n keys: ['fuseText'],\n threshold: 0.35,\n }),\n)\n\nconst popularContextRows = computed((): DropdownRow[] => {\n const byKey = new Map(contextFunctionItems.map((c) => [c.key, c]))\n return POPULAR_CONTEXT_FUNCTION_KEYS.flatMap((key) => {\n const item = byKey.get(key)\n return item\n ? [\n {\n kind: 'context' as const,\n key: item.key,\n secondary: item.description,\n },\n ]\n : []\n })\n})\n\nconst DROPDOWN_LIMIT = 12\n\nconst filteredVariables = computed((): DropdownRow[] => {\n if (!query.trim()) {\n const envSlice = envRows.value.slice(-4)\n return [...envSlice, ...popularContextRows.value]\n }\n\n const q = query.trim()\n const envMatches = fuseEnv.value\n .search(q, { limit: DROPDOWN_LIMIT })\n .map((res) => {\n const { kind, key, secondary } = res.item\n return { kind, key, secondary }\n })\n\n const remaining = DROPDOWN_LIMIT - envMatches.length\n const contextMatches =\n remaining > 0\n ? fuseContext.value.search(q, { limit: remaining }).map((res) => {\n const { kind, key, secondary } = res.item\n return { kind, key, secondary }\n })\n : []\n\n return [...envMatches, ...contextMatches]\n})\n\nconst selectVariable = (variableKey: string): void => {\n emit('select', variableKey)\n}\n\nconst handleArrowKey = (direction: 'up' | 'down') => {\n const offset = direction === 'up' ? -1 : 1\n const length = filteredVariables.value.length\n\n if (length === 0) {\n return\n }\n\n selectedVariableIndex.value =\n (selectedVariableIndex.value + offset + length) % length\n}\n\nconst handleSelect = () => {\n if (selectedVariableIndex.value >= 0) {\n const selectedVariable =\n filteredVariables.value[selectedVariableIndex.value]\n if (selectedVariable) {\n selectVariable(selectedVariable.key)\n }\n }\n}\n\ndefineExpose({\n handleArrowKey,\n handleSelect,\n})\n\nonMounted(() => {\n // Reset selected index to the first item when dropdown opens\n selectedVariableIndex.value = 0\n})\n\nconst dropdownStyle = computed<CSSProperties>(() => {\n return {\n left: (dropdownPosition?.left ?? 0) + 'px',\n // Add a 5px offset from the editor\n top: (dropdownPosition?.top ?? 0) + 5 + 'px',\n }\n})\n\nonClickOutside(\n dropdownRef,\n () => {\n isOpen.value = false\n },\n { ignore: [dropdownRef] },\n)\n</script>\n<template>\n <ScalarTeleport\n v-if=\"isOpen\"\n class=\"scalar-client\">\n <div\n ref=\"dropdownRef\"\n class=\"custom-scroll z-context fixed top-0 left-0 flex max-h-[60svh] w-56 flex-col rounded border p-0.75\"\n :style=\"dropdownStyle\">\n <ul\n v-if=\"filteredVariables.length\"\n class=\"gap-1/2 flex flex-col\">\n <template\n v-for=\"(item, index) in filteredVariables\"\n :key=\"`${item.kind}-${item.key}`\">\n <li\n class=\"font-code text-xxs hover:bg-b-2 flex h-8 cursor-pointer items-center justify-between gap-1.5 rounded p-1.5 transition-colors duration-150\"\n :class=\"{ 'bg-b-2': index === selectedVariableIndex }\"\n @click=\"selectVariable(item.key)\">\n <div class=\"flex items-center gap-2 whitespace-nowrap\">\n <span\n v-if=\"item.kind === 'env'\"\n class=\"h-2.25 w-2.25 min-w-2.25 rounded-full\"\n :style=\"{\n backgroundColor: environment.color,\n }\" />\n <span\n v-else\n class=\"text-c-3 bg-b-3 flex h-4.5 min-w-4.5 items-center justify-center rounded px-0.5 font-sans text-[9px] font-semibold\">\n fn\n </span>\n {{ item.key }}\n </div>\n <span\n class=\"max-w-[9rem] overflow-hidden text-right text-ellipsis whitespace-nowrap\">\n {{ item.secondary }}\n </span>\n </li>\n </template>\n </ul>\n <ScalarButton\n v-else\n class=\"font-code text-xxs bg-b-inherit hover:bg-b-2 flex h-8 w-full justify-start gap-2 px-1.5 transition-colors duration-150\"\n variant=\"outlined\"\n @click=\"redirectToEnvironment\">\n <ScalarIconPlus class=\"size-3\" />\n Add Variable\n </ScalarButton>\n <!-- Backdrop for the dropdown -->\n <div\n class=\"bg-b-1 brightness-lifted absolute inset-0 -z-1 rounded shadow-lg\" />\n </div>\n </ScalarTeleport>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"EnvironmentVariablesDropdown.vue.script.js","names":[],"sources":["../../../../../src/v2/features/environments/components/EnvironmentVariablesDropdown.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ScalarButton, ScalarTeleport } from '@scalar/components'\nimport { ScalarIconPlus } from '@scalar/icons'\nimport { POPULAR_CONTEXT_FUNCTION_KEYS } from '@scalar/workspace-store/request-example'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport { onClickOutside } from '@vueuse/core'\nimport Fuse from 'fuse.js'\nimport { computed, onMounted, ref, type CSSProperties } from 'vue'\n\ntype DropdownRow =\n | { kind: 'env'; key: string; secondary: string }\n | { kind: 'context'; key: string; secondary: string }\n\nconst {\n query,\n environment,\n dropdownPosition,\n contextFunctionItems = [],\n} = defineProps<{\n query: string\n environment?: XScalarEnvironment\n dropdownPosition?: { left: number; top: number }\n /** Runtime placeholders such as `{{$guid}}`, shown with environment variables */\n contextFunctionItems?: { key: string; description: string }[]\n}>()\n\nconst emit = defineEmits<{\n (e: 'select', variable: string): void\n (e: 'redirect'): void\n}>()\n\nconst isOpen = ref(true)\nconst dropdownRef = ref<HTMLElement | null>(null)\nconst selectedVariableIndex = ref(0)\n\nconst redirectToEnvironment = () => {\n emit('redirect')\n isOpen.value = false\n}\n\n/** Normalize the variables to have a name and value */\nconst normalizedVariables = computed(() =>\n (environment?.variables ?? []).map((v) => ({\n key: v.name,\n value: typeof v.value === 'string' ? v.value : v.value.default,\n })),\n)\n\nconst contextRows = computed((): DropdownRow[] =>\n contextFunctionItems.map((item) => ({\n kind: 'context',\n key: item.key,\n secondary: item.description,\n })),\n)\n\nconst envRows = computed((): DropdownRow[] =>\n normalizedVariables.value\n .filter(({ key, value }) => key !== '' || value !== '')\n .map(({ key, value }) => ({\n kind: 'env' as const,\n key,\n secondary: value,\n })),\n)\n\ntype FuseRow = DropdownRow & { fuseText: string }\n\nconst envFuseSource = computed((): FuseRow[] =>\n envRows.value.map((row) => ({\n ...row,\n fuseText: `${row.key} ${row.secondary}`,\n })),\n)\n\nconst contextFuseSource = computed((): FuseRow[] =>\n contextRows.value.map((row) => ({\n ...row,\n fuseText: `${row.key} ${row.secondary}`,\n })),\n)\n\nconst fuseEnv = computed(\n () =>\n new Fuse(envFuseSource.value, {\n keys: ['fuseText'],\n threshold: 0.35,\n }),\n)\n\nconst fuseContext = computed(\n () =>\n new Fuse(contextFuseSource.value, {\n keys: ['fuseText'],\n threshold: 0.35,\n }),\n)\n\nconst popularContextRows = computed((): DropdownRow[] => {\n const byKey = new Map(contextFunctionItems.map((c) => [c.key, c]))\n return POPULAR_CONTEXT_FUNCTION_KEYS.flatMap((key) => {\n const item = byKey.get(key)\n return item\n ? [\n {\n kind: 'context' as const,\n key: item.key,\n secondary: item.description,\n },\n ]\n : []\n })\n})\n\nconst DROPDOWN_LIMIT = 12\n\nconst filteredVariables = computed((): DropdownRow[] => {\n if (!query.trim()) {\n const envSlice = envRows.value.slice(-4)\n return [...envSlice, ...popularContextRows.value]\n }\n\n const q = query.trim()\n const envMatches = fuseEnv.value\n .search(q, { limit: DROPDOWN_LIMIT })\n .map((res) => {\n const { kind, key, secondary } = res.item\n return { kind, key, secondary }\n })\n\n const remaining = DROPDOWN_LIMIT - envMatches.length\n const contextMatches =\n remaining > 0\n ? fuseContext.value.search(q, { limit: remaining }).map((res) => {\n const { kind, key, secondary } = res.item\n return { kind, key, secondary }\n })\n : []\n\n return [...envMatches, ...contextMatches]\n})\n\nconst selectVariable = (variableKey: string): void => {\n emit('select', variableKey)\n}\n\nconst handleArrowKey = (direction: 'up' | 'down') => {\n const offset = direction === 'up' ? -1 : 1\n const length = filteredVariables.value.length\n\n if (length === 0) {\n return\n }\n\n selectedVariableIndex.value =\n (selectedVariableIndex.value + offset + length) % length\n}\n\nconst handleSelect = () => {\n if (selectedVariableIndex.value >= 0) {\n const selectedVariable =\n filteredVariables.value[selectedVariableIndex.value]\n if (selectedVariable) {\n selectVariable(selectedVariable.key)\n }\n }\n}\n\ndefineExpose({\n handleArrowKey,\n handleSelect,\n})\n\nonMounted(() => {\n // Reset selected index to the first item when dropdown opens\n selectedVariableIndex.value = 0\n})\n\nconst dropdownStyle = computed<CSSProperties>(() => {\n return {\n left: (dropdownPosition?.left ?? 0) + 'px',\n // Add a 5px offset from the editor\n top: (dropdownPosition?.top ?? 0) + 5 + 'px',\n }\n})\n\nonClickOutside(\n dropdownRef,\n () => {\n isOpen.value = false\n },\n { ignore: [dropdownRef] },\n)\n</script>\n<template>\n <ScalarTeleport\n v-if=\"isOpen\"\n class=\"scalar-client\">\n <div\n ref=\"dropdownRef\"\n class=\"custom-scroll z-context fixed top-0 left-0 flex max-h-[60svh] w-56 flex-col rounded border p-0.75\"\n :style=\"dropdownStyle\">\n <ul\n v-if=\"filteredVariables.length\"\n class=\"gap-1/2 flex flex-col\">\n <template\n v-for=\"(item, index) in filteredVariables\"\n :key=\"`${item.kind}-${item.key}`\">\n <li\n class=\"font-code text-xxs hover:bg-b-2 flex h-8 cursor-pointer items-center justify-between gap-1.5 rounded p-1.5 transition-colors duration-150\"\n :class=\"{ 'bg-b-2': index === selectedVariableIndex }\"\n @click=\"selectVariable(item.key)\">\n <div class=\"flex items-center gap-2 whitespace-nowrap\">\n <span\n v-if=\"item.kind === 'env'\"\n class=\"h-2.25 w-2.25 min-w-2.25 rounded-full\"\n :style=\"{\n backgroundColor: environment?.color,\n }\" />\n <span\n v-else\n class=\"text-c-3 bg-b-3 flex h-4.5 min-w-4.5 items-center justify-center rounded px-0.5 font-sans text-[9px] font-semibold\">\n fn\n </span>\n {{ item.key }}\n </div>\n <span\n class=\"max-w-[9rem] overflow-hidden text-right text-ellipsis whitespace-nowrap\">\n {{ item.secondary }}\n </span>\n </li>\n </template>\n </ul>\n <ScalarButton\n v-else\n class=\"font-code text-xxs bg-b-inherit hover:bg-b-2 flex h-8 w-full justify-start gap-2 px-1.5 transition-colors duration-150\"\n variant=\"outlined\"\n @click=\"redirectToEnvironment\">\n <ScalarIconPlus class=\"size-3\" />\n Add Variable\n </ScalarButton>\n <!-- Backdrop for the dropdown -->\n <div\n class=\"bg-b-1 brightness-lifted absolute inset-0 -z-1 rounded shadow-lg\" />\n </div>\n </ScalarTeleport>\n</template>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"CookiesTable.vue.d.ts","sourceRoot":"","sources":["../../../../../src/v2/features/global-cookies/components/CookiesTable.vue"],"names":[],"mappings":"AAuPA,OAAO,KAAK,EACV,cAAc,EACd,iBAAiB,EAClB,MAAM,gCAAgC,CAAA;AACvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qEAAqE,CAAA;AAYxG,KAAK,WAAW,GAAG;IACf,OAAO,EAAE,aAAa,EAAE,CAAA;IACxB,QAAQ,EAAE,iBAAiB,CAAA;CAC5B,GAAG,cAAc,CAAC;AA8erB,QAAA,MAAM,YAAY,kSAEhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
1
+ {"version":3,"file":"CookiesTable.vue.d.ts","sourceRoot":"","sources":["../../../../../src/v2/features/global-cookies/components/CookiesTable.vue"],"names":[],"mappings":"AAyPA,OAAO,KAAK,EACV,cAAc,EACd,iBAAiB,EAClB,MAAM,gCAAgC,CAAA;AACvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qEAAqE,CAAA;AAYxG,KAAK,WAAW,GAAG;IACf,OAAO,EAAE,aAAa,EAAE,CAAA;IACxB,QAAQ,EAAE,iBAAiB,CAAA;CAC5B,GAAG,cAAc,CAAC;AAkfrB,QAAA,MAAM,YAAY,kSAEhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
@@ -2,7 +2,7 @@ import _plugin_vue_export_helper_default from "../../../../_virtual/_plugin-vue_
2
2
  import CookiesTable_vue_vue_type_script_setup_true_lang_default from "./CookiesTable.vue.script.js";
3
3
  /* empty css */
4
4
  //#region src/v2/features/global-cookies/components/CookiesTable.vue
5
- var CookiesTable_default = /* @__PURE__ */ _plugin_vue_export_helper_default(CookiesTable_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-ddfccc08"]]);
5
+ var CookiesTable_default = /* @__PURE__ */ _plugin_vue_export_helper_default(CookiesTable_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-2f13118d"]]);
6
6
  //#endregion
7
7
  export { CookiesTable_default as default };
8
8
 
@@ -1 +1 @@
1
- {"version":3,"file":"CookiesTable.vue.js","names":[],"sources":["../../../../../src/v2/features/global-cookies/components/CookiesTable.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ScalarButton } from '@scalar/components'\nimport { ScalarIconTrash } from '@scalar/icons'\nimport type {\n CollectionType,\n WorkspaceEventBus,\n} from '@scalar/workspace-store/events'\nimport type { XScalarCookie } from '@scalar/workspace-store/schemas/extensions/general/x-scalar-cookies'\nimport { computed } from 'vue'\n\nimport { CodeInput } from '@/v2/components/code-input'\nimport {\n DataTable,\n DataTableCell,\n DataTableCheckbox,\n DataTableHeader,\n DataTableRow,\n} from '@/v2/components/data-table'\n\nconst { cookies, eventBus, collectionType } = defineProps<\n {\n cookies: XScalarCookie[]\n eventBus: WorkspaceEventBus\n } & CollectionType\n>()\n\n/** Column widths: Enabled checkbox, Name, Value, Domain, Actions (delete button) */\nconst COLUMNS = ['32px', '1fr', '1fr', '1fr', '36px']\n\n/** Adds an empty row at the end for creating new cookies */\nconst displayRows = computed<\n {\n name: string\n value: string\n domain: string\n isDisabled: boolean\n }[]\n>(() => {\n /** Normalize the cookies to have name, value, and domain */\n const cookieRows = cookies.map((cookie) => ({\n name: cookie.name,\n value: cookie.value,\n domain: cookie.domain ?? '',\n isDisabled: cookie.isDisabled ?? false,\n }))\n\n const lastCookie = cookies.at(-1)\n const hasContentInLastRow =\n lastCookie &&\n (lastCookie.name !== '' ||\n lastCookie.value !== '' ||\n lastCookie.domain !== '')\n\n // Add the extra row at the end\n if (!lastCookie || hasContentInLastRow) {\n return [\n ...cookieRows,\n { name: '', value: '', domain: '', isDisabled: true },\n ]\n }\n\n return cookieRows\n})\n\n/** Updates an existing cookie or creates a new one */\nconst handleCookieChange = (\n name: string,\n value: string,\n domain: string,\n isDisabled: boolean,\n index: number,\n): void => {\n const isNewCookie = index >= cookies.length\n\n /**\n * Do not allow adding a new cookie with an empty name on the last row,\n * we allow it on other rows as it will delete the row\n */\n if (!name && isNewCookie) {\n return\n }\n\n // Adding a new cookie\n if (index >= cookies.length) {\n eventBus.emit('cookie:upsert:cookie', {\n payload: { name, value, domain, isDisabled: false },\n collectionType,\n })\n return\n }\n\n // Updating existing cookie\n eventBus.emit('cookie:upsert:cookie', {\n payload: { name, value, domain, isDisabled },\n collectionType,\n index,\n })\n}\n\n/** Deletes a cookie by index */\nconst handleCookieDelete = (index: number): void =>\n eventBus.emit('cookie:delete:cookie', {\n cookieName: cookies[index]?.name ?? '',\n index,\n collectionType,\n })\n</script>\n<template>\n <!-- Cookies table -->\n <DataTable\n class=\"group/table data-table h-min flex-1 rounded border border-t-0\"\n :columns=\"COLUMNS\">\n <!-- Accessibility header row -->\n <DataTableRow class=\"sr-only !block\">\n <DataTableHeader>Enabled</DataTableHeader>\n <DataTableHeader>Name</DataTableHeader>\n <DataTableHeader>Value</DataTableHeader>\n <DataTableHeader>Domain</DataTableHeader>\n <DataTableHeader>Actions</DataTableHeader>\n </DataTableRow>\n\n <!-- Cookie rows -->\n <DataTableRow\n v-for=\"(row, index) in displayRows\"\n :key=\"index\"\n class=\"group/row\">\n <!-- Enabled checkbox -->\n <DataTableCheckbox\n class=\"!border-r\"\n :modelValue=\"!row.isDisabled\"\n @update:modelValue=\"\n (value) =>\n handleCookieChange(row.name, row.value, row.domain, !value, index)\n \" />\n\n <!-- Name -->\n <DataTableCell>\n <CodeInput\n aria-label=\"Cookie Name\"\n disableCloseBrackets\n disableTabIndent\n :environment=\"undefined\"\n lineWrapping\n :modelValue=\"row.name\"\n placeholder=\"Name\"\n @update:modelValue=\"\n (name) =>\n handleCookieChange(\n name,\n row.value,\n row.domain,\n row.isDisabled,\n index,\n )\n \" />\n </DataTableCell>\n\n <!-- Value -->\n <DataTableCell>\n <CodeInput\n aria-label=\"Cookie Value\"\n disableTabIndent\n :environment=\"undefined\"\n lineWrapping\n :modelValue=\"row.value\"\n placeholder=\"Value\"\n @update:modelValue=\"\n (value) =>\n handleCookieChange(\n row.name,\n value,\n row.domain,\n row.isDisabled,\n index,\n )\n \" />\n </DataTableCell>\n\n <!-- Domain -->\n <DataTableCell>\n <CodeInput\n aria-label=\"Cookie Domain\"\n disableCloseBrackets\n disableTabIndent\n :environment=\"undefined\"\n lineWrapping\n :modelValue=\"row.domain\"\n placeholder=\"Domain\"\n @update:modelValue=\"\n (domain) =>\n handleCookieChange(\n row.name,\n row.value,\n domain,\n row.isDisabled,\n index,\n )\n \" />\n </DataTableCell>\n\n <!-- Delete button -->\n <DataTableCell class=\"flex items-center justify-center\">\n <ScalarButton\n v-if=\"index < cookies.length\"\n class=\"text-c-2 hover:text-c-1 hover:bg-b-2 hidden h-fit rounded p-1 group-focus-within:flex group-hover/row:flex\"\n size=\"sm\"\n variant=\"ghost\"\n @click=\"handleCookieDelete(index)\">\n <ScalarIconTrash class=\"size-3.5\" />\n </ScalarButton>\n </DataTableCell>\n </DataTableRow>\n </DataTable>\n</template>\n<style scoped>\n:deep(.cm-editor) {\n padding: 0;\n}\n:deep(.cm-content) {\n align-items: center;\n background-color: transparent;\n display: flex;\n font-family: var(--scalar-font);\n font-size: var(--scalar-small);\n padding: 5px 8px;\n width: 100%;\n}\n:deep(.cm-content):has(.cm-pill) {\n padding: 5px 8px;\n}\n:deep(.cm-content .cm-pill:not(:last-of-type)) {\n margin-right: 0.5px;\n}\n:deep(.cm-content .cm-pill:not(:first-of-type)) {\n margin-left: 0.5px;\n}\n:deep(.cm-line) {\n overflow: hidden;\n padding: 0;\n text-overflow: ellipsis;\n}\n</style>\n"],"mappings":""}
1
+ {"version":3,"file":"CookiesTable.vue.js","names":[],"sources":["../../../../../src/v2/features/global-cookies/components/CookiesTable.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ScalarButton } from '@scalar/components'\nimport { ScalarIconTrash } from '@scalar/icons'\nimport type {\n CollectionType,\n WorkspaceEventBus,\n} from '@scalar/workspace-store/events'\nimport type { XScalarCookie } from '@scalar/workspace-store/schemas/extensions/general/x-scalar-cookies'\nimport { computed } from 'vue'\n\nimport { CodeInput } from '@/v2/components/code-input'\nimport {\n DataTable,\n DataTableCell,\n DataTableCheckbox,\n DataTableHeader,\n DataTableRow,\n} from '@/v2/components/data-table'\n\nconst { cookies, eventBus, collectionType } = defineProps<\n {\n cookies: XScalarCookie[]\n eventBus: WorkspaceEventBus\n } & CollectionType\n>()\n\n/** Column widths: Enabled checkbox, Name, Value, Domain, Actions (delete button) */\nconst COLUMNS = ['32px', '1fr', '1fr', '1fr', '36px']\n\n/** Adds an empty row at the end for creating new cookies */\nconst displayRows = computed<\n {\n name: string\n value: string\n domain: string\n isDisabled: boolean\n }[]\n>(() => {\n /** Normalize the cookies to have name, value, and domain */\n const cookieRows = cookies.map((cookie) => ({\n name: cookie.name,\n value: cookie.value,\n domain: cookie.domain ?? '',\n isDisabled: cookie.isDisabled ?? false,\n }))\n\n const lastCookie = cookies.at(-1)\n const hasContentInLastRow =\n lastCookie &&\n (lastCookie.name !== '' ||\n lastCookie.value !== '' ||\n lastCookie.domain !== '')\n\n // Add the extra row at the end\n if (!lastCookie || hasContentInLastRow) {\n return [\n ...cookieRows,\n { name: '', value: '', domain: '', isDisabled: true },\n ]\n }\n\n return cookieRows\n})\n\n/** Updates an existing cookie or creates a new one */\nconst handleCookieChange = (\n name: string,\n value: string,\n domain: string,\n isDisabled: boolean,\n index: number,\n): void => {\n const isNewCookie = index >= cookies.length\n\n /**\n * Do not allow adding a new cookie with an empty name on the last row,\n * we allow it on other rows as it will delete the row\n */\n if (!name && isNewCookie) {\n return\n }\n\n // Adding a new cookie\n if (index >= cookies.length) {\n eventBus.emit('cookie:upsert:cookie', {\n payload: { name, value, domain, isDisabled: false },\n collectionType,\n })\n return\n }\n\n // Updating existing cookie\n eventBus.emit('cookie:upsert:cookie', {\n payload: { name, value, domain, isDisabled },\n collectionType,\n index,\n })\n}\n\n/** Deletes a cookie by index */\nconst handleCookieDelete = (index: number): void =>\n eventBus.emit('cookie:delete:cookie', {\n cookieName: cookies[index]?.name ?? '',\n index,\n collectionType,\n })\n</script>\n<template>\n <!-- Cookies table -->\n <DataTable\n class=\"group/table data-table h-min flex-1 rounded border border-t-0\"\n :columns=\"COLUMNS\">\n <!-- Accessibility header row -->\n <DataTableRow class=\"sr-only !block\">\n <DataTableHeader>Enabled</DataTableHeader>\n <DataTableHeader>Name</DataTableHeader>\n <DataTableHeader>Value</DataTableHeader>\n <DataTableHeader>Domain</DataTableHeader>\n <DataTableHeader>Actions</DataTableHeader>\n </DataTableRow>\n\n <!-- Cookie rows -->\n <DataTableRow\n v-for=\"(row, index) in displayRows\"\n :key=\"index\"\n class=\"group/row\">\n <!-- Enabled checkbox -->\n <DataTableCheckbox\n class=\"!border-r\"\n :modelValue=\"!row.isDisabled\"\n @update:modelValue=\"\n (value) =>\n handleCookieChange(row.name, row.value, row.domain, !value, index)\n \" />\n\n <!-- Name -->\n <DataTableCell>\n <CodeInput\n aria-label=\"Cookie Name\"\n disableCloseBrackets\n disableTabIndent\n :environment=\"undefined\"\n lineWrapping\n :modelValue=\"row.name\"\n placeholder=\"Name\"\n @update:modelValue=\"\n (name) =>\n handleCookieChange(\n name,\n row.value,\n row.domain,\n row.isDisabled,\n index,\n )\n \" />\n </DataTableCell>\n\n <!-- Value -->\n <DataTableCell>\n <CodeInput\n aria-label=\"Cookie Value\"\n disableCloseBrackets\n disableTabIndent\n :environment=\"undefined\"\n lineWrapping\n :modelValue=\"row.value\"\n placeholder=\"Value\"\n withFakeData\n @update:modelValue=\"\n (value) =>\n handleCookieChange(\n row.name,\n value,\n row.domain,\n row.isDisabled,\n index,\n )\n \" />\n </DataTableCell>\n\n <!-- Domain -->\n <DataTableCell>\n <CodeInput\n aria-label=\"Cookie Domain\"\n disableCloseBrackets\n disableTabIndent\n :environment=\"undefined\"\n lineWrapping\n :modelValue=\"row.domain\"\n placeholder=\"Domain\"\n @update:modelValue=\"\n (domain) =>\n handleCookieChange(\n row.name,\n row.value,\n domain,\n row.isDisabled,\n index,\n )\n \" />\n </DataTableCell>\n\n <!-- Delete button -->\n <DataTableCell class=\"flex items-center justify-center\">\n <ScalarButton\n v-if=\"index < cookies.length\"\n class=\"text-c-2 hover:text-c-1 hover:bg-b-2 hidden h-fit rounded p-1 group-focus-within:flex group-hover/row:flex\"\n size=\"sm\"\n variant=\"ghost\"\n @click=\"handleCookieDelete(index)\">\n <ScalarIconTrash class=\"size-3.5\" />\n </ScalarButton>\n </DataTableCell>\n </DataTableRow>\n </DataTable>\n</template>\n<style scoped>\n:deep(.cm-editor) {\n padding: 0;\n}\n:deep(.cm-content) {\n align-items: center;\n background-color: transparent;\n display: flex;\n font-family: var(--scalar-font);\n font-size: var(--scalar-small);\n padding: 5px 8px;\n width: 100%;\n}\n:deep(.cm-content):has(.cm-pill) {\n padding: 5px 8px;\n}\n:deep(.cm-content .cm-pill:not(:last-of-type)) {\n margin-right: 0.5px;\n}\n:deep(.cm-content .cm-pill:not(:first-of-type)) {\n margin-left: 0.5px;\n}\n:deep(.cm-line) {\n overflow: hidden;\n padding: 0;\n text-overflow: ellipsis;\n}\n</style>\n"],"mappings":""}
@@ -136,11 +136,13 @@ var CookiesTable_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ d
136
136
  createVNode(unref(DataTableCell_default), null, {
137
137
  default: withCtx(() => [createVNode(unref(CodeInput_default), {
138
138
  "aria-label": "Cookie Value",
139
+ disableCloseBrackets: "",
139
140
  disableTabIndent: "",
140
141
  environment: void 0,
141
142
  lineWrapping: "",
142
143
  modelValue: row.value,
143
144
  placeholder: "Value",
145
+ withFakeData: "",
144
146
  "onUpdate:modelValue": (value) => handleCookieChange(row.name, value, row.domain, row.isDisabled, index)
145
147
  }, null, 8, ["modelValue", "onUpdate:modelValue"])]),
146
148
  _: 2
@@ -1 +1 @@
1
- {"version":3,"file":"CookiesTable.vue.script.js","names":[],"sources":["../../../../../src/v2/features/global-cookies/components/CookiesTable.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ScalarButton } from '@scalar/components'\nimport { ScalarIconTrash } from '@scalar/icons'\nimport type {\n CollectionType,\n WorkspaceEventBus,\n} from '@scalar/workspace-store/events'\nimport type { XScalarCookie } from '@scalar/workspace-store/schemas/extensions/general/x-scalar-cookies'\nimport { computed } from 'vue'\n\nimport { CodeInput } from '@/v2/components/code-input'\nimport {\n DataTable,\n DataTableCell,\n DataTableCheckbox,\n DataTableHeader,\n DataTableRow,\n} from '@/v2/components/data-table'\n\nconst { cookies, eventBus, collectionType } = defineProps<\n {\n cookies: XScalarCookie[]\n eventBus: WorkspaceEventBus\n } & CollectionType\n>()\n\n/** Column widths: Enabled checkbox, Name, Value, Domain, Actions (delete button) */\nconst COLUMNS = ['32px', '1fr', '1fr', '1fr', '36px']\n\n/** Adds an empty row at the end for creating new cookies */\nconst displayRows = computed<\n {\n name: string\n value: string\n domain: string\n isDisabled: boolean\n }[]\n>(() => {\n /** Normalize the cookies to have name, value, and domain */\n const cookieRows = cookies.map((cookie) => ({\n name: cookie.name,\n value: cookie.value,\n domain: cookie.domain ?? '',\n isDisabled: cookie.isDisabled ?? false,\n }))\n\n const lastCookie = cookies.at(-1)\n const hasContentInLastRow =\n lastCookie &&\n (lastCookie.name !== '' ||\n lastCookie.value !== '' ||\n lastCookie.domain !== '')\n\n // Add the extra row at the end\n if (!lastCookie || hasContentInLastRow) {\n return [\n ...cookieRows,\n { name: '', value: '', domain: '', isDisabled: true },\n ]\n }\n\n return cookieRows\n})\n\n/** Updates an existing cookie or creates a new one */\nconst handleCookieChange = (\n name: string,\n value: string,\n domain: string,\n isDisabled: boolean,\n index: number,\n): void => {\n const isNewCookie = index >= cookies.length\n\n /**\n * Do not allow adding a new cookie with an empty name on the last row,\n * we allow it on other rows as it will delete the row\n */\n if (!name && isNewCookie) {\n return\n }\n\n // Adding a new cookie\n if (index >= cookies.length) {\n eventBus.emit('cookie:upsert:cookie', {\n payload: { name, value, domain, isDisabled: false },\n collectionType,\n })\n return\n }\n\n // Updating existing cookie\n eventBus.emit('cookie:upsert:cookie', {\n payload: { name, value, domain, isDisabled },\n collectionType,\n index,\n })\n}\n\n/** Deletes a cookie by index */\nconst handleCookieDelete = (index: number): void =>\n eventBus.emit('cookie:delete:cookie', {\n cookieName: cookies[index]?.name ?? '',\n index,\n collectionType,\n })\n</script>\n<template>\n <!-- Cookies table -->\n <DataTable\n class=\"group/table data-table h-min flex-1 rounded border border-t-0\"\n :columns=\"COLUMNS\">\n <!-- Accessibility header row -->\n <DataTableRow class=\"sr-only !block\">\n <DataTableHeader>Enabled</DataTableHeader>\n <DataTableHeader>Name</DataTableHeader>\n <DataTableHeader>Value</DataTableHeader>\n <DataTableHeader>Domain</DataTableHeader>\n <DataTableHeader>Actions</DataTableHeader>\n </DataTableRow>\n\n <!-- Cookie rows -->\n <DataTableRow\n v-for=\"(row, index) in displayRows\"\n :key=\"index\"\n class=\"group/row\">\n <!-- Enabled checkbox -->\n <DataTableCheckbox\n class=\"!border-r\"\n :modelValue=\"!row.isDisabled\"\n @update:modelValue=\"\n (value) =>\n handleCookieChange(row.name, row.value, row.domain, !value, index)\n \" />\n\n <!-- Name -->\n <DataTableCell>\n <CodeInput\n aria-label=\"Cookie Name\"\n disableCloseBrackets\n disableTabIndent\n :environment=\"undefined\"\n lineWrapping\n :modelValue=\"row.name\"\n placeholder=\"Name\"\n @update:modelValue=\"\n (name) =>\n handleCookieChange(\n name,\n row.value,\n row.domain,\n row.isDisabled,\n index,\n )\n \" />\n </DataTableCell>\n\n <!-- Value -->\n <DataTableCell>\n <CodeInput\n aria-label=\"Cookie Value\"\n disableTabIndent\n :environment=\"undefined\"\n lineWrapping\n :modelValue=\"row.value\"\n placeholder=\"Value\"\n @update:modelValue=\"\n (value) =>\n handleCookieChange(\n row.name,\n value,\n row.domain,\n row.isDisabled,\n index,\n )\n \" />\n </DataTableCell>\n\n <!-- Domain -->\n <DataTableCell>\n <CodeInput\n aria-label=\"Cookie Domain\"\n disableCloseBrackets\n disableTabIndent\n :environment=\"undefined\"\n lineWrapping\n :modelValue=\"row.domain\"\n placeholder=\"Domain\"\n @update:modelValue=\"\n (domain) =>\n handleCookieChange(\n row.name,\n row.value,\n domain,\n row.isDisabled,\n index,\n )\n \" />\n </DataTableCell>\n\n <!-- Delete button -->\n <DataTableCell class=\"flex items-center justify-center\">\n <ScalarButton\n v-if=\"index < cookies.length\"\n class=\"text-c-2 hover:text-c-1 hover:bg-b-2 hidden h-fit rounded p-1 group-focus-within:flex group-hover/row:flex\"\n size=\"sm\"\n variant=\"ghost\"\n @click=\"handleCookieDelete(index)\">\n <ScalarIconTrash class=\"size-3.5\" />\n </ScalarButton>\n </DataTableCell>\n </DataTableRow>\n </DataTable>\n</template>\n<style scoped>\n:deep(.cm-editor) {\n padding: 0;\n}\n:deep(.cm-content) {\n align-items: center;\n background-color: transparent;\n display: flex;\n font-family: var(--scalar-font);\n font-size: var(--scalar-small);\n padding: 5px 8px;\n width: 100%;\n}\n:deep(.cm-content):has(.cm-pill) {\n padding: 5px 8px;\n}\n:deep(.cm-content .cm-pill:not(:last-of-type)) {\n margin-right: 0.5px;\n}\n:deep(.cm-content .cm-pill:not(:first-of-type)) {\n margin-left: 0.5px;\n}\n:deep(.cm-line) {\n overflow: hidden;\n padding: 0;\n text-overflow: ellipsis;\n}\n</style>\n"],"mappings":"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"}
1
+ {"version":3,"file":"CookiesTable.vue.script.js","names":[],"sources":["../../../../../src/v2/features/global-cookies/components/CookiesTable.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ScalarButton } from '@scalar/components'\nimport { ScalarIconTrash } from '@scalar/icons'\nimport type {\n CollectionType,\n WorkspaceEventBus,\n} from '@scalar/workspace-store/events'\nimport type { XScalarCookie } from '@scalar/workspace-store/schemas/extensions/general/x-scalar-cookies'\nimport { computed } from 'vue'\n\nimport { CodeInput } from '@/v2/components/code-input'\nimport {\n DataTable,\n DataTableCell,\n DataTableCheckbox,\n DataTableHeader,\n DataTableRow,\n} from '@/v2/components/data-table'\n\nconst { cookies, eventBus, collectionType } = defineProps<\n {\n cookies: XScalarCookie[]\n eventBus: WorkspaceEventBus\n } & CollectionType\n>()\n\n/** Column widths: Enabled checkbox, Name, Value, Domain, Actions (delete button) */\nconst COLUMNS = ['32px', '1fr', '1fr', '1fr', '36px']\n\n/** Adds an empty row at the end for creating new cookies */\nconst displayRows = computed<\n {\n name: string\n value: string\n domain: string\n isDisabled: boolean\n }[]\n>(() => {\n /** Normalize the cookies to have name, value, and domain */\n const cookieRows = cookies.map((cookie) => ({\n name: cookie.name,\n value: cookie.value,\n domain: cookie.domain ?? '',\n isDisabled: cookie.isDisabled ?? false,\n }))\n\n const lastCookie = cookies.at(-1)\n const hasContentInLastRow =\n lastCookie &&\n (lastCookie.name !== '' ||\n lastCookie.value !== '' ||\n lastCookie.domain !== '')\n\n // Add the extra row at the end\n if (!lastCookie || hasContentInLastRow) {\n return [\n ...cookieRows,\n { name: '', value: '', domain: '', isDisabled: true },\n ]\n }\n\n return cookieRows\n})\n\n/** Updates an existing cookie or creates a new one */\nconst handleCookieChange = (\n name: string,\n value: string,\n domain: string,\n isDisabled: boolean,\n index: number,\n): void => {\n const isNewCookie = index >= cookies.length\n\n /**\n * Do not allow adding a new cookie with an empty name on the last row,\n * we allow it on other rows as it will delete the row\n */\n if (!name && isNewCookie) {\n return\n }\n\n // Adding a new cookie\n if (index >= cookies.length) {\n eventBus.emit('cookie:upsert:cookie', {\n payload: { name, value, domain, isDisabled: false },\n collectionType,\n })\n return\n }\n\n // Updating existing cookie\n eventBus.emit('cookie:upsert:cookie', {\n payload: { name, value, domain, isDisabled },\n collectionType,\n index,\n })\n}\n\n/** Deletes a cookie by index */\nconst handleCookieDelete = (index: number): void =>\n eventBus.emit('cookie:delete:cookie', {\n cookieName: cookies[index]?.name ?? '',\n index,\n collectionType,\n })\n</script>\n<template>\n <!-- Cookies table -->\n <DataTable\n class=\"group/table data-table h-min flex-1 rounded border border-t-0\"\n :columns=\"COLUMNS\">\n <!-- Accessibility header row -->\n <DataTableRow class=\"sr-only !block\">\n <DataTableHeader>Enabled</DataTableHeader>\n <DataTableHeader>Name</DataTableHeader>\n <DataTableHeader>Value</DataTableHeader>\n <DataTableHeader>Domain</DataTableHeader>\n <DataTableHeader>Actions</DataTableHeader>\n </DataTableRow>\n\n <!-- Cookie rows -->\n <DataTableRow\n v-for=\"(row, index) in displayRows\"\n :key=\"index\"\n class=\"group/row\">\n <!-- Enabled checkbox -->\n <DataTableCheckbox\n class=\"!border-r\"\n :modelValue=\"!row.isDisabled\"\n @update:modelValue=\"\n (value) =>\n handleCookieChange(row.name, row.value, row.domain, !value, index)\n \" />\n\n <!-- Name -->\n <DataTableCell>\n <CodeInput\n aria-label=\"Cookie Name\"\n disableCloseBrackets\n disableTabIndent\n :environment=\"undefined\"\n lineWrapping\n :modelValue=\"row.name\"\n placeholder=\"Name\"\n @update:modelValue=\"\n (name) =>\n handleCookieChange(\n name,\n row.value,\n row.domain,\n row.isDisabled,\n index,\n )\n \" />\n </DataTableCell>\n\n <!-- Value -->\n <DataTableCell>\n <CodeInput\n aria-label=\"Cookie Value\"\n disableCloseBrackets\n disableTabIndent\n :environment=\"undefined\"\n lineWrapping\n :modelValue=\"row.value\"\n placeholder=\"Value\"\n withFakeData\n @update:modelValue=\"\n (value) =>\n handleCookieChange(\n row.name,\n value,\n row.domain,\n row.isDisabled,\n index,\n )\n \" />\n </DataTableCell>\n\n <!-- Domain -->\n <DataTableCell>\n <CodeInput\n aria-label=\"Cookie Domain\"\n disableCloseBrackets\n disableTabIndent\n :environment=\"undefined\"\n lineWrapping\n :modelValue=\"row.domain\"\n placeholder=\"Domain\"\n @update:modelValue=\"\n (domain) =>\n handleCookieChange(\n row.name,\n row.value,\n domain,\n row.isDisabled,\n index,\n )\n \" />\n </DataTableCell>\n\n <!-- Delete button -->\n <DataTableCell class=\"flex items-center justify-center\">\n <ScalarButton\n v-if=\"index < cookies.length\"\n class=\"text-c-2 hover:text-c-1 hover:bg-b-2 hidden h-fit rounded p-1 group-focus-within:flex group-hover/row:flex\"\n size=\"sm\"\n variant=\"ghost\"\n @click=\"handleCookieDelete(index)\">\n <ScalarIconTrash class=\"size-3.5\" />\n </ScalarButton>\n </DataTableCell>\n </DataTableRow>\n </DataTable>\n</template>\n<style scoped>\n:deep(.cm-editor) {\n padding: 0;\n}\n:deep(.cm-content) {\n align-items: center;\n background-color: transparent;\n display: flex;\n font-family: var(--scalar-font);\n font-size: var(--scalar-small);\n padding: 5px 8px;\n width: 100%;\n}\n:deep(.cm-content):has(.cm-pill) {\n padding: 5px 8px;\n}\n:deep(.cm-content .cm-pill:not(:last-of-type)) {\n margin-right: 0.5px;\n}\n:deep(.cm-content .cm-pill:not(:first-of-type)) {\n margin-left: 0.5px;\n}\n:deep(.cm-line) {\n overflow: hidden;\n padding: 0;\n text-overflow: ellipsis;\n}\n</style>\n"],"mappings":"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"}