fix: response schema is now inferred from each endpoint's sample JSON

This commit is contained in:
Florian Sylvain committed 2026-10-23 01:56:35 +02:00
1 parent d2af39da61
commit 9ab98fd50c
1 file changed
+51 -1
+51 -1
View File
@@ -212,6 +212,53 @@ function parseExample(response: string) {
}
}
type Schema = Record<string, unknown>
function mergeSchemas(schemas: Schema[]): Schema {
const unique = [...new Map(schemas.map((schema) => [JSON.stringify(schema), schema])).values()]
if (unique.length === 1) return unique[0]
const objects = unique.filter((schema) => schema.type === 'object')
if (objects.length > 1 && objects.length === unique.length) {
const keys = [...new Set(objects.flatMap((schema) => Object.keys(schema.properties as Schema)))]
return {
type: 'object',
properties: Object.fromEntries(
keys.map((key) => [
key,
mergeSchemas(
objects
.map((schema) => (schema.properties as Record<string, Schema>)[key])
.filter((schema) => schema !== undefined),
),
]),
),
required: keys.filter((key) =>
objects.every((schema) => key in (schema.properties as Schema)),
),
}
}
return { anyOf: unique }
}
function inferSchema(value: unknown): Schema {
if (value === null) return { type: 'null' }
if (Array.isArray(value)) {
return value.length === 0
? { type: 'array', items: {} }
: { type: 'array', items: mergeSchemas(value.map(inferSchema)) }
}
if (typeof value === 'object') {
const entries = Object.entries(value as Record<string, unknown>)
return {
type: 'object',
properties: Object.fromEntries(entries.map(([key, child]) => [key, inferSchema(child)])),
required: entries.map(([key]) => key),
}
}
if (typeof value === 'number') return { type: Number.isInteger(value) ? 'integer' : 'number' }
return { type: typeof value }
}
function operation(item: ApiEndpoint) {
const pathParameters = [...item.path.matchAll(/\{(\w+)\}/g)].map((match) => ({
name: match[1],
@@ -234,7 +281,10 @@ function operation(item: ApiEndpoint) {
: {
description: 'Success',
content: {
'application/json': { schema: {}, ...(example === undefined ? {} : { example }) },
'application/json': {
schema: example === undefined ? {} : inferSchema(example),
...(example === undefined ? {} : { example }),
},
},
},
}