import type { OpenAPI } from '@gitbook/openapi-parser'; import { OpenAPIRequestBody } from './OpenAPIRequestBody'; import { OpenAPIResponses } from './OpenAPIResponses'; import { OpenAPISchemaProperties } from './OpenAPISchemaServer'; import { OpenAPISecurities } from './OpenAPISecurities'; import { StaticSection } from './StaticSection'; import type { OpenAPIClientContext } from './context'; import { tString } from './translate'; import type { OpenAPIOperationData, OpenAPIWebhookData } from './types'; import { parameterToProperty } from './utils'; export function OpenAPISpec(props: { data: OpenAPIOperationData | OpenAPIWebhookData; context: OpenAPIClientContext; }) { const { data, context } = props; const { operation } = data; const parameters = deduplicateParameters(operation.parameters ?? []); const parameterGroups = groupParameters(parameters, context); const securities = 'securities' in data ? data.securities : []; return ( <> {securities.length > 0 ? ( ) : null} {parameterGroups.map((group) => { return ( ); })} {operation.requestBody ? ( ) : null} {operation.responses ? ( ) : null} ); } function groupParameters( parameters: OpenAPI.Parameters, context: OpenAPIClientContext ): Array<{ key: string; label: string; parameters: OpenAPI.Parameters; }> { const sorted = ['path', 'query', 'header']; const groups: Array<{ key: string; label: string; parameters: OpenAPI.Parameters; }> = []; parameters .filter((parameter) => parameter.in) .forEach((parameter) => { const key = parameter.in; const label = getParameterGroupName(parameter.in, context); const group = groups.find((group) => group.key === key); if (group) { group.parameters.push(parameter); } else { groups.push({ key, label, parameters: [parameter], }); } }); groups.sort((a, b) => sorted.indexOf(a.key) - sorted.indexOf(b.key)); return groups; } function getParameterGroupName(paramIn: string, context: OpenAPIClientContext): string { switch (paramIn) { case 'path': return tString(context.translation, 'path_parameters'); case 'query': return tString(context.translation, 'query_parameters'); case 'header': return tString(context.translation, 'header_parameters'); default: return paramIn; } } /** Deduplicate parameters by name and in. * Some specs have both parameters define at path and operation level. * We only want to display one of them. */ function deduplicateParameters(parameters: OpenAPI.Parameters): OpenAPI.Parameters { const seen = new Set(); return parameters.filter((param) => { const key = `${param.name}:${param.in}`; if (seen.has(key)) { return false; } seen.add(key); return true; }); }