* Resolve a $ref to its actual schema
(
schema: Schema | undefined,
spec: OpenApiSpec = this.spec!
)
| 400 | * Resolve a $ref to its actual schema |
| 401 | */ |
| 402 | private resolveSchemaRef( |
| 403 | schema: Schema | undefined, |
| 404 | spec: OpenApiSpec = this.spec! |
| 405 | ): Schema | undefined { |
| 406 | if (!schema) return undefined; |
| 407 | |
| 408 | if (schema.$ref) { |
| 409 | // Parse $ref like "#/components/schemas/SchemaName" |
| 410 | const match = schema.$ref.match(/^#\/components\/schemas\/(.+)$/); |
| 411 | if (match && spec.components?.schemas) { |
| 412 | const resolved = spec.components.schemas[match[1]]; |
| 413 | // Recursively resolve if the resolved schema also has a $ref |
| 414 | return this.resolveSchemaRef(resolved, spec); |
| 415 | } |
| 416 | return undefined; |
| 417 | } |
| 418 | |
| 419 | // Handle allOf by merging schemas |
| 420 | if (schema.allOf && schema.allOf.length > 0) { |
| 421 | const merged: Schema = { type: 'object', properties: {}, required: [] }; |
| 422 | for (const subSchema of schema.allOf) { |
| 423 | const resolved = this.resolveSchemaRef(subSchema, spec); |
| 424 | if (resolved) { |
| 425 | if (resolved.properties) { |
| 426 | merged.properties = { |
| 427 | ...merged.properties, |
| 428 | ...resolved.properties, |
| 429 | }; |
| 430 | } |
| 431 | if (resolved.required) { |
| 432 | merged.required = [ |
| 433 | ...(merged.required || []), |
| 434 | ...resolved.required, |
| 435 | ]; |
| 436 | } |
| 437 | } |
| 438 | } |
| 439 | return merged; |
| 440 | } |
| 441 | |
| 442 | return schema; |
| 443 | } |
| 444 | } |