@open-mercato/core 0.6.1-develop.3256.1.fe3dec2464 → 0.6.1-develop.3260.1.dc719cac84
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/dist/helpers/integration/authFixtures.js.map +1 -1
- package/dist/helpers/integration/authUi.js +10 -2
- package/dist/helpers/integration/authUi.js.map +2 -2
- package/dist/helpers/integration/salesUi.js +3 -1
- package/dist/helpers/integration/salesUi.js.map +2 -2
- package/dist/modules/api_docs/frontend/docs/api/Explorer.js +10 -1
- package/dist/modules/api_docs/frontend/docs/api/Explorer.js.map +2 -2
- package/dist/modules/audit_logs/lib/display-helpers.js +28 -27
- package/dist/modules/audit_logs/lib/display-helpers.js.map +2 -2
- package/dist/modules/auth/api/users/route.js +21 -3
- package/dist/modules/auth/api/users/route.js.map +2 -2
- package/dist/modules/auth/backend/users/[id]/edit/page.js +6 -1
- package/dist/modules/auth/backend/users/[id]/edit/page.js.map +2 -2
- package/dist/modules/auth/backend/users/create/page.js +4 -1
- package/dist/modules/auth/backend/users/create/page.js.map +2 -2
- package/dist/modules/auth/backend/users/page.js +56 -2
- package/dist/modules/auth/backend/users/page.js.map +3 -3
- package/dist/modules/auth/commands/users.js +14 -0
- package/dist/modules/auth/commands/users.js.map +2 -2
- package/dist/modules/auth/data/validators.js +8 -0
- package/dist/modules/auth/data/validators.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js +1 -1
- package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/page.js +15 -9
- package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/pipeline/page.js +26 -3
- package/dist/modules/customers/backend/customers/deals/pipeline/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/people-v2/[id]/page.js +1 -1
- package/dist/modules/customers/backend/customers/people-v2/[id]/page.js.map +2 -2
- package/dist/modules/customers/components/PipelineSettings.js +108 -99
- package/dist/modules/customers/components/PipelineSettings.js.map +2 -2
- package/dist/modules/customers/components/detail/AssignRoleDialog.js +13 -5
- package/dist/modules/customers/components/detail/AssignRoleDialog.js.map +2 -2
- package/dist/modules/customers/components/detail/EntityTagsDialog.js +10 -2
- package/dist/modules/customers/components/detail/EntityTagsDialog.js.map +2 -2
- package/dist/modules/customers/components/detail/PersonCompaniesSection.js +15 -8
- package/dist/modules/customers/components/detail/PersonCompaniesSection.js.map +2 -2
- package/dist/modules/customers/components/detail/RolesSection.js +35 -22
- package/dist/modules/customers/components/detail/RolesSection.js.map +2 -2
- package/dist/modules/customers/components/detail/TasksSection.js +2 -2
- package/dist/modules/customers/components/detail/TasksSection.js.map +2 -2
- package/dist/modules/customers/components/detail/schedule/DateTimeFields.js +73 -64
- package/dist/modules/customers/components/detail/schedule/DateTimeFields.js.map +2 -2
- package/dist/modules/customers/components/linking/LinkEntityDialog.js +11 -2
- package/dist/modules/customers/components/linking/LinkEntityDialog.js.map +2 -2
- package/dist/modules/data_sync/backend/data-sync/page.js +2 -9
- package/dist/modules/data_sync/backend/data-sync/page.js.map +2 -2
- package/dist/modules/data_sync/backend/data-sync/runs/[id]/page.js +14 -29
- package/dist/modules/data_sync/backend/data-sync/runs/[id]/page.js.map +2 -2
- package/dist/modules/dictionaries/components/DictionariesManager.js +10 -2
- package/dist/modules/dictionaries/components/DictionariesManager.js.map +2 -2
- package/dist/modules/integrations/backend/integrations/[id]/page.js +79 -95
- package/dist/modules/integrations/backend/integrations/[id]/page.js.map +2 -2
- package/dist/modules/payment_gateways/backend/payment-gateways/page.js +49 -70
- package/dist/modules/payment_gateways/backend/payment-gateways/page.js.map +2 -2
- package/dist/modules/planner/components/AvailabilityRuleSetForm.js +1 -1
- package/dist/modules/planner/components/AvailabilityRuleSetForm.js.map +1 -1
- package/dist/modules/planner/components/AvailabilityRulesEditor.js +19 -19
- package/dist/modules/planner/components/AvailabilityRulesEditor.js.map +2 -2
- package/dist/modules/resources/components/ResourceCrudForm.js +1 -1
- package/dist/modules/resources/components/ResourceCrudForm.js.map +1 -1
- package/dist/modules/resources/components/ResourceTypeCrudForm.js +1 -1
- package/dist/modules/resources/components/ResourceTypeCrudForm.js.map +2 -2
- package/dist/modules/sales/components/documents/ReturnDialog.js +11 -8
- package/dist/modules/sales/components/documents/ReturnDialog.js.map +2 -2
- package/dist/modules/staff/backend/staff/profile/create/page.js +1 -1
- package/dist/modules/staff/backend/staff/profile/create/page.js.map +2 -2
- package/dist/modules/staff/components/TeamForm.js +1 -1
- package/dist/modules/staff/components/TeamForm.js.map +2 -2
- package/dist/modules/staff/components/TeamMemberForm.js +1 -1
- package/dist/modules/staff/components/TeamMemberForm.js.map +1 -1
- package/dist/modules/staff/components/TeamRoleForm.js +1 -1
- package/dist/modules/staff/components/TeamRoleForm.js.map +2 -2
- package/package.json +5 -5
- package/src/helpers/integration/authFixtures.ts +1 -1
- package/src/helpers/integration/authUi.ts +11 -2
- package/src/helpers/integration/salesUi.ts +10 -1
- package/src/modules/api_docs/frontend/docs/api/Explorer.tsx +7 -3
- package/src/modules/audit_logs/lib/display-helpers.tsx +22 -14
- package/src/modules/auth/api/users/route.ts +22 -3
- package/src/modules/auth/backend/users/[id]/edit/page.tsx +9 -1
- package/src/modules/auth/backend/users/create/page.tsx +6 -2
- package/src/modules/auth/backend/users/page.tsx +60 -3
- package/src/modules/auth/commands/users.ts +15 -0
- package/src/modules/auth/data/validators.ts +8 -0
- package/src/modules/auth/i18n/de.json +4 -0
- package/src/modules/auth/i18n/en.json +4 -0
- package/src/modules/auth/i18n/es.json +4 -0
- package/src/modules/auth/i18n/pl.json +4 -0
- package/src/modules/customers/backend/customers/companies-v2/[id]/page.tsx +1 -1
- package/src/modules/customers/backend/customers/deals/[id]/page.tsx +12 -13
- package/src/modules/customers/backend/customers/deals/pipeline/page.tsx +17 -13
- package/src/modules/customers/backend/customers/people-v2/[id]/page.tsx +1 -1
- package/src/modules/customers/components/PipelineSettings.tsx +95 -95
- package/src/modules/customers/components/detail/AssignRoleDialog.tsx +7 -4
- package/src/modules/customers/components/detail/EntityTagsDialog.tsx +13 -8
- package/src/modules/customers/components/detail/PersonCompaniesSection.tsx +16 -12
- package/src/modules/customers/components/detail/RolesSection.tsx +34 -31
- package/src/modules/customers/components/detail/TasksSection.tsx +16 -8
- package/src/modules/customers/components/detail/schedule/DateTimeFields.tsx +77 -51
- package/src/modules/customers/components/linking/LinkEntityDialog.tsx +7 -3
- package/src/modules/data_sync/backend/data-sync/page.tsx +4 -7
- package/src/modules/data_sync/backend/data-sync/runs/[id]/page.tsx +19 -54
- package/src/modules/dictionaries/components/DictionariesManager.tsx +7 -4
- package/src/modules/integrations/backend/integrations/[id]/page.tsx +101 -146
- package/src/modules/payment_gateways/backend/payment-gateways/page.tsx +60 -103
- package/src/modules/planner/components/AvailabilityRuleSetForm.tsx +1 -1
- package/src/modules/planner/components/AvailabilityRulesEditor.tsx +17 -17
- package/src/modules/resources/components/ResourceCrudForm.tsx +1 -1
- package/src/modules/resources/components/ResourceTypeCrudForm.tsx +1 -1
- package/src/modules/sales/components/documents/ReturnDialog.tsx +10 -7
- package/src/modules/sales/i18n/de.json +2 -0
- package/src/modules/sales/i18n/en.json +2 -0
- package/src/modules/sales/i18n/es.json +2 -0
- package/src/modules/sales/i18n/pl.json +2 -0
- package/src/modules/staff/backend/staff/profile/create/page.tsx +1 -1
- package/src/modules/staff/components/TeamForm.tsx +1 -1
- package/src/modules/staff/components/TeamMemberForm.tsx +1 -1
- package/src/modules/staff/components/TeamRoleForm.tsx +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/modules/api_docs/frontend/docs/api/Explorer.tsx"],
|
|
4
|
-
"sourcesContent": ["'use client'\n\nimport { useEffect, useMemo, useState, type ReactNode } from 'react'\nimport Image from 'next/image'\nimport Link from 'next/link'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\n\nconst METHOD_STYLES: Record<string, string> = {\n GET: 'bg-emerald-100 text-emerald-800 border border-emerald-200',\n POST: 'bg-blue-100 text-blue-800 border border-blue-200',\n PUT: 'bg-amber-100 text-amber-800 border border-amber-200',\n PATCH: 'bg-purple-100 text-purple-800 border border-purple-200',\n DELETE: 'bg-rose-100 text-rose-800 border border-rose-200',\n}\n\nconst PREFERRED_MEDIA_TYPES = [\n 'application/json',\n 'application/x-www-form-urlencoded',\n 'multipart/form-data',\n 'text/plain',\n]\n\ntype ExplorerOperation = {\n id: string\n path: string\n method: string\n tag: string\n summary?: string\n description?: string\n operation: any\n}\n\ntype ServerOption = { url: string; description?: string }\n\ntype ApiDocsExplorerProps = {\n title: string\n version: string\n description?: string\n operations: ExplorerOperation[]\n tagOrder: string[]\n servers: ServerOption[]\n docsUrl: string\n jsonSpecUrl: string\n markdownSpecUrl: string\n}\n\ntype ContentVariant = {\n mediaType: string\n entry: any\n}\n\ntype TestResponse = {\n status: number\n durationMs: number\n ok: boolean\n body: string\n parsed?: unknown\n}\n\nfunction pickContentVariant(content?: Record<string, any>): ContentVariant | null {\n if (!content) return null\n const entries = Object.entries(content)\n if (!entries.length) return null\n for (const mediaType of PREFERRED_MEDIA_TYPES) {\n const match = entries.find(([candidate]) => candidate === mediaType)\n if (match) {\n return { mediaType: match[0], entry: match[1] }\n }\n }\n const [mediaType, entry] = entries[0]\n return { mediaType, entry }\n}\n\nfunction buildExampleFromSchema(schema: any): unknown {\n if (!schema || typeof schema !== 'object') return undefined\n if (schema.example !== undefined) return schema.example\n if (schema.default !== undefined) return schema.default\n if (Array.isArray(schema.enum) && schema.enum.length) return schema.enum[0]\n\n if (Array.isArray(schema.oneOf) && schema.oneOf.length) return buildExampleFromSchema(schema.oneOf[0])\n if (Array.isArray(schema.anyOf) && schema.anyOf.length) return buildExampleFromSchema(schema.anyOf[0])\n if (Array.isArray(schema.allOf) && schema.allOf.length) {\n return Object.assign({}, ...schema.allOf.map((part: any) => buildExampleFromSchema(part) ?? {}))\n }\n\n const type = Array.isArray(schema.type) ? schema.type[0] : schema.type\n\n if (schema.properties || type === 'object' || (!type && schema.required)) {\n const properties = schema.properties ?? {}\n const result: Record<string, unknown> = {}\n for (const key of Object.keys(properties)) {\n const value = buildExampleFromSchema(properties[key])\n if (value !== undefined) {\n result[key] = value\n }\n }\n if (schema.additionalProperties && typeof schema.additionalProperties === 'object') {\n const value = buildExampleFromSchema(schema.additionalProperties)\n if (value !== undefined) {\n result['additionalProperty'] = value\n }\n }\n return Object.keys(result).length ? result : {}\n }\n\n if (type === 'array') {\n const itemSchema = schema.items ?? (Array.isArray(schema.prefixItems) ? schema.prefixItems[0] : undefined)\n const value = buildExampleFromSchema(itemSchema)\n return value === undefined ? [] : [value]\n }\n\n if (type === 'number' || type === 'integer') return 1\n if (type === 'boolean') return true\n if (schema.format === 'date-time') return new Date('2025-01-01T00:00:00.000Z').toISOString()\n if (schema.format === 'uuid') return '00000000-0000-4000-8000-000000000000'\n if (schema.format === 'email') return 'user@example.com'\n if (schema.format === 'uri' || schema.format === 'url') return 'https://example.com/resource'\n\n return 'string'\n}\n\nfunction stringifyExample(mediaType: string, example: unknown): string {\n if (example === undefined || example === null) return ''\n if (mediaType === 'application/json') {\n try {\n return JSON.stringify(example, null, 2)\n } catch {\n return ''\n }\n }\n if (mediaType === 'application/x-www-form-urlencoded') {\n if (typeof example !== 'object') return ''\n const params = new URLSearchParams()\n for (const [key, value] of Object.entries(example as Record<string, unknown>)) {\n if (value === undefined) continue\n params.append(key, value === null ? '' : String(value))\n }\n return params.toString()\n }\n if (mediaType === 'multipart/form-data') {\n if (typeof example === 'object') {\n return Object.entries(example as Record<string, unknown>)\n .map(([key, value]) => `${key}=${value ?? ''}`)\n .join('\\n')\n }\n return typeof example === 'string' ? example : ''\n }\n if (typeof example === 'string') return example\n try {\n return JSON.stringify(example, null, 2)\n } catch {\n return ''\n }\n}\n\nfunction formatJson(value: unknown): string {\n try {\n return JSON.stringify(value, null, 2)\n } catch {\n return ''\n }\n}\n\nfunction applyPathParams(path: string, params: Record<string, string>): string {\n return path.replace(/\\{([^}]+)\\}/g, (_, key: string) => {\n const value = params[key] ?? ''\n return value ? encodeURIComponent(value) : `{${key}}`\n })\n}\n\ntype Category = {\n tag: string\n operations: ExplorerOperation[]\n}\n\nconst PLACEHOLDER_BASE_URL = 'https://api.your-service.com'\nconst CATEGORY_PAGE_SIZE = 20\n\ntype RequestPreview = {\n method: string\n url: string\n headers: Array<[string, string]>\n body?: string\n jsonBody?: unknown\n mediaType?: string\n usesPlaceholderBase: boolean\n missingPathParam?: string\n bodyParseError?: string\n baseError?: string\n}\n\ntype CodeSnippet = {\n id: string\n label: string\n language: string\n code: string\n}\n\nfunction escapeSingleQuotes(value: string): string {\n return value.replace(/'/g, `'\\\\''`)\n}\n\nfunction escapeSingleQuotesForJs(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\")\n}\n\nfunction escapeBackticks(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/`/g, '\\\\`')\n}\n\nfunction toPythonLiteral(value: unknown, indent = 0): string {\n const padding = ' '.repeat(indent)\n if (value === null || value === undefined) return 'None'\n if (typeof value === 'boolean') return value ? 'True' : 'False'\n if (typeof value === 'number' && Number.isFinite(value)) return String(value)\n if (typeof value === 'string') {\n return `'${value.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\")}'`\n }\n if (Array.isArray(value)) {\n if (!value.length) return '[]'\n const entries = value\n .map((item) => `${' '.repeat(indent + 1)}${toPythonLiteral(item, indent + 1)}`)\n .join(',\\n')\n return `[\\n${entries},\\n${padding}]`\n }\n if (typeof value === 'object') {\n const entries = Object.entries(value as Record<string, unknown>)\n if (!entries.length) return '{}'\n const lines = entries.map(\n ([key, entry]) =>\n `${' '.repeat(indent + 1)}'${key.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\")}': ${toPythonLiteral(entry, indent + 1)}`\n )\n return `{\\n${lines.join(',\\n')},\\n${padding}}`\n }\n return 'None'\n}\n\nexport default function ApiDocsExplorer(props: ApiDocsExplorerProps) {\n const { title, version, description, operations, tagOrder, servers, docsUrl, jsonSpecUrl, markdownSpecUrl } = props\n\n const methodOptions = useMemo(\n () => Array.from(new Set(operations.map((operation) => operation.method))).sort((a, b) => a.localeCompare(b)),\n [operations]\n )\n\n const operationsById = useMemo(() => {\n const map = new Map<string, ExplorerOperation>()\n for (const operation of operations) {\n map.set(operation.id, operation)\n }\n return map\n }, [operations])\n\n const [searchTerm, setSearchTerm] = useState('')\n const [methodFilter, setMethodFilter] = useState<string[]>(methodOptions)\n const [selectedId, setSelectedId] = useState<string>(operations[0]?.id ?? '')\n const [isNavOpen, setIsNavOpen] = useState(false)\n const [isTesterOpen, setIsTesterOpen] = useState(false)\n const [expanded, setExpanded] = useState<Record<string, boolean>>({})\n const [visibleCounts, setVisibleCounts] = useState<Record<string, number>>({})\n const [baseUrl, setBaseUrl] = useState<string>(servers[0]?.url ?? '')\n const [apiKey, setApiKey] = useState<string>('')\n\n useEffect(() => {\n setMethodFilter(methodOptions)\n }, [methodOptions])\n\n useEffect(() => {\n if (servers.length === 0) return\n setBaseUrl((prev) => {\n if (!prev) return servers[0].url\n return prev\n })\n }, [servers])\n\n const filteredOperations = useMemo(() => {\n const lowered = searchTerm.trim().toLowerCase()\n return operations.filter((operation) => {\n if (!methodFilter.includes(operation.method)) return false\n if (!lowered) return true\n return (\n operation.path.toLowerCase().includes(lowered) ||\n (operation.summary && operation.summary.toLowerCase().includes(lowered)) ||\n (operation.description && operation.description.toLowerCase().includes(lowered))\n )\n })\n }, [operations, methodFilter, searchTerm])\n\n const categories = useMemo(() => {\n const grouped = new Map<string, ExplorerOperation[]>()\n for (const operation of filteredOperations) {\n const list = grouped.get(operation.tag) ?? []\n list.push(operation)\n grouped.set(operation.tag, list)\n }\n const ordered: Category[] = []\n for (const tag of tagOrder) {\n const list = grouped.get(tag)\n if (list && list.length) {\n ordered.push({ tag, operations: list })\n grouped.delete(tag)\n }\n }\n const remaining = Array.from(grouped.entries()).sort(([a], [b]) => a.localeCompare(b))\n for (const [tag, ops] of remaining) {\n ordered.push({ tag, operations: ops })\n }\n return ordered\n }, [filteredOperations, tagOrder])\n\n useEffect(() => {\n setExpanded((prev) => {\n const next: Record<string, boolean> = {}\n for (const category of categories) {\n next[category.tag] = prev[category.tag] ?? true\n }\n return next\n })\n setVisibleCounts((prev) => {\n const next: Record<string, number> = {}\n for (const category of categories) {\n const total = category.operations.length\n const previous = prev[category.tag] ?? CATEGORY_PAGE_SIZE\n next[category.tag] = Math.min(total, previous)\n }\n return next\n })\n }, [categories])\n\n useEffect(() => {\n if (!selectedId && filteredOperations.length) {\n setSelectedId(filteredOperations[0].id)\n return\n }\n if (selectedId && filteredOperations.some((operation) => operation.id === selectedId)) return\n if (filteredOperations.length) {\n setSelectedId(filteredOperations[0].id)\n }\n }, [filteredOperations, selectedId])\n\n const selectedOperation =\n (selectedId ? operationsById.get(selectedId) : undefined) ?? filteredOperations[0] ?? operations[0] ?? null\n\n const shouldOpenTesterOverlay = () => {\n if (typeof window === 'undefined') return false\n return window.innerWidth < 1280\n }\n\n const handleSelectOperation = (operationId: string) => {\n setSelectedId(operationId)\n const targetCategory = categories.find((category) =>\n category.operations.some((operation) => operation.id === operationId)\n )\n if (targetCategory) {\n const index = targetCategory.operations.findIndex((operation) => operation.id === operationId)\n if (index >= 0) {\n setVisibleCounts((prev) => {\n const currentVisible = prev[targetCategory.tag] ?? CATEGORY_PAGE_SIZE\n if (index < currentVisible) return prev\n return { ...prev, [targetCategory.tag]: index + 1 }\n })\n }\n }\n requestAnimationFrame(() => {\n const element = document.getElementById(`operation-${operationId}`)\n if (element) element.scrollIntoView({ behavior: 'smooth', block: 'start', inline: 'nearest' })\n })\n if (shouldOpenTesterOverlay()) setIsTesterOpen(true)\n setIsNavOpen(false)\n }\n\n return (\n <div className=\"min-h-screen bg-background text-foreground\">\n <header className=\"border-b bg-card\">\n <div className=\"mx-auto flex w-full max-w-screen-2xl flex-col gap-4 px-6 py-6 lg:flex-row lg:items-center lg:justify-between\">\n <div className=\"flex items-center gap-4\">\n <button\n type=\"button\"\n className=\"inline-flex h-10 w-10 items-center justify-center rounded-md border border-border text-sm font-medium text-muted-foreground hover:border-foreground hover:text-foreground lg:hidden\"\n onClick={() => setIsNavOpen(true)}\n >\n <span className=\"sr-only\">Open navigation</span>\n \u2630\n </button>\n <Link href=\"/\" className=\"flex items-center gap-3\">\n <Image src=\"/open-mercato.svg\" alt=\"Open Mercato\" width={36} height={36} />\n <div>\n <div className=\"text-base font-semibold leading-tight\">{title}</div>\n <div className=\"text-xs text-muted-foreground\">Version {version}</div>\n </div>\n </Link>\n </div>\n <div className=\"flex flex-wrap items-center justify-end gap-2\">\n <nav className=\"hidden items-center gap-2 text-xs text-muted-foreground sm:flex\">\n <Link href=\"/\" className=\"hover:text-foreground hover:underline\">\n Home\n </Link>\n <span>/</span>\n <span>Docs</span>\n <span>/</span>\n <span className=\"font-medium text-foreground\">API Explorer</span>\n </nav>\n <button\n type=\"button\"\n className=\"inline-flex h-10 items-center justify-center rounded-md border border-border px-3 text-sm font-medium text-muted-foreground hover:border-foreground hover:text-foreground xl:hidden\"\n onClick={() => setIsTesterOpen(true)}\n >\n Try Endpoint\n </button>\n <Link\n href={jsonSpecUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"inline-flex h-10 items-center justify-center rounded-md border border-border px-3 text-sm font-medium text-muted-foreground hover:border-foreground hover:text-foreground\"\n >\n OpenAPI JSON\n </Link>\n <Link\n href={markdownSpecUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"inline-flex h-10 items-center justify-center rounded-md border border-border px-3 text-sm font-medium text-muted-foreground hover:border-foreground hover:text-foreground\"\n >\n Markdown Docs\n </Link>\n <Link\n href={docsUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"hidden rounded-md border border-primary/30 px-4 py-2 text-sm font-medium text-primary hover:bg-primary/10 sm:inline-flex\"\n >\n View full docs\n </Link>\n </div>\n </div>\n </header>\n\n <main className=\"mx-auto flex w-full max-w-screen-2xl flex-1 flex-col px-6 py-8 lg:flex-row lg:gap-6\">\n <aside className=\"hidden w-64 shrink-0 lg:block\">\n <div className=\"sticky top-20 max-h-[calc(100vh-6rem)] overflow-y-auto rounded-lg border bg-card p-4\">\n <h2 className=\"text-sm font-semibold uppercase tracking-wide text-muted-foreground\">API Categories</h2>\n <nav className=\"mt-4 space-y-4 text-sm\">\n {categories.map((category) => {\n const isExpanded = expanded[category.tag] ?? true\n return (\n <div key={category.tag} className=\"space-y-2\">\n <button\n type=\"button\"\n className=\"flex w-full items-center justify-between rounded-md bg-muted px-3 py-2 text-left font-medium text-foreground hover:bg-muted/50\"\n onClick={() =>\n setExpanded((prev) => ({\n ...prev,\n [category.tag]: !isExpanded,\n }))\n }\n >\n <span>{category.tag}</span>\n <span className=\"text-xs text-muted-foreground\">{isExpanded ? '\u2212' : '+'}</span>\n </button>\n {isExpanded ? (\n <ul className=\"space-y-1 pl-2\">\n {category.operations.map((operation) => (\n <li key={operation.id}>\n <button\n type=\"button\"\n className={`flex w-full items-center gap-2 rounded-md px-3 py-2 text-left transition ${\n selectedOperation?.id === operation.id\n ? 'bg-primary/10 text-primary'\n : 'text-muted-foreground hover:bg-muted hover:text-foreground'\n }`}\n onClick={() => handleSelectOperation(operation.id)}\n >\n <span\n className={`inline-flex min-w-[3rem] justify-center rounded border px-2 py-0.5 text-overline font-semibold uppercase ${\n METHOD_STYLES[operation.method] ?? 'border border-border bg-muted text-foreground'\n }`}\n >\n {operation.method}\n </span>\n <span className=\"truncate text-xs\">{operation.path}</span>\n </button>\n </li>\n ))}\n </ul>\n ) : null}\n </div>\n )\n })}\n </nav>\n </div>\n </aside>\n\n <section className=\"flex-1 space-y-6\">\n <div className=\"rounded-lg border bg-card p-5 shadow-sm\">\n <div className=\"space-y-3\">\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">OpenAPI Explorer</h1>\n {description ? <p className=\"text-sm text-muted-foreground\">{description}</p> : null}\n </div>\n <div className=\"text-xs text-muted-foreground\">\n {servers[0]?.url ? <span>Default server: {servers[0].url}</span> : <span>Server URL not configured.</span>}\n </div>\n </div>\n <div className=\"flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between\">\n <div className=\"flex flex-1 items-center gap-3\">\n <Input\n type=\"search\"\n value={searchTerm}\n onChange={(event) => setSearchTerm(event.target.value)}\n placeholder=\"Search endpoints by path or summary\"\n className=\"flex-1\"\n />\n </div>\n <div className=\"flex flex-wrap gap-2 text-xs\">\n {methodOptions.map((method) => {\n const isActive = methodFilter.includes(method)\n return (\n <button\n key={method}\n type=\"button\"\n className={`rounded-md border px-3 py-1 font-semibold uppercase transition ${\n isActive\n ? 'border-primary bg-primary/10 text-primary'\n : 'border-border text-muted-foreground hover:border-foreground hover:text-foreground'\n }`}\n onClick={() => {\n setMethodFilter((prev) => {\n if (prev.includes(method)) {\n const next = prev.filter((entry) => entry !== method)\n return next.length ? next : prev\n }\n return [...prev, method]\n })\n }}\n >\n {method}\n </button>\n )\n })}\n </div>\n </div>\n </div>\n </div>\n\n <div className=\"space-y-8\">\n {categories.map((category) => {\n const totalCount = category.operations.length\n const visibleCount = Math.min(\n totalCount,\n visibleCounts[category.tag] ?? CATEGORY_PAGE_SIZE\n )\n const visibleOperations = category.operations.slice(0, visibleCount)\n const hiddenCount = totalCount - visibleCount\n return (\n <div key={category.tag} className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold\">{category.tag}</h2>\n <div className=\"text-xs text-muted-foreground\">\n Showing {visibleCount} of {totalCount} endpoints\n </div>\n </div>\n <div className=\"space-y-6\">\n {visibleOperations.map((operation) => {\n const methodClass = METHOD_STYLES[operation.method] ?? 'border border-border bg-muted text-foreground'\n const operationId = `operation-${operation.id}`\n const contentVariant = pickContentVariant(operation.operation?.requestBody?.content)\n const contentExample =\n contentVariant?.entry?.example ??\n contentVariant?.entry?.examples?.default?.value ??\n buildExampleFromSchema(contentVariant?.entry?.schema)\n const requestSnippet =\n contentVariant && contentExample\n ? stringifyExample(contentVariant.mediaType, contentExample)\n : undefined\n\n return (\n <article\n key={operation.id}\n id={operationId}\n className={`rounded-lg border bg-card shadow-sm transition ${\n selectedOperation?.id === operation.id ? 'ring-2 ring-primary/40' : ''\n }`}\n >\n <div className=\"flex flex-col gap-4 border-b bg-muted/50 px-5 py-4 md:flex-row md:items-center md:justify-between\">\n <div className=\"flex items-center gap-3\">\n <span className={`rounded px-3 py-1 text-xs font-semibold uppercase ${methodClass}`}>\n {operation.method}\n </span>\n <code className=\"text-sm text-foreground\">{operation.path}</code>\n </div>\n <div className=\"flex items-center gap-2 text-overline text-muted-foreground\">\n {operation.operation?.['x-require-auth'] ? (\n <span className=\"rounded bg-amber-100 px-2 py-0.5 text-amber-900\">Auth required</span>\n ) : null}\n {Array.isArray(operation.operation?.['x-require-features'])\n ? operation.operation['x-require-features'].map((feature: string) => (\n <span key={feature} className=\"rounded bg-blue-100 px-2 py-0.5 text-blue-900\">\n {feature}\n </span>\n ))\n : null}\n </div>\n </div>\n <div className=\"space-y-5 p-5\">\n <div className=\"space-y-2\">\n {operation.summary ? <h3 className=\"text-lg font-semibold\">{operation.summary}</h3> : null}\n {operation.description ? (\n <p className=\"text-sm text-muted-foreground whitespace-pre-line\">\n {operation.description}\n </p>\n ) : null}\n </div>\n\n {Array.isArray(operation.operation?.parameters) &&\n operation.operation.parameters.length ? (\n <section className=\"space-y-3\">\n <h4 className=\"text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n Parameters\n </h4>\n <div className=\"overflow-hidden rounded-lg border\">\n <table className=\"min-w-full divide-y divide-border text-left text-xs\">\n <thead className=\"bg-muted/50 text-overline uppercase tracking-wide text-muted-foreground\">\n <tr>\n <th className=\"px-3 py-2 font-medium\">Name</th>\n <th className=\"px-3 py-2 font-medium\">In</th>\n <th className=\"px-3 py-2 font-medium\">Required</th>\n <th className=\"px-3 py-2 font-medium\">Schema</th>\n <th className=\"px-3 py-2 font-medium\">Description</th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-border text-xs\">\n {operation.operation.parameters.map((parameter: any) => (\n <tr key={`${parameter.in}-${parameter.name}`}>\n <td className=\"px-3 py-2 font-medium text-foreground\">{parameter.name}</td>\n <td className=\"px-3 py-2 text-muted-foreground\">{parameter.in}</td>\n <td className=\"px-3 py-2 text-muted-foreground\">\n {parameter.required ? 'Yes' : 'No'}\n </td>\n <td className=\"px-3 py-2 text-muted-foreground\">\n {parameter.schema?.type ?? 'any'}\n </td>\n <td className=\"px-3 py-2 text-muted-foreground\">\n {parameter.description ?? '\u2014'}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </section>\n ) : null}\n\n {contentVariant ? (\n <section className=\"space-y-3\">\n <h4 className=\"text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n Request body ({contentVariant.mediaType})\n </h4>\n {requestSnippet ? (\n <pre className=\"max-h-80 overflow-auto rounded-lg bg-muted px-4 py-3 text-xs leading-relaxed\">\n {requestSnippet}\n </pre>\n ) : (\n <p className=\"text-xs text-muted-foreground\">\n No example available for this content type.\n </p>\n )}\n </section>\n ) : null}\n\n {operation.operation?.responses ? (\n <section className=\"space-y-3\">\n <h4 className=\"text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n Responses\n </h4>\n <div className=\"space-y-3\">\n {Object.entries(operation.operation.responses).map(([status, response]: [string, any]) => {\n if (response?.['x-autoGenerated']) return null\n const responseVariant = pickContentVariant(response?.content)\n const responseExample =\n responseVariant?.entry?.example ??\n responseVariant?.entry?.examples?.default?.value ??\n buildExampleFromSchema(responseVariant?.entry?.schema)\n const responseSnippet =\n responseVariant && responseExample\n ? stringifyExample(responseVariant.mediaType, responseExample)\n : undefined\n\n return (\n <div key={status} className=\"rounded-lg border\">\n <div className=\"flex items-center justify-between border-b bg-muted/50 px-4 py-2 text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n <span>{status}</span>\n <span className=\"text-muted-foreground\">\n {response?.description ?? 'Response'}\n </span>\n </div>\n {responseVariant ? (\n <div className=\"border-b bg-muted/50 px-4 py-2 text-overline text-muted-foreground\">\n Content-Type: {responseVariant.mediaType}\n </div>\n ) : null}\n {responseSnippet ? (\n <pre className=\"max-h-80 overflow-auto bg-muted px-4 py-3 text-xs leading-relaxed\">\n {responseSnippet}\n </pre>\n ) : (\n <p className=\"px-4 py-3 text-xs text-muted-foreground\">\n {responseVariant ? 'No example available for this content type.' : 'No response body.'}\n </p>\n )}\n </div>\n )\n })}\n </div>\n </section>\n ) : null}\n\n {Array.isArray(operation.operation?.['x-codeSamples']) &&\n operation.operation['x-codeSamples'].length ? (\n <section className=\"space-y-3\">\n <h4 className=\"text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n Example\n </h4>\n <pre className=\"overflow-auto rounded-lg bg-muted px-4 py-3 text-xs leading-relaxed\">\n {operation.operation['x-codeSamples'][0].source}\n </pre>\n </section>\n ) : null}\n\n <div className=\"flex flex-wrap gap-3\">\n <button\n type=\"button\"\n className=\"inline-flex items-center rounded-md border border-primary px-4 py-2 text-sm font-semibold text-primary hover:bg-primary/10\"\n onClick={() => {\n setSelectedId(operation.id)\n if (shouldOpenTesterOverlay()) setIsTesterOpen(true)\n }}\n >\n Test this endpoint\n </button>\n <button\n type=\"button\"\n className=\"inline-flex items-center rounded-md border border-border px-4 py-2 text-sm text-muted-foreground hover:border-foreground hover:text-foreground\"\n onClick={() => handleSelectOperation(operation.id)}\n >\n Jump to tester\n </button>\n </div>\n </div>\n </article>\n )\n })}\n </div>\n {hiddenCount > 0 ? (\n <div className=\"flex justify-center\">\n <button\n type=\"button\"\n className=\"inline-flex items-center rounded-md border border-border px-4 py-2 text-sm font-medium text-muted-foreground hover:border-foreground hover:text-foreground\"\n onClick={() =>\n setVisibleCounts((prev) => ({\n ...prev,\n [category.tag]: Math.min(\n totalCount,\n (prev[category.tag] ?? CATEGORY_PAGE_SIZE) + CATEGORY_PAGE_SIZE\n ),\n }))\n }\n >\n Show {Math.min(CATEGORY_PAGE_SIZE, hiddenCount)} more endpoints\n </button>\n </div>\n ) : null}\n </div>\n )\n })}\n {!categories.length ? (\n <div className=\"rounded-lg border border-dashed bg-muted/50 p-6 text-center text-sm text-muted-foreground\">\n No endpoints match your filters. Try adjusting the method filters or clearing the search query.\n </div>\n ) : null}\n </div>\n </section>\n\n <aside className=\"hidden w-96 shrink-0 xl:block\">\n <div className=\"sticky top-20 max-h-[calc(100vh-6rem)] overflow-y-auto\">\n <TesterPanel\n key={selectedOperation?.id ?? 'tester'}\n operation={selectedOperation}\n baseUrl={baseUrl}\n setBaseUrl={setBaseUrl}\n baseUrlOptions={servers}\n apiKey={apiKey}\n setApiKey={setApiKey}\n />\n </div>\n </aside>\n </main>\n\n <footer className=\"border-t bg-card\">\n <div className=\"mx-auto flex w-full max-w-screen-2xl flex-col gap-4 px-6 py-6 md:flex-row md:items-center md:justify-between\">\n <div className=\"text-sm text-muted-foreground\">\u00A9 {new Date().getFullYear()} Open Mercato. All rights reserved.</div>\n <div className=\"flex flex-wrap items-center gap-4 text-sm text-muted-foreground\">\n <Link href={docsUrl} target=\"_blank\" rel=\"noreferrer\" className=\"hover:text-foreground hover:underline\">\n Documentation\n </Link>\n <Link\n href=\"https://openmercato.com/privacy\"\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"hover:text-foreground hover:underline\"\n >\n Privacy\n </Link>\n <Link\n href=\"https://openmercato.com/terms\"\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"hover:text-foreground hover:underline\"\n >\n Terms\n </Link>\n </div>\n </div>\n </footer>\n\n {isNavOpen ? (\n <MobileOverlay title=\"API categories\" onClose={() => setIsNavOpen(false)}>\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-sm font-semibold uppercase tracking-wide text-muted-foreground\">API Categories</h2>\n <button\n type=\"button\"\n className=\"text-sm text-muted-foreground hover:text-foreground\"\n onClick={() => setIsNavOpen(false)}\n >\n Close\n </button>\n </div>\n <div className=\"max-h-[70vh] space-y-4 overflow-y-auto\">\n {categories.map((category) => (\n <div key={`mobile-${category.tag}`} className=\"space-y-2\">\n <div className=\"font-semibold text-foreground\">{category.tag}</div>\n <ul className=\"space-y-2\">\n {category.operations.map((operation) => (\n <li key={`mobile-${operation.id}`}>\n <button\n type=\"button\"\n className={`flex w-full items-center gap-2 rounded-md border px-3 py-2 text-left text-sm ${\n selectedOperation?.id === operation.id\n ? 'border-primary text-primary'\n : 'border-border text-muted-foreground'\n }`}\n onClick={() => handleSelectOperation(operation.id)}\n >\n <span\n className={`inline-flex min-w-[3rem] justify-center rounded border px-2 py-0.5 text-overline font-semibold uppercase ${\n METHOD_STYLES[operation.method] ?? 'border border-border bg-muted text-foreground'\n }`}\n >\n {operation.method}\n </span>\n <span className=\"truncate\">{operation.path}</span>\n </button>\n </li>\n ))}\n </ul>\n </div>\n ))}\n </div>\n </div>\n </MobileOverlay>\n ) : null}\n\n {isTesterOpen ? (\n <MobileOverlay title=\"API tester\" onClose={() => setIsTesterOpen(false)}>\n <TesterPanel\n key={`mobile-${selectedOperation?.id ?? 'tester'}`}\n operation={selectedOperation}\n baseUrl={baseUrl}\n setBaseUrl={setBaseUrl}\n baseUrlOptions={servers}\n apiKey={apiKey}\n setApiKey={setApiKey}\n />\n </MobileOverlay>\n ) : null}\n </div>\n )\n}\n\nfunction CodeSnippetTabs(props: { snippets: CodeSnippet[] }) {\n const { snippets } = props\n const [activeId, setActiveId] = useState(snippets[0]?.id ?? '')\n const [copied, setCopied] = useState(false)\n\n useEffect(() => {\n const first = snippets[0]?.id ?? ''\n setActiveId((current) => (snippets.some((snippet) => snippet.id === current) ? current : first))\n }, [snippets])\n\n useEffect(() => {\n setCopied(false)\n }, [activeId])\n\n useEffect(() => {\n if (!copied) return\n const timeout = window.setTimeout(() => setCopied(false), 2000)\n return () => window.clearTimeout(timeout)\n }, [copied])\n\n if (!snippets.length) {\n return null\n }\n\n const activeSnippet = snippets.find((snippet) => snippet.id === activeId) ?? snippets[0]\n\n const handleCopy = async () => {\n if (!activeSnippet) return\n if (typeof navigator === 'undefined' || !navigator.clipboard) return\n try {\n await navigator.clipboard.writeText(activeSnippet.code)\n setCopied(true)\n } catch {\n setCopied(false)\n }\n }\n\n return (\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between gap-2\">\n <div className=\"flex flex-wrap gap-2\">\n {snippets.map((snippet) => (\n <button\n type=\"button\"\n key={snippet.id}\n className={`rounded-md border px-3 py-1 text-xs font-semibold ${\n snippet.id === activeSnippet.id\n ? 'border-primary bg-primary/10 text-primary'\n : 'border-border text-muted-foreground hover:border-foreground hover:text-foreground'\n }`}\n onClick={() => setActiveId(snippet.id)}\n >\n {snippet.label}\n </button>\n ))}\n </div>\n <button\n type=\"button\"\n className=\"inline-flex items-center rounded-md border border-border px-3 py-1 text-xs font-semibold text-muted-foreground hover:border-foreground hover:text-foreground\"\n onClick={handleCopy}\n >\n {copied ? 'Copied' : 'Copy'}\n </button>\n </div>\n <pre className=\"max-h-80 overflow-auto rounded-md bg-muted px-3 py-2 text-xs leading-relaxed\">\n {activeSnippet.code}\n </pre>\n </div>\n )\n}\n\nfunction MobileOverlay(props: { title: string; children: ReactNode; onClose: () => void }) {\n const { title, children, onClose } = props\n return (\n <div className=\"fixed inset-0 z-modal flex flex-col bg-background/95 backdrop-blur\">\n <div className=\"border-b bg-card px-6 py-4\">\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-base font-semibold text-foreground\">{title}</h2>\n <button\n type=\"button\"\n className=\"rounded-md border border-border px-3 py-1 text-sm text-muted-foreground hover:border-foreground hover:text-foreground\"\n onClick={onClose}\n >\n Close\n </button>\n </div>\n </div>\n <div className=\"flex-1 overflow-y-auto px-6 py-4\">{children}</div>\n </div>\n )\n}\n\ntype TesterPanelProps = {\n operation: ExplorerOperation | null\n baseUrl: string\n setBaseUrl: (value: string) => void\n baseUrlOptions: ServerOption[]\n apiKey: string\n setApiKey: (value: string) => void\n}\n\nfunction TesterPanel(props: TesterPanelProps) {\n const { operation, baseUrl, setBaseUrl, baseUrlOptions, apiKey, setApiKey } = props\n const [pathValues, setPathValues] = useState<Record<string, string>>({})\n const [queryValues, setQueryValues] = useState<Record<string, string>>({})\n const [bodyContent, setBodyContent] = useState<string>('')\n const [response, setResponse] = useState<TestResponse | null>(null)\n const [error, setError] = useState<string | null>(null)\n const [isLoading, setIsLoading] = useState(false)\n\n const parameters = useMemo(\n () => (operation && Array.isArray(operation.operation?.parameters) ? operation.operation.parameters : []),\n [operation]\n )\n const pathParams = useMemo(\n () => parameters.filter((parameter: any) => parameter.in === 'path'),\n [parameters]\n )\n const queryParams = useMemo(\n () => parameters.filter((parameter: any) => parameter.in === 'query'),\n [parameters]\n )\n const requestVariant = useMemo(\n () => (operation ? pickContentVariant(operation.operation?.requestBody?.content) : null),\n [operation]\n )\n const mergedBaseUrls = useMemo(() => {\n if (!baseUrl) return baseUrlOptions\n if (baseUrlOptions.some((server) => server.url === baseUrl)) return baseUrlOptions\n return [...baseUrlOptions, { url: baseUrl }]\n }, [baseUrlOptions, baseUrl])\n\n const requestPreview = useMemo<RequestPreview | null>(() => {\n if (!operation) return null\n const method = operation.method.toUpperCase()\n const rawBase = baseUrl.trim()\n const normalizedBase = rawBase || PLACEHOLDER_BASE_URL\n const usesPlaceholderBase = !rawBase\n const baseWithSlash = normalizedBase.endsWith('/') ? normalizedBase : `${normalizedBase}/`\n const resolvedPath = applyPathParams(operation.path, pathValues)\n const relativePath = resolvedPath.replace(/^\\//, '')\n\n let url: URL\n try {\n url = new URL(relativePath, baseWithSlash)\n } catch {\n return {\n method,\n url: '',\n headers: [],\n mediaType: requestVariant?.mediaType,\n usesPlaceholderBase,\n baseError: 'Base URL must be absolute (include protocol, e.g. https://api.example.com).',\n }\n }\n\n for (const [key, value] of Object.entries(queryValues)) {\n if (!value) continue\n url.searchParams.append(key, value)\n }\n\n const headers: Array<[string, string]> = [['Accept', 'application/json']]\n const trimmedKey = apiKey.trim()\n if (trimmedKey) {\n headers.push(['Authorization', `ApiKey ${trimmedKey}`])\n headers.push(['X-Api-Key', trimmedKey])\n }\n\n let body: string | undefined\n let jsonBody: unknown\n let bodyParseError: string | undefined\n\n if (requestVariant && method !== 'GET' && method !== 'HEAD') {\n headers.push(['Content-Type', requestVariant.mediaType])\n if (requestVariant.mediaType === 'application/json') {\n if (bodyContent.trim()) {\n try {\n jsonBody = JSON.parse(bodyContent)\n body = JSON.stringify(jsonBody)\n } catch {\n bodyParseError = 'Request body must be valid JSON.'\n }\n }\n } else {\n if (bodyContent) {\n body = bodyContent\n }\n }\n }\n\n const missingPathParam = pathParams.find((parameter: any) => parameter.required && !pathValues[parameter.name])\n\n return {\n method,\n url: url.toString(),\n headers,\n body,\n jsonBody,\n mediaType: requestVariant?.mediaType,\n usesPlaceholderBase,\n missingPathParam: missingPathParam?.name,\n bodyParseError,\n }\n }, [operation, baseUrl, pathValues, queryValues, apiKey, requestVariant, bodyContent, pathParams])\n\n const codeSnippets = useMemo<CodeSnippet[]>(() => {\n if (!requestPreview || requestPreview.baseError) return []\n\n const snippets: CodeSnippet[] = []\n const { method, url, headers, body, jsonBody, mediaType } = requestPreview\n\n if (url) {\n const curlParts = [`curl -X ${method} '${escapeSingleQuotes(url)}'`]\n for (const [key, value] of headers) {\n curlParts.push(` -H '${escapeSingleQuotes(`${key}: ${value}`)}'`)\n }\n if (body) {\n curlParts.push(` --data '${escapeSingleQuotes(body)}'`)\n }\n snippets.push({\n id: 'curl',\n label: 'cURL',\n language: 'bash',\n code: curlParts.join(' \\\\\\n'),\n })\n\n const headerEntries =\n headers.length === 0\n ? ''\n : headers.map(([key, value]) => ` '${key}': '${escapeSingleQuotesForJs(value)}',`).join('\\n')\n const tsLines: string[] = [\n `const url = '${escapeSingleQuotesForJs(url)}';`,\n headerEntries ? `const headers = {\\n${headerEntries}\\n};` : 'const headers = {};',\n ]\n\n if (mediaType === 'application/json' && jsonBody !== undefined) {\n const payloadLiteral = JSON.stringify(jsonBody, null, 2)\n tsLines.push('', `const payload = ${payloadLiteral};`)\n tsLines.push(\n '',\n 'const response = await fetch(url, {',\n ` method: '${method}',`,\n ' headers,',\n ' body: JSON.stringify(payload),',\n '});'\n )\n } else if (body) {\n tsLines.push('', `const body = \\`${escapeBackticks(body)}\\`;`)\n tsLines.push(\n '',\n 'const response = await fetch(url, {',\n ` method: '${method}',`,\n ' headers,',\n ' body,',\n '});'\n )\n } else {\n tsLines.push(\n '',\n 'const response = await fetch(url, {',\n ` method: '${method}',`,\n ' headers,',\n '});'\n )\n }\n tsLines.push('const data = await response.json();', 'console.log(data);')\n\n snippets.push({\n id: 'typescript',\n label: 'TypeScript',\n language: 'ts',\n code: tsLines.join('\\n'),\n })\n\n const pythonLines: string[] = [\"import requests\", \"\", `url = '${escapeSingleQuotesForJs(url)}'`]\n if (headers.length) {\n const pythonHeaders = headers\n .map(([key, value]) => ` '${key}': '${escapeSingleQuotesForJs(value)}',`)\n .join('\\n')\n pythonLines.push('headers = {', pythonHeaders, '}')\n } else {\n pythonLines.push('headers = {}')\n }\n\n if (mediaType === 'application/json' && jsonBody !== undefined) {\n const pythonPayload = toPythonLiteral(jsonBody)\n pythonLines.push('', `payload = ${pythonPayload}`)\n pythonLines.push(\n `response = requests.request('${method}', url, headers=headers, json=payload)`\n )\n } else if (body) {\n pythonLines.push('', `data = ${toPythonLiteral(body)}`)\n pythonLines.push(`response = requests.request('${method}', url, headers=headers, data=data)`)\n } else {\n pythonLines.push('', `response = requests.request('${method}', url, headers=headers)`)\n }\n pythonLines.push('print(response.status_code)', 'print(response.text)')\n\n snippets.push({\n id: 'python',\n label: 'Python',\n language: 'python',\n code: pythonLines.join('\\n'),\n })\n }\n\n return snippets\n }, [requestPreview])\n\n useEffect(() => {\n const nextPath: Record<string, string> = {}\n for (const parameter of pathParams) {\n nextPath[parameter.name] = ''\n }\n const nextQuery: Record<string, string> = {}\n for (const parameter of queryParams) {\n nextQuery[parameter.name] = ''\n }\n setPathValues(nextPath)\n setQueryValues(nextQuery)\n\n if (requestVariant) {\n const example =\n requestVariant.entry?.example ??\n requestVariant.entry?.examples?.default?.value ??\n buildExampleFromSchema(requestVariant.entry?.schema)\n setBodyContent(example ? stringifyExample(requestVariant.mediaType, example) : '')\n } else {\n setBodyContent('')\n }\n setResponse(null)\n setError(null)\n }, [operation?.id, pathParams, queryParams, requestVariant])\n\n if (!operation) {\n return (\n <div className=\"rounded-lg border bg-card p-5 text-sm text-muted-foreground\">\n Select an endpoint to start testing requests.\n </div>\n )\n }\n\n const handleSubmit = async () => {\n if (!operation) return\n if (!baseUrl.trim()) {\n setError('Please provide a base URL for the request.')\n return\n }\n if (requestPreview?.baseError) {\n setError(requestPreview.baseError)\n return\n }\n if (requestPreview?.missingPathParam) {\n setError(`Path parameter \"${requestPreview.missingPathParam}\" is required.`)\n return\n }\n if (requestPreview?.bodyParseError) {\n setError(requestPreview.bodyParseError)\n return\n }\n if (!requestPreview) {\n setError('Unable to prepare the request. Check your input and try again.')\n return\n }\n\n setIsLoading(true)\n setError(null)\n setResponse(null)\n\n try {\n const started = performance.now()\n const res = await fetch(requestPreview.url, {\n method: requestPreview.method,\n headers: Object.fromEntries(requestPreview.headers),\n body: requestPreview.body,\n })\n const duration = performance.now() - started\n const text = await res.text()\n let parsed: unknown | undefined\n try {\n parsed = JSON.parse(text)\n } catch {\n parsed = undefined\n }\n setResponse({\n status: res.status,\n ok: res.ok,\n durationMs: Math.round(duration),\n body: text,\n parsed,\n })\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : 'Request failed. Check your network connection.')\n } finally {\n setIsLoading(false)\n }\n }\n\n return (\n <div className=\"flex flex-col gap-4 rounded-lg border bg-card p-5 shadow-sm\">\n <div className=\"flex items-start justify-between gap-3\">\n <div>\n <h2 className=\"text-lg font-semibold\">Interactive tester</h2>\n <p className=\"text-xs text-muted-foreground\">\n Provide the endpoint parameters and your API key to execute a live request.\n </p>\n </div>\n <span\n className={`inline-flex min-w-[3rem] justify-center rounded border px-2 py-0.5 text-overline font-semibold uppercase ${\n METHOD_STYLES[operation.method] ?? 'border border-border bg-muted text-foreground'\n }`}\n >\n {operation.method}\n </span>\n </div>\n\n <div className=\"space-y-2 text-xs\">\n <div className=\"font-semibold text-foreground\">Endpoint</div>\n <code className=\"rounded-md bg-muted px-3 py-2 text-xs text-primary\">{operation.path}</code>\n </div>\n\n <label className=\"space-y-2 text-sm\">\n <span className=\"font-medium text-foreground\">Base URL</span>\n <Select value={baseUrl} onValueChange={(value) => setBaseUrl(value)}>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {mergedBaseUrls.map((server) => (\n <SelectItem key={server.url} value={server.url}>\n {server.url} {server.description ? `\u2014 ${server.description}` : ''}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {!baseUrl.trim() && requestPreview?.usesPlaceholderBase ? (\n <p className=\"text-xs text-muted-foreground\">\n Examples default to {PLACEHOLDER_BASE_URL}. Update the base URL to match your environment.\n </p>\n ) : null}\n {requestPreview?.baseError ? (\n <p className=\"text-xs text-rose-600\">{requestPreview.baseError}</p>\n ) : null}\n </label>\n\n <label className=\"space-y-2 text-sm\">\n <span className=\"font-medium text-foreground\">API key</span>\n <Input\n type=\"text\"\n value={apiKey}\n onChange={(event) => setApiKey(event.target.value)}\n placeholder=\"Paste your API key secret (omk_\u2026)\"\n />\n </label>\n\n {pathParams.length ? (\n <section className=\"space-y-2 text-sm\">\n <div className=\"font-medium text-foreground\">Path parameters</div>\n <div className=\"space-y-3\">\n {pathParams.map((parameter: any) => (\n <label key={parameter.name} className=\"space-y-1\">\n <div className=\"flex items-center justify-between text-xs text-muted-foreground\">\n <span>{parameter.name}</span>\n {parameter.required ? <span className=\"text-amber-600\">required</span> : null}\n </div>\n <Input\n type=\"text\"\n value={pathValues[parameter.name] ?? ''}\n onChange={(event) =>\n setPathValues((prev) => ({\n ...prev,\n [parameter.name]: event.target.value,\n }))\n }\n placeholder={parameter.description ?? ''}\n />\n </label>\n ))}\n </div>\n </section>\n ) : null}\n\n {queryParams.length ? (\n <section className=\"space-y-2 text-sm\">\n <div className=\"font-medium text-foreground\">Query parameters</div>\n <div className=\"space-y-3\">\n {queryParams.map((parameter: any) => (\n <label key={parameter.name} className=\"space-y-1\">\n <div className=\"flex items-center justify-between text-xs text-muted-foreground\">\n <span>{parameter.name}</span>\n {parameter.required ? <span className=\"text-amber-600\">required</span> : null}\n </div>\n <Input\n type=\"text\"\n value={queryValues[parameter.name] ?? ''}\n onChange={(event) =>\n setQueryValues((prev) => ({\n ...prev,\n [parameter.name]: event.target.value,\n }))\n }\n placeholder={parameter.description ?? ''}\n />\n </label>\n ))}\n </div>\n </section>\n ) : null}\n\n {requestVariant ? (\n <section className=\"space-y-2 text-sm\">\n <div className=\"flex items-center justify-between\">\n <span className=\"font-medium text-foreground\">Request body</span>\n <span className=\"text-xs text-muted-foreground\">{requestVariant.mediaType}</span>\n </div>\n <textarea\n value={bodyContent}\n onChange={(event) => setBodyContent(event.target.value)}\n rows={8}\n className=\"w-full rounded-md border border-border bg-background px-3 py-2 text-xs font-mono leading-relaxed focus-visible:border-ring focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/20\"\n placeholder=\"Provide request payload\"\n />\n </section>\n ) : null}\n\n {requestPreview?.bodyParseError ? (\n <div className=\"rounded border border-amber-300 bg-amber-50 px-3 py-2 text-xs text-amber-700\">\n {requestPreview.bodyParseError}\n </div>\n ) : null}\n\n {codeSnippets.length ? (\n <section className=\"space-y-2 text-sm\">\n <div className=\"font-medium text-foreground\">Request examples</div>\n <CodeSnippetTabs snippets={codeSnippets} />\n </section>\n ) : null}\n\n <button\n type=\"button\"\n onClick={handleSubmit}\n disabled={isLoading}\n className=\"inline-flex items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-semibold text-primary-foreground hover:bg-primary/90 disabled:cursor-not-allowed disabled:bg-primary/10\"\n >\n {isLoading ? 'Sending\u2026' : 'Send request'}\n </button>\n\n {error ? <div className=\"rounded border border-rose-300 bg-rose-50 px-3 py-2 text-xs text-rose-700\">{error}</div> : null}\n\n {response ? (\n <section className=\"space-y-2 text-sm\">\n <div className=\"flex items-center justify-between\">\n <div className=\"font-medium text-foreground\">\n Response \u00B7 <span className={response.ok ? 'text-emerald-600' : 'text-rose-600'}>{response.status}</span>\n </div>\n <div className=\"text-xs text-muted-foreground\">{response.durationMs} ms</div>\n </div>\n <pre className=\"max-h-80 overflow-auto rounded-md bg-muted px-3 py-2 text-xs leading-relaxed\">\n {response.parsed ? formatJson(response.parsed) : response.body || '(empty response)'}\n </pre>\n </section>\n ) : null}\n </div>\n )\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["'use client'\n\nimport { useEffect, useMemo, useState, type ReactNode } from 'react'\nimport Image from 'next/image'\nimport Link from 'next/link'\nimport { SearchX } from 'lucide-react'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport { EmptyState } from '@open-mercato/ui/primitives/empty-state'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\n\nconst METHOD_STYLES: Record<string, string> = {\n GET: 'bg-emerald-100 text-emerald-800 border border-emerald-200',\n POST: 'bg-blue-100 text-blue-800 border border-blue-200',\n PUT: 'bg-amber-100 text-amber-800 border border-amber-200',\n PATCH: 'bg-purple-100 text-purple-800 border border-purple-200',\n DELETE: 'bg-rose-100 text-rose-800 border border-rose-200',\n}\n\nconst PREFERRED_MEDIA_TYPES = [\n 'application/json',\n 'application/x-www-form-urlencoded',\n 'multipart/form-data',\n 'text/plain',\n]\n\ntype ExplorerOperation = {\n id: string\n path: string\n method: string\n tag: string\n summary?: string\n description?: string\n operation: any\n}\n\ntype ServerOption = { url: string; description?: string }\n\ntype ApiDocsExplorerProps = {\n title: string\n version: string\n description?: string\n operations: ExplorerOperation[]\n tagOrder: string[]\n servers: ServerOption[]\n docsUrl: string\n jsonSpecUrl: string\n markdownSpecUrl: string\n}\n\ntype ContentVariant = {\n mediaType: string\n entry: any\n}\n\ntype TestResponse = {\n status: number\n durationMs: number\n ok: boolean\n body: string\n parsed?: unknown\n}\n\nfunction pickContentVariant(content?: Record<string, any>): ContentVariant | null {\n if (!content) return null\n const entries = Object.entries(content)\n if (!entries.length) return null\n for (const mediaType of PREFERRED_MEDIA_TYPES) {\n const match = entries.find(([candidate]) => candidate === mediaType)\n if (match) {\n return { mediaType: match[0], entry: match[1] }\n }\n }\n const [mediaType, entry] = entries[0]\n return { mediaType, entry }\n}\n\nfunction buildExampleFromSchema(schema: any): unknown {\n if (!schema || typeof schema !== 'object') return undefined\n if (schema.example !== undefined) return schema.example\n if (schema.default !== undefined) return schema.default\n if (Array.isArray(schema.enum) && schema.enum.length) return schema.enum[0]\n\n if (Array.isArray(schema.oneOf) && schema.oneOf.length) return buildExampleFromSchema(schema.oneOf[0])\n if (Array.isArray(schema.anyOf) && schema.anyOf.length) return buildExampleFromSchema(schema.anyOf[0])\n if (Array.isArray(schema.allOf) && schema.allOf.length) {\n return Object.assign({}, ...schema.allOf.map((part: any) => buildExampleFromSchema(part) ?? {}))\n }\n\n const type = Array.isArray(schema.type) ? schema.type[0] : schema.type\n\n if (schema.properties || type === 'object' || (!type && schema.required)) {\n const properties = schema.properties ?? {}\n const result: Record<string, unknown> = {}\n for (const key of Object.keys(properties)) {\n const value = buildExampleFromSchema(properties[key])\n if (value !== undefined) {\n result[key] = value\n }\n }\n if (schema.additionalProperties && typeof schema.additionalProperties === 'object') {\n const value = buildExampleFromSchema(schema.additionalProperties)\n if (value !== undefined) {\n result['additionalProperty'] = value\n }\n }\n return Object.keys(result).length ? result : {}\n }\n\n if (type === 'array') {\n const itemSchema = schema.items ?? (Array.isArray(schema.prefixItems) ? schema.prefixItems[0] : undefined)\n const value = buildExampleFromSchema(itemSchema)\n return value === undefined ? [] : [value]\n }\n\n if (type === 'number' || type === 'integer') return 1\n if (type === 'boolean') return true\n if (schema.format === 'date-time') return new Date('2025-01-01T00:00:00.000Z').toISOString()\n if (schema.format === 'uuid') return '00000000-0000-4000-8000-000000000000'\n if (schema.format === 'email') return 'user@example.com'\n if (schema.format === 'uri' || schema.format === 'url') return 'https://example.com/resource'\n\n return 'string'\n}\n\nfunction stringifyExample(mediaType: string, example: unknown): string {\n if (example === undefined || example === null) return ''\n if (mediaType === 'application/json') {\n try {\n return JSON.stringify(example, null, 2)\n } catch {\n return ''\n }\n }\n if (mediaType === 'application/x-www-form-urlencoded') {\n if (typeof example !== 'object') return ''\n const params = new URLSearchParams()\n for (const [key, value] of Object.entries(example as Record<string, unknown>)) {\n if (value === undefined) continue\n params.append(key, value === null ? '' : String(value))\n }\n return params.toString()\n }\n if (mediaType === 'multipart/form-data') {\n if (typeof example === 'object') {\n return Object.entries(example as Record<string, unknown>)\n .map(([key, value]) => `${key}=${value ?? ''}`)\n .join('\\n')\n }\n return typeof example === 'string' ? example : ''\n }\n if (typeof example === 'string') return example\n try {\n return JSON.stringify(example, null, 2)\n } catch {\n return ''\n }\n}\n\nfunction formatJson(value: unknown): string {\n try {\n return JSON.stringify(value, null, 2)\n } catch {\n return ''\n }\n}\n\nfunction applyPathParams(path: string, params: Record<string, string>): string {\n return path.replace(/\\{([^}]+)\\}/g, (_, key: string) => {\n const value = params[key] ?? ''\n return value ? encodeURIComponent(value) : `{${key}}`\n })\n}\n\ntype Category = {\n tag: string\n operations: ExplorerOperation[]\n}\n\nconst PLACEHOLDER_BASE_URL = 'https://api.your-service.com'\nconst CATEGORY_PAGE_SIZE = 20\n\ntype RequestPreview = {\n method: string\n url: string\n headers: Array<[string, string]>\n body?: string\n jsonBody?: unknown\n mediaType?: string\n usesPlaceholderBase: boolean\n missingPathParam?: string\n bodyParseError?: string\n baseError?: string\n}\n\ntype CodeSnippet = {\n id: string\n label: string\n language: string\n code: string\n}\n\nfunction escapeSingleQuotes(value: string): string {\n return value.replace(/'/g, `'\\\\''`)\n}\n\nfunction escapeSingleQuotesForJs(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\")\n}\n\nfunction escapeBackticks(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/`/g, '\\\\`')\n}\n\nfunction toPythonLiteral(value: unknown, indent = 0): string {\n const padding = ' '.repeat(indent)\n if (value === null || value === undefined) return 'None'\n if (typeof value === 'boolean') return value ? 'True' : 'False'\n if (typeof value === 'number' && Number.isFinite(value)) return String(value)\n if (typeof value === 'string') {\n return `'${value.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\")}'`\n }\n if (Array.isArray(value)) {\n if (!value.length) return '[]'\n const entries = value\n .map((item) => `${' '.repeat(indent + 1)}${toPythonLiteral(item, indent + 1)}`)\n .join(',\\n')\n return `[\\n${entries},\\n${padding}]`\n }\n if (typeof value === 'object') {\n const entries = Object.entries(value as Record<string, unknown>)\n if (!entries.length) return '{}'\n const lines = entries.map(\n ([key, entry]) =>\n `${' '.repeat(indent + 1)}'${key.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\")}': ${toPythonLiteral(entry, indent + 1)}`\n )\n return `{\\n${lines.join(',\\n')},\\n${padding}}`\n }\n return 'None'\n}\n\nexport default function ApiDocsExplorer(props: ApiDocsExplorerProps) {\n const { title, version, description, operations, tagOrder, servers, docsUrl, jsonSpecUrl, markdownSpecUrl } = props\n\n const methodOptions = useMemo(\n () => Array.from(new Set(operations.map((operation) => operation.method))).sort((a, b) => a.localeCompare(b)),\n [operations]\n )\n\n const operationsById = useMemo(() => {\n const map = new Map<string, ExplorerOperation>()\n for (const operation of operations) {\n map.set(operation.id, operation)\n }\n return map\n }, [operations])\n\n const [searchTerm, setSearchTerm] = useState('')\n const [methodFilter, setMethodFilter] = useState<string[]>(methodOptions)\n const [selectedId, setSelectedId] = useState<string>(operations[0]?.id ?? '')\n const [isNavOpen, setIsNavOpen] = useState(false)\n const [isTesterOpen, setIsTesterOpen] = useState(false)\n const [expanded, setExpanded] = useState<Record<string, boolean>>({})\n const [visibleCounts, setVisibleCounts] = useState<Record<string, number>>({})\n const [baseUrl, setBaseUrl] = useState<string>(servers[0]?.url ?? '')\n const [apiKey, setApiKey] = useState<string>('')\n\n useEffect(() => {\n setMethodFilter(methodOptions)\n }, [methodOptions])\n\n useEffect(() => {\n if (servers.length === 0) return\n setBaseUrl((prev) => {\n if (!prev) return servers[0].url\n return prev\n })\n }, [servers])\n\n const filteredOperations = useMemo(() => {\n const lowered = searchTerm.trim().toLowerCase()\n return operations.filter((operation) => {\n if (!methodFilter.includes(operation.method)) return false\n if (!lowered) return true\n return (\n operation.path.toLowerCase().includes(lowered) ||\n (operation.summary && operation.summary.toLowerCase().includes(lowered)) ||\n (operation.description && operation.description.toLowerCase().includes(lowered))\n )\n })\n }, [operations, methodFilter, searchTerm])\n\n const categories = useMemo(() => {\n const grouped = new Map<string, ExplorerOperation[]>()\n for (const operation of filteredOperations) {\n const list = grouped.get(operation.tag) ?? []\n list.push(operation)\n grouped.set(operation.tag, list)\n }\n const ordered: Category[] = []\n for (const tag of tagOrder) {\n const list = grouped.get(tag)\n if (list && list.length) {\n ordered.push({ tag, operations: list })\n grouped.delete(tag)\n }\n }\n const remaining = Array.from(grouped.entries()).sort(([a], [b]) => a.localeCompare(b))\n for (const [tag, ops] of remaining) {\n ordered.push({ tag, operations: ops })\n }\n return ordered\n }, [filteredOperations, tagOrder])\n\n useEffect(() => {\n setExpanded((prev) => {\n const next: Record<string, boolean> = {}\n for (const category of categories) {\n next[category.tag] = prev[category.tag] ?? true\n }\n return next\n })\n setVisibleCounts((prev) => {\n const next: Record<string, number> = {}\n for (const category of categories) {\n const total = category.operations.length\n const previous = prev[category.tag] ?? CATEGORY_PAGE_SIZE\n next[category.tag] = Math.min(total, previous)\n }\n return next\n })\n }, [categories])\n\n useEffect(() => {\n if (!selectedId && filteredOperations.length) {\n setSelectedId(filteredOperations[0].id)\n return\n }\n if (selectedId && filteredOperations.some((operation) => operation.id === selectedId)) return\n if (filteredOperations.length) {\n setSelectedId(filteredOperations[0].id)\n }\n }, [filteredOperations, selectedId])\n\n const selectedOperation =\n (selectedId ? operationsById.get(selectedId) : undefined) ?? filteredOperations[0] ?? operations[0] ?? null\n\n const shouldOpenTesterOverlay = () => {\n if (typeof window === 'undefined') return false\n return window.innerWidth < 1280\n }\n\n const handleSelectOperation = (operationId: string) => {\n setSelectedId(operationId)\n const targetCategory = categories.find((category) =>\n category.operations.some((operation) => operation.id === operationId)\n )\n if (targetCategory) {\n const index = targetCategory.operations.findIndex((operation) => operation.id === operationId)\n if (index >= 0) {\n setVisibleCounts((prev) => {\n const currentVisible = prev[targetCategory.tag] ?? CATEGORY_PAGE_SIZE\n if (index < currentVisible) return prev\n return { ...prev, [targetCategory.tag]: index + 1 }\n })\n }\n }\n requestAnimationFrame(() => {\n const element = document.getElementById(`operation-${operationId}`)\n if (element) element.scrollIntoView({ behavior: 'smooth', block: 'start', inline: 'nearest' })\n })\n if (shouldOpenTesterOverlay()) setIsTesterOpen(true)\n setIsNavOpen(false)\n }\n\n return (\n <div className=\"min-h-screen bg-background text-foreground\">\n <header className=\"border-b bg-card\">\n <div className=\"mx-auto flex w-full max-w-screen-2xl flex-col gap-4 px-6 py-6 lg:flex-row lg:items-center lg:justify-between\">\n <div className=\"flex items-center gap-4\">\n <button\n type=\"button\"\n className=\"inline-flex h-10 w-10 items-center justify-center rounded-md border border-border text-sm font-medium text-muted-foreground hover:border-foreground hover:text-foreground lg:hidden\"\n onClick={() => setIsNavOpen(true)}\n >\n <span className=\"sr-only\">Open navigation</span>\n \u2630\n </button>\n <Link href=\"/\" className=\"flex items-center gap-3\">\n <Image src=\"/open-mercato.svg\" alt=\"Open Mercato\" width={36} height={36} />\n <div>\n <div className=\"text-base font-semibold leading-tight\">{title}</div>\n <div className=\"text-xs text-muted-foreground\">Version {version}</div>\n </div>\n </Link>\n </div>\n <div className=\"flex flex-wrap items-center justify-end gap-2\">\n <nav className=\"hidden items-center gap-2 text-xs text-muted-foreground sm:flex\">\n <Link href=\"/\" className=\"hover:text-foreground hover:underline\">\n Home\n </Link>\n <span>/</span>\n <span>Docs</span>\n <span>/</span>\n <span className=\"font-medium text-foreground\">API Explorer</span>\n </nav>\n <button\n type=\"button\"\n className=\"inline-flex h-10 items-center justify-center rounded-md border border-border px-3 text-sm font-medium text-muted-foreground hover:border-foreground hover:text-foreground xl:hidden\"\n onClick={() => setIsTesterOpen(true)}\n >\n Try Endpoint\n </button>\n <Link\n href={jsonSpecUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"inline-flex h-10 items-center justify-center rounded-md border border-border px-3 text-sm font-medium text-muted-foreground hover:border-foreground hover:text-foreground\"\n >\n OpenAPI JSON\n </Link>\n <Link\n href={markdownSpecUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"inline-flex h-10 items-center justify-center rounded-md border border-border px-3 text-sm font-medium text-muted-foreground hover:border-foreground hover:text-foreground\"\n >\n Markdown Docs\n </Link>\n <Link\n href={docsUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"hidden rounded-md border border-primary/30 px-4 py-2 text-sm font-medium text-primary hover:bg-primary/10 sm:inline-flex\"\n >\n View full docs\n </Link>\n </div>\n </div>\n </header>\n\n <main className=\"mx-auto flex w-full max-w-screen-2xl flex-1 flex-col px-6 py-8 lg:flex-row lg:gap-6\">\n <aside className=\"hidden w-64 shrink-0 lg:block\">\n <div className=\"sticky top-20 max-h-[calc(100vh-6rem)] overflow-y-auto rounded-lg border bg-card p-4\">\n <h2 className=\"text-sm font-semibold uppercase tracking-wide text-muted-foreground\">API Categories</h2>\n <nav className=\"mt-4 space-y-4 text-sm\">\n {categories.map((category) => {\n const isExpanded = expanded[category.tag] ?? true\n return (\n <div key={category.tag} className=\"space-y-2\">\n <button\n type=\"button\"\n className=\"flex w-full items-center justify-between rounded-md bg-muted px-3 py-2 text-left font-medium text-foreground hover:bg-muted/50\"\n onClick={() =>\n setExpanded((prev) => ({\n ...prev,\n [category.tag]: !isExpanded,\n }))\n }\n >\n <span>{category.tag}</span>\n <span className=\"text-xs text-muted-foreground\">{isExpanded ? '\u2212' : '+'}</span>\n </button>\n {isExpanded ? (\n <ul className=\"space-y-1 pl-2\">\n {category.operations.map((operation) => (\n <li key={operation.id}>\n <button\n type=\"button\"\n className={`flex w-full items-center gap-2 rounded-md px-3 py-2 text-left transition ${\n selectedOperation?.id === operation.id\n ? 'bg-primary/10 text-primary'\n : 'text-muted-foreground hover:bg-muted hover:text-foreground'\n }`}\n onClick={() => handleSelectOperation(operation.id)}\n >\n <span\n className={`inline-flex min-w-[3rem] justify-center rounded border px-2 py-0.5 text-overline font-semibold uppercase ${\n METHOD_STYLES[operation.method] ?? 'border border-border bg-muted text-foreground'\n }`}\n >\n {operation.method}\n </span>\n <span className=\"truncate text-xs\">{operation.path}</span>\n </button>\n </li>\n ))}\n </ul>\n ) : null}\n </div>\n )\n })}\n </nav>\n </div>\n </aside>\n\n <section className=\"flex-1 space-y-6\">\n <div className=\"rounded-lg border bg-card p-5 shadow-sm\">\n <div className=\"space-y-3\">\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">OpenAPI Explorer</h1>\n {description ? <p className=\"text-sm text-muted-foreground\">{description}</p> : null}\n </div>\n <div className=\"text-xs text-muted-foreground\">\n {servers[0]?.url ? <span>Default server: {servers[0].url}</span> : <span>Server URL not configured.</span>}\n </div>\n </div>\n <div className=\"flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between\">\n <div className=\"flex flex-1 items-center gap-3\">\n <Input\n type=\"search\"\n value={searchTerm}\n onChange={(event) => setSearchTerm(event.target.value)}\n placeholder=\"Search endpoints by path or summary\"\n className=\"flex-1\"\n />\n </div>\n <div className=\"flex flex-wrap gap-2 text-xs\">\n {methodOptions.map((method) => {\n const isActive = methodFilter.includes(method)\n return (\n <button\n key={method}\n type=\"button\"\n className={`rounded-md border px-3 py-1 font-semibold uppercase transition ${\n isActive\n ? 'border-primary bg-primary/10 text-primary'\n : 'border-border text-muted-foreground hover:border-foreground hover:text-foreground'\n }`}\n onClick={() => {\n setMethodFilter((prev) => {\n if (prev.includes(method)) {\n const next = prev.filter((entry) => entry !== method)\n return next.length ? next : prev\n }\n return [...prev, method]\n })\n }}\n >\n {method}\n </button>\n )\n })}\n </div>\n </div>\n </div>\n </div>\n\n <div className=\"space-y-8\">\n {categories.map((category) => {\n const totalCount = category.operations.length\n const visibleCount = Math.min(\n totalCount,\n visibleCounts[category.tag] ?? CATEGORY_PAGE_SIZE\n )\n const visibleOperations = category.operations.slice(0, visibleCount)\n const hiddenCount = totalCount - visibleCount\n return (\n <div key={category.tag} className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold\">{category.tag}</h2>\n <div className=\"text-xs text-muted-foreground\">\n Showing {visibleCount} of {totalCount} endpoints\n </div>\n </div>\n <div className=\"space-y-6\">\n {visibleOperations.map((operation) => {\n const methodClass = METHOD_STYLES[operation.method] ?? 'border border-border bg-muted text-foreground'\n const operationId = `operation-${operation.id}`\n const contentVariant = pickContentVariant(operation.operation?.requestBody?.content)\n const contentExample =\n contentVariant?.entry?.example ??\n contentVariant?.entry?.examples?.default?.value ??\n buildExampleFromSchema(contentVariant?.entry?.schema)\n const requestSnippet =\n contentVariant && contentExample\n ? stringifyExample(contentVariant.mediaType, contentExample)\n : undefined\n\n return (\n <article\n key={operation.id}\n id={operationId}\n className={`rounded-lg border bg-card shadow-sm transition ${\n selectedOperation?.id === operation.id ? 'ring-2 ring-primary/40' : ''\n }`}\n >\n <div className=\"flex flex-col gap-4 border-b bg-muted/50 px-5 py-4 md:flex-row md:items-center md:justify-between\">\n <div className=\"flex items-center gap-3\">\n <span className={`rounded px-3 py-1 text-xs font-semibold uppercase ${methodClass}`}>\n {operation.method}\n </span>\n <code className=\"text-sm text-foreground\">{operation.path}</code>\n </div>\n <div className=\"flex items-center gap-2 text-overline text-muted-foreground\">\n {operation.operation?.['x-require-auth'] ? (\n <span className=\"rounded bg-amber-100 px-2 py-0.5 text-amber-900\">Auth required</span>\n ) : null}\n {Array.isArray(operation.operation?.['x-require-features'])\n ? operation.operation['x-require-features'].map((feature: string) => (\n <span key={feature} className=\"rounded bg-blue-100 px-2 py-0.5 text-blue-900\">\n {feature}\n </span>\n ))\n : null}\n </div>\n </div>\n <div className=\"space-y-5 p-5\">\n <div className=\"space-y-2\">\n {operation.summary ? <h3 className=\"text-lg font-semibold\">{operation.summary}</h3> : null}\n {operation.description ? (\n <p className=\"text-sm text-muted-foreground whitespace-pre-line\">\n {operation.description}\n </p>\n ) : null}\n </div>\n\n {Array.isArray(operation.operation?.parameters) &&\n operation.operation.parameters.length ? (\n <section className=\"space-y-3\">\n <h4 className=\"text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n Parameters\n </h4>\n <div className=\"overflow-hidden rounded-lg border\">\n <table className=\"min-w-full divide-y divide-border text-left text-xs\">\n <thead className=\"bg-muted/50 text-overline uppercase tracking-wide text-muted-foreground\">\n <tr>\n <th className=\"px-3 py-2 font-medium\">Name</th>\n <th className=\"px-3 py-2 font-medium\">In</th>\n <th className=\"px-3 py-2 font-medium\">Required</th>\n <th className=\"px-3 py-2 font-medium\">Schema</th>\n <th className=\"px-3 py-2 font-medium\">Description</th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-border text-xs\">\n {operation.operation.parameters.map((parameter: any) => (\n <tr key={`${parameter.in}-${parameter.name}`}>\n <td className=\"px-3 py-2 font-medium text-foreground\">{parameter.name}</td>\n <td className=\"px-3 py-2 text-muted-foreground\">{parameter.in}</td>\n <td className=\"px-3 py-2 text-muted-foreground\">\n {parameter.required ? 'Yes' : 'No'}\n </td>\n <td className=\"px-3 py-2 text-muted-foreground\">\n {parameter.schema?.type ?? 'any'}\n </td>\n <td className=\"px-3 py-2 text-muted-foreground\">\n {parameter.description ?? '\u2014'}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </section>\n ) : null}\n\n {contentVariant ? (\n <section className=\"space-y-3\">\n <h4 className=\"text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n Request body ({contentVariant.mediaType})\n </h4>\n {requestSnippet ? (\n <pre className=\"max-h-80 overflow-auto rounded-lg bg-muted px-4 py-3 text-xs leading-relaxed\">\n {requestSnippet}\n </pre>\n ) : (\n <p className=\"text-xs text-muted-foreground\">\n No example available for this content type.\n </p>\n )}\n </section>\n ) : null}\n\n {operation.operation?.responses ? (\n <section className=\"space-y-3\">\n <h4 className=\"text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n Responses\n </h4>\n <div className=\"space-y-3\">\n {Object.entries(operation.operation.responses).map(([status, response]: [string, any]) => {\n if (response?.['x-autoGenerated']) return null\n const responseVariant = pickContentVariant(response?.content)\n const responseExample =\n responseVariant?.entry?.example ??\n responseVariant?.entry?.examples?.default?.value ??\n buildExampleFromSchema(responseVariant?.entry?.schema)\n const responseSnippet =\n responseVariant && responseExample\n ? stringifyExample(responseVariant.mediaType, responseExample)\n : undefined\n\n return (\n <div key={status} className=\"rounded-lg border\">\n <div className=\"flex items-center justify-between border-b bg-muted/50 px-4 py-2 text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n <span>{status}</span>\n <span className=\"text-muted-foreground\">\n {response?.description ?? 'Response'}\n </span>\n </div>\n {responseVariant ? (\n <div className=\"border-b bg-muted/50 px-4 py-2 text-overline text-muted-foreground\">\n Content-Type: {responseVariant.mediaType}\n </div>\n ) : null}\n {responseSnippet ? (\n <pre className=\"max-h-80 overflow-auto bg-muted px-4 py-3 text-xs leading-relaxed\">\n {responseSnippet}\n </pre>\n ) : (\n <p className=\"px-4 py-3 text-xs text-muted-foreground\">\n {responseVariant ? 'No example available for this content type.' : 'No response body.'}\n </p>\n )}\n </div>\n )\n })}\n </div>\n </section>\n ) : null}\n\n {Array.isArray(operation.operation?.['x-codeSamples']) &&\n operation.operation['x-codeSamples'].length ? (\n <section className=\"space-y-3\">\n <h4 className=\"text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n Example\n </h4>\n <pre className=\"overflow-auto rounded-lg bg-muted px-4 py-3 text-xs leading-relaxed\">\n {operation.operation['x-codeSamples'][0].source}\n </pre>\n </section>\n ) : null}\n\n <div className=\"flex flex-wrap gap-3\">\n <button\n type=\"button\"\n className=\"inline-flex items-center rounded-md border border-primary px-4 py-2 text-sm font-semibold text-primary hover:bg-primary/10\"\n onClick={() => {\n setSelectedId(operation.id)\n if (shouldOpenTesterOverlay()) setIsTesterOpen(true)\n }}\n >\n Test this endpoint\n </button>\n <button\n type=\"button\"\n className=\"inline-flex items-center rounded-md border border-border px-4 py-2 text-sm text-muted-foreground hover:border-foreground hover:text-foreground\"\n onClick={() => handleSelectOperation(operation.id)}\n >\n Jump to tester\n </button>\n </div>\n </div>\n </article>\n )\n })}\n </div>\n {hiddenCount > 0 ? (\n <div className=\"flex justify-center\">\n <button\n type=\"button\"\n className=\"inline-flex items-center rounded-md border border-border px-4 py-2 text-sm font-medium text-muted-foreground hover:border-foreground hover:text-foreground\"\n onClick={() =>\n setVisibleCounts((prev) => ({\n ...prev,\n [category.tag]: Math.min(\n totalCount,\n (prev[category.tag] ?? CATEGORY_PAGE_SIZE) + CATEGORY_PAGE_SIZE\n ),\n }))\n }\n >\n Show {Math.min(CATEGORY_PAGE_SIZE, hiddenCount)} more endpoints\n </button>\n </div>\n ) : null}\n </div>\n )\n })}\n {!categories.length ? (\n <EmptyState\n icon={<SearchX className=\"h-8 w-8\" aria-hidden=\"true\" />}\n title=\"No endpoints match your filters.\"\n description=\"Try adjusting the method filters or clearing the search query.\"\n />\n ) : null}\n </div>\n </section>\n\n <aside className=\"hidden w-96 shrink-0 xl:block\">\n <div className=\"sticky top-20 max-h-[calc(100vh-6rem)] overflow-y-auto\">\n <TesterPanel\n key={selectedOperation?.id ?? 'tester'}\n operation={selectedOperation}\n baseUrl={baseUrl}\n setBaseUrl={setBaseUrl}\n baseUrlOptions={servers}\n apiKey={apiKey}\n setApiKey={setApiKey}\n />\n </div>\n </aside>\n </main>\n\n <footer className=\"border-t bg-card\">\n <div className=\"mx-auto flex w-full max-w-screen-2xl flex-col gap-4 px-6 py-6 md:flex-row md:items-center md:justify-between\">\n <div className=\"text-sm text-muted-foreground\">\u00A9 {new Date().getFullYear()} Open Mercato. All rights reserved.</div>\n <div className=\"flex flex-wrap items-center gap-4 text-sm text-muted-foreground\">\n <Link href={docsUrl} target=\"_blank\" rel=\"noreferrer\" className=\"hover:text-foreground hover:underline\">\n Documentation\n </Link>\n <Link\n href=\"https://openmercato.com/privacy\"\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"hover:text-foreground hover:underline\"\n >\n Privacy\n </Link>\n <Link\n href=\"https://openmercato.com/terms\"\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"hover:text-foreground hover:underline\"\n >\n Terms\n </Link>\n </div>\n </div>\n </footer>\n\n {isNavOpen ? (\n <MobileOverlay title=\"API categories\" onClose={() => setIsNavOpen(false)}>\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-sm font-semibold uppercase tracking-wide text-muted-foreground\">API Categories</h2>\n <button\n type=\"button\"\n className=\"text-sm text-muted-foreground hover:text-foreground\"\n onClick={() => setIsNavOpen(false)}\n >\n Close\n </button>\n </div>\n <div className=\"max-h-[70vh] space-y-4 overflow-y-auto\">\n {categories.map((category) => (\n <div key={`mobile-${category.tag}`} className=\"space-y-2\">\n <div className=\"font-semibold text-foreground\">{category.tag}</div>\n <ul className=\"space-y-2\">\n {category.operations.map((operation) => (\n <li key={`mobile-${operation.id}`}>\n <button\n type=\"button\"\n className={`flex w-full items-center gap-2 rounded-md border px-3 py-2 text-left text-sm ${\n selectedOperation?.id === operation.id\n ? 'border-primary text-primary'\n : 'border-border text-muted-foreground'\n }`}\n onClick={() => handleSelectOperation(operation.id)}\n >\n <span\n className={`inline-flex min-w-[3rem] justify-center rounded border px-2 py-0.5 text-overline font-semibold uppercase ${\n METHOD_STYLES[operation.method] ?? 'border border-border bg-muted text-foreground'\n }`}\n >\n {operation.method}\n </span>\n <span className=\"truncate\">{operation.path}</span>\n </button>\n </li>\n ))}\n </ul>\n </div>\n ))}\n </div>\n </div>\n </MobileOverlay>\n ) : null}\n\n {isTesterOpen ? (\n <MobileOverlay title=\"API tester\" onClose={() => setIsTesterOpen(false)}>\n <TesterPanel\n key={`mobile-${selectedOperation?.id ?? 'tester'}`}\n operation={selectedOperation}\n baseUrl={baseUrl}\n setBaseUrl={setBaseUrl}\n baseUrlOptions={servers}\n apiKey={apiKey}\n setApiKey={setApiKey}\n />\n </MobileOverlay>\n ) : null}\n </div>\n )\n}\n\nfunction CodeSnippetTabs(props: { snippets: CodeSnippet[] }) {\n const { snippets } = props\n const [activeId, setActiveId] = useState(snippets[0]?.id ?? '')\n const [copied, setCopied] = useState(false)\n\n useEffect(() => {\n const first = snippets[0]?.id ?? ''\n setActiveId((current) => (snippets.some((snippet) => snippet.id === current) ? current : first))\n }, [snippets])\n\n useEffect(() => {\n setCopied(false)\n }, [activeId])\n\n useEffect(() => {\n if (!copied) return\n const timeout = window.setTimeout(() => setCopied(false), 2000)\n return () => window.clearTimeout(timeout)\n }, [copied])\n\n if (!snippets.length) {\n return null\n }\n\n const activeSnippet = snippets.find((snippet) => snippet.id === activeId) ?? snippets[0]\n\n const handleCopy = async () => {\n if (!activeSnippet) return\n if (typeof navigator === 'undefined' || !navigator.clipboard) return\n try {\n await navigator.clipboard.writeText(activeSnippet.code)\n setCopied(true)\n } catch {\n setCopied(false)\n }\n }\n\n return (\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between gap-2\">\n <div className=\"flex flex-wrap gap-2\">\n {snippets.map((snippet) => (\n <button\n type=\"button\"\n key={snippet.id}\n className={`rounded-md border px-3 py-1 text-xs font-semibold ${\n snippet.id === activeSnippet.id\n ? 'border-primary bg-primary/10 text-primary'\n : 'border-border text-muted-foreground hover:border-foreground hover:text-foreground'\n }`}\n onClick={() => setActiveId(snippet.id)}\n >\n {snippet.label}\n </button>\n ))}\n </div>\n <button\n type=\"button\"\n className=\"inline-flex items-center rounded-md border border-border px-3 py-1 text-xs font-semibold text-muted-foreground hover:border-foreground hover:text-foreground\"\n onClick={handleCopy}\n >\n {copied ? 'Copied' : 'Copy'}\n </button>\n </div>\n <pre className=\"max-h-80 overflow-auto rounded-md bg-muted px-3 py-2 text-xs leading-relaxed\">\n {activeSnippet.code}\n </pre>\n </div>\n )\n}\n\nfunction MobileOverlay(props: { title: string; children: ReactNode; onClose: () => void }) {\n const { title, children, onClose } = props\n return (\n <div className=\"fixed inset-0 z-modal flex flex-col bg-background/95 backdrop-blur\">\n <div className=\"border-b bg-card px-6 py-4\">\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-base font-semibold text-foreground\">{title}</h2>\n <button\n type=\"button\"\n className=\"rounded-md border border-border px-3 py-1 text-sm text-muted-foreground hover:border-foreground hover:text-foreground\"\n onClick={onClose}\n >\n Close\n </button>\n </div>\n </div>\n <div className=\"flex-1 overflow-y-auto px-6 py-4\">{children}</div>\n </div>\n )\n}\n\ntype TesterPanelProps = {\n operation: ExplorerOperation | null\n baseUrl: string\n setBaseUrl: (value: string) => void\n baseUrlOptions: ServerOption[]\n apiKey: string\n setApiKey: (value: string) => void\n}\n\nfunction TesterPanel(props: TesterPanelProps) {\n const { operation, baseUrl, setBaseUrl, baseUrlOptions, apiKey, setApiKey } = props\n const [pathValues, setPathValues] = useState<Record<string, string>>({})\n const [queryValues, setQueryValues] = useState<Record<string, string>>({})\n const [bodyContent, setBodyContent] = useState<string>('')\n const [response, setResponse] = useState<TestResponse | null>(null)\n const [error, setError] = useState<string | null>(null)\n const [isLoading, setIsLoading] = useState(false)\n\n const parameters = useMemo(\n () => (operation && Array.isArray(operation.operation?.parameters) ? operation.operation.parameters : []),\n [operation]\n )\n const pathParams = useMemo(\n () => parameters.filter((parameter: any) => parameter.in === 'path'),\n [parameters]\n )\n const queryParams = useMemo(\n () => parameters.filter((parameter: any) => parameter.in === 'query'),\n [parameters]\n )\n const requestVariant = useMemo(\n () => (operation ? pickContentVariant(operation.operation?.requestBody?.content) : null),\n [operation]\n )\n const mergedBaseUrls = useMemo(() => {\n if (!baseUrl) return baseUrlOptions\n if (baseUrlOptions.some((server) => server.url === baseUrl)) return baseUrlOptions\n return [...baseUrlOptions, { url: baseUrl }]\n }, [baseUrlOptions, baseUrl])\n\n const requestPreview = useMemo<RequestPreview | null>(() => {\n if (!operation) return null\n const method = operation.method.toUpperCase()\n const rawBase = baseUrl.trim()\n const normalizedBase = rawBase || PLACEHOLDER_BASE_URL\n const usesPlaceholderBase = !rawBase\n const baseWithSlash = normalizedBase.endsWith('/') ? normalizedBase : `${normalizedBase}/`\n const resolvedPath = applyPathParams(operation.path, pathValues)\n const relativePath = resolvedPath.replace(/^\\//, '')\n\n let url: URL\n try {\n url = new URL(relativePath, baseWithSlash)\n } catch {\n return {\n method,\n url: '',\n headers: [],\n mediaType: requestVariant?.mediaType,\n usesPlaceholderBase,\n baseError: 'Base URL must be absolute (include protocol, e.g. https://api.example.com).',\n }\n }\n\n for (const [key, value] of Object.entries(queryValues)) {\n if (!value) continue\n url.searchParams.append(key, value)\n }\n\n const headers: Array<[string, string]> = [['Accept', 'application/json']]\n const trimmedKey = apiKey.trim()\n if (trimmedKey) {\n headers.push(['Authorization', `ApiKey ${trimmedKey}`])\n headers.push(['X-Api-Key', trimmedKey])\n }\n\n let body: string | undefined\n let jsonBody: unknown\n let bodyParseError: string | undefined\n\n if (requestVariant && method !== 'GET' && method !== 'HEAD') {\n headers.push(['Content-Type', requestVariant.mediaType])\n if (requestVariant.mediaType === 'application/json') {\n if (bodyContent.trim()) {\n try {\n jsonBody = JSON.parse(bodyContent)\n body = JSON.stringify(jsonBody)\n } catch {\n bodyParseError = 'Request body must be valid JSON.'\n }\n }\n } else {\n if (bodyContent) {\n body = bodyContent\n }\n }\n }\n\n const missingPathParam = pathParams.find((parameter: any) => parameter.required && !pathValues[parameter.name])\n\n return {\n method,\n url: url.toString(),\n headers,\n body,\n jsonBody,\n mediaType: requestVariant?.mediaType,\n usesPlaceholderBase,\n missingPathParam: missingPathParam?.name,\n bodyParseError,\n }\n }, [operation, baseUrl, pathValues, queryValues, apiKey, requestVariant, bodyContent, pathParams])\n\n const codeSnippets = useMemo<CodeSnippet[]>(() => {\n if (!requestPreview || requestPreview.baseError) return []\n\n const snippets: CodeSnippet[] = []\n const { method, url, headers, body, jsonBody, mediaType } = requestPreview\n\n if (url) {\n const curlParts = [`curl -X ${method} '${escapeSingleQuotes(url)}'`]\n for (const [key, value] of headers) {\n curlParts.push(` -H '${escapeSingleQuotes(`${key}: ${value}`)}'`)\n }\n if (body) {\n curlParts.push(` --data '${escapeSingleQuotes(body)}'`)\n }\n snippets.push({\n id: 'curl',\n label: 'cURL',\n language: 'bash',\n code: curlParts.join(' \\\\\\n'),\n })\n\n const headerEntries =\n headers.length === 0\n ? ''\n : headers.map(([key, value]) => ` '${key}': '${escapeSingleQuotesForJs(value)}',`).join('\\n')\n const tsLines: string[] = [\n `const url = '${escapeSingleQuotesForJs(url)}';`,\n headerEntries ? `const headers = {\\n${headerEntries}\\n};` : 'const headers = {};',\n ]\n\n if (mediaType === 'application/json' && jsonBody !== undefined) {\n const payloadLiteral = JSON.stringify(jsonBody, null, 2)\n tsLines.push('', `const payload = ${payloadLiteral};`)\n tsLines.push(\n '',\n 'const response = await fetch(url, {',\n ` method: '${method}',`,\n ' headers,',\n ' body: JSON.stringify(payload),',\n '});'\n )\n } else if (body) {\n tsLines.push('', `const body = \\`${escapeBackticks(body)}\\`;`)\n tsLines.push(\n '',\n 'const response = await fetch(url, {',\n ` method: '${method}',`,\n ' headers,',\n ' body,',\n '});'\n )\n } else {\n tsLines.push(\n '',\n 'const response = await fetch(url, {',\n ` method: '${method}',`,\n ' headers,',\n '});'\n )\n }\n tsLines.push('const data = await response.json();', 'console.log(data);')\n\n snippets.push({\n id: 'typescript',\n label: 'TypeScript',\n language: 'ts',\n code: tsLines.join('\\n'),\n })\n\n const pythonLines: string[] = [\"import requests\", \"\", `url = '${escapeSingleQuotesForJs(url)}'`]\n if (headers.length) {\n const pythonHeaders = headers\n .map(([key, value]) => ` '${key}': '${escapeSingleQuotesForJs(value)}',`)\n .join('\\n')\n pythonLines.push('headers = {', pythonHeaders, '}')\n } else {\n pythonLines.push('headers = {}')\n }\n\n if (mediaType === 'application/json' && jsonBody !== undefined) {\n const pythonPayload = toPythonLiteral(jsonBody)\n pythonLines.push('', `payload = ${pythonPayload}`)\n pythonLines.push(\n `response = requests.request('${method}', url, headers=headers, json=payload)`\n )\n } else if (body) {\n pythonLines.push('', `data = ${toPythonLiteral(body)}`)\n pythonLines.push(`response = requests.request('${method}', url, headers=headers, data=data)`)\n } else {\n pythonLines.push('', `response = requests.request('${method}', url, headers=headers)`)\n }\n pythonLines.push('print(response.status_code)', 'print(response.text)')\n\n snippets.push({\n id: 'python',\n label: 'Python',\n language: 'python',\n code: pythonLines.join('\\n'),\n })\n }\n\n return snippets\n }, [requestPreview])\n\n useEffect(() => {\n const nextPath: Record<string, string> = {}\n for (const parameter of pathParams) {\n nextPath[parameter.name] = ''\n }\n const nextQuery: Record<string, string> = {}\n for (const parameter of queryParams) {\n nextQuery[parameter.name] = ''\n }\n setPathValues(nextPath)\n setQueryValues(nextQuery)\n\n if (requestVariant) {\n const example =\n requestVariant.entry?.example ??\n requestVariant.entry?.examples?.default?.value ??\n buildExampleFromSchema(requestVariant.entry?.schema)\n setBodyContent(example ? stringifyExample(requestVariant.mediaType, example) : '')\n } else {\n setBodyContent('')\n }\n setResponse(null)\n setError(null)\n }, [operation?.id, pathParams, queryParams, requestVariant])\n\n if (!operation) {\n return (\n <div className=\"rounded-lg border bg-card p-5 text-sm text-muted-foreground\">\n Select an endpoint to start testing requests.\n </div>\n )\n }\n\n const handleSubmit = async () => {\n if (!operation) return\n if (!baseUrl.trim()) {\n setError('Please provide a base URL for the request.')\n return\n }\n if (requestPreview?.baseError) {\n setError(requestPreview.baseError)\n return\n }\n if (requestPreview?.missingPathParam) {\n setError(`Path parameter \"${requestPreview.missingPathParam}\" is required.`)\n return\n }\n if (requestPreview?.bodyParseError) {\n setError(requestPreview.bodyParseError)\n return\n }\n if (!requestPreview) {\n setError('Unable to prepare the request. Check your input and try again.')\n return\n }\n\n setIsLoading(true)\n setError(null)\n setResponse(null)\n\n try {\n const started = performance.now()\n const res = await fetch(requestPreview.url, {\n method: requestPreview.method,\n headers: Object.fromEntries(requestPreview.headers),\n body: requestPreview.body,\n })\n const duration = performance.now() - started\n const text = await res.text()\n let parsed: unknown | undefined\n try {\n parsed = JSON.parse(text)\n } catch {\n parsed = undefined\n }\n setResponse({\n status: res.status,\n ok: res.ok,\n durationMs: Math.round(duration),\n body: text,\n parsed,\n })\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : 'Request failed. Check your network connection.')\n } finally {\n setIsLoading(false)\n }\n }\n\n return (\n <div className=\"flex flex-col gap-4 rounded-lg border bg-card p-5 shadow-sm\">\n <div className=\"flex items-start justify-between gap-3\">\n <div>\n <h2 className=\"text-lg font-semibold\">Interactive tester</h2>\n <p className=\"text-xs text-muted-foreground\">\n Provide the endpoint parameters and your API key to execute a live request.\n </p>\n </div>\n <span\n className={`inline-flex min-w-[3rem] justify-center rounded border px-2 py-0.5 text-overline font-semibold uppercase ${\n METHOD_STYLES[operation.method] ?? 'border border-border bg-muted text-foreground'\n }`}\n >\n {operation.method}\n </span>\n </div>\n\n <div className=\"space-y-2 text-xs\">\n <div className=\"font-semibold text-foreground\">Endpoint</div>\n <code className=\"rounded-md bg-muted px-3 py-2 text-xs text-primary\">{operation.path}</code>\n </div>\n\n <label className=\"space-y-2 text-sm\">\n <span className=\"font-medium text-foreground\">Base URL</span>\n <Select value={baseUrl} onValueChange={(value) => setBaseUrl(value)}>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {mergedBaseUrls.map((server) => (\n <SelectItem key={server.url} value={server.url}>\n {server.url} {server.description ? `\u2014 ${server.description}` : ''}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {!baseUrl.trim() && requestPreview?.usesPlaceholderBase ? (\n <p className=\"text-xs text-muted-foreground\">\n Examples default to {PLACEHOLDER_BASE_URL}. Update the base URL to match your environment.\n </p>\n ) : null}\n {requestPreview?.baseError ? (\n <p className=\"text-xs text-rose-600\">{requestPreview.baseError}</p>\n ) : null}\n </label>\n\n <label className=\"space-y-2 text-sm\">\n <span className=\"font-medium text-foreground\">API key</span>\n <Input\n type=\"text\"\n value={apiKey}\n onChange={(event) => setApiKey(event.target.value)}\n placeholder=\"Paste your API key secret (omk_\u2026)\"\n />\n </label>\n\n {pathParams.length ? (\n <section className=\"space-y-2 text-sm\">\n <div className=\"font-medium text-foreground\">Path parameters</div>\n <div className=\"space-y-3\">\n {pathParams.map((parameter: any) => (\n <label key={parameter.name} className=\"space-y-1\">\n <div className=\"flex items-center justify-between text-xs text-muted-foreground\">\n <span>{parameter.name}</span>\n {parameter.required ? <span className=\"text-amber-600\">required</span> : null}\n </div>\n <Input\n type=\"text\"\n value={pathValues[parameter.name] ?? ''}\n onChange={(event) =>\n setPathValues((prev) => ({\n ...prev,\n [parameter.name]: event.target.value,\n }))\n }\n placeholder={parameter.description ?? ''}\n />\n </label>\n ))}\n </div>\n </section>\n ) : null}\n\n {queryParams.length ? (\n <section className=\"space-y-2 text-sm\">\n <div className=\"font-medium text-foreground\">Query parameters</div>\n <div className=\"space-y-3\">\n {queryParams.map((parameter: any) => (\n <label key={parameter.name} className=\"space-y-1\">\n <div className=\"flex items-center justify-between text-xs text-muted-foreground\">\n <span>{parameter.name}</span>\n {parameter.required ? <span className=\"text-amber-600\">required</span> : null}\n </div>\n <Input\n type=\"text\"\n value={queryValues[parameter.name] ?? ''}\n onChange={(event) =>\n setQueryValues((prev) => ({\n ...prev,\n [parameter.name]: event.target.value,\n }))\n }\n placeholder={parameter.description ?? ''}\n />\n </label>\n ))}\n </div>\n </section>\n ) : null}\n\n {requestVariant ? (\n <section className=\"space-y-2 text-sm\">\n <div className=\"flex items-center justify-between\">\n <span className=\"font-medium text-foreground\">Request body</span>\n <span className=\"text-xs text-muted-foreground\">{requestVariant.mediaType}</span>\n </div>\n <textarea\n value={bodyContent}\n onChange={(event) => setBodyContent(event.target.value)}\n rows={8}\n className=\"w-full rounded-md border border-border bg-background px-3 py-2 text-xs font-mono leading-relaxed focus-visible:border-ring focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/20\"\n placeholder=\"Provide request payload\"\n />\n </section>\n ) : null}\n\n {requestPreview?.bodyParseError ? (\n <div className=\"rounded border border-amber-300 bg-amber-50 px-3 py-2 text-xs text-amber-700\">\n {requestPreview.bodyParseError}\n </div>\n ) : null}\n\n {codeSnippets.length ? (\n <section className=\"space-y-2 text-sm\">\n <div className=\"font-medium text-foreground\">Request examples</div>\n <CodeSnippetTabs snippets={codeSnippets} />\n </section>\n ) : null}\n\n <button\n type=\"button\"\n onClick={handleSubmit}\n disabled={isLoading}\n className=\"inline-flex items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-semibold text-primary-foreground hover:bg-primary/90 disabled:cursor-not-allowed disabled:bg-primary/10\"\n >\n {isLoading ? 'Sending\u2026' : 'Send request'}\n </button>\n\n {error ? <div className=\"rounded border border-rose-300 bg-rose-50 px-3 py-2 text-xs text-rose-700\">{error}</div> : null}\n\n {response ? (\n <section className=\"space-y-2 text-sm\">\n <div className=\"flex items-center justify-between\">\n <div className=\"font-medium text-foreground\">\n Response \u00B7 <span className={response.ok ? 'text-emerald-600' : 'text-rose-600'}>{response.status}</span>\n </div>\n <div className=\"text-xs text-muted-foreground\">{response.durationMs} ms</div>\n </div>\n <pre className=\"max-h-80 overflow-auto rounded-md bg-muted px-3 py-2 text-xs leading-relaxed\">\n {response.parsed ? formatJson(response.parsed) : response.body || '(empty response)'}\n </pre>\n </section>\n ) : null}\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["mediaType"]
|
|
7
7
|
}
|
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import * as React from "react";
|
|
3
|
+
import {
|
|
4
|
+
Accordion,
|
|
5
|
+
AccordionContent,
|
|
6
|
+
AccordionItem,
|
|
7
|
+
AccordionTrigger
|
|
8
|
+
} from "@open-mercato/ui/primitives/accordion";
|
|
3
9
|
import { extractChangeRows, isRecord as isRecord2 } from "./changeRows.js";
|
|
4
10
|
function humanizeField(field) {
|
|
5
11
|
return field.replace(/[_-]+/g, " ").replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/\b\w/g, (s) => s.toUpperCase());
|
|
@@ -59,37 +65,32 @@ function ChangedFieldsTable({ changeRows, noneLabel, t, beforeLabel, afterLabel
|
|
|
59
65
|
] });
|
|
60
66
|
}
|
|
61
67
|
const DEFAULT_TRUNCATE_AT = 5e3;
|
|
68
|
+
const COLLAPSIBLE_JSON_ITEM_VALUE = "open";
|
|
62
69
|
function CollapsibleJsonSection({ label, value, truncateAt = DEFAULT_TRUNCATE_AT }) {
|
|
63
|
-
const [
|
|
70
|
+
const [openValue, setOpenValue] = React.useState("");
|
|
64
71
|
const [showFull, setShowFull] = React.useState(false);
|
|
72
|
+
const isOpen = openValue === COLLAPSIBLE_JSON_ITEM_VALUE;
|
|
65
73
|
const stringified = React.useMemo(() => isOpen ? safeStringify(value) : "", [isOpen, value]);
|
|
66
74
|
const isTruncated = stringified.length > truncateAt;
|
|
67
75
|
const displayText = !showFull && isTruncated ? stringified.slice(0, truncateAt) : stringified;
|
|
68
|
-
return /* @__PURE__ */ jsxs(
|
|
69
|
-
"
|
|
70
|
-
{
|
|
71
|
-
className: "
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
children: showFull ? "Show less" : `Show all (${Math.ceil(stringified.length / 1024)} KB)`
|
|
87
|
-
}
|
|
88
|
-
) : null
|
|
89
|
-
] }) : null
|
|
90
|
-
]
|
|
91
|
-
}
|
|
92
|
-
);
|
|
76
|
+
return /* @__PURE__ */ jsx(Accordion, { type: "single", collapsible: true, value: openValue, onValueChange: setOpenValue, children: /* @__PURE__ */ jsxs(AccordionItem, { value: COLLAPSIBLE_JSON_ITEM_VALUE, children: [
|
|
77
|
+
/* @__PURE__ */ jsx(AccordionTrigger, { children: /* @__PURE__ */ jsx("span", { className: "font-semibold text-foreground group-data-[state=open]/accordion-trigger:text-primary", children: label }) }),
|
|
78
|
+
/* @__PURE__ */ jsxs(AccordionContent, { children: [
|
|
79
|
+
/* @__PURE__ */ jsxs("pre", { className: "max-h-96 overflow-auto whitespace-pre-wrap break-words text-xs leading-5 text-muted-foreground", children: [
|
|
80
|
+
displayText,
|
|
81
|
+
!showFull && isTruncated ? "\n\u2026" : null
|
|
82
|
+
] }),
|
|
83
|
+
isTruncated ? /* @__PURE__ */ jsx(
|
|
84
|
+
"button",
|
|
85
|
+
{
|
|
86
|
+
type: "button",
|
|
87
|
+
className: "mt-1 text-xs text-primary hover:underline",
|
|
88
|
+
onClick: () => setShowFull((prev) => !prev),
|
|
89
|
+
children: showFull ? "Show less" : `Show all (${Math.ceil(stringified.length / 1024)} KB)`
|
|
90
|
+
}
|
|
91
|
+
) : null
|
|
92
|
+
] })
|
|
93
|
+
] }) });
|
|
93
94
|
}
|
|
94
95
|
export {
|
|
95
96
|
ChangedFieldsTable,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/audit_logs/lib/display-helpers.tsx"],
|
|
4
|
-
"sourcesContent": ["import * as React from 'react'\nimport type { TranslateFn } from '@open-mercato/shared/lib/i18n/context'\nimport type { ChangeRow } from './changeRows'\nimport { isRecord } from './changeRows'\nexport { extractChangeRows, isRecord } from './changeRows'\nexport type { ChangeRow } from './changeRows'\n\nexport function humanizeField(field: string) {\n return field\n .replace(/[_-]+/g, ' ')\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n .replace(/\\b\\w/g, (s) => s.toUpperCase())\n}\n\nexport function normalizeChangeField(field: string) {\n const parts = field.split('.')\n const base = parts.length === 2 ? parts[1] : field\n if (base.startsWith('cf_')) return base.slice(3)\n if (base.startsWith('cf:')) return base.slice(3)\n return base\n}\n\nexport function renderValue(value: unknown, fallback: string) {\n if (value === undefined || value === null || value === '') {\n return <span className=\"text-muted-foreground\">{fallback}</span>\n }\n if (typeof value === 'boolean') return <span>{value ? 'true' : 'false'}</span>\n if (typeof value === 'number' || typeof value === 'bigint') return <span>{String(value)}</span>\n if (value instanceof Date) return <span>{value.toISOString()}</span>\n if (typeof value === 'string') return <span className=\"break-words\">{value}</span>\n return (\n <pre className=\"max-h-40 overflow-y-auto whitespace-pre-wrap break-words rounded-md bg-muted/50 px-2 py-1 text-xs leading-5 text-muted-foreground\">\n {safeStringify(value)}\n </pre>\n )\n}\n\nexport function safeStringify(value: unknown) {\n if (typeof value === 'string') return value\n try {\n return JSON.stringify(value, null, 2)\n } catch {\n return String(value)\n }\n}\n\nexport function formatResource(\n item: { resourceKind: string | null; resourceId: string | null },\n fallback: string,\n) {\n if (!item.resourceKind && !item.resourceId) return fallback\n return [item.resourceKind, item.resourceId].filter(Boolean).join(' \u00B7 ')\n}\n\nexport function formatDate(value: string) {\n const date = new Date(value)\n if (Number.isNaN(date.getTime())) return value\n return new Intl.DateTimeFormat(undefined, {\n dateStyle: 'medium',\n timeStyle: 'short',\n }).format(date)\n}\n\nexport type ChangedFieldsTableProps = {\n changeRows: ChangeRow[]\n noneLabel: string\n t: TranslateFn\n beforeLabel?: string\n afterLabel?: string\n}\n\nexport function ChangedFieldsTable({ changeRows, noneLabel, t, beforeLabel, afterLabel }: ChangedFieldsTableProps) {\n return (\n <section>\n <h3 className=\"text-sm font-semibold\">\n {t('audit_logs.actions.details.changed_fields')}\n </h3>\n {changeRows.length ? (\n <div className=\"mt-2 overflow-x-auto rounded-lg border\">\n <table className=\"min-w-full divide-y text-sm\">\n <thead className=\"bg-muted/50\">\n <tr>\n <th scope=\"col\" className=\"px-4 py-2 text-left font-medium text-muted-foreground\">\n {t('audit_logs.actions.details.field')}\n </th>\n <th scope=\"col\" className=\"px-4 py-2 text-left font-medium text-muted-foreground\">\n {beforeLabel ?? t('audit_logs.actions.details.before')}\n </th>\n <th scope=\"col\" className=\"px-4 py-2 text-left font-medium text-muted-foreground\">\n {afterLabel ?? t('audit_logs.actions.details.after')}\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-y\">\n {changeRows.map((row) => (\n <tr key={row.field} className=\"align-top\">\n <td className=\"px-4 py-2 align-top font-medium\">\n {humanizeField(normalizeChangeField(row.field))}\n </td>\n <td className=\"px-4 py-2\">\n {renderValue(row.from, noneLabel)}\n </td>\n <td className=\"px-4 py-2\">\n {renderValue(row.to, noneLabel)}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n ) : (\n <p className=\"mt-2 text-sm text-muted-foreground\">\n {t('audit_logs.actions.details.no_changes')}\n </p>\n )}\n </section>\n )\n}\n\nexport type CollapsibleJsonSectionProps = {\n label: string\n value: unknown\n truncateAt?: number\n}\n\nconst DEFAULT_TRUNCATE_AT = 5000\n\nexport function CollapsibleJsonSection({ label, value, truncateAt = DEFAULT_TRUNCATE_AT }: CollapsibleJsonSectionProps) {\n const [
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import * as React from 'react'\nimport type { TranslateFn } from '@open-mercato/shared/lib/i18n/context'\nimport {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n} from '@open-mercato/ui/primitives/accordion'\nimport type { ChangeRow } from './changeRows'\nimport { isRecord } from './changeRows'\nexport { extractChangeRows, isRecord } from './changeRows'\nexport type { ChangeRow } from './changeRows'\n\nexport function humanizeField(field: string) {\n return field\n .replace(/[_-]+/g, ' ')\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n .replace(/\\b\\w/g, (s) => s.toUpperCase())\n}\n\nexport function normalizeChangeField(field: string) {\n const parts = field.split('.')\n const base = parts.length === 2 ? parts[1] : field\n if (base.startsWith('cf_')) return base.slice(3)\n if (base.startsWith('cf:')) return base.slice(3)\n return base\n}\n\nexport function renderValue(value: unknown, fallback: string) {\n if (value === undefined || value === null || value === '') {\n return <span className=\"text-muted-foreground\">{fallback}</span>\n }\n if (typeof value === 'boolean') return <span>{value ? 'true' : 'false'}</span>\n if (typeof value === 'number' || typeof value === 'bigint') return <span>{String(value)}</span>\n if (value instanceof Date) return <span>{value.toISOString()}</span>\n if (typeof value === 'string') return <span className=\"break-words\">{value}</span>\n return (\n <pre className=\"max-h-40 overflow-y-auto whitespace-pre-wrap break-words rounded-md bg-muted/50 px-2 py-1 text-xs leading-5 text-muted-foreground\">\n {safeStringify(value)}\n </pre>\n )\n}\n\nexport function safeStringify(value: unknown) {\n if (typeof value === 'string') return value\n try {\n return JSON.stringify(value, null, 2)\n } catch {\n return String(value)\n }\n}\n\nexport function formatResource(\n item: { resourceKind: string | null; resourceId: string | null },\n fallback: string,\n) {\n if (!item.resourceKind && !item.resourceId) return fallback\n return [item.resourceKind, item.resourceId].filter(Boolean).join(' \u00B7 ')\n}\n\nexport function formatDate(value: string) {\n const date = new Date(value)\n if (Number.isNaN(date.getTime())) return value\n return new Intl.DateTimeFormat(undefined, {\n dateStyle: 'medium',\n timeStyle: 'short',\n }).format(date)\n}\n\nexport type ChangedFieldsTableProps = {\n changeRows: ChangeRow[]\n noneLabel: string\n t: TranslateFn\n beforeLabel?: string\n afterLabel?: string\n}\n\nexport function ChangedFieldsTable({ changeRows, noneLabel, t, beforeLabel, afterLabel }: ChangedFieldsTableProps) {\n return (\n <section>\n <h3 className=\"text-sm font-semibold\">\n {t('audit_logs.actions.details.changed_fields')}\n </h3>\n {changeRows.length ? (\n <div className=\"mt-2 overflow-x-auto rounded-lg border\">\n <table className=\"min-w-full divide-y text-sm\">\n <thead className=\"bg-muted/50\">\n <tr>\n <th scope=\"col\" className=\"px-4 py-2 text-left font-medium text-muted-foreground\">\n {t('audit_logs.actions.details.field')}\n </th>\n <th scope=\"col\" className=\"px-4 py-2 text-left font-medium text-muted-foreground\">\n {beforeLabel ?? t('audit_logs.actions.details.before')}\n </th>\n <th scope=\"col\" className=\"px-4 py-2 text-left font-medium text-muted-foreground\">\n {afterLabel ?? t('audit_logs.actions.details.after')}\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-y\">\n {changeRows.map((row) => (\n <tr key={row.field} className=\"align-top\">\n <td className=\"px-4 py-2 align-top font-medium\">\n {humanizeField(normalizeChangeField(row.field))}\n </td>\n <td className=\"px-4 py-2\">\n {renderValue(row.from, noneLabel)}\n </td>\n <td className=\"px-4 py-2\">\n {renderValue(row.to, noneLabel)}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n ) : (\n <p className=\"mt-2 text-sm text-muted-foreground\">\n {t('audit_logs.actions.details.no_changes')}\n </p>\n )}\n </section>\n )\n}\n\nexport type CollapsibleJsonSectionProps = {\n label: string\n value: unknown\n truncateAt?: number\n}\n\nconst DEFAULT_TRUNCATE_AT = 5000\n\nconst COLLAPSIBLE_JSON_ITEM_VALUE = 'open'\n\nexport function CollapsibleJsonSection({ label, value, truncateAt = DEFAULT_TRUNCATE_AT }: CollapsibleJsonSectionProps) {\n const [openValue, setOpenValue] = React.useState<string>('')\n const [showFull, setShowFull] = React.useState(false)\n\n const isOpen = openValue === COLLAPSIBLE_JSON_ITEM_VALUE\n const stringified = React.useMemo(() => (isOpen ? safeStringify(value) : ''), [isOpen, value])\n const isTruncated = stringified.length > truncateAt\n const displayText = !showFull && isTruncated ? stringified.slice(0, truncateAt) : stringified\n\n return (\n <Accordion type=\"single\" collapsible value={openValue} onValueChange={setOpenValue}>\n <AccordionItem value={COLLAPSIBLE_JSON_ITEM_VALUE}>\n <AccordionTrigger>\n <span className=\"font-semibold text-foreground group-data-[state=open]/accordion-trigger:text-primary\">\n {label}\n </span>\n </AccordionTrigger>\n <AccordionContent>\n <pre className=\"max-h-96 overflow-auto whitespace-pre-wrap break-words text-xs leading-5 text-muted-foreground\">\n {displayText}\n {!showFull && isTruncated ? '\\n\u2026' : null}\n </pre>\n {isTruncated ? (\n <button\n type=\"button\"\n className=\"mt-1 text-xs text-primary hover:underline\"\n onClick={() => setShowFull((prev) => !prev)}\n >\n {showFull ? 'Show less' : `Show all (${Math.ceil(stringified.length / 1024)} KB)`}\n </button>\n ) : null}\n </AccordionContent>\n </AccordionItem>\n </Accordion>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["isRecord"]
|
|
7
7
|
}
|