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.

refactor: optimize schemaNameTransform for efficiency and clarity

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

+9 -48
+2 -3
packages/openapi-ts-tests/main/test/3.0.x.test.ts
··· 618 618 output: 'transforms-schemas-name-collision', 619 619 parser: { 620 620 transforms: { 621 - schemaName: (name: string) => 621 + schemaName: (name: string) => 622 622 // Try to rename all _vX_User schemas to "User" 623 623 // This should cause collisions since "User" already exists 624 - name.replace(/_v\d+_User$/, '') 625 - , 624 + name.replace(/_v\d+_User$/, ''), 626 625 }, 627 626 }, 628 627 plugins: ['@hey-api/typescript'],
+7 -45
packages/shared/src/openApi/shared/transforms/schemas.ts
··· 8 8 /** 9 9 * Recursively walks the entire spec object and replaces all $ref strings 10 10 * according to the provided rename mapping. 11 - * 12 - * @param node - Current node being visited 13 - * @param renameMap - Map from old pointer to new pointer 14 11 */ 15 12 const rewriteRefs = (node: unknown, renameMap: Record<string, string>) => { 16 13 if (node instanceof Array) { ··· 18 15 } else if (node && typeof node === 'object') { 19 16 for (const [key, value] of Object.entries(node)) { 20 17 if (key === '$ref' && typeof value === 'string' && value in renameMap) { 21 - // Replace the $ref with the new name 22 18 (node as Record<string, unknown>)[key] = renameMap[value]; 23 19 } else { 24 20 rewriteRefs(value, renameMap); ··· 28 24 }; 29 25 30 26 /** 31 - * Applies the schema name transform to rename schema component keys and 32 - * update all $ref pointers throughout the spec. 33 - * 34 - * This transform: 35 - * 1. Iterates all schema keys in components.schemas (or definitions for Swagger 2.0) 36 - * 2. Applies the name transformer to compute new names 37 - * 3. Handles name collisions (skips rename if new name already exists) 38 - * 4. Renames schema keys in the schemas object 39 - * 5. Updates all $ref pointers throughout the spec to use the new names 40 - * 41 - * @param config - The schema name transformer 42 - * @param spec - The OpenAPI spec object to transform 27 + * Renames schema component keys and updates all $ref pointers throughout 28 + * the spec. Handles collisions by skipping renames when the target name 29 + * already exists or conflicts with another rename. 43 30 */ 44 31 export const schemaNameTransform = ({ 45 32 config, ··· 62 49 return; 63 50 } 64 51 65 - // Build rename map: oldPointer -> newPointer 66 52 const renameMap: Record<string, string> = {}; 67 53 const newNames = new Set<string>(); 54 + const namingConfig = { name: config }; 68 55 69 - // Create a simple config object for applyNaming 70 - const namingConfig = typeof config === 'function' ? { name: config } : { name: config }; 71 - 72 - // First pass: compute all new names and check for collisions 73 56 for (const oldName of Object.keys(schemasObj)) { 74 57 const newName = applyNaming(oldName, namingConfig); 75 58 76 - // Skip if name doesn't change 77 59 if (newName === oldName) { 78 60 continue; 79 61 } 80 62 81 - // Skip if new name collides with an existing schema 82 63 if (newName in schemasObj) { 83 64 continue; 84 65 } 85 66 86 - // Skip if new name collides with another renamed schema 87 67 if (newNames.has(newName)) { 88 68 continue; 89 69 } 90 70 91 - // Record the rename 92 71 renameMap[`${schemasPointerNamespace}${oldName}`] = `${schemasPointerNamespace}${newName}`; 93 72 newNames.add(newName); 94 73 } 95 74 96 - // Second pass: rename schema keys 97 - // We need to be careful about the order to avoid overwriting 98 - const renamedSchemas: Record<string, unknown> = {}; 99 - const processedOldNames = new Set<string>(); 100 - 101 75 for (const [oldPointer, newPointer] of Object.entries(renameMap)) { 102 76 const oldName = oldPointer.slice(schemasPointerNamespace.length); 103 77 const newName = newPointer.slice(schemasPointerNamespace.length); 104 - 105 - // Store the schema under the new name 106 - renamedSchemas[newName] = schemasObj[oldName]; 107 - processedOldNames.add(oldName); 108 - } 78 + const schema = schemasObj[oldName]; 109 79 110 - // Add all schemas that weren't renamed 111 - for (const [name, schema] of Object.entries(schemasObj)) { 112 - if (!processedOldNames.has(name)) { 113 - renamedSchemas[name] = schema; 114 - } 80 + delete schemasObj[oldName]; 81 + schemasObj[newName] = schema; 115 82 } 116 83 117 - // Replace the entire schemas object with the renamed version 118 - Object.keys(schemasObj).forEach((key) => delete schemasObj[key]); 119 - Object.assign(schemasObj, renamedSchemas); 120 - 121 - // Third pass: rewrite all $ref pointers throughout the spec 122 84 if (Object.keys(renameMap).length > 0) { 123 85 rewriteRefs(spec, renameMap); 124 86 }