raffel 1.1.97 → 1.1.98

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/dist/docs/try-it-proxy.d.ts +15 -0
  2. package/dist/docs/try-it-proxy.d.ts.map +1 -1
  3. package/dist/docs/try-it-proxy.js +54 -0
  4. package/dist/docs/try-it-proxy.js.map +1 -1
  5. package/dist/docs/ui/assets/protocol-console.js +13 -1
  6. package/dist/docs/ui/assets/raffel-docs.js +167 -1
  7. package/dist/docs/ui/client-script/index.d.ts.map +1 -1
  8. package/dist/docs/ui/client-script/index.js +3 -95
  9. package/dist/docs/ui/client-script/index.js.map +1 -1
  10. package/dist/docs/ui/html-builder.d.ts.map +1 -1
  11. package/dist/docs/ui/html-builder.js +6 -3
  12. package/dist/docs/ui/html-builder.js.map +1 -1
  13. package/dist/docs/ui/runtime/index.js +167 -1
  14. package/dist/docs/ui/runtime/index.js.map +1 -1
  15. package/dist/docs/ui/runtime/protocol-console.d.ts +2 -0
  16. package/dist/docs/ui/runtime/protocol-console.d.ts.map +1 -1
  17. package/dist/docs/ui/runtime/protocol-console.js +13 -1
  18. package/dist/docs/ui/runtime/protocol-console.js.map +1 -1
  19. package/dist/docs/usd-middleware.d.ts +2 -0
  20. package/dist/docs/usd-middleware.d.ts.map +1 -1
  21. package/dist/docs/usd-middleware.js +37 -1
  22. package/dist/docs/usd-middleware.js.map +1 -1
  23. package/dist/server/builder/execution-http-docs.d.ts.map +1 -1
  24. package/dist/server/builder/execution-http-docs.js +8 -0
  25. package/dist/server/builder/execution-http-docs.js.map +1 -1
  26. package/dist/server/rest-middleware.d.ts.map +1 -1
  27. package/dist/server/rest-middleware.js +26 -0
  28. package/dist/server/rest-middleware.js.map +1 -1
  29. package/dist/ui/docs/try-it-proxy.d.ts +15 -0
  30. package/dist/ui/docs/try-it-proxy.d.ts.map +1 -1
  31. package/dist/ui/docs/ui/client-script/index.d.ts.map +1 -1
  32. package/dist/ui/docs/ui/html-builder.d.ts.map +1 -1
  33. package/dist/ui/docs/ui/runtime/protocol-console.d.ts +2 -0
  34. package/dist/ui/docs/ui/runtime/protocol-console.d.ts.map +1 -1
  35. package/dist/ui/docs/usd-middleware.d.ts +2 -0
  36. package/dist/ui/docs/usd-middleware.d.ts.map +1 -1
  37. package/package.json +1 -1
  38. package/dist/docs/ui/client-script/cards-and-code.d.ts +0 -5
  39. package/dist/docs/ui/client-script/cards-and-code.d.ts.map +0 -1
  40. package/dist/docs/ui/client-script/cards-and-code.js +0 -5
  41. package/dist/docs/ui/client-script/cards-and-code.js.map +0 -1
  42. package/dist/docs/ui/client-script/content.d.ts +0 -5
  43. package/dist/docs/ui/client-script/content.d.ts.map +0 -1
  44. package/dist/docs/ui/client-script/content.js +0 -412
  45. package/dist/docs/ui/client-script/content.js.map +0 -1
  46. package/dist/docs/ui/client-script/docs-pages.d.ts +0 -5
  47. package/dist/docs/ui/client-script/docs-pages.d.ts.map +0 -1
  48. package/dist/docs/ui/client-script/docs-pages.js +0 -153
  49. package/dist/docs/ui/client-script/docs-pages.js.map +0 -1
  50. package/dist/docs/ui/client-script/endpoint-details.d.ts +0 -5
  51. package/dist/docs/ui/client-script/endpoint-details.d.ts.map +0 -1
  52. package/dist/docs/ui/client-script/endpoint-details.js +0 -5
  53. package/dist/docs/ui/client-script/endpoint-details.js.map +0 -1
  54. package/dist/docs/ui/client-script/init.d.ts +0 -5
  55. package/dist/docs/ui/client-script/init.d.ts.map +0 -1
  56. package/dist/docs/ui/client-script/init.js +0 -227
  57. package/dist/docs/ui/client-script/init.js.map +0 -1
  58. package/dist/docs/ui/client-script/markdown.d.ts +0 -5
  59. package/dist/docs/ui/client-script/markdown.d.ts.map +0 -1
  60. package/dist/docs/ui/client-script/markdown.js +0 -438
  61. package/dist/docs/ui/client-script/markdown.js.map +0 -1
  62. package/dist/docs/ui/client-script/navigation.d.ts +0 -5
  63. package/dist/docs/ui/client-script/navigation.d.ts.map +0 -1
  64. package/dist/docs/ui/client-script/navigation.js +0 -548
  65. package/dist/docs/ui/client-script/navigation.js.map +0 -1
  66. package/dist/docs/ui/client-script/protocols.d.ts +0 -5
  67. package/dist/docs/ui/client-script/protocols.d.ts.map +0 -1
  68. package/dist/docs/ui/client-script/protocols.js +0 -5
  69. package/dist/docs/ui/client-script/protocols.js.map +0 -1
  70. package/dist/docs/ui/client-script/schema-rendering.d.ts +0 -5
  71. package/dist/docs/ui/client-script/schema-rendering.d.ts.map +0 -1
  72. package/dist/docs/ui/client-script/schema-rendering.js +0 -5
  73. package/dist/docs/ui/client-script/schema-rendering.js.map +0 -1
  74. package/dist/docs/ui/client-script/try-it.d.ts +0 -5
  75. package/dist/docs/ui/client-script/try-it.d.ts.map +0 -1
  76. package/dist/docs/ui/client-script/try-it.js +0 -5
  77. package/dist/docs/ui/client-script/try-it.js.map +0 -1
  78. package/dist/ui/docs/ui/client-script/cards-and-code.d.ts +0 -5
  79. package/dist/ui/docs/ui/client-script/cards-and-code.d.ts.map +0 -1
  80. package/dist/ui/docs/ui/client-script/content.d.ts +0 -5
  81. package/dist/ui/docs/ui/client-script/content.d.ts.map +0 -1
  82. package/dist/ui/docs/ui/client-script/docs-pages.d.ts +0 -5
  83. package/dist/ui/docs/ui/client-script/docs-pages.d.ts.map +0 -1
  84. package/dist/ui/docs/ui/client-script/endpoint-details.d.ts +0 -5
  85. package/dist/ui/docs/ui/client-script/endpoint-details.d.ts.map +0 -1
  86. package/dist/ui/docs/ui/client-script/init.d.ts +0 -5
  87. package/dist/ui/docs/ui/client-script/init.d.ts.map +0 -1
  88. package/dist/ui/docs/ui/client-script/markdown.d.ts +0 -5
  89. package/dist/ui/docs/ui/client-script/markdown.d.ts.map +0 -1
  90. package/dist/ui/docs/ui/client-script/navigation.d.ts +0 -5
  91. package/dist/ui/docs/ui/client-script/navigation.d.ts.map +0 -1
  92. package/dist/ui/docs/ui/client-script/protocols.d.ts +0 -5
  93. package/dist/ui/docs/ui/client-script/protocols.d.ts.map +0 -1
  94. package/dist/ui/docs/ui/client-script/schema-rendering.d.ts +0 -5
  95. package/dist/ui/docs/ui/client-script/schema-rendering.d.ts.map +0 -1
  96. package/dist/ui/docs/ui/client-script/try-it.d.ts +0 -5
  97. package/dist/ui/docs/ui/client-script/try-it.d.ts.map +0 -1
@@ -1,5 +0,0 @@
1
- /**
2
- * Embedded docs UI client script chunk.
3
- */
4
- export declare const schemaRenderingClientScript = " // ========== SCHEMA RENDERING HELPERS ==========\n\n function resolveRef(ref) {\n if (!ref || typeof ref !== 'string') return null;\n const parts = ref.replace('#/', '').split('/');\n let result = spec;\n for (const part of parts) {\n if (!result) return null;\n result = result[part];\n }\n return result;\n }\n\n function getSchemaType(schema) {\n if (!schema) return 'any';\n if (schema.$ref) {\n const resolved = resolveRef(schema.$ref);\n return resolved ? getSchemaType(resolved) : 'ref';\n }\n if (schema.oneOf) return 'oneOf';\n if (schema.anyOf) return 'anyOf';\n if (schema.allOf) return 'allOf';\n if (Array.isArray(schema.type)) return schema.type.join(' | ');\n return schema.type || 'any';\n }\n\n function getTypeClass(type) {\n const t = (type || '').toLowerCase();\n if (t === 'string') return 'type-string';\n if (t === 'number' || t === 'integer') return 'type-number';\n if (t === 'boolean') return 'type-boolean';\n if (t === 'object') return 'type-object';\n if (t === 'array') return 'type-array';\n if (t === 'null') return 'type-null';\n return 'type-ref';\n }\n\n function getRefName(ref) {\n if (!ref) return '';\n const parts = ref.split('/');\n return parts[parts.length - 1];\n }\n\n function renderSchemaType(schema, showFormat) {\n if (!schema) return '<span class=\"schema-type type-ref\">any</span>';\n\n if (schema.$ref) {\n const name = getRefName(schema.$ref);\n return '<span class=\"schema-type type-ref\">' + esc(name) + '</span>';\n }\n\n let type = getSchemaType(schema);\n let extra = '';\n\n if (schema.format && showFormat !== false) {\n extra = '<' + schema.format + '>';\n }\n\n if (type === 'array' && schema.items) {\n const itemType = schema.items.$ref\n ? getRefName(schema.items.$ref)\n : getSchemaType(schema.items);\n return '<span class=\"schema-type type-array\">array[' + esc(itemType) + ']</span>';\n }\n\n if (type === 'oneOf' || type === 'anyOf' || type === 'allOf') {\n const items = schema[type];\n const types = items.map(s => s.$ref ? getRefName(s.$ref) : getSchemaType(s));\n return '<span class=\"schema-type type-ref\">' + esc(type) + '(' + types.join(', ') + ')</span>';\n }\n\n return '<span class=\"schema-type ' + getTypeClass(type) + '\">' + esc(type + extra) + '</span>';\n }\n\n function renderConstraints(schema) {\n const constraints = [];\n\n // String constraints\n if (schema.minLength !== undefined) constraints.push('minLength: ' + schema.minLength);\n if (schema.maxLength !== undefined) constraints.push('maxLength: ' + schema.maxLength);\n if (schema.pattern) constraints.push('pattern: ' + schema.pattern);\n\n // Number constraints\n if (schema.minimum !== undefined) constraints.push('min: ' + schema.minimum);\n if (schema.maximum !== undefined) constraints.push('max: ' + schema.maximum);\n if (schema.exclusiveMinimum !== undefined) constraints.push('exclusiveMin: ' + schema.exclusiveMinimum);\n if (schema.exclusiveMaximum !== undefined) constraints.push('exclusiveMax: ' + schema.exclusiveMaximum);\n if (schema.multipleOf !== undefined) constraints.push('multipleOf: ' + schema.multipleOf);\n\n // Array constraints\n if (schema.minItems !== undefined) constraints.push('minItems: ' + schema.minItems);\n if (schema.maxItems !== undefined) constraints.push('maxItems: ' + schema.maxItems);\n if (schema.uniqueItems) constraints.push('uniqueItems');\n\n // Object constraints\n if (schema.minProperties !== undefined) constraints.push('minProperties: ' + schema.minProperties);\n if (schema.maxProperties !== undefined) constraints.push('maxProperties: ' + schema.maxProperties);\n\n if (constraints.length === 0) return '';\n\n return '<div class=\"schema-constraints\">' +\n constraints.map(c => '<span class=\"schema-constraint\">' + esc(c) + '</span>').join('') +\n '</div>';\n }\n\n function renderEnumValues(schema) {\n if (!schema.enum || schema.enum.length === 0) return '';\n\n return '<div class=\"schema-enum\">' +\n '<span style=\"font-size: 11px; color: var(--text-muted); margin-right: 4px;\">Enum:</span>' +\n schema.enum.map(v => '<span class=\"schema-enum-value\">' + esc(JSON.stringify(v)) + '</span>').join('') +\n '</div>';\n }\n\n function renderDefault(schema) {\n if (schema.default === undefined) return '';\n return '<div class=\"schema-default\">Default: <code>' + esc(JSON.stringify(schema.default)) + '</code></div>';\n }\n\n let schemaIdCounter = 0;\n\n // Normalize non-standard schema formats (e.g., from some Zod conversions)\n function normalizeSchema(schema) {\n if (!schema) return schema;\n\n // Handle schemas with 'def' and 'shape' (non-standard Zod output)\n if (schema.def && schema.def.shape) {\n const normalized = { type: 'object', properties: {} };\n for (const [key, val] of Object.entries(schema.def.shape)) {\n normalized.properties[key] = normalizeSchema(val);\n }\n return normalized;\n }\n\n // Handle 'innerType' for default values\n if (schema.def && schema.def.innerType) {\n const inner = normalizeSchema(schema.def.innerType);\n if (schema.def.defaultValue !== undefined) {\n inner.default = schema.def.defaultValue;\n }\n return inner;\n }\n\n // Handle simple def types\n if (schema.def && schema.def.type === 'string') {\n const result = { type: 'string' };\n if (schema.format) result.format = schema.format;\n if (schema.minLength) result.minLength = schema.minLength;\n if (schema.maxLength) result.maxLength = schema.maxLength;\n return result;\n }\n\n if (schema.def && schema.def.type === 'number') {\n return { type: 'number' };\n }\n\n if (schema.def && schema.def.type === 'integer') {\n return { type: 'integer' };\n }\n\n if (schema.def && schema.def.type === 'boolean') {\n return { type: 'boolean' };\n }\n\n return schema;\n }\n\n // ========== REDOC-STYLE RENDERING FUNCTIONS ==========\n\n function renderParametersRedocStyle(params) {\n const container = document.createElement('div');\n\n params.forEach(param => {\n const row = document.createElement('div');\n row.className = 'param-row';\n\n // Tree line\n const tree = document.createElement('div');\n tree.className = 'param-tree';\n tree.innerHTML = '<div class=\"param-tree-line\"></div>';\n row.appendChild(tree);\n\n // Info\n const info = document.createElement('div');\n info.className = 'param-info';\n\n // Header row: name, required badge, type\n const header = document.createElement('div');\n header.className = 'param-header';\n\n const nameSpan = document.createElement('span');\n nameSpan.className = 'param-name-text';\n nameSpan.textContent = param.name;\n header.appendChild(nameSpan);\n\n if (param.required) {\n const reqBadge = document.createElement('span');\n reqBadge.className = 'param-required-badge';\n reqBadge.textContent = 'required';\n header.appendChild(reqBadge);\n }\n\n // Type info\n const schema = param.schema || {};\n const typeInfo = document.createElement('span');\n typeInfo.className = 'param-type-info';\n let typeText = schema.type || 'string';\n if (schema.format) {\n typeText += ' <span class=\"format\">&lt;' + esc(schema.format) + '&gt;</span>';\n }\n typeInfo.innerHTML = typeText;\n header.appendChild(typeInfo);\n\n // Constraints\n if (schema.maximum !== undefined || schema.minimum !== undefined) {\n const constraint = document.createElement('span');\n constraint.className = 'param-constraint';\n if (schema.maximum !== undefined) {\n constraint.textContent = '<= ' + schema.maximum;\n } else if (schema.minimum !== undefined) {\n constraint.textContent = '>= ' + schema.minimum;\n }\n header.appendChild(constraint);\n }\n\n info.appendChild(header);\n\n // Default value\n if (schema.default !== undefined) {\n const def = document.createElement('div');\n def.className = 'param-default';\n def.innerHTML = 'Default: <code>' + esc(JSON.stringify(schema.default)) + '</code>';\n info.appendChild(def);\n }\n\n // Example\n if (schema.example !== undefined || param.example !== undefined) {\n const ex = document.createElement('div');\n ex.className = 'param-example';\n const exValue = param.example !== undefined ? param.example : schema.example;\n ex.innerHTML = 'Example: <code>' + esc(param.name + '=' + exValue) + '</code>';\n info.appendChild(ex);\n }\n\n // Description\n if (param.description || schema.description) {\n const desc = document.createElement('div');\n desc.className = 'param-description';\n desc.textContent = param.description || schema.description;\n info.appendChild(desc);\n }\n\n row.appendChild(info);\n container.appendChild(row);\n });\n\n return container;\n }\n\n function renderRequestBodyRedocStyle(reqBody) {\n const container = document.createElement('div');\n\n // Get schema\n const content = reqBody.content || {};\n const contentType = Object.keys(content)[0] || 'application/json';\n const mediaType = content[contentType] || {};\n const schema = mediaType.schema;\n\n if (schema) {\n // Resolve and normalize\n let actualSchema = schema.$ref ? resolveRef(schema.$ref) : schema;\n actualSchema = normalizeSchema(actualSchema);\n\n // Render properties as Redoc-style rows\n if (actualSchema && actualSchema.properties) {\n const required = actualSchema.required || [];\n Object.entries(actualSchema.properties).forEach(([propName, propSchema]) => {\n const row = renderPropertyRow(propName, propSchema, required.includes(propName), 0);\n container.appendChild(row);\n });\n } else if (actualSchema && actualSchema.type === 'array' && actualSchema.items) {\n const itemSchema = actualSchema.items.$ref ? resolveRef(actualSchema.items.$ref) : actualSchema.items;\n const arrayLabel = document.createElement('div');\n arrayLabel.style.marginBottom = '12px';\n arrayLabel.innerHTML = '<span class=\"param-type-info\">Array [</span>';\n container.appendChild(arrayLabel);\n\n if (itemSchema && itemSchema.properties) {\n const required = itemSchema.required || [];\n Object.entries(itemSchema.properties).forEach(([propName, propSchema]) => {\n const row = renderPropertyRow(propName, propSchema, required.includes(propName), 1);\n container.appendChild(row);\n });\n }\n\n const arrayEnd = document.createElement('div');\n arrayEnd.innerHTML = '<span class=\"param-type-info\">]</span>';\n container.appendChild(arrayEnd);\n }\n }\n\n return container;\n }\n\n function renderPropertyRow(name, schema, isRequired, depth) {\n const row = document.createElement('div');\n row.className = 'param-row';\n if (depth > 0) {\n row.style.paddingLeft = (depth * 20) + 'px';\n }\n\n // Tree line\n const tree = document.createElement('div');\n tree.className = 'param-tree';\n tree.innerHTML = '<div class=\"param-tree-line\"></div>';\n row.appendChild(tree);\n\n // Info\n const info = document.createElement('div');\n info.className = 'param-info';\n\n // Header row\n const header = document.createElement('div');\n header.className = 'param-header';\n\n const nameSpan = document.createElement('span');\n nameSpan.className = 'param-name-text';\n nameSpan.textContent = name;\n header.appendChild(nameSpan);\n\n if (isRequired) {\n const reqBadge = document.createElement('span');\n reqBadge.className = 'param-required-badge';\n reqBadge.textContent = 'required';\n header.appendChild(reqBadge);\n }\n\n // Type info\n const resolved = schema.$ref ? resolveRef(schema.$ref) : schema;\n const normalized = normalizeSchema(resolved) || resolved || {};\n const typeInfo = document.createElement('span');\n typeInfo.className = 'param-type-info';\n let typeText = normalized.type || 'any';\n if (normalized.format) {\n typeText += ' <span class=\"format\">(' + esc(normalized.format) + ')</span>';\n }\n if (schema.$ref) {\n typeText = '<span class=\"format\">' + esc(getRefName(schema.$ref)) + '</span>';\n }\n typeInfo.innerHTML = typeText;\n header.appendChild(typeInfo);\n\n // Pattern/constraint\n if (normalized.pattern) {\n const constraint = document.createElement('span');\n constraint.className = 'param-constraint';\n constraint.textContent = normalized.pattern;\n header.appendChild(constraint);\n }\n\n info.appendChild(header);\n\n // Default\n if (normalized.default !== undefined) {\n const def = document.createElement('div');\n def.className = 'param-default';\n def.innerHTML = 'Default: <code>' + esc(JSON.stringify(normalized.default)) + '</code>';\n info.appendChild(def);\n }\n\n // Example\n if (normalized.example !== undefined) {\n const ex = document.createElement('div');\n ex.className = 'param-example';\n ex.innerHTML = 'Example: <code>' + esc(JSON.stringify(normalized.example)) + '</code>';\n info.appendChild(ex);\n }\n\n // Description\n if (normalized.description) {\n const desc = document.createElement('div');\n desc.className = 'param-description';\n desc.textContent = normalized.description;\n info.appendChild(desc);\n }\n\n row.appendChild(info);\n return row;\n }\n\n function renderResponsesRedocStyle(responses) {\n const container = document.createElement('div');\n const statusCodes = Object.keys(responses).sort();\n\n statusCodes.forEach((status, idx) => {\n const response = responses[status];\n const statusClass = status.startsWith('2') ? 'status-2xx' :\n status.startsWith('4') ? 'status-4xx' :\n status.startsWith('5') ? 'status-5xx' : '';\n\n const item = document.createElement('div');\n item.className = 'response-item' + (idx === 0 ? ' expanded' : '');\n\n // Header\n const header = document.createElement('div');\n header.className = 'response-header';\n header.innerHTML = '<span class=\"response-arrow\">\u25B6</span>' +\n '<span class=\"response-status ' + statusClass + '\">' + esc(status) + '</span>' +\n '<span class=\"response-desc\">' + esc(response.description || '') + '</span>';\n header.onclick = () => item.classList.toggle('expanded');\n item.appendChild(header);\n\n // Body (headers + schema)\n const body = document.createElement('div');\n body.className = 'response-body';\n\n // Render response headers if present\n if (response.headers && Object.keys(response.headers).length > 0) {\n const headersSection = document.createElement('div');\n headersSection.className = 'response-headers-section';\n\n const headersLabel = document.createElement('div');\n headersLabel.className = 'response-headers-label';\n headersLabel.textContent = 'RESPONSE HEADERS';\n headersSection.appendChild(headersLabel);\n\n Object.entries(response.headers).forEach(([headerName, headerDef]) => {\n const resolved = headerDef.$ref ? resolveRef(headerDef.$ref) : headerDef;\n const row = document.createElement('div');\n row.className = 'response-header-row';\n\n const nameEl = document.createElement('div');\n nameEl.className = 'response-header-name';\n nameEl.textContent = headerName;\n if (resolved.required) {\n nameEl.innerHTML += '<span class=\"response-header-required\">required</span>';\n }\n\n const infoEl = document.createElement('div');\n infoEl.className = 'response-header-info';\n\n const typeStr = resolved.schema ? (resolved.schema.type || 'string') : 'string';\n const typeEl = document.createElement('div');\n typeEl.className = 'response-header-type';\n typeEl.textContent = typeStr;\n infoEl.appendChild(typeEl);\n\n if (resolved.description) {\n const descEl = document.createElement('div');\n descEl.className = 'response-header-desc';\n descEl.textContent = resolved.description;\n infoEl.appendChild(descEl);\n }\n\n row.appendChild(nameEl);\n row.appendChild(infoEl);\n headersSection.appendChild(row);\n });\n\n body.appendChild(headersSection);\n }\n\n const respContent = response.content || {};\n const contentType = Object.keys(respContent)[0];\n if (contentType) {\n const label = document.createElement('div');\n label.className = 'response-schema-label';\n label.innerHTML = 'RESPONSE SCHEMA: <span class=\"content-type\">' + esc(contentType) + '</span>';\n body.appendChild(label);\n\n const mediaType = respContent[contentType] || {};\n const schema = mediaType.schema;\n if (schema) {\n let actualSchema = schema.$ref ? resolveRef(schema.$ref) : schema;\n actualSchema = normalizeSchema(actualSchema);\n\n if (actualSchema && actualSchema.properties) {\n const required = actualSchema.required || [];\n Object.entries(actualSchema.properties).forEach(([propName, propSchema]) => {\n const row = renderPropertyRow(propName, propSchema, required.includes(propName), 0);\n body.appendChild(row);\n });\n } else if (actualSchema && actualSchema.type === 'array' && actualSchema.items) {\n const itemSchema = actualSchema.items.$ref ? resolveRef(actualSchema.items.$ref) : actualSchema.items;\n const arrayLabel = document.createElement('div');\n arrayLabel.innerHTML = '<span class=\"param-type-info\">Array [</span>';\n arrayLabel.style.marginBottom = '8px';\n body.appendChild(arrayLabel);\n\n if (itemSchema && itemSchema.properties) {\n const itemRequired = itemSchema.required || [];\n Object.entries(itemSchema.properties).forEach(([propName, propSchema]) => {\n const row = renderPropertyRow(propName, propSchema, itemRequired.includes(propName), 1);\n body.appendChild(row);\n });\n }\n\n const arrayEnd = document.createElement('div');\n arrayEnd.innerHTML = '<span class=\"param-type-info\">]</span>';\n body.appendChild(arrayEnd);\n }\n }\n }\n\n item.appendChild(body);\n container.appendChild(item);\n });\n\n return container;\n }\n\n function renderSchemaProperties(schema, requiredProps, depth) {\n const container = document.createElement('div');\n container.className = 'schema-container';\n\n // Normalize non-standard schemas first\n let actualSchema = normalizeSchema(schema);\n\n // Handle $ref\n if (actualSchema.$ref) {\n const resolved = resolveRef(actualSchema.$ref);\n actualSchema = normalizeSchema(resolved) || actualSchema;\n }\n\n // Handle allOf, oneOf, anyOf by merging/showing options\n if (actualSchema.allOf) {\n actualSchema.allOf.forEach((subSchema, idx) => {\n const resolved = subSchema.$ref ? resolveRef(subSchema.$ref) : subSchema;\n if (resolved && resolved.properties) {\n renderPropertiesInto(container, resolved, resolved.required || [], depth);\n }\n });\n return container;\n }\n\n if (actualSchema.oneOf || actualSchema.anyOf) {\n const variants = actualSchema.oneOf || actualSchema.anyOf;\n const label = actualSchema.oneOf ? 'One of' : 'Any of';\n const row = document.createElement('div');\n row.className = 'schema-row';\n row.innerHTML = '<div class=\"schema-property\">' +\n '<span class=\"schema-name\" style=\"font-style: italic;\">' + label + ':</span>' +\n '</div><div class=\"schema-details\">' +\n variants.map((v, i) => {\n const name = v.$ref ? getRefName(v.$ref) : ('Option ' + (i + 1));\n return '<span class=\"schema-type type-ref\" style=\"margin-right: 6px; cursor: pointer;\">' + esc(name) + '</span>';\n }).join('') +\n '</div>';\n container.appendChild(row);\n return container;\n }\n\n // Render object properties\n if (actualSchema.properties) {\n renderPropertiesInto(container, actualSchema, requiredProps || actualSchema.required || [], depth);\n } else if (actualSchema.type === 'array' && actualSchema.items) {\n // For arrays, show the items schema\n const itemSchema = actualSchema.items.$ref ? resolveRef(actualSchema.items.$ref) : actualSchema.items;\n if (itemSchema && itemSchema.properties) {\n renderPropertiesInto(container, itemSchema, itemSchema.required || [], depth);\n } else {\n const row = document.createElement('div');\n row.className = 'schema-row';\n row.innerHTML = '<div class=\"schema-property\">' +\n '<span class=\"schema-name\">[items]</span>' +\n '</div><div class=\"schema-details\">' +\n renderSchemaType(actualSchema.items, true) +\n '</div>';\n container.appendChild(row);\n }\n } else if (Object.keys(actualSchema).length === 0 || actualSchema.type === 'object') {\n const row = document.createElement('div');\n row.className = 'schema-row';\n row.innerHTML = '<div class=\"schema-property\">' +\n '<span class=\"schema-name\" style=\"color: var(--text-muted); font-style: italic;\">empty object</span>' +\n '</div>';\n container.appendChild(row);\n }\n\n return container;\n }\n\n function renderPropertiesInto(container, schema, requiredProps, depth) {\n const props = schema.properties || {};\n const required = requiredProps || [];\n const depthClass = depth > 0 ? ' nested' + (depth > 1 ? '-' + Math.min(depth, 4) : '') : '';\n\n Object.entries(props).forEach(([propName, propSchema]) => {\n const isRequired = required.includes(propName);\n const resolved = propSchema.$ref ? resolveRef(propSchema.$ref) : propSchema;\n const hasNested = resolved && (resolved.properties || (resolved.type === 'array' && resolved.items?.properties));\n\n const row = document.createElement('div');\n row.className = 'schema-row' + depthClass;\n\n const id = 'schema-' + (schemaIdCounter++);\n\n let toggleHtml = '';\n if (hasNested) {\n toggleHtml = '<span class=\"schema-toggle\" data-target=\"' + id + '\">\u25BC expand</span>';\n }\n\n let detailsHtml = '<div class=\"schema-details\">' +\n renderSchemaType(propSchema, true) + toggleHtml;\n\n if (resolved?.description) {\n detailsHtml += '<div class=\"schema-desc\">' + esc(resolved.description) + '</div>';\n }\n\n detailsHtml += renderConstraints(resolved || {});\n detailsHtml += renderEnumValues(resolved || {});\n detailsHtml += renderDefault(resolved || {});\n detailsHtml += '</div>';\n\n row.innerHTML = '<div class=\"schema-property\">' +\n '<span class=\"schema-name\">' + esc(propName) + '</span>' +\n (isRequired ? '<span class=\"schema-required\">*</span>' : '') +\n '</div>' + detailsHtml;\n\n container.appendChild(row);\n\n // Add nested container for expandable schemas\n if (hasNested) {\n const nestedContainer = document.createElement('div');\n nestedContainer.id = id;\n nestedContainer.className = 'schema-nested-container collapsed';\n\n if (resolved.properties) {\n const nested = renderSchemaProperties(resolved, resolved.required || [], depth + 1);\n nestedContainer.appendChild(nested);\n } else if (resolved.type === 'array' && resolved.items) {\n const itemSchema = resolved.items.$ref ? resolveRef(resolved.items.$ref) : resolved.items;\n if (itemSchema) {\n const nested = renderSchemaProperties(itemSchema, itemSchema.required || [], depth + 1);\n nestedContainer.appendChild(nested);\n }\n }\n\n container.appendChild(nestedContainer);\n\n // Add click handler for toggle\n const toggle = row.querySelector('.schema-toggle');\n if (toggle) {\n toggle.onclick = () => {\n nestedContainer.classList.toggle('collapsed');\n toggle.textContent = nestedContainer.classList.contains('collapsed') ? '\u25BC expand' : '\u25B2 collapse';\n };\n }\n }\n });\n }\n\n function renderParameters(params) {\n if (!params || params.length === 0) return null;\n\n const container = document.createElement('div');\n const table = document.createElement('table');\n table.className = 'params-table';\n\n const thead = document.createElement('thead');\n thead.innerHTML = '<tr><th>Name</th><th>Type</th><th>Description</th></tr>';\n table.appendChild(thead);\n\n const tbody = document.createElement('tbody');\n params.forEach(param => {\n const schema = param.schema || {};\n const tr = document.createElement('tr');\n tr.innerHTML = '<td>' +\n '<span class=\"param-name\">' + esc(param.name) + '</span>' +\n '<span class=\"param-in\">' + esc(param.in) + '</span>' +\n (param.required ? '<span class=\"schema-required\"> *</span>' : '') +\n '</td>' +\n '<td>' + renderSchemaType(schema, true) + '</td>' +\n '<td>' + esc(param.description || schema.description || '') +\n renderDefault(schema) + '</td>';\n tbody.appendChild(tr);\n });\n table.appendChild(tbody);\n container.appendChild(table);\n\n return container;\n }\n\n function renderRequestBody(reqBody) {\n if (!reqBody) return null;\n\n const container = document.createElement('div');\n\n if (reqBody.description) {\n const desc = document.createElement('p');\n desc.className = 'schema-desc';\n desc.textContent = reqBody.description;\n container.appendChild(desc);\n }\n\n // Get content type (usually application/json)\n const content = reqBody.content || {};\n const contentType = Object.keys(content)[0] || 'application/json';\n const mediaType = content[contentType] || {};\n const schema = mediaType.schema;\n\n if (schema) {\n const schemaEl = renderSchemaProperties(schema, schema.required || [], 0);\n container.appendChild(schemaEl);\n\n // Show example if available\n if (mediaType.example || schema.example) {\n const example = mediaType.example || schema.example;\n const exampleDiv = document.createElement('div');\n exampleDiv.className = 'schema-example';\n exampleDiv.innerHTML = '<div class=\"schema-example-header\">Example</div>' +\n '<div class=\"schema-example-body\">' + esc(JSON.stringify(example, null, 2)) + '</div>';\n container.appendChild(exampleDiv);\n }\n }\n\n return container;\n }\n\n function renderResponses(responses) {\n if (!responses) return null;\n\n const container = document.createElement('div');\n const statusCodes = Object.keys(responses).sort();\n\n if (statusCodes.length === 0) return null;\n\n // Create tabs\n const tabs = document.createElement('div');\n tabs.className = 'response-tabs';\n\n const contents = document.createElement('div');\n\n statusCodes.forEach((status, idx) => {\n const statusClass = status.startsWith('2') ? 'status-2xx' :\n status.startsWith('4') ? 'status-4xx' :\n status.startsWith('5') ? 'status-5xx' : '';\n\n const tab = document.createElement('button');\n tab.className = 'response-tab ' + statusClass + (idx === 0 ? ' active' : '');\n tab.textContent = status;\n tab.dataset.status = status;\n tabs.appendChild(tab);\n\n const content = document.createElement('div');\n content.className = 'response-content' + (idx === 0 ? ' active' : '');\n content.dataset.status = status;\n\n const response = responses[status];\n if (response.description) {\n const desc = document.createElement('p');\n desc.className = 'schema-desc';\n desc.textContent = response.description;\n content.appendChild(desc);\n }\n\n // Get schema from content\n const respContent = response.content || {};\n const contentType = Object.keys(respContent)[0] || 'application/json';\n const mediaType = respContent[contentType] || {};\n const schema = mediaType.schema;\n\n if (schema) {\n const schemaEl = renderSchemaProperties(schema, schema.required || [], 0);\n content.appendChild(schemaEl);\n\n // Show example if available\n if (mediaType.example || schema.example) {\n const example = mediaType.example || schema.example;\n const exampleDiv = document.createElement('div');\n exampleDiv.className = 'schema-example';\n exampleDiv.innerHTML = '<div class=\"schema-example-header\">Example</div>' +\n '<div class=\"schema-example-body\">' + esc(JSON.stringify(example, null, 2)) + '</div>';\n content.appendChild(exampleDiv);\n }\n }\n\n contents.appendChild(content);\n });\n\n container.appendChild(tabs);\n container.appendChild(contents);\n\n // Tab click handler\n tabs.onclick = (e) => {\n if (e.target.classList.contains('response-tab')) {\n const status = e.target.dataset.status;\n tabs.querySelectorAll('.response-tab').forEach(t => t.classList.remove('active'));\n contents.querySelectorAll('.response-content').forEach(c => c.classList.remove('active'));\n e.target.classList.add('active');\n contents.querySelector('[data-status=\"' + status + '\"]').classList.add('active');\n }\n };\n\n return container;\n }\n\n";
5
- //# sourceMappingURL=schema-rendering.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"schema-rendering.d.ts","sourceRoot":"","sources":["../../../../src/docs/ui/client-script/schema-rendering.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,2BAA2B,+v+BAA2u+B,CAAA"}
@@ -1,5 +0,0 @@
1
- /**
2
- * Embedded docs UI client script chunk.
3
- */
4
- export const schemaRenderingClientScript = " // ========== SCHEMA RENDERING HELPERS ==========\n\n function resolveRef(ref) {\n if (!ref || typeof ref !== 'string') return null;\n const parts = ref.replace('#/', '').split('/');\n let result = spec;\n for (const part of parts) {\n if (!result) return null;\n result = result[part];\n }\n return result;\n }\n\n function getSchemaType(schema) {\n if (!schema) return 'any';\n if (schema.$ref) {\n const resolved = resolveRef(schema.$ref);\n return resolved ? getSchemaType(resolved) : 'ref';\n }\n if (schema.oneOf) return 'oneOf';\n if (schema.anyOf) return 'anyOf';\n if (schema.allOf) return 'allOf';\n if (Array.isArray(schema.type)) return schema.type.join(' | ');\n return schema.type || 'any';\n }\n\n function getTypeClass(type) {\n const t = (type || '').toLowerCase();\n if (t === 'string') return 'type-string';\n if (t === 'number' || t === 'integer') return 'type-number';\n if (t === 'boolean') return 'type-boolean';\n if (t === 'object') return 'type-object';\n if (t === 'array') return 'type-array';\n if (t === 'null') return 'type-null';\n return 'type-ref';\n }\n\n function getRefName(ref) {\n if (!ref) return '';\n const parts = ref.split('/');\n return parts[parts.length - 1];\n }\n\n function renderSchemaType(schema, showFormat) {\n if (!schema) return '<span class=\"schema-type type-ref\">any</span>';\n\n if (schema.$ref) {\n const name = getRefName(schema.$ref);\n return '<span class=\"schema-type type-ref\">' + esc(name) + '</span>';\n }\n\n let type = getSchemaType(schema);\n let extra = '';\n\n if (schema.format && showFormat !== false) {\n extra = '<' + schema.format + '>';\n }\n\n if (type === 'array' && schema.items) {\n const itemType = schema.items.$ref\n ? getRefName(schema.items.$ref)\n : getSchemaType(schema.items);\n return '<span class=\"schema-type type-array\">array[' + esc(itemType) + ']</span>';\n }\n\n if (type === 'oneOf' || type === 'anyOf' || type === 'allOf') {\n const items = schema[type];\n const types = items.map(s => s.$ref ? getRefName(s.$ref) : getSchemaType(s));\n return '<span class=\"schema-type type-ref\">' + esc(type) + '(' + types.join(', ') + ')</span>';\n }\n\n return '<span class=\"schema-type ' + getTypeClass(type) + '\">' + esc(type + extra) + '</span>';\n }\n\n function renderConstraints(schema) {\n const constraints = [];\n\n // String constraints\n if (schema.minLength !== undefined) constraints.push('minLength: ' + schema.minLength);\n if (schema.maxLength !== undefined) constraints.push('maxLength: ' + schema.maxLength);\n if (schema.pattern) constraints.push('pattern: ' + schema.pattern);\n\n // Number constraints\n if (schema.minimum !== undefined) constraints.push('min: ' + schema.minimum);\n if (schema.maximum !== undefined) constraints.push('max: ' + schema.maximum);\n if (schema.exclusiveMinimum !== undefined) constraints.push('exclusiveMin: ' + schema.exclusiveMinimum);\n if (schema.exclusiveMaximum !== undefined) constraints.push('exclusiveMax: ' + schema.exclusiveMaximum);\n if (schema.multipleOf !== undefined) constraints.push('multipleOf: ' + schema.multipleOf);\n\n // Array constraints\n if (schema.minItems !== undefined) constraints.push('minItems: ' + schema.minItems);\n if (schema.maxItems !== undefined) constraints.push('maxItems: ' + schema.maxItems);\n if (schema.uniqueItems) constraints.push('uniqueItems');\n\n // Object constraints\n if (schema.minProperties !== undefined) constraints.push('minProperties: ' + schema.minProperties);\n if (schema.maxProperties !== undefined) constraints.push('maxProperties: ' + schema.maxProperties);\n\n if (constraints.length === 0) return '';\n\n return '<div class=\"schema-constraints\">' +\n constraints.map(c => '<span class=\"schema-constraint\">' + esc(c) + '</span>').join('') +\n '</div>';\n }\n\n function renderEnumValues(schema) {\n if (!schema.enum || schema.enum.length === 0) return '';\n\n return '<div class=\"schema-enum\">' +\n '<span style=\"font-size: 11px; color: var(--text-muted); margin-right: 4px;\">Enum:</span>' +\n schema.enum.map(v => '<span class=\"schema-enum-value\">' + esc(JSON.stringify(v)) + '</span>').join('') +\n '</div>';\n }\n\n function renderDefault(schema) {\n if (schema.default === undefined) return '';\n return '<div class=\"schema-default\">Default: <code>' + esc(JSON.stringify(schema.default)) + '</code></div>';\n }\n\n let schemaIdCounter = 0;\n\n // Normalize non-standard schema formats (e.g., from some Zod conversions)\n function normalizeSchema(schema) {\n if (!schema) return schema;\n\n // Handle schemas with 'def' and 'shape' (non-standard Zod output)\n if (schema.def && schema.def.shape) {\n const normalized = { type: 'object', properties: {} };\n for (const [key, val] of Object.entries(schema.def.shape)) {\n normalized.properties[key] = normalizeSchema(val);\n }\n return normalized;\n }\n\n // Handle 'innerType' for default values\n if (schema.def && schema.def.innerType) {\n const inner = normalizeSchema(schema.def.innerType);\n if (schema.def.defaultValue !== undefined) {\n inner.default = schema.def.defaultValue;\n }\n return inner;\n }\n\n // Handle simple def types\n if (schema.def && schema.def.type === 'string') {\n const result = { type: 'string' };\n if (schema.format) result.format = schema.format;\n if (schema.minLength) result.minLength = schema.minLength;\n if (schema.maxLength) result.maxLength = schema.maxLength;\n return result;\n }\n\n if (schema.def && schema.def.type === 'number') {\n return { type: 'number' };\n }\n\n if (schema.def && schema.def.type === 'integer') {\n return { type: 'integer' };\n }\n\n if (schema.def && schema.def.type === 'boolean') {\n return { type: 'boolean' };\n }\n\n return schema;\n }\n\n // ========== REDOC-STYLE RENDERING FUNCTIONS ==========\n\n function renderParametersRedocStyle(params) {\n const container = document.createElement('div');\n\n params.forEach(param => {\n const row = document.createElement('div');\n row.className = 'param-row';\n\n // Tree line\n const tree = document.createElement('div');\n tree.className = 'param-tree';\n tree.innerHTML = '<div class=\"param-tree-line\"></div>';\n row.appendChild(tree);\n\n // Info\n const info = document.createElement('div');\n info.className = 'param-info';\n\n // Header row: name, required badge, type\n const header = document.createElement('div');\n header.className = 'param-header';\n\n const nameSpan = document.createElement('span');\n nameSpan.className = 'param-name-text';\n nameSpan.textContent = param.name;\n header.appendChild(nameSpan);\n\n if (param.required) {\n const reqBadge = document.createElement('span');\n reqBadge.className = 'param-required-badge';\n reqBadge.textContent = 'required';\n header.appendChild(reqBadge);\n }\n\n // Type info\n const schema = param.schema || {};\n const typeInfo = document.createElement('span');\n typeInfo.className = 'param-type-info';\n let typeText = schema.type || 'string';\n if (schema.format) {\n typeText += ' <span class=\"format\">&lt;' + esc(schema.format) + '&gt;</span>';\n }\n typeInfo.innerHTML = typeText;\n header.appendChild(typeInfo);\n\n // Constraints\n if (schema.maximum !== undefined || schema.minimum !== undefined) {\n const constraint = document.createElement('span');\n constraint.className = 'param-constraint';\n if (schema.maximum !== undefined) {\n constraint.textContent = '<= ' + schema.maximum;\n } else if (schema.minimum !== undefined) {\n constraint.textContent = '>= ' + schema.minimum;\n }\n header.appendChild(constraint);\n }\n\n info.appendChild(header);\n\n // Default value\n if (schema.default !== undefined) {\n const def = document.createElement('div');\n def.className = 'param-default';\n def.innerHTML = 'Default: <code>' + esc(JSON.stringify(schema.default)) + '</code>';\n info.appendChild(def);\n }\n\n // Example\n if (schema.example !== undefined || param.example !== undefined) {\n const ex = document.createElement('div');\n ex.className = 'param-example';\n const exValue = param.example !== undefined ? param.example : schema.example;\n ex.innerHTML = 'Example: <code>' + esc(param.name + '=' + exValue) + '</code>';\n info.appendChild(ex);\n }\n\n // Description\n if (param.description || schema.description) {\n const desc = document.createElement('div');\n desc.className = 'param-description';\n desc.textContent = param.description || schema.description;\n info.appendChild(desc);\n }\n\n row.appendChild(info);\n container.appendChild(row);\n });\n\n return container;\n }\n\n function renderRequestBodyRedocStyle(reqBody) {\n const container = document.createElement('div');\n\n // Get schema\n const content = reqBody.content || {};\n const contentType = Object.keys(content)[0] || 'application/json';\n const mediaType = content[contentType] || {};\n const schema = mediaType.schema;\n\n if (schema) {\n // Resolve and normalize\n let actualSchema = schema.$ref ? resolveRef(schema.$ref) : schema;\n actualSchema = normalizeSchema(actualSchema);\n\n // Render properties as Redoc-style rows\n if (actualSchema && actualSchema.properties) {\n const required = actualSchema.required || [];\n Object.entries(actualSchema.properties).forEach(([propName, propSchema]) => {\n const row = renderPropertyRow(propName, propSchema, required.includes(propName), 0);\n container.appendChild(row);\n });\n } else if (actualSchema && actualSchema.type === 'array' && actualSchema.items) {\n const itemSchema = actualSchema.items.$ref ? resolveRef(actualSchema.items.$ref) : actualSchema.items;\n const arrayLabel = document.createElement('div');\n arrayLabel.style.marginBottom = '12px';\n arrayLabel.innerHTML = '<span class=\"param-type-info\">Array [</span>';\n container.appendChild(arrayLabel);\n\n if (itemSchema && itemSchema.properties) {\n const required = itemSchema.required || [];\n Object.entries(itemSchema.properties).forEach(([propName, propSchema]) => {\n const row = renderPropertyRow(propName, propSchema, required.includes(propName), 1);\n container.appendChild(row);\n });\n }\n\n const arrayEnd = document.createElement('div');\n arrayEnd.innerHTML = '<span class=\"param-type-info\">]</span>';\n container.appendChild(arrayEnd);\n }\n }\n\n return container;\n }\n\n function renderPropertyRow(name, schema, isRequired, depth) {\n const row = document.createElement('div');\n row.className = 'param-row';\n if (depth > 0) {\n row.style.paddingLeft = (depth * 20) + 'px';\n }\n\n // Tree line\n const tree = document.createElement('div');\n tree.className = 'param-tree';\n tree.innerHTML = '<div class=\"param-tree-line\"></div>';\n row.appendChild(tree);\n\n // Info\n const info = document.createElement('div');\n info.className = 'param-info';\n\n // Header row\n const header = document.createElement('div');\n header.className = 'param-header';\n\n const nameSpan = document.createElement('span');\n nameSpan.className = 'param-name-text';\n nameSpan.textContent = name;\n header.appendChild(nameSpan);\n\n if (isRequired) {\n const reqBadge = document.createElement('span');\n reqBadge.className = 'param-required-badge';\n reqBadge.textContent = 'required';\n header.appendChild(reqBadge);\n }\n\n // Type info\n const resolved = schema.$ref ? resolveRef(schema.$ref) : schema;\n const normalized = normalizeSchema(resolved) || resolved || {};\n const typeInfo = document.createElement('span');\n typeInfo.className = 'param-type-info';\n let typeText = normalized.type || 'any';\n if (normalized.format) {\n typeText += ' <span class=\"format\">(' + esc(normalized.format) + ')</span>';\n }\n if (schema.$ref) {\n typeText = '<span class=\"format\">' + esc(getRefName(schema.$ref)) + '</span>';\n }\n typeInfo.innerHTML = typeText;\n header.appendChild(typeInfo);\n\n // Pattern/constraint\n if (normalized.pattern) {\n const constraint = document.createElement('span');\n constraint.className = 'param-constraint';\n constraint.textContent = normalized.pattern;\n header.appendChild(constraint);\n }\n\n info.appendChild(header);\n\n // Default\n if (normalized.default !== undefined) {\n const def = document.createElement('div');\n def.className = 'param-default';\n def.innerHTML = 'Default: <code>' + esc(JSON.stringify(normalized.default)) + '</code>';\n info.appendChild(def);\n }\n\n // Example\n if (normalized.example !== undefined) {\n const ex = document.createElement('div');\n ex.className = 'param-example';\n ex.innerHTML = 'Example: <code>' + esc(JSON.stringify(normalized.example)) + '</code>';\n info.appendChild(ex);\n }\n\n // Description\n if (normalized.description) {\n const desc = document.createElement('div');\n desc.className = 'param-description';\n desc.textContent = normalized.description;\n info.appendChild(desc);\n }\n\n row.appendChild(info);\n return row;\n }\n\n function renderResponsesRedocStyle(responses) {\n const container = document.createElement('div');\n const statusCodes = Object.keys(responses).sort();\n\n statusCodes.forEach((status, idx) => {\n const response = responses[status];\n const statusClass = status.startsWith('2') ? 'status-2xx' :\n status.startsWith('4') ? 'status-4xx' :\n status.startsWith('5') ? 'status-5xx' : '';\n\n const item = document.createElement('div');\n item.className = 'response-item' + (idx === 0 ? ' expanded' : '');\n\n // Header\n const header = document.createElement('div');\n header.className = 'response-header';\n header.innerHTML = '<span class=\"response-arrow\">▶</span>' +\n '<span class=\"response-status ' + statusClass + '\">' + esc(status) + '</span>' +\n '<span class=\"response-desc\">' + esc(response.description || '') + '</span>';\n header.onclick = () => item.classList.toggle('expanded');\n item.appendChild(header);\n\n // Body (headers + schema)\n const body = document.createElement('div');\n body.className = 'response-body';\n\n // Render response headers if present\n if (response.headers && Object.keys(response.headers).length > 0) {\n const headersSection = document.createElement('div');\n headersSection.className = 'response-headers-section';\n\n const headersLabel = document.createElement('div');\n headersLabel.className = 'response-headers-label';\n headersLabel.textContent = 'RESPONSE HEADERS';\n headersSection.appendChild(headersLabel);\n\n Object.entries(response.headers).forEach(([headerName, headerDef]) => {\n const resolved = headerDef.$ref ? resolveRef(headerDef.$ref) : headerDef;\n const row = document.createElement('div');\n row.className = 'response-header-row';\n\n const nameEl = document.createElement('div');\n nameEl.className = 'response-header-name';\n nameEl.textContent = headerName;\n if (resolved.required) {\n nameEl.innerHTML += '<span class=\"response-header-required\">required</span>';\n }\n\n const infoEl = document.createElement('div');\n infoEl.className = 'response-header-info';\n\n const typeStr = resolved.schema ? (resolved.schema.type || 'string') : 'string';\n const typeEl = document.createElement('div');\n typeEl.className = 'response-header-type';\n typeEl.textContent = typeStr;\n infoEl.appendChild(typeEl);\n\n if (resolved.description) {\n const descEl = document.createElement('div');\n descEl.className = 'response-header-desc';\n descEl.textContent = resolved.description;\n infoEl.appendChild(descEl);\n }\n\n row.appendChild(nameEl);\n row.appendChild(infoEl);\n headersSection.appendChild(row);\n });\n\n body.appendChild(headersSection);\n }\n\n const respContent = response.content || {};\n const contentType = Object.keys(respContent)[0];\n if (contentType) {\n const label = document.createElement('div');\n label.className = 'response-schema-label';\n label.innerHTML = 'RESPONSE SCHEMA: <span class=\"content-type\">' + esc(contentType) + '</span>';\n body.appendChild(label);\n\n const mediaType = respContent[contentType] || {};\n const schema = mediaType.schema;\n if (schema) {\n let actualSchema = schema.$ref ? resolveRef(schema.$ref) : schema;\n actualSchema = normalizeSchema(actualSchema);\n\n if (actualSchema && actualSchema.properties) {\n const required = actualSchema.required || [];\n Object.entries(actualSchema.properties).forEach(([propName, propSchema]) => {\n const row = renderPropertyRow(propName, propSchema, required.includes(propName), 0);\n body.appendChild(row);\n });\n } else if (actualSchema && actualSchema.type === 'array' && actualSchema.items) {\n const itemSchema = actualSchema.items.$ref ? resolveRef(actualSchema.items.$ref) : actualSchema.items;\n const arrayLabel = document.createElement('div');\n arrayLabel.innerHTML = '<span class=\"param-type-info\">Array [</span>';\n arrayLabel.style.marginBottom = '8px';\n body.appendChild(arrayLabel);\n\n if (itemSchema && itemSchema.properties) {\n const itemRequired = itemSchema.required || [];\n Object.entries(itemSchema.properties).forEach(([propName, propSchema]) => {\n const row = renderPropertyRow(propName, propSchema, itemRequired.includes(propName), 1);\n body.appendChild(row);\n });\n }\n\n const arrayEnd = document.createElement('div');\n arrayEnd.innerHTML = '<span class=\"param-type-info\">]</span>';\n body.appendChild(arrayEnd);\n }\n }\n }\n\n item.appendChild(body);\n container.appendChild(item);\n });\n\n return container;\n }\n\n function renderSchemaProperties(schema, requiredProps, depth) {\n const container = document.createElement('div');\n container.className = 'schema-container';\n\n // Normalize non-standard schemas first\n let actualSchema = normalizeSchema(schema);\n\n // Handle $ref\n if (actualSchema.$ref) {\n const resolved = resolveRef(actualSchema.$ref);\n actualSchema = normalizeSchema(resolved) || actualSchema;\n }\n\n // Handle allOf, oneOf, anyOf by merging/showing options\n if (actualSchema.allOf) {\n actualSchema.allOf.forEach((subSchema, idx) => {\n const resolved = subSchema.$ref ? resolveRef(subSchema.$ref) : subSchema;\n if (resolved && resolved.properties) {\n renderPropertiesInto(container, resolved, resolved.required || [], depth);\n }\n });\n return container;\n }\n\n if (actualSchema.oneOf || actualSchema.anyOf) {\n const variants = actualSchema.oneOf || actualSchema.anyOf;\n const label = actualSchema.oneOf ? 'One of' : 'Any of';\n const row = document.createElement('div');\n row.className = 'schema-row';\n row.innerHTML = '<div class=\"schema-property\">' +\n '<span class=\"schema-name\" style=\"font-style: italic;\">' + label + ':</span>' +\n '</div><div class=\"schema-details\">' +\n variants.map((v, i) => {\n const name = v.$ref ? getRefName(v.$ref) : ('Option ' + (i + 1));\n return '<span class=\"schema-type type-ref\" style=\"margin-right: 6px; cursor: pointer;\">' + esc(name) + '</span>';\n }).join('') +\n '</div>';\n container.appendChild(row);\n return container;\n }\n\n // Render object properties\n if (actualSchema.properties) {\n renderPropertiesInto(container, actualSchema, requiredProps || actualSchema.required || [], depth);\n } else if (actualSchema.type === 'array' && actualSchema.items) {\n // For arrays, show the items schema\n const itemSchema = actualSchema.items.$ref ? resolveRef(actualSchema.items.$ref) : actualSchema.items;\n if (itemSchema && itemSchema.properties) {\n renderPropertiesInto(container, itemSchema, itemSchema.required || [], depth);\n } else {\n const row = document.createElement('div');\n row.className = 'schema-row';\n row.innerHTML = '<div class=\"schema-property\">' +\n '<span class=\"schema-name\">[items]</span>' +\n '</div><div class=\"schema-details\">' +\n renderSchemaType(actualSchema.items, true) +\n '</div>';\n container.appendChild(row);\n }\n } else if (Object.keys(actualSchema).length === 0 || actualSchema.type === 'object') {\n const row = document.createElement('div');\n row.className = 'schema-row';\n row.innerHTML = '<div class=\"schema-property\">' +\n '<span class=\"schema-name\" style=\"color: var(--text-muted); font-style: italic;\">empty object</span>' +\n '</div>';\n container.appendChild(row);\n }\n\n return container;\n }\n\n function renderPropertiesInto(container, schema, requiredProps, depth) {\n const props = schema.properties || {};\n const required = requiredProps || [];\n const depthClass = depth > 0 ? ' nested' + (depth > 1 ? '-' + Math.min(depth, 4) : '') : '';\n\n Object.entries(props).forEach(([propName, propSchema]) => {\n const isRequired = required.includes(propName);\n const resolved = propSchema.$ref ? resolveRef(propSchema.$ref) : propSchema;\n const hasNested = resolved && (resolved.properties || (resolved.type === 'array' && resolved.items?.properties));\n\n const row = document.createElement('div');\n row.className = 'schema-row' + depthClass;\n\n const id = 'schema-' + (schemaIdCounter++);\n\n let toggleHtml = '';\n if (hasNested) {\n toggleHtml = '<span class=\"schema-toggle\" data-target=\"' + id + '\">▼ expand</span>';\n }\n\n let detailsHtml = '<div class=\"schema-details\">' +\n renderSchemaType(propSchema, true) + toggleHtml;\n\n if (resolved?.description) {\n detailsHtml += '<div class=\"schema-desc\">' + esc(resolved.description) + '</div>';\n }\n\n detailsHtml += renderConstraints(resolved || {});\n detailsHtml += renderEnumValues(resolved || {});\n detailsHtml += renderDefault(resolved || {});\n detailsHtml += '</div>';\n\n row.innerHTML = '<div class=\"schema-property\">' +\n '<span class=\"schema-name\">' + esc(propName) + '</span>' +\n (isRequired ? '<span class=\"schema-required\">*</span>' : '') +\n '</div>' + detailsHtml;\n\n container.appendChild(row);\n\n // Add nested container for expandable schemas\n if (hasNested) {\n const nestedContainer = document.createElement('div');\n nestedContainer.id = id;\n nestedContainer.className = 'schema-nested-container collapsed';\n\n if (resolved.properties) {\n const nested = renderSchemaProperties(resolved, resolved.required || [], depth + 1);\n nestedContainer.appendChild(nested);\n } else if (resolved.type === 'array' && resolved.items) {\n const itemSchema = resolved.items.$ref ? resolveRef(resolved.items.$ref) : resolved.items;\n if (itemSchema) {\n const nested = renderSchemaProperties(itemSchema, itemSchema.required || [], depth + 1);\n nestedContainer.appendChild(nested);\n }\n }\n\n container.appendChild(nestedContainer);\n\n // Add click handler for toggle\n const toggle = row.querySelector('.schema-toggle');\n if (toggle) {\n toggle.onclick = () => {\n nestedContainer.classList.toggle('collapsed');\n toggle.textContent = nestedContainer.classList.contains('collapsed') ? '▼ expand' : '▲ collapse';\n };\n }\n }\n });\n }\n\n function renderParameters(params) {\n if (!params || params.length === 0) return null;\n\n const container = document.createElement('div');\n const table = document.createElement('table');\n table.className = 'params-table';\n\n const thead = document.createElement('thead');\n thead.innerHTML = '<tr><th>Name</th><th>Type</th><th>Description</th></tr>';\n table.appendChild(thead);\n\n const tbody = document.createElement('tbody');\n params.forEach(param => {\n const schema = param.schema || {};\n const tr = document.createElement('tr');\n tr.innerHTML = '<td>' +\n '<span class=\"param-name\">' + esc(param.name) + '</span>' +\n '<span class=\"param-in\">' + esc(param.in) + '</span>' +\n (param.required ? '<span class=\"schema-required\"> *</span>' : '') +\n '</td>' +\n '<td>' + renderSchemaType(schema, true) + '</td>' +\n '<td>' + esc(param.description || schema.description || '') +\n renderDefault(schema) + '</td>';\n tbody.appendChild(tr);\n });\n table.appendChild(tbody);\n container.appendChild(table);\n\n return container;\n }\n\n function renderRequestBody(reqBody) {\n if (!reqBody) return null;\n\n const container = document.createElement('div');\n\n if (reqBody.description) {\n const desc = document.createElement('p');\n desc.className = 'schema-desc';\n desc.textContent = reqBody.description;\n container.appendChild(desc);\n }\n\n // Get content type (usually application/json)\n const content = reqBody.content || {};\n const contentType = Object.keys(content)[0] || 'application/json';\n const mediaType = content[contentType] || {};\n const schema = mediaType.schema;\n\n if (schema) {\n const schemaEl = renderSchemaProperties(schema, schema.required || [], 0);\n container.appendChild(schemaEl);\n\n // Show example if available\n if (mediaType.example || schema.example) {\n const example = mediaType.example || schema.example;\n const exampleDiv = document.createElement('div');\n exampleDiv.className = 'schema-example';\n exampleDiv.innerHTML = '<div class=\"schema-example-header\">Example</div>' +\n '<div class=\"schema-example-body\">' + esc(JSON.stringify(example, null, 2)) + '</div>';\n container.appendChild(exampleDiv);\n }\n }\n\n return container;\n }\n\n function renderResponses(responses) {\n if (!responses) return null;\n\n const container = document.createElement('div');\n const statusCodes = Object.keys(responses).sort();\n\n if (statusCodes.length === 0) return null;\n\n // Create tabs\n const tabs = document.createElement('div');\n tabs.className = 'response-tabs';\n\n const contents = document.createElement('div');\n\n statusCodes.forEach((status, idx) => {\n const statusClass = status.startsWith('2') ? 'status-2xx' :\n status.startsWith('4') ? 'status-4xx' :\n status.startsWith('5') ? 'status-5xx' : '';\n\n const tab = document.createElement('button');\n tab.className = 'response-tab ' + statusClass + (idx === 0 ? ' active' : '');\n tab.textContent = status;\n tab.dataset.status = status;\n tabs.appendChild(tab);\n\n const content = document.createElement('div');\n content.className = 'response-content' + (idx === 0 ? ' active' : '');\n content.dataset.status = status;\n\n const response = responses[status];\n if (response.description) {\n const desc = document.createElement('p');\n desc.className = 'schema-desc';\n desc.textContent = response.description;\n content.appendChild(desc);\n }\n\n // Get schema from content\n const respContent = response.content || {};\n const contentType = Object.keys(respContent)[0] || 'application/json';\n const mediaType = respContent[contentType] || {};\n const schema = mediaType.schema;\n\n if (schema) {\n const schemaEl = renderSchemaProperties(schema, schema.required || [], 0);\n content.appendChild(schemaEl);\n\n // Show example if available\n if (mediaType.example || schema.example) {\n const example = mediaType.example || schema.example;\n const exampleDiv = document.createElement('div');\n exampleDiv.className = 'schema-example';\n exampleDiv.innerHTML = '<div class=\"schema-example-header\">Example</div>' +\n '<div class=\"schema-example-body\">' + esc(JSON.stringify(example, null, 2)) + '</div>';\n content.appendChild(exampleDiv);\n }\n }\n\n contents.appendChild(content);\n });\n\n container.appendChild(tabs);\n container.appendChild(contents);\n\n // Tab click handler\n tabs.onclick = (e) => {\n if (e.target.classList.contains('response-tab')) {\n const status = e.target.dataset.status;\n tabs.querySelectorAll('.response-tab').forEach(t => t.classList.remove('active'));\n contents.querySelectorAll('.response-content').forEach(c => c.classList.remove('active'));\n e.target.classList.add('active');\n contents.querySelector('[data-status=\"' + status + '\"]').classList.add('active');\n }\n };\n\n return container;\n }\n\n";
5
- //# sourceMappingURL=schema-rendering.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"schema-rendering.js","sourceRoot":"","sources":["../../../../src/docs/ui/client-script/schema-rendering.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,CAAC,MAAM,2BAA2B,GAAG,wu+BAAwu+B,CAAA"}
@@ -1,5 +0,0 @@
1
- /**
2
- * Embedded docs UI client script chunk.
3
- */
4
- export declare const tryItClientScript = " // ========== TRY IT OUT ==========\n\n function renderTryItOut(ep) {\n const container = document.createElement('div');\n container.className = 'try-it-out';\n\n // Header\n const header = document.createElement('div');\n header.className = 'try-it-header';\n header.innerHTML = '<span class=\"try-it-title\">Try it out</span>' +\n '<button class=\"try-it-toggle\" type=\"button\">\u25BC</button>';\n header.onclick = () => container.classList.toggle('collapsed');\n container.appendChild(header);\n\n // Form content\n const form = document.createElement('div');\n form.className = 'try-it-form';\n\n const data = ep.data || {};\n const params = data.parameters || [];\n const baseUrl = (spec.servers && spec.servers[0]?.url) || 'http://localhost:3000';\n\n // Server URL\n const urlGroup = document.createElement('div');\n urlGroup.className = 'try-it-group';\n urlGroup.innerHTML = '<label class=\"try-it-label\">Server</label>' +\n '<input type=\"text\" class=\"try-it-input try-it-server\" value=\"' + esc(baseUrl) + '\">';\n form.appendChild(urlGroup);\n\n // Path parameters\n const pathParams = params.filter(p => p.in === 'path');\n if (pathParams.length > 0) {\n const section = document.createElement('div');\n section.className = 'try-it-section';\n section.innerHTML = '<div class=\"try-it-section-title\">Path Parameters</div>';\n pathParams.forEach(p => {\n const group = document.createElement('div');\n group.className = 'try-it-group';\n const schema = p.schema || {};\n const placeholder = schema.example || schema.default || p.name;\n group.innerHTML = '<label class=\"try-it-label\">' + esc(p.name) +\n (p.required ? ' <span class=\"try-it-required\">*</span>' : '') + '</label>' +\n '<input type=\"text\" class=\"try-it-input try-it-path-param\" ' +\n 'data-name=\"' + esc(p.name) + '\" placeholder=\"' + esc(String(placeholder)) + '\"' +\n (schema.default !== undefined ? ' value=\"' + esc(String(schema.default)) + '\"' : '') + '>';\n section.appendChild(group);\n });\n form.appendChild(section);\n }\n\n // Query parameters\n const queryParams = params.filter(p => p.in === 'query');\n if (queryParams.length > 0) {\n const section = document.createElement('div');\n section.className = 'try-it-section';\n section.innerHTML = '<div class=\"try-it-section-title\">Query Parameters</div>';\n queryParams.forEach(p => {\n const group = document.createElement('div');\n group.className = 'try-it-group';\n const schema = p.schema || {};\n const placeholder = schema.example || schema.default || '';\n group.innerHTML = '<label class=\"try-it-label\">' + esc(p.name) +\n (p.required ? ' <span class=\"try-it-required\">*</span>' : '') + '</label>' +\n '<input type=\"text\" class=\"try-it-input try-it-query-param\" ' +\n 'data-name=\"' + esc(p.name) + '\" placeholder=\"' + esc(String(placeholder)) + '\"' +\n (schema.default !== undefined ? ' value=\"' + esc(String(schema.default)) + '\"' : '') + '>';\n section.appendChild(group);\n });\n form.appendChild(section);\n }\n\n // Header parameters\n const headerParams = params.filter(p => p.in === 'header');\n if (headerParams.length > 0) {\n const section = document.createElement('div');\n section.className = 'try-it-section';\n section.innerHTML = '<div class=\"try-it-section-title\">Headers</div>';\n headerParams.forEach(p => {\n const group = document.createElement('div');\n group.className = 'try-it-group';\n const schema = p.schema || {};\n group.innerHTML = '<label class=\"try-it-label\">' + esc(p.name) +\n (p.required ? ' <span class=\"try-it-required\">*</span>' : '') + '</label>' +\n '<input type=\"text\" class=\"try-it-input try-it-header-param\" ' +\n 'data-name=\"' + esc(p.name) + '\"' +\n (schema.default !== undefined ? ' value=\"' + esc(String(schema.default)) + '\"' : '') + '>';\n section.appendChild(group);\n });\n form.appendChild(section);\n }\n\n // Request body\n if (data.requestBody) {\n const section = document.createElement('div');\n section.className = 'try-it-section';\n section.innerHTML = '<div class=\"try-it-section-title\">Request Body</div>';\n\n const content = data.requestBody.content || {};\n const contentType = Object.keys(content)[0] || 'application/json';\n const mediaType = content[contentType] || {};\n\n // Build example from schema\n let exampleBody = {};\n if (mediaType.schema) {\n exampleBody = buildExampleFromSchema(mediaType.schema) || {};\n }\n\n const textarea = document.createElement('textarea');\n textarea.className = 'try-it-body';\n textarea.placeholder = 'Request body (JSON)';\n textarea.value = JSON.stringify(exampleBody, null, 2);\n section.appendChild(textarea);\n form.appendChild(section);\n }\n\n // Send button\n const actions = document.createElement('div');\n actions.className = 'try-it-actions';\n const sendBtn = document.createElement('button');\n sendBtn.type = 'button';\n sendBtn.className = 'try-it-send';\n sendBtn.textContent = 'Send Request';\n actions.appendChild(sendBtn);\n form.appendChild(actions);\n\n // Response area\n const responseArea = document.createElement('div');\n responseArea.className = 'try-it-response';\n responseArea.style.display = 'none';\n form.appendChild(responseArea);\n\n container.appendChild(form);\n\n // Handle send\n sendBtn.onclick = async () => {\n sendBtn.disabled = true;\n sendBtn.textContent = 'Sending...';\n responseArea.style.display = 'block';\n responseArea.innerHTML = '<div class=\"try-it-loading\">Loading...</div>';\n\n try {\n // Build URL\n const serverInput = form.querySelector('.try-it-server');\n let url = serverInput.value + ep.path;\n\n // Replace path params\n form.querySelectorAll('.try-it-path-param').forEach(input => {\n const name = input.getAttribute('data-name');\n const value = input.value || input.placeholder;\n url = url.replace('{' + name + '}', encodeURIComponent(value));\n url = url.replace(':' + name, encodeURIComponent(value));\n });\n\n // Add query params\n const queryParts = [];\n form.querySelectorAll('.try-it-query-param').forEach(input => {\n const name = input.getAttribute('data-name');\n const value = input.value;\n if (value) {\n queryParts.push(encodeURIComponent(name) + '=' + encodeURIComponent(value));\n }\n });\n if (queryParts.length > 0) {\n url += '?' + queryParts.join('&');\n }\n\n // Build headers\n const headers = {};\n form.querySelectorAll('.try-it-header-param').forEach(input => {\n const name = input.getAttribute('data-name');\n const value = input.value;\n if (value) {\n headers[name] = value;\n }\n });\n\n // Build request options\n const options = {\n method: ep.method.toUpperCase(),\n headers: headers,\n };\n\n // Add body for POST/PUT/PATCH\n if (['POST', 'PUT', 'PATCH'].includes(options.method)) {\n const bodyTextarea = form.querySelector('.try-it-body');\n if (bodyTextarea && bodyTextarea.value) {\n options.headers['Content-Type'] = 'application/json';\n options.body = bodyTextarea.value;\n }\n }\n\n // Send request\n const startTime = performance.now();\n const response = await fetch(url, options);\n const endTime = performance.now();\n const duration = Math.round(endTime - startTime);\n\n // Get response body\n let responseBody = '';\n const contentType = response.headers.get('content-type') || '';\n if (contentType.includes('application/json')) {\n try {\n const json = await response.json();\n responseBody = JSON.stringify(json, null, 2);\n } catch (e) {\n responseBody = await response.text();\n }\n } else {\n responseBody = await response.text();\n }\n\n // Display response\n const statusClass = response.ok ? 'status-2xx' :\n response.status >= 400 && response.status < 500 ? 'status-4xx' : 'status-5xx';\n\n responseArea.innerHTML =\n '<div class=\"try-it-response-header\">' +\n '<span class=\"try-it-response-status ' + statusClass + '\">' + response.status + ' ' + response.statusText + '</span>' +\n '<span class=\"try-it-response-time\">' + duration + 'ms</span>' +\n '</div>' +\n '<div class=\"try-it-response-headers\">' +\n '<div class=\"try-it-section-title\">Response Headers</div>' +\n '<pre class=\"try-it-response-headers-pre\">' + formatResponseHeaders(response) + '</pre>' +\n '</div>' +\n '<div class=\"try-it-response-body\">' +\n '<div class=\"try-it-section-title\">Response Body</div>' +\n '<pre class=\"sample-json\"><code>' + (contentType.includes('json') ? syntaxHighlightJSON(responseBody) : esc(responseBody)) + '</code></pre>' +\n '</div>';\n } catch (error) {\n responseArea.innerHTML =\n '<div class=\"try-it-error\">' +\n '<strong>Error:</strong> ' + esc(error.message) +\n '</div>';\n } finally {\n sendBtn.disabled = false;\n sendBtn.textContent = 'Send Request';\n }\n };\n\n return container;\n }\n\n function formatResponseHeaders(response) {\n const lines = [];\n response.headers.forEach((value, key) => {\n lines.push(esc(key) + ': ' + esc(value));\n });\n return lines.join('\\\\n');\n }\n\n // ========== TRY IT OUT WEBSOCKET ==========\n\n function renderTryItOutWebSocket(ep) {\n const container = document.createElement('div');\n container.className = 'try-it-out try-it-ws';\n\n // Header\n const header = document.createElement('div');\n header.className = 'try-it-header';\n header.innerHTML = '<span class=\"try-it-title\">WebSocket Console</span>' +\n '<button class=\"try-it-toggle\" type=\"button\">\u25BC</button>';\n header.onclick = () => container.classList.toggle('collapsed');\n container.appendChild(header);\n\n // Form content\n const form = document.createElement('div');\n form.className = 'try-it-form';\n\n const data = ep.data || {};\n const baseUrl = (spec.servers && spec.servers[0]?.url) || 'http://localhost:3000';\n const wsUrl = baseUrl.replace(/^http/, 'ws') + (ep.path || '/' + ep.id);\n\n // WebSocket URL\n const urlGroup = document.createElement('div');\n urlGroup.className = 'try-it-group';\n urlGroup.innerHTML = '<label class=\"try-it-label\">WebSocket URL</label>' +\n '<input type=\"text\" class=\"try-it-input try-it-ws-url\" value=\"' + esc(wsUrl) + '\">';\n form.appendChild(urlGroup);\n\n // Connection parameters (if any)\n if (data.parameters && Object.keys(data.parameters).length > 0) {\n const section = document.createElement('div');\n section.className = 'try-it-section';\n section.innerHTML = '<div class=\"try-it-section-title\">Parameters</div>';\n Object.entries(data.parameters).forEach(([name, param]) => {\n const group = document.createElement('div');\n group.className = 'try-it-group';\n group.innerHTML = '<label class=\"try-it-label\">' + esc(name) +\n (param.required ? ' <span class=\"try-it-required\">*</span>' : '') + '</label>' +\n '<input type=\"text\" class=\"try-it-input try-it-ws-param\" ' +\n 'data-name=\"' + esc(name) + '\" placeholder=\"' + esc(param.description || '') + '\">';\n section.appendChild(group);\n });\n form.appendChild(section);\n }\n\n // Message to send\n const msgSection = document.createElement('div');\n msgSection.className = 'try-it-section';\n msgSection.innerHTML = '<div class=\"try-it-section-title\">Send Message</div>';\n\n // Build example message from subscribe/publish schema\n let exampleMsg = {};\n if (data.subscribe?.message?.payload) {\n exampleMsg = buildExampleFromSchema(data.subscribe.message.payload);\n } else if (data.publish?.message?.payload) {\n exampleMsg = buildExampleFromSchema(data.publish.message.payload);\n }\n\n const textarea = document.createElement('textarea');\n textarea.className = 'try-it-body try-it-ws-message';\n textarea.placeholder = 'Message to send (JSON)';\n textarea.value = JSON.stringify(exampleMsg || {}, null, 2);\n msgSection.appendChild(textarea);\n form.appendChild(msgSection);\n\n // Actions\n const actions = document.createElement('div');\n actions.className = 'try-it-actions try-it-ws-actions';\n\n const connectBtn = document.createElement('button');\n connectBtn.type = 'button';\n connectBtn.className = 'try-it-send try-it-ws-connect';\n connectBtn.textContent = 'Connect';\n\n const sendBtn = document.createElement('button');\n sendBtn.type = 'button';\n sendBtn.className = 'try-it-send try-it-ws-send';\n sendBtn.textContent = 'Send';\n sendBtn.disabled = true;\n sendBtn.style.marginTop = '8px';\n\n actions.appendChild(connectBtn);\n actions.appendChild(sendBtn);\n form.appendChild(actions);\n\n // Status indicator\n const statusDiv = document.createElement('div');\n statusDiv.className = 'try-it-ws-status';\n statusDiv.innerHTML = '<span class=\"ws-status-dot\"></span><span class=\"ws-status-text\">Disconnected</span>';\n form.appendChild(statusDiv);\n\n // Messages log\n const logSection = document.createElement('div');\n logSection.className = 'try-it-section try-it-ws-log-section';\n logSection.style.display = 'none';\n logSection.innerHTML = '<div class=\"try-it-section-title\">Messages <button class=\"try-it-ws-clear\" type=\"button\">Clear</button></div>';\n const log = document.createElement('div');\n log.className = 'try-it-ws-log';\n logSection.appendChild(log);\n form.appendChild(logSection);\n\n container.appendChild(form);\n\n // WebSocket connection logic\n let ws = null;\n\n const updateStatus = (connected) => {\n const dot = statusDiv.querySelector('.ws-status-dot');\n const text = statusDiv.querySelector('.ws-status-text');\n if (connected) {\n dot.classList.add('connected');\n text.textContent = 'Connected';\n connectBtn.textContent = 'Disconnect';\n sendBtn.disabled = false;\n logSection.style.display = 'block';\n } else {\n dot.classList.remove('connected');\n text.textContent = 'Disconnected';\n connectBtn.textContent = 'Connect';\n sendBtn.disabled = true;\n }\n };\n\n const addMessage = (type, content) => {\n const msg = document.createElement('div');\n msg.className = 'try-it-ws-msg try-it-ws-msg-' + type;\n const time = new Date().toLocaleTimeString();\n msg.innerHTML = '<span class=\"ws-msg-time\">' + time + '</span>' +\n '<span class=\"ws-msg-type\">' + type + '</span>' +\n '<pre class=\"ws-msg-content\">' + esc(typeof content === 'string' ? content : JSON.stringify(content, null, 2)) + '</pre>';\n log.appendChild(msg);\n log.scrollTop = log.scrollHeight;\n };\n\n connectBtn.onclick = () => {\n if (ws && ws.readyState === WebSocket.OPEN) {\n ws.close();\n return;\n }\n\n let url = form.querySelector('.try-it-ws-url').value;\n\n // Add parameters to URL\n const params = [];\n form.querySelectorAll('.try-it-ws-param').forEach(input => {\n const name = input.getAttribute('data-name');\n const value = input.value;\n if (value) {\n params.push(encodeURIComponent(name) + '=' + encodeURIComponent(value));\n }\n });\n if (params.length > 0) {\n url += (url.includes('?') ? '&' : '?') + params.join('&');\n }\n\n try {\n ws = new WebSocket(url);\n\n ws.onopen = () => {\n updateStatus(true);\n addMessage('system', 'Connected to ' + url);\n };\n\n ws.onmessage = (event) => {\n let data = event.data;\n try {\n data = JSON.parse(data);\n } catch (e) {}\n addMessage('received', data);\n };\n\n ws.onclose = (event) => {\n updateStatus(false);\n addMessage('system', 'Disconnected (code: ' + event.code + ')');\n };\n\n ws.onerror = () => {\n addMessage('error', 'Connection error');\n };\n } catch (err) {\n addMessage('error', err.message);\n }\n };\n\n sendBtn.onclick = () => {\n if (!ws || ws.readyState !== WebSocket.OPEN) return;\n const message = form.querySelector('.try-it-ws-message').value;\n ws.send(message);\n addMessage('sent', message);\n };\n\n logSection.querySelector('.try-it-ws-clear').onclick = () => {\n log.innerHTML = '';\n };\n\n return container;\n }\n\n // ========== TRY IT OUT STREAMS (SSE/EventSource) ==========\n\n function renderTryItOutStreams(ep) {\n const container = document.createElement('div');\n container.className = 'try-it-out try-it-sse';\n\n // Header\n const header = document.createElement('div');\n header.className = 'try-it-header';\n header.innerHTML = '<span class=\"try-it-title\">Stream Console</span>' +\n '<button class=\"try-it-toggle\" type=\"button\">\u25BC</button>';\n header.onclick = () => container.classList.toggle('collapsed');\n container.appendChild(header);\n\n // Form content\n const form = document.createElement('div');\n form.className = 'try-it-form';\n\n const data = ep.data || {};\n const baseUrl = (spec.servers && spec.servers[0]?.url) || 'http://localhost:3000';\n const streamUrl = baseUrl + (ep.path || '/' + ep.id);\n\n // Stream URL\n const urlGroup = document.createElement('div');\n urlGroup.className = 'try-it-group';\n urlGroup.innerHTML = '<label class=\"try-it-label\">Stream URL</label>' +\n '<input type=\"text\" class=\"try-it-input try-it-sse-url\" value=\"' + esc(streamUrl) + '\">';\n form.appendChild(urlGroup);\n\n // Query parameters (if any)\n if (data.parameters && Object.keys(data.parameters).length > 0) {\n const section = document.createElement('div');\n section.className = 'try-it-section';\n section.innerHTML = '<div class=\"try-it-section-title\">Parameters</div>';\n Object.entries(data.parameters).forEach(([name, param]) => {\n const group = document.createElement('div');\n group.className = 'try-it-group';\n group.innerHTML = '<label class=\"try-it-label\">' + esc(name) +\n (param.required ? ' <span class=\"try-it-required\">*</span>' : '') + '</label>' +\n '<input type=\"text\" class=\"try-it-input try-it-sse-param\" ' +\n 'data-name=\"' + esc(name) + '\" placeholder=\"' + esc(param.description || '') + '\">';\n section.appendChild(group);\n });\n form.appendChild(section);\n }\n\n // Actions\n const actions = document.createElement('div');\n actions.className = 'try-it-actions try-it-sse-actions';\n\n const subscribeBtn = document.createElement('button');\n subscribeBtn.type = 'button';\n subscribeBtn.className = 'try-it-send try-it-sse-subscribe';\n subscribeBtn.textContent = 'Subscribe';\n\n actions.appendChild(subscribeBtn);\n form.appendChild(actions);\n\n // Status indicator\n const statusDiv = document.createElement('div');\n statusDiv.className = 'try-it-sse-status';\n statusDiv.innerHTML = '<span class=\"sse-status-dot\"></span><span class=\"sse-status-text\">Disconnected</span>';\n form.appendChild(statusDiv);\n\n // Event types filter (shows received event types)\n const filterSection = document.createElement('div');\n filterSection.className = 'try-it-section try-it-sse-filter-section';\n filterSection.style.display = 'none';\n filterSection.innerHTML = '<div class=\"try-it-section-title\">Event Types</div>' +\n '<div class=\"try-it-sse-filter\"></div>';\n form.appendChild(filterSection);\n\n // Events log\n const logSection = document.createElement('div');\n logSection.className = 'try-it-section try-it-sse-log-section';\n logSection.style.display = 'none';\n logSection.innerHTML = '<div class=\"try-it-section-title\">Events <span class=\"sse-event-count\"></span><button class=\"try-it-sse-clear\" type=\"button\">Clear</button></div>';\n const log = document.createElement('div');\n log.className = 'try-it-sse-log';\n logSection.appendChild(log);\n form.appendChild(logSection);\n\n container.appendChild(form);\n\n // EventSource connection logic\n let eventSource = null;\n let eventCount = 0;\n const eventTypes = new Set();\n\n const updateStatus = (connected, connecting) => {\n const dot = statusDiv.querySelector('.sse-status-dot');\n const text = statusDiv.querySelector('.sse-status-text');\n dot.classList.remove('connected', 'connecting');\n if (connected) {\n dot.classList.add('connected');\n text.textContent = 'Connected';\n subscribeBtn.textContent = 'Unsubscribe';\n logSection.style.display = 'block';\n } else if (connecting) {\n dot.classList.add('connecting');\n text.textContent = 'Connecting...';\n subscribeBtn.textContent = 'Cancel';\n } else {\n text.textContent = 'Disconnected';\n subscribeBtn.textContent = 'Subscribe';\n }\n };\n\n const updateEventCount = () => {\n const countEl = logSection.querySelector('.sse-event-count');\n countEl.textContent = '(' + eventCount + ')';\n };\n\n const addEvent = (type, data, lastEventId) => {\n eventCount++;\n updateEventCount();\n\n // Track event type\n if (!eventTypes.has(type)) {\n eventTypes.add(type);\n updateFilterSection();\n }\n\n const event = document.createElement('div');\n event.className = 'try-it-sse-event' + (type === 'error' ? ' try-it-sse-event-error' : '');\n event.setAttribute('data-type', type);\n const time = new Date().toLocaleTimeString();\n\n let dataStr = data;\n try {\n const parsed = JSON.parse(data);\n dataStr = JSON.stringify(parsed, null, 2);\n } catch (e) {}\n\n event.innerHTML = '<div class=\"sse-event-header\">' +\n '<span class=\"sse-event-time\">' + time + '</span>' +\n '<span class=\"sse-event-type\">' + esc(type || 'message') + '</span>' +\n (lastEventId ? '<span class=\"sse-event-id\">id: ' + esc(lastEventId) + '</span>' : '') +\n '</div>' +\n '<pre class=\"sse-event-data\">' + esc(dataStr) + '</pre>';\n log.appendChild(event);\n log.scrollTop = log.scrollHeight;\n };\n\n const updateFilterSection = () => {\n if (eventTypes.size === 0) {\n filterSection.style.display = 'none';\n return;\n }\n filterSection.style.display = 'block';\n const filterContainer = filterSection.querySelector('.try-it-sse-filter');\n filterContainer.innerHTML = '';\n eventTypes.forEach(type => {\n const badge = document.createElement('span');\n badge.className = 'sse-type-badge';\n badge.textContent = type || 'message';\n badge.onclick = () => {\n badge.classList.toggle('inactive');\n const show = !badge.classList.contains('inactive');\n log.querySelectorAll('.try-it-sse-event[data-type=\"' + type + '\"]').forEach(el => {\n el.style.display = show ? 'block' : 'none';\n });\n };\n filterContainer.appendChild(badge);\n });\n };\n\n subscribeBtn.onclick = () => {\n if (eventSource) {\n eventSource.close();\n eventSource = null;\n updateStatus(false, false);\n return;\n }\n\n let url = form.querySelector('.try-it-sse-url').value;\n\n // Add parameters to URL\n const params = [];\n form.querySelectorAll('.try-it-sse-param').forEach(input => {\n const name = input.getAttribute('data-name');\n const value = input.value;\n if (value) {\n params.push(encodeURIComponent(name) + '=' + encodeURIComponent(value));\n }\n });\n if (params.length > 0) {\n url += (url.includes('?') ? '&' : '?') + params.join('&');\n }\n\n updateStatus(false, true);\n\n try {\n eventSource = new EventSource(url);\n\n eventSource.onopen = () => {\n updateStatus(true, false);\n addEvent('system', 'Connected to ' + url, null);\n };\n\n eventSource.onmessage = (e) => {\n addEvent('message', e.data, e.lastEventId);\n };\n\n // Listen for named events from spec\n const events = data.events || [];\n events.forEach(eventName => {\n eventSource.addEventListener(eventName, (e) => {\n addEvent(eventName, e.data, e.lastEventId);\n });\n });\n\n eventSource.onerror = () => {\n if (eventSource.readyState === EventSource.CLOSED) {\n addEvent('error', 'Connection closed', null);\n updateStatus(false, false);\n eventSource = null;\n } else {\n addEvent('error', 'Connection error (reconnecting...)', null);\n }\n };\n } catch (err) {\n addEvent('error', err.message, null);\n updateStatus(false, false);\n }\n };\n\n logSection.querySelector('.try-it-sse-clear').onclick = () => {\n log.innerHTML = '';\n eventCount = 0;\n updateEventCount();\n };\n\n return container;\n }\n\n";
5
- //# sourceMappingURL=try-it.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"try-it.d.ts","sourceRoot":"","sources":["../../../../src/docs/ui/client-script/try-it.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,iBAAiB,s+1BAAu91B,CAAA"}
@@ -1,5 +0,0 @@
1
- /**
2
- * Embedded docs UI client script chunk.
3
- */
4
- export const tryItClientScript = " // ========== TRY IT OUT ==========\n\n function renderTryItOut(ep) {\n const container = document.createElement('div');\n container.className = 'try-it-out';\n\n // Header\n const header = document.createElement('div');\n header.className = 'try-it-header';\n header.innerHTML = '<span class=\"try-it-title\">Try it out</span>' +\n '<button class=\"try-it-toggle\" type=\"button\">▼</button>';\n header.onclick = () => container.classList.toggle('collapsed');\n container.appendChild(header);\n\n // Form content\n const form = document.createElement('div');\n form.className = 'try-it-form';\n\n const data = ep.data || {};\n const params = data.parameters || [];\n const baseUrl = (spec.servers && spec.servers[0]?.url) || 'http://localhost:3000';\n\n // Server URL\n const urlGroup = document.createElement('div');\n urlGroup.className = 'try-it-group';\n urlGroup.innerHTML = '<label class=\"try-it-label\">Server</label>' +\n '<input type=\"text\" class=\"try-it-input try-it-server\" value=\"' + esc(baseUrl) + '\">';\n form.appendChild(urlGroup);\n\n // Path parameters\n const pathParams = params.filter(p => p.in === 'path');\n if (pathParams.length > 0) {\n const section = document.createElement('div');\n section.className = 'try-it-section';\n section.innerHTML = '<div class=\"try-it-section-title\">Path Parameters</div>';\n pathParams.forEach(p => {\n const group = document.createElement('div');\n group.className = 'try-it-group';\n const schema = p.schema || {};\n const placeholder = schema.example || schema.default || p.name;\n group.innerHTML = '<label class=\"try-it-label\">' + esc(p.name) +\n (p.required ? ' <span class=\"try-it-required\">*</span>' : '') + '</label>' +\n '<input type=\"text\" class=\"try-it-input try-it-path-param\" ' +\n 'data-name=\"' + esc(p.name) + '\" placeholder=\"' + esc(String(placeholder)) + '\"' +\n (schema.default !== undefined ? ' value=\"' + esc(String(schema.default)) + '\"' : '') + '>';\n section.appendChild(group);\n });\n form.appendChild(section);\n }\n\n // Query parameters\n const queryParams = params.filter(p => p.in === 'query');\n if (queryParams.length > 0) {\n const section = document.createElement('div');\n section.className = 'try-it-section';\n section.innerHTML = '<div class=\"try-it-section-title\">Query Parameters</div>';\n queryParams.forEach(p => {\n const group = document.createElement('div');\n group.className = 'try-it-group';\n const schema = p.schema || {};\n const placeholder = schema.example || schema.default || '';\n group.innerHTML = '<label class=\"try-it-label\">' + esc(p.name) +\n (p.required ? ' <span class=\"try-it-required\">*</span>' : '') + '</label>' +\n '<input type=\"text\" class=\"try-it-input try-it-query-param\" ' +\n 'data-name=\"' + esc(p.name) + '\" placeholder=\"' + esc(String(placeholder)) + '\"' +\n (schema.default !== undefined ? ' value=\"' + esc(String(schema.default)) + '\"' : '') + '>';\n section.appendChild(group);\n });\n form.appendChild(section);\n }\n\n // Header parameters\n const headerParams = params.filter(p => p.in === 'header');\n if (headerParams.length > 0) {\n const section = document.createElement('div');\n section.className = 'try-it-section';\n section.innerHTML = '<div class=\"try-it-section-title\">Headers</div>';\n headerParams.forEach(p => {\n const group = document.createElement('div');\n group.className = 'try-it-group';\n const schema = p.schema || {};\n group.innerHTML = '<label class=\"try-it-label\">' + esc(p.name) +\n (p.required ? ' <span class=\"try-it-required\">*</span>' : '') + '</label>' +\n '<input type=\"text\" class=\"try-it-input try-it-header-param\" ' +\n 'data-name=\"' + esc(p.name) + '\"' +\n (schema.default !== undefined ? ' value=\"' + esc(String(schema.default)) + '\"' : '') + '>';\n section.appendChild(group);\n });\n form.appendChild(section);\n }\n\n // Request body\n if (data.requestBody) {\n const section = document.createElement('div');\n section.className = 'try-it-section';\n section.innerHTML = '<div class=\"try-it-section-title\">Request Body</div>';\n\n const content = data.requestBody.content || {};\n const contentType = Object.keys(content)[0] || 'application/json';\n const mediaType = content[contentType] || {};\n\n // Build example from schema\n let exampleBody = {};\n if (mediaType.schema) {\n exampleBody = buildExampleFromSchema(mediaType.schema) || {};\n }\n\n const textarea = document.createElement('textarea');\n textarea.className = 'try-it-body';\n textarea.placeholder = 'Request body (JSON)';\n textarea.value = JSON.stringify(exampleBody, null, 2);\n section.appendChild(textarea);\n form.appendChild(section);\n }\n\n // Send button\n const actions = document.createElement('div');\n actions.className = 'try-it-actions';\n const sendBtn = document.createElement('button');\n sendBtn.type = 'button';\n sendBtn.className = 'try-it-send';\n sendBtn.textContent = 'Send Request';\n actions.appendChild(sendBtn);\n form.appendChild(actions);\n\n // Response area\n const responseArea = document.createElement('div');\n responseArea.className = 'try-it-response';\n responseArea.style.display = 'none';\n form.appendChild(responseArea);\n\n container.appendChild(form);\n\n // Handle send\n sendBtn.onclick = async () => {\n sendBtn.disabled = true;\n sendBtn.textContent = 'Sending...';\n responseArea.style.display = 'block';\n responseArea.innerHTML = '<div class=\"try-it-loading\">Loading...</div>';\n\n try {\n // Build URL\n const serverInput = form.querySelector('.try-it-server');\n let url = serverInput.value + ep.path;\n\n // Replace path params\n form.querySelectorAll('.try-it-path-param').forEach(input => {\n const name = input.getAttribute('data-name');\n const value = input.value || input.placeholder;\n url = url.replace('{' + name + '}', encodeURIComponent(value));\n url = url.replace(':' + name, encodeURIComponent(value));\n });\n\n // Add query params\n const queryParts = [];\n form.querySelectorAll('.try-it-query-param').forEach(input => {\n const name = input.getAttribute('data-name');\n const value = input.value;\n if (value) {\n queryParts.push(encodeURIComponent(name) + '=' + encodeURIComponent(value));\n }\n });\n if (queryParts.length > 0) {\n url += '?' + queryParts.join('&');\n }\n\n // Build headers\n const headers = {};\n form.querySelectorAll('.try-it-header-param').forEach(input => {\n const name = input.getAttribute('data-name');\n const value = input.value;\n if (value) {\n headers[name] = value;\n }\n });\n\n // Build request options\n const options = {\n method: ep.method.toUpperCase(),\n headers: headers,\n };\n\n // Add body for POST/PUT/PATCH\n if (['POST', 'PUT', 'PATCH'].includes(options.method)) {\n const bodyTextarea = form.querySelector('.try-it-body');\n if (bodyTextarea && bodyTextarea.value) {\n options.headers['Content-Type'] = 'application/json';\n options.body = bodyTextarea.value;\n }\n }\n\n // Send request\n const startTime = performance.now();\n const response = await fetch(url, options);\n const endTime = performance.now();\n const duration = Math.round(endTime - startTime);\n\n // Get response body\n let responseBody = '';\n const contentType = response.headers.get('content-type') || '';\n if (contentType.includes('application/json')) {\n try {\n const json = await response.json();\n responseBody = JSON.stringify(json, null, 2);\n } catch (e) {\n responseBody = await response.text();\n }\n } else {\n responseBody = await response.text();\n }\n\n // Display response\n const statusClass = response.ok ? 'status-2xx' :\n response.status >= 400 && response.status < 500 ? 'status-4xx' : 'status-5xx';\n\n responseArea.innerHTML =\n '<div class=\"try-it-response-header\">' +\n '<span class=\"try-it-response-status ' + statusClass + '\">' + response.status + ' ' + response.statusText + '</span>' +\n '<span class=\"try-it-response-time\">' + duration + 'ms</span>' +\n '</div>' +\n '<div class=\"try-it-response-headers\">' +\n '<div class=\"try-it-section-title\">Response Headers</div>' +\n '<pre class=\"try-it-response-headers-pre\">' + formatResponseHeaders(response) + '</pre>' +\n '</div>' +\n '<div class=\"try-it-response-body\">' +\n '<div class=\"try-it-section-title\">Response Body</div>' +\n '<pre class=\"sample-json\"><code>' + (contentType.includes('json') ? syntaxHighlightJSON(responseBody) : esc(responseBody)) + '</code></pre>' +\n '</div>';\n } catch (error) {\n responseArea.innerHTML =\n '<div class=\"try-it-error\">' +\n '<strong>Error:</strong> ' + esc(error.message) +\n '</div>';\n } finally {\n sendBtn.disabled = false;\n sendBtn.textContent = 'Send Request';\n }\n };\n\n return container;\n }\n\n function formatResponseHeaders(response) {\n const lines = [];\n response.headers.forEach((value, key) => {\n lines.push(esc(key) + ': ' + esc(value));\n });\n return lines.join('\\\\n');\n }\n\n // ========== TRY IT OUT WEBSOCKET ==========\n\n function renderTryItOutWebSocket(ep) {\n const container = document.createElement('div');\n container.className = 'try-it-out try-it-ws';\n\n // Header\n const header = document.createElement('div');\n header.className = 'try-it-header';\n header.innerHTML = '<span class=\"try-it-title\">WebSocket Console</span>' +\n '<button class=\"try-it-toggle\" type=\"button\">▼</button>';\n header.onclick = () => container.classList.toggle('collapsed');\n container.appendChild(header);\n\n // Form content\n const form = document.createElement('div');\n form.className = 'try-it-form';\n\n const data = ep.data || {};\n const baseUrl = (spec.servers && spec.servers[0]?.url) || 'http://localhost:3000';\n const wsUrl = baseUrl.replace(/^http/, 'ws') + (ep.path || '/' + ep.id);\n\n // WebSocket URL\n const urlGroup = document.createElement('div');\n urlGroup.className = 'try-it-group';\n urlGroup.innerHTML = '<label class=\"try-it-label\">WebSocket URL</label>' +\n '<input type=\"text\" class=\"try-it-input try-it-ws-url\" value=\"' + esc(wsUrl) + '\">';\n form.appendChild(urlGroup);\n\n // Connection parameters (if any)\n if (data.parameters && Object.keys(data.parameters).length > 0) {\n const section = document.createElement('div');\n section.className = 'try-it-section';\n section.innerHTML = '<div class=\"try-it-section-title\">Parameters</div>';\n Object.entries(data.parameters).forEach(([name, param]) => {\n const group = document.createElement('div');\n group.className = 'try-it-group';\n group.innerHTML = '<label class=\"try-it-label\">' + esc(name) +\n (param.required ? ' <span class=\"try-it-required\">*</span>' : '') + '</label>' +\n '<input type=\"text\" class=\"try-it-input try-it-ws-param\" ' +\n 'data-name=\"' + esc(name) + '\" placeholder=\"' + esc(param.description || '') + '\">';\n section.appendChild(group);\n });\n form.appendChild(section);\n }\n\n // Message to send\n const msgSection = document.createElement('div');\n msgSection.className = 'try-it-section';\n msgSection.innerHTML = '<div class=\"try-it-section-title\">Send Message</div>';\n\n // Build example message from subscribe/publish schema\n let exampleMsg = {};\n if (data.subscribe?.message?.payload) {\n exampleMsg = buildExampleFromSchema(data.subscribe.message.payload);\n } else if (data.publish?.message?.payload) {\n exampleMsg = buildExampleFromSchema(data.publish.message.payload);\n }\n\n const textarea = document.createElement('textarea');\n textarea.className = 'try-it-body try-it-ws-message';\n textarea.placeholder = 'Message to send (JSON)';\n textarea.value = JSON.stringify(exampleMsg || {}, null, 2);\n msgSection.appendChild(textarea);\n form.appendChild(msgSection);\n\n // Actions\n const actions = document.createElement('div');\n actions.className = 'try-it-actions try-it-ws-actions';\n\n const connectBtn = document.createElement('button');\n connectBtn.type = 'button';\n connectBtn.className = 'try-it-send try-it-ws-connect';\n connectBtn.textContent = 'Connect';\n\n const sendBtn = document.createElement('button');\n sendBtn.type = 'button';\n sendBtn.className = 'try-it-send try-it-ws-send';\n sendBtn.textContent = 'Send';\n sendBtn.disabled = true;\n sendBtn.style.marginTop = '8px';\n\n actions.appendChild(connectBtn);\n actions.appendChild(sendBtn);\n form.appendChild(actions);\n\n // Status indicator\n const statusDiv = document.createElement('div');\n statusDiv.className = 'try-it-ws-status';\n statusDiv.innerHTML = '<span class=\"ws-status-dot\"></span><span class=\"ws-status-text\">Disconnected</span>';\n form.appendChild(statusDiv);\n\n // Messages log\n const logSection = document.createElement('div');\n logSection.className = 'try-it-section try-it-ws-log-section';\n logSection.style.display = 'none';\n logSection.innerHTML = '<div class=\"try-it-section-title\">Messages <button class=\"try-it-ws-clear\" type=\"button\">Clear</button></div>';\n const log = document.createElement('div');\n log.className = 'try-it-ws-log';\n logSection.appendChild(log);\n form.appendChild(logSection);\n\n container.appendChild(form);\n\n // WebSocket connection logic\n let ws = null;\n\n const updateStatus = (connected) => {\n const dot = statusDiv.querySelector('.ws-status-dot');\n const text = statusDiv.querySelector('.ws-status-text');\n if (connected) {\n dot.classList.add('connected');\n text.textContent = 'Connected';\n connectBtn.textContent = 'Disconnect';\n sendBtn.disabled = false;\n logSection.style.display = 'block';\n } else {\n dot.classList.remove('connected');\n text.textContent = 'Disconnected';\n connectBtn.textContent = 'Connect';\n sendBtn.disabled = true;\n }\n };\n\n const addMessage = (type, content) => {\n const msg = document.createElement('div');\n msg.className = 'try-it-ws-msg try-it-ws-msg-' + type;\n const time = new Date().toLocaleTimeString();\n msg.innerHTML = '<span class=\"ws-msg-time\">' + time + '</span>' +\n '<span class=\"ws-msg-type\">' + type + '</span>' +\n '<pre class=\"ws-msg-content\">' + esc(typeof content === 'string' ? content : JSON.stringify(content, null, 2)) + '</pre>';\n log.appendChild(msg);\n log.scrollTop = log.scrollHeight;\n };\n\n connectBtn.onclick = () => {\n if (ws && ws.readyState === WebSocket.OPEN) {\n ws.close();\n return;\n }\n\n let url = form.querySelector('.try-it-ws-url').value;\n\n // Add parameters to URL\n const params = [];\n form.querySelectorAll('.try-it-ws-param').forEach(input => {\n const name = input.getAttribute('data-name');\n const value = input.value;\n if (value) {\n params.push(encodeURIComponent(name) + '=' + encodeURIComponent(value));\n }\n });\n if (params.length > 0) {\n url += (url.includes('?') ? '&' : '?') + params.join('&');\n }\n\n try {\n ws = new WebSocket(url);\n\n ws.onopen = () => {\n updateStatus(true);\n addMessage('system', 'Connected to ' + url);\n };\n\n ws.onmessage = (event) => {\n let data = event.data;\n try {\n data = JSON.parse(data);\n } catch (e) {}\n addMessage('received', data);\n };\n\n ws.onclose = (event) => {\n updateStatus(false);\n addMessage('system', 'Disconnected (code: ' + event.code + ')');\n };\n\n ws.onerror = () => {\n addMessage('error', 'Connection error');\n };\n } catch (err) {\n addMessage('error', err.message);\n }\n };\n\n sendBtn.onclick = () => {\n if (!ws || ws.readyState !== WebSocket.OPEN) return;\n const message = form.querySelector('.try-it-ws-message').value;\n ws.send(message);\n addMessage('sent', message);\n };\n\n logSection.querySelector('.try-it-ws-clear').onclick = () => {\n log.innerHTML = '';\n };\n\n return container;\n }\n\n // ========== TRY IT OUT STREAMS (SSE/EventSource) ==========\n\n function renderTryItOutStreams(ep) {\n const container = document.createElement('div');\n container.className = 'try-it-out try-it-sse';\n\n // Header\n const header = document.createElement('div');\n header.className = 'try-it-header';\n header.innerHTML = '<span class=\"try-it-title\">Stream Console</span>' +\n '<button class=\"try-it-toggle\" type=\"button\">▼</button>';\n header.onclick = () => container.classList.toggle('collapsed');\n container.appendChild(header);\n\n // Form content\n const form = document.createElement('div');\n form.className = 'try-it-form';\n\n const data = ep.data || {};\n const baseUrl = (spec.servers && spec.servers[0]?.url) || 'http://localhost:3000';\n const streamUrl = baseUrl + (ep.path || '/' + ep.id);\n\n // Stream URL\n const urlGroup = document.createElement('div');\n urlGroup.className = 'try-it-group';\n urlGroup.innerHTML = '<label class=\"try-it-label\">Stream URL</label>' +\n '<input type=\"text\" class=\"try-it-input try-it-sse-url\" value=\"' + esc(streamUrl) + '\">';\n form.appendChild(urlGroup);\n\n // Query parameters (if any)\n if (data.parameters && Object.keys(data.parameters).length > 0) {\n const section = document.createElement('div');\n section.className = 'try-it-section';\n section.innerHTML = '<div class=\"try-it-section-title\">Parameters</div>';\n Object.entries(data.parameters).forEach(([name, param]) => {\n const group = document.createElement('div');\n group.className = 'try-it-group';\n group.innerHTML = '<label class=\"try-it-label\">' + esc(name) +\n (param.required ? ' <span class=\"try-it-required\">*</span>' : '') + '</label>' +\n '<input type=\"text\" class=\"try-it-input try-it-sse-param\" ' +\n 'data-name=\"' + esc(name) + '\" placeholder=\"' + esc(param.description || '') + '\">';\n section.appendChild(group);\n });\n form.appendChild(section);\n }\n\n // Actions\n const actions = document.createElement('div');\n actions.className = 'try-it-actions try-it-sse-actions';\n\n const subscribeBtn = document.createElement('button');\n subscribeBtn.type = 'button';\n subscribeBtn.className = 'try-it-send try-it-sse-subscribe';\n subscribeBtn.textContent = 'Subscribe';\n\n actions.appendChild(subscribeBtn);\n form.appendChild(actions);\n\n // Status indicator\n const statusDiv = document.createElement('div');\n statusDiv.className = 'try-it-sse-status';\n statusDiv.innerHTML = '<span class=\"sse-status-dot\"></span><span class=\"sse-status-text\">Disconnected</span>';\n form.appendChild(statusDiv);\n\n // Event types filter (shows received event types)\n const filterSection = document.createElement('div');\n filterSection.className = 'try-it-section try-it-sse-filter-section';\n filterSection.style.display = 'none';\n filterSection.innerHTML = '<div class=\"try-it-section-title\">Event Types</div>' +\n '<div class=\"try-it-sse-filter\"></div>';\n form.appendChild(filterSection);\n\n // Events log\n const logSection = document.createElement('div');\n logSection.className = 'try-it-section try-it-sse-log-section';\n logSection.style.display = 'none';\n logSection.innerHTML = '<div class=\"try-it-section-title\">Events <span class=\"sse-event-count\"></span><button class=\"try-it-sse-clear\" type=\"button\">Clear</button></div>';\n const log = document.createElement('div');\n log.className = 'try-it-sse-log';\n logSection.appendChild(log);\n form.appendChild(logSection);\n\n container.appendChild(form);\n\n // EventSource connection logic\n let eventSource = null;\n let eventCount = 0;\n const eventTypes = new Set();\n\n const updateStatus = (connected, connecting) => {\n const dot = statusDiv.querySelector('.sse-status-dot');\n const text = statusDiv.querySelector('.sse-status-text');\n dot.classList.remove('connected', 'connecting');\n if (connected) {\n dot.classList.add('connected');\n text.textContent = 'Connected';\n subscribeBtn.textContent = 'Unsubscribe';\n logSection.style.display = 'block';\n } else if (connecting) {\n dot.classList.add('connecting');\n text.textContent = 'Connecting...';\n subscribeBtn.textContent = 'Cancel';\n } else {\n text.textContent = 'Disconnected';\n subscribeBtn.textContent = 'Subscribe';\n }\n };\n\n const updateEventCount = () => {\n const countEl = logSection.querySelector('.sse-event-count');\n countEl.textContent = '(' + eventCount + ')';\n };\n\n const addEvent = (type, data, lastEventId) => {\n eventCount++;\n updateEventCount();\n\n // Track event type\n if (!eventTypes.has(type)) {\n eventTypes.add(type);\n updateFilterSection();\n }\n\n const event = document.createElement('div');\n event.className = 'try-it-sse-event' + (type === 'error' ? ' try-it-sse-event-error' : '');\n event.setAttribute('data-type', type);\n const time = new Date().toLocaleTimeString();\n\n let dataStr = data;\n try {\n const parsed = JSON.parse(data);\n dataStr = JSON.stringify(parsed, null, 2);\n } catch (e) {}\n\n event.innerHTML = '<div class=\"sse-event-header\">' +\n '<span class=\"sse-event-time\">' + time + '</span>' +\n '<span class=\"sse-event-type\">' + esc(type || 'message') + '</span>' +\n (lastEventId ? '<span class=\"sse-event-id\">id: ' + esc(lastEventId) + '</span>' : '') +\n '</div>' +\n '<pre class=\"sse-event-data\">' + esc(dataStr) + '</pre>';\n log.appendChild(event);\n log.scrollTop = log.scrollHeight;\n };\n\n const updateFilterSection = () => {\n if (eventTypes.size === 0) {\n filterSection.style.display = 'none';\n return;\n }\n filterSection.style.display = 'block';\n const filterContainer = filterSection.querySelector('.try-it-sse-filter');\n filterContainer.innerHTML = '';\n eventTypes.forEach(type => {\n const badge = document.createElement('span');\n badge.className = 'sse-type-badge';\n badge.textContent = type || 'message';\n badge.onclick = () => {\n badge.classList.toggle('inactive');\n const show = !badge.classList.contains('inactive');\n log.querySelectorAll('.try-it-sse-event[data-type=\"' + type + '\"]').forEach(el => {\n el.style.display = show ? 'block' : 'none';\n });\n };\n filterContainer.appendChild(badge);\n });\n };\n\n subscribeBtn.onclick = () => {\n if (eventSource) {\n eventSource.close();\n eventSource = null;\n updateStatus(false, false);\n return;\n }\n\n let url = form.querySelector('.try-it-sse-url').value;\n\n // Add parameters to URL\n const params = [];\n form.querySelectorAll('.try-it-sse-param').forEach(input => {\n const name = input.getAttribute('data-name');\n const value = input.value;\n if (value) {\n params.push(encodeURIComponent(name) + '=' + encodeURIComponent(value));\n }\n });\n if (params.length > 0) {\n url += (url.includes('?') ? '&' : '?') + params.join('&');\n }\n\n updateStatus(false, true);\n\n try {\n eventSource = new EventSource(url);\n\n eventSource.onopen = () => {\n updateStatus(true, false);\n addEvent('system', 'Connected to ' + url, null);\n };\n\n eventSource.onmessage = (e) => {\n addEvent('message', e.data, e.lastEventId);\n };\n\n // Listen for named events from spec\n const events = data.events || [];\n events.forEach(eventName => {\n eventSource.addEventListener(eventName, (e) => {\n addEvent(eventName, e.data, e.lastEventId);\n });\n });\n\n eventSource.onerror = () => {\n if (eventSource.readyState === EventSource.CLOSED) {\n addEvent('error', 'Connection closed', null);\n updateStatus(false, false);\n eventSource = null;\n } else {\n addEvent('error', 'Connection error (reconnecting...)', null);\n }\n };\n } catch (err) {\n addEvent('error', err.message, null);\n updateStatus(false, false);\n }\n };\n\n logSection.querySelector('.try-it-sse-clear').onclick = () => {\n log.innerHTML = '';\n eventCount = 0;\n updateEventCount();\n };\n\n return container;\n }\n\n";
5
- //# sourceMappingURL=try-it.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"try-it.js","sourceRoot":"","sources":["../../../../src/docs/ui/client-script/try-it.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG,o91BAAo91B,CAAA"}
@@ -1,5 +0,0 @@
1
- /**
2
- * Embedded docs UI client script chunk.
3
- */
4
- export declare const cardsAndCodeClientScript = " function createEndpointCard(ep) {\n const section = document.createElement('div');\n section.className = 'endpoint-section';\n section.id = ep.id;\n\n // Header with method + path\n const header = document.createElement('div');\n header.className = 'endpoint-header';\n\n const methodPath = document.createElement('div');\n methodPath.className = 'endpoint-method-path';\n\n const badge = document.createElement('span');\n badge.className = 'badge badge-' + ep.method.toLowerCase();\n badge.textContent = ep.method;\n\n const path = document.createElement('span');\n path.className = 'endpoint-path';\n path.textContent = ep.path;\n\n methodPath.appendChild(badge);\n methodPath.appendChild(path);\n header.appendChild(methodPath);\n\n section.appendChild(header);\n\n // Title (operation summary)\n if (ep.summary) {\n const title = document.createElement('h3');\n title.className = 'endpoint-title';\n title.textContent = ep.summary;\n section.appendChild(title);\n }\n\n // Description if available (rendered as markdown)\n const opData = ep.data;\n if (opData?.description && opData.description !== ep.summary) {\n const desc = document.createElement('div');\n desc.className = 'endpoint-description markdown-content';\n desc.innerHTML = parseMarkdown(opData.description);\n section.appendChild(desc);\n }\n\n // Two-column content layout\n const content = document.createElement('div');\n content.className = 'endpoint-content';\n\n const leftCol = document.createElement('div');\n leftCol.className = 'endpoint-left';\n\n const rightCol = document.createElement('div');\n rightCol.className = 'endpoint-right';\n\n // Render details into left column\n leftCol.appendChild(renderEndpointDetails(ep));\n\n // Render right column content (Request + Response samples)\n rightCol.appendChild(renderRightPanelContent(ep));\n\n content.appendChild(leftCol);\n content.appendChild(rightCol);\n section.appendChild(content);\n\n return section;\n }\n\n // ========== RIGHT PANEL CONTENT (Request + Response Samples) ==========\n\n function renderRightPanelContent(ep) {\n const container = document.createElement('div');\n container.className = 'right-panel-content';\n\n if (activeProtocol === 'http') {\n // Try It Out section\n const tryItSection = document.createElement('div');\n tryItSection.className = 'right-section try-it-section';\n tryItSection.appendChild(renderTryItOut(ep));\n container.appendChild(tryItSection);\n\n // Request section\n const requestSection = document.createElement('div');\n requestSection.className = 'right-section request-section';\n\n const requestHeader = document.createElement('div');\n requestHeader.className = 'right-section-header';\n requestHeader.textContent = 'Request samples';\n requestSection.appendChild(requestHeader);\n\n // Add curl example\n requestSection.appendChild(renderCodeExample(ep));\n container.appendChild(requestSection);\n\n // Response samples section\n const data = ep.data || {};\n const responses = data.responses || {};\n const statusCodes = Object.keys(responses).sort();\n\n if (statusCodes.length > 0) {\n const responseSection = document.createElement('div');\n responseSection.className = 'right-section response-samples-section';\n\n const responseHeader = document.createElement('div');\n responseHeader.className = 'right-section-header';\n responseHeader.textContent = 'Response samples';\n responseSection.appendChild(responseHeader);\n\n // Tabs for status codes\n const tabsContainer = document.createElement('div');\n tabsContainer.className = 'sample-tabs';\n\n const contentContainer = document.createElement('div');\n contentContainer.className = 'sample-contents';\n\n statusCodes.forEach((status, idx) => {\n // Tab button\n const tab = document.createElement('button');\n tab.className = 'sample-tab' + (idx === 0 ? ' active' : '');\n const statusClass = status.startsWith('2') ? 'status-2xx' :\n status.startsWith('4') ? 'status-4xx' :\n status.startsWith('5') ? 'status-5xx' : '';\n tab.innerHTML = '<span class=\"tab-status ' + statusClass + '\">' + esc(status) + '</span>';\n tab.onclick = () => {\n // Remove active from all tabs\n tabsContainer.querySelectorAll('.sample-tab').forEach(t => t.classList.remove('active'));\n tab.classList.add('active');\n // Show corresponding content\n contentContainer.querySelectorAll('.sample-content').forEach((c, i) => {\n c.style.display = i === idx ? 'block' : 'none';\n });\n };\n tabsContainer.appendChild(tab);\n\n // Content for this status\n const content = document.createElement('div');\n content.className = 'sample-content';\n content.style.display = idx === 0 ? 'block' : 'none';\n\n const response = responses[status];\n const respContent = response.content || {};\n const contentType = Object.keys(respContent)[0];\n\n if (contentType && respContent[contentType]) {\n const mediaType = respContent[contentType];\n let example = null;\n\n // Try to get example from various places\n if (mediaType.example) {\n example = mediaType.example;\n } else if (mediaType.examples) {\n const firstExKey = Object.keys(mediaType.examples)[0];\n if (firstExKey && mediaType.examples[firstExKey]) {\n example = mediaType.examples[firstExKey].value;\n }\n } else if (mediaType.schema) {\n // Build example from schema\n example = buildExampleFromSchema(mediaType.schema);\n }\n\n if (example !== null) {\n const pre = document.createElement('pre');\n pre.className = 'sample-json';\n const code = document.createElement('code');\n code.innerHTML = syntaxHighlightJSON(JSON.stringify(example, null, 2));\n pre.appendChild(code);\n content.appendChild(pre);\n } else {\n const noExample = document.createElement('div');\n noExample.className = 'no-example';\n noExample.textContent = 'No example available';\n content.appendChild(noExample);\n }\n } else {\n // No content, just description\n const desc = document.createElement('div');\n desc.className = 'response-desc-only';\n desc.textContent = response.description || 'No content';\n content.appendChild(desc);\n }\n\n contentContainer.appendChild(content);\n });\n\n responseSection.appendChild(tabsContainer);\n responseSection.appendChild(contentContainer);\n container.appendChild(responseSection);\n }\n } else if (activeProtocol === 'websocket') {\n // WebSocket Try It Out\n const tryItSection = document.createElement('div');\n tryItSection.className = 'right-section try-it-section';\n tryItSection.appendChild(renderTryItOutWebSocket(ep));\n container.appendChild(tryItSection);\n\n // Request samples (wscat)\n const requestSection = document.createElement('div');\n requestSection.className = 'right-section request-section';\n const requestHeader = document.createElement('div');\n requestHeader.className = 'right-section-header';\n requestHeader.textContent = 'Request samples';\n requestSection.appendChild(requestHeader);\n requestSection.appendChild(renderCodeExampleWebSocket(ep));\n container.appendChild(requestSection);\n } else if (activeProtocol === 'streams') {\n // Streams (SSE) Try It Out\n const tryItSection = document.createElement('div');\n tryItSection.className = 'right-section try-it-section';\n tryItSection.appendChild(renderTryItOutStreams(ep));\n container.appendChild(tryItSection);\n\n // Request samples (curl, EventSource)\n const requestSection = document.createElement('div');\n requestSection.className = 'right-section request-section';\n const requestHeader = document.createElement('div');\n requestHeader.className = 'right-section-header';\n requestHeader.textContent = 'Request samples';\n requestSection.appendChild(requestHeader);\n requestSection.appendChild(renderCodeExampleStreams(ep));\n container.appendChild(requestSection);\n } else {\n // For other protocols, just show basic code example\n container.appendChild(renderCodeExample(ep));\n }\n\n return container;\n }\n\n // WebSocket code examples (wscat, etc.)\n function renderCodeExampleWebSocket(ep) {\n const container = document.createElement('div');\n container.className = 'code-example';\n\n const baseUrl = (spec.servers && spec.servers[0]?.url) || 'http://localhost:3000';\n // WebSocket URL uses the ws:// scheme and the configured WebSocket path (default: /ws)\n const wsPath = wsSpec?.path || '/ws';\n const wsUrl = baseUrl.replace(/^http/, 'ws') + wsPath;\n\n // Language tabs\n const languages = ['wscat', 'javascript', 'recker', 'python'];\n const tabs = document.createElement('div');\n tabs.className = 'code-tabs';\n\n const contents = document.createElement('div');\n contents.className = 'code-contents';\n\n const langLabels = {\n wscat: 'wscat',\n javascript: 'WebSocket',\n recker: 'Recker',\n python: 'Python'\n };\n\n languages.forEach((lang, i) => {\n // Tab button\n const tab = document.createElement('button');\n tab.className = 'code-tab' + (i === 0 ? ' active' : '');\n tab.textContent = langLabels[lang] || lang;\n tab.onclick = () => {\n tabs.querySelectorAll('.code-tab').forEach(t => t.classList.remove('active'));\n tab.classList.add('active');\n contents.querySelectorAll('.code-content').forEach(c => c.classList.remove('active'));\n contents.querySelector('.code-content[data-lang=\"' + lang + '\"]').classList.add('active');\n };\n tabs.appendChild(tab);\n\n // Content\n const content = document.createElement('div');\n content.className = 'code-content' + (i === 0 ? ' active' : '');\n content.setAttribute('data-lang', lang);\n\n const pre = document.createElement('pre');\n const code = document.createElement('code');\n code.textContent = generateWsCodeSample(lang, wsUrl, ep);\n pre.appendChild(code);\n content.appendChild(pre);\n contents.appendChild(content);\n });\n\n container.appendChild(tabs);\n container.appendChild(contents);\n\n return container;\n }\n\n function generateWsCodeSample(lang, url, ep) {\n const channelName = ep.path;\n const channelType = ep.data?.type || 'public';\n\n // Build subscribe message\n const subscribeMsg = { type: 'subscribe', channel: channelName, id: '1' };\n const subscribeMsgStr = JSON.stringify(subscribeMsg, null, 2);\n\n // Build example publish message if channel supports it\n let publishMsg = null;\n if (ep.data?.publish?.message?.payload) {\n const payload = buildExampleFromSchema(ep.data.publish.message.payload);\n publishMsg = { type: 'publish', channel: channelName, event: 'message', data: payload, id: '2' };\n }\n const publishMsgStr = publishMsg ? JSON.stringify(publishMsg, null, 2) : null;\n\n // For private/presence channels, add token to URL\n const needsAuth = channelType === 'private' || channelType === 'presence';\n const authUrl = needsAuth ? url + '?token=YOUR_TOKEN' : url;\n\n switch (lang) {\n case 'wscat':\n let wscatCode = 'wscat -c \"' + authUrl + '\"\\\\n\\\\n';\n wscatCode += '# Subscribe to channel:\\\\n> ' + JSON.stringify(subscribeMsg);\n if (publishMsgStr) {\n wscatCode += '\\\\n\\\\n# Publish a message:\\\\n> ' + JSON.stringify(publishMsg);\n }\n return wscatCode;\n\n case 'javascript':\n let jsCode = 'const ws = new WebSocket(\"' + authUrl + '\");\\\\n\\\\n';\n jsCode += 'ws.onopen = () => {\\\\n';\n jsCode += ' console.log(\"Connected\");\\\\n';\n jsCode += ' // Subscribe to channel\\\\n';\n jsCode += ' ws.send(JSON.stringify(' + subscribeMsgStr.split('\\\\n').map((l, i) => i === 0 ? l : ' ' + l).join('\\\\n') + '));\\\\n';\n jsCode += '};\\\\n\\\\n';\n jsCode += 'ws.onmessage = (event) => {\\\\n';\n jsCode += ' const msg = JSON.parse(event.data);\\\\n';\n jsCode += ' console.log(\"Received:\", msg);\\\\n';\n if (publishMsgStr) {\n jsCode += '\\\\n // After subscribed, you can publish:\\\\n';\n jsCode += ' // ws.send(JSON.stringify(' + JSON.stringify(publishMsg) + '));\\\\n';\n }\n jsCode += '};\\\\n\\\\n';\n jsCode += 'ws.onclose = () => {\\\\n';\n jsCode += ' console.log(\"Disconnected\");\\\\n';\n jsCode += '};';\n return jsCode;\n\n case 'recker':\n let reckerCode = 'import { ws } from \"recker\";\\\\n\\\\n';\n if (needsAuth) {\n reckerCode += 'const socket = await ws(\"' + url + '\", {\\\\n';\n reckerCode += ' query: { token: \"YOUR_TOKEN\" }\\\\n';\n reckerCode += '});\\\\n\\\\n';\n } else {\n reckerCode += 'const socket = await ws(\"' + url + '\");\\\\n\\\\n';\n }\n reckerCode += '// Subscribe to channel\\\\n';\n reckerCode += 'socket.send(' + subscribeMsgStr.split('\\\\n').map((l, i) => i === 0 ? l : ' ' + l).join('\\\\n') + ');\\\\n\\\\n';\n reckerCode += '// Listen for messages\\\\n';\n reckerCode += 'socket.on(\"message\", (data) => {\\\\n';\n reckerCode += ' console.log(\"Received:\", data);\\\\n';\n reckerCode += '});\\\\n';\n if (publishMsgStr) {\n reckerCode += '\\\\n// Publish a message\\\\n';\n reckerCode += '// socket.send(' + JSON.stringify(publishMsg) + ');\\\\n';\n }\n return reckerCode;\n\n case 'python':\n let pyCode = 'import asyncio\\\\n';\n pyCode += 'import websockets\\\\n';\n pyCode += 'import json\\\\n\\\\n';\n pyCode += 'async def connect():\\\\n';\n pyCode += ' async with websockets.connect(\"' + authUrl + '\") as ws:\\\\n';\n pyCode += ' # Subscribe to channel\\\\n';\n pyCode += ' await ws.send(json.dumps(' + subscribeMsgStr.split('\\\\n').map((l, i) => i === 0 ? l : ' ' + l).join('\\\\n') + '))\\\\n';\n pyCode += ' \\\\n';\n pyCode += ' # Wait for messages\\\\n';\n pyCode += ' async for message in ws:\\\\n';\n pyCode += ' data = json.loads(message)\\\\n';\n pyCode += ' print(f\"Received: {data}\")\\\\n\\\\n';\n pyCode += 'asyncio.run(connect())';\n return pyCode;\n\n default:\n return '// Not implemented';\n }\n }\n\n // Streams (SSE) code examples\n function renderCodeExampleStreams(ep) {\n const container = document.createElement('div');\n container.className = 'code-example';\n\n const baseUrl = (spec.servers && spec.servers[0]?.url) || 'http://localhost:3000';\n // SSE streams are accessed via GET /streams/<procedure-name>\n const streamUrl = baseUrl + '/streams/' + ep.path;\n\n // Language tabs\n const languages = ['curl', 'eventsource', 'recker', 'python'];\n const tabs = document.createElement('div');\n tabs.className = 'code-tabs';\n\n const contents = document.createElement('div');\n contents.className = 'code-contents';\n\n const langLabels = {\n curl: 'cURL',\n eventsource: 'EventSource',\n recker: 'Recker',\n python: 'Python'\n };\n\n languages.forEach((lang, i) => {\n // Tab button\n const tab = document.createElement('button');\n tab.className = 'code-tab' + (i === 0 ? ' active' : '');\n tab.textContent = langLabels[lang] || lang;\n tab.onclick = () => {\n tabs.querySelectorAll('.code-tab').forEach(t => t.classList.remove('active'));\n tab.classList.add('active');\n contents.querySelectorAll('.code-content').forEach(c => c.classList.remove('active'));\n contents.querySelector('.code-content[data-lang=\"' + lang + '\"]').classList.add('active');\n };\n tabs.appendChild(tab);\n\n // Content\n const content = document.createElement('div');\n content.className = 'code-content' + (i === 0 ? ' active' : '');\n content.setAttribute('data-lang', lang);\n\n const pre = document.createElement('pre');\n const code = document.createElement('code');\n code.textContent = generateStreamCodeSample(lang, streamUrl, ep);\n pre.appendChild(code);\n content.appendChild(pre);\n contents.appendChild(content);\n });\n\n container.appendChild(tabs);\n container.appendChild(contents);\n\n return container;\n }\n\n function generateStreamCodeSample(lang, url, ep) {\n switch (lang) {\n case 'curl':\n return 'curl -N \"' + url + '\"\\\\n\\\\n# -N disables buffering for streaming output';\n\n case 'eventsource':\n return 'const eventSource = new EventSource(\"' + url + '\");\\\\n\\\\n' +\n 'eventSource.onmessage = (event) => {\\\\n' +\n ' console.log(\"Received:\", event.data);\\\\n' +\n '};\\\\n\\\\n' +\n 'eventSource.onerror = (error) => {\\\\n' +\n ' console.error(\"Error:\", error);\\\\n' +\n ' eventSource.close();\\\\n' +\n '};\\\\n\\\\n' +\n '// To close the connection:\\\\n' +\n '// eventSource.close();';\n\n case 'recker':\n return 'import { sse } from \"recker\";\\\\n\\\\n' +\n 'const stream = sse(\"' + url + '\");\\\\n\\\\n' +\n 'for await (const event of stream) {\\\\n' +\n ' console.log(\"Received:\", event.data);\\\\n' +\n '}';\n\n case 'python':\n return 'import sseclient\\\\n' +\n 'import requests\\\\n\\\\n' +\n 'response = requests.get(\"' + url + '\", stream=True)\\\\n' +\n 'client = sseclient.SSEClient(response)\\\\n\\\\n' +\n 'for event in client.events():\\\\n' +\n ' print(f\"Event: {event.event}, Data: {event.data}\")';\n\n default:\n return '// Not implemented';\n }\n }\n\n // JSON syntax highlighting\n function syntaxHighlightJSON(json) {\n return json\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/(\"(\\\\\\\\u[a-zA-Z0-9]{4}|\\\\\\\\[^u]|[^\\\\\\\\\"])*\"(\\\\s*:)?)/g, function(match) {\n let cls = 'json-string';\n if (/:$/.test(match)) {\n cls = 'json-key';\n match = match.replace(/:$/, '') + ':';\n }\n return '<span class=\"' + cls + '\">' + match + '</span>';\n })\n .replace(/\\\\b(true|false|null)\\\\b/g, '<span class=\"json-boolean\">$1</span>')\n .replace(/\\\\b(-?\\\\d+\\\\.?\\\\d*)\\\\b/g, '<span class=\"json-number\">$1</span>');\n }\n\n function renderCodeExample(ep) {\n const container = document.createElement('div');\n container.className = 'code-example';\n\n // Build request details\n const method = ep.method.toUpperCase();\n const path = ep.path;\n const baseUrl = (spec.servers && spec.servers[0]?.url) || 'http://localhost:3000';\n\n // Handle JSON-RPC methods specially\n const isJsonRpc = method === 'RPC';\n let fullUrl;\n let exampleBody = null;\n let actualMethod = method;\n\n if (isJsonRpc) {\n // For JSON-RPC, use the /rpc endpoint and POST method\n const rpcEndpoint = jsonrpcSpec?.endpoint || '/rpc';\n fullUrl = baseUrl + rpcEndpoint;\n actualMethod = 'POST';\n\n // Build JSON-RPC request body\n const opData = ep.data;\n let params = {};\n if (opData && opData.params) {\n params = buildExampleFromSchema(opData.params);\n }\n exampleBody = {\n jsonrpc: '2.0',\n method: path, // The method name like \"tasks.list\"\n params: params,\n id: 1\n };\n } else {\n // Ensure path has leading slash for proper URL construction\n const normalizedPath = path.startsWith('/') ? path : '/' + path;\n fullUrl = baseUrl + normalizedPath;\n\n // Get request body if exists\n const opData = ep.data;\n if (opData && opData.requestBody && opData.requestBody.content) {\n const jsonContent = opData.requestBody.content['application/json'];\n if (jsonContent && jsonContent.schema) {\n exampleBody = buildExampleFromSchema(jsonContent.schema);\n }\n }\n }\n\n // Language tabs\n const languages = ['curl', 'fetch', 'recker', 'python', 'go'];\n const tabs = document.createElement('div');\n tabs.className = 'code-tabs';\n\n const contents = document.createElement('div');\n contents.className = 'code-contents';\n\n const langLabels = {\n curl: 'cURL',\n fetch: 'Fetch',\n recker: 'Recker',\n python: 'Python',\n go: 'Go'\n };\n\n languages.forEach((lang, i) => {\n // Tab button\n const tab = document.createElement('button');\n tab.className = 'code-tab' + (i === 0 ? ' active' : '');\n tab.textContent = langLabels[lang] || lang;\n tab.onclick = () => {\n tabs.querySelectorAll('.code-tab').forEach(t => t.classList.remove('active'));\n tab.classList.add('active');\n contents.querySelectorAll('.code-content').forEach(c => c.classList.remove('active'));\n contents.querySelector('.code-content[data-lang=\"' + lang + '\"]').classList.add('active');\n };\n tabs.appendChild(tab);\n\n // Content\n const content = document.createElement('div');\n content.className = 'code-content' + (i === 0 ? ' active' : '');\n content.setAttribute('data-lang', lang);\n\n const pre = document.createElement('pre');\n const code = document.createElement('code');\n code.textContent = generateCodeSample(lang, actualMethod, fullUrl, exampleBody);\n pre.appendChild(code);\n content.appendChild(pre);\n contents.appendChild(content);\n });\n\n container.appendChild(tabs);\n container.appendChild(contents);\n\n return container;\n }\n\n function generateCodeSample(lang, method, url, body) {\n const hasBody = body && ['POST', 'PUT', 'PATCH'].includes(method);\n const bodyStr = body ? JSON.stringify(body, null, 2) : '';\n\n switch (lang) {\n case 'curl':\n const curlLines = [];\n curlLines.push('curl' + (method !== 'GET' ? ' -X ' + method : ''));\n curlLines.push(' \"' + url + '\"');\n if (hasBody) {\n curlLines.push(' -H \"Content-Type: application/json\"');\n curlLines.push(\" -d '\" + bodyStr + \"'\");\n }\n return curlLines.join(' \\\\\\\\\\\\n');\n\n case 'fetch':\n if (hasBody) {\n return 'const response = await fetch(\"' + url + '\", {\\\\n' +\n ' method: \"' + method + '\",\\\\n' +\n ' headers: {\\\\n' +\n ' \"Content-Type\": \"application/json\",\\\\n' +\n ' },\\\\n' +\n ' body: JSON.stringify(' + bodyStr.split('\\\\n').map((l, i) => i === 0 ? l : ' ' + l).join('\\\\n') + '),\\\\n' +\n '});\\\\n\\\\n' +\n 'const data = await response.json();\\\\n' +\n 'console.log(data);';\n }\n return 'const response = await fetch(\"' + url + '\"' +\n (method !== 'GET' ? ', {\\\\n method: \"' + method + '\",\\\\n}' : '') + ');\\\\n\\\\n' +\n 'const data = await response.json();\\\\n' +\n 'console.log(data);';\n\n case 'recker':\n if (hasBody) {\n return 'import { ' + method.toLowerCase() + ' } from \"recker\";\\\\n\\\\n' +\n 'const data = await ' + method.toLowerCase() + '(\"' + url + '\")\\\\n' +\n ' .json(' + bodyStr.split('\\\\n').map((l, i) => i === 0 ? l : ' ' + l).join('\\\\n') + ')\\\\n' +\n ' .json();\\\\n\\\\n' +\n 'console.log(data);';\n }\n return 'import { ' + method.toLowerCase() + ' } from \"recker\";\\\\n\\\\n' +\n 'const data = await ' + method.toLowerCase() + '(\"' + url + '\").json();\\\\n\\\\n' +\n 'console.log(data);';\n\n case 'python':\n if (hasBody) {\n return 'import requests\\\\n\\\\n' +\n 'response = requests.' + method.toLowerCase() + '(\\\\n' +\n ' \"' + url + '\",\\\\n' +\n ' json=' + bodyStr.split('\\\\n').map((l, i) => i === 0 ? l : ' ' + l).join('\\\\n') + ',\\\\n' +\n ')\\\\n\\\\n' +\n 'print(response.json())';\n }\n return 'import requests\\\\n\\\\n' +\n 'response = requests.' + method.toLowerCase() + '(\"' + url + '\")\\\\n\\\\n' +\n 'print(response.json())';\n\n case 'go':\n if (hasBody) {\n return 'package main\\\\n\\\\n' +\n 'import (\\\\n' +\n ' \"bytes\"\\\\n' +\n ' \"encoding/json\"\\\\n' +\n ' \"fmt\"\\\\n' +\n ' \"net/http\"\\\\n' +\n ' \"io\"\\\\n' +\n ')\\\\n\\\\n' +\n 'func main() {\\\\n' +\n ' body, _ := json.Marshal(map[string]interface{}{\\\\n' +\n generateGoMapBody(body) +\n ' })\\\\n\\\\n' +\n ' req, _ := http.NewRequest(\"' + method + '\", \"' + url + '\", bytes.NewBuffer(body))\\\\n' +\n ' req.Header.Set(\"Content-Type\", \"application/json\")\\\\n\\\\n' +\n ' client := &http.Client{}\\\\n' +\n ' resp, _ := client.Do(req)\\\\n' +\n ' defer resp.Body.Close()\\\\n\\\\n' +\n ' data, _ := io.ReadAll(resp.Body)\\\\n' +\n ' fmt.Println(string(data))\\\\n' +\n '}';\n }\n return 'package main\\\\n\\\\n' +\n 'import (\\\\n' +\n ' \"fmt\"\\\\n' +\n ' \"net/http\"\\\\n' +\n ' \"io\"\\\\n' +\n ')\\\\n\\\\n' +\n 'func main() {\\\\n' +\n ' resp, _ := http.Get(\"' + url + '\")\\\\n' +\n ' defer resp.Body.Close()\\\\n\\\\n' +\n ' body, _ := io.ReadAll(resp.Body)\\\\n' +\n ' fmt.Println(string(body))\\\\n' +\n '}';\n\n default:\n return '// Not implemented';\n }\n }\n\n function generateGoMapBody(body) {\n if (!body || typeof body !== 'object') return '';\n const lines = [];\n for (const [key, value] of Object.entries(body)) {\n const goValue = typeof value === 'string' ? '\"' + value + '\"' :\n typeof value === 'number' ? String(value) :\n typeof value === 'boolean' ? String(value) :\n 'nil';\n lines.push(' \"' + key + '\": ' + goValue + ',');\n }\n return lines.join('\\\\n') + '\\\\n';\n }\n\n function buildExampleFromSchema(schema) {\n if (!schema) return null;\n\n // Resolve $ref\n if (schema.$ref) {\n const resolved = resolveRef(schema.$ref);\n return buildExampleFromSchema(resolved);\n }\n\n // Normalize non-standard format\n schema = normalizeSchema(schema);\n\n if (schema.example !== undefined) return schema.example;\n if (schema.default !== undefined) return schema.default;\n\n if (schema.type === 'object' && schema.properties) {\n const obj = {};\n for (const [key, prop] of Object.entries(schema.properties)) {\n obj[key] = buildExampleFromSchema(prop);\n }\n return obj;\n }\n\n if (schema.type === 'array' && schema.items) {\n return [buildExampleFromSchema(schema.items)];\n }\n\n // Primitive defaults\n switch (schema.type) {\n case 'string': return schema.format === 'email' ? 'user@example.com' : 'string';\n case 'number': return 0;\n case 'integer': return 0;\n case 'boolean': return true;\n default: return null;\n }\n }\n\n";
5
- //# sourceMappingURL=cards-and-code.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cards-and-code.d.ts","sourceRoot":"","sources":["../../../../../src/docs/ui/client-script/cards-and-code.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,wBAAwB,sx6BAAsx6B,CAAA"}
@@ -1,5 +0,0 @@
1
- /**
2
- * Embedded docs UI client script chunk.
3
- */
4
- export declare const contentClientScript: string;
5
- //# sourceMappingURL=content.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../../../../src/docs/ui/client-script/content.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,mBAAmB,QAuZ/B,CAAA"}
@@ -1,5 +0,0 @@
1
- /**
2
- * Embedded docs UI client script chunk.
3
- */
4
- export declare const docsPagesClientScript: string;
5
- //# sourceMappingURL=docs-pages.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"docs-pages.d.ts","sourceRoot":"","sources":["../../../../../src/docs/ui/client-script/docs-pages.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,qBAAqB,QAoJjC,CAAA"}
@@ -1,5 +0,0 @@
1
- /**
2
- * Embedded docs UI client script chunk.
3
- */
4
- export declare const endpointDetailsClientScript = " function resolveEffectiveContentTypes(operationTypes, protocolTypes) {\n const globalTypes = (xUsd && xUsd.contentTypes) ? xUsd.contentTypes : {};\n const defaultType =\n (operationTypes && operationTypes.default) ||\n (protocolTypes && protocolTypes.default) ||\n globalTypes.default ||\n 'application/json';\n const supportedList =\n (operationTypes && operationTypes.supported) ||\n (protocolTypes && protocolTypes.supported) ||\n globalTypes.supported ||\n [];\n const supported = Array.isArray(supportedList) ? supportedList.slice() : [];\n if (defaultType && supported.indexOf(defaultType) === -1) {\n supported.unshift(defaultType);\n }\n return { default: defaultType, supported };\n }\n\n function appendContentTypes(container, label, contentTypes) {\n if (!contentTypes) return;\n const section = document.createElement('div');\n section.className = 'endpoint-subsection';\n section.innerHTML = '<div class=\"subsection-label\">' + esc(label) + '</div>';\n const grid = document.createElement('div');\n grid.className = 'info-grid';\n const supportedText = (contentTypes.supported && contentTypes.supported.length > 0)\n ? contentTypes.supported.join(', ')\n : contentTypes.default;\n grid.innerHTML =\n '<div class=\"info-card\"><div class=\"info-card-title\">Default</div><div class=\"info-card-value\">' +\n esc(contentTypes.default || 'application/json') + '</div></div>' +\n '<div class=\"info-card\"><div class=\"info-card-title\">Supported</div><div class=\"info-card-value\">' +\n esc(supportedText || 'application/json') + '</div></div>';\n section.appendChild(grid);\n container.appendChild(section);\n }\n\n function renderEndpointDetails(ep) {\n const container = document.createElement('div');\n const data = ep.data;\n\n // HTTP-specific (Redoc-style layout)\n if (activeProtocol === 'http') {\n // AUTHORIZATIONS section\n if (data.security && data.security.length > 0) {\n const authSection = document.createElement('div');\n authSection.className = 'endpoint-subsection';\n authSection.innerHTML = '<div class=\"subsection-label\">AUTHORIZATIONS:</div>';\n const authValue = document.createElement('span');\n authValue.className = 'auth-value';\n const authNames = data.security.flatMap(s => Object.keys(s));\n authValue.textContent = authNames.join(', ') || 'None';\n authSection.appendChild(authValue);\n container.appendChild(authSection);\n }\n\n // PATH PARAMETERS\n const pathParams = (data.parameters || []).filter(p => p.in === 'path');\n if (pathParams.length > 0) {\n const section = document.createElement('div');\n section.className = 'endpoint-subsection';\n section.innerHTML = '<div class=\"subsection-label\">PATH PARAMETERS</div>';\n section.appendChild(renderParametersRedocStyle(pathParams));\n container.appendChild(section);\n }\n\n // QUERY PARAMETERS\n const queryParams = (data.parameters || []).filter(p => p.in === 'query');\n if (queryParams.length > 0) {\n const section = document.createElement('div');\n section.className = 'endpoint-subsection';\n section.innerHTML = '<div class=\"subsection-label\">QUERY PARAMETERS</div>';\n section.appendChild(renderParametersRedocStyle(queryParams));\n container.appendChild(section);\n }\n\n // HEADER PARAMETERS\n const headerParams = (data.parameters || []).filter(p => p.in === 'header');\n if (headerParams.length > 0) {\n const section = document.createElement('div');\n section.className = 'endpoint-subsection';\n section.innerHTML = '<div class=\"subsection-label\">HEADER PARAMETERS</div>';\n section.appendChild(renderParametersRedocStyle(headerParams));\n container.appendChild(section);\n }\n }\n\n // WebSocket-specific\n if (activeProtocol === 'websocket') {\n if (data.type) {\n const badge = document.createElement('span');\n badge.className = 'badge channel-type-' + data.type;\n badge.textContent = data.type;\n badge.style.marginBottom = '16px';\n badge.style.display = 'inline-block';\n container.appendChild(badge);\n }\n if (data.subscribe) {\n appendContentTypes(\n container,\n 'Subscribe Content Types',\n resolveEffectiveContentTypes(data.subscribe?.contentTypes, wsSpec?.contentTypes)\n );\n }\n if (data.publish) {\n appendContentTypes(\n container,\n 'Publish Content Types',\n resolveEffectiveContentTypes(data.publish?.contentTypes, wsSpec?.contentTypes)\n );\n }\n if (data.parameters) {\n const paramSchema = { type: 'object', properties: {}, required: [] };\n Object.entries(data.parameters).forEach(([name, param]) => {\n const schema = param.schema || { type: 'string' };\n if (param.description) schema.description = param.description;\n paramSchema.properties[name] = schema;\n if (param.required) paramSchema.required.push(name);\n });\n const h = document.createElement('h4');\n h.textContent = 'Parameters';\n container.appendChild(h);\n const schemaEl = renderSchemaProperties(paramSchema, paramSchema.required, 0);\n container.appendChild(schemaEl);\n }\n const subscribePayload = resolveMessagePayload(data.subscribe?.message);\n if (subscribePayload) {\n const h = document.createElement('h4');\n h.textContent = 'Subscribe (receive)';\n container.appendChild(h);\n const schemaEl = renderSchemaProperties(subscribePayload, [], 0);\n container.appendChild(schemaEl);\n }\n const publishPayload = resolveMessagePayload(data.publish?.message);\n if (publishPayload) {\n const h = document.createElement('h4');\n h.textContent = 'Publish (send)';\n container.appendChild(h);\n const schemaEl = renderSchemaProperties(publishPayload, [], 0);\n container.appendChild(schemaEl);\n }\n }\n\n // Streams-specific\n if (activeProtocol === 'streams') {\n if (data.direction) {\n const badge = document.createElement('span');\n badge.className = 'badge badge-stream';\n badge.textContent = data.direction;\n badge.style.marginBottom = '16px';\n badge.style.display = 'inline-block';\n container.appendChild(badge);\n }\n appendContentTypes(\n container,\n 'Content Types',\n resolveEffectiveContentTypes(data.contentTypes, streamsSpec?.contentTypes)\n );\n const streamPayload = resolveMessagePayload(data.message);\n if (streamPayload) {\n const h = document.createElement('h4');\n h.textContent = 'Message Schema';\n container.appendChild(h);\n const schemaEl = renderSchemaProperties(streamPayload, [], 0);\n container.appendChild(schemaEl);\n }\n }\n\n // JSON-RPC-specific\n if (activeProtocol === 'jsonrpc') {\n if (data['x-usd-notification'] || data['x-usd-streaming']) {\n const flags = [];\n if (data['x-usd-notification']) flags.push('notification');\n if (data['x-usd-streaming']) flags.push('streaming');\n const info = document.createElement('div');\n info.style.marginBottom = '16px';\n info.innerHTML = flags.map(f => '<span class=\"badge badge-rpc\" style=\"margin-right: 6px;\">' + esc(f) + '</span>').join('');\n container.appendChild(info);\n }\n appendContentTypes(\n container,\n 'Content Types',\n resolveEffectiveContentTypes(data.contentTypes, jsonrpcSpec?.contentTypes)\n );\n if (data.params) {\n const h = document.createElement('h4');\n h.textContent = 'Parameters';\n container.appendChild(h);\n const schemaEl = renderSchemaProperties(data.params, data.params.required || [], 0);\n container.appendChild(schemaEl);\n }\n if (data.result) {\n const h = document.createElement('h4');\n h.textContent = 'Result';\n container.appendChild(h);\n const schemaEl = renderSchemaProperties(data.result, [], 0);\n container.appendChild(schemaEl);\n }\n if (Array.isArray(data.errors) && data.errors.length > 0) {\n const section = document.createElement('div');\n section.className = 'endpoint-subsection';\n section.innerHTML = '<div class=\"subsection-label\">Errors</div>';\n data.errors.forEach((err) => {\n const card = document.createElement('div');\n card.className = 'info-card';\n card.innerHTML =\n '<div class=\"info-card-title\">' + esc(err.code) + '</div>' +\n '<div class=\"info-card-value\">' + esc(err.message) + '</div>' +\n (err.description ? '<div class=\"info-card-subtitle\">' + esc(err.description) + '</div>' : '');\n section.appendChild(card);\n if (err.data) {\n const schemaEl = renderSchemaProperties(err.data, [], 0);\n section.appendChild(schemaEl);\n }\n });\n container.appendChild(section);\n }\n }\n\n // gRPC-specific\n if (activeProtocol === 'grpc') {\n const method = data.method;\n if (method) {\n const methodType = getGrpcMethodType(method);\n if (methodType && methodType !== 'unary') {\n const badge = document.createElement('span');\n badge.className = 'badge badge-stream';\n badge.textContent = methodType.replace('_', ' ');\n badge.style.marginBottom = '16px';\n badge.style.display = 'inline-block';\n container.appendChild(badge);\n }\n appendContentTypes(\n container,\n 'Content Types',\n resolveEffectiveContentTypes(method.contentTypes, grpcSpec?.contentTypes)\n );\n if (method.input) {\n const h = document.createElement('h4');\n h.textContent = 'Request';\n container.appendChild(h);\n const schemaEl = renderSchemaProperties(method.input, [], 0);\n container.appendChild(schemaEl);\n }\n if (method.output) {\n const h = document.createElement('h4');\n h.textContent = 'Response';\n container.appendChild(h);\n const schemaEl = renderSchemaProperties(method.output, [], 0);\n container.appendChild(schemaEl);\n }\n }\n }\n\n // TCP-specific\n if (activeProtocol === 'tcp') {\n const grid = document.createElement('div');\n grid.className = 'info-grid';\n grid.innerHTML =\n '<div class=\"info-card\"><div class=\"info-card-title\">Host</div><div class=\"info-card-value\">' +\n esc(data.host || 'localhost') + '</div></div>' +\n '<div class=\"info-card\"><div class=\"info-card-title\">Port</div><div class=\"info-card-value\">' +\n (data.port || 'N/A') + '</div></div>' +\n (data.tls?.enabled ? '<div class=\"info-card\"><div class=\"info-card-title\">TLS</div><div class=\"info-card-value\">Enabled</div></div>' : '');\n container.appendChild(grid);\n appendContentTypes(\n container,\n 'Content Types',\n resolveEffectiveContentTypes(data.contentTypes, tcpSpec?.contentTypes)\n );\n if (data.framing) {\n const h = document.createElement('h4');\n h.textContent = 'Framing';\n container.appendChild(h);\n const schemaEl = renderSchemaProperties(data.framing, [], 0);\n container.appendChild(schemaEl);\n }\n if (data.messages?.inbound || data.messages?.outbound) {\n if (data.messages?.inbound) {\n const h = document.createElement('h4');\n h.textContent = 'Inbound Message';\n container.appendChild(h);\n const schemaEl = renderSchemaProperties(resolveMessagePayload(data.messages.inbound), [], 0);\n container.appendChild(schemaEl);\n }\n if (data.messages?.outbound) {\n const h = document.createElement('h4');\n h.textContent = 'Outbound Message';\n container.appendChild(h);\n const schemaEl = renderSchemaProperties(resolveMessagePayload(data.messages.outbound), [], 0);\n container.appendChild(schemaEl);\n }\n }\n }\n\n // UDP-specific\n if (activeProtocol === 'udp') {\n const grid = document.createElement('div');\n grid.className = 'info-grid';\n grid.innerHTML =\n '<div class=\"info-card\"><div class=\"info-card-title\">Host</div><div class=\"info-card-value\">' +\n esc(data.host || '127.0.0.1') + '</div></div>' +\n '<div class=\"info-card\"><div class=\"info-card-title\">Port</div><div class=\"info-card-value\">' +\n (data.port || 'N/A') + '</div></div>' +\n '<div class=\"info-card\"><div class=\"info-card-title\">Max Packet</div><div class=\"info-card-value\">' +\n (data.maxPacketSize || 65507) + ' bytes</div></div>';\n container.appendChild(grid);\n appendContentTypes(\n container,\n 'Content Types',\n resolveEffectiveContentTypes(data.contentTypes, udpSpec?.contentTypes)\n );\n if (data.messages?.inbound) {\n const h = document.createElement('h4');\n h.textContent = 'Inbound Message';\n container.appendChild(h);\n const schemaEl = renderSchemaProperties(resolveMessagePayload(data.messages.inbound), [], 0);\n container.appendChild(schemaEl);\n }\n if (data.messages?.outbound) {\n const h = document.createElement('h4');\n h.textContent = 'Outbound Message';\n container.appendChild(h);\n const schemaEl = renderSchemaProperties(resolveMessagePayload(data.messages.outbound), [], 0);\n container.appendChild(schemaEl);\n }\n if (!data.messages?.inbound && !data.messages?.outbound && data.message) {\n const h = document.createElement('h4');\n h.textContent = 'Message Schema';\n container.appendChild(h);\n const schemaEl = renderSchemaProperties(resolveMessagePayload(data.message), [], 0);\n container.appendChild(schemaEl);\n }\n }\n\n return container;\n }\n\n function getGrpcMethodType(method) {\n const client = method['x-usd-client-streaming'];\n const server = method['x-usd-server-streaming'];\n if (client && server) return 'bidirectional';\n if (client) return 'client_streaming';\n if (server) return 'server_streaming';\n return 'unary';\n }\n\n function resolveMessagePayload(message) {\n if (!message) return null;\n if (message.$ref) {\n const resolved = resolveRef(message.$ref);\n if (resolved && resolved.payload) return resolved.payload;\n return resolved || message;\n }\n if (message.payload) return message.payload;\n return message;\n }\n\n";
5
- //# sourceMappingURL=endpoint-details.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"endpoint-details.d.ts","sourceRoot":"","sources":["../../../../../src/docs/ui/client-script/endpoint-details.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,2BAA2B,w/eAA0/e,CAAA"}
@@ -1,5 +0,0 @@
1
- /**
2
- * Embedded docs UI client script chunk.
3
- */
4
- export declare const initClientScript: string;
5
- //# sourceMappingURL=init.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../../../src/docs/ui/client-script/init.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,gBAAgB,QA8N5B,CAAA"}
@@ -1,5 +0,0 @@
1
- /**
2
- * Embedded docs UI client script chunk.
3
- */
4
- export declare const markdownClientScript: string;
5
- //# sourceMappingURL=markdown.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../../../../src/docs/ui/client-script/markdown.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,oBAAoB,QAibhC,CAAA"}
@@ -1,5 +0,0 @@
1
- /**
2
- * Embedded docs UI client script chunk.
3
- */
4
- export declare const navigationClientScript: string;
5
- //# sourceMappingURL=navigation.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../../../../src/docs/ui/client-script/navigation.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,sBAAsB,QA+hBlC,CAAA"}
@@ -1,5 +0,0 @@
1
- /**
2
- * Embedded docs UI client script chunk.
3
- */
4
- export declare const protocolClientScript = " // Detect protocols with counts\n const protocolData = {};\n const xUsd = spec['x-usd'] || {};\n const wsSpec = xUsd.websocket;\n const streamsSpec = xUsd.streams;\n const jsonrpcSpec = xUsd.jsonrpc;\n const grpcSpec = xUsd.grpc;\n const tcpSpec = xUsd.tcp;\n const udpSpec = xUsd.udp;\n if (spec.paths) {\n let count = 0;\n Object.values(spec.paths).forEach(methods => {\n Object.keys(methods).forEach(m => {\n if (['get','post','put','patch','delete'].includes(m)) count++;\n });\n });\n if (count > 0) protocolData.http = count;\n }\n if (wsSpec?.channels) {\n protocolData.websocket = Object.keys(wsSpec.channels).length;\n }\n if (streamsSpec?.endpoints) {\n protocolData.streams = Object.keys(streamsSpec.endpoints).length;\n }\n if (jsonrpcSpec?.methods) {\n protocolData.jsonrpc = Object.keys(jsonrpcSpec.methods).length;\n }\n if (grpcSpec?.services) {\n let count = 0;\n Object.values(grpcSpec.services).forEach(s => {\n count += Object.keys(s.methods || {}).length;\n });\n if (count > 0) protocolData.grpc = count;\n }\n if (tcpSpec?.servers) {\n protocolData.tcp = Object.keys(tcpSpec.servers).length;\n } else if (tcpSpec) {\n protocolData.tcp = 0;\n }\n if (udpSpec?.endpoints) {\n protocolData.udp = Object.keys(udpSpec.endpoints).length;\n } else if (udpSpec) {\n protocolData.udp = 0;\n }\n if (wsSpec && !protocolData.websocket) {\n protocolData.websocket = 0;\n }\n\n const protocols = Object.keys(protocolData);\n let activeProtocol = protocols.includes('http') ? 'http' : (protocols[0] || 'http');\n let searchQuery = '';\n const initialRoute = parseRouteHash();\n let activePagePath = initialRoute.pagePath;\n let activeHeadingId = initialRoute.headingId;\n\n function parseRouteHash() {\n const hash = String(location.hash || '');\n if (!hash.startsWith('#/')) return { pagePath: '/', headingId: hash.startsWith('#') ? hash.slice(1) : '' };\n const raw = hash.slice(1);\n const parts = raw.split('?');\n const params = typeof URLSearchParams === 'undefined' ? null : new URLSearchParams(parts[1] || '');\n return { pagePath: normalizeDocsPath(parts[0]), headingId: params?.get?.('id') || '' };\n }\n\n function normalizeDocsPath(path) {\n const raw = String(path || '').trim();\n if (!raw) return '';\n const withSlash = raw.startsWith('/') ? raw : '/' + raw;\n return withSlash.replace(/\\/+$/, '') || '/';\n }\n\n";
5
- //# sourceMappingURL=protocols.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"protocols.d.ts","sourceRoot":"","sources":["../../../../../src/docs/ui/client-script/protocols.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,oBAAoB,wjFAAwjF,CAAA"}