@websublime/vite-plugin-open-api-devtools 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/dist/ModelsPage-CWTC2dZx.js +629 -0
  2. package/dist/ModelsPage-CWTC2dZx.js.map +1 -0
  3. package/dist/{RoutesPage-D7H_CupP.js → RoutesPage-C2CUh7EQ.js} +6 -5
  4. package/dist/{RoutesPage-D7H_CupP.js.map → RoutesPage-C2CUh7EQ.js.map} +1 -1
  5. package/dist/{SimulatorPage-9sBeAxQI.js → SimulatorPage-BeGppUDC.js} +6 -5
  6. package/dist/{SimulatorPage-9sBeAxQI.js.map → SimulatorPage-BeGppUDC.js.map} +1 -1
  7. package/dist/{TimelinePage-CMchXIlE.js → TimelinePage-CwQC37C0.js} +25 -23
  8. package/dist/TimelinePage-CwQC37C0.js.map +1 -0
  9. package/dist/check-Yd6w1NtA.js +6 -0
  10. package/dist/check-Yd6w1NtA.js.map +1 -0
  11. package/dist/devtools.css +1 -1
  12. package/dist/devtools.js +1 -1
  13. package/dist/devtools.umd.cjs +3 -1
  14. package/dist/devtools.umd.cjs.map +1 -1
  15. package/dist/{format-CE7KDbll.js → format-mVjPq6hT.js} +11 -16
  16. package/dist/format-mVjPq6hT.js.map +1 -0
  17. package/dist/{main-AUiFaD93.js → main-BxRf_QJn.js} +5 -5
  18. package/dist/{main-AUiFaD93.js.map → main-BxRf_QJn.js.map} +1 -1
  19. package/dist/trash-2-kFFQD_yH.js +12 -0
  20. package/dist/trash-2-kFFQD_yH.js.map +1 -0
  21. package/dist/triangle-alert-jXNj-fTF.js +16 -0
  22. package/dist/triangle-alert-jXNj-fTF.js.map +1 -0
  23. package/dist/x-BkudkKl_.js +9 -0
  24. package/dist/x-BkudkKl_.js.map +1 -0
  25. package/package.json +10 -9
  26. package/dist/ModelsPage-D-qLEz14.js +0 -93
  27. package/dist/ModelsPage-D-qLEz14.js.map +0 -1
  28. package/dist/TimelinePage-CMchXIlE.js.map +0 -1
  29. package/dist/format-CE7KDbll.js.map +0 -1
  30. package/dist/triangle-alert-ZH4fYFnz.js +0 -24
  31. package/dist/triangle-alert-ZH4fYFnz.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ModelsPage-CWTC2dZx.js","sources":["../../../node_modules/.pnpm/lucide-vue-next@0.513.0_vue@3.5.27_typescript@5.9.3_/node_modules/lucide-vue-next/dist/esm/icons/circle-alert.js","../../../node_modules/.pnpm/lucide-vue-next@0.513.0_vue@3.5.27_typescript@5.9.3_/node_modules/lucide-vue-next/dist/esm/icons/refresh-cw.js","../../../node_modules/.pnpm/lucide-vue-next@0.513.0_vue@3.5.27_typescript@5.9.3_/node_modules/lucide-vue-next/dist/esm/icons/save.js","../src/stores/models.ts","../src/components/JsonEditor.vue","../src/composables/useNotifications.ts","../src/pages/ModelsPage.vue"],"sourcesContent":["/**\n * @license lucide-vue-next v0.513.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst CircleAlert = createLucideIcon(\"circle-alert\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"line\", { x1: \"12\", x2: \"12\", y1: \"8\", y2: \"12\", key: \"1pkeuh\" }],\n [\"line\", { x1: \"12\", x2: \"12.01\", y1: \"16\", y2: \"16\", key: \"4dfq90\" }]\n]);\n\nexport { CircleAlert as default };\n//# sourceMappingURL=circle-alert.js.map\n","/**\n * @license lucide-vue-next v0.513.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst RefreshCw = createLucideIcon(\"refresh-cw\", [\n [\"path\", { d: \"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8\", key: \"v9h5vc\" }],\n [\"path\", { d: \"M21 3v5h-5\", key: \"1q7to0\" }],\n [\"path\", { d: \"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16\", key: \"3uifl3\" }],\n [\"path\", { d: \"M8 16H3v5\", key: \"1cv678\" }]\n]);\n\nexport { RefreshCw as default };\n//# sourceMappingURL=refresh-cw.js.map\n","/**\n * @license lucide-vue-next v0.513.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Save = createLucideIcon(\"save\", [\n [\n \"path\",\n {\n d: \"M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z\",\n key: \"1c8476\"\n }\n ],\n [\"path\", { d: \"M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7\", key: \"1ydtos\" }],\n [\"path\", { d: \"M7 3v4a1 1 0 0 0 1 1h7\", key: \"t51u73\" }]\n]);\n\nexport { Save as default };\n//# sourceMappingURL=save.js.map\n","/**\n * Models Store - Store Data Management\n *\n * What: Manages in-memory store data for viewing and editing mock data\n * How: Fetches data from /_api/store endpoints and sends WebSocket commands\n * Why: Provides centralized state management for the Models page\n *\n * API Endpoints Used:\n * - GET /_api/store - List all schemas\n * - GET /_api/store/:schema - Get items for a schema\n * - POST /_api/store/:schema - Bulk replace items\n * - DELETE /_api/store/:schema - Clear schema data\n *\n * WebSocket Commands:\n * - reseed - Trigger reseed of all schemas\n */\n\nimport { defineStore } from 'pinia';\nimport type { ComputedRef, Ref } from 'vue';\nimport { computed, ref, toRaw } from 'vue';\n\n/**\n * Safe clone helper that handles Vue reactive/proxy values\n * Attempts structuredClone with toRaw, falls back to JSON serialization\n */\nfunction safeClone<T>(value: T): T {\n try {\n return structuredClone(toRaw(value));\n } catch {\n return JSON.parse(JSON.stringify(value)) as T;\n }\n}\n\n/**\n * Schema metadata from the server\n */\nexport interface SchemaInfo {\n /** Schema name from OpenAPI components */\n name: string;\n /** Number of items in the store for this schema */\n count: number;\n /** ID field name for this schema */\n idField: string;\n}\n\n/**\n * Schema data response from the server\n */\nexport interface SchemaData {\n /** Schema name */\n schema: string;\n /** Number of items */\n count: number;\n /** ID field name */\n idField: string;\n /** Array of data items */\n items: unknown[];\n}\n\n/**\n * Store state data\n */\nexport interface ModelsData {\n /** List of available schemas */\n schemas: SchemaInfo[];\n /** Currently selected schema name */\n selectedSchema: string | null;\n /** Items for the currently selected schema */\n currentItems: unknown[];\n /** Loading state */\n loading: boolean;\n /** Error message if any */\n error: string | null;\n /** Editing state - whether data has been modified */\n isDirty: boolean;\n}\n\n/**\n * Models store for managing store data\n */\nexport const useModelsStore = defineStore('models', () => {\n // ==========================================================================\n // State\n // ==========================================================================\n\n /** List of available schemas with metadata */\n const schemas: Ref<SchemaInfo[]> = ref([]);\n\n /** Currently selected schema name */\n const selectedSchema: Ref<string | null> = ref(null);\n\n /** Items for the currently selected schema */\n const currentItems: Ref<unknown[]> = ref([]);\n\n /** Original items (before editing) for dirty detection */\n const originalItems: Ref<unknown[]> = ref([]);\n\n /** Loading state */\n const loading: Ref<boolean> = ref(false);\n\n /** Error message */\n const error: Ref<string | null> = ref(null);\n\n // ==========================================================================\n // Computed\n // ==========================================================================\n\n /**\n * Currently selected schema metadata\n */\n const currentSchema: ComputedRef<SchemaInfo | null> = computed(() => {\n if (!selectedSchema.value) return null;\n return schemas.value.find((s) => s.name === selectedSchema.value) ?? null;\n });\n\n /**\n * Dirty state flag - updated by functions that mutate state\n */\n const isDirtyFlag: Ref<boolean> = ref(false);\n\n /**\n * Whether the current data has been modified\n */\n const isDirty: ComputedRef<boolean> = computed(() => isDirtyFlag.value);\n\n /**\n * Total number of schemas\n */\n const schemaCount: ComputedRef<number> = computed(() => schemas.value.length);\n\n /**\n * Total number of items across all schemas\n */\n const totalItems: ComputedRef<number> = computed(() => {\n return schemas.value.reduce((sum, schema) => sum + schema.count, 0);\n });\n\n // ==========================================================================\n // Actions\n // ==========================================================================\n\n /**\n * Fetch the list of schemas from the server\n */\n async function fetchSchemas(): Promise<void> {\n loading.value = true;\n error.value = null;\n\n try {\n const response = await fetch('/_api/store');\n if (!response.ok) {\n throw new Error(`Failed to fetch schemas: ${response.statusText}`);\n }\n\n const data = await response.json();\n schemas.value = data.schemas ?? [];\n } catch (err) {\n error.value = err instanceof Error ? err.message : 'Failed to fetch schemas';\n console.error('[ModelsStore] Error fetching schemas:', err);\n } finally {\n loading.value = false;\n }\n }\n\n /**\n * Select a schema and fetch its data\n */\n async function selectSchemaByName(schemaName: string): Promise<void> {\n if (selectedSchema.value === schemaName) return;\n\n selectedSchema.value = schemaName;\n await fetchSchemaData(schemaName);\n }\n\n /**\n * Fetch data for a specific schema\n */\n async function fetchSchemaData(schemaName: string): Promise<void> {\n loading.value = true;\n error.value = null;\n\n try {\n const response = await fetch(`/_api/store/${encodeURIComponent(schemaName)}`);\n if (!response.ok) {\n throw new Error(`Failed to fetch schema data: ${response.statusText}`);\n }\n\n const data: SchemaData = await response.json();\n const items = data.items ?? [];\n // Clone items to avoid shared references between current and original\n currentItems.value = safeClone(items);\n originalItems.value = safeClone(items);\n isDirtyFlag.value = false;\n\n // Update schema count in the list\n const schemaIndex = schemas.value.findIndex((s) => s.name === schemaName);\n if (schemaIndex !== -1) {\n schemas.value[schemaIndex].count = data.count;\n }\n } catch (err) {\n error.value = err instanceof Error ? err.message : 'Failed to fetch schema data';\n console.error('[ModelsStore] Error fetching schema data:', err);\n } finally {\n loading.value = false;\n }\n }\n\n /**\n * Update the current items (for editing)\n */\n function updateItems(items: unknown): void {\n // Validate that items is an array\n if (!Array.isArray(items)) {\n error.value = 'Invalid data: Expected an array of items';\n console.error('[ModelsStore] updateItems received non-array value:', typeof items);\n return;\n }\n\n currentItems.value = items;\n // Clear any previous validation errors\n error.value = null;\n // Mark as dirty since items were updated\n isDirtyFlag.value = true;\n }\n\n /**\n * Save the current items to the server\n */\n async function saveItems(): Promise<boolean> {\n if (!selectedSchema.value) {\n error.value = 'No schema selected';\n return false;\n }\n\n loading.value = true;\n error.value = null;\n\n try {\n const response = await fetch(`/_api/store/${encodeURIComponent(selectedSchema.value)}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(currentItems.value),\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n throw new Error(errorData.error || `Failed to save items: ${response.statusText}`);\n }\n\n const result = await response.json();\n\n // Update original items to match saved items\n originalItems.value = safeClone(currentItems.value);\n isDirtyFlag.value = false;\n\n // Update schema count\n const schemaIndex = schemas.value.findIndex((s) => s.name === selectedSchema.value);\n if (schemaIndex !== -1) {\n schemas.value[schemaIndex].count = result.created ?? currentItems.value.length;\n }\n\n return true;\n } catch (err) {\n error.value = err instanceof Error ? err.message : 'Failed to save items';\n console.error('[ModelsStore] Error saving items:', err);\n return false;\n } finally {\n loading.value = false;\n }\n }\n\n /**\n * Clear all items for the current schema\n */\n async function clearSchema(): Promise<boolean> {\n if (!selectedSchema.value) {\n error.value = 'No schema selected';\n return false;\n }\n\n loading.value = true;\n error.value = null;\n\n try {\n const response = await fetch(`/_api/store/${encodeURIComponent(selectedSchema.value)}`, {\n method: 'DELETE',\n });\n\n if (!response.ok) {\n throw new Error(`Failed to clear schema: ${response.statusText}`);\n }\n\n // Update local state\n currentItems.value = [];\n originalItems.value = [];\n isDirtyFlag.value = false;\n\n // Update schema count\n const schemaIndex = schemas.value.findIndex((s) => s.name === selectedSchema.value);\n if (schemaIndex !== -1) {\n schemas.value[schemaIndex].count = 0;\n }\n\n return true;\n } catch (err) {\n error.value = err instanceof Error ? err.message : 'Failed to clear schema';\n console.error('[ModelsStore] Error clearing schema:', err);\n return false;\n } finally {\n loading.value = false;\n }\n }\n\n /**\n * Discard changes and revert to original items\n */\n function discardChanges(): void {\n currentItems.value = safeClone(originalItems.value);\n isDirtyFlag.value = false;\n }\n\n /**\n * Refresh the current schema data from the server\n */\n async function refresh(): Promise<void> {\n if (selectedSchema.value) {\n await fetchSchemaData(selectedSchema.value);\n } else {\n await fetchSchemas();\n }\n }\n\n /**\n * Reset the store state\n */\n function reset(): void {\n schemas.value = [];\n selectedSchema.value = null;\n currentItems.value = [];\n originalItems.value = [];\n loading.value = false;\n error.value = null;\n isDirtyFlag.value = false;\n }\n\n /**\n * Handle store update from WebSocket event\n */\n function handleStoreUpdate(data: { schema: string; action: string; count: number }): void {\n const schemaIndex = schemas.value.findIndex((s) => s.name === data.schema);\n if (schemaIndex !== -1) {\n schemas.value[schemaIndex].count = data.count;\n }\n\n // If the updated schema is currently selected, refresh it only if no unsaved changes\n if (selectedSchema.value === data.schema) {\n if (!isDirty.value) {\n fetchSchemaData(data.schema);\n } else {\n // Don't auto-refresh when there are unsaved changes\n console.warn(\n `[ModelsStore] Skipping auto-refresh for schema \"${data.schema}\" - unsaved changes exist`,\n );\n }\n }\n }\n\n /**\n * Handle reseed completion from WebSocket event\n */\n function handleReseedComplete(data: { success: boolean; schemas: string[] }): void {\n if (data.success) {\n // Refresh schema list\n fetchSchemas();\n\n // Refresh current schema data only if no unsaved changes\n if (selectedSchema.value) {\n if (!isDirty.value) {\n fetchSchemaData(selectedSchema.value);\n } else {\n console.warn(\n `[ModelsStore] Skipping auto-refresh after reseed for schema \"${selectedSchema.value}\" - unsaved changes exist`,\n );\n }\n }\n }\n }\n\n // ==========================================================================\n // Return store interface\n // ==========================================================================\n\n return {\n // State\n schemas,\n selectedSchema,\n currentItems,\n loading,\n error,\n\n // Computed\n currentSchema,\n isDirty,\n schemaCount,\n totalItems,\n\n // Actions\n fetchSchemas,\n selectSchemaByName,\n fetchSchemaData,\n updateItems,\n saveItems,\n clearSchema,\n discardChanges,\n refresh,\n reset,\n handleStoreUpdate,\n handleReseedComplete,\n };\n});\n\nexport type ModelsStore = ReturnType<typeof useModelsStore>;\n","<!--\n JsonEditor.vue - JSON Editor Component\n\n What: Editable JSON textarea with syntax highlighting and validation\n How: Uses a textarea with syntax validation and formatting utilities\n Why: Allows developers to edit mock data in a user-friendly interface\n\n Features:\n - Real-time JSON validation\n - Syntax error display\n - Format/prettify button\n - Line numbers\n - Monospace font\n-->\n\n<script setup lang=\"ts\">\nimport { AlertCircle, Check } from 'lucide-vue-next';\nimport { computed, ref, watch } from 'vue';\n\n/**\n * Component props\n */\ninterface Props {\n /** JSON data to edit (will be stringified) */\n modelValue: unknown;\n /** Whether the editor is read-only */\n readonly?: boolean;\n /** Placeholder text when empty */\n placeholder?: string;\n /** Minimum height in pixels */\n minHeight?: number;\n}\n\n/**\n * Component emits\n */\ninterface Emits {\n (e: 'update:modelValue', value: unknown): void;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n readonly: false,\n placeholder: 'Enter JSON data...',\n minHeight: 200,\n});\n\nconst emit = defineEmits<Emits>();\n\n// ==========================================================================\n// State\n// ==========================================================================\n\n/** Current text content */\nconst text = ref<string>('');\n\n/** JSON validation error */\nconst validationError = ref<string | null>(null);\n\n/** Whether JSON is valid */\nconst isValid = computed(() => validationError.value === null);\n\n/** Line count for line numbers */\nconst lineCount = computed(() => {\n return text.value.split('\\n').length;\n});\n\n/** Line numbers array */\nconst lineNumbers = computed(() => {\n return Array.from({ length: lineCount.value }, (_, i) => i + 1);\n});\n\n// ==========================================================================\n// Initialization\n// ==========================================================================\n\n/**\n * Initialize text from modelValue\n */\nfunction initializeText(): void {\n try {\n text.value = JSON.stringify(props.modelValue, null, 2);\n validationError.value = null;\n } catch (err) {\n text.value = '';\n validationError.value = 'Invalid initial value';\n }\n}\n\n// Initialize on mount\ninitializeText();\n\n// Watch for external changes to modelValue\nwatch(\n () => props.modelValue,\n () => {\n // Only update if the parsed value differs (avoid cursor jumps during typing)\n try {\n const currentParsed = JSON.parse(text.value);\n if (JSON.stringify(currentParsed) !== JSON.stringify(props.modelValue)) {\n initializeText();\n }\n } catch {\n // If current text is invalid, always update\n initializeText();\n }\n },\n);\n\n// ==========================================================================\n// Actions\n// ==========================================================================\n\n/**\n * Handle text input\n */\nfunction handleInput(event: Event): void {\n const target = event.target as HTMLTextAreaElement;\n text.value = target.value;\n validateAndEmit();\n}\n\n/**\n * Validate JSON and emit update\n */\nfunction validateAndEmit(): void {\n if (text.value.trim() === '') {\n validationError.value = null;\n emit('update:modelValue', []);\n return;\n }\n\n try {\n const parsed = JSON.parse(text.value);\n validationError.value = null;\n emit('update:modelValue', parsed);\n } catch (err) {\n if (err instanceof Error) {\n // Extract line/column info from error message\n const match = err.message.match(/position (\\d+)/);\n if (match) {\n const position = Number.parseInt(match[1], 10);\n const lines = text.value.substring(0, position).split('\\n');\n const line = lines.length;\n const column = lines[lines.length - 1].length + 1;\n validationError.value = `Line ${line}, Column ${column}: ${err.message}`;\n } else {\n validationError.value = err.message;\n }\n } else {\n validationError.value = 'Invalid JSON';\n }\n }\n}\n\n/**\n * Format/prettify the JSON\n */\nfunction formatJson(): void {\n try {\n const parsed = JSON.parse(text.value);\n text.value = JSON.stringify(parsed, null, 2);\n validationError.value = null;\n emit('update:modelValue', parsed);\n } catch {\n // If invalid, do nothing\n }\n}\n\n/**\n * Handle Tab key for indentation\n */\nfunction handleKeyDown(event: KeyboardEvent): void {\n if (event.key === 'Tab') {\n event.preventDefault();\n const target = event.target as HTMLTextAreaElement;\n const start = target.selectionStart;\n const end = target.selectionEnd;\n\n // Insert 2 spaces\n const newText = `${text.value.substring(0, start)} ${text.value.substring(end)}`;\n text.value = newText;\n\n // Move cursor\n setTimeout(() => {\n target.selectionStart = target.selectionEnd = start + 2;\n }, 0);\n\n validateAndEmit();\n }\n}\n\n// ==========================================================================\n// Expose methods\n// ==========================================================================\n\ndefineExpose({\n formatJson,\n isValid,\n});\n</script>\n\n<template>\n <div class=\"json-editor\">\n <!-- Editor Container -->\n <div class=\"json-editor__container\">\n <!-- Line Numbers -->\n <div class=\"json-editor__lines\" aria-hidden=\"true\">\n <div\n v-for=\"lineNum in lineNumbers\"\n :key=\"lineNum\"\n class=\"json-editor__line-number\"\n >\n {{ lineNum }}\n </div>\n </div>\n\n <!-- Textarea -->\n <textarea\n :value=\"text\"\n :readonly=\"readonly\"\n :placeholder=\"placeholder\"\n :style=\"{ minHeight: `${minHeight}px` }\"\n class=\"json-editor__textarea\"\n spellcheck=\"false\"\n @input=\"handleInput\"\n @keydown=\"handleKeyDown\"\n />\n </div>\n\n <!-- Status Bar -->\n <div class=\"json-editor__status\">\n <div class=\"json-editor__status-left\">\n <!-- Validation Status -->\n <div v-if=\"isValid\" class=\"json-editor__valid\">\n <Check :size=\"14\" />\n <span>Valid JSON</span>\n </div>\n <div v-else-if=\"validationError\" class=\"json-editor__error\">\n <AlertCircle :size=\"14\" />\n <span>{{ validationError }}</span>\n </div>\n </div>\n\n <div class=\"json-editor__status-right\">\n <!-- Line Count -->\n <span class=\"json-editor__info\">{{ lineCount }} lines</span>\n </div>\n </div>\n </div>\n</template>\n\n<style scoped>\n.json-editor {\n display: flex;\n flex-direction: column;\n background-color: var(--devtools-surface);\n border: 1px solid var(--devtools-border);\n border-radius: var(--devtools-radius-md);\n overflow: hidden;\n}\n\n/* Editor Container */\n.json-editor__container {\n display: flex;\n overflow: auto;\n flex: 1;\n}\n\n/* Line Numbers */\n.json-editor__lines {\n display: flex;\n flex-direction: column;\n padding: var(--devtools-space-sm) var(--devtools-space-xs);\n background-color: var(--devtools-surface-elevated);\n border-right: 1px solid var(--devtools-border);\n user-select: none;\n flex-shrink: 0;\n}\n\n.json-editor__line-number {\n height: 1.5em;\n line-height: 1.5;\n text-align: right;\n font-family: var(--devtools-font-mono);\n font-size: var(--font-size-0);\n color: var(--devtools-text-muted);\n min-width: 2ch;\n padding-right: var(--devtools-space-xs);\n}\n\n/* Textarea */\n.json-editor__textarea {\n flex: 1;\n padding: var(--devtools-space-sm);\n background-color: var(--devtools-surface);\n color: var(--devtools-text);\n border: none;\n outline: none;\n resize: vertical;\n font-family: var(--devtools-font-mono);\n font-size: var(--font-size-0);\n line-height: 1.5;\n tab-size: 2;\n white-space: pre;\n overflow-wrap: normal;\n overflow-x: auto;\n}\n\n.json-editor__textarea::placeholder {\n color: var(--devtools-text-muted);\n opacity: 0.6;\n}\n\n.json-editor__textarea:focus {\n outline: 2px solid var(--devtools-primary);\n outline-offset: -2px;\n}\n\n.json-editor__textarea[readonly] {\n background-color: var(--devtools-surface-elevated);\n cursor: not-allowed;\n opacity: 0.7;\n}\n\n/* Status Bar */\n.json-editor__status {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--devtools-space-md);\n padding: var(--devtools-space-xs) var(--devtools-space-sm);\n background-color: var(--devtools-surface-elevated);\n border-top: 1px solid var(--devtools-border);\n font-size: var(--font-size-0);\n}\n\n.json-editor__status-left,\n.json-editor__status-right {\n display: flex;\n align-items: center;\n gap: var(--devtools-space-sm);\n}\n\n/* Validation Indicators */\n.json-editor__valid {\n display: flex;\n align-items: center;\n gap: var(--devtools-space-xs);\n color: var(--devtools-success);\n}\n\n.json-editor__error {\n display: flex;\n align-items: center;\n gap: var(--devtools-space-xs);\n color: var(--devtools-error);\n}\n\n.json-editor__info {\n color: var(--devtools-text-muted);\n}\n\n/* Dark mode adjustments */\n@media (prefers-color-scheme: dark) {\n .json-editor__textarea {\n color: #e2e8f0;\n }\n\n .json-editor__textarea::placeholder {\n color: #64748b;\n }\n}\n</style>\n","/**\n * Notifications Composable\n *\n * What: Provides consistent user feedback mechanism for the DevTools\n * How: Manages toast notifications and confirmation modals\n * Why: Replaces inconsistent alert()/confirm()/console.log() usage\n *\n * Features:\n * - Toast notifications for success/error/info messages\n * - Confirmation modals with custom messages\n * - Auto-dismiss for toast notifications\n * - Centralized state management\n */\n\nimport { reactive, ref } from 'vue';\n\n/**\n * Toast notification types\n */\nexport type ToastType = 'success' | 'error' | 'info' | 'warning';\n\n/**\n * Toast notification\n */\nexport interface Toast {\n id: string;\n type: ToastType;\n message: string;\n duration: number;\n timestamp: number;\n}\n\n/**\n * Confirmation dialog state\n */\nexport interface ConfirmDialog {\n visible: boolean;\n title: string;\n message: string;\n confirmText: string;\n cancelText: string;\n onConfirm: (() => void) | null;\n onCancel: (() => void) | null;\n}\n\n// ==========================================================================\n// Global State\n// ==========================================================================\n\nconst toasts = ref<Toast[]>([]);\nconst confirmDialog = reactive<ConfirmDialog>({\n visible: false,\n title: '',\n message: '',\n confirmText: 'Confirm',\n cancelText: 'Cancel',\n onConfirm: null,\n onCancel: null,\n});\n\n// Track active timeout IDs to prevent orphaned timers\nconst timeouts = new Map<string, ReturnType<typeof setTimeout>>();\n\n// Track pending confirm dialog promise resolver\nlet pendingResolve: ((value: boolean) => void) | null = null;\n\n// ==========================================================================\n// Helper Functions\n// ==========================================================================\n\nlet toastIdCounter = 0;\n\nfunction generateToastId(): string {\n return `toast-${Date.now()}-${toastIdCounter++}`;\n}\n\nfunction addToast(type: ToastType, message: string, duration = 3000): string {\n const id = generateToastId();\n const toast: Toast = {\n id,\n type,\n message,\n duration,\n timestamp: Date.now(),\n };\n\n toasts.value.push(toast);\n\n // Auto-dismiss\n if (duration > 0) {\n const timeoutId = setTimeout(() => {\n removeToast(id);\n timeouts.delete(id);\n }, duration);\n timeouts.set(id, timeoutId);\n }\n\n return id;\n}\n\nfunction removeToast(id: string): void {\n // Clear the timeout if it exists\n const timeoutId = timeouts.get(id);\n if (timeoutId !== undefined) {\n clearTimeout(timeoutId);\n timeouts.delete(id);\n }\n\n // Remove the toast from the array\n const index = toasts.value.findIndex((t) => t.id === id);\n if (index !== -1) {\n toasts.value.splice(index, 1);\n }\n}\n\n// ==========================================================================\n// Composable\n// ==========================================================================\n\n/**\n * Notifications composable\n *\n * Provides methods for showing toast notifications and confirmation dialogs\n */\nexport function useNotifications() {\n /**\n * Show a success toast notification\n */\n function success(message: string, duration?: number): string {\n return addToast('success', message, duration);\n }\n\n /**\n * Show an error toast notification\n */\n function error(message: string, duration?: number): string {\n return addToast('error', message, duration);\n }\n\n /**\n * Show an info toast notification\n */\n function info(message: string, duration?: number): string {\n return addToast('info', message, duration);\n }\n\n /**\n * Show a warning toast notification\n */\n function warning(message: string, duration?: number): string {\n return addToast('warning', message, duration);\n }\n\n /**\n * Show a confirmation dialog\n *\n * @returns Promise that resolves to true if confirmed, false if cancelled\n */\n function confirm(\n message: string,\n options?: {\n title?: string;\n confirmText?: string;\n cancelText?: string;\n },\n ): Promise<boolean> {\n return new Promise((resolve) => {\n // Resolve any pending dialog with false (cancelled) before opening new one\n if (pendingResolve) {\n pendingResolve(false);\n pendingResolve = null;\n }\n\n // Store the new resolve reference\n pendingResolve = resolve;\n\n confirmDialog.visible = true;\n confirmDialog.title = options?.title || 'Confirm';\n confirmDialog.message = message;\n confirmDialog.confirmText = options?.confirmText || 'Confirm';\n confirmDialog.cancelText = options?.cancelText || 'Cancel';\n\n confirmDialog.onConfirm = () => {\n confirmDialog.visible = false;\n if (pendingResolve) {\n pendingResolve(true);\n pendingResolve = null;\n }\n };\n\n confirmDialog.onCancel = () => {\n confirmDialog.visible = false;\n if (pendingResolve) {\n pendingResolve(false);\n pendingResolve = null;\n }\n };\n });\n }\n\n /**\n * Close the confirmation dialog\n */\n function closeConfirm(): void {\n confirmDialog.visible = false;\n if (pendingResolve) {\n pendingResolve(false);\n pendingResolve = null;\n }\n }\n\n /**\n * Manually dismiss a toast by ID\n */\n function dismiss(id: string): void {\n removeToast(id);\n }\n\n /**\n * Clear all toasts\n */\n function clearAll(): void {\n // Clear all active timeouts\n for (const timeoutId of timeouts.values()) {\n clearTimeout(timeoutId);\n }\n timeouts.clear();\n toasts.value = [];\n }\n\n return {\n // State\n toasts,\n confirmDialog,\n\n // Toast methods\n success,\n error,\n info,\n warning,\n dismiss,\n clearAll,\n\n // Confirm methods\n confirm,\n closeConfirm,\n };\n}\n","<!--\n ModelsPage.vue - Store Data Editor Page\n\n What: Displays and allows editing of in-memory store data organized by schema\n How: Fetches store data from models store and displays in an editable JSON view\n Why: Allows developers to inspect and modify mock data during development\n\n Features:\n - Schema listing sidebar with item counts\n - JSON editor with syntax validation\n - Save, discard, clear, and reseed actions\n - Real-time updates via WebSocket\n - Dirty state tracking\n-->\n<script setup lang=\"ts\">\nimport { Database, RefreshCw, Save, Trash2, X } from 'lucide-vue-next';\nimport { nextTick, onMounted, ref, watch } from 'vue';\n// biome-ignore lint/style/useImportType: Component needs to be available at runtime\nimport JsonEditor from '@/components/JsonEditor.vue';\nimport { useNotifications } from '@/composables/useNotifications';\nimport { useWebSocket } from '@/composables/useWebSocket';\nimport { useModelsStore } from '@/stores';\n\n// ==========================================================================\n// Store & Composables\n// ==========================================================================\n\nconst modelsStore = useModelsStore();\nconst { send, on, connected } = useWebSocket();\nconst { success, error: notifyError, confirm } = useNotifications();\n\n// ==========================================================================\n// State\n// ==========================================================================\n\n/** Reference to the JSON editor component */\nconst jsonEditorRef = ref<InstanceType<typeof JsonEditor> | null>(null);\n\n/** Confirmation dialog state */\nconst showClearConfirm = ref(false);\n\n// ==========================================================================\n// Lifecycle\n// ==========================================================================\n\nonMounted(async () => {\n // Load schemas on mount\n try {\n await modelsStore.fetchSchemas();\n\n // Select first schema if available\n if (modelsStore.schemas.length > 0 && !modelsStore.selectedSchema) {\n await modelsStore.selectSchemaByName(modelsStore.schemas[0].name);\n }\n } catch (err) {\n // Error is already set in the store, but ensure it's visible\n if (!modelsStore.error) {\n modelsStore.error = err instanceof Error ? err.message : 'Failed to load schemas';\n }\n }\n});\n\n// ==========================================================================\n// WebSocket Event Handlers\n// ==========================================================================\n\n// Handle store updates from WebSocket\non('store:updated', (data) => {\n // Validate payload structure\n const payload = data as any;\n if (\n typeof data !== 'object' ||\n data === null ||\n typeof payload.schema !== 'string' ||\n typeof payload.action !== 'string' ||\n typeof payload.count !== 'number'\n ) {\n console.warn('[ModelsPage] Invalid store:updated payload:', data);\n return;\n }\n\n modelsStore.handleStoreUpdate(data as { schema: string; action: string; count: number });\n});\n\n// Handle reseed completion\non('reseeded', (data) => {\n // Validate payload structure\n const payload = data as any;\n if (\n typeof data !== 'object' ||\n data === null ||\n typeof payload.success !== 'boolean' ||\n !Array.isArray(payload.schemas)\n ) {\n console.warn('[ModelsPage] Invalid reseeded payload:', data);\n return;\n }\n\n modelsStore.handleReseedComplete(data as { success: boolean; schemas: string[] });\n});\n\n// ==========================================================================\n// Watchers\n// ==========================================================================\n\n// Format JSON when schema changes\nwatch(\n () => modelsStore.selectedSchema,\n async () => {\n if (jsonEditorRef.value && modelsStore.currentItems.length > 0) {\n // Wait for next tick to ensure editor is updated\n await nextTick();\n jsonEditorRef.value?.formatJson();\n }\n },\n);\n\n// ==========================================================================\n// Actions\n// ==========================================================================\n\n/**\n * Select a schema and fetch its data\n */\nasync function selectSchema(schemaName: string): Promise<void> {\n if (modelsStore.isDirty) {\n const confirmed = await confirm(\n 'You have unsaved changes. Are you sure you want to switch schemas?',\n {\n title: 'Unsaved Changes',\n confirmText: 'Switch Schema',\n cancelText: 'Cancel',\n },\n );\n if (!confirmed) return;\n }\n\n await modelsStore.selectSchemaByName(schemaName);\n}\n\n/**\n * Save the current items to the server\n */\nasync function saveItems(): Promise<void> {\n if (!jsonEditorRef.value?.isValid) {\n notifyError('Cannot save invalid JSON. Please fix the errors first.');\n return;\n }\n\n const saved = await modelsStore.saveItems();\n if (saved) {\n success('Items saved successfully');\n } else {\n // Show error to user if save failed\n const errorMessage = modelsStore.error || 'Failed to save items';\n notifyError(errorMessage);\n }\n}\n\n/**\n * Discard changes and revert to original\n */\nasync function discardChanges(): Promise<void> {\n if (!modelsStore.isDirty) return;\n\n const confirmed = await confirm('Discard all changes and revert to saved data?', {\n title: 'Discard Changes',\n confirmText: 'Discard',\n cancelText: 'Cancel',\n });\n if (confirmed) {\n modelsStore.discardChanges();\n success('Changes discarded');\n }\n}\n\n/**\n * Clear all items for the current schema\n */\nasync function clearSchema(): Promise<void> {\n showClearConfirm.value = false;\n\n try {\n const cleared = await modelsStore.clearSchema();\n if (cleared) {\n success('Schema cleared successfully');\n } else {\n // Show error to user if clear failed\n const errorMessage = modelsStore.error || 'Failed to clear schema';\n notifyError(errorMessage);\n }\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Failed to clear schema';\n notifyError(errorMessage);\n }\n}\n\n/**\n * Trigger reseed via WebSocket\n */\nasync function reseedAll(): Promise<void> {\n if (!connected.value) {\n notifyError('WebSocket not connected. Cannot trigger reseed.');\n return;\n }\n\n const confirmed = await confirm(\n 'This will regenerate all seed data and replace existing items. Continue?',\n {\n title: 'Reseed All Schemas',\n confirmText: 'Reseed',\n cancelText: 'Cancel',\n },\n );\n if (!confirmed) return;\n\n send({ type: 'reseed' });\n success('Reseed command sent');\n}\n\n/**\n * Handle JSON editor value updates\n */\nfunction onJsonEditorUpdate(value: unknown): void {\n modelsStore.updateItems(value);\n}\n</script>\n\n<template>\n <div class=\"models-page\">\n <!-- Schema Sidebar -->\n <aside class=\"models-sidebar\">\n <div class=\"models-sidebar__header\">\n <Database :size=\"18\" />\n <span>Schemas</span>\n <span class=\"models-sidebar__badge\">{{ modelsStore.schemaCount }}</span>\n </div>\n\n <!-- Loading State -->\n <div v-if=\"modelsStore.loading && modelsStore.schemas.length === 0\" class=\"models-sidebar__loading\">\n <div class=\"spinner\" />\n <span>Loading...</span>\n </div>\n\n <!-- Schema List -->\n <div v-else class=\"models-sidebar__list\">\n <button\n v-for=\"schema in modelsStore.schemas\"\n :key=\"schema.name\"\n :class=\"[\n 'models-sidebar__item',\n { 'models-sidebar__item--active': modelsStore.selectedSchema === schema.name },\n ]\"\n @click=\"selectSchema(schema.name)\"\n >\n <span class=\"models-sidebar__name\">{{ schema.name }}</span>\n <span class=\"models-sidebar__count\">{{ schema.count }}</span>\n </button>\n </div>\n\n <!-- Footer Stats -->\n <div class=\"models-sidebar__footer\">\n <div class=\"models-sidebar__stat\">\n <span class=\"text-muted\">Total Items:</span>\n <span class=\"font-mono\">{{ modelsStore.totalItems }}</span>\n </div>\n </div>\n </aside>\n\n <!-- Data Panel -->\n <main class=\"models-content\">\n <template v-if=\"modelsStore.selectedSchema\">\n <!-- Toolbar -->\n <div class=\"models-toolbar\">\n <div class=\"models-toolbar__title\">\n <span class=\"font-mono\">{{ modelsStore.selectedSchema }}</span>\n <span class=\"text-muted\">({{ modelsStore.currentItems.length }} items)</span>\n <span\n v-if=\"modelsStore.isDirty\"\n class=\"models-toolbar__badge models-toolbar__badge--warning\"\n >\n Unsaved\n </span>\n </div>\n\n <div class=\"models-toolbar__actions\">\n <!-- Discard Button -->\n <button\n v-if=\"modelsStore.isDirty\"\n class=\"btn btn--ghost\"\n title=\"Discard changes\"\n @click=\"discardChanges\"\n >\n <X :size=\"16\" />\n <span>Discard</span>\n </button>\n\n <!-- Save Button -->\n <button\n :disabled=\"!modelsStore.isDirty || modelsStore.loading\"\n class=\"btn btn--primary\"\n title=\"Save changes\"\n @click=\"saveItems\"\n >\n <Save :size=\"16\" />\n <span>Save</span>\n </button>\n\n <!-- Clear Button -->\n <button\n class=\"btn btn--danger\"\n title=\"Clear all items\"\n @click=\"showClearConfirm = true\"\n >\n <Trash2 :size=\"16\" />\n <span>Clear</span>\n </button>\n\n <!-- Reseed Button -->\n <button\n :disabled=\"!connected\"\n class=\"btn btn--secondary\"\n title=\"Reseed all schemas with generated data\"\n @click=\"reseedAll\"\n >\n <RefreshCw :size=\"16\" />\n <span>Reseed All</span>\n </button>\n </div>\n </div>\n\n <!-- Error Display -->\n <div v-if=\"modelsStore.error\" class=\"models-error\">\n <span>⚠️ {{ modelsStore.error }}</span>\n </div>\n\n <!-- JSON Editor -->\n <div class=\"models-editor\">\n <JsonEditor\n ref=\"jsonEditorRef\"\n :model-value=\"modelsStore.currentItems\"\n :readonly=\"modelsStore.loading\"\n :min-height=\"400\"\n @update:model-value=\"onJsonEditorUpdate\"\n />\n </div>\n\n <!-- Loading Overlay -->\n <div v-if=\"modelsStore.loading\" class=\"models-loading-overlay\">\n <div class=\"spinner\" />\n <span>Loading...</span>\n </div>\n </template>\n\n <!-- Empty State or Error -->\n <div v-else class=\"empty-state\">\n <!-- Show error if present and no schema selected -->\n <div v-if=\"modelsStore.error\" class=\"models-error\">\n <span>⚠️ {{ modelsStore.error }}</span>\n </div>\n <template v-else>\n <Database :size=\"48\" class=\"empty-state__icon\" />\n <h3 class=\"empty-state__title\">Select a schema</h3>\n <p class=\"empty-state__description\">\n Choose a schema from the sidebar to view and edit its data.\n </p>\n </template>\n </div>\n </main>\n\n <!-- Clear Confirmation Modal -->\n <Teleport to=\"body\">\n <div v-if=\"showClearConfirm\" class=\"modal-overlay\" @click=\"showClearConfirm = false\">\n <div class=\"modal\" @click.stop>\n <div class=\"modal__header\">\n <h3>Clear Schema Data</h3>\n </div>\n <div class=\"modal__body\">\n <p>\n Are you sure you want to clear all items for\n <strong>{{ modelsStore.selectedSchema }}</strong>?\n </p>\n <p class=\"text-muted\">This action cannot be undone.</p>\n </div>\n <div class=\"modal__footer\">\n <button class=\"btn btn--ghost\" @click=\"showClearConfirm = false\">\n Cancel\n </button>\n <button class=\"btn btn--danger\" @click=\"clearSchema\">\n Clear Schema\n </button>\n </div>\n </div>\n </div>\n </Teleport>\n </div>\n</template>\n\n<style scoped>\n.models-page {\n display: grid;\n grid-template-columns: 240px 1fr;\n height: 100%;\n overflow: hidden;\n}\n\n/* Sidebar */\n.models-sidebar {\n display: flex;\n flex-direction: column;\n background-color: var(--devtools-surface);\n border-right: 1px solid var(--devtools-border);\n overflow: hidden;\n}\n\n.models-sidebar__header {\n display: flex;\n align-items: center;\n gap: var(--devtools-space-sm);\n padding: var(--devtools-space-md);\n font-weight: var(--font-weight-6);\n font-size: var(--font-size-1);\n border-bottom: 1px solid var(--devtools-border);\n}\n\n.models-sidebar__badge {\n margin-left: auto;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 20px;\n height: 20px;\n padding: 0 var(--devtools-space-xs);\n background-color: var(--devtools-primary);\n color: white;\n border-radius: var(--devtools-radius-sm);\n font-size: var(--font-size-0);\n font-weight: var(--font-weight-6);\n}\n\n.models-sidebar__loading {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--devtools-space-md);\n padding: var(--devtools-space-xl);\n color: var(--devtools-text-muted);\n}\n\n.models-sidebar__list {\n flex: 1;\n overflow-y: auto;\n padding: var(--devtools-space-xs);\n}\n\n.models-sidebar__item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n padding: var(--devtools-space-sm) var(--devtools-space-md);\n background: none;\n border: none;\n border-radius: var(--devtools-radius-sm);\n color: var(--devtools-text);\n font-family: var(--devtools-font-sans);\n font-size: var(--font-size-1);\n cursor: pointer;\n transition: background-color var(--devtools-transition-fast);\n}\n\n.models-sidebar__item:hover {\n background-color: var(--devtools-surface-elevated);\n}\n\n.models-sidebar__item--active {\n background-color: color-mix(in srgb, var(--devtools-primary) 15%, transparent);\n color: var(--devtools-primary);\n}\n\n.models-sidebar__name {\n font-family: var(--devtools-font-mono);\n}\n\n.models-sidebar__count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 24px;\n height: 20px;\n padding: 0 var(--devtools-space-xs);\n background-color: var(--devtools-surface-elevated);\n border-radius: var(--devtools-radius-sm);\n font-size: var(--font-size-0);\n color: var(--devtools-text-muted);\n}\n\n.models-sidebar__footer {\n padding: var(--devtools-space-md);\n border-top: 1px solid var(--devtools-border);\n}\n\n.models-sidebar__stat {\n display: flex;\n justify-content: space-between;\n font-size: var(--font-size-0);\n}\n\n/* Content Area */\n.models-content {\n position: relative;\n display: flex;\n flex-direction: column;\n padding: var(--devtools-space-md);\n overflow: hidden;\n}\n\n/* Toolbar */\n.models-toolbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--devtools-space-md);\n margin-bottom: var(--devtools-space-md);\n}\n\n.models-toolbar__title {\n display: flex;\n align-items: center;\n gap: var(--devtools-space-sm);\n font-size: var(--font-size-2);\n font-weight: var(--font-weight-6);\n}\n\n.models-toolbar__badge {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n border-radius: var(--devtools-radius-sm);\n font-size: var(--font-size-0);\n font-weight: var(--font-weight-5);\n}\n\n.models-toolbar__badge--warning {\n background-color: color-mix(in srgb, #f59e0b 20%, transparent);\n color: #f59e0b;\n}\n\n.models-toolbar__actions {\n display: flex;\n align-items: center;\n gap: var(--devtools-space-sm);\n}\n\n/* Error Display */\n.models-error {\n padding: var(--devtools-space-sm) var(--devtools-space-md);\n margin-bottom: var(--devtools-space-md);\n background-color: color-mix(in srgb, var(--devtools-error) 10%, transparent);\n border: 1px solid var(--devtools-error);\n border-radius: var(--devtools-radius-sm);\n color: var(--devtools-error);\n font-size: var(--font-size-0);\n}\n\n/* Editor */\n.models-editor {\n flex: 1;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n}\n\n/* Loading Overlay */\n.models-loading-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--devtools-space-md);\n background-color: color-mix(in srgb, var(--devtools-bg) 80%, transparent);\n backdrop-filter: blur(2px);\n z-index: 10;\n}\n\n/* Modal */\n.modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n background-color: rgba(0, 0, 0, 0.5);\n z-index: 1000;\n}\n\n.modal {\n min-width: 400px;\n background-color: var(--devtools-surface);\n border: 1px solid var(--devtools-border);\n border-radius: var(--devtools-radius-md);\n box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);\n}\n\n.modal__header {\n padding: var(--devtools-space-md);\n border-bottom: 1px solid var(--devtools-border);\n}\n\n.modal__header h3 {\n margin: 0;\n font-size: var(--font-size-2);\n font-weight: var(--font-weight-6);\n}\n\n.modal__body {\n padding: var(--devtools-space-md);\n}\n\n.modal__body p {\n margin: 0 0 var(--devtools-space-sm) 0;\n}\n\n.modal__body p:last-child {\n margin-bottom: 0;\n}\n\n.modal__footer {\n display: flex;\n justify-content: flex-end;\n gap: var(--devtools-space-sm);\n padding: var(--devtools-space-md);\n border-top: 1px solid var(--devtools-border);\n}\n\n/* Spinner */\n.spinner {\n width: 24px;\n height: 24px;\n border: 3px solid var(--devtools-border);\n border-top-color: var(--devtools-primary);\n border-radius: 50%;\n animation: spin 0.8s linear infinite;\n}\n\n@keyframes spin {\n to {\n transform: rotate(360deg);\n }\n}\n</style>\n"],"names":["CircleAlert","createLucideIcon","RefreshCw","Save","safeClone","value","toRaw","useModelsStore","defineStore","schemas","ref","selectedSchema","currentItems","originalItems","loading","error","currentSchema","computed","s","isDirtyFlag","isDirty","schemaCount","totalItems","sum","schema","fetchSchemas","response","data","err","selectSchemaByName","schemaName","fetchSchemaData","items","schemaIndex","updateItems","saveItems","errorData","result","clearSchema","discardChanges","refresh","reset","handleStoreUpdate","handleReseedComplete","props","__props","emit","__emit","text","validationError","isValid","lineCount","lineNumbers","_","i","initializeText","watch","currentParsed","handleInput","event","target","validateAndEmit","parsed","match","position","lines","line","column","formatJson","handleKeyDown","start","end","newText","__expose","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_hoisted_2","_hoisted_3","_Fragment","_renderList","lineNum","_hoisted_5","_hoisted_6","_hoisted_7","_createVNode","_unref","Check","_cache","_hoisted_8","AlertCircle","_hoisted_9","_hoisted_10","_toDisplayString","toasts","confirmDialog","reactive","timeouts","pendingResolve","toastIdCounter","generateToastId","addToast","type","message","duration","id","toast","timeoutId","removeToast","index","t","useNotifications","success","info","warning","confirm","options","resolve","closeConfirm","dismiss","clearAll","modelsStore","send","on","connected","useWebSocket","notifyError","jsonEditorRef","showClearConfirm","onMounted","payload","nextTick","selectSchema","errorMessage","reseedAll","onJsonEditorUpdate","Database","_hoisted_4","_normalizeClass","$event","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","_hoisted_15","_hoisted_16","_hoisted_17","_hoisted_18","_hoisted_19","X","Trash2","_hoisted_22","_hoisted_23","JsonEditor","_hoisted_24","_hoisted_25","_hoisted_26","_createBlock","_Teleport","_hoisted_27","_hoisted_28"],"mappings":"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","x_google_ignoreList":[0,1,2]}
@@ -1,7 +1,8 @@
1
1
  import { ref as $, computed as C, defineComponent as B, createElementBlock as l, openBlock as a, createVNode as p, createElementVNode as e, unref as i, normalizeClass as H, toDisplayString as _, createCommentVNode as m, createTextVNode as T, Fragment as w, renderList as M, withDirectives as de, createBlock as Y, resolveDynamicComponent as ee, vShow as re, onMounted as ue, onUnmounted as ce, watch as pe } from "vue";
2
- import { g as te, C as se, a as _e, S as X, X as Z, F as he, b as fe } from "./format-CE7KDbll.js";
3
- import { c as E, _ as P, u as ge, R as me } from "./main-AUiFaD93.js";
2
+ import { g as te, C as se, a as _e, S as X, F as he, b as fe } from "./format-mVjPq6hT.js";
3
+ import { c as E, _ as P, u as ge, R as me } from "./main-BxRf_QJn.js";
4
4
  import { defineStore as ve } from "pinia";
5
+ import { X as Z } from "./x-BkudkKl_.js";
5
6
  const U = E("code", [
6
7
  ["path", { d: "m16 18 6-6-6-6", key: "eg8j8" }],
7
8
  ["path", { d: "m8 6-6 6 6 6", key: "ppft3o" }]
@@ -658,8 +659,8 @@ const Se = E("tag", [
658
659
  ])
659
660
  ]));
660
661
  }
661
- }), Qt = /* @__PURE__ */ P(Tt, [["__scopeId", "data-v-bdd419e3"]]);
662
+ }), jt = /* @__PURE__ */ P(Tt, [["__scopeId", "data-v-bdd419e3"]]);
662
663
  export {
663
- Qt as default
664
+ jt as default
664
665
  };
665
- //# sourceMappingURL=RoutesPage-D7H_CupP.js.map
666
+ //# sourceMappingURL=RoutesPage-C2CUh7EQ.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"RoutesPage-D7H_CupP.js","sources":["../../../node_modules/.pnpm/lucide-vue-next@0.513.0_vue@3.5.27_typescript@5.9.3_/node_modules/lucide-vue-next/dist/esm/icons/code.js","../../../node_modules/.pnpm/lucide-vue-next@0.513.0_vue@3.5.27_typescript@5.9.3_/node_modules/lucide-vue-next/dist/esm/icons/file-json.js","../../../node_modules/.pnpm/lucide-vue-next@0.513.0_vue@3.5.27_typescript@5.9.3_/node_modules/lucide-vue-next/dist/esm/icons/lock.js","../../../node_modules/.pnpm/lucide-vue-next@0.513.0_vue@3.5.27_typescript@5.9.3_/node_modules/lucide-vue-next/dist/esm/icons/shield.js","../../../node_modules/.pnpm/lucide-vue-next@0.513.0_vue@3.5.27_typescript@5.9.3_/node_modules/lucide-vue-next/dist/esm/icons/sprout.js","../../../node_modules/.pnpm/lucide-vue-next@0.513.0_vue@3.5.27_typescript@5.9.3_/node_modules/lucide-vue-next/dist/esm/icons/tag.js","../src/stores/registry.ts","../src/components/EndpointDetail.vue","../src/components/EndpointList.vue","../src/pages/RoutesPage.vue"],"sourcesContent":["/**\n * @license lucide-vue-next v0.513.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Code = createLucideIcon(\"code\", [\n [\"path\", { d: \"m16 18 6-6-6-6\", key: \"eg8j8\" }],\n [\"path\", { d: \"m8 6-6 6 6 6\", key: \"ppft3o\" }]\n]);\n\nexport { Code as default };\n//# sourceMappingURL=code.js.map\n","/**\n * @license lucide-vue-next v0.513.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst FileJson = createLucideIcon(\"file-json\", [\n [\"path\", { d: \"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\", key: \"1rqfz7\" }],\n [\"path\", { d: \"M14 2v4a2 2 0 0 0 2 2h4\", key: \"tnqrlb\" }],\n [\n \"path\",\n { d: \"M10 12a1 1 0 0 0-1 1v1a1 1 0 0 1-1 1 1 1 0 0 1 1 1v1a1 1 0 0 0 1 1\", key: \"1oajmo\" }\n ],\n [\n \"path\",\n { d: \"M14 18a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1 1 1 0 0 1-1-1v-1a1 1 0 0 0-1-1\", key: \"mpwhp6\" }\n ]\n]);\n\nexport { FileJson as default };\n//# sourceMappingURL=file-json.js.map\n","/**\n * @license lucide-vue-next v0.513.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Lock = createLucideIcon(\"lock\", [\n [\"rect\", { width: \"18\", height: \"11\", x: \"3\", y: \"11\", rx: \"2\", ry: \"2\", key: \"1w4ew1\" }],\n [\"path\", { d: \"M7 11V7a5 5 0 0 1 10 0v4\", key: \"fwvmzm\" }]\n]);\n\nexport { Lock as default };\n//# sourceMappingURL=lock.js.map\n","/**\n * @license lucide-vue-next v0.513.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Shield = createLucideIcon(\"shield\", [\n [\n \"path\",\n {\n d: \"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z\",\n key: \"oel41y\"\n }\n ]\n]);\n\nexport { Shield as default };\n//# sourceMappingURL=shield.js.map\n","/**\n * @license lucide-vue-next v0.513.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Sprout = createLucideIcon(\"sprout\", [\n [\"path\", { d: \"M7 20h10\", key: \"e6iznv\" }],\n [\"path\", { d: \"M10 20c5.5-2.5.8-6.4 3-10\", key: \"161w41\" }],\n [\n \"path\",\n {\n d: \"M9.5 9.4c1.1.8 1.8 2.2 2.3 3.7-2 .4-3.5.4-4.8-.3-1.2-.6-2.3-1.9-3-4.2 2.8-.5 4.4 0 5.5.8z\",\n key: \"9gtqwd\"\n }\n ],\n [\n \"path\",\n {\n d: \"M14.1 6a7 7 0 0 0-1.1 4c1.9-.1 3.3-.6 4.3-1.4 1-1 1.6-2.3 1.7-4.6-2.7.1-4 1-4.9 2z\",\n key: \"bkxnd2\"\n }\n ]\n]);\n\nexport { Sprout as default };\n//# sourceMappingURL=sprout.js.map\n","/**\n * @license lucide-vue-next v0.513.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Tag = createLucideIcon(\"tag\", [\n [\n \"path\",\n {\n d: \"M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z\",\n key: \"vktsd0\"\n }\n ],\n [\"circle\", { cx: \"7.5\", cy: \"7.5\", r: \".5\", fill: \"currentColor\", key: \"kqv944\" }]\n]);\n\nexport { Tag as default };\n//# sourceMappingURL=tag.js.map\n","/**\n * Registry Store\n *\n * What: Pinia store for managing endpoint registry data\n * How: Fetches and caches endpoint data from the server via WebSocket\n * Why: Provides reactive access to endpoint data for the Routes Page\n *\n * @module stores/registry\n */\n\nimport { defineStore } from 'pinia';\nimport { computed, ref } from 'vue';\n\n/**\n * HTTP method type\n */\nexport type HttpMethod = 'get' | 'post' | 'put' | 'patch' | 'delete' | 'options' | 'head' | 'trace';\n\n/**\n * Security requirement from OpenAPI spec\n */\nexport interface SecurityRequirement {\n name: string;\n scopes: string[];\n}\n\n/**\n * Endpoint entry from the server\n */\nexport interface EndpointEntry {\n key: string;\n operationId: string;\n method: HttpMethod;\n path: string;\n summary?: string;\n description?: string;\n tags: string[];\n responseSchema?: string;\n hasHandler: boolean;\n hasSeed: boolean;\n security: SecurityRequirement[];\n}\n\n/**\n * Registry statistics\n */\nexport interface RegistryStats {\n totalEndpoints: number;\n withCustomHandler: number;\n totalSchemas: number;\n withCustomSeed: number;\n autoGenerated: number;\n}\n\n/**\n * Registry data from server\n */\nexport interface RegistryData {\n endpoints: EndpointEntry[];\n stats: RegistryStats;\n}\n\n/**\n * Grouped endpoints by tag\n */\nexport interface EndpointGroup {\n tag: string;\n endpoints: EndpointEntry[];\n isExpanded: boolean;\n}\n\n/**\n * Filter options for endpoints\n */\nexport interface EndpointFilter {\n methods: HttpMethod[];\n hasHandler: boolean | null;\n hasSeed: boolean | null;\n tags: string[];\n}\n\n/**\n * Registry store for endpoint data management\n *\n * Provides:\n * - Endpoint data storage and retrieval\n * - Grouping by tags\n * - Search and filter functionality\n * - Selected endpoint tracking\n */\nexport const useRegistryStore = defineStore('registry', () => {\n // ==========================================================================\n // State\n // ==========================================================================\n\n /** All endpoints from the server */\n const endpoints = ref<EndpointEntry[]>([]);\n\n /** Registry statistics */\n const stats = ref<RegistryStats>({\n totalEndpoints: 0,\n withCustomHandler: 0,\n totalSchemas: 0,\n withCustomSeed: 0,\n autoGenerated: 0,\n });\n\n /** Loading state */\n const isLoading = ref(false);\n\n /** Error state */\n const error = ref<string | null>(null);\n\n /** Search query */\n const searchQuery = ref('');\n\n /** Active filters */\n const filter = ref<EndpointFilter>({\n methods: [],\n hasHandler: null,\n hasSeed: null,\n tags: [],\n });\n\n /** Currently selected endpoint key */\n const selectedEndpointKey = ref<string | null>(null);\n\n /** Expanded tag groups */\n const expandedTags = ref<Set<string>>(new Set());\n\n // ==========================================================================\n // Getters / Computed\n // ==========================================================================\n\n /**\n * All unique tags from endpoints\n */\n const allTags = computed(() => {\n const tagSet = new Set<string>();\n for (const endpoint of endpoints.value) {\n for (const tag of endpoint.tags) {\n tagSet.add(tag);\n }\n }\n return Array.from(tagSet).sort();\n });\n\n /**\n * All unique response schemas\n */\n const allSchemas = computed(() => {\n const schemaSet = new Set<string>();\n for (const endpoint of endpoints.value) {\n if (endpoint.responseSchema) {\n schemaSet.add(endpoint.responseSchema);\n }\n }\n return Array.from(schemaSet).sort();\n });\n\n /**\n * Filtered endpoints based on search and filters\n */\n const filteredEndpoints = computed(() => {\n let result = endpoints.value;\n\n // Apply search query\n if (searchQuery.value.trim()) {\n const query = searchQuery.value.toLowerCase().trim();\n result = result.filter((endpoint) => {\n return (\n endpoint.path.toLowerCase().includes(query) ||\n endpoint.operationId.toLowerCase().includes(query) ||\n endpoint.summary?.toLowerCase().includes(query) ||\n endpoint.tags.some((tag) => tag.toLowerCase().includes(query))\n );\n });\n }\n\n // Apply method filter\n if (filter.value.methods.length > 0) {\n result = result.filter((endpoint) => filter.value.methods.includes(endpoint.method));\n }\n\n // Apply handler filter\n if (filter.value.hasHandler !== null) {\n result = result.filter((endpoint) => endpoint.hasHandler === filter.value.hasHandler);\n }\n\n // Apply seed filter\n if (filter.value.hasSeed !== null) {\n result = result.filter((endpoint) => endpoint.hasSeed === filter.value.hasSeed);\n }\n\n // Apply tag filter\n if (filter.value.tags.length > 0) {\n result = result.filter((endpoint) =>\n endpoint.tags.some((tag) => filter.value.tags.includes(tag)),\n );\n }\n\n return result;\n });\n\n /**\n * Endpoints grouped by tag\n *\n * Grouping logic (from PRD):\n * 1. By tags (if they exist in spec)\n * 2. Fallback: By response schema\n * 3. Final fallback: By first path segment\n */\n const groupedEndpoints = computed((): EndpointGroup[] => {\n const groups = new Map<string, EndpointEntry[]>();\n\n for (const endpoint of filteredEndpoints.value) {\n // Determine group key\n let groupKey: string;\n\n if (endpoint.tags.length > 0) {\n // Use first tag as group\n groupKey = endpoint.tags[0];\n } else if (endpoint.responseSchema) {\n // Fallback to response schema\n groupKey = endpoint.responseSchema;\n } else {\n // Final fallback: first path segment\n const segments = endpoint.path.split('/').filter(Boolean);\n groupKey = segments[0] || 'Other';\n }\n\n if (!groups.has(groupKey)) {\n groups.set(groupKey, []);\n }\n groups.get(groupKey)?.push(endpoint);\n }\n\n // Convert to array and sort\n return Array.from(groups.entries())\n .map(([tag, eps]) => ({\n tag,\n endpoints: eps.sort((a, b) => a.path.localeCompare(b.path)),\n isExpanded: expandedTags.value.has(tag),\n }))\n .sort((a, b) => a.tag.localeCompare(b.tag));\n });\n\n /**\n * Currently selected endpoint\n */\n const selectedEndpoint = computed(() => {\n if (!selectedEndpointKey.value) return null;\n return endpoints.value.find((e) => e.key === selectedEndpointKey.value) ?? null;\n });\n\n /**\n * Count of endpoints with custom handlers\n */\n const handlerCount = computed(() => endpoints.value.filter((e) => e.hasHandler).length);\n\n /**\n * Count of endpoints with seed data\n */\n const seedCount = computed(() => endpoints.value.filter((e) => e.hasSeed).length);\n\n // ==========================================================================\n // Actions\n // ==========================================================================\n\n /**\n * Set registry data from server response\n */\n function setRegistryData(data: RegistryData): void {\n endpoints.value = data.endpoints;\n stats.value = data.stats;\n error.value = null;\n\n // Auto-expand all groups initially\n for (const endpoint of data.endpoints) {\n if (endpoint.tags.length > 0) {\n expandedTags.value.add(endpoint.tags[0]);\n }\n }\n }\n\n /**\n * Set loading state\n */\n function setLoading(loading: boolean): void {\n isLoading.value = loading;\n }\n\n /**\n * Set error state\n */\n function setError(errorMessage: string): void {\n error.value = errorMessage;\n isLoading.value = false;\n }\n\n /**\n * Clear error state\n */\n function clearError(): void {\n error.value = null;\n }\n\n /**\n * Set search query\n */\n function setSearchQuery(query: string): void {\n searchQuery.value = query;\n }\n\n /**\n * Toggle method filter\n */\n function toggleMethodFilter(method: HttpMethod): void {\n const index = filter.value.methods.indexOf(method);\n if (index === -1) {\n filter.value.methods.push(method);\n } else {\n filter.value.methods.splice(index, 1);\n }\n }\n\n /**\n * Set handler filter\n */\n function setHandlerFilter(hasHandler: boolean | null): void {\n filter.value.hasHandler = hasHandler;\n }\n\n /**\n * Set seed filter\n */\n function setSeedFilter(hasSeed: boolean | null): void {\n filter.value.hasSeed = hasSeed;\n }\n\n /**\n * Toggle tag filter\n */\n function toggleTagFilter(tag: string): void {\n const index = filter.value.tags.indexOf(tag);\n if (index === -1) {\n filter.value.tags.push(tag);\n } else {\n filter.value.tags.splice(index, 1);\n }\n }\n\n /**\n * Clear all filters\n */\n function clearFilters(): void {\n filter.value = {\n methods: [],\n hasHandler: null,\n hasSeed: null,\n tags: [],\n };\n searchQuery.value = '';\n }\n\n /**\n * Check if any filter is active\n */\n function hasActiveFilters(): boolean {\n return (\n searchQuery.value.trim() !== '' ||\n filter.value.methods.length > 0 ||\n filter.value.hasHandler !== null ||\n filter.value.hasSeed !== null ||\n filter.value.tags.length > 0\n );\n }\n\n /**\n * Select an endpoint by key\n */\n function selectEndpoint(key: string | null): void {\n selectedEndpointKey.value = key;\n }\n\n /**\n * Toggle group expansion\n */\n function toggleGroup(tag: string): void {\n if (expandedTags.value.has(tag)) {\n expandedTags.value.delete(tag);\n } else {\n expandedTags.value.add(tag);\n }\n }\n\n /**\n * Expand all groups\n */\n function expandAllGroups(): void {\n for (const group of groupedEndpoints.value) {\n expandedTags.value.add(group.tag);\n }\n }\n\n /**\n * Collapse all groups\n */\n function collapseAllGroups(): void {\n expandedTags.value.clear();\n }\n\n /**\n * Update handler status for endpoints\n * Called when handlers are reloaded\n */\n function updateHandlerStatus(handlerOperationIds: string[]): void {\n const handlerSet = new Set(handlerOperationIds);\n for (const endpoint of endpoints.value) {\n endpoint.hasHandler = handlerSet.has(endpoint.operationId);\n }\n }\n\n /**\n * Update seed status for endpoints\n * Called when seeds are reloaded\n */\n function updateSeedStatus(seedSchemas: string[]): void {\n const seedSet = new Set(seedSchemas);\n for (const endpoint of endpoints.value) {\n endpoint.hasSeed = endpoint.responseSchema ? seedSet.has(endpoint.responseSchema) : false;\n }\n }\n\n // ==========================================================================\n // Return\n // ==========================================================================\n\n return {\n // State\n endpoints,\n stats,\n isLoading,\n error,\n searchQuery,\n filter,\n selectedEndpointKey,\n expandedTags,\n\n // Getters\n allTags,\n allSchemas,\n filteredEndpoints,\n groupedEndpoints,\n selectedEndpoint,\n handlerCount,\n seedCount,\n\n // Actions\n setRegistryData,\n setLoading,\n setError,\n clearError,\n setSearchQuery,\n toggleMethodFilter,\n setHandlerFilter,\n setSeedFilter,\n toggleTagFilter,\n clearFilters,\n hasActiveFilters,\n selectEndpoint,\n toggleGroup,\n expandAllGroups,\n collapseAllGroups,\n updateHandlerStatus,\n updateSeedStatus,\n };\n});\n","<!--\n EndpointDetail.vue - Endpoint Detail Panel Component\n\n What: Displays detailed information about a selected API endpoint\n How: Shows method, path, operation ID, tags, summary, description, and status indicators\n Why: Provides comprehensive endpoint information for developers using the DevTools\n-->\n\n<script setup lang=\"ts\">\nimport { Code, FileJson, Lock, Shield, Sprout, Tag } from 'lucide-vue-next';\nimport { computed } from 'vue';\n\nimport type { EndpointEntry } from '@/stores/registry';\nimport { getMethodLabel } from '@/utils/format';\n\n/**\n * Component props\n */\ninterface Props {\n /** Endpoint to display details for */\n endpoint: EndpointEntry | null;\n}\n\nconst props = defineProps<Props>();\n\n/**\n * Check if endpoint has security requirements\n */\nconst hasSecurity = computed(() => {\n return props.endpoint?.security && props.endpoint.security.length > 0;\n});\n\n/**\n * Format security requirements for display\n */\nconst securityDisplay = computed(() => {\n if (!props.endpoint?.security) return [];\n return props.endpoint.security.map((sec) => ({\n name: sec.name,\n scopes: sec.scopes.length > 0 ? sec.scopes.join(', ') : 'No scopes',\n }));\n});\n</script>\n\n<template>\n <div class=\"endpoint-detail\">\n <!-- Empty state when no endpoint selected -->\n <div v-if=\"!endpoint\" class=\"endpoint-detail__empty\">\n <FileJson :size=\"48\" class=\"endpoint-detail__empty-icon\" />\n <h3 class=\"endpoint-detail__empty-title\">No endpoint selected</h3>\n <p class=\"endpoint-detail__empty-text text-muted\">\n Select an endpoint from the list to view its details\n </p>\n </div>\n\n <!-- Endpoint details -->\n <div v-else class=\"endpoint-detail__content\">\n <!-- Header with method and path -->\n <header class=\"endpoint-detail__header\">\n <span\n :class=\"[\n 'method-badge',\n 'method-badge--large',\n `method-badge--${endpoint.method}`\n ]\"\n >\n {{ getMethodLabel(endpoint.method) }}\n </span>\n <h2 class=\"endpoint-detail__path font-mono\">\n {{ endpoint.path }}\n </h2>\n </header>\n\n <!-- Status indicators -->\n <div class=\"endpoint-detail__status\">\n <div\n v-if=\"endpoint.hasHandler\"\n class=\"endpoint-detail__status-item endpoint-detail__status-item--handler\"\n >\n <Code :size=\"14\" />\n <span>Has custom handler</span>\n </div>\n <div\n v-if=\"endpoint.hasSeed\"\n class=\"endpoint-detail__status-item endpoint-detail__status-item--seed\"\n >\n <Sprout :size=\"14\" />\n <span>Has seed data</span>\n </div>\n <div\n v-if=\"hasSecurity\"\n class=\"endpoint-detail__status-item endpoint-detail__status-item--security\"\n >\n <Lock :size=\"14\" />\n <span>Requires authentication</span>\n </div>\n <div\n v-if=\"!endpoint.hasHandler && !endpoint.hasSeed\"\n class=\"endpoint-detail__status-item endpoint-detail__status-item--auto\"\n >\n <FileJson :size=\"14\" />\n <span>Auto-generated response</span>\n </div>\n </div>\n\n <!-- Info sections -->\n <div class=\"endpoint-detail__sections\">\n <!-- Operation ID -->\n <section class=\"endpoint-detail__section\">\n <h3 class=\"endpoint-detail__section-title\">Operation</h3>\n <p class=\"endpoint-detail__section-content font-mono\">\n {{ endpoint.operationId }}\n </p>\n </section>\n\n <!-- Tags -->\n <section v-if=\"endpoint.tags.length > 0\" class=\"endpoint-detail__section\">\n <h3 class=\"endpoint-detail__section-title\">\n <Tag :size=\"14\" />\n Tags\n </h3>\n <div class=\"endpoint-detail__tags\">\n <span\n v-for=\"tag in endpoint.tags\"\n :key=\"tag\"\n class=\"endpoint-detail__tag\"\n >\n {{ tag }}\n </span>\n </div>\n </section>\n\n <!-- Summary -->\n <section v-if=\"endpoint.summary\" class=\"endpoint-detail__section\">\n <h3 class=\"endpoint-detail__section-title\">Summary</h3>\n <p class=\"endpoint-detail__section-content\">\n {{ endpoint.summary }}\n </p>\n </section>\n\n <!-- Description -->\n <section v-if=\"endpoint.description\" class=\"endpoint-detail__section\">\n <h3 class=\"endpoint-detail__section-title\">Description</h3>\n <p class=\"endpoint-detail__section-content endpoint-detail__description\">\n {{ endpoint.description }}\n </p>\n </section>\n\n <!-- Response Schema -->\n <section v-if=\"endpoint.responseSchema\" class=\"endpoint-detail__section\">\n <h3 class=\"endpoint-detail__section-title\">\n <FileJson :size=\"14\" />\n Response Schema\n </h3>\n <p class=\"endpoint-detail__section-content font-mono\">\n {{ endpoint.responseSchema }}\n </p>\n </section>\n\n <!-- Security -->\n <section v-if=\"hasSecurity\" class=\"endpoint-detail__section\">\n <h3 class=\"endpoint-detail__section-title\">\n <Shield :size=\"14\" />\n Security\n </h3>\n <div class=\"endpoint-detail__security\">\n <div\n v-for=\"sec in securityDisplay\"\n :key=\"sec.name\"\n class=\"endpoint-detail__security-item\"\n >\n <span class=\"endpoint-detail__security-name font-mono\">\n {{ sec.name }}\n </span>\n <span class=\"endpoint-detail__security-scopes text-muted\">\n {{ sec.scopes }}\n </span>\n </div>\n </div>\n </section>\n </div>\n </div>\n </div>\n</template>\n\n<style scoped>\n.endpoint-detail {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n}\n\n/* Empty state */\n.endpoint-detail__empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n padding: var(--devtools-space-xl);\n text-align: center;\n}\n\n.endpoint-detail__empty-icon {\n color: var(--devtools-text-muted);\n opacity: 0.5;\n margin-bottom: var(--devtools-space-md);\n}\n\n.endpoint-detail__empty-title {\n font-size: var(--font-size-2);\n font-weight: var(--font-weight-5);\n color: var(--devtools-text);\n margin: 0 0 var(--devtools-space-sm);\n}\n\n.endpoint-detail__empty-text {\n font-size: var(--font-size-1);\n margin: 0;\n}\n\n/* Content */\n.endpoint-detail__content {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow-y: auto;\n padding: var(--devtools-space-md);\n}\n\n/* Header */\n.endpoint-detail__header {\n display: flex;\n align-items: center;\n gap: var(--devtools-space-md);\n margin-bottom: var(--devtools-space-md);\n padding-bottom: var(--devtools-space-md);\n border-bottom: 1px solid var(--devtools-border);\n}\n\n.endpoint-detail__path {\n font-size: var(--font-size-2);\n font-weight: var(--font-weight-5);\n color: var(--devtools-text);\n margin: 0;\n word-break: break-all;\n}\n\n/* Large method badge */\n.method-badge--large {\n font-size: var(--font-size-0);\n padding: var(--devtools-space-sm) var(--devtools-space-md);\n min-width: 70px;\n}\n\n/* Status indicators */\n.endpoint-detail__status {\n display: flex;\n flex-wrap: wrap;\n gap: var(--devtools-space-sm);\n margin-bottom: var(--devtools-space-md);\n}\n\n.endpoint-detail__status-item {\n display: inline-flex;\n align-items: center;\n gap: var(--devtools-space-xs);\n padding: var(--devtools-space-xs) var(--devtools-space-sm);\n border-radius: var(--devtools-radius-sm);\n font-size: var(--font-size-0);\n font-weight: var(--font-weight-5);\n}\n\n.endpoint-detail__status-item--handler {\n background-color: color-mix(in srgb, var(--devtools-info) 15%, transparent);\n color: var(--devtools-info);\n}\n\n.endpoint-detail__status-item--seed {\n background-color: color-mix(in srgb, var(--devtools-success) 15%, transparent);\n color: var(--devtools-success);\n}\n\n.endpoint-detail__status-item--security {\n background-color: color-mix(in srgb, var(--devtools-warning) 15%, transparent);\n color: var(--devtools-warning);\n}\n\n.endpoint-detail__status-item--auto {\n background-color: color-mix(in srgb, var(--devtools-text-muted) 15%, transparent);\n color: var(--devtools-text-muted);\n}\n\n/* Sections */\n.endpoint-detail__sections {\n display: flex;\n flex-direction: column;\n gap: var(--devtools-space-md);\n}\n\n.endpoint-detail__section {\n display: flex;\n flex-direction: column;\n gap: var(--devtools-space-xs);\n}\n\n.endpoint-detail__section-title {\n display: flex;\n align-items: center;\n gap: var(--devtools-space-xs);\n font-size: var(--font-size-0);\n font-weight: var(--font-weight-6);\n color: var(--devtools-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n margin: 0;\n}\n\n.endpoint-detail__section-content {\n font-size: var(--font-size-1);\n color: var(--devtools-text);\n margin: 0;\n line-height: var(--font-lineheight-3);\n}\n\n.endpoint-detail__description {\n white-space: pre-wrap;\n}\n\n/* Tags */\n.endpoint-detail__tags {\n display: flex;\n flex-wrap: wrap;\n gap: var(--devtools-space-xs);\n}\n\n.endpoint-detail__tag {\n display: inline-flex;\n align-items: center;\n padding: var(--devtools-space-xs) var(--devtools-space-sm);\n background-color: var(--devtools-surface-elevated);\n border-radius: var(--devtools-radius-sm);\n font-size: var(--font-size-0);\n color: var(--devtools-text);\n}\n\n/* Security */\n.endpoint-detail__security {\n display: flex;\n flex-direction: column;\n gap: var(--devtools-space-xs);\n}\n\n.endpoint-detail__security-item {\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding: var(--devtools-space-sm);\n background-color: var(--devtools-surface-elevated);\n border-radius: var(--devtools-radius-sm);\n}\n\n.endpoint-detail__security-name {\n font-size: var(--font-size-1);\n font-weight: var(--font-weight-5);\n}\n\n.endpoint-detail__security-scopes {\n font-size: var(--font-size-0);\n}\n</style>\n","<!--\n EndpointList.vue - Grouped Endpoint Listing Component\n\n What: Displays a list of API endpoints grouped by tags with collapsible sections\n How: Renders endpoint groups from registry store with method badges and selection support\n Why: Provides organized navigation through available mock endpoints\n-->\n\n<script setup lang=\"ts\">\nimport { ChevronDown, ChevronRight, Code, Sprout } from 'lucide-vue-next';\n\nimport type { EndpointEntry, EndpointGroup } from '@/stores/registry';\nimport { getMethodLabel } from '@/utils/format';\n\n/**\n * Component props\n */\ninterface Props {\n /** Grouped endpoints to display */\n groups: EndpointGroup[];\n /** Currently selected endpoint key */\n selectedKey: string | null;\n}\n\nconst props = defineProps<Props>();\n\n/**\n * Component events\n */\nconst emit = defineEmits<{\n /** Emitted when an endpoint is selected */\n (e: 'select', key: string): void;\n /** Emitted when a group is toggled */\n (e: 'toggle-group', tag: string): void;\n}>();\n\n/**\n * Handle endpoint click\n */\nfunction handleEndpointClick(endpoint: EndpointEntry): void {\n emit('select', endpoint.key);\n}\n\n/**\n * Handle group toggle\n */\nfunction handleGroupToggle(tag: string): void {\n emit('toggle-group', tag);\n}\n\n/**\n * Check if endpoint is selected\n */\nfunction isSelected(endpoint: EndpointEntry): boolean {\n return props.selectedKey === endpoint.key;\n}\n</script>\n\n<template>\n <div class=\"endpoint-list\">\n <!-- Empty state -->\n <div v-if=\"groups.length === 0\" class=\"endpoint-list__empty\">\n <p class=\"text-muted\">No endpoints found</p>\n </div>\n\n <!-- Endpoint groups -->\n <div v-else class=\"endpoint-list__groups\">\n <div\n v-for=\"group in groups\"\n :key=\"group.tag\"\n class=\"endpoint-group\"\n >\n <!-- Group header -->\n <button\n type=\"button\"\n class=\"endpoint-group__header\"\n :aria-expanded=\"group.isExpanded\"\n :aria-controls=\"`group-${group.tag}`\"\n @click=\"handleGroupToggle(group.tag)\"\n >\n <component\n :is=\"group.isExpanded ? ChevronDown : ChevronRight\"\n :size=\"16\"\n class=\"endpoint-group__chevron\"\n />\n <span class=\"endpoint-group__tag\">{{ group.tag }}</span>\n <span class=\"endpoint-group__count text-muted\">\n ({{ group.endpoints.length }})\n </span>\n </button>\n\n <!-- Group endpoints -->\n <div\n v-show=\"group.isExpanded\"\n :id=\"`group-${group.tag}`\"\n class=\"endpoint-group__items\"\n role=\"group\"\n :aria-label=\"`${group.tag} endpoints`\"\n >\n <button\n v-for=\"endpoint in group.endpoints\"\n :key=\"endpoint.key\"\n type=\"button\"\n :class=\"[\n 'endpoint-item',\n { 'endpoint-item--selected': isSelected(endpoint) }\n ]\"\n :aria-selected=\"isSelected(endpoint)\"\n @click=\"handleEndpointClick(endpoint)\"\n >\n <!-- Method badge -->\n <span\n :class=\"[\n 'method-badge',\n `method-badge--${endpoint.method}`\n ]\"\n >\n {{ getMethodLabel(endpoint.method) }}\n </span>\n\n <!-- Path -->\n <span class=\"endpoint-item__path font-mono\">\n {{ endpoint.path }}\n </span>\n\n <!-- Status indicators -->\n <div class=\"endpoint-item__indicators\">\n <span\n v-if=\"endpoint.hasHandler\"\n class=\"endpoint-item__indicator endpoint-item__indicator--handler\"\n title=\"Has custom handler\"\n >\n <Code :size=\"12\" />\n </span>\n <span\n v-if=\"endpoint.hasSeed\"\n class=\"endpoint-item__indicator endpoint-item__indicator--seed\"\n title=\"Has seed data\"\n >\n <Sprout :size=\"12\" />\n </span>\n </div>\n </button>\n </div>\n </div>\n </div>\n </div>\n</template>\n\n<style scoped>\n.endpoint-list {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n}\n\n.endpoint-list__empty {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: var(--devtools-space-lg);\n}\n\n.endpoint-list__groups {\n flex: 1;\n overflow-y: auto;\n padding: var(--devtools-space-xs);\n}\n\n/* Group styles */\n.endpoint-group {\n margin-bottom: var(--devtools-space-xs);\n}\n\n.endpoint-group__header {\n display: flex;\n align-items: center;\n gap: var(--devtools-space-xs);\n width: 100%;\n padding: var(--devtools-space-sm) var(--devtools-space-sm);\n background: none;\n border: none;\n border-radius: var(--devtools-radius-sm);\n font-family: var(--devtools-font-sans);\n font-size: var(--font-size-1);\n font-weight: var(--font-weight-5);\n color: var(--devtools-text);\n text-align: left;\n cursor: pointer;\n transition: background-color var(--devtools-transition-fast);\n}\n\n.endpoint-group__header:hover {\n background-color: var(--devtools-surface-elevated);\n}\n\n.endpoint-group__header:focus {\n outline: none;\n}\n\n.endpoint-group__header:focus-visible {\n outline: 2px solid var(--devtools-primary);\n outline-offset: -2px;\n}\n\n.endpoint-group__chevron {\n flex-shrink: 0;\n color: var(--devtools-text-muted);\n}\n\n.endpoint-group__tag {\n flex: 1;\n text-transform: capitalize;\n}\n\n.endpoint-group__count {\n font-size: var(--font-size-0);\n font-weight: var(--font-weight-4);\n}\n\n.endpoint-group__items {\n padding-left: var(--devtools-space-md);\n}\n\n/* Endpoint item styles */\n.endpoint-item {\n display: flex;\n align-items: center;\n gap: var(--devtools-space-sm);\n width: 100%;\n padding: var(--devtools-space-xs) var(--devtools-space-sm);\n background: none;\n border: none;\n border-radius: var(--devtools-radius-sm);\n font-family: var(--devtools-font-sans);\n text-align: left;\n cursor: pointer;\n transition: background-color var(--devtools-transition-fast);\n}\n\n.endpoint-item:hover {\n background-color: var(--devtools-surface-elevated);\n}\n\n.endpoint-item:focus {\n outline: none;\n}\n\n.endpoint-item:focus-visible {\n outline: 2px solid var(--devtools-primary);\n outline-offset: -2px;\n}\n\n.endpoint-item--selected {\n background-color: color-mix(in srgb, var(--devtools-primary) 15%, transparent);\n}\n\n.endpoint-item--selected:hover {\n background-color: color-mix(in srgb, var(--devtools-primary) 20%, transparent);\n}\n\n.endpoint-item__path {\n flex: 1;\n font-size: var(--font-size-0);\n color: var(--devtools-text);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.endpoint-item__indicators {\n display: flex;\n align-items: center;\n gap: var(--devtools-space-xs);\n}\n\n.endpoint-item__indicator {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 18px;\n height: 18px;\n border-radius: var(--devtools-radius-sm);\n}\n\n.endpoint-item__indicator--handler {\n background-color: color-mix(in srgb, var(--devtools-info) 15%, transparent);\n color: var(--devtools-info);\n}\n\n.endpoint-item__indicator--seed {\n background-color: color-mix(in srgb, var(--devtools-success) 15%, transparent);\n color: var(--devtools-success);\n}\n</style>\n","<!--\n RoutesPage.vue - Endpoint Listing Page\n\n What: Displays a list of all available API endpoints from the OpenAPI spec\n How: Fetches endpoint data via WebSocket and displays in a searchable/filterable list\n Why: Allows developers to quickly browse and inspect available mock endpoints\n-->\n\n<script setup lang=\"ts\">\nimport { ChevronDown, ChevronUp, Code, Filter, Route, Search, Sprout, X } from 'lucide-vue-next';\nimport { computed, onMounted, onUnmounted, ref, watch } from 'vue';\n\nimport EndpointDetail from '@/components/EndpointDetail.vue';\nimport EndpointList from '@/components/EndpointList.vue';\nimport { useWebSocket } from '@/composables/useWebSocket';\nimport { type HttpMethod, type RegistryData, useRegistryStore } from '@/stores/registry';\n\n// Store and WebSocket\nconst registryStore = useRegistryStore();\nconst { send, on, connected } = useWebSocket();\n\n// Local UI state\nconst showFilters = ref(false);\nconst searchInputRef = ref<HTMLInputElement | null>(null);\n\n// HTTP methods for filter (matches HttpMethod type from registry store)\nconst httpMethods: HttpMethod[] = [\n 'get',\n 'post',\n 'put',\n 'patch',\n 'delete',\n 'options',\n 'head',\n 'trace',\n];\n\n/**\n * Fetch registry data when connected\n */\nfunction fetchRegistry(): void {\n if (connected.value) {\n registryStore.setLoading(true);\n send({ type: 'get:registry' });\n }\n}\n\n/**\n * Handle registry data from server\n */\nfunction handleRegistryData(data: RegistryData): void {\n registryStore.setRegistryData(data);\n registryStore.setLoading(false);\n}\n\n/**\n * Handle endpoint selection\n */\nfunction handleSelectEndpoint(key: string): void {\n registryStore.selectEndpoint(key);\n}\n\n/**\n * Handle group toggle\n */\nfunction handleToggleGroup(tag: string): void {\n registryStore.toggleGroup(tag);\n}\n\n/**\n * Handle search input\n */\nfunction handleSearchInput(event: Event): void {\n const target = event.target as HTMLInputElement;\n registryStore.setSearchQuery(target.value);\n}\n\n/**\n * Clear search\n */\nfunction clearSearch(): void {\n registryStore.setSearchQuery('');\n searchInputRef.value?.focus();\n}\n\n/**\n * Toggle method filter\n */\nfunction toggleMethod(method: HttpMethod): void {\n registryStore.toggleMethodFilter(method);\n}\n\n/**\n * Check if method is active in filter\n */\nfunction isMethodActive(method: HttpMethod): boolean {\n return registryStore.filter.methods.includes(method);\n}\n\n/**\n * Toggle handler filter\n */\nfunction toggleHandlerFilter(): void {\n const current = registryStore.filter.hasHandler;\n registryStore.setHandlerFilter(current === true ? null : true);\n}\n\n/**\n * Toggle seed filter\n */\nfunction toggleSeedFilter(): void {\n const current = registryStore.filter.hasSeed;\n registryStore.setSeedFilter(current === true ? null : true);\n}\n\n/**\n * Clear all filters\n */\nfunction clearAllFilters(): void {\n registryStore.clearFilters();\n}\n\n/**\n * Toggle filter panel visibility\n */\nfunction toggleFilters(): void {\n showFilters.value = !showFilters.value;\n}\n\n/**\n * Computed: Has active filters\n */\nconst hasActiveFilters = computed(() => registryStore.hasActiveFilters());\n\n// Event cleanup functions for WebSocket subscriptions\nlet unsubRegistry: (() => void) | null = null;\nlet unsubHandlers: (() => void) | null = null;\nlet unsubSeeds: (() => void) | null = null;\n\n// Subscribe to registry events and setup cleanup\nonMounted(() => {\n // Subscribe to WebSocket events (on() returns unsubscribe function)\n unsubRegistry = on<RegistryData>('registry', handleRegistryData);\n unsubHandlers = on('handlers:updated', () => fetchRegistry());\n unsubSeeds = on('seeds:updated', () => fetchRegistry());\n\n // Fetch registry when already connected\n if (connected.value) {\n fetchRegistry();\n }\n});\n\n// Cleanup event subscriptions on unmount to prevent memory leaks\nonUnmounted(() => {\n unsubRegistry?.();\n unsubHandlers?.();\n unsubSeeds?.();\n});\n\n// Re-fetch when connection is established\nwatch(connected, (isConnected) => {\n if (isConnected) {\n fetchRegistry();\n }\n});\n</script>\n\n<template>\n <div class=\"routes-page\">\n <!-- Toolbar -->\n <div class=\"routes-toolbar\">\n <!-- Search -->\n <div class=\"routes-search\">\n <Search :size=\"16\" class=\"routes-search__icon\" />\n <input\n ref=\"searchInputRef\"\n type=\"text\"\n class=\"routes-search__input input\"\n placeholder=\"Search endpoints...\"\n :value=\"registryStore.searchQuery\"\n @input=\"handleSearchInput\"\n />\n <button\n v-if=\"registryStore.searchQuery\"\n type=\"button\"\n class=\"routes-search__clear btn btn--ghost btn--icon\"\n title=\"Clear search\"\n @click=\"clearSearch\"\n >\n <X :size=\"14\" />\n </button>\n </div>\n\n <!-- Filter toggle -->\n <button\n type=\"button\"\n :class=\"[\n 'routes-filter-toggle btn btn--secondary',\n { 'routes-filter-toggle--active': hasActiveFilters }\n ]\"\n :aria-expanded=\"showFilters\"\n @click=\"toggleFilters\"\n >\n <Filter :size=\"16\" />\n <span>Filters</span>\n <span v-if=\"hasActiveFilters\" class=\"routes-filter-toggle__badge\">\n {{ registryStore.filter.methods.length +\n (registryStore.filter.hasHandler ? 1 : 0) +\n (registryStore.filter.hasSeed ? 1 : 0) }}\n </span>\n <component :is=\"showFilters ? ChevronUp : ChevronDown\" :size=\"14\" />\n </button>\n\n <!-- Stats -->\n <div class=\"routes-stats\">\n <span class=\"routes-stats__item\">\n {{ registryStore.filteredEndpoints.length }} endpoints\n </span>\n <span class=\"routes-stats__separator\">|</span>\n <span class=\"routes-stats__item\">\n {{ registryStore.allTags.length }} tags\n </span>\n </div>\n </div>\n\n <!-- Filter panel -->\n <div v-if=\"showFilters\" class=\"routes-filters\">\n <!-- Method filters -->\n <div class=\"routes-filters__section\">\n <h4 class=\"routes-filters__title\">Methods</h4>\n <div class=\"routes-filters__methods\">\n <button\n v-for=\"method in httpMethods\"\n :key=\"method\"\n type=\"button\"\n :class=\"[\n 'method-badge',\n `method-badge--${method}`,\n { 'method-badge--inactive': !isMethodActive(method) && registryStore.filter.methods.length > 0 }\n ]\"\n @click=\"toggleMethod(method)\"\n >\n {{ method.toUpperCase() }}\n </button>\n </div>\n </div>\n\n <!-- Status filters -->\n <div class=\"routes-filters__section\">\n <h4 class=\"routes-filters__title\">Status</h4>\n <div class=\"routes-filters__status\">\n <button\n type=\"button\"\n :class=\"[\n 'routes-filters__status-btn',\n { 'routes-filters__status-btn--active': registryStore.filter.hasHandler }\n ]\"\n @click=\"toggleHandlerFilter\"\n >\n <Code :size=\"14\" />\n <span>Has Handler</span>\n </button>\n <button\n type=\"button\"\n :class=\"[\n 'routes-filters__status-btn',\n { 'routes-filters__status-btn--active': registryStore.filter.hasSeed }\n ]\"\n @click=\"toggleSeedFilter\"\n >\n <Sprout :size=\"14\" />\n <span>Has Seed</span>\n </button>\n </div>\n </div>\n\n <!-- Clear filters -->\n <div v-if=\"hasActiveFilters\" class=\"routes-filters__actions\">\n <button\n type=\"button\"\n class=\"btn btn--ghost\"\n @click=\"clearAllFilters\"\n >\n <X :size=\"14\" />\n Clear all filters\n </button>\n </div>\n </div>\n\n <!-- Main content: split panel -->\n <div class=\"routes-content\">\n <!-- Loading state -->\n <div v-if=\"registryStore.isLoading\" class=\"routes-loading\">\n <div class=\"routes-loading__spinner\" />\n <span class=\"text-muted\">Loading endpoints...</span>\n </div>\n\n <!-- Error state -->\n <div v-else-if=\"registryStore.error\" class=\"routes-error\">\n <p class=\"routes-error__message\">{{ registryStore.error }}</p>\n <button type=\"button\" class=\"btn btn--primary\" @click=\"fetchRegistry\">\n Retry\n </button>\n </div>\n\n <!-- Empty state -->\n <div v-else-if=\"registryStore.endpoints.length === 0\" class=\"routes-empty empty-state\">\n <Route :size=\"48\" class=\"empty-state__icon\" />\n <h3 class=\"empty-state__title\">No endpoints found</h3>\n <p class=\"empty-state__description\">\n No API endpoints are available. Make sure your OpenAPI spec is loaded.\n </p>\n </div>\n\n <!-- No results state -->\n <div v-else-if=\"registryStore.filteredEndpoints.length === 0\" class=\"routes-empty empty-state\">\n <Search :size=\"48\" class=\"empty-state__icon\" />\n <h3 class=\"empty-state__title\">No matching endpoints</h3>\n <p class=\"empty-state__description\">\n Try adjusting your search or filters.\n </p>\n <button\n v-if=\"hasActiveFilters\"\n type=\"button\"\n class=\"btn btn--secondary\"\n @click=\"clearAllFilters\"\n >\n Clear filters\n </button>\n </div>\n\n <!-- Split panel layout -->\n <template v-else>\n <!-- Endpoint list panel -->\n <div class=\"routes-list-panel\">\n <EndpointList\n :groups=\"registryStore.groupedEndpoints\"\n :selected-key=\"registryStore.selectedEndpointKey\"\n @select=\"handleSelectEndpoint\"\n @toggle-group=\"handleToggleGroup\"\n />\n </div>\n\n <!-- Endpoint detail panel -->\n <div class=\"routes-detail-panel\">\n <EndpointDetail :endpoint=\"registryStore.selectedEndpoint\" />\n </div>\n </template>\n </div>\n </div>\n</template>\n\n<style scoped>\n.routes-page {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n}\n\n/* Toolbar */\n.routes-toolbar {\n display: flex;\n align-items: center;\n gap: var(--devtools-space-md);\n padding: var(--devtools-space-md);\n background-color: var(--devtools-surface);\n border-bottom: 1px solid var(--devtools-border);\n}\n\n.routes-search {\n position: relative;\n flex: 1;\n max-width: 400px;\n}\n\n.routes-search__icon {\n position: absolute;\n left: var(--devtools-space-sm);\n top: 50%;\n transform: translateY(-50%);\n color: var(--devtools-text-muted);\n pointer-events: none;\n}\n\n.routes-search__input {\n padding-left: calc(var(--devtools-space-sm) + 24px);\n padding-right: calc(var(--devtools-space-sm) + 24px);\n}\n\n.routes-search__clear {\n position: absolute;\n right: var(--devtools-space-xs);\n top: 50%;\n transform: translateY(-50%);\n padding: var(--devtools-space-xs);\n}\n\n.routes-filter-toggle {\n flex-shrink: 0;\n}\n\n.routes-filter-toggle--active {\n background-color: color-mix(in srgb, var(--devtools-primary) 15%, transparent);\n border-color: var(--devtools-primary);\n color: var(--devtools-primary);\n}\n\n.routes-filter-toggle__badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 var(--devtools-space-xs);\n background-color: var(--devtools-primary);\n color: var(--devtools-text-inverted);\n border-radius: 9px;\n font-size: var(--font-size-0);\n font-weight: var(--font-weight-6);\n}\n\n.routes-stats {\n display: flex;\n align-items: center;\n gap: var(--devtools-space-sm);\n margin-left: auto;\n font-size: var(--font-size-0);\n color: var(--devtools-text-muted);\n}\n\n.routes-stats__separator {\n opacity: 0.5;\n}\n\n/* Filter panel */\n.routes-filters {\n display: flex;\n flex-wrap: wrap;\n align-items: flex-start;\n gap: var(--devtools-space-lg);\n padding: var(--devtools-space-md);\n background-color: var(--devtools-surface-elevated);\n border-bottom: 1px solid var(--devtools-border);\n}\n\n.routes-filters__section {\n display: flex;\n flex-direction: column;\n gap: var(--devtools-space-sm);\n}\n\n.routes-filters__title {\n font-size: var(--font-size-0);\n font-weight: var(--font-weight-6);\n color: var(--devtools-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n margin: 0;\n}\n\n.routes-filters__methods {\n display: flex;\n flex-wrap: wrap;\n gap: var(--devtools-space-xs);\n}\n\n.routes-filters__methods .method-badge {\n cursor: pointer;\n transition: all var(--devtools-transition-fast);\n}\n\n.routes-filters__methods .method-badge--inactive {\n opacity: 0.4;\n}\n\n.routes-filters__status {\n display: flex;\n gap: var(--devtools-space-sm);\n}\n\n.routes-filters__status-btn {\n display: inline-flex;\n align-items: center;\n gap: var(--devtools-space-xs);\n padding: var(--devtools-space-xs) var(--devtools-space-sm);\n background-color: var(--devtools-surface);\n border: 1px solid var(--devtools-border);\n border-radius: var(--devtools-radius-sm);\n font-family: var(--devtools-font-sans);\n font-size: var(--font-size-0);\n color: var(--devtools-text-muted);\n cursor: pointer;\n transition: all var(--devtools-transition-fast);\n}\n\n.routes-filters__status-btn:hover {\n background-color: var(--devtools-surface-elevated);\n color: var(--devtools-text);\n}\n\n.routes-filters__status-btn--active {\n background-color: color-mix(in srgb, var(--devtools-primary) 15%, transparent);\n border-color: var(--devtools-primary);\n color: var(--devtools-primary);\n}\n\n.routes-filters__actions {\n display: flex;\n align-items: flex-end;\n margin-left: auto;\n}\n\n/* Main content */\n.routes-content {\n flex: 1;\n display: flex;\n overflow: hidden;\n}\n\n/* Loading state */\n.routes-loading {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n width: 100%;\n gap: var(--devtools-space-md);\n}\n\n.routes-loading__spinner {\n width: 32px;\n height: 32px;\n border: 3px solid var(--devtools-border);\n border-top-color: var(--devtools-primary);\n border-radius: 50%;\n animation: spin 1s linear infinite;\n}\n\n@keyframes spin {\n to {\n transform: rotate(360deg);\n }\n}\n\n/* Error state */\n.routes-error {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n width: 100%;\n gap: var(--devtools-space-md);\n padding: var(--devtools-space-xl);\n}\n\n.routes-error__message {\n color: var(--devtools-error);\n margin: 0;\n}\n\n/* Empty state */\n.routes-empty {\n width: 100%;\n}\n\n/* Split panels */\n.routes-list-panel {\n width: var(--devtools-sidebar-width);\n min-width: 200px;\n max-width: 400px;\n border-right: 1px solid var(--devtools-border);\n background-color: var(--devtools-surface);\n overflow: hidden;\n}\n\n.routes-detail-panel {\n flex: 1;\n overflow: hidden;\n background-color: var(--devtools-bg);\n}\n</style>\n"],"names":["Code","createLucideIcon","FileJson","Lock","Shield","Sprout","Tag","useRegistryStore","defineStore","endpoints","ref","stats","isLoading","error","searchQuery","filter","selectedEndpointKey","expandedTags","allTags","computed","tagSet","endpoint","tag","allSchemas","schemaSet","filteredEndpoints","result","query","groupedEndpoints","groups","groupKey","eps","a","b","selectedEndpoint","e","handlerCount","seedCount","setRegistryData","data","setLoading","loading","setError","errorMessage","clearError","setSearchQuery","toggleMethodFilter","method","index","setHandlerFilter","hasHandler","setSeedFilter","hasSeed","toggleTagFilter","clearFilters","hasActiveFilters","selectEndpoint","key","toggleGroup","expandAllGroups","group","collapseAllGroups","updateHandlerStatus","handlerOperationIds","handlerSet","updateSeedStatus","seedSchemas","seedSet","props","__props","hasSecurity","securityDisplay","sec","_openBlock","_createElementBlock","_hoisted_1","_hoisted_3","_createElementVNode","_hoisted_4","_normalizeClass","_unref","getMethodLabel","_hoisted_5","_toDisplayString","_hoisted_6","_hoisted_7","_createVNode","_cache","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","_hoisted_15","_hoisted_16","_Fragment","_renderList","_hoisted_17","_hoisted_18","_hoisted_19","_hoisted_20","_hoisted_21","_hoisted_22","_hoisted_23","_hoisted_24","_hoisted_25","_hoisted_26","_hoisted_27","_hoisted_28","_hoisted_2","emit","__emit","handleEndpointClick","handleGroupToggle","isSelected","$event","_createBlock","_resolveDynamicComponent","ChevronDown","ChevronRight","_vShow","registryStore","send","on","connected","useWebSocket","showFilters","searchInputRef","httpMethods","fetchRegistry","handleRegistryData","handleSelectEndpoint","handleToggleGroup","handleSearchInput","event","target","clearSearch","toggleMethod","isMethodActive","toggleHandlerFilter","current","toggleSeedFilter","clearAllFilters","toggleFilters","unsubRegistry","unsubHandlers","unsubSeeds","onMounted","onUnmounted","watch","isConnected","Search","X","Filter","ChevronUp","Route","EndpointList","EndpointDetail"],"mappings":"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","x_google_ignoreList":[0,1,2,3,4,5]}
1
+ {"version":3,"file":"RoutesPage-C2CUh7EQ.js","sources":["../../../node_modules/.pnpm/lucide-vue-next@0.513.0_vue@3.5.27_typescript@5.9.3_/node_modules/lucide-vue-next/dist/esm/icons/code.js","../../../node_modules/.pnpm/lucide-vue-next@0.513.0_vue@3.5.27_typescript@5.9.3_/node_modules/lucide-vue-next/dist/esm/icons/file-json.js","../../../node_modules/.pnpm/lucide-vue-next@0.513.0_vue@3.5.27_typescript@5.9.3_/node_modules/lucide-vue-next/dist/esm/icons/lock.js","../../../node_modules/.pnpm/lucide-vue-next@0.513.0_vue@3.5.27_typescript@5.9.3_/node_modules/lucide-vue-next/dist/esm/icons/shield.js","../../../node_modules/.pnpm/lucide-vue-next@0.513.0_vue@3.5.27_typescript@5.9.3_/node_modules/lucide-vue-next/dist/esm/icons/sprout.js","../../../node_modules/.pnpm/lucide-vue-next@0.513.0_vue@3.5.27_typescript@5.9.3_/node_modules/lucide-vue-next/dist/esm/icons/tag.js","../src/stores/registry.ts","../src/components/EndpointDetail.vue","../src/components/EndpointList.vue","../src/pages/RoutesPage.vue"],"sourcesContent":["/**\n * @license lucide-vue-next v0.513.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Code = createLucideIcon(\"code\", [\n [\"path\", { d: \"m16 18 6-6-6-6\", key: \"eg8j8\" }],\n [\"path\", { d: \"m8 6-6 6 6 6\", key: \"ppft3o\" }]\n]);\n\nexport { Code as default };\n//# sourceMappingURL=code.js.map\n","/**\n * @license lucide-vue-next v0.513.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst FileJson = createLucideIcon(\"file-json\", [\n [\"path\", { d: \"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\", key: \"1rqfz7\" }],\n [\"path\", { d: \"M14 2v4a2 2 0 0 0 2 2h4\", key: \"tnqrlb\" }],\n [\n \"path\",\n { d: \"M10 12a1 1 0 0 0-1 1v1a1 1 0 0 1-1 1 1 1 0 0 1 1 1v1a1 1 0 0 0 1 1\", key: \"1oajmo\" }\n ],\n [\n \"path\",\n { d: \"M14 18a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1 1 1 0 0 1-1-1v-1a1 1 0 0 0-1-1\", key: \"mpwhp6\" }\n ]\n]);\n\nexport { FileJson as default };\n//# sourceMappingURL=file-json.js.map\n","/**\n * @license lucide-vue-next v0.513.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Lock = createLucideIcon(\"lock\", [\n [\"rect\", { width: \"18\", height: \"11\", x: \"3\", y: \"11\", rx: \"2\", ry: \"2\", key: \"1w4ew1\" }],\n [\"path\", { d: \"M7 11V7a5 5 0 0 1 10 0v4\", key: \"fwvmzm\" }]\n]);\n\nexport { Lock as default };\n//# sourceMappingURL=lock.js.map\n","/**\n * @license lucide-vue-next v0.513.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Shield = createLucideIcon(\"shield\", [\n [\n \"path\",\n {\n d: \"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z\",\n key: \"oel41y\"\n }\n ]\n]);\n\nexport { Shield as default };\n//# sourceMappingURL=shield.js.map\n","/**\n * @license lucide-vue-next v0.513.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Sprout = createLucideIcon(\"sprout\", [\n [\"path\", { d: \"M7 20h10\", key: \"e6iznv\" }],\n [\"path\", { d: \"M10 20c5.5-2.5.8-6.4 3-10\", key: \"161w41\" }],\n [\n \"path\",\n {\n d: \"M9.5 9.4c1.1.8 1.8 2.2 2.3 3.7-2 .4-3.5.4-4.8-.3-1.2-.6-2.3-1.9-3-4.2 2.8-.5 4.4 0 5.5.8z\",\n key: \"9gtqwd\"\n }\n ],\n [\n \"path\",\n {\n d: \"M14.1 6a7 7 0 0 0-1.1 4c1.9-.1 3.3-.6 4.3-1.4 1-1 1.6-2.3 1.7-4.6-2.7.1-4 1-4.9 2z\",\n key: \"bkxnd2\"\n }\n ]\n]);\n\nexport { Sprout as default };\n//# sourceMappingURL=sprout.js.map\n","/**\n * @license lucide-vue-next v0.513.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Tag = createLucideIcon(\"tag\", [\n [\n \"path\",\n {\n d: \"M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z\",\n key: \"vktsd0\"\n }\n ],\n [\"circle\", { cx: \"7.5\", cy: \"7.5\", r: \".5\", fill: \"currentColor\", key: \"kqv944\" }]\n]);\n\nexport { Tag as default };\n//# sourceMappingURL=tag.js.map\n","/**\n * Registry Store\n *\n * What: Pinia store for managing endpoint registry data\n * How: Fetches and caches endpoint data from the server via WebSocket\n * Why: Provides reactive access to endpoint data for the Routes Page\n *\n * @module stores/registry\n */\n\nimport { defineStore } from 'pinia';\nimport { computed, ref } from 'vue';\n\n/**\n * HTTP method type\n */\nexport type HttpMethod = 'get' | 'post' | 'put' | 'patch' | 'delete' | 'options' | 'head' | 'trace';\n\n/**\n * Security requirement from OpenAPI spec\n */\nexport interface SecurityRequirement {\n name: string;\n scopes: string[];\n}\n\n/**\n * Endpoint entry from the server\n */\nexport interface EndpointEntry {\n key: string;\n operationId: string;\n method: HttpMethod;\n path: string;\n summary?: string;\n description?: string;\n tags: string[];\n responseSchema?: string;\n hasHandler: boolean;\n hasSeed: boolean;\n security: SecurityRequirement[];\n}\n\n/**\n * Registry statistics\n */\nexport interface RegistryStats {\n totalEndpoints: number;\n withCustomHandler: number;\n totalSchemas: number;\n withCustomSeed: number;\n autoGenerated: number;\n}\n\n/**\n * Registry data from server\n */\nexport interface RegistryData {\n endpoints: EndpointEntry[];\n stats: RegistryStats;\n}\n\n/**\n * Grouped endpoints by tag\n */\nexport interface EndpointGroup {\n tag: string;\n endpoints: EndpointEntry[];\n isExpanded: boolean;\n}\n\n/**\n * Filter options for endpoints\n */\nexport interface EndpointFilter {\n methods: HttpMethod[];\n hasHandler: boolean | null;\n hasSeed: boolean | null;\n tags: string[];\n}\n\n/**\n * Registry store for endpoint data management\n *\n * Provides:\n * - Endpoint data storage and retrieval\n * - Grouping by tags\n * - Search and filter functionality\n * - Selected endpoint tracking\n */\nexport const useRegistryStore = defineStore('registry', () => {\n // ==========================================================================\n // State\n // ==========================================================================\n\n /** All endpoints from the server */\n const endpoints = ref<EndpointEntry[]>([]);\n\n /** Registry statistics */\n const stats = ref<RegistryStats>({\n totalEndpoints: 0,\n withCustomHandler: 0,\n totalSchemas: 0,\n withCustomSeed: 0,\n autoGenerated: 0,\n });\n\n /** Loading state */\n const isLoading = ref(false);\n\n /** Error state */\n const error = ref<string | null>(null);\n\n /** Search query */\n const searchQuery = ref('');\n\n /** Active filters */\n const filter = ref<EndpointFilter>({\n methods: [],\n hasHandler: null,\n hasSeed: null,\n tags: [],\n });\n\n /** Currently selected endpoint key */\n const selectedEndpointKey = ref<string | null>(null);\n\n /** Expanded tag groups */\n const expandedTags = ref<Set<string>>(new Set());\n\n // ==========================================================================\n // Getters / Computed\n // ==========================================================================\n\n /**\n * All unique tags from endpoints\n */\n const allTags = computed(() => {\n const tagSet = new Set<string>();\n for (const endpoint of endpoints.value) {\n for (const tag of endpoint.tags) {\n tagSet.add(tag);\n }\n }\n return Array.from(tagSet).sort();\n });\n\n /**\n * All unique response schemas\n */\n const allSchemas = computed(() => {\n const schemaSet = new Set<string>();\n for (const endpoint of endpoints.value) {\n if (endpoint.responseSchema) {\n schemaSet.add(endpoint.responseSchema);\n }\n }\n return Array.from(schemaSet).sort();\n });\n\n /**\n * Filtered endpoints based on search and filters\n */\n const filteredEndpoints = computed(() => {\n let result = endpoints.value;\n\n // Apply search query\n if (searchQuery.value.trim()) {\n const query = searchQuery.value.toLowerCase().trim();\n result = result.filter((endpoint) => {\n return (\n endpoint.path.toLowerCase().includes(query) ||\n endpoint.operationId.toLowerCase().includes(query) ||\n endpoint.summary?.toLowerCase().includes(query) ||\n endpoint.tags.some((tag) => tag.toLowerCase().includes(query))\n );\n });\n }\n\n // Apply method filter\n if (filter.value.methods.length > 0) {\n result = result.filter((endpoint) => filter.value.methods.includes(endpoint.method));\n }\n\n // Apply handler filter\n if (filter.value.hasHandler !== null) {\n result = result.filter((endpoint) => endpoint.hasHandler === filter.value.hasHandler);\n }\n\n // Apply seed filter\n if (filter.value.hasSeed !== null) {\n result = result.filter((endpoint) => endpoint.hasSeed === filter.value.hasSeed);\n }\n\n // Apply tag filter\n if (filter.value.tags.length > 0) {\n result = result.filter((endpoint) =>\n endpoint.tags.some((tag) => filter.value.tags.includes(tag)),\n );\n }\n\n return result;\n });\n\n /**\n * Endpoints grouped by tag\n *\n * Grouping logic (from PRD):\n * 1. By tags (if they exist in spec)\n * 2. Fallback: By response schema\n * 3. Final fallback: By first path segment\n */\n const groupedEndpoints = computed((): EndpointGroup[] => {\n const groups = new Map<string, EndpointEntry[]>();\n\n for (const endpoint of filteredEndpoints.value) {\n // Determine group key\n let groupKey: string;\n\n if (endpoint.tags.length > 0) {\n // Use first tag as group\n groupKey = endpoint.tags[0];\n } else if (endpoint.responseSchema) {\n // Fallback to response schema\n groupKey = endpoint.responseSchema;\n } else {\n // Final fallback: first path segment\n const segments = endpoint.path.split('/').filter(Boolean);\n groupKey = segments[0] || 'Other';\n }\n\n if (!groups.has(groupKey)) {\n groups.set(groupKey, []);\n }\n groups.get(groupKey)?.push(endpoint);\n }\n\n // Convert to array and sort\n return Array.from(groups.entries())\n .map(([tag, eps]) => ({\n tag,\n endpoints: eps.sort((a, b) => a.path.localeCompare(b.path)),\n isExpanded: expandedTags.value.has(tag),\n }))\n .sort((a, b) => a.tag.localeCompare(b.tag));\n });\n\n /**\n * Currently selected endpoint\n */\n const selectedEndpoint = computed(() => {\n if (!selectedEndpointKey.value) return null;\n return endpoints.value.find((e) => e.key === selectedEndpointKey.value) ?? null;\n });\n\n /**\n * Count of endpoints with custom handlers\n */\n const handlerCount = computed(() => endpoints.value.filter((e) => e.hasHandler).length);\n\n /**\n * Count of endpoints with seed data\n */\n const seedCount = computed(() => endpoints.value.filter((e) => e.hasSeed).length);\n\n // ==========================================================================\n // Actions\n // ==========================================================================\n\n /**\n * Set registry data from server response\n */\n function setRegistryData(data: RegistryData): void {\n endpoints.value = data.endpoints;\n stats.value = data.stats;\n error.value = null;\n\n // Auto-expand all groups initially\n for (const endpoint of data.endpoints) {\n if (endpoint.tags.length > 0) {\n expandedTags.value.add(endpoint.tags[0]);\n }\n }\n }\n\n /**\n * Set loading state\n */\n function setLoading(loading: boolean): void {\n isLoading.value = loading;\n }\n\n /**\n * Set error state\n */\n function setError(errorMessage: string): void {\n error.value = errorMessage;\n isLoading.value = false;\n }\n\n /**\n * Clear error state\n */\n function clearError(): void {\n error.value = null;\n }\n\n /**\n * Set search query\n */\n function setSearchQuery(query: string): void {\n searchQuery.value = query;\n }\n\n /**\n * Toggle method filter\n */\n function toggleMethodFilter(method: HttpMethod): void {\n const index = filter.value.methods.indexOf(method);\n if (index === -1) {\n filter.value.methods.push(method);\n } else {\n filter.value.methods.splice(index, 1);\n }\n }\n\n /**\n * Set handler filter\n */\n function setHandlerFilter(hasHandler: boolean | null): void {\n filter.value.hasHandler = hasHandler;\n }\n\n /**\n * Set seed filter\n */\n function setSeedFilter(hasSeed: boolean | null): void {\n filter.value.hasSeed = hasSeed;\n }\n\n /**\n * Toggle tag filter\n */\n function toggleTagFilter(tag: string): void {\n const index = filter.value.tags.indexOf(tag);\n if (index === -1) {\n filter.value.tags.push(tag);\n } else {\n filter.value.tags.splice(index, 1);\n }\n }\n\n /**\n * Clear all filters\n */\n function clearFilters(): void {\n filter.value = {\n methods: [],\n hasHandler: null,\n hasSeed: null,\n tags: [],\n };\n searchQuery.value = '';\n }\n\n /**\n * Check if any filter is active\n */\n function hasActiveFilters(): boolean {\n return (\n searchQuery.value.trim() !== '' ||\n filter.value.methods.length > 0 ||\n filter.value.hasHandler !== null ||\n filter.value.hasSeed !== null ||\n filter.value.tags.length > 0\n );\n }\n\n /**\n * Select an endpoint by key\n */\n function selectEndpoint(key: string | null): void {\n selectedEndpointKey.value = key;\n }\n\n /**\n * Toggle group expansion\n */\n function toggleGroup(tag: string): void {\n if (expandedTags.value.has(tag)) {\n expandedTags.value.delete(tag);\n } else {\n expandedTags.value.add(tag);\n }\n }\n\n /**\n * Expand all groups\n */\n function expandAllGroups(): void {\n for (const group of groupedEndpoints.value) {\n expandedTags.value.add(group.tag);\n }\n }\n\n /**\n * Collapse all groups\n */\n function collapseAllGroups(): void {\n expandedTags.value.clear();\n }\n\n /**\n * Update handler status for endpoints\n * Called when handlers are reloaded\n */\n function updateHandlerStatus(handlerOperationIds: string[]): void {\n const handlerSet = new Set(handlerOperationIds);\n for (const endpoint of endpoints.value) {\n endpoint.hasHandler = handlerSet.has(endpoint.operationId);\n }\n }\n\n /**\n * Update seed status for endpoints\n * Called when seeds are reloaded\n */\n function updateSeedStatus(seedSchemas: string[]): void {\n const seedSet = new Set(seedSchemas);\n for (const endpoint of endpoints.value) {\n endpoint.hasSeed = endpoint.responseSchema ? seedSet.has(endpoint.responseSchema) : false;\n }\n }\n\n // ==========================================================================\n // Return\n // ==========================================================================\n\n return {\n // State\n endpoints,\n stats,\n isLoading,\n error,\n searchQuery,\n filter,\n selectedEndpointKey,\n expandedTags,\n\n // Getters\n allTags,\n allSchemas,\n filteredEndpoints,\n groupedEndpoints,\n selectedEndpoint,\n handlerCount,\n seedCount,\n\n // Actions\n setRegistryData,\n setLoading,\n setError,\n clearError,\n setSearchQuery,\n toggleMethodFilter,\n setHandlerFilter,\n setSeedFilter,\n toggleTagFilter,\n clearFilters,\n hasActiveFilters,\n selectEndpoint,\n toggleGroup,\n expandAllGroups,\n collapseAllGroups,\n updateHandlerStatus,\n updateSeedStatus,\n };\n});\n","<!--\n EndpointDetail.vue - Endpoint Detail Panel Component\n\n What: Displays detailed information about a selected API endpoint\n How: Shows method, path, operation ID, tags, summary, description, and status indicators\n Why: Provides comprehensive endpoint information for developers using the DevTools\n-->\n\n<script setup lang=\"ts\">\nimport { Code, FileJson, Lock, Shield, Sprout, Tag } from 'lucide-vue-next';\nimport { computed } from 'vue';\n\nimport type { EndpointEntry } from '@/stores/registry';\nimport { getMethodLabel } from '@/utils/format';\n\n/**\n * Component props\n */\ninterface Props {\n /** Endpoint to display details for */\n endpoint: EndpointEntry | null;\n}\n\nconst props = defineProps<Props>();\n\n/**\n * Check if endpoint has security requirements\n */\nconst hasSecurity = computed(() => {\n return props.endpoint?.security && props.endpoint.security.length > 0;\n});\n\n/**\n * Format security requirements for display\n */\nconst securityDisplay = computed(() => {\n if (!props.endpoint?.security) return [];\n return props.endpoint.security.map((sec) => ({\n name: sec.name,\n scopes: sec.scopes.length > 0 ? sec.scopes.join(', ') : 'No scopes',\n }));\n});\n</script>\n\n<template>\n <div class=\"endpoint-detail\">\n <!-- Empty state when no endpoint selected -->\n <div v-if=\"!endpoint\" class=\"endpoint-detail__empty\">\n <FileJson :size=\"48\" class=\"endpoint-detail__empty-icon\" />\n <h3 class=\"endpoint-detail__empty-title\">No endpoint selected</h3>\n <p class=\"endpoint-detail__empty-text text-muted\">\n Select an endpoint from the list to view its details\n </p>\n </div>\n\n <!-- Endpoint details -->\n <div v-else class=\"endpoint-detail__content\">\n <!-- Header with method and path -->\n <header class=\"endpoint-detail__header\">\n <span\n :class=\"[\n 'method-badge',\n 'method-badge--large',\n `method-badge--${endpoint.method}`\n ]\"\n >\n {{ getMethodLabel(endpoint.method) }}\n </span>\n <h2 class=\"endpoint-detail__path font-mono\">\n {{ endpoint.path }}\n </h2>\n </header>\n\n <!-- Status indicators -->\n <div class=\"endpoint-detail__status\">\n <div\n v-if=\"endpoint.hasHandler\"\n class=\"endpoint-detail__status-item endpoint-detail__status-item--handler\"\n >\n <Code :size=\"14\" />\n <span>Has custom handler</span>\n </div>\n <div\n v-if=\"endpoint.hasSeed\"\n class=\"endpoint-detail__status-item endpoint-detail__status-item--seed\"\n >\n <Sprout :size=\"14\" />\n <span>Has seed data</span>\n </div>\n <div\n v-if=\"hasSecurity\"\n class=\"endpoint-detail__status-item endpoint-detail__status-item--security\"\n >\n <Lock :size=\"14\" />\n <span>Requires authentication</span>\n </div>\n <div\n v-if=\"!endpoint.hasHandler && !endpoint.hasSeed\"\n class=\"endpoint-detail__status-item endpoint-detail__status-item--auto\"\n >\n <FileJson :size=\"14\" />\n <span>Auto-generated response</span>\n </div>\n </div>\n\n <!-- Info sections -->\n <div class=\"endpoint-detail__sections\">\n <!-- Operation ID -->\n <section class=\"endpoint-detail__section\">\n <h3 class=\"endpoint-detail__section-title\">Operation</h3>\n <p class=\"endpoint-detail__section-content font-mono\">\n {{ endpoint.operationId }}\n </p>\n </section>\n\n <!-- Tags -->\n <section v-if=\"endpoint.tags.length > 0\" class=\"endpoint-detail__section\">\n <h3 class=\"endpoint-detail__section-title\">\n <Tag :size=\"14\" />\n Tags\n </h3>\n <div class=\"endpoint-detail__tags\">\n <span\n v-for=\"tag in endpoint.tags\"\n :key=\"tag\"\n class=\"endpoint-detail__tag\"\n >\n {{ tag }}\n </span>\n </div>\n </section>\n\n <!-- Summary -->\n <section v-if=\"endpoint.summary\" class=\"endpoint-detail__section\">\n <h3 class=\"endpoint-detail__section-title\">Summary</h3>\n <p class=\"endpoint-detail__section-content\">\n {{ endpoint.summary }}\n </p>\n </section>\n\n <!-- Description -->\n <section v-if=\"endpoint.description\" class=\"endpoint-detail__section\">\n <h3 class=\"endpoint-detail__section-title\">Description</h3>\n <p class=\"endpoint-detail__section-content endpoint-detail__description\">\n {{ endpoint.description }}\n </p>\n </section>\n\n <!-- Response Schema -->\n <section v-if=\"endpoint.responseSchema\" class=\"endpoint-detail__section\">\n <h3 class=\"endpoint-detail__section-title\">\n <FileJson :size=\"14\" />\n Response Schema\n </h3>\n <p class=\"endpoint-detail__section-content font-mono\">\n {{ endpoint.responseSchema }}\n </p>\n </section>\n\n <!-- Security -->\n <section v-if=\"hasSecurity\" class=\"endpoint-detail__section\">\n <h3 class=\"endpoint-detail__section-title\">\n <Shield :size=\"14\" />\n Security\n </h3>\n <div class=\"endpoint-detail__security\">\n <div\n v-for=\"sec in securityDisplay\"\n :key=\"sec.name\"\n class=\"endpoint-detail__security-item\"\n >\n <span class=\"endpoint-detail__security-name font-mono\">\n {{ sec.name }}\n </span>\n <span class=\"endpoint-detail__security-scopes text-muted\">\n {{ sec.scopes }}\n </span>\n </div>\n </div>\n </section>\n </div>\n </div>\n </div>\n</template>\n\n<style scoped>\n.endpoint-detail {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n}\n\n/* Empty state */\n.endpoint-detail__empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n padding: var(--devtools-space-xl);\n text-align: center;\n}\n\n.endpoint-detail__empty-icon {\n color: var(--devtools-text-muted);\n opacity: 0.5;\n margin-bottom: var(--devtools-space-md);\n}\n\n.endpoint-detail__empty-title {\n font-size: var(--font-size-2);\n font-weight: var(--font-weight-5);\n color: var(--devtools-text);\n margin: 0 0 var(--devtools-space-sm);\n}\n\n.endpoint-detail__empty-text {\n font-size: var(--font-size-1);\n margin: 0;\n}\n\n/* Content */\n.endpoint-detail__content {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow-y: auto;\n padding: var(--devtools-space-md);\n}\n\n/* Header */\n.endpoint-detail__header {\n display: flex;\n align-items: center;\n gap: var(--devtools-space-md);\n margin-bottom: var(--devtools-space-md);\n padding-bottom: var(--devtools-space-md);\n border-bottom: 1px solid var(--devtools-border);\n}\n\n.endpoint-detail__path {\n font-size: var(--font-size-2);\n font-weight: var(--font-weight-5);\n color: var(--devtools-text);\n margin: 0;\n word-break: break-all;\n}\n\n/* Large method badge */\n.method-badge--large {\n font-size: var(--font-size-0);\n padding: var(--devtools-space-sm) var(--devtools-space-md);\n min-width: 70px;\n}\n\n/* Status indicators */\n.endpoint-detail__status {\n display: flex;\n flex-wrap: wrap;\n gap: var(--devtools-space-sm);\n margin-bottom: var(--devtools-space-md);\n}\n\n.endpoint-detail__status-item {\n display: inline-flex;\n align-items: center;\n gap: var(--devtools-space-xs);\n padding: var(--devtools-space-xs) var(--devtools-space-sm);\n border-radius: var(--devtools-radius-sm);\n font-size: var(--font-size-0);\n font-weight: var(--font-weight-5);\n}\n\n.endpoint-detail__status-item--handler {\n background-color: color-mix(in srgb, var(--devtools-info) 15%, transparent);\n color: var(--devtools-info);\n}\n\n.endpoint-detail__status-item--seed {\n background-color: color-mix(in srgb, var(--devtools-success) 15%, transparent);\n color: var(--devtools-success);\n}\n\n.endpoint-detail__status-item--security {\n background-color: color-mix(in srgb, var(--devtools-warning) 15%, transparent);\n color: var(--devtools-warning);\n}\n\n.endpoint-detail__status-item--auto {\n background-color: color-mix(in srgb, var(--devtools-text-muted) 15%, transparent);\n color: var(--devtools-text-muted);\n}\n\n/* Sections */\n.endpoint-detail__sections {\n display: flex;\n flex-direction: column;\n gap: var(--devtools-space-md);\n}\n\n.endpoint-detail__section {\n display: flex;\n flex-direction: column;\n gap: var(--devtools-space-xs);\n}\n\n.endpoint-detail__section-title {\n display: flex;\n align-items: center;\n gap: var(--devtools-space-xs);\n font-size: var(--font-size-0);\n font-weight: var(--font-weight-6);\n color: var(--devtools-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n margin: 0;\n}\n\n.endpoint-detail__section-content {\n font-size: var(--font-size-1);\n color: var(--devtools-text);\n margin: 0;\n line-height: var(--font-lineheight-3);\n}\n\n.endpoint-detail__description {\n white-space: pre-wrap;\n}\n\n/* Tags */\n.endpoint-detail__tags {\n display: flex;\n flex-wrap: wrap;\n gap: var(--devtools-space-xs);\n}\n\n.endpoint-detail__tag {\n display: inline-flex;\n align-items: center;\n padding: var(--devtools-space-xs) var(--devtools-space-sm);\n background-color: var(--devtools-surface-elevated);\n border-radius: var(--devtools-radius-sm);\n font-size: var(--font-size-0);\n color: var(--devtools-text);\n}\n\n/* Security */\n.endpoint-detail__security {\n display: flex;\n flex-direction: column;\n gap: var(--devtools-space-xs);\n}\n\n.endpoint-detail__security-item {\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding: var(--devtools-space-sm);\n background-color: var(--devtools-surface-elevated);\n border-radius: var(--devtools-radius-sm);\n}\n\n.endpoint-detail__security-name {\n font-size: var(--font-size-1);\n font-weight: var(--font-weight-5);\n}\n\n.endpoint-detail__security-scopes {\n font-size: var(--font-size-0);\n}\n</style>\n","<!--\n EndpointList.vue - Grouped Endpoint Listing Component\n\n What: Displays a list of API endpoints grouped by tags with collapsible sections\n How: Renders endpoint groups from registry store with method badges and selection support\n Why: Provides organized navigation through available mock endpoints\n-->\n\n<script setup lang=\"ts\">\nimport { ChevronDown, ChevronRight, Code, Sprout } from 'lucide-vue-next';\n\nimport type { EndpointEntry, EndpointGroup } from '@/stores/registry';\nimport { getMethodLabel } from '@/utils/format';\n\n/**\n * Component props\n */\ninterface Props {\n /** Grouped endpoints to display */\n groups: EndpointGroup[];\n /** Currently selected endpoint key */\n selectedKey: string | null;\n}\n\nconst props = defineProps<Props>();\n\n/**\n * Component events\n */\nconst emit = defineEmits<{\n /** Emitted when an endpoint is selected */\n (e: 'select', key: string): void;\n /** Emitted when a group is toggled */\n (e: 'toggle-group', tag: string): void;\n}>();\n\n/**\n * Handle endpoint click\n */\nfunction handleEndpointClick(endpoint: EndpointEntry): void {\n emit('select', endpoint.key);\n}\n\n/**\n * Handle group toggle\n */\nfunction handleGroupToggle(tag: string): void {\n emit('toggle-group', tag);\n}\n\n/**\n * Check if endpoint is selected\n */\nfunction isSelected(endpoint: EndpointEntry): boolean {\n return props.selectedKey === endpoint.key;\n}\n</script>\n\n<template>\n <div class=\"endpoint-list\">\n <!-- Empty state -->\n <div v-if=\"groups.length === 0\" class=\"endpoint-list__empty\">\n <p class=\"text-muted\">No endpoints found</p>\n </div>\n\n <!-- Endpoint groups -->\n <div v-else class=\"endpoint-list__groups\">\n <div\n v-for=\"group in groups\"\n :key=\"group.tag\"\n class=\"endpoint-group\"\n >\n <!-- Group header -->\n <button\n type=\"button\"\n class=\"endpoint-group__header\"\n :aria-expanded=\"group.isExpanded\"\n :aria-controls=\"`group-${group.tag}`\"\n @click=\"handleGroupToggle(group.tag)\"\n >\n <component\n :is=\"group.isExpanded ? ChevronDown : ChevronRight\"\n :size=\"16\"\n class=\"endpoint-group__chevron\"\n />\n <span class=\"endpoint-group__tag\">{{ group.tag }}</span>\n <span class=\"endpoint-group__count text-muted\">\n ({{ group.endpoints.length }})\n </span>\n </button>\n\n <!-- Group endpoints -->\n <div\n v-show=\"group.isExpanded\"\n :id=\"`group-${group.tag}`\"\n class=\"endpoint-group__items\"\n role=\"group\"\n :aria-label=\"`${group.tag} endpoints`\"\n >\n <button\n v-for=\"endpoint in group.endpoints\"\n :key=\"endpoint.key\"\n type=\"button\"\n :class=\"[\n 'endpoint-item',\n { 'endpoint-item--selected': isSelected(endpoint) }\n ]\"\n :aria-selected=\"isSelected(endpoint)\"\n @click=\"handleEndpointClick(endpoint)\"\n >\n <!-- Method badge -->\n <span\n :class=\"[\n 'method-badge',\n `method-badge--${endpoint.method}`\n ]\"\n >\n {{ getMethodLabel(endpoint.method) }}\n </span>\n\n <!-- Path -->\n <span class=\"endpoint-item__path font-mono\">\n {{ endpoint.path }}\n </span>\n\n <!-- Status indicators -->\n <div class=\"endpoint-item__indicators\">\n <span\n v-if=\"endpoint.hasHandler\"\n class=\"endpoint-item__indicator endpoint-item__indicator--handler\"\n title=\"Has custom handler\"\n >\n <Code :size=\"12\" />\n </span>\n <span\n v-if=\"endpoint.hasSeed\"\n class=\"endpoint-item__indicator endpoint-item__indicator--seed\"\n title=\"Has seed data\"\n >\n <Sprout :size=\"12\" />\n </span>\n </div>\n </button>\n </div>\n </div>\n </div>\n </div>\n</template>\n\n<style scoped>\n.endpoint-list {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n}\n\n.endpoint-list__empty {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: var(--devtools-space-lg);\n}\n\n.endpoint-list__groups {\n flex: 1;\n overflow-y: auto;\n padding: var(--devtools-space-xs);\n}\n\n/* Group styles */\n.endpoint-group {\n margin-bottom: var(--devtools-space-xs);\n}\n\n.endpoint-group__header {\n display: flex;\n align-items: center;\n gap: var(--devtools-space-xs);\n width: 100%;\n padding: var(--devtools-space-sm) var(--devtools-space-sm);\n background: none;\n border: none;\n border-radius: var(--devtools-radius-sm);\n font-family: var(--devtools-font-sans);\n font-size: var(--font-size-1);\n font-weight: var(--font-weight-5);\n color: var(--devtools-text);\n text-align: left;\n cursor: pointer;\n transition: background-color var(--devtools-transition-fast);\n}\n\n.endpoint-group__header:hover {\n background-color: var(--devtools-surface-elevated);\n}\n\n.endpoint-group__header:focus {\n outline: none;\n}\n\n.endpoint-group__header:focus-visible {\n outline: 2px solid var(--devtools-primary);\n outline-offset: -2px;\n}\n\n.endpoint-group__chevron {\n flex-shrink: 0;\n color: var(--devtools-text-muted);\n}\n\n.endpoint-group__tag {\n flex: 1;\n text-transform: capitalize;\n}\n\n.endpoint-group__count {\n font-size: var(--font-size-0);\n font-weight: var(--font-weight-4);\n}\n\n.endpoint-group__items {\n padding-left: var(--devtools-space-md);\n}\n\n/* Endpoint item styles */\n.endpoint-item {\n display: flex;\n align-items: center;\n gap: var(--devtools-space-sm);\n width: 100%;\n padding: var(--devtools-space-xs) var(--devtools-space-sm);\n background: none;\n border: none;\n border-radius: var(--devtools-radius-sm);\n font-family: var(--devtools-font-sans);\n text-align: left;\n cursor: pointer;\n transition: background-color var(--devtools-transition-fast);\n}\n\n.endpoint-item:hover {\n background-color: var(--devtools-surface-elevated);\n}\n\n.endpoint-item:focus {\n outline: none;\n}\n\n.endpoint-item:focus-visible {\n outline: 2px solid var(--devtools-primary);\n outline-offset: -2px;\n}\n\n.endpoint-item--selected {\n background-color: color-mix(in srgb, var(--devtools-primary) 15%, transparent);\n}\n\n.endpoint-item--selected:hover {\n background-color: color-mix(in srgb, var(--devtools-primary) 20%, transparent);\n}\n\n.endpoint-item__path {\n flex: 1;\n font-size: var(--font-size-0);\n color: var(--devtools-text);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.endpoint-item__indicators {\n display: flex;\n align-items: center;\n gap: var(--devtools-space-xs);\n}\n\n.endpoint-item__indicator {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 18px;\n height: 18px;\n border-radius: var(--devtools-radius-sm);\n}\n\n.endpoint-item__indicator--handler {\n background-color: color-mix(in srgb, var(--devtools-info) 15%, transparent);\n color: var(--devtools-info);\n}\n\n.endpoint-item__indicator--seed {\n background-color: color-mix(in srgb, var(--devtools-success) 15%, transparent);\n color: var(--devtools-success);\n}\n</style>\n","<!--\n RoutesPage.vue - Endpoint Listing Page\n\n What: Displays a list of all available API endpoints from the OpenAPI spec\n How: Fetches endpoint data via WebSocket and displays in a searchable/filterable list\n Why: Allows developers to quickly browse and inspect available mock endpoints\n-->\n\n<script setup lang=\"ts\">\nimport { ChevronDown, ChevronUp, Code, Filter, Route, Search, Sprout, X } from 'lucide-vue-next';\nimport { computed, onMounted, onUnmounted, ref, watch } from 'vue';\n\nimport EndpointDetail from '@/components/EndpointDetail.vue';\nimport EndpointList from '@/components/EndpointList.vue';\nimport { useWebSocket } from '@/composables/useWebSocket';\nimport { type HttpMethod, type RegistryData, useRegistryStore } from '@/stores/registry';\n\n// Store and WebSocket\nconst registryStore = useRegistryStore();\nconst { send, on, connected } = useWebSocket();\n\n// Local UI state\nconst showFilters = ref(false);\nconst searchInputRef = ref<HTMLInputElement | null>(null);\n\n// HTTP methods for filter (matches HttpMethod type from registry store)\nconst httpMethods: HttpMethod[] = [\n 'get',\n 'post',\n 'put',\n 'patch',\n 'delete',\n 'options',\n 'head',\n 'trace',\n];\n\n/**\n * Fetch registry data when connected\n */\nfunction fetchRegistry(): void {\n if (connected.value) {\n registryStore.setLoading(true);\n send({ type: 'get:registry' });\n }\n}\n\n/**\n * Handle registry data from server\n */\nfunction handleRegistryData(data: RegistryData): void {\n registryStore.setRegistryData(data);\n registryStore.setLoading(false);\n}\n\n/**\n * Handle endpoint selection\n */\nfunction handleSelectEndpoint(key: string): void {\n registryStore.selectEndpoint(key);\n}\n\n/**\n * Handle group toggle\n */\nfunction handleToggleGroup(tag: string): void {\n registryStore.toggleGroup(tag);\n}\n\n/**\n * Handle search input\n */\nfunction handleSearchInput(event: Event): void {\n const target = event.target as HTMLInputElement;\n registryStore.setSearchQuery(target.value);\n}\n\n/**\n * Clear search\n */\nfunction clearSearch(): void {\n registryStore.setSearchQuery('');\n searchInputRef.value?.focus();\n}\n\n/**\n * Toggle method filter\n */\nfunction toggleMethod(method: HttpMethod): void {\n registryStore.toggleMethodFilter(method);\n}\n\n/**\n * Check if method is active in filter\n */\nfunction isMethodActive(method: HttpMethod): boolean {\n return registryStore.filter.methods.includes(method);\n}\n\n/**\n * Toggle handler filter\n */\nfunction toggleHandlerFilter(): void {\n const current = registryStore.filter.hasHandler;\n registryStore.setHandlerFilter(current === true ? null : true);\n}\n\n/**\n * Toggle seed filter\n */\nfunction toggleSeedFilter(): void {\n const current = registryStore.filter.hasSeed;\n registryStore.setSeedFilter(current === true ? null : true);\n}\n\n/**\n * Clear all filters\n */\nfunction clearAllFilters(): void {\n registryStore.clearFilters();\n}\n\n/**\n * Toggle filter panel visibility\n */\nfunction toggleFilters(): void {\n showFilters.value = !showFilters.value;\n}\n\n/**\n * Computed: Has active filters\n */\nconst hasActiveFilters = computed(() => registryStore.hasActiveFilters());\n\n// Event cleanup functions for WebSocket subscriptions\nlet unsubRegistry: (() => void) | null = null;\nlet unsubHandlers: (() => void) | null = null;\nlet unsubSeeds: (() => void) | null = null;\n\n// Subscribe to registry events and setup cleanup\nonMounted(() => {\n // Subscribe to WebSocket events (on() returns unsubscribe function)\n unsubRegistry = on<RegistryData>('registry', handleRegistryData);\n unsubHandlers = on('handlers:updated', () => fetchRegistry());\n unsubSeeds = on('seeds:updated', () => fetchRegistry());\n\n // Fetch registry when already connected\n if (connected.value) {\n fetchRegistry();\n }\n});\n\n// Cleanup event subscriptions on unmount to prevent memory leaks\nonUnmounted(() => {\n unsubRegistry?.();\n unsubHandlers?.();\n unsubSeeds?.();\n});\n\n// Re-fetch when connection is established\nwatch(connected, (isConnected) => {\n if (isConnected) {\n fetchRegistry();\n }\n});\n</script>\n\n<template>\n <div class=\"routes-page\">\n <!-- Toolbar -->\n <div class=\"routes-toolbar\">\n <!-- Search -->\n <div class=\"routes-search\">\n <Search :size=\"16\" class=\"routes-search__icon\" />\n <input\n ref=\"searchInputRef\"\n type=\"text\"\n class=\"routes-search__input input\"\n placeholder=\"Search endpoints...\"\n :value=\"registryStore.searchQuery\"\n @input=\"handleSearchInput\"\n />\n <button\n v-if=\"registryStore.searchQuery\"\n type=\"button\"\n class=\"routes-search__clear btn btn--ghost btn--icon\"\n title=\"Clear search\"\n @click=\"clearSearch\"\n >\n <X :size=\"14\" />\n </button>\n </div>\n\n <!-- Filter toggle -->\n <button\n type=\"button\"\n :class=\"[\n 'routes-filter-toggle btn btn--secondary',\n { 'routes-filter-toggle--active': hasActiveFilters }\n ]\"\n :aria-expanded=\"showFilters\"\n @click=\"toggleFilters\"\n >\n <Filter :size=\"16\" />\n <span>Filters</span>\n <span v-if=\"hasActiveFilters\" class=\"routes-filter-toggle__badge\">\n {{ registryStore.filter.methods.length +\n (registryStore.filter.hasHandler ? 1 : 0) +\n (registryStore.filter.hasSeed ? 1 : 0) }}\n </span>\n <component :is=\"showFilters ? ChevronUp : ChevronDown\" :size=\"14\" />\n </button>\n\n <!-- Stats -->\n <div class=\"routes-stats\">\n <span class=\"routes-stats__item\">\n {{ registryStore.filteredEndpoints.length }} endpoints\n </span>\n <span class=\"routes-stats__separator\">|</span>\n <span class=\"routes-stats__item\">\n {{ registryStore.allTags.length }} tags\n </span>\n </div>\n </div>\n\n <!-- Filter panel -->\n <div v-if=\"showFilters\" class=\"routes-filters\">\n <!-- Method filters -->\n <div class=\"routes-filters__section\">\n <h4 class=\"routes-filters__title\">Methods</h4>\n <div class=\"routes-filters__methods\">\n <button\n v-for=\"method in httpMethods\"\n :key=\"method\"\n type=\"button\"\n :class=\"[\n 'method-badge',\n `method-badge--${method}`,\n { 'method-badge--inactive': !isMethodActive(method) && registryStore.filter.methods.length > 0 }\n ]\"\n @click=\"toggleMethod(method)\"\n >\n {{ method.toUpperCase() }}\n </button>\n </div>\n </div>\n\n <!-- Status filters -->\n <div class=\"routes-filters__section\">\n <h4 class=\"routes-filters__title\">Status</h4>\n <div class=\"routes-filters__status\">\n <button\n type=\"button\"\n :class=\"[\n 'routes-filters__status-btn',\n { 'routes-filters__status-btn--active': registryStore.filter.hasHandler }\n ]\"\n @click=\"toggleHandlerFilter\"\n >\n <Code :size=\"14\" />\n <span>Has Handler</span>\n </button>\n <button\n type=\"button\"\n :class=\"[\n 'routes-filters__status-btn',\n { 'routes-filters__status-btn--active': registryStore.filter.hasSeed }\n ]\"\n @click=\"toggleSeedFilter\"\n >\n <Sprout :size=\"14\" />\n <span>Has Seed</span>\n </button>\n </div>\n </div>\n\n <!-- Clear filters -->\n <div v-if=\"hasActiveFilters\" class=\"routes-filters__actions\">\n <button\n type=\"button\"\n class=\"btn btn--ghost\"\n @click=\"clearAllFilters\"\n >\n <X :size=\"14\" />\n Clear all filters\n </button>\n </div>\n </div>\n\n <!-- Main content: split panel -->\n <div class=\"routes-content\">\n <!-- Loading state -->\n <div v-if=\"registryStore.isLoading\" class=\"routes-loading\">\n <div class=\"routes-loading__spinner\" />\n <span class=\"text-muted\">Loading endpoints...</span>\n </div>\n\n <!-- Error state -->\n <div v-else-if=\"registryStore.error\" class=\"routes-error\">\n <p class=\"routes-error__message\">{{ registryStore.error }}</p>\n <button type=\"button\" class=\"btn btn--primary\" @click=\"fetchRegistry\">\n Retry\n </button>\n </div>\n\n <!-- Empty state -->\n <div v-else-if=\"registryStore.endpoints.length === 0\" class=\"routes-empty empty-state\">\n <Route :size=\"48\" class=\"empty-state__icon\" />\n <h3 class=\"empty-state__title\">No endpoints found</h3>\n <p class=\"empty-state__description\">\n No API endpoints are available. Make sure your OpenAPI spec is loaded.\n </p>\n </div>\n\n <!-- No results state -->\n <div v-else-if=\"registryStore.filteredEndpoints.length === 0\" class=\"routes-empty empty-state\">\n <Search :size=\"48\" class=\"empty-state__icon\" />\n <h3 class=\"empty-state__title\">No matching endpoints</h3>\n <p class=\"empty-state__description\">\n Try adjusting your search or filters.\n </p>\n <button\n v-if=\"hasActiveFilters\"\n type=\"button\"\n class=\"btn btn--secondary\"\n @click=\"clearAllFilters\"\n >\n Clear filters\n </button>\n </div>\n\n <!-- Split panel layout -->\n <template v-else>\n <!-- Endpoint list panel -->\n <div class=\"routes-list-panel\">\n <EndpointList\n :groups=\"registryStore.groupedEndpoints\"\n :selected-key=\"registryStore.selectedEndpointKey\"\n @select=\"handleSelectEndpoint\"\n @toggle-group=\"handleToggleGroup\"\n />\n </div>\n\n <!-- Endpoint detail panel -->\n <div class=\"routes-detail-panel\">\n <EndpointDetail :endpoint=\"registryStore.selectedEndpoint\" />\n </div>\n </template>\n </div>\n </div>\n</template>\n\n<style scoped>\n.routes-page {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n}\n\n/* Toolbar */\n.routes-toolbar {\n display: flex;\n align-items: center;\n gap: var(--devtools-space-md);\n padding: var(--devtools-space-md);\n background-color: var(--devtools-surface);\n border-bottom: 1px solid var(--devtools-border);\n}\n\n.routes-search {\n position: relative;\n flex: 1;\n max-width: 400px;\n}\n\n.routes-search__icon {\n position: absolute;\n left: var(--devtools-space-sm);\n top: 50%;\n transform: translateY(-50%);\n color: var(--devtools-text-muted);\n pointer-events: none;\n}\n\n.routes-search__input {\n padding-left: calc(var(--devtools-space-sm) + 24px);\n padding-right: calc(var(--devtools-space-sm) + 24px);\n}\n\n.routes-search__clear {\n position: absolute;\n right: var(--devtools-space-xs);\n top: 50%;\n transform: translateY(-50%);\n padding: var(--devtools-space-xs);\n}\n\n.routes-filter-toggle {\n flex-shrink: 0;\n}\n\n.routes-filter-toggle--active {\n background-color: color-mix(in srgb, var(--devtools-primary) 15%, transparent);\n border-color: var(--devtools-primary);\n color: var(--devtools-primary);\n}\n\n.routes-filter-toggle__badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 var(--devtools-space-xs);\n background-color: var(--devtools-primary);\n color: var(--devtools-text-inverted);\n border-radius: 9px;\n font-size: var(--font-size-0);\n font-weight: var(--font-weight-6);\n}\n\n.routes-stats {\n display: flex;\n align-items: center;\n gap: var(--devtools-space-sm);\n margin-left: auto;\n font-size: var(--font-size-0);\n color: var(--devtools-text-muted);\n}\n\n.routes-stats__separator {\n opacity: 0.5;\n}\n\n/* Filter panel */\n.routes-filters {\n display: flex;\n flex-wrap: wrap;\n align-items: flex-start;\n gap: var(--devtools-space-lg);\n padding: var(--devtools-space-md);\n background-color: var(--devtools-surface-elevated);\n border-bottom: 1px solid var(--devtools-border);\n}\n\n.routes-filters__section {\n display: flex;\n flex-direction: column;\n gap: var(--devtools-space-sm);\n}\n\n.routes-filters__title {\n font-size: var(--font-size-0);\n font-weight: var(--font-weight-6);\n color: var(--devtools-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n margin: 0;\n}\n\n.routes-filters__methods {\n display: flex;\n flex-wrap: wrap;\n gap: var(--devtools-space-xs);\n}\n\n.routes-filters__methods .method-badge {\n cursor: pointer;\n transition: all var(--devtools-transition-fast);\n}\n\n.routes-filters__methods .method-badge--inactive {\n opacity: 0.4;\n}\n\n.routes-filters__status {\n display: flex;\n gap: var(--devtools-space-sm);\n}\n\n.routes-filters__status-btn {\n display: inline-flex;\n align-items: center;\n gap: var(--devtools-space-xs);\n padding: var(--devtools-space-xs) var(--devtools-space-sm);\n background-color: var(--devtools-surface);\n border: 1px solid var(--devtools-border);\n border-radius: var(--devtools-radius-sm);\n font-family: var(--devtools-font-sans);\n font-size: var(--font-size-0);\n color: var(--devtools-text-muted);\n cursor: pointer;\n transition: all var(--devtools-transition-fast);\n}\n\n.routes-filters__status-btn:hover {\n background-color: var(--devtools-surface-elevated);\n color: var(--devtools-text);\n}\n\n.routes-filters__status-btn--active {\n background-color: color-mix(in srgb, var(--devtools-primary) 15%, transparent);\n border-color: var(--devtools-primary);\n color: var(--devtools-primary);\n}\n\n.routes-filters__actions {\n display: flex;\n align-items: flex-end;\n margin-left: auto;\n}\n\n/* Main content */\n.routes-content {\n flex: 1;\n display: flex;\n overflow: hidden;\n}\n\n/* Loading state */\n.routes-loading {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n width: 100%;\n gap: var(--devtools-space-md);\n}\n\n.routes-loading__spinner {\n width: 32px;\n height: 32px;\n border: 3px solid var(--devtools-border);\n border-top-color: var(--devtools-primary);\n border-radius: 50%;\n animation: spin 1s linear infinite;\n}\n\n@keyframes spin {\n to {\n transform: rotate(360deg);\n }\n}\n\n/* Error state */\n.routes-error {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n width: 100%;\n gap: var(--devtools-space-md);\n padding: var(--devtools-space-xl);\n}\n\n.routes-error__message {\n color: var(--devtools-error);\n margin: 0;\n}\n\n/* Empty state */\n.routes-empty {\n width: 100%;\n}\n\n/* Split panels */\n.routes-list-panel {\n width: var(--devtools-sidebar-width);\n min-width: 200px;\n max-width: 400px;\n border-right: 1px solid var(--devtools-border);\n background-color: var(--devtools-surface);\n overflow: hidden;\n}\n\n.routes-detail-panel {\n flex: 1;\n overflow: hidden;\n background-color: var(--devtools-bg);\n}\n</style>\n"],"names":["Code","createLucideIcon","FileJson","Lock","Shield","Sprout","Tag","useRegistryStore","defineStore","endpoints","ref","stats","isLoading","error","searchQuery","filter","selectedEndpointKey","expandedTags","allTags","computed","tagSet","endpoint","tag","allSchemas","schemaSet","filteredEndpoints","result","query","groupedEndpoints","groups","groupKey","eps","a","b","selectedEndpoint","e","handlerCount","seedCount","setRegistryData","data","setLoading","loading","setError","errorMessage","clearError","setSearchQuery","toggleMethodFilter","method","index","setHandlerFilter","hasHandler","setSeedFilter","hasSeed","toggleTagFilter","clearFilters","hasActiveFilters","selectEndpoint","key","toggleGroup","expandAllGroups","group","collapseAllGroups","updateHandlerStatus","handlerOperationIds","handlerSet","updateSeedStatus","seedSchemas","seedSet","props","__props","hasSecurity","securityDisplay","sec","_openBlock","_createElementBlock","_hoisted_1","_hoisted_3","_createElementVNode","_hoisted_4","_normalizeClass","_unref","getMethodLabel","_hoisted_5","_toDisplayString","_hoisted_6","_hoisted_7","_createVNode","_cache","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","_hoisted_15","_hoisted_16","_Fragment","_renderList","_hoisted_17","_hoisted_18","_hoisted_19","_hoisted_20","_hoisted_21","_hoisted_22","_hoisted_23","_hoisted_24","_hoisted_25","_hoisted_26","_hoisted_27","_hoisted_28","_hoisted_2","emit","__emit","handleEndpointClick","handleGroupToggle","isSelected","$event","_createBlock","_resolveDynamicComponent","ChevronDown","ChevronRight","_vShow","registryStore","send","on","connected","useWebSocket","showFilters","searchInputRef","httpMethods","fetchRegistry","handleRegistryData","handleSelectEndpoint","handleToggleGroup","handleSearchInput","event","target","clearSearch","toggleMethod","isMethodActive","toggleHandlerFilter","current","toggleSeedFilter","clearAllFilters","toggleFilters","unsubRegistry","unsubHandlers","unsubSeeds","onMounted","onUnmounted","watch","isConnected","Search","X","Filter","ChevronUp","Route","EndpointList","EndpointDetail"],"mappings":"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","x_google_ignoreList":[0,1,2,3,4,5]}
@@ -1,6 +1,7 @@
1
1
  import { defineComponent as V, ref as m, computed as D, createElementBlock as r, openBlock as o, createElementVNode as e, createVNode as c, unref as l, withDirectives as f, Fragment as v, renderList as y, toDisplayString as d, vModelSelect as L, vModelText as N, normalizeClass as h, createBlock as S, resolveDynamicComponent as g, createCommentVNode as k } from "vue";
2
- import { c as U, Z as C, C as T, _ as B } from "./main-AUiFaD93.js";
3
- import { T as w, a as A } from "./triangle-alert-ZH4fYFnz.js";
2
+ import { c as U, Z as C, C as T, _ as B } from "./main-BxRf_QJn.js";
3
+ import { T as w } from "./triangle-alert-jXNj-fTF.js";
4
+ import { T as A } from "./trash-2-kFFQD_yH.js";
4
5
  const G = U("plus", [
5
6
  ["path", { d: "M5 12h14", key: "1ays0h" }],
6
7
  ["path", { d: "M12 5v14", key: "s699le" }]
@@ -222,8 +223,8 @@ const G = U("plus", [
222
223
  ])
223
224
  ]));
224
225
  }
225
- }), ue = /* @__PURE__ */ B(ae, [["__scopeId", "data-v-cf6df4d2"]]);
226
+ }), ce = /* @__PURE__ */ B(ae, [["__scopeId", "data-v-cf6df4d2"]]);
226
227
  export {
227
- ue as default
228
+ ce as default
228
229
  };
229
- //# sourceMappingURL=SimulatorPage-9sBeAxQI.js.map
230
+ //# sourceMappingURL=SimulatorPage-BeGppUDC.js.map