| | |
| | |
| | |
| | const DEFAULT_EXAMPLE_DESCRIPTION = 'Example' |
| | const DEFAULT_EXAMPLE_KEY = 'default' |
| | const DEFAULT_ACCEPT_HEADER = 'application/vnd.github.v3+json' |
| |
|
| | |
| | type Operation = any |
| |
|
| | interface RequestExample { |
| | key: string |
| | request: { |
| | contentType?: string |
| | description: string |
| | acceptHeader: string |
| | bodyParameters?: any |
| | parameters?: Record<string, any> |
| | } |
| | } |
| |
|
| | interface ResponseExample { |
| | key: string |
| | response: { |
| | statusCode: string |
| | contentType?: string |
| | description: string |
| | example?: any |
| | schema?: any |
| | } |
| | } |
| |
|
| | interface MergedExample { |
| | key: string |
| | request: { |
| | contentType?: string |
| | description: string |
| | acceptHeader: string |
| | bodyParameters?: any |
| | parameters?: Record<string, any> |
| | } |
| | response?: { |
| | statusCode: string |
| | contentType?: string |
| | description: string |
| | example?: any |
| | schema?: any |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | export default async function getCodeSamples(operation: Operation): Promise<MergedExample[]> { |
| | const responseExamples = getResponseExamples(operation) |
| | const requestExamples = getRequestExamples(operation) |
| |
|
| | const mergedExamples = mergeExamples(requestExamples, responseExamples) |
| |
|
| | |
| | |
| | if (mergedExamples.length > 1) { |
| | const count: Record<string, number> = {} |
| | for (const item of mergedExamples) { |
| | count[item.request.description] = (count[item.request.description] || 0) + 1 |
| | } |
| |
|
| | const newMergedExamples = mergedExamples.map((example, i) => ({ |
| | ...example, |
| | request: { |
| | ...example.request, |
| | description: |
| | count[example.request.description] > 1 |
| | ? `${example.request.description} ${i + 1}: Status Code ${example.response!.statusCode}` |
| | : example.request.description, |
| | }, |
| | })) |
| |
|
| | return newMergedExamples |
| | } |
| |
|
| | return mergedExamples |
| | } |
| |
|
| | export function mergeExamples( |
| | requestExamples: RequestExample[], |
| | responseExamples: ResponseExample[], |
| | ): MergedExample[] { |
| | |
| | |
| | if (requestExamples.length === 1 && responseExamples.length === 0) { |
| | return [] |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | if (requestExamples.length === 1 && responseExamples.length === 1) { |
| | return [{ ...requestExamples[0], response: responseExamples[0].response }] |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | if ( |
| | requestExamples.length === 1 && |
| | responseExamples.length > 1 && |
| | !responseExamples.find((ex) => ex.response.example) |
| | ) { |
| | return responseExamples |
| | .filter((resp) => parseInt(resp.response.statusCode, 10) < 300) |
| | .map((ex) => ({ ...requestExamples[0], ...ex })) |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | if ( |
| | requestExamples.length === 1 && |
| | responseExamples.length > 1 && |
| | responseExamples.filter((ex) => ex.response.example).length >= 1 |
| | ) { |
| | return responseExamples |
| | .filter((ex) => ex.response.example) |
| | .map((ex) => ({ ...requestExamples[0], ...ex })) |
| | } |
| |
|
| | |
| | |
| | |
| | const requestsExamplesLarger = requestExamples.length >= responseExamples.length |
| | const target = requestsExamplesLarger ? requestExamples : responseExamples |
| | const source = requestsExamplesLarger ? responseExamples : requestExamples |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | return target |
| | .filter((targetEx) => { |
| | const match = source.find((srcEx) => srcEx.key === targetEx.key) |
| | if (match) return Object.assign(targetEx, match) |
| | return false |
| | }) |
| | .map((ex) => ex as MergedExample) |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | export function getRequestExamples(operation: Operation): RequestExample[] { |
| | const requestExamples: RequestExample[] = [] |
| | const parameterExamples = getParameterExamples(operation) |
| |
|
| | |
| | |
| | |
| | if (!operation.requestBody && Object.keys(parameterExamples).length === 0) { |
| | return [ |
| | { |
| | key: DEFAULT_EXAMPLE_KEY, |
| | request: { |
| | description: DEFAULT_EXAMPLE_DESCRIPTION, |
| | acceptHeader: DEFAULT_ACCEPT_HEADER, |
| | }, |
| | }, |
| | ] |
| | } |
| |
|
| | |
| | if (!operation.requestBody) { |
| | return Object.keys(parameterExamples).map((key) => { |
| | return { |
| | key, |
| | request: { |
| | description: DEFAULT_EXAMPLE_DESCRIPTION, |
| | acceptHeader: DEFAULT_ACCEPT_HEADER, |
| | parameters: parameterExamples[key] || parameterExamples.default, |
| | }, |
| | } |
| | }) |
| | } |
| |
|
| | |
| | |
| | for (const contentType of Object.keys(operation.requestBody.content)) { |
| | let examples: Record<string, any> = {} |
| | |
| | |
| | |
| | |
| | |
| | if (operation.requestBody.content[contentType].example) { |
| | examples = { |
| | default: { |
| | value: operation.requestBody.content[contentType].example, |
| | }, |
| | } |
| | } else if (operation.requestBody.content[contentType].examples) { |
| | examples = operation.requestBody.content[contentType].examples |
| | } else { |
| | |
| | requestExamples.push({ |
| | key: DEFAULT_EXAMPLE_KEY, |
| | request: { |
| | contentType, |
| | description: DEFAULT_EXAMPLE_DESCRIPTION, |
| | acceptHeader: DEFAULT_ACCEPT_HEADER, |
| | parameters: parameterExamples.default, |
| | }, |
| | }) |
| | continue |
| | } |
| |
|
| | |
| | |
| | |
| | for (const key of Object.keys(examples)) { |
| | |
| | |
| | |
| | const acceptHeader = contentType.includes('+json') |
| | ? contentType |
| | : 'application/vnd.github.v3+json' |
| |
|
| | const example = { |
| | key, |
| | request: { |
| | contentType, |
| | description: examples[key].summary || DEFAULT_EXAMPLE_DESCRIPTION, |
| | acceptHeader, |
| | bodyParameters: examples[key].value, |
| | parameters: parameterExamples[key] || parameterExamples.default, |
| | }, |
| | } |
| | requestExamples.push(example) |
| | } |
| | } |
| | return requestExamples |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | export function getResponseExamples(operation: Operation): ResponseExample[] { |
| | const responseExamples: ResponseExample[] = [] |
| | for (const statusCode of Object.keys(operation.responses)) { |
| | |
| | |
| | if (parseInt(statusCode, 10) >= 400) continue |
| |
|
| | const content = operation.responses[statusCode].content |
| |
|
| | |
| | |
| | |
| | if (!content) { |
| | const example = { |
| | key: statusCode, |
| | response: { |
| | statusCode, |
| | description: operation.responses[statusCode].description, |
| | }, |
| | } |
| | responseExamples.push(example) |
| | continue |
| | } |
| |
|
| | |
| | |
| | for (const contentType of Object.keys(content)) { |
| | let examples: Record<string, any> = {} |
| | |
| | |
| | |
| | |
| | |
| | if (operation.responses[statusCode].content[contentType].example) { |
| | examples = { |
| | default: { |
| | value: operation.responses[statusCode].content[contentType].example, |
| | }, |
| | } |
| | } else if (operation.responses[statusCode].content[contentType].examples) { |
| | examples = operation.responses[statusCode].content[contentType].examples |
| | } else if (parseInt(statusCode, 10) < 300) { |
| | |
| | |
| | |
| | |
| | |
| | |
| | const example = { |
| | key: statusCode, |
| | response: { |
| | statusCode, |
| | description: operation.responses[statusCode].description, |
| | }, |
| | } |
| | responseExamples.push(example) |
| | continue |
| | } else { |
| | |
| | |
| | |
| | continue |
| | } |
| |
|
| | |
| | |
| | |
| | for (const key of Object.keys(examples)) { |
| | const example = { |
| | key, |
| | response: { |
| | statusCode, |
| | contentType, |
| | description: examples[key].summary || operation.responses[statusCode].description, |
| | example: examples[key].value, |
| | |
| | |
| | |
| | |
| | schema: operation.responses[statusCode].content[contentType].schema, |
| | }, |
| | } |
| | responseExamples.push(example) |
| | } |
| | } |
| | } |
| | return responseExamples |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | export function getParameterExamples(operation: Operation): Record<string, Record<string, any>> { |
| | if (!operation.parameters) { |
| | return {} |
| | } |
| | const parameters = operation.parameters.filter((param: any) => param.in === 'path') |
| | const parameterExamples: Record<string, Record<string, any>> = {} |
| | for (const parameter of parameters) { |
| | const examples = parameter.examples |
| | |
| | |
| | |
| | if (!examples) { |
| | if (!parameterExamples.default) parameterExamples.default = {} |
| | parameterExamples.default[parameter.name] = parameter.name.toUpperCase() |
| | } else { |
| | for (const key of Object.keys(examples)) { |
| | if (!parameterExamples[key]) parameterExamples[key] = {} |
| | parameterExamples[key][parameter.name] = examples[key].value |
| | } |
| | } |
| | } |
| | return parameterExamples |
| | } |
| |
|