Skip to content

Commit 0b2ea50

Browse files
committed
feat(Markdown): markdown support for single, 1-depth responses
1 parent 0007194 commit 0b2ea50

File tree

2 files changed

+85
-26
lines changed

2 files changed

+85
-26
lines changed

src/utils/format-single-api-endpoint-as-markdown.ts

+14-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
import { OpenAPIV3 } from 'openapi-types'
12
import { CustomPathDiffItem } from './generate-markdown-diff'
2-
import { jsonToMarkdown } from './json-to-markdown'
3+
import { SchemaObject, jsonToMarkdown } from './json-to-markdown'
34

45
type FormatSingleApiEndpointAsMarkdown = (
56
endpoint: CustomPathDiffItem
@@ -25,13 +26,17 @@ export const formatSingleApiEndpointAsMarkdown: FormatSingleApiEndpointAsMarkdow
2526
endpoint => {
2627
const { url, method, endpointDetailData } = endpoint
2728
const { responses } = endpointDetailData
28-
const successResponse = responses['200'] ?? responses['201']
29-
const successResponseContent = isReferenceObject(successResponse)
30-
? {}
31-
: successResponse?.content?.['application/json'] ??
32-
successResponse?.content?.['text/plain']
33-
34-
const responseMarkdown = jsonToMarkdown(successResponseContent)
29+
const successResponse = (responses['200'] ??
30+
responses['201']) as OpenAPIV3.ResponseObject // all refs have been resolved in main.ts
31+
const successResponseContent =
32+
successResponse?.content?.['application/json'] ??
33+
successResponse?.content?.['text/plain']
34+
const successResponseContentSchema =
35+
successResponseContent?.schema as SchemaObject
36+
37+
const responseMarkdown = successResponseContent?.schema
38+
? jsonToMarkdown({ schema: successResponseContentSchema })
39+
: ''
3540

3641
const parameterMarkdownArray = Object.entries(
3742
endpointDetailData.parameters ?? {}
@@ -69,7 +74,7 @@ ${responseMarkdown}
6974
7075
`
7176

72-
console.log(generatedMarkdown)
77+
// console.log(generatedMarkdown)
7378

7479
return generatedMarkdown
7580
}

src/utils/json-to-markdown.ts

+71-17
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,79 @@
11
// Utility function to format JSON as Markdown code block
22

3+
import { OpenAPIV3 } from 'openapi-types'
4+
35
// eslint-disable-next-line @typescript-eslint/no-explicit-any
4-
export function jsonToMarkdown(obj: any, depth = 0): string {
5-
let md = depth === 0 ? '```markdown\n' : '' // Start code block only at the top level
6-
const indent = ' '.repeat(depth)
7-
8-
for (const key in obj) {
9-
if (
10-
typeof obj[key] === 'object' &&
11-
obj[key] !== null &&
12-
!Array.isArray(obj[key])
13-
) {
14-
md += `${indent} ${key} :\n`
15-
md += jsonToMarkdown(obj[key], depth + 1) // Recursively append sub-objects
16-
} else {
17-
md += `${indent}- ${key}: ${JSON.stringify(obj[key], null, 2)}\n`
18-
}
6+
7+
export type SchemaObject = ArraySchemaObject | NonArraySchemaObject
8+
interface ArraySchemaObject extends CustomBaseSchemaObject {
9+
type: OpenAPIV3.ArraySchemaObjectType
10+
items: SchemaObject // All refs are resolved in main.ts before calling this function
11+
}
12+
interface NonArraySchemaObject extends CustomBaseSchemaObject {
13+
type?: OpenAPIV3.NonArraySchemaObjectType
14+
}
15+
interface CustomBaseSchemaObject {
16+
title?: string
17+
description?: string
18+
format?: string
19+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
20+
default?: any
21+
multipleOf?: number
22+
maximum?: number
23+
exclusiveMaximum?: boolean
24+
minimum?: number
25+
exclusiveMinimum?: boolean
26+
maxLength?: number
27+
minLength?: number
28+
pattern?: string
29+
additionalProperties?: boolean | SchemaObject
30+
maxItems?: number
31+
minItems?: number
32+
uniqueItems?: boolean
33+
maxProperties?: number
34+
minProperties?: number
35+
required?: string[]
36+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
37+
enum?: any[]
38+
properties?: {
39+
[name: string]: SchemaObject
1940
}
41+
allOf?: SchemaObject[]
42+
oneOf?: SchemaObject[]
43+
anyOf?: SchemaObject[]
44+
not?: SchemaObject
45+
nullable?: boolean
46+
discriminator?: OpenAPIV3.DiscriminatorObject
47+
readOnly?: boolean
48+
writeOnly?: boolean
49+
xml?: OpenAPIV3.XMLObject
50+
externalDocs?: OpenAPIV3.ExternalDocumentationObject
51+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
52+
example?: any
53+
deprecated?: boolean
54+
}
55+
56+
export type SingleReponseObj = {
57+
schema: SchemaObject
58+
}
2059

21-
if (depth === 0) {
22-
md += '```\n' // End code block only at the top level
60+
// recursively format nested objects until obj.type is not 'object' , 'array' , null or undefined
61+
// WRITE YOUR CODE HERE
62+
63+
export function jsonToMarkdown(obj: SingleReponseObj): string {
64+
const properties = obj.schema.properties
65+
66+
if (!properties) return ''
67+
68+
let md = '```markdown\n'
69+
70+
for (const property of Object.entries(properties)) {
71+
const [propertyName, propertyMetadata] = property
72+
73+
md += `${propertyName} : ${propertyMetadata.type}; \n📎${propertyMetadata.description} \n📚EX) ${propertyMetadata.example} \n\n`
2374
}
75+
76+
md += '```'
77+
2478
return md
2579
}

0 commit comments

Comments
 (0)