fork of hey-api/openapi-ts because I need some additional things
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

WIP: Add discriminator mapping updates for writable types (partial fix)

Co-authored-by: mrlubos <12529395+mrlubos@users.noreply.github.com>

+210
+103
packages/shared/src/openApi/shared/transforms/readWrite.ts
··· 437 437 split.reverseMapping[writePointer] = pointer; 438 438 } 439 439 440 + // Helper function to update discriminator mappings in a schema 441 + const updateDiscriminatorMappingsInSchema = ( 442 + schema: unknown, 443 + contextVariant: 'read' | 'write', 444 + ) => { 445 + if (schema && typeof schema === 'object') { 446 + // If this schema has a discriminator with a mapping 447 + if ( 448 + 'discriminator' in schema && 449 + schema.discriminator && 450 + typeof schema.discriminator === 'object' && 451 + 'mapping' in schema.discriminator && 452 + schema.discriminator.mapping && 453 + typeof schema.discriminator.mapping === 'object' 454 + ) { 455 + const mapping = schema.discriminator.mapping as Record<string, string>; 456 + const updatedMapping: Record<string, string> = {}; 457 + 458 + for (const [discriminatorValue, originalRef] of Object.entries(mapping)) { 459 + const map = split.mapping[originalRef]; 460 + if (map) { 461 + // Update to the appropriate variant 462 + if (contextVariant === 'read' && map.read) { 463 + updatedMapping[discriminatorValue] = map.read; 464 + } else if (contextVariant === 'write' && map.write) { 465 + updatedMapping[discriminatorValue] = map.write; 466 + } else { 467 + updatedMapping[discriminatorValue] = originalRef; 468 + } 469 + } else { 470 + updatedMapping[discriminatorValue] = originalRef; 471 + } 472 + } 473 + 474 + (schema.discriminator as Record<string, unknown>).mapping = updatedMapping; 475 + } 476 + 477 + // Recursively update discriminators in allOf, oneOf, anyOf 478 + for (const key of ['allOf', 'oneOf', 'anyOf'] as const) { 479 + if (key in schema && Array.isArray((schema as Record<string, unknown>)[key])) { 480 + const compositions = (schema as Record<string, unknown>)[key] as Array<unknown>; 481 + for (const comp of compositions) { 482 + updateDiscriminatorMappingsInSchema(comp, contextVariant); 483 + } 484 + } 485 + } 486 + } 487 + }; 488 + 489 + // Update discriminator mappings in all split schemas 490 + for (const [name, schema] of Object.entries(split.schemas)) { 491 + const pointer = `${schemasPointerNamespace}${name}`; 492 + const originalPointer = split.reverseMapping[pointer]; 493 + 494 + if (originalPointer) { 495 + const mapping = split.mapping[originalPointer]; 496 + if (mapping) { 497 + // Determine if this is a read or write variant 498 + const isRead = mapping.read === pointer; 499 + const isWrite = mapping.write === pointer; 500 + 501 + if (isRead) { 502 + updateDiscriminatorMappingsInSchema(schema, 'read'); 503 + } else if (isWrite) { 504 + updateDiscriminatorMappingsInSchema(schema, 'write'); 505 + } 506 + } 507 + } 508 + } 509 + 440 510 event.timeEnd(); 441 511 return split; 442 512 }; ··· 630 700 (node as Record<string, unknown>)[key] = map.read; 631 701 } 632 702 } 703 + } else if (key === 'discriminator' && typeof value === 'object' && value !== null) { 704 + // Update discriminator mappings to point to the correct read/write variants 705 + const discriminator = value as Record<string, unknown>; 706 + if (discriminator.mapping && typeof discriminator.mapping === 'object') { 707 + const mapping = discriminator.mapping as Record<string, string>; 708 + const updatedMapping: Record<string, string> = {}; 709 + for (const [discriminatorValue, originalRef] of Object.entries(mapping)) { 710 + const map = split.mapping[originalRef]; 711 + if (map) { 712 + if (nextContext === 'read' && map.read) { 713 + updatedMapping[discriminatorValue] = map.read; 714 + } else if (nextContext === 'write' && map.write) { 715 + updatedMapping[discriminatorValue] = map.write; 716 + } else { 717 + // For schemas with no context, don't update the mapping. 718 + // This preserves the original mapping for base schemas. 719 + updatedMapping[discriminatorValue] = originalRef; 720 + } 721 + } else { 722 + updatedMapping[discriminatorValue] = originalRef; 723 + } 724 + } 725 + discriminator.mapping = updatedMapping; 726 + } 727 + // Continue walking the discriminator object for other properties 728 + walk({ 729 + context: nextContext, 730 + currentPointer: nextPointer, 731 + inSchema, 732 + node: value, 733 + path: [...path, key], 734 + visited, 735 + }); 633 736 } else { 634 737 walk({ 635 738 context: nextContext,
+107
specs/3.1.x/discriminator-one-of-read-write.yaml
··· 1 + openapi: 3.1.0 2 + info: 3 + title: OpenAPI 3.1.0 discriminator one of with read/write example 4 + version: 1 5 + paths: 6 + /pets: 7 + post: 8 + requestBody: 9 + content: 10 + application/json: 11 + schema: 12 + $ref: '#/components/schemas/CreatePetRequest' 13 + required: true 14 + responses: 15 + '200': 16 + content: 17 + application/json: 18 + schema: 19 + $ref: '#/components/schemas/CreatePetResponse' 20 + description: OK 21 + components: 22 + schemas: 23 + AnimalPayload: 24 + type: object 25 + required: 26 + - typeDiscriminator 27 + properties: 28 + typeDiscriminator: 29 + type: string 30 + discriminator: 31 + propertyName: typeDiscriminator 32 + mapping: 33 + dog: '#/components/schemas/DogPayload' 34 + cat: '#/components/schemas/CatPayload' 35 + 36 + DogPayload: 37 + allOf: 38 + - $ref: '#/components/schemas/AnimalPayload' 39 + - type: object 40 + required: 41 + - breed 42 + - canFetch 43 + - displayBreed 44 + properties: 45 + breed: 46 + type: string 47 + canFetch: 48 + type: boolean 49 + displayBreed: 50 + type: string 51 + readOnly: true 52 + 53 + CatPayload: 54 + allOf: 55 + - $ref: '#/components/schemas/AnimalPayload' 56 + - type: object 57 + required: 58 + - breed 59 + - livesRemaining 60 + - displayBreed 61 + properties: 62 + breed: 63 + type: string 64 + livesRemaining: 65 + type: integer 66 + displayBreed: 67 + type: string 68 + readOnly: true 69 + 70 + CreatePetRequest: 71 + type: object 72 + required: 73 + - name 74 + - animal 75 + properties: 76 + name: 77 + type: string 78 + animal: 79 + oneOf: 80 + - $ref: '#/components/schemas/DogPayload' 81 + - $ref: '#/components/schemas/CatPayload' 82 + discriminator: 83 + propertyName: typeDiscriminator 84 + mapping: 85 + dog: '#/components/schemas/DogPayload' 86 + cat: '#/components/schemas/CatPayload' 87 + 88 + CreatePetResponse: 89 + type: object 90 + required: 91 + - id 92 + - name 93 + - animal 94 + properties: 95 + id: 96 + type: string 97 + name: 98 + type: string 99 + animal: 100 + oneOf: 101 + - $ref: '#/components/schemas/DogPayload' 102 + - $ref: '#/components/schemas/CatPayload' 103 + discriminator: 104 + propertyName: typeDiscriminator 105 + mapping: 106 + dog: '#/components/schemas/DogPayload' 107 + cat: '#/components/schemas/CatPayload'